@api-client/core 0.5.4 → 0.5.7

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.
Files changed (51) hide show
  1. package/build/browser.d.ts +1 -0
  2. package/build/browser.js +1 -0
  3. package/build/browser.js.map +1 -1
  4. package/build/index.d.ts +1 -0
  5. package/build/index.js +1 -0
  6. package/build/index.js.map +1 -1
  7. package/build/src/models/Backend.d.ts +7 -9
  8. package/build/src/models/HttpHistory.d.ts +2 -2
  9. package/build/src/models/Project.d.ts +1 -1
  10. package/build/src/models/Project.js +2 -2
  11. package/build/src/models/Project.js.map +1 -1
  12. package/build/src/models/RevisionInfo.d.ts +2 -2
  13. package/build/src/models/SerializableError.d.ts +1 -0
  14. package/build/src/models/SerializableError.js.map +1 -1
  15. package/build/src/runtime/store/Errors.d.ts +50 -0
  16. package/build/src/runtime/store/Errors.js +63 -0
  17. package/build/src/runtime/store/Errors.js.map +1 -0
  18. package/build/src/runtime/store/FilesSdk.d.ts +43 -27
  19. package/build/src/runtime/store/FilesSdk.js +102 -54
  20. package/build/src/runtime/store/FilesSdk.js.map +1 -1
  21. package/build/src/runtime/store/HistorySdk.d.ts +14 -7
  22. package/build/src/runtime/store/HistorySdk.js +34 -12
  23. package/build/src/runtime/store/HistorySdk.js.map +1 -1
  24. package/build/src/runtime/store/Sdk.d.ts +4 -0
  25. package/build/src/runtime/store/Sdk.js +4 -0
  26. package/build/src/runtime/store/Sdk.js.map +1 -1
  27. package/build/src/runtime/store/SdkBase.d.ts +16 -6
  28. package/build/src/runtime/store/SdkBase.js +54 -4
  29. package/build/src/runtime/store/SdkBase.js.map +1 -1
  30. package/build/src/runtime/store/SharedSdk.d.ts +8 -2
  31. package/build/src/runtime/store/SharedSdk.js +21 -7
  32. package/build/src/runtime/store/SharedSdk.js.map +1 -1
  33. package/build/src/runtime/store/StoreSdkWeb.d.ts +1 -1
  34. package/build/src/runtime/store/UsersSdk.d.ts +10 -4
  35. package/build/src/runtime/store/UsersSdk.js +12 -6
  36. package/build/src/runtime/store/UsersSdk.js.map +1 -1
  37. package/package.json +3 -4
  38. package/src/models/Backend.ts +7 -9
  39. package/src/models/HttpHistory.ts +2 -2
  40. package/src/models/Project.ts +2 -2
  41. package/src/models/RevisionInfo.ts +2 -2
  42. package/src/models/SerializableError.ts +1 -0
  43. package/src/runtime/store/Errors.ts +100 -0
  44. package/src/runtime/store/FilesSdk.ts +120 -65
  45. package/src/runtime/store/HistorySdk.ts +42 -17
  46. package/src/runtime/store/Sdk.ts +5 -0
  47. package/src/runtime/store/SdkBase.ts +63 -9
  48. package/src/runtime/store/SharedSdk.ts +26 -9
  49. package/src/runtime/store/StoreSdkWeb.ts +1 -1
  50. package/src/runtime/store/UsersSdk.ts +14 -8
  51. package/json8-patch.d.ts +0 -270
@@ -1,17 +1,20 @@
1
- import { JsonPatch } from 'json8-patch';
2
- import { SdkBase, E_RESPONSE_STATUS, E_RESPONSE_NO_VALUE, E_INVALID_JSON, E_RESPONSE_UNKNOWN, E_RESPONSE_LOCATION } from './SdkBase.js';
1
+ import WebSocketNode from 'ws';
2
+ import { Patch } from '@api-client/json';
3
+ import { SdkBase, E_RESPONSE_STATUS, E_RESPONSE_NO_VALUE, E_INVALID_JSON, E_RESPONSE_UNKNOWN, E_RESPONSE_LOCATION, ISdkRequestOptions } from './SdkBase.js';
3
4
  import { RouteBuilder } from './RouteBuilder.js';
