zudoku 0.0.0-z5b63904b → 0.0.0-z6b1ecd2d

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 (30) hide show
  1. package/dist/config/validators/NavigationSchema.js +1 -0
  2. package/dist/config/validators/NavigationSchema.js.map +1 -1
  3. package/dist/lib/plugins/openapi/playground/fileUtils.d.ts +1 -0
  4. package/dist/lib/plugins/openapi/playground/fileUtils.js +3 -0
  5. package/dist/lib/plugins/openapi/playground/fileUtils.js.map +1 -1
  6. package/dist/lib/plugins/openapi/playground/result-panel/AudioPlayer.d.ts +6 -0
  7. package/dist/lib/plugins/openapi/playground/result-panel/AudioPlayer.js +20 -0
  8. package/dist/lib/plugins/openapi/playground/result-panel/AudioPlayer.js.map +1 -0
  9. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +7 -2
  10. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -1
  11. package/lib/{OasProvider--Ee8eUgN.js → OasProvider-DPPdikt_.js} +2 -2
  12. package/lib/{OasProvider--Ee8eUgN.js.map → OasProvider-DPPdikt_.js.map} +1 -1
  13. package/lib/{OperationList-DftaNVEs.js → OperationList-cEveQ_l5.js} +3 -3
  14. package/lib/{OperationList-DftaNVEs.js.map → OperationList-cEveQ_l5.js.map} +1 -1
  15. package/lib/{SchemaList-CSOKHa_l.js → SchemaList-CRC8n5co.js} +3 -3
  16. package/lib/{SchemaList-CSOKHa_l.js.map → SchemaList-CRC8n5co.js.map} +1 -1
  17. package/lib/{SchemaView-BrYjZLEd.js → SchemaView-BR6dtnPg.js} +2 -2
  18. package/lib/{SchemaView-BrYjZLEd.js.map → SchemaView-BR6dtnPg.js.map} +1 -1
  19. package/lib/{circular-D7do-Usk.js → circular-C4l1Kj1N.js} +2 -2
  20. package/lib/{circular-D7do-Usk.js.map → circular-C4l1Kj1N.js.map} +1 -1
  21. package/lib/{createServer-BQ1_wtQj.js → createServer-DoRZ6tMa.js} +3 -3
  22. package/lib/{createServer-BQ1_wtQj.js.map → createServer-DoRZ6tMa.js.map} +1 -1
  23. package/lib/{index-B0M6y_Fr.js → index-Ck4TmzTO.js} +653 -619
  24. package/lib/index-Ck4TmzTO.js.map +1 -0
  25. package/lib/zudoku.plugin-openapi.js +1 -1
  26. package/package.json +1 -1
  27. package/src/lib/plugins/openapi/playground/fileUtils.ts +4 -0
  28. package/src/lib/plugins/openapi/playground/result-panel/AudioPlayer.tsx +50 -0
  29. package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +33 -17
  30. package/lib/index-B0M6y_Fr.js.map +0 -1
@@ -3,7 +3,7 @@ import "lucide-react";
3
3
  import "./chunk-EPOLDU6W-C6C8jAwd.js";
4
4
  import "./ui/Button.js";
5
5
  import "./ZudokuContext-C6wlLMUH.js";
