@api-client/core 0.9.11 → 0.9.13
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 +2 -2
- package/build/browser.js +1 -0
- package/build/browser.js.map +1 -1
- package/build/index.d.ts +2 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/src/models/TrashEntry.d.ts +19 -0
- package/build/src/runtime/store/ProjectExecutionsSdk.d.ts +55 -0
- package/build/src/runtime/store/ProjectExecutionsSdk.js +114 -0
- package/build/src/runtime/store/ProjectExecutionsSdk.js.map +1 -0
- package/build/src/runtime/store/RouteBuilder.d.ts +8 -2
- package/build/src/runtime/store/RouteBuilder.js +23 -4
- package/build/src/runtime/store/RouteBuilder.js.map +1 -1
- package/build/src/runtime/store/Sdk.d.ts +2 -0
- package/build/src/runtime/store/Sdk.js +2 -0
- package/build/src/runtime/store/Sdk.js.map +1 -1
- package/build/src/runtime/store/SdkBase.d.ts +20 -0
- package/build/src/runtime/store/SdkBase.js +114 -0
- package/build/src/runtime/store/SdkBase.js.map +1 -1
- package/build/src/runtime/store/TrashSdk.d.ts +12 -2
- package/build/src/runtime/store/TrashSdk.js +47 -16
- package/build/src/runtime/store/TrashSdk.js.map +1 -1
- package/build/src/runtime/store/interfaces/ApiClientStore.d.ts +2 -2
- package/build/src/runtime/store/interfaces/{ProjectRuns.d.ts → ProjectExecutions.d.ts} +1 -1
- package/build/src/runtime/store/interfaces/ProjectExecutions.js +2 -0
- package/build/src/runtime/store/interfaces/ProjectExecutions.js.map +1 -0
- package/build/src/runtime/store/interfaces/Trash.d.ts +17 -5
- package/package.json +1 -1
- package/src/models/TrashEntry.ts +20 -0
- package/src/runtime/store/ProjectExecutionsSdk.ts +122 -0
- package/src/runtime/store/RouteBuilder.ts +29 -4
- package/src/runtime/store/Sdk.ts +3 -0
- package/src/runtime/store/SdkBase.ts +123 -0
- package/src/runtime/store/TrashSdk.ts +63 -18
- package/src/runtime/store/interfaces/ApiClientStore.ts +2 -2
- package/src/runtime/store/interfaces/{ProjectRuns.ts → ProjectExecutions.ts} +1 -1
- package/src/runtime/store/interfaces/Trash.ts +20 -5
- package/build/src/runtime/store/interfaces/ProjectRuns.js +0 -2
- package/build/src/runtime/store/interfaces/ProjectRuns.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SdkBase, ISdkRequestOptions } from './SdkBase.js';
|
|
2
|
-
import { ContextChangeRecord, ContextListResult, ContextSpaceListOptions } from '../../events/BaseEvents.js';
|
|
2
|
+
import { ContextChangeRecord, ContextDeleteRecord, ContextListResult, ContextSpaceListOptions, IBulkOperationResult } from '../../events/BaseEvents.js';
|
|
3
3
|
import { IFile } from '../../models/store/File.js';
|
|
4
4
|
import { TrashEntry, TrashEntryCreate } from '../../models/TrashEntry.js';
|
|
5
5
|
export declare class TrashSdk extends SdkBase {
|
|
@@ -16,10 +16,19 @@ export declare class TrashSdk extends SdkBase {
|
|
|
16
16
|
*/
|
|
17
17
|
list(options: ContextSpaceListOptions, request?: ISdkRequestOptions): Promise<ContextListResult<TrashEntry>>;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* Permanently deletes a file.
|
|
20
|
+
*
|
|
20
21
|
* @param key The key of the deleted object
|
|
21
22
|
*/
|
|
22
23
|
delete(key: string, request?: ISdkRequestOptions): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Permanently deletes a number of files in a batch operation.
|
|
26
|
+
*
|
|
27
|
+
* @param keys The list of trash entry keys to delete.
|
|
28
|
+
* @param request Optional request options.
|
|
29
|
+
* @returns The list of delete records.
|
|
30
|
+
*/
|
|
31
|
+
batchDelete(keys: string[], request?: ISdkRequestOptions): Promise<IBulkOperationResult<ContextDeleteRecord>>;
|
|
23
32
|
/**
|
|
24
33
|
* Restores a file from the trash.
|
|
25
34
|
* It deletes a trash entry and updates the `file` object.
|
|
@@ -27,6 +36,7 @@ export declare class TrashSdk extends SdkBase {
|
|
|
27
36
|
* @param key The key of the file to restore
|
|
28
37
|
*/
|
|
29
38
|
restore(key: string, request?: ISdkRequestOptions): Promise<ContextChangeRecord<IFile>>;
|
|
39
|
+
batchRestore(keys: string[], request?: ISdkRequestOptions): Promise<IBulkOperationResult<ContextChangeRecord<IFile>>>;
|
|
30
40
|
/**
|
|
31
41
|
* Empties the trash for the given space.
|
|
32
42
|
* @param space The space key to remove trash for.
|
|
@@ -76,24 +76,25 @@ export class TrashSdk extends SdkBase {
|
|
|
76
76
|
return data;
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
|
-
*
|
|
79
|
+
* Permanently deletes a file.
|
|
80
|
+
*
|
|
80
81
|
* @param key The key of the deleted object
|
|
81
82
|
*/
|
|
82
83
|
async delete(key, request = {}) {
|
|
83
|
-
const token = request.token || this.sdk.token;
|
|
84
84
|
const url = this.sdk.getUrl(RouteBuilder.trashItem(key));
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
return this.genericDelete(url, request);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Permanently deletes a number of files in a batch operation.
|
|
89
|
+
*
|
|
90
|
+
* @param keys The list of trash entry keys to delete.
|
|
91
|
+
* @param request Optional request options.
|
|
92
|
+
* @returns The list of delete records.
|
|
93
|
+
*/
|
|
94
|
+
async batchDelete(keys, request = {}) {
|
|
95
|
+
const path = RouteBuilder.trashBatchDelete();
|
|
96
|
+
const url = this.sdk.getUrl(path);
|
|
97
|
+
return this.genericBatchDelete(url, keys, request);
|
|
97
98
|
}
|
|
98
99
|
/**
|
|
99
100
|
* Restores a file from the trash.
|
|
@@ -102,12 +103,12 @@ export class TrashSdk extends SdkBase {
|
|
|
102
103
|
* @param key The key of the file to restore
|
|
103
104
|
*/
|
|
104
105
|
async restore(key, request = {}) {
|
|
105
|
-
const token = request.token || this.sdk.token;
|
|
106
106
|
const url = this.sdk.getUrl(RouteBuilder.trashRestore(key));
|
|
107
|
+
const token = request.token || this.sdk.token;
|
|
107
108
|
const result = await this.sdk.http.put(url.toString(), { token });
|
|
108
109
|
this.inspectCommonStatusCodes(result);
|
|
109
110
|
const E_PREFIX = 'Unable to restore from trash. ';
|
|
110
|
-
if (result.status !==
|
|
111
|
+
if (result.status !== 200) {
|
|
111
112
|
this.logInvalidResponse(result);
|
|
112
113
|
let e = this.createGenericSdkError(result.body);
|
|
113
114
|
if (!e) {
|
|
@@ -131,6 +132,36 @@ export class TrashSdk extends SdkBase {
|
|
|
131
132
|
}
|
|
132
133
|
return data;
|
|
133
134
|
}
|
|
135
|
+
async batchRestore(keys, request = {}) {
|
|
136
|
+
const url = this.sdk.getUrl(RouteBuilder.trashBatchRestore());
|
|
137
|
+
const token = request.token || this.sdk.token;
|
|
138
|
+
const result = await this.sdk.http.post(url.toString(), { token, body: JSON.stringify(keys) });
|
|
139
|
+
this.inspectCommonStatusCodes(result);
|
|
140
|
+
const E_PREFIX = 'Unable to restore from trash. ';
|
|
141
|
+
if (result.status !== 200) {
|
|
142
|
+
this.logInvalidResponse(result);
|
|
143
|
+
let e = this.createGenericSdkError(result.body);
|
|
144
|
+
if (!e) {
|
|
145
|
+
e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
|
|
146
|
+
e.response = result.body;
|
|
147
|
+
}
|
|
148
|
+
throw e;
|
|
149
|
+
}
|
|
150
|
+
if (!result.body) {
|
|
151
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
|
|
152
|
+
}
|
|
153
|
+
let data;
|
|
154
|
+
try {
|
|
155
|
+
data = JSON.parse(result.body);
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
throw new Error(`${E_PREFIX}${E_INVALID_JSON}.`);
|
|
159
|
+
}
|
|
160
|
+
if (!Array.isArray(data.items)) {
|
|
161
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`);
|
|
162
|
+
}
|
|
163
|
+
return data;
|
|
164
|
+
}
|
|
134
165
|
/**
|
|
135
166
|
* Empties the trash for the given space.
|
|
136
167
|
* @param space The space key to remove trash for.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrashSdk.js","sourceRoot":"","sources":["../../../../src/runtime/store/TrashSdk.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"TrashSdk.js","sourceRoot":"","sources":["../../../../src/runtime/store/TrashSdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { Certificates } from "./Certificates.js";
|
|
|
2
2
|
import { Files } from "./Files.js";
|
|
3
3
|
import { History } from "./History.js";
|
|
4
4
|
import { Media } from "./Media.js";
|
|
5
|
-
import {
|
|
5
|
+
import { ProjectExecutions } from "./ProjectExecutions.js";
|
|
6
6
|
import { Revisions } from "./Revisions.js";
|
|
7
7
|
import { Spaces } from "./Spaces.js";
|
|
8
8
|
import { Trash } from "./Trash.js";
|
|
@@ -28,5 +28,5 @@ export interface ApiClientStore {
|
|
|
28
28
|
revisions: Revisions;
|
|
29
29
|
media: Media;
|
|
30
30
|
files: Files;
|
|
31
|
-
|
|
31
|
+
projectExecutions: ProjectExecutions;
|
|
32
32
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectExecutions.js","sourceRoot":"","sources":["../../../../../src/runtime/store/interfaces/ProjectExecutions.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IFile } from "../../../models/store/File.js";
|
|
2
|
-
import { ContextChangeRecord, ContextListResult, ContextSpaceListOptions } from "../../../events/BaseEvents.js";
|
|
2
|
+
import { ContextChangeRecord, ContextDeleteRecord, ContextListResult, ContextSpaceListOptions, IBulkOperationResult } from "../../../events/BaseEvents.js";
|
|
3
3
|
import { TrashEntry, TrashEntryCreate } from "../../../models/TrashEntry.js";
|
|
4
4
|
/**
|
|
5
5
|
* A store for the file trash.
|
|
@@ -19,17 +19,29 @@ export interface Trash {
|
|
|
19
19
|
*/
|
|
20
20
|
list(options: ContextSpaceListOptions): Promise<ContextListResult<TrashEntry>>;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Permanently deletes a file.
|
|
23
|
+
*
|
|
23
24
|
* @param key The key of the deleted object
|
|
24
25
|
*/
|
|
25
|
-
delete(key: string): Promise<
|
|
26
|
+
delete(key: string): Promise<ContextDeleteRecord>;
|
|
27
|
+
/**
|
|
28
|
+
* Permanently deletes a number of files in a batch operation.
|
|
29
|
+
*
|
|
30
|
+
* @param keys The list of trash entry keys to delete.
|
|
31
|
+
*/
|
|
32
|
+
batchDelete(keys: string[]): Promise<IBulkOperationResult<ContextDeleteRecord>>;
|
|
26
33
|
/**
|
|
27
|
-
* Restores
|
|
28
|
-
* It deletes a trash entry and updates the `file` object.
|
|
34
|
+
* Restores trash entries permanently from the store.
|
|
29
35
|
*
|
|
30
36
|
* @param key The key of the file to restore
|
|
31
37
|
*/
|
|
32
38
|
restore(key: string): Promise<ContextChangeRecord<IFile>>;
|
|
39
|
+
/**
|
|
40
|
+
* Restores multiple files in a batch operation.
|
|
41
|
+
*
|
|
42
|
+
* @param keys The lit of trash keys to restore.
|
|
43
|
+
*/
|
|
44
|
+
batchRestore(keys: string[]): Promise<IBulkOperationResult<ContextChangeRecord<IFile>>>;
|
|
33
45
|
/**
|
|
34
46
|
* Empties the trash for the given space.
|
|
35
47
|
* @param space The space key to remove trash for.
|
package/package.json
CHANGED
package/src/models/TrashEntry.ts
CHANGED
|
@@ -17,6 +17,22 @@ export interface TrashEntryCreate {
|
|
|
17
17
|
name: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* The trash entry object capabilities for the current user.
|
|
22
|
+
* Note, this information has no effect on the backend and only tells the client application
|
|
23
|
+
* what operations on the file are permitted.
|
|
24
|
+
*/
|
|
25
|
+
export interface TrashCapabilities {
|
|
26
|
+
/**
|
|
27
|
+
* Whether the current user can restore the file.
|
|
28
|
+
*/
|
|
29
|
+
canRestore: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Whether the current user can permanently delete the file.
|
|
32
|
+
*/
|
|
33
|
+
canDelete: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
export interface TrashEntry extends TrashEntryCreate {
|
|
21
37
|
/**
|
|
22
38
|
* The key of the trash entry.
|
|
@@ -26,4 +42,8 @@ export interface TrashEntry extends TrashEntryCreate {
|
|
|
26
42
|
* The delete info.
|
|
27
43
|
*/
|
|
28
44
|
info: IDeletion;
|
|
45
|
+
/**
|
|
46
|
+
* Trash entry capabilities for the user.
|
|
47
|
+
*/
|
|
48
|
+
capabilities: TrashCapabilities;
|
|
29
49
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { SdkBase, E_RESPONSE_UNKNOWN, ISdkRequestOptions } from './SdkBase.js';
|
|
2
|
+
import { RouteBuilder } from './RouteBuilder.js';
|
|
3
|
+
import { ContextChangeRecord, ContextDeleteRecord, ContextListResult, IBulkOperationResult, IProjectExecutionListOptions } from '../../events/BaseEvents.js';
|
|
4
|
+
import { IProjectExecution, Kind as ProjectExecutionKind } from '../../models/ProjectExecution.js';
|
|
5
|
+
|
|
6
|
+
export class ProjectExecutionSdk extends SdkBase {
|
|
7
|
+
/**
|
|
8
|
+
* Adds an execution logs object to the store.
|
|
9
|
+
*
|
|
10
|
+
* @param history The history object
|
|
11
|
+
* @param space The parent space key
|
|
12
|
+
*/
|
|
13
|
+
async add(space: string, value: IProjectExecution, request: ISdkRequestOptions = {}): Promise<ContextChangeRecord<IProjectExecution>> {
|
|
14
|
+
const url = this.sdk.getUrl(RouteBuilder.projectExecutions());
|
|
15
|
+
url.searchParams.set('space', space);
|
|
16
|
+
const token = request.token || this.sdk.token;
|
|
17
|
+
const result = await this.sdk.http.post(url.toString(), { token, body: JSON.stringify(value) });
|
|
18
|
+
this.inspectCommonStatusCodes(result);
|
|
19
|
+
const E_PREFIX = 'Unable to create a project execution entity. ';
|
|
20
|
+
const data = this.readResponseJSON(result, E_PREFIX) as ContextChangeRecord<IProjectExecution>;
|
|
21
|
+
if (!data.key) {
|
|
22
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`);
|
|
23
|
+
}
|
|
24
|
+
return data;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Reads an execution logs item.
|
|
29
|
+
*
|
|
30
|
+
* @param key The key of the history object to read.
|
|
31
|
+
*/
|
|
32
|
+
async read(key: string, request: ISdkRequestOptions = {}): Promise<IProjectExecution> {
|
|
33
|
+
const url = this.sdk.getUrl(RouteBuilder.projectExecution(key));
|
|
34
|
+
const token = request.token || this.sdk.token;
|
|
35
|
+
const result = await this.sdk.http.get(url.toString(), { token });
|
|
36
|
+
this.inspectCommonStatusCodes(result);
|
|
37
|
+
const E_PREFIX = 'Unable to read a project execution entity. ';
|
|
38
|
+
const data = this.readResponseJSON(result, E_PREFIX) as IProjectExecution;
|
|
39
|
+
if (data.kind !== ProjectExecutionKind) {
|
|
40
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`);
|
|
41
|
+
}
|
|
42
|
+
return data;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Lists the execution logs data.
|
|
47
|
+
*
|
|
48
|
+
* @param key The id of the file to lists revisions for.
|
|
49
|
+
* @param options The list query options
|
|
50
|
+
*/
|
|
51
|
+
async list(options: IProjectExecutionListOptions, request: ISdkRequestOptions = {}): Promise<ContextListResult<IProjectExecution>> {
|
|
52
|
+
const url = this.sdk.getUrl(RouteBuilder.projectExecutions());
|
|
53
|
+
if (options.project) {
|
|
54
|
+
url.searchParams.set('project', options.project);
|
|
55
|
+
}
|
|
56
|
+
if (options.app) {
|
|
57
|
+
url.searchParams.set('app', options.app);
|
|
58
|
+
}
|
|
59
|
+
if (options.user) {
|
|
60
|
+
url.searchParams.set('user', options.user);
|
|
61
|
+
}
|
|
62
|
+
// the rest query params is set through the generic function.
|
|
63
|
+
const result = await this.genericList(url, options, request) as ContextListResult<IProjectExecution>;
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Marks the data as deleted.
|
|
69
|
+
*
|
|
70
|
+
* @param key The key of the object to delete.
|
|
71
|
+
*/
|
|
72
|
+
async delete(key: string, request: ISdkRequestOptions = {}): Promise<void> {
|
|
73
|
+
const url = this.sdk.getUrl(RouteBuilder.projectExecution(key));
|
|
74
|
+
return this.genericDelete(url, request);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Deletes a history in a bulk operation.
|
|
79
|
+
*
|
|
80
|
+
* @param keys The list of history keys to delete.
|
|
81
|
+
*/
|
|
82
|
+
async deleteBulk(keys: string[], request: ISdkRequestOptions = {}): Promise<IBulkOperationResult<ContextDeleteRecord>> {
|
|
83
|
+
const url = this.sdk.getUrl(RouteBuilder.projectExecutionBulkDelete());
|
|
84
|
+
return this.genericBatchDelete(url, keys, request);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Clears the datastore from history for a space.
|
|
89
|
+
*
|
|
90
|
+
* @param space The parent space key
|
|
91
|
+
*/
|
|
92
|
+
async clearSpace(space: string, request: ISdkRequestOptions = {}): Promise<void> {
|
|
93
|
+
const url = this.sdk.getUrl(RouteBuilder.projectExecutionClear('space'));
|
|
94
|
+
url.searchParams.set('space', space);
|
|
95
|
+
await this.genericDelete(url, request);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Clears all history from a project
|
|
100
|
+
*
|
|
101
|
+
* @param project The parent project key
|
|
102
|
+
*/
|
|
103
|
+
async clearProject(space: string, project: string, request: ISdkRequestOptions = {}): Promise<void> {
|
|
104
|
+
const url = this.sdk.getUrl(RouteBuilder.projectExecutionClear('project'));
|
|
105
|
+
url.searchParams.set('space', space);
|
|
106
|
+
url.searchParams.set('project', project);
|
|
107
|
+
await this.genericDelete(url, request);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Clears all history from a folder
|
|
112
|
+
*
|
|
113
|
+
* @param project The parent project key
|
|
114
|
+
*/
|
|
115
|
+
async clearParent(space: string, project: string, folder: string, request: ISdkRequestOptions = {}): Promise<void> {
|
|
116
|
+
const url = this.sdk.getUrl(RouteBuilder.projectExecutionClear('folder'));
|
|
117
|
+
url.searchParams.set('space', space);
|
|
118
|
+
url.searchParams.set('project', project);
|
|
119
|
+
url.searchParams.set('folder', folder);
|
|
120
|
+
await this.genericDelete(url, request);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -131,15 +131,40 @@ export class RouteBuilder {
|
|
|
131
131
|
return `/trash`
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
static trashItem(
|
|
135
|
-
|
|
134
|
+
static trashItem(trashKey: string): string {
|
|
135
|
+
// GET + DELETE (link to ./delete)
|
|
136
|
+
return `/trash/${trashKey}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static trashRestore(trashKey: string): string {
|
|
140
|
+
return `/trash/${trashKey}/restore`
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
static trashEmpty(space: string): string {
|
|
139
144
|
return `/trash/empty/${space}`
|
|
140
145
|
}
|
|
141
146
|
|
|
142
|
-
static
|
|
143
|
-
return `/trash/restore
|
|
147
|
+
static trashBatchRestore(): string {
|
|
148
|
+
return `/trash/batch/restore`
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static trashBatchDelete(): string {
|
|
152
|
+
return `/trash/batch/delete`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
static projectExecutions(): string {
|
|
156
|
+
return `/project/execution`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static projectExecution(key: string): string {
|
|
160
|
+
return `/project/execution/${key}`;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static projectExecutionBulkDelete(): string {
|
|
164
|
+
return `/project/execution/delete`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
static projectExecutionClear(scope: 'space' | 'project' | 'folder'): string {
|
|
168
|
+
return `/project/execution/clear/${scope}`;
|
|
144
169
|
}
|
|
145
170
|
}
|
package/src/runtime/store/Sdk.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { CertificatesSdk } from './CertificatesSdk.js';
|
|
|
11
11
|
import { RevisionsSdk } from './RevisionsSdk.js';
|
|
12
12
|
import { SpacesSdk } from './SpacesSdk.js';
|
|
13
13
|
import { TrashSdk } from './TrashSdk.js';
|
|
14
|
+
import { ProjectExecutionSdk } from './ProjectExecutionsSdk.js';
|
|
14
15
|
|
|
15
16
|
const baseUriSymbol = Symbol('baseUri');
|
|
16
17
|
|
|
@@ -63,6 +64,8 @@ export abstract class Sdk {
|
|
|
63
64
|
|
|
64
65
|
trash = new TrashSdk(this);
|
|
65
66
|
|
|
67
|
+
projectExecution = new ProjectExecutionSdk(this);
|
|
68
|
+
|
|
66
69
|
/**
|
|
67
70
|
* When set it limits log output to minimum.
|
|
68
71
|
*/
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
import { Headers } from '../../lib/headers/Headers.js';
|
|
3
3
|
import { Sdk } from './Sdk.js';
|
|
4
4
|
import { SdkError, IApiError } from './Errors.js';
|
|
5
|
+
import {
|
|
6
|
+
ContextDeleteRecord,
|
|
7
|
+
ContextListResult,
|
|
8
|
+
ContextSpaceListOptions,
|
|
9
|
+
IBulkOperationResult
|
|
10
|
+
} from '../../events/BaseEvents.js';
|
|
5
11
|
|
|
6
12
|
export interface ISdkRequestOptions {
|
|
7
13
|
/**
|
|
@@ -125,4 +131,121 @@ export class SdkBase {
|
|
|
125
131
|
e.response = body;
|
|
126
132
|
return e;
|
|
127
133
|
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A generic (common) method to batch-delete object from the store.
|
|
137
|
+
*
|
|
138
|
+
* @param url The URL object to make the request.
|
|
139
|
+
* @param keys The list of keys to delete
|
|
140
|
+
* @param request Optional request options.
|
|
141
|
+
* @returns THe list of context delete records.
|
|
142
|
+
*/
|
|
143
|
+
protected async genericBatchDelete(url: URL, keys: string[], request: ISdkRequestOptions = {}): Promise<IBulkOperationResult<ContextDeleteRecord>> {
|
|
144
|
+
const token = request.token || this.sdk.token;
|
|
145
|
+
const result = await this.sdk.http.post(url.toString(), { token, body: JSON.stringify(keys) });
|
|
146
|
+
this.inspectCommonStatusCodes(result);
|
|
147
|
+
const E_PREFIX = 'Unable to delete in batch. ';
|
|
148
|
+
if (result.status !== 200) {
|
|
149
|
+
this.logInvalidResponse(result);
|
|
150
|
+
let e = this.createGenericSdkError(result.body)
|
|
151
|
+
if (!e) {
|
|
152
|
+
e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
|
|
153
|
+
e.response = result.body;
|
|
154
|
+
}
|
|
155
|
+
throw e;
|
|
156
|
+
}
|
|
157
|
+
if (!result.body) {
|
|
158
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
let data: IBulkOperationResult<ContextDeleteRecord>;
|
|
162
|
+
try {
|
|
163
|
+
data = JSON.parse(result.body);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
throw new Error(`${E_PREFIX}${E_INVALID_JSON}.`);
|
|
166
|
+
}
|
|
167
|
+
if (!Array.isArray(data.items)) {
|
|
168
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`);
|
|
169
|
+
}
|
|
170
|
+
return data;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Generic (common) function to delete an entity in the store.
|
|
175
|
+
*
|
|
176
|
+
* @param url The URL to make the DELETE request to.
|
|
177
|
+
* @param request Optional request options.
|
|
178
|
+
*/
|
|
179
|
+
protected async genericDelete(url: URL, request: ISdkRequestOptions = {}): Promise<void> {
|
|
180
|
+
const token = request.token || this.sdk.token;
|
|
181
|
+
const result = await this.sdk.http.delete(url.toString(), { token });
|
|
182
|
+
this.inspectCommonStatusCodes(result);
|
|
183
|
+
const E_PREFIX = 'Unable to delete the object. ';
|
|
184
|
+
if (result.status !== 204) {
|
|
185
|
+
this.logInvalidResponse(result);
|
|
186
|
+
let e = this.createGenericSdkError(result.body)
|
|
187
|
+
if (!e) {
|
|
188
|
+
e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
|
|
189
|
+
e.response = result.body;
|
|
190
|
+
}
|
|
191
|
+
throw e;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
protected async genericList(url: URL, options: ContextSpaceListOptions, request: ISdkRequestOptions = {}): Promise<ContextListResult<unknown>> {
|
|
196
|
+
const token = request.token || this.sdk.token;
|
|
197
|
+
this.sdk.appendListOptions(url, options);
|
|
198
|
+
const result = await this.sdk.http.get(url.toString(), { token });
|
|
199
|
+
this.inspectCommonStatusCodes(result);
|
|
200
|
+
const E_PREFIX = 'Unable to list revisions for a file. ';
|
|
201
|
+
if (result.status !== 200) {
|
|
202
|
+
this.logInvalidResponse(result);
|
|
203
|
+
let e = this.createGenericSdkError(result.body)
|
|
204
|
+
if (!e) {
|
|
205
|
+
e = new SdkError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.status);
|
|
206
|
+
e.response = result.body;
|
|
207
|
+
}
|
|
208
|
+
throw e;
|
|
209
|
+
}
|
|
210
|
+
if (!result.body) {
|
|
211
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
|
|
212
|
+
}
|
|
213
|
+
let data: ContextListResult<unknown>;
|
|
214
|
+
try {
|
|
215
|
+
data = JSON.parse(result.body);
|
|
216
|
+
} catch (e) {
|
|
217
|
+
throw new Error(`${E_PREFIX}${E_INVALID_JSON}.`);
|
|
218
|
+
}
|
|
219
|
+
if (!Array.isArray(data.items)) {
|
|
220
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`);
|
|
221
|
+
}
|
|
222
|
+
return data;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
protected readResponseBody(response: IStoreResponse, errorPrefix: string): string {
|
|
226
|
+
if (response.status !== 200) {
|
|
227
|
+
this.logInvalidResponse(response);
|
|
228
|
+
let e = this.createGenericSdkError(response.body)
|
|
229
|
+
if (!e) {
|
|
230
|
+
e = new SdkError(`${errorPrefix}${E_RESPONSE_STATUS}${response.status}`, response.status);
|
|
231
|
+
e.response = response.body;
|
|
232
|
+
}
|
|
233
|
+
throw e;
|
|
234
|
+
}
|
|
235
|
+
if (!response.body) {
|
|
236
|
+
throw new Error(`${errorPrefix}${E_RESPONSE_NO_VALUE}`);
|
|
237
|
+
}
|
|
238
|
+
return response.body;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
protected readResponseJSON(response: IStoreResponse, errorPrefix: string): unknown {
|
|
242
|
+
const body = this.readResponseBody(response, errorPrefix);
|
|
243
|
+
let data: unknown;
|
|
244
|
+
try {
|
|
245
|
+
data = JSON.parse(body);
|
|
246
|
+
} catch (e) {
|
|
247
|
+
throw new Error(`${errorPrefix}${E_INVALID_JSON}.`);
|
|
248
|
+
}
|
|
249
|
+
return data;
|
|
250
|
+
}
|
|
128
251
|
}
|