4
5
  import { IListOptions, IListResponse } from '../../models/Backend.js';
5
- import { IWorkspace, Workspace, Kind as WorkspaceKind } from '../../models/Workspace.js';
6
6
  import { AccessOperation } from '../../models/store/Permission.js';
7
7
  import { IUser } from '../../models/store/User.js';
8
8
  import { IFile } from '../../models/store/File.js';
9
- import WebSocketNode from 'ws';
9
+ import { Kind as ProjectKind } from '../../models/Project.js';
10
+ import { Kind as WorkspaceKind } from '../../models/Workspace.js';
11
+ import { IHttpProject } from '../../models/HttpProject.js';
12
+ import { SdkError } from './Errors.js';
10
13
 
11
14
  export interface IFileCreateOptions {
12
15
  /**
13
- * Optional parent space id.
14
- * When set it creates a space under this parent.
16
+ * Optional parent file id.
17
+ * When set it creates a file under this parent.
15
18
  */
16
19
  parent?: string;
17
20
  }
@@ -19,18 +22,27 @@ export interface IFileCreateOptions {
19
22
  export class FilesSdk extends SdkBase {
20
23
  /**
21
24
  * Lists files (spaces, projects, etc) in the store.
25
+ *
26
+ * @param kinds the list of kinds to list. Spaces are always included.
22
27
  * @param options Optional query options.
28
+ * @param request Optional request options.
23
29
  */
24
- async list(options?: IListOptions): Promise<IListResponse<IFile>> {
25
- const { token } = this.sdk;
30
+ async list(kinds: (typeof ProjectKind | typeof WorkspaceKind)[], options?: IListOptions, request: ISdkRequestOptions = {}): Promise<IListResponse<IFile>> {
31
+ const token = request.token || this.sdk.token;
26
32
  const url = this.sdk.getUrl(RouteBuilder.files());
27
33
  this.sdk.appendListOptions(url, options);
34
+ kinds.forEach(k => url.searchParams.append('kind', k));
28
35
  const result = await this.sdk.http.get(url.toString(), { token });
29
- this.inspectCommonStatusCodes(result.status);
30
- const E_PREFIX = 'Unable to list spaces. ';
36
+ this.inspectCommonStatusCodes(result.status, result.body);
37
+ const E_PREFIX = 'Unable to list files. ';
31
38
  if (result.status !== 200) {
32
39
  this.logInvalidResponse(result);
33
- throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
40
+ let e = this.createGenericSdkError(result.body)
41
+ if (!e) {
42
+ e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
43
+ e.response = result.body;
44
+ }
45
+ throw e;
34
46
  }
35
47
  if (!result.body) {
36
48
  throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
@@ -48,21 +60,29 @@ export class FilesSdk extends SdkBase {
48
60
  }
49
61
 
50
62
  /**
51
- * Creates a workspace in the store.
52
- * @param space The workspace definition.
53
- * @returns The key of the creates space.
63
+ * Creates a file in the store.
64
+ *
65
+ * @param file The definition of a file that extends the IFile interface or one of the supported by the server schemas.
66
+ * @param opts Optional options when creating a file
67
+ * @param request Optional request options.
68
+ * @returns The key of the creates file.
54
69
  */
55
- async create(space: IWorkspace | Workspace, opts: IFileCreateOptions = {}): Promise<string> {
56
- const { token } = this.sdk;
70
+ async create(file: IFile | IHttpProject, opts: IFileCreateOptions = {}, request: ISdkRequestOptions = {}): Promise<string> {
71
+ const token = request.token || this.sdk.token;
57
72
  const path = opts.parent ? RouteBuilder.file(opts.parent) : RouteBuilder.files();
58
73
  const url = this.sdk.getUrl(path);
59
- const body = JSON.stringify(space);
74
+ const body = JSON.stringify(file);
60
75
  const result = await this.sdk.http.post(url.toString(), { token, body });
61
- this.inspectCommonStatusCodes(result.status);
62
- const E_PREFIX = 'Unable to create a user space. ';
76
+ this.inspectCommonStatusCodes(result.status, result.body);
77
+ const E_PREFIX = 'Unable to create a file. ';
63
78
  if (result.status !== 204) {
64
79
  this.logInvalidResponse(result);
65
- throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
80
+ let e = this.createGenericSdkError(result.body)
81
+ if (!e) {
82
+ e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
83
+ e.response = result.body;
84
+ }
85
+ throw e;
66
86
  }
67
87
  const location = result.headers.get('location');
68
88
  if (!location) {
@@ -76,45 +96,53 @@ export class FilesSdk extends SdkBase {
76
96
  * Reads file metadata from the store.
77
97
  *
78
98
  * @param key The file key
99
+ * @param request Optional request options.
79
100
  * @returns THe file metadata
80
101
  */
81
- read(key: string, media: false): Promise<IFile>;
102
+ read(key: string, media: false, request?: ISdkRequestOptions): Promise<IFile>;
82
103
  /**
83
104
  * Reads file contents from the store.
84
105
  *
85
106
  * @param key The file key
107
+ * @param request Optional request options.
86
108
  * @returns THe file contents
87
109
  */
88
- read(key: string, media: true): Promise<unknown>;
110
+ read(key: string, media: true, request?: ISdkRequestOptions): Promise<unknown>;
89
111
 
90
112
  /**
91
113
  * Reads a user file definition from the store.
92
114
  * @param key The file key
93
115
  * @param media When true it reads file contents rather than metadata.
116
+ * @param request Optional request options.
94
117
  */
95
- async read(key: string, media?: boolean): Promise<IFile | unknown> {
96
- const { token } = this.sdk;
118
+ async read(key: string, media?: boolean, request: ISdkRequestOptions = {}): Promise<IFile | unknown> {
119
+ const token = request.token || this.sdk.token;
97
120
  const url = this.sdk.getUrl(RouteBuilder.file(key));
98
121
  if (media) {
99
122
  url.searchParams.set('alt', 'media');
100
123
  }
101
124
  const result = await this.sdk.http.get(url.toString(), { token });
102
- this.inspectCommonStatusCodes(result.status);
103
- const E_PREFIX = 'Unable to read a user space. ';
125
+ this.inspectCommonStatusCodes(result.status, result.body);
126
+ const E_PREFIX = 'Unable to read a file. ';
104
127
  if (result.status !== 200) {
105
128
  this.logInvalidResponse(result);
106
- throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
129
+ let e = this.createGenericSdkError(result.body)
130
+ if (!e) {
131
+ e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
132
+ e.response = result.body;
133
+ }
134
+ throw e;
107
135
  }
108
136
  if (!result.body) {
109
137
  throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
110
138
  }
111
- let data: IWorkspace;
139
+ let data: IFile;
112
140
  try {
113
141
  data = JSON.parse(result.body);
114
142
  } catch (e) {
115
143
  throw new Error(`${E_PREFIX}${E_INVALID_JSON}.`);
116
144
  }
117
- if (data.kind !== WorkspaceKind) {
145
+ if (!data.kind) {
118
146
  throw new Error(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`);
119
147
  }
120
148
  return data;
@@ -125,36 +153,44 @@ export class FilesSdk extends SdkBase {
125
153
  *
126
154
  * @param key The file key
127
155
  * @param value The patch to apply.
156
+ * @param request Optional request options.
128
157
  */
129
- patch(key: string, value: JsonPatch, media: false): Promise<JsonPatch>;
158
+ patch(key: string, value: Patch.JsonPatch, media: false, request?: ISdkRequestOptions): Promise<Patch.JsonPatch>;
130
159
 
131
160
  /**
132
161
  * Patches file's content in the store.
133
162
  *
134
163
  * @param key The file key
135
164
  * @param value The patch to apply.
165
+ * @param request Optional request options.
136
166
  */
137
- patch(key: string, value: JsonPatch, media: true): Promise<JsonPatch>;
167
+ patch(key: string, value: Patch.JsonPatch, media: true, request?: ISdkRequestOptions): Promise<Patch.JsonPatch>;
138
168
 
139
169
  /**
140
- * Patches a user space in the store.
141
- * @param key The key of the user space to patch
170
+ * Patches a file in the store.
171
+ * @param key The key of the file to patch
142
172
  * @param value The JSON patch to be processed.
143
- * @returns The JSON patch to revert the change using the `json8-patch` library
173
+ * @param request Optional request options.
174
+ * @returns The JSON patch to revert the change using the `@api-client/json` library
144
175
  */
145
- async patch(key: string, value: JsonPatch, media?: boolean): Promise<JsonPatch> {
146
- const { token } = this.sdk;
176
+ async patch(key: string, value: Patch.JsonPatch, media?: boolean, request: ISdkRequestOptions = {}): Promise<Patch.JsonPatch> {
177
+ const token = request.token || this.sdk.token;
147
178
  const url = this.sdk.getUrl(RouteBuilder.file(key));
148
179
  if (media) {
149
180
  url.searchParams.set('alt', 'media');
150
181
  }
151
182
  const body = JSON.stringify(value);
152
183
  const result = await this.sdk.http.patch(url.toString(), { token, body });
153
- this.inspectCommonStatusCodes(result.status);
154
- const E_PREFIX = 'Unable to patch a user space. ';
184
+ this.inspectCommonStatusCodes(result.status, result.body);
185
+ const E_PREFIX = 'Unable to patch a file. ';
155
186
  if (result.status !== 200) {
156
187
  this.logInvalidResponse(result);
157
- throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
188
+ let e = this.createGenericSdkError(result.body)
189
+ if (!e) {
190
+ e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
191
+ e.response = result.body;
192
+ }
193
+ throw e;
158
194
  }
159
195
  if (!result.body) {
160
196
  throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
@@ -168,59 +204,77 @@ export class FilesSdk extends SdkBase {
168
204
  if (!data.revert) {
169
205
  throw new Error(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`);
170
206
  }
171
- return data.revert as JsonPatch;
207
+ return data.revert as Patch.JsonPatch;
172
208
  }
173
209
 
174
210
  /**
175
- * Deletes the space in the store.
211
+ * Deletes the file in the store.
176
212
  *
177
- * @param key The key of the space to delete.
213
+ * @param key The key of the file to delete.
214
+ * @param request Optional request options.
178
215
  */
179
- async delete(key: string): Promise<void> {
180
- const { token } = this.sdk;
216
+ async delete(key: string, request: ISdkRequestOptions = {}): Promise<void> {
217
+ const token = request.token || this.sdk.token;
181
218
  const url = this.sdk.getUrl(RouteBuilder.file(key));
182
219
  const result = await this.sdk.http.delete(url.toString(), { token });
183
- this.inspectCommonStatusCodes(result.status);
184
- const E_PREFIX = 'Unable to delete a user space. ';
220
+ this.inspectCommonStatusCodes(result.status, result.body);
221
+ const E_PREFIX = 'Unable to delete a file. ';
185
222
  if (result.status !== 204) {
186
223
  this.logInvalidResponse(result);
187
- throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
224
+ let e = this.createGenericSdkError(result.body)
225
+ if (!e) {
226
+ e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
227
+ e.response = result.body;
228
+ }
229
+ throw e;
188
230
  }
189
231
  }
190
232
 
191
233
  /**
192
- * Updates the sharing options of the space.
234
+ * Updates the sharing options of the file.
193
235
  *
194
- * @param key The user space key
195
- * @param value The patch operation on the space's ACL
236
+ * @param key The file key
237
+ * @param value The patch operation on the file's ACL
238
+ * @param request Optional request options.
196
239
  */
197
- async patchUsers(key: string, value: AccessOperation[]): Promise<void> {
198
- const { token } = this.sdk;
240
+ async patchUsers(key: string, value: AccessOperation[], request: ISdkRequestOptions = {}): Promise<void> {
241
+ const token = request.token || this.sdk.token;
199
242
  const url = this.sdk.getUrl(RouteBuilder.fileUsers(key));
200
243
  const body = JSON.stringify(value);
201
244
  const result = await this.sdk.http.patch(url.toString(), { token, body });
202
- this.inspectCommonStatusCodes(result.status);
203
- const E_PREFIX = 'Unable to patch a user space. ';
245
+ this.inspectCommonStatusCodes(result.status, result.body);
246
+ const E_PREFIX = 'Unable to patch a file. ';
204
247
  if (result.status !== 204) {
205
248
  this.logInvalidResponse(result);
206
- throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
249
+ let e = this.createGenericSdkError(result.body)
250
+ if (!e) {
251
+ e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
252
+ e.response = result.body;
253
+ }
254
+ throw e;
207
255
  }
208
256
  }
209
257
 
210
258
  /**
211
- * Lists uses having access to the user space.
259
+ * Lists uses having access to the file.
212
260
  *
213
- * @param key The user space key
261
+ * @param key The file key
262
+ * @param request Optional request options.
214
263
  */
215
- async listUsers(key: string): Promise<IListResponse<IUser>> {
216
- const { token } = this.sdk;
264
+ async listUsers(key: string, request: ISdkRequestOptions = {}): Promise<IListResponse<IUser>> {
265
+ const token = request.token || this.sdk.token;
217
266
  const url = this.sdk.getUrl(RouteBuilder.fileUsers(key));
218
267
  const result = await this.sdk.http.get(url.toString(), { token });
219
- this.inspectCommonStatusCodes(result.status);
220
- const E_PREFIX = 'Unable to list users in the space. ';
268
+ this.inspectCommonStatusCodes(result.status, result.body);
269
+ const E_PREFIX = 'Unable to list users in the file. ';
221
270
  if (result.status !== 200) {
222
271
  this.logInvalidResponse(result);
223
- throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
272
+ let e = this.createGenericSdkError(result.body)
273
+ if (!e) {
274
+ e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
275
+ e.response = result.body;
276
+ }
277
+ throw e;
224
278
  }
225
279
  if (!result.body) {
226
280
  throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
@@ -238,10 +292,11 @@ export class FilesSdk extends SdkBase {
238
292
  }
239
293
 
240
294
  /**
241
- * Creates a WS client that listens to the spaces events.
295
+ * Creates a WS client that listens to the files events.
296
+ * @param request Optional request options.
242
297
  */
243
- async observeFiles(): Promise<WebSocketNode | WebSocket> {
244
- const { token } = this.sdk;
298
+ async observeFiles(request: ISdkRequestOptions = {}): Promise<WebSocketNode | WebSocket> {
299
+ const token = request.token || this.sdk.token;
245
300
  const url = this.sdk.getUrl(RouteBuilder.files());
246
301
  return this.sdk.ws.createAndConnect(url.toString(), token);
247
302
  }
@@ -1,6 +1,6 @@
1
- import { SdkBase, E_RESPONSE_STATUS, E_RESPONSE_NO_VALUE, E_INVALID_JSON, E_RESPONSE_UNKNOWN, E_RESPONSE_LOCATION } from './SdkBase.js';
1
+ import { SdkBase, E_RESPONSE_STATUS, E_RESPONSE_NO_VALUE, E_INVALID_JSON, E_RESPONSE_UNKNOWN, E_RESPONSE_LOCATION, ISdkRequestOptions } from './SdkBase.js';
2
2
  import { RouteBuilder } from './RouteBuilder.js';
3
- import { IListResponse, HistoryListOptions } from '../../models/Backend.js';
3
+ import { IListResponse, HistoryListOptions, IHistoryRequestListOptions } from '../../models/Backend.js';
4
4
  import { IHttpHistory, IHttpHistoryBulkAdd, Kind as HttpHistoryKind } from '../../models/HttpHistory.js';
5
5
 
6
6
  export class HistorySdk extends SdkBase {
@@ -14,10 +14,11 @@ export class HistorySdk extends SdkBase {
14
14
  * Note, history objects cannot be updated. They can only be created or deleted.
15
15
  *
16
16
  * @param history The history to create
17
+ * @param request Optional request options.
17
18
  * @returns The key of the created history.
18
19
  */
19
- async create(history: IHttpHistory): Promise<string> {
20
- const { token } = this.sdk;
20
+ async create(history: IHttpHistory, request: ISdkRequestOptions = {}): Promise<string> {
21
+ const token = request.token || this.sdk.token;
21
22
  const url = this.sdk.getUrl(RouteBuilder.history());
22
23
  const body = JSON.stringify(history);
23
24
  const result = await this.sdk.http.post(url.toString(), { token, body });
@@ -39,9 +40,10 @@ export class HistorySdk extends SdkBase {
39
40
  * Creates a multiple history objects in a batch operation.
40
41
  *
41
42
  * @param info The bulk create info object.
43
+ * @param request Optional request options.
42
44
  */
43
- async createBulk(info: IHttpHistoryBulkAdd): Promise<string[]> {
44
- const { token } = this.sdk;
45
+ async createBulk(info: IHttpHistoryBulkAdd, request: ISdkRequestOptions = {}): Promise<string[]> {
46
+ const token = request.token || this.sdk.token;
45
47
  const url = this.sdk.getUrl(RouteBuilder.historyBatchCreate());
46
48
  const body = JSON.stringify(info);
47
49
  const result = await this.sdk.http.post(url.toString(), { token, body });
@@ -56,7 +58,7 @@ export class HistorySdk extends SdkBase {
56
58
  }
57
59
  let data: string[];
58
60
  try {
59
- data = JSON.parse(result.body);
61
+ data = JSON.parse(result.body).data;
60
62
  } catch (e) {
61
63
  throw new Error(`${E_PREFIX}${E_INVALID_JSON}.`);
62
64
  }
@@ -67,11 +69,12 @@ export class HistorySdk extends SdkBase {
67
69
  * Lists the history.
68
70
  *
69
71
  * @param options Optional query options.
72
+ * @param request Optional request options.
70
73
  */
71
- async list(options: HistoryListOptions): Promise<IListResponse> {
72
- const { token } = this.sdk;
74
+ async list(options: HistoryListOptions, request: ISdkRequestOptions = {}): Promise<IListResponse<IHttpHistory>> {
75
+ const token = request.token || this.sdk.token;
73
76
  const url = this.sdk.getUrl(RouteBuilder.history());
74
- this.sdk.appendListOptions(url, options);
77
+ this.appendHistoryListParameters(url, options);
75
78
  const result = await this.sdk.http.get(url.toString(), { token });
76
79
  this.inspectCommonStatusCodes(result.status);
77
80
  const E_PREFIX = 'Unable to list history. ';
@@ -82,7 +85,7 @@ export class HistorySdk extends SdkBase {
82
85
  if (!result.body) {
83
86
  throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
84
87
  }
85
- let data: IListResponse;
88
+ let data: IListResponse<IHttpHistory>;
86
89
  try {
87
90
  data = JSON.parse(result.body);
88
91
  } catch (e) {
@@ -94,24 +97,45 @@ export class HistorySdk extends SdkBase {
94
97
  return data;
95
98
  }
96
99
 
100
+ appendHistoryListParameters(url: URL, options: HistoryListOptions): void {
101
+ this.sdk.appendListOptions(url, options);
102
+ const { searchParams } = url;
103
+ if (options.type) {
104
+ searchParams.set('type', options.type);
105
+ }
106
+ const projectOptions = options as IHistoryRequestListOptions;
107
+ if (projectOptions.id) {
108
+ searchParams.set('id', projectOptions.id);
109
+ }
110
+ if (projectOptions.user) {
111
+ searchParams.set('user', 'true');
112
+ }
113
+ if (projectOptions.project) {
114
+ searchParams.set('project', projectOptions.project);
115
+ }
116
+ }
117
+
97
118
  /**
98
119
  * Deletes a history object form the store.
99
120
  *
100
121
  * @param key The key returned by the store when created the history. Also available via the `key` property on the history object.
122
+ * @param request Optional request options.
101
123
  */
102
- delete(key: string): Promise<void>;
124
+ delete(key: string, request?: ISdkRequestOptions): Promise<void>;
103
125
  /**
104
126
  * Deletes a list of history objects in a batch operation.
105
127
  *
106
128
  * @param keys The keys returned by the store when created the history. Also available via the `key` property on the history object.
129
+ * @param request Optional request options.
107
130
  */
108
- delete(keys: string[]): Promise<void>;
131
+ delete(keys: string[], request?: ISdkRequestOptions): Promise<void>;
109
132
  /**
110
133
  * Deletes a history or a list of history objects from the store.
111
134
  * @param key A key or a list of keys.
135
+ * @param request Optional request options.
112
136
  */
113
- async delete(key: string | string[]): Promise<void> {
114
- const { token } = this.sdk;
137
+ async delete(key: string | string[], request: ISdkRequestOptions = {}): Promise<void> {
138
+ const token = request.token || this.sdk.token;
115
139
  const isArray = Array.isArray(key);
116
140
  const path = isArray ? RouteBuilder.historyBatchDelete() : RouteBuilder.historyItem(key);
117
141
  const url = this.sdk.getUrl(path);
@@ -128,10 +152,11 @@ export class HistorySdk extends SdkBase {
128
152
  /**
129
153
  * Reads a history definition from the store.
130
154
  * @param key The history key
155
+ * @param request Optional request options.
131
156
  * @returns The history object
132
157
  */
133
- async read(key: string): Promise<IHttpHistory> {
134
- const { token } = this.sdk;
158
+ async read(key: string, request: ISdkRequestOptions = {}): Promise<IHttpHistory> {
159
+ const token = request.token || this.sdk.token;
135
160
  const url = this.sdk.getUrl(RouteBuilder.historyItem(key));
136
161
  const result = await this.sdk.http.get(url.toString(), { token });
137
162
  this.inspectCommonStatusCodes(result.status);
@@ -51,6 +51,11 @@ export abstract class Sdk {
51
51
  */
52
52
  shared = new SharedSdk(this);
53
53
 
54
+ /**
55
+ * When set it limits log output to minimum.
56
+ */
57
+ silent = false;
58
+
54
59
 
55
60
  [baseUriSymbol] = '';
56
61
 
@@ -1,16 +1,20 @@
1
1
  import { Headers } from '../../lib/headers/Headers.js';
2
2
  import { Sdk } from './Sdk.js';
3
+ import { SdkError, IApiError } from './Errors.js';
3
4
 
4
- export interface IStoreRequestOptions {
5
- method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';
6
- headers?: Record<string, string>,
7
- body?: string | Buffer;
5
+ export interface ISdkRequestOptions {
8
6
  /**
9
- * Adds the token to the headers.
7
+ * Uses the provided token for authentication.
10
8
  */
11
9
  token?: string;
12
10
  }
13
11
 
12
+ export interface IStoreRequestOptions extends ISdkRequestOptions {
13
+ method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';
14
+ headers?: Record<string, string>,
15
+ body?: string | Buffer;
16
+ }
17
+
14
18
  export interface IStoreResponse {
15
19
  status: number;
16
20
  headers: Headers;
@@ -42,6 +46,9 @@ export class SdkBase {
42
46
  constructor(public sdk: Sdk) {}
43
47
 
44
48
  protected logInvalidResponse(response: IStoreResponse): void {
49
+ if (this.sdk.silent) {
50
+ return;
51
+ }
45
52
  if (response.body) {
46
53
  try {
47
54
  const data = JSON.parse(response.body);
@@ -58,15 +65,62 @@ export class SdkBase {
58
65
  * Throws unified message for a common error status codes.
59
66
  * It handles 404, 403, and 401 status codes.
60
67
  */
61
- protected inspectCommonStatusCodes(status: number): void {
68
+ protected inspectCommonStatusCodes(status: number, body?: string): void {
62
69
  if (status === 404) {
63
- throw new Error(`Not found.`);
70
+ let e = this.createGenericSdkError(body)
71
+ if (!e) {
72
+ e = new SdkError(`Not found.`, 400);
73
+ e.response = body;
74
+ }
75
+ throw e;
64
76
  }
65
77
  if (status === 403) {
66
- throw new Error(`You have no access to this resource.`);
78
+ let e = this.createGenericSdkError(body)
79
+ if (!e) {
80
+ e = new SdkError(`You have no access to this resource.`, 403);
81
+ e.response = body;
82
+ }
83
+ throw e;
67
84
  }
68
85
  if (status === 401) {
69
- throw new Error(`Not authorized.`);
86
+ let e = this.createGenericSdkError(body)
87
+ if (!e) {
88
+ e = new SdkError(`Not authorized.`, 401);
89
+ e.response = body;
90
+ }
91
+ throw e;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Reads the response as ApiError
97
+ * @param body The message returned by the store.
98
+ * @returns The error schema or undefined when not an error;
99
+ */
100
+ protected readErrorResponse(body?: string): IApiError | undefined {
101
+ if (!body) {
102
+ return undefined;
103
+ }
104
+ let data: any;
105
+ try {
106
+ data = JSON.parse(body);
107
+ } catch (e) {
108
+ return undefined;
109
+ }
110
+ if (data.error && data.message) {
111
+ return data as IApiError;
112
+ }
113
+ return undefined;
114
+ }
115
+
116
+ protected createGenericSdkError(body?: string): SdkError | undefined {
117
+ const info = this.readErrorResponse(body);
118
+ if (!info) {
119
+ return undefined;
70
120
  }
121
+ const e = new SdkError(info.message, info.code);
122
+ e.detail = info.detail;
123
+ e.response = body;
124
+ return e;
71
125
  }
72
126
  }
@@ -1,34 +1,51 @@
1
- import { SdkBase, E_RESPONSE_STATUS, E_RESPONSE_NO_VALUE, E_INVALID_JSON, E_RESPONSE_UNKNOWN } from './SdkBase.js';
1
+ import { SdkBase, E_RESPONSE_STATUS, E_RESPONSE_NO_VALUE, E_INVALID_JSON, E_RESPONSE_UNKNOWN, ISdkRequestOptions } from './SdkBase.js';
2
2
  import { RouteBuilder } from './RouteBuilder.js';
3
3
  import { IListOptions, IListResponse } from '../../models/Backend.js';
4
+ import { Kind as ProjectKind } from '../../models/Project.js';
5
+ import { Kind as WorkspaceKind } from '../../models/Workspace.js';
6
+ import { IFile } from '../../models/store/File.js';
7
+ import { SdkError } from './Errors.js';
4
8
 
5
9
  export class SharedSdk extends SdkBase {
6
10
  /**
7
11
  * Lists shared with the user spaces.
12
+ *
13
+ * @param kinds the list of kinds to list. Spaces are always included.
8
14
  * @param options Optional query options.
15
+ * @param request Optional request options.
9
16
  */
10
- async list(options?: IListOptions): Promise<IListResponse> {
11
- const { token } = this.sdk;
17
+ async list(kinds: (typeof ProjectKind | typeof WorkspaceKind)[], options?: IListOptions, request: ISdkRequestOptions = {}): Promise<IListResponse<IFile>> {
18
+ const token = request.token || this.sdk.token;
12
19
  const url = this.sdk.getUrl(RouteBuilder.shared());
13
20
  this.sdk.appendListOptions(url, options);
21
+ kinds.forEach(k => url.searchParams.append('kind', k));
14
22
  const result = await this.sdk.http.get(url.toString(), { token });
15
- this.inspectCommonStatusCodes(result.status);
23
+ this.inspectCommonStatusCodes(result.status, result.body);
16
24
  const E_PREFIX = 'Unable to list spaces. ';
17
25
  if (result.status !== 200) {
18
26
  this.logInvalidResponse(result);
19
- throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
27
+ let e = this.createGenericSdkError(result.body)
28
+ if (!e) {
29
+ e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
30
+ e.response = result.body;
31
+ }
32
+ throw e;
20
33
  }
21
34
  if (!result.body) {
22
- throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
35
+ throw new SdkError(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, 0);
23
36
  }
24
- let data: IListResponse;
37
+ let data: IListResponse<IFile>;
25
38
  try {
26
39
  data = JSON.parse(result.body);
27
40
  } catch (e) {
28
- throw new Error(`${E_PREFIX}${E_INVALID_JSON}.`);
41
+ const err = new SdkError(`${E_PREFIX}${E_INVALID_JSON}.`, 0);
42
+ err.response = result.body;
43
+ throw err;
29
44
  }
30
45
  if (!Array.isArray(data.data)) {
31
- throw new Error(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`);
46
+ const err = new SdkError(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`, 0);
47
+ err.response = result.body;
48
+ throw err;
32
49
  }
33
50
  return data;
34
51
  }
@@ -5,7 +5,7 @@ import { Http } from './Http.js';
5
5
  import { WsClient } from './WsClient.js';
6
6
 
7
7
  export { IStoreTokenInfo, IStoreResponse, IStoreRequestOptions } from './SdkBase.js';
8
- export { IFileCreateOptions as ISpaceCreateOptions } from './FilesSdk.js';
8
+ export { IFileCreateOptions } from './FilesSdk.js';
9
9
 
10
10
  /**
11
11
  * NodeJS API for API Client's net-store module.