@knime/hub-features 1.10.3 → 1.10.5
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,18 @@
|
|
|
1
1
|
# @knime/hub-features
|
|
2
2
|
|
|
3
|
+
## 1.10.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 805588d: update async download flow in useDownloadArtifact to reflect api changes
|
|
8
|
+
|
|
9
|
+
## 1.10.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- cd0f5f0: Fix baseURL handling on ofetch client used by the upload, download and versions features.
|
|
14
|
+
Supplying a custom baseURL with trailing slashes now doesn't break these features
|
|
15
|
+
|
|
3
16
|
## 1.10.3
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knime/hub-features",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.5",
|
|
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,6 +1,8 @@
|
|
|
1
1
|
import { merge } from "lodash-es";
|
|
2
2
|
import { type FetchOptions, ofetch } from "ofetch";
|
|
3
3
|
|
|
4
|
+
import { DEFAULT_API_BASE_URL } from "./constants";
|
|
5
|
+
|
|
4
6
|
export const defaultConfig: FetchOptions = {
|
|
5
7
|
headers: {
|
|
6
8
|
"Content-Type": "application/json",
|
|
@@ -10,5 +12,11 @@ export const defaultConfig: FetchOptions = {
|
|
|
10
12
|
},
|
|
11
13
|
} as const;
|
|
12
14
|
|
|
13
|
-
export const getFetchClient = (customOptions?: FetchOptions) =>
|
|
14
|
-
|
|
15
|
+
export const getFetchClient = (customOptions?: FetchOptions) => {
|
|
16
|
+
const { baseURL = DEFAULT_API_BASE_URL, ...otherCustomOptions } =
|
|
17
|
+
customOptions ?? {};
|
|
18
|
+
|
|
19
|
+
return ofetch.create(
|
|
20
|
+
merge({ baseURL, ...otherCustomOptions }, defaultConfig),
|
|
21
|
+
);
|
|
22
|
+
};
|
|
@@ -12,7 +12,6 @@ import type {
|
|
|
12
12
|
WithLabels,
|
|
13
13
|
} from "@knime/hub-features/versions";
|
|
14
14
|
|
|
15
|
-
import { DEFAULT_API_BASE_URL } from "../../common/constants";
|
|
16
15
|
import { getFetchClient } from "../../common/ofetchClient";
|
|
17
16
|
|
|
18
17
|
type UseVersionsApiOptions = {
|
|
@@ -22,10 +21,7 @@ type UseVersionsApiOptions = {
|
|
|
22
21
|
export const useVersionsApi = ({
|
|
23
22
|
customFetchClientOptions,
|
|
24
23
|
}: UseVersionsApiOptions) => {
|
|
25
|
-
const
|
|
26
|
-
customFetchClientOptions ?? {};
|
|
27
|
-
|
|
28
|
-
const $ofetch = getFetchClient({ baseURL, ...otherCustomOptions });
|
|
24
|
+
const $ofetch = getFetchClient(customFetchClientOptions);
|
|
29
25
|
|
|
30
26
|
const doHubRequest = (path: string, fetchOptions?: FetchOptions) => {
|
|
31
27
|
const defaults: FetchOptions = {
|
|
@@ -4,7 +4,6 @@ import { FetchError, type FetchOptions } from "ofetch";
|
|
|
4
4
|
import type { DownloadItem as DownloadItemExternal } from "@knime/components";
|
|
5
5
|
import { sleep } from "@knime/utils";
|
|
6
6
|
|
|
7
|
-
import { DEFAULT_API_BASE_URL } from "../common/constants";
|
|
8
7
|
import { getFetchClient } from "../common/ofetchClient";
|
|
9
8
|
import { rfcErrors } from "../rfcErrors";
|
|
10
9
|
|
|
@@ -19,8 +18,20 @@ type ArtifactStatusResponse = {
|
|
|
19
18
|
downloadUrl?: string;
|
|
20
19
|
};
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
// Initial request can have either download url (if it can be downloaded immediately) or download id (to poll for the status)
|
|
22
|
+
type RequestDownloadResponse =
|
|
23
|
+
| {
|
|
24
|
+
downloadId: string;
|
|
25
|
+
}
|
|
26
|
+
| {
|
|
27
|
+
downloadUrl: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// type guard
|
|
31
|
+
const hasDownloadUrl = (
|
|
32
|
+
response: RequestDownloadResponse,
|
|
33
|
+
): response is { downloadUrl: string } => {
|
|
34
|
+
return "downloadUrl" in response;
|
|
24
35
|
};
|
|
25
36
|
|
|
26
37
|
/**
|
|
@@ -80,13 +91,11 @@ const isAbortError = (error: unknown) =>
|
|
|
80
91
|
export const useDownloadArtifact = (
|
|
81
92
|
options: UseDownloadArtifactOptions = {},
|
|
82
93
|
) => {
|
|
94
|
+
const $ofetch = getFetchClient(options.customFetchClientOptions);
|
|
95
|
+
|
|
83
96
|
const downloadItems = ref<Record<string, DownloadItem>>({});
|
|
84
97
|
const abortControllers: Record<string, AbortController> = {};
|
|
85
98
|
|
|
86
|
-
const $ofetch = getFetchClient(options.customFetchClientOptions);
|
|
87
|
-
const baseUrl =
|
|
88
|
-
options.customFetchClientOptions?.baseURL ?? DEFAULT_API_BASE_URL;
|
|
89
|
-
|
|
90
99
|
// Use fallback values if none are provided
|
|
91
100
|
const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
92
101
|
const pollingInterval = options.pollingInterval ?? DEFAULT_POLLING_INTERVAL;
|
|
@@ -111,13 +120,10 @@ export const useDownloadArtifact = (
|
|
|
111
120
|
downloadId: string;
|
|
112
121
|
signal?: AbortSignal;
|
|
113
122
|
}) => {
|
|
114
|
-
return $ofetch<ArtifactStatusResponse>(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
signal,
|
|
119
|
-
},
|
|
120
|
-
);
|
|
123
|
+
return $ofetch<ArtifactStatusResponse>(`/downloads/${downloadId}/status`, {
|
|
124
|
+
method: "GET",
|
|
125
|
+
signal,
|
|
126
|
+
});
|
|
121
127
|
};
|
|
122
128
|
|
|
123
129
|
const openDownload = (downloadUrl: string) => {
|
|
@@ -255,30 +261,26 @@ export const useDownloadArtifact = (
|
|
|
255
261
|
}) => {
|
|
256
262
|
try {
|
|
257
263
|
const response = await $ofetch<RequestDownloadResponse>(
|
|
258
|
-
|
|
264
|
+
`/repository/${itemId}/artifact`,
|
|
259
265
|
{
|
|
260
266
|
method: "GET",
|
|
261
267
|
query: { version },
|
|
262
268
|
},
|
|
263
269
|
);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
// download is ready immediately, no polling needed
|
|
270
|
-
downloadStatusResponse?.status === "READY" &&
|
|
271
|
-
downloadStatusResponse?.downloadUrl
|
|
272
|
-
) {
|
|
273
|
-
openDownload(downloadStatusResponse.downloadUrl);
|
|
274
|
-
} else {
|
|
275
|
-
await pollDownloadItem({
|
|
276
|
-
itemId,
|
|
277
|
-
version,
|
|
278
|
-
downloadId,
|
|
279
|
-
name,
|
|
280
|
-
});
|
|
270
|
+
|
|
271
|
+
// if download is ready, open url immediately
|
|
272
|
+
if (hasDownloadUrl(response)) {
|
|
273
|
+
openDownload(response.downloadUrl);
|
|
274
|
+
return;
|
|
281
275
|
}
|
|
276
|
+
|
|
277
|
+
// otherwise start polling download status
|
|
278
|
+
await pollDownloadItem({
|
|
279
|
+
itemId,
|
|
280
|
+
version,
|
|
281
|
+
downloadId: response.downloadId,
|
|
282
|
+
name,
|
|
283
|
+
});
|
|
282
284
|
} catch (error: unknown) {
|
|
283
285
|
// here only errors thrown by the initial requests are caught;
|
|
284
286
|
// errors occurring while polling will be handled in pollDownloadItem
|
|
@@ -4,7 +4,6 @@ import { FetchError, type FetchOptions } from "ofetch";
|
|
|
4
4
|
import { useUploadManager } from "@knime/components";
|
|
5
5
|
import { getFileMimeType, knimeFileFormats, promise } from "@knime/utils";
|
|
6
6
|
|
|
7
|
-
import { DEFAULT_API_BASE_URL } from "../common/constants";
|
|
8
7
|
import { getFetchClient } from "../common/ofetchClient";
|
|
9
8
|
import { rfcErrors } from "../rfcErrors";
|
|
10
9
|
|
|
@@ -108,8 +107,6 @@ type UseFileUploadOptions = {
|
|
|
108
107
|
* ```
|
|
109
108
|
*/
|
|
110
109
|
export const useFileUpload = (options: UseFileUploadOptions = {}) => {
|
|
111
|
-
const baseUrl =
|
|
112
|
-
options.customFetchClientOptions?.baseURL ?? DEFAULT_API_BASE_URL;
|
|
113
110
|
const $ofetch = getFetchClient(options.customFetchClientOptions);
|
|
114
111
|
|
|
115
112
|
const prepareUpload = (
|
|
@@ -141,10 +138,10 @@ export const useFileUpload = (options: UseFileUploadOptions = {}) => {
|
|
|
141
138
|
items: Record<string, { uploadId: string }>;
|
|
142
139
|
};
|
|
143
140
|
|
|
144
|
-
return $ofetch<PrepareUploadResponse>(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
).then(({ items }) => {
|
|
141
|
+
return $ofetch<PrepareUploadResponse>(`/repository/${parentId}/manifest`, {
|
|
142
|
+
method: "POST",
|
|
143
|
+
body: { items },
|
|
144
|
+
}).then(({ items }) => {
|
|
148
145
|
return Object.keys(items).map((name) => {
|
|
149
146
|
const { uploadId } = items[name];
|
|
150
147
|
const file = fileDictionary[name];
|
|
@@ -161,7 +158,7 @@ export const useFileUpload = (options: UseFileUploadOptions = {}) => {
|
|
|
161
158
|
};
|
|
162
159
|
|
|
163
160
|
return $ofetch<UploadURLResponse>(
|
|
164
|
-
|
|
161
|
+
`/uploads/${uploadId}/parts/?partNumber=${partNumber}`,
|
|
165
162
|
{ method: "POST" },
|
|
166
163
|
);
|
|
167
164
|
};
|
|
@@ -170,14 +167,14 @@ export const useFileUpload = (options: UseFileUploadOptions = {}) => {
|
|
|
170
167
|
uploadId: string,
|
|
171
168
|
partIds: Record<number, string>,
|
|
172
169
|
) => {
|
|
173
|
-
return $ofetch(
|
|
170
|
+
return $ofetch(`/uploads/${uploadId}`, {
|
|
174
171
|
method: "POST",
|
|
175
172
|
body: partIds,
|
|
176
173
|
});
|
|
177
174
|
};
|
|
178
175
|
|
|
179
176
|
const cancelUpload = (uploadId: string) => {
|
|
180
|
-
return $ofetch(
|
|
177
|
+
return $ofetch(`/uploads/${uploadId}`, {
|
|
181
178
|
method: "DELETE",
|
|
182
179
|
});
|
|
183
180
|
};
|