@knime/hub-features 1.7.3 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @knime/hub-features
2
2
 
3
+ ## 1.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - add restoreVersion to versionsApi
8
+
9
+ ## 1.7.4
10
+
11
+ ### Patch Changes
12
+
13
+ - df25c75: switch to ofetch and improve error handling
14
+
3
15
  ## 1.7.3
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knime/hub-features",
3
- "version": "1.7.3",
3
+ "version": "1.8.0",
4
4
  "description": "Vue components & composables for shared hub features",
5
5
  "homepage": "https://knime.github.io/webapps-common/",
6
6
  "license": "GPL 3 and Additional Permissions according to Sec. 7 (SEE the file LICENSE)",
@@ -1,7 +1,6 @@
1
- /* global RequestInit */
2
- import { merge } from "lodash-es";
1
+ import { FetchError, type FetchOptions } from "ofetch";
3
2
 
4
- import type { HubAvatarData } from "@knime/hub-features";
3
+ import { type HubAvatarData, rfcErrors } from "@knime/hub-features";
5
4
  import { VERSION_DEFAULT_LIMIT } from "@knime/hub-features/versions";
6
5
  import type {
7
6
  AssignedLabel,
@@ -13,40 +12,47 @@ import type {
13
12
  WithLabels,
14
13
  } from "@knime/hub-features/versions";
15
14
 
15
+ import { DEFAULT_API_BASE_URL } from "../../common/constants";
16
+ import { getFetchClient } from "../../common/ofetchClient";
17
+
16
18
  type UseVersionsApiOptions = {
17
19
  baseUrl?: string;
20
+ customFetchClientOptions?: FetchOptions;
18
21
  };
19
22
 
20
- export const useVersionsApi = ({ baseUrl }: UseVersionsApiOptions) => {
21
- const doHubRequest = (path: string, requestOptions: RequestInit = {}) => {
22
- const res = `${baseUrl}${path}`;
23
- consola.trace(`useVersionsApi::fetching '${res}'`, requestOptions);
23
+ export const useVersionsApi = ({
24
+ baseUrl,
25
+ customFetchClientOptions,
26
+ }: UseVersionsApiOptions) => {
27
+ const $ofetch = getFetchClient(customFetchClientOptions);
24
28
 
25
- const defaults = {
29
+ const doHubRequest = (path: string, fetchOptions?: FetchOptions) => {
30
+ const res = `${baseUrl ?? DEFAULT_API_BASE_URL}${path}`;
31
+ const defaults: FetchOptions = {
26
32
  method: "GET",
27
33
  };
28
- return fetch(res, {
29
- ...defaults,
30
- ...requestOptions,
31
- });
32
- };
33
34
 
34
- const doHubRequestJson = async (
35
- path: string,
36
- requestOptions: RequestInit = {},
37
- ) => {
38
- merge(requestOptions, {
39
- headers: { "Content-Type": "application/json" as const },
40
- });
41
- const response = await doHubRequest(path, requestOptions);
42
- return response.json();
35
+ try {
36
+ consola.trace("useVersionsApi::calling", {
37
+ path: res,
38
+ options: fetchOptions,
39
+ });
40
+
41
+ return $ofetch(res, {
42
+ ...defaults,
43
+ ...fetchOptions,
44
+ });
45
+ } catch (error) {
46
+ if (error instanceof FetchError) {
47
+ throw rfcErrors.tryParse(error);
48
+ }
49
+
50
+ throw error;
51
+ }
43
52
  };
44
53
 
45
54
  const fetchRepositoryItem = ({ itemId }: { itemId: string }) => {
46
- return doHubRequestJson(
47
- `/repository/${itemId}`,
48
- {},
49
- ) as Promise<RepositoryItem>;
55
+ return doHubRequest(`/repository/${itemId}`) as Promise<RepositoryItem>;
50
56
  };
51
57
 
52
58
  const fetchVersions = ({
@@ -62,7 +68,7 @@ export const useVersionsApi = ({ baseUrl }: UseVersionsApiOptions) => {
62
68
  path += "?limit=-1";
63
69
  }
64
70
 
65
- return doHubRequestJson(path) as Promise<{
71
+ return doHubRequest(path) as Promise<{
66
72
  totalCount: number;
67
73
  versions: Array<NamedItemVersion>;
68
74
  }>;
@@ -75,36 +81,50 @@ export const useVersionsApi = ({ baseUrl }: UseVersionsApiOptions) => {
75
81
  resourceType: "savepoint";
76
82
  resourceId: string;
77
83
  }) => {
78
- return doHubRequestJson(
84
+ return doHubRequest(
79
85
  `/validation/validation/resources/${resourceType}/${resourceId}/labels`,
80
- {},
81
86
  ).catch(() => ({ assignedLabels: [] })) as Promise<{
82
87
  assignedLabels: Array<AssignedLabel>;
83
88
  }>;
84
89
  };
85
90
 
86
91
  const deleteVersion = ({
87
- projectItemId,
92
+ itemId,
88
93
  version,
89
94
  }: {
90
- projectItemId: string;
95
+ itemId: string;
91
96
  version: NamedItemVersion["version"];
92
97
  }) => {
93
- return doHubRequest(`/repository/${projectItemId}/versions/${version}`, {
98
+ return doHubRequest(`/repository/${itemId}/versions/${version}`, {
94
99
  method: "DELETE",
95
100
  });
96
101
  };
97
102
 
103
+ const restoreVersion = ({
104
+ itemId,
105
+ version,
106
+ }: {
107
+ itemId: string;
108
+ version: NamedItemVersion["version"];
109
+ }) => {
110
+ return doHubRequest(
111
+ `/repository/${itemId}/workingArea?fromVersion=${version}`,
112
+ {
113
+ method: "POST",
114
+ },
115
+ );
116
+ };
117
+
98
118
  const createVersion = ({
99
- projectItemId,
119
+ itemId,
100
120
  title,
101
121
  description,
102
122
  }: {
103
- projectItemId: string;
123
+ itemId: string;
104
124
  title: string;
105
125
  description: string;
106
126
  }): Promise<NamedItemVersion> => {
107
- return doHubRequestJson(`/repository/${projectItemId}/versions`, {
127
+ return doHubRequest(`/repository/${itemId}/versions`, {
108
128
  method: "POST",
109
129
  body: JSON.stringify({
110
130
  title,
@@ -118,14 +138,11 @@ export const useVersionsApi = ({ baseUrl }: UseVersionsApiOptions) => {
118
138
  }: {
119
139
  accountName: string;
120
140
  }): Promise<HubAvatarData> => {
121
- const accountInfo = await doHubRequestJson(
122
- `/accounts/name/${accountName}`,
123
- {
124
- headers: {
125
- Prefer: "representation=minimal",
126
- },
141
+ const accountInfo = await doHubRequest(`/accounts/name/${accountName}`, {
142
+ headers: {
143
+ Prefer: "representation=minimal",
127
144
  },
128
- );
145
+ });
129
146
 
130
147
  return {
131
148
  kind: accountInfo.type === "TEAM" ? "group" : "account",
@@ -134,7 +151,7 @@ export const useVersionsApi = ({ baseUrl }: UseVersionsApiOptions) => {
134
151
  url: accountInfo.avatarUrl,
135
152
  altText: `${accountInfo.realName ?? accountInfo.name} profile image`,
136
153
  },
137
- } satisfies HubAvatarData;
154
+ };
138
155
  };
139
156
 
140
157
  const loadSavepointMetadata = async (
@@ -160,7 +177,7 @@ export const useVersionsApi = ({ baseUrl }: UseVersionsApiOptions) => {
160
177
  itemId: string;
161
178
  limit?: number;
162
179
  }) => {
163
- return doHubRequestJson(
180
+ return doHubRequest(
164
181
  `/repository/${itemId}/savepoints?limit=${
165
182
  limit ?? VERSION_DEFAULT_LIMIT
166
183
  }`,
@@ -200,6 +217,7 @@ export const useVersionsApi = ({ baseUrl }: UseVersionsApiOptions) => {
200
217
  fetchPermissions,
201
218
  loadSavepointMetadata,
202
219
  deleteVersion,
220
+ restoreVersion,
203
221
  createVersion,
204
222
  getAvatar,
205
223
  };
@@ -43,7 +43,7 @@ type UseFileUploadOptions = {
43
43
  * It is a multi-step process which is described as follows:
44
44
  *
45
45
  * Step 1:
46
- * First we need to prepare an upload. The items will will be uploaded to a `parent` container
46
+ * First we need to prepare an upload. The items will be uploaded to a `parent` container
47
47
  * identified by its id. Then, for each file we want to upload, we must provide paths relative
48
48
  * to the parent that identify each file. Example:
49
49
  * ```