6
- import { y as e, U as n, z as s } from "./index-B0M6y_Fr.js";
6
+ import { y as e, U as n, z as s } from "./index-Ck4TmzTO.js";
7
7
  export {
8
8
  e as GetNavigationOperationsQuery,
9
9
  n as UNTAGGED_PATH,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.0.0-z5b63904b",
3
+ "version": "0.0.0-z6b1ecd2d",
4
4
  "type": "module",
5
5
  "homepage": "https://zudoku.dev",
6
6
  "repository": {
@@ -4,6 +4,10 @@ export function isBinaryContentType(contentType: string) {
4
4
  );
5
5
  }
6
6
 
7
+ export function isAudioContentType(contentType: string) {
8
+ return /^audio\//i.test(contentType);
9
+ }
10
+
7
11
  export const extractFileName = (
8
12
  headers: Array<[string, string]>,
9
13
  url: string,
@@ -0,0 +1,50 @@
1
+ import { DownloadIcon } from "lucide-react";
2
+ import { useEffect, useState } from "react";
3
+ import { Button } from "zudoku/ui/Button.js";
4
+ import { humanFileSize } from "../../../../util/humanFileSize.js";
5
+
6
+ export const AudioPlayer = ({
7
+ blob,
8
+ fileName,
9
+ size,
10
+ onDownload,
11
+ }: {
12
+ blob: Blob;
13
+ fileName: string;
14
+ size: number;
15
+ onDownload: () => void;
16
+ }) => {
17
+ const [audioUrl, setAudioUrl] = useState<string | null>(null);
18
+
19
+ useEffect(() => {
20
+ const url = URL.createObjectURL(blob);
21
+ setAudioUrl(url);
22
+
23
+ return () => {
24
+ URL.revokeObjectURL(url);
25
+ };
26
+ }, [blob]);
27
+
28
+ if (!audioUrl) {
29
+ return (
30
+ <div className="p-4 text-center">
31
+ <div className="text-sm text-muted-foreground">Loading audio...</div>
32
+ </div>
33
+ );
34
+ }
35
+
36
+ return (
37
+ <div className="p-4 text-center">
38
+ <div className="flex flex-col items-center gap-4">
39
+ {/* biome-ignore lint/a11y/useMediaCaption: API response audio cannot have predefined captions */}
40
+ <audio controls src={audioUrl} className="w-full max-w-md">
41
+ Your browser does not support the audio element.
42
+ </audio>
43
+ <Button onClick={onDownload} className="flex items-center gap-2">
44
+ <DownloadIcon className="h-4 w-4" />
45
+ Download {fileName} ({humanFileSize(size)})
46
+ </Button>
47
+ </div>
48
+ </div>
49
+ );
50
+ };
@@ -32,6 +32,8 @@ import {
32
32
  CollapsibleHeader,
33
33
  CollapsibleHeaderTrigger,
34
34
  } from "../CollapsibleHeader.js";
35
+ import { isAudioContentType } from "../fileUtils.js";
36
+ import { AudioPlayer } from "./AudioPlayer.js";
35
37
  import { convertToTypes } from "./convertToTypes.js";
36
38
 
37
39
  const mimeTypeToLanguage = (mimeType: string) => {
@@ -50,9 +52,14 @@ const mimeTypeToLanguage = (mimeType: string) => {
50
52
  )?.[1];
51
53
  };
52
54
 
55
+ const getContentType = (headers: Array<[string, string]>) => {
56
+ return (
57
+ headers.find(([key]) => key.toLowerCase() === "content-type")?.[1] || ""
58
+ );
59
+ };
60
+
53
61
  const detectLanguage = (headers: Array<[string, string]>) => {
54
- const contentType =
55
- headers.find(([key]) => key.toLowerCase() === "content-type")?.[1] || "";
62
+ const contentType = getContentType(headers);
56
63
  return mimeTypeToLanguage(contentType);
57
64
  };
58
65
 
@@ -293,23 +300,32 @@ export const ResponseTab = ({
293
300
  </div>
294
301
  <div className="flex-1">
295
302
  {isBinary ? (
296
- <div className="p-4 text-center">
297
- <div className="flex flex-col items-center gap-4">
298
- <div className="text-lg font-semibold">Binary Content</div>
299
- <div className="text-sm text-muted-foreground">
300
- This response contains binary data that cannot be displayed as
301
- text.
303
+ blob && isAudioContentType(getContentType(headers)) ? (
304
+ <AudioPlayer
305
+ blob={blob}
306
+ fileName={fileName ?? "audio"}
307
+ size={size}
308
+ onDownload={handleDownload}
309
+ />
310
+ ) : (
311
+ <div className="p-4 text-center">
312
+ <div className="flex flex-col items-center gap-4">
313
+ <div className="text-lg font-semibold">Binary Content</div>
314
+ <div className="text-sm text-muted-foreground">
315
+ This response contains binary data that cannot be displayed as
316
+ text.
317
+ </div>
318
+ <Button
319
+ onClick={handleDownload}
320
+ className="flex items-center gap-2"
321
+ disabled={!blob}
322
+ >
323
+ <DownloadIcon className="h-4 w-4" />
324
+ Download {fileName || "file"} ({humanFileSize(size)})
325
+ </Button>
302
326
  </div>
303
- <Button
304
- onClick={handleDownload}
305
- className="flex items-center gap-2"
306
- disabled={!blob}
307
- >
308
- <DownloadIcon className="h-4 w-4" />
309
- Download {fileName || "file"} ({humanFileSize(size)})
310
- </Button>
311
327
  </div>
312
- </div>
328
+ )
313
329
  ) : (
314
330
  <SyntaxHighlight
315
331
  className="text-xs flex-1"