@gradio/client 0.17.0 → 0.18.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/client.d.ts +15 -4
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/constants.d.ts +8 -2
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/helpers/data.d.ts +2 -2
  7. package/dist/helpers/data.d.ts.map +1 -1
  8. package/dist/helpers/init_helpers.d.ts.map +1 -1
  9. package/dist/helpers/spaces.d.ts.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +219 -176
  13. package/dist/test/handlers.d.ts +3 -0
  14. package/dist/test/handlers.d.ts.map +1 -0
  15. package/dist/test/mock_eventsource.d.ts +2 -0
  16. package/dist/test/mock_eventsource.d.ts.map +1 -0
  17. package/dist/test/server.d.ts +2 -0
  18. package/dist/test/server.d.ts.map +1 -0
  19. package/dist/test/test_data.d.ts +76 -0
  20. package/dist/test/test_data.d.ts.map +1 -0
  21. package/dist/types.d.ts +4 -3
  22. package/dist/types.d.ts.map +1 -1
  23. package/dist/upload.d.ts +2 -2
  24. package/dist/upload.d.ts.map +1 -1
  25. package/dist/utils/duplicate.d.ts.map +1 -1
  26. package/dist/utils/stream.d.ts +1 -1
  27. package/dist/utils/stream.d.ts.map +1 -1
  28. package/dist/utils/submit.d.ts.map +1 -1
  29. package/dist/utils/upload_files.d.ts.map +1 -1
  30. package/dist/utils/view_api.d.ts.map +1 -1
  31. package/package.json +8 -2
  32. package/src/client.ts +50 -24
  33. package/src/constants.ts +9 -2
  34. package/src/helpers/api_info.ts +4 -4
  35. package/src/helpers/data.ts +46 -28
  36. package/src/helpers/init_helpers.ts +7 -11
  37. package/src/helpers/spaces.ts +8 -3
  38. package/src/index.ts +1 -1
  39. package/src/test/api_info.test.ts +456 -0
  40. package/src/test/data.test.ts +281 -0
  41. package/src/test/handlers.ts +438 -0
  42. package/src/test/init.test.ts +139 -0
  43. package/src/test/init_helpers.test.ts +94 -0
  44. package/src/test/mock_eventsource.ts +11 -0
  45. package/src/test/post_data.test.ts +45 -0
  46. package/src/test/server.ts +6 -0
  47. package/src/test/spaces.test.ts +145 -0
  48. package/src/test/stream.test.ts +67 -0
  49. package/src/test/test_data.ts +557 -0
  50. package/src/test/upload_files.test.ts +42 -0
  51. package/src/test/view_api.test.ts +53 -0
  52. package/src/types.ts +4 -3
  53. package/src/upload.ts +4 -8
  54. package/src/utils/duplicate.ts +20 -3
  55. package/src/utils/handle_blob.ts +1 -1
  56. package/src/utils/post_data.ts +1 -1
  57. package/src/utils/stream.ts +29 -20
  58. package/src/utils/submit.ts +23 -15
  59. package/src/utils/upload_files.ts +11 -6
  60. package/src/utils/view_api.ts +4 -7
  61. package/vite.config.js +7 -0
  62. package/src/utils/client.node-test.ts +0 -173
@@ -0,0 +1,281 @@
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import {
3
+ update_object,
4
+ walk_and_store_blobs,
5
+ skip_queue,
6
+ post_message
7
+ } from "../helpers/data";
8
+ import { NodeBlob } from "../client";
9
+ import { config_response, endpoint_info } from "./test_data";
10
+ import { BlobRef } from "../types";
11
+
12
+ describe("walk_and_store_blobs", () => {
13
+ it("should convert a Buffer to a Blob", async () => {
14
+ const buffer = Buffer.from("test data");
15
+ const parts = await walk_and_store_blobs(buffer, "text");
16
+
17
+ expect(parts).toHaveLength(1);
18
+ expect(parts[0].blob).toBeInstanceOf(NodeBlob);
19
+ });
20
+
21
+ it("should return a Blob when passed a Blob", async () => {
22
+ const blob = new Blob(["test data"]);
23
+ const parts = await walk_and_store_blobs(
24
+ blob,
25
+ undefined,
26
+ [],
27
+ true,
28
+ endpoint_info
29
+ );
30
+
31
+ expect(parts[0].blob).toBeInstanceOf(NodeBlob);
32
+ });
33
+
34
+ it("should return blob: false when passed an image", async () => {
35
+ const blob = new Blob([]);
36
+ const parts = await walk_and_store_blobs(
37
+ blob,
38
+ "Image",
39
+ [],
40
+ true,
41
+ endpoint_info
42
+ );
43
+ expect(parts[0].blob).toBe(false);
44
+ });
45
+
46
+ it("should handle deep structures", async () => {
47
+ const image = new Blob([]);
48
+ const parts = await walk_and_store_blobs({ a: { b: { data: { image } } } });
49
+
50
+ expect(parts).toHaveLength(1);
51
+ expect(parts[0].blob).toBeInstanceOf(NodeBlob);
52
+ expect(parts[0].path).toEqual(["a", "b", "data", "image"]);
53
+ });
54
+
55
+ it("should handle deep structures with arrays", async () => {
56
+ const image = new Blob([]);
57
+ const parts = await walk_and_store_blobs({
58
+ a: [
59
+ {
60
+ b: [
61
+ {
62
+ data: [
63
+ {
64
+ image
65
+ }
66
+ ]
67
+ }
68
+ ]
69
+ }
70
+ ]
71
+ });
72
+
73
+ expect(parts[0].blob).toBeInstanceOf(NodeBlob);
74
+ });
75
+
76
+ it("should handle deep structures with arrays (with equality check)", async () => {
77
+ const image = new Blob([]);
78
+
79
+ const obj = {
80
+ a: [
81
+ {
82
+ b: [
83
+ {
84
+ data: [[image], image, [image, [image]]]
85
+ }
86
+ ]
87
+ }
88
+ ]
89
+ };
90
+ const parts = await walk_and_store_blobs(obj);
91
+
92
+ async function map_path(obj: Record<string, any>, parts: BlobRef[]) {
93
+ const { path, blob } = parts[parts.length - 1];
94
+ let ref = obj;
95
+ path.forEach((p) => (ref = ref[p]));
96
+
97
+ // since ref is a Blob and blob is a NodeBlob, we deep equal check the two buffers instead
98
+ if (ref instanceof Blob && blob instanceof NodeBlob) {
99
+ const refBuffer = Buffer.from(await ref.arrayBuffer());
100
+ const blobBuffer = Buffer.from(await blob.arrayBuffer());
101
+ return refBuffer.equals(blobBuffer);
102
+ }
103
+
104
+ return ref === blob;
105
+ }
106
+
107
+ expect(parts[0].blob).toBeInstanceOf(NodeBlob);
108
+ expect(map_path(obj, parts)).toBeTruthy();
109
+ });
110
+
111
+ it("should handle buffer instances and return a BlobRef", async () => {
112
+ const buffer = Buffer.from("test");
113
+ const parts = await walk_and_store_blobs(buffer, undefined, ["blob"]);
114
+
115
+ expect(parts).toHaveLength(1);
116
+ expect(parts[0].blob).toBeInstanceOf(NodeBlob);
117
+ expect(parts[0].path).toEqual(["blob"]);
118
+ });
119
+
120
+ it("should handle buffer instances with a path and return a BlobRef with the path", async () => {
121
+ const buffer = Buffer.from("test data");
122
+ const parts = await walk_and_store_blobs(buffer);
123
+
124
+ expect(parts).toHaveLength(1);
125
+ expect(parts[0].path).toEqual([]);
126
+ expect(parts[0].blob).toBeInstanceOf(NodeBlob);
127
+ });
128
+
129
+ it("should convert an object with deep structures to BlobRefs", async () => {
130
+ const param = {
131
+ a: {
132
+ b: {
133
+ data: {
134
+ image: Buffer.from("test image")
135
+ }
136
+ }
137
+ }
138
+ };
139
+ const parts = await walk_and_store_blobs(param);
140
+
141
+ expect(parts).toHaveLength(1);
142
+ expect(parts[0].path).toEqual(["a", "b", "data", "image"]);
143
+ expect(parts[0].blob).toBeInstanceOf(NodeBlob);
144
+ });
145
+
146
+ it("should convert an object with primitive values to BlobRefs", async () => {
147
+ const param = {
148
+ test: "test"
149
+ };
150
+ const parts = await walk_and_store_blobs(param);
151
+
152
+ expect(parts).toHaveLength(1);
153
+ expect(parts[0].path).toEqual([]);
154
+ expect(parts[0].blob).toBeInstanceOf(NodeBlob);
155
+ expect(parts[0].type).toEqual("object");
156
+ });
157
+ });
158
+ describe("update_object", () => {
159
+ it("should update the value of a nested property", () => {
160
+ const obj = {
161
+ a: {
162
+ b: {
163
+ c: "old value"
164
+ }
165
+ }
166
+ };
167
+
168
+ const stack = ["a", "b", "c"];
169
+ const new_val = "new value";
170
+
171
+ update_object(obj, new_val, stack);
172
+
173
+ expect(obj.a.b.c).toBe(new_val);
174
+ });
175
+
176
+ it("should throw an error for invalid key type", () => {
177
+ const obj = {
178
+ a: {
179
+ b: {
180
+ c: "value"
181
+ }
182
+ }
183
+ };
184
+
185
+ const stack = ["a", "b", true];
186
+ const newValue = "new value";
187
+
188
+ expect(() => {
189
+ // @ts-ignore
190
+ update_object(obj, newValue, stack);
191
+ }).toThrowError("Invalid key type");
192
+ });
193
+ });
194
+
195
+ describe("skip_queue", () => {
196
+ const id = 0;
197
+ const config = config_response;
198
+
199
+ it("should not skip queue when global and dependency queue is enabled", () => {
200
+ config.enable_queue = true;
201
+ config.dependencies[id].queue = true;
202
+
203
+ const result = skip_queue(id, config_response);
204
+
205
+ expect(result).toBe(false);
206
+ });
207
+
208
+ it("should not skip queue when global queue is disabled and dependency queue is enabled", () => {
209
+ config.enable_queue = false;
210
+ config.dependencies[id].queue = true;
211
+
212
+ const result = skip_queue(id, config_response);
213
+
214
+ expect(result).toBe(false);
215
+ });
216
+
217
+ it("should should skip queue when global queue and dependency queue is disabled", () => {
218
+ config.enable_queue = false;
219
+ config.dependencies[id].queue = false;
220
+
221
+ const result = skip_queue(id, config_response);
222
+
223
+ expect(result).toBe(true);
224
+ });
225
+
226
+ it("should should skip queue when global queue is enabled and dependency queue is disabled", () => {
227
+ config.enable_queue = true;
228
+ config.dependencies[id].queue = false;
229
+
230
+ const result = skip_queue(id, config_response);
231
+
232
+ expect(result).toBe(true);
233
+ });
234
+ });
235
+
236
+ describe("post_message", () => {
237
+ afterEach(() => {
238
+ vi.restoreAllMocks();
239
+ });
240
+
241
+ it("should send a message to the parent window and resolve with received data", async () => {
242
+ const test_data = { key: "value" };
243
+ const test_origin = "https://huggingface.co";
244
+
245
+ const post_message_mock = vi.fn();
246
+
247
+ global.window = {
248
+ // @ts-ignore
249
+ parent: {
250
+ postMessage: post_message_mock
251
+ }
252
+ };
253
+
254
+ const message_channel_mock = {
255
+ port1: {
256
+ onmessage: (handler) => {
257
+ onmessage = handler;
258
+ },
259
+ close: vi.fn()
260
+ },
261
+ port2: {}
262
+ };
263
+
264
+ vi.stubGlobal("MessageChannel", function () {
265
+ this.port1 = message_channel_mock.port1;
266
+ this.port2 = message_channel_mock.port2;
267
+ return this;
268
+ });
269
+
270
+ const promise = post_message(test_data, test_origin);
271
+
272
+ if (message_channel_mock.port1.onmessage) {
273
+ message_channel_mock.port1.onmessage({ data: test_data });
274
+ }
275
+
276
+ await expect(promise).resolves.toEqual(test_data);
277
+ expect(post_message_mock).toHaveBeenCalledWith(test_data, test_origin, [
278
+ message_channel_mock.port2
279
+ ]);
280
+ });
281
+ });
@@ -0,0 +1,438 @@
1
+ import { HttpResponse, http, RequestHandler } from "msw";
2
+ import {
3
+ HOST_URL,
4
+ API_INFO_URL,
5
+ CONFIG_URL,
6
+ RUNTIME_URL,
7
+ SLEEPTIME_URL,
8
+ UPLOAD_URL,
9
+ BROKEN_CONNECTION_MSG
10
+ } from "../constants";
11
+ import {
12
+ response_api_info,
13
+ config_response,
14
+ whoami_response,
15
+ duplicate_response,
16
+ hardware_sleeptime_response,
17
+ discussions_response,
18
+ runtime_response
19
+ } from "./test_data";
20
+
21
+ const root_url = "https://huggingface.co";
22
+
23
+ const direct_space_url = "https://hmb-hello-world.hf.space";
24
+ const private_space_url = "https://hmb-secret-world.hf.space";
25
+
26
+ const server_error_space_url = "https://hmb-server-error.hf.space";
27
+ const upload_server_test_space_url = "https://hmb-server-test.hf.space";
28
+ const server_error_reference = "hmb/server_error";
29
+
30
+ const app_reference = "hmb/hello_world";
31
+ const broken_app_reference = "hmb/bye_world";
32
+ const duplicate_app_reference = "gradio/hello_world";
33
+ const private_app_reference = "hmb/secret_world";
34
+ const server_test_app_reference = "hmb/server_test";
35
+
36
+ export const handlers: RequestHandler[] = [
37
+ // /host requests
38
+ http.get(`${root_url}/api/spaces/${app_reference}/${HOST_URL}`, () => {
39
+ return new HttpResponse(
40
+ JSON.stringify({
41
+ subdomain: "hmb-hello-world",
42
+ host: "https://hmb-hello-world.hf.space"
43
+ }),
44
+ {
45
+ status: 200,
46
+ headers: {
47
+ "Content-Type": "application/json"
48
+ }
49
+ }
50
+ );
51
+ }),
52
+ http.get(`${root_url}/api/spaces/${broken_app_reference}/${HOST_URL}`, () => {
53
+ return new HttpResponse(null, {
54
+ status: 404,
55
+ headers: {
56
+ "Content-Type": "application/json",
57
+ hf_token: "hf_123"
58
+ }
59
+ });
60
+ }),
61
+ http.get(
62
+ `${root_url}/api/spaces/${private_app_reference}/${HOST_URL}`,
63
+ ({ request }) => {
64
+ const token = request.headers.get("authorization")?.substring(7);
65
+
66
+ if (!token || token !== "hf_123") {
67
+ return new HttpResponse(null, {
68
+ status: 401,
69
+ headers: {
70
+ "Content-Type": "application/json"
71
+ }
72
+ });
73
+ }
74
+
75
+ return new HttpResponse(
76
+ JSON.stringify({
77
+ subdomain: private_app_reference,
78
+ host: private_space_url
79
+ }),
80
+ {
81
+ status: 200,
82
+ headers: {
83
+ "Content-Type": "application/json"
84
+ }
85
+ }
86
+ );
87
+ }
88
+ ),
89
+ http.get(
90
+ `${root_url}/api/spaces/${server_error_reference}/${HOST_URL}`,
91
+ () => {
92
+ return new HttpResponse(
93
+ JSON.stringify({
94
+ subdomain: "hmb-server-test",
95
+ host: "https://hmb-server-test.hf.space"
96
+ }),
97
+ {
98
+ status: 200,
99
+ headers: {
100
+ "Content-Type": "application/json"
101
+ }
102
+ }
103
+ );
104
+ }
105
+ ),
106
+ http.get(
107
+ `${root_url}/api/spaces/${server_test_app_reference}/${HOST_URL}`,
108
+ () => {
109
+ return new HttpResponse(
110
+ JSON.stringify({
111
+ subdomain: "hmb-server-test",
112
+ host: "https://hmb-server-test.hf.space"
113
+ }),
114
+ {
115
+ status: 200,
116
+ headers: {
117
+ "Content-Type": "application/json"
118
+ }
119
+ }
120
+ );
121
+ }
122
+ ),
123
+ // /info requests
124
+ http.get(`${direct_space_url}/${API_INFO_URL}`, () => {
125
+ return new HttpResponse(JSON.stringify(response_api_info), {
126
+ status: 200,
127
+ headers: {
128
+ "Content-Type": "application/json"
129
+ }
130
+ });
131
+ }),
132
+ http.get(`${upload_server_test_space_url}/${API_INFO_URL}`, () => {
133
+ return new HttpResponse(JSON.stringify(response_api_info), {
134
+ status: 200,
135
+ headers: {
136
+ "Content-Type": "application/json"
137
+ }
138
+ });
139
+ }),
140
+ http.get(`${private_space_url}/${API_INFO_URL}`, () => {
141
+ return new HttpResponse(JSON.stringify(response_api_info), {
142
+ status: 200,
143
+ headers: {
144
+ "Content-Type": "application/json"
145
+ }
146
+ });
147
+ }),
148
+ http.get(`${server_error_space_url}/${API_INFO_URL}`, () => {
149
+ return new HttpResponse(JSON.stringify(response_api_info), {
150
+ status: 200,
151
+ headers: {
152
+ "Content-Type": "application/json"
153
+ }
154
+ });
155
+ }),
156
+ // /config requests
157
+ http.get(`${direct_space_url}/${CONFIG_URL}`, () => {
158
+ return new HttpResponse(JSON.stringify(config_response), {
159
+ status: 200,
160
+ headers: {
161
+ "Content-Type": "application/json"
162
+ }
163
+ });
164
+ }),
165
+ http.get(`${private_space_url}/${CONFIG_URL}`, () => {
166
+ return new HttpResponse(
167
+ JSON.stringify({
168
+ ...config_response,
169
+ root: "https://hmb-secret-world.hf.space"
170
+ }),
171
+ {
172
+ status: 200,
173
+ headers: {
174
+ "Content-Type": "application/json"
175
+ }
176
+ }
177
+ );
178
+ }),
179
+ http.get(`${upload_server_test_space_url}/${CONFIG_URL}`, () => {
180
+ return new HttpResponse(
181
+ JSON.stringify({
182
+ ...config_response,
183
+ root: "https://hmb-server-test.hf.space"
184
+ }),
185
+ {
186
+ status: 200,
187
+ headers: {
188
+ "Content-Type": "application/json"
189
+ }
190
+ }
191
+ );
192
+ }),
193
+ http.get(`${direct_space_url}/${CONFIG_URL}`, () => {
194
+ return new HttpResponse(JSON.stringify(config_response), {
195
+ status: 500,
196
+ headers: {
197
+ "Content-Type": "application/json"
198
+ }
199
+ });
200
+ }),
201
+ http.get(`${server_error_space_url}/${CONFIG_URL}`, () => {
202
+ return new HttpResponse(JSON.stringify(config_response), {
203
+ status: 200,
204
+ headers: {
205
+ "Content-Type": "application/json"
206
+ }
207
+ });
208
+ }),
209
+ // /whoami requests
210
+ http.get(`${root_url}/api/whoami-v2`, () => {
211
+ return new HttpResponse(JSON.stringify(whoami_response), {
212
+ status: 200,
213
+ headers: {
214
+ "Content-Type": "application/json",
215
+ "hf-token": "hf_123"
216
+ }
217
+ });
218
+ }),
219
+ // /duplicate requests
220
+ http.post(
221
+ `${root_url}/api/spaces/${duplicate_app_reference}/duplicate`,
222
+ ({ request }) => {
223
+ if (request.headers.get("authorization")?.substring(7) !== "hf_123") {
224
+ throw new HttpResponse(null, {
225
+ status: 401,
226
+ headers: {
227
+ "Content-Type": "application/json"
228
+ }
229
+ });
230
+ }
231
+ return new HttpResponse(JSON.stringify(duplicate_response), {
232
+ status: 200,
233
+ headers: {
234
+ "Content-Type": "application/json"
235
+ }
236
+ });
237
+ }
238
+ ),
239
+ // /sleeptime requests
240
+ http.post(`${root_url}/api/spaces/${app_reference}/${SLEEPTIME_URL}`, () => {
241
+ return new HttpResponse(JSON.stringify(hardware_sleeptime_response), {
242
+ status: 200,
243
+ headers: {
244
+ "Content-Type": "application/json"
245
+ }
246
+ });
247
+ }),
248
+ http.post(
249
+ `${root_url}/api/spaces/${server_test_app_reference}/${SLEEPTIME_URL}`,
250
+ () => {
251
+ throw new HttpResponse(null, {
252
+ status: 500,
253
+ headers: {
254
+ "Content-Type": "application/json"
255
+ }
256
+ });
257
+ }
258
+ ),
259
+ // /runtime requests
260
+ http.get(
261
+ `${root_url}/api/spaces/${broken_app_reference}/${RUNTIME_URL}`,
262
+ () => {
263
+ return new HttpResponse(null, {
264
+ status: 404,
265
+ headers: {
266
+ "Content-Type": "application/json"
267
+ }
268
+ });
269
+ }
270
+ ),
271
+ http.get(`${root_url}/api/spaces/${app_reference}/${RUNTIME_URL}`, () => {
272
+ return new HttpResponse(JSON.stringify(hardware_sleeptime_response), {
273
+ status: 200,
274
+ headers: {
275
+ "Content-Type": "application/json"
276
+ }
277
+ });
278
+ }),
279
+ // queue requests
280
+ http.post(`${direct_space_url}/queue/join`, () => {
281
+ return new HttpResponse(JSON.stringify({ event_id: "123" }), {
282
+ status: 200,
283
+ headers: {
284
+ "Content-Type": "application/json"
285
+ }
286
+ });
287
+ }),
288
+ // upload requests
289
+ http.post(`${direct_space_url}/${UPLOAD_URL}`, () => {
290
+ return new HttpResponse(JSON.stringify(["lion.jpg"]), {
291
+ status: 200,
292
+ headers: {
293
+ "Content-Type": "application/json"
294
+ }
295
+ });
296
+ }),
297
+ http.post(`${upload_server_test_space_url}/${UPLOAD_URL}`, () => {
298
+ throw new HttpResponse(JSON.parse("Internal Server Error"), {
299
+ status: 200,
300
+ headers: {
301
+ "Content-Type": "application/json"
302
+ }
303
+ });
304
+ }),
305
+ // discussions requests
306
+ http.head(`${root_url}/api/spaces/${app_reference}/discussions`, () => {
307
+ return new HttpResponse(JSON.stringify(discussions_response), {
308
+ status: 200,
309
+ headers: {
310
+ "Content-Type": "application/json"
311
+ }
312
+ });
313
+ }),
314
+ http.head(
315
+ `${root_url}/api/spaces/${broken_app_reference}/discussions`,
316
+ () => {
317
+ throw new HttpResponse(
318
+ JSON.parse("Discussions are disabled for this repo"),
319
+ {
320
+ status: 403,
321
+ headers: {
322
+ "Content-Type": "application/json"
323
+ }
324
+ }
325
+ );
326
+ }
327
+ ),
328
+ // space requests
329
+ http.get(`${root_url}/api/spaces/${app_reference}`, () => {
330
+ return new HttpResponse(
331
+ JSON.stringify({ id: app_reference, runtime: runtime_response }),
332
+ {
333
+ status: 200,
334
+ headers: {
335
+ "Content-Type": "application/json"
336
+ }
337
+ }
338
+ );
339
+ }),
340
+ http.get(`${root_url}/api/spaces/hmb/paused_space`, () => {
341
+ return new HttpResponse(
342
+ JSON.stringify({
343
+ id: app_reference,
344
+ runtime: { ...runtime_response, stage: "PAUSED" }
345
+ }),
346
+ {
347
+ status: 200,
348
+ headers: {
349
+ "Content-Type": "application/json"
350
+ }
351
+ }
352
+ );
353
+ }),
354
+ http.get(`${root_url}/api/spaces/hmb/building_space`, () => {
355
+ return new HttpResponse(
356
+ JSON.stringify({
357
+ id: app_reference,
358
+ runtime: { ...runtime_response, stage: "BUILDING" }
359
+ }),
360
+ {
361
+ status: 200,
362
+ headers: {
363
+ "Content-Type": "application/json"
364
+ }
365
+ }
366
+ );
367
+ }),
368
+ http.get(`${root_url}/api/spaces/hmb/stopped_space`, () => {
369
+ return new HttpResponse(
370
+ JSON.stringify({
371
+ id: app_reference,
372
+ runtime: { ...runtime_response, stage: "STOPPED" }
373
+ }),
374
+ {
375
+ status: 200,
376
+ headers: {
377
+ "Content-Type": "application/json"
378
+ }
379
+ }
380
+ );
381
+ }),
382
+ http.get(`${root_url}/api/spaces/hmb/failed_space`, () => {
383
+ throw new HttpResponse(null, {
384
+ status: 500,
385
+ headers: {
386
+ "Content-Type": "application/json"
387
+ }
388
+ });
389
+ }),
390
+ // jwt requests
391
+ http.get(`${root_url}/api/spaces/${app_reference}/jwt`, () => {
392
+ return new HttpResponse(
393
+ JSON.stringify({
394
+ token: "jwt_123"
395
+ }),
396
+ {
397
+ status: 200,
398
+ headers: {
399
+ "Content-Type": "application/json"
400
+ }
401
+ }
402
+ );
403
+ }),
404
+ http.get(`${root_url}/api/spaces/${broken_app_reference}/jwt`, () => {
405
+ return new HttpResponse(null, {
406
+ status: 500,
407
+ headers: {
408
+ "Content-Type": "application/json"
409
+ }
410
+ });
411
+ }),
412
+ // post_data requests
413
+ http.post(`${direct_space_url}`, () => {
414
+ return new HttpResponse(JSON.stringify({}), {
415
+ status: 200,
416
+ headers: {
417
+ "Content-Type": "application/json"
418
+ }
419
+ });
420
+ }),
421
+ http.post(`${private_space_url}`, () => {
422
+ return new HttpResponse(JSON.stringify(BROKEN_CONNECTION_MSG), {
423
+ status: 500,
424
+ headers: {
425
+ "Content-Type": "application/json"
426
+ }
427
+ });
428
+ }),
429
+ // heartbeat requests
430
+ http.get(`*/heartbeat/*`, () => {
431
+ return new HttpResponse(null, {
432
+ status: 200,
433
+ headers: {
434
+ "Content-Type": "application/json"
435
+ }
436
+ });
437
+ })
438
+ ];