@sampleapp.ai/sdk 1.0.35 → 1.0.37

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 (96) hide show
  1. package/dist/components/sandbox/Sandbox.js +20 -8
  2. package/dist/components/sandbox/api.js +3 -2
  3. package/dist/components/sandbox/guardian/ask-ai-view.js +4 -4
  4. package/dist/components/sandbox/guardian/default-guide-view.js +1 -1
  5. package/dist/components/sandbox/guardian/demo/left-view.js +2 -2
  6. package/dist/components/sandbox/guardian/guardian-component.js +7 -38
  7. package/dist/components/sandbox/guardian/guardian-playground.js +3 -3
  8. package/dist/components/sandbox/guardian/guardian-style-wrapper.js +21 -2
  9. package/dist/components/sandbox/guardian/hooks/use-sandbox-url-loader.js +12 -10
  10. package/dist/components/sandbox/guardian/ide/browser.js +30 -30
  11. package/dist/components/sandbox/guardian/index.js +1 -1
  12. package/dist/components/sandbox/guardian/right-view/preview-control-bar.js +3 -3
  13. package/dist/components/sandbox/guardian/right-view/right-top-down-view.js +2 -2
  14. package/dist/components/sandbox/guardian/ui/download-and-open-buttons.js +1 -1
  15. package/dist/components/sandbox/guardian/ui/markdown/code-group/code-block.js +48 -11
  16. package/dist/components/sandbox/guardian/ui/markdown.js +3 -3
  17. package/dist/components/sandbox/guardian/utils.js +0 -18
  18. package/dist/components/sandbox/index.js +1 -1
  19. package/dist/components/sandbox/sandbox-home/SandboxCard.js +4 -4
  20. package/dist/components/sandbox/sandbox-home/SandboxHome.js +14 -9
  21. package/dist/components/sandbox/sandbox-home/SearchBar.js +2 -2
  22. package/dist/index.d.ts +29 -42
  23. package/dist/index.es.js +8208 -7715
  24. package/dist/index.js +1 -1
  25. package/dist/index.standalone.umd.js +1 -1
  26. package/dist/lib/api-client.js +9 -26
  27. package/dist/lib/generated-css.js +1 -1
  28. package/dist/sdk.css +1 -1
  29. package/dist/tailwind.css +1 -1
  30. package/package.json +1 -1
  31. package/dist/components/guardian/app-layout-no-sidebar.js +0 -8
  32. package/dist/components/guardian/ask-ai-view.js +0 -249
  33. package/dist/components/guardian/code-focus-section.d.ts +0 -41
  34. package/dist/components/guardian/code-focus-section.js +0 -174
  35. package/dist/components/guardian/context/guardian-context.js +0 -94
  36. package/dist/components/guardian/context/vm-context.js +0 -28
  37. package/dist/components/guardian/default-guide-view.js +0 -34
  38. package/dist/components/guardian/demo/guardian-demo.js +0 -35
  39. package/dist/components/guardian/demo/left-view/toggle.js +0 -28
  40. package/dist/components/guardian/demo/left-view.js +0 -49
  41. package/dist/components/guardian/guardian-component.js +0 -79
  42. package/dist/components/guardian/guardian-demo.js +0 -35
  43. package/dist/components/guardian/guardian-home.d.ts +0 -4
  44. package/dist/components/guardian/guardian-home.js +0 -61
  45. package/dist/components/guardian/guardian-playground.js +0 -45
  46. package/dist/components/guardian/guardian-style-wrapper.js +0 -29
  47. package/dist/components/guardian/guardian-upload-spec.d.ts +0 -14
  48. package/dist/components/guardian/guardian-upload-spec.js +0 -160
  49. package/dist/components/guardian/header/glassmorphic-combobox.d.ts +0 -15
  50. package/dist/components/guardian/header/glassmorphic-combobox.js +0 -30
  51. package/dist/components/guardian/header.js +0 -61
  52. package/dist/components/guardian/hooks/use-frame-messages.js +0 -65
  53. package/dist/components/guardian/hooks/use-frame-params.js +0 -44
  54. package/dist/components/guardian/hooks/use-sandbox-url-loader.js +0 -101
  55. package/dist/components/guardian/ide/browser.js +0 -538
  56. package/dist/components/guardian/index.js +0 -8
  57. package/dist/components/guardian/layout/app-layout-no-sidebar.js +0 -8
  58. package/dist/components/guardian/layout/header/glassmorphic-combobox.js +0 -48
  59. package/dist/components/guardian/layout/header.js +0 -63
  60. package/dist/components/guardian/right-view/code-view.js +0 -56
  61. package/dist/components/guardian/right-view/pill-file-selector.js +0 -233
  62. package/dist/components/guardian/right-view/preview-control-bar.js +0 -25
  63. package/dist/components/guardian/right-view/right-panel-view.js +0 -38
  64. package/dist/components/guardian/right-view/right-top-down-view.js +0 -289
  65. package/dist/components/guardian/right-view/right-view.js +0 -28
  66. package/dist/components/guardian/right-view/simplified-editor.js +0 -234
  67. package/dist/components/guardian/types/ide-types.js +0 -162
  68. package/dist/components/guardian/types.js +0 -3
  69. package/dist/components/guardian/ui/ai-loader.js +0 -48
  70. package/dist/components/guardian/ui/badge.js +0 -24
  71. package/dist/components/guardian/ui/button.js +0 -45
  72. package/dist/components/guardian/ui/command.js +0 -63
  73. package/dist/components/guardian/ui/console-with-app.js +0 -17
  74. package/dist/components/guardian/ui/dialog.js +0 -57
  75. package/dist/components/guardian/ui/dropdown-menu.js +0 -82
  76. package/dist/components/guardian/ui/markdown.js +0 -57
  77. package/dist/components/guardian/ui/popover.js +0 -25
  78. package/dist/components/guardian/ui/tooltip.js +0 -25
  79. package/dist/components/guardian/utils.js +0 -88
  80. package/dist/components/guardian/zip-to-codebase.js +0 -246
  81. package/dist/components/guardian/zip-to-filetree.js +0 -284
  82. package/dist/components/sandbox/SandboxHome.js +0 -141
  83. package/dist/components/sandbox/guardian/guardian-demo.js +0 -35
  84. package/dist/components/sandbox/guardian/guardian-home.d.ts +0 -4
  85. package/dist/components/sandbox/guardian/guardian-home.js +0 -61
  86. package/dist/components/sandbox/guardian/guardian-upload-spec.d.ts +0 -14
  87. package/dist/components/sandbox/guardian/guardian-upload-spec.js +0 -160
  88. package/dist/components/sandbox/guardian/ui/theme-color-context.d.ts +0 -6
  89. package/dist/components/sandbox/sandbox-control-bar.js +0 -91
  90. package/dist/components/sandbox/sandbox-header.js +0 -52
  91. package/dist/components/sandbox/sandbox-left-panel.js +0 -248
  92. package/dist/components/sandbox/sandbox-loading.js +0 -48
  93. package/dist/components/sandbox/sandbox-right-panel.js +0 -247
  94. package/dist/components/sandbox.js +0 -32
  95. package/dist/lib/api-client.example.js +0 -60
  96. package/dist/lib/ssr-safe-decode-entity.js +0 -16
@@ -1,35 +0,0 @@
1
- "use client";
2
- import React, { useEffect, useState, useCallback } from "react";
3
- import ConsoleWithApp from "../ui/console-with-app";
4
- import { useGuardianContext } from "../context/guardian-context";
5
- import ConsoleWithGuide from "./left-view";
6
- import RightView from "../right-view/right-view";
7
- export default function GuardianDemo({ CustomConsole, GuideView, browserUrl, playgroundUid, useVm, codeZipFile, completeCodeZipFile, variant, themeColor, hasPreview, isFrame = false, isGuardian = false, }) {
8
- const { isBrowserMaximized } = useGuardianContext();
9
- const { setCurrentView } = useGuardianContext();
10
- const [reloadCounter, setReloadCounter] = useState(0);
11
- const [overlayStage, setOverlayStage] = useState("hidden");
12
- const handleReloadPreview = useCallback(() => {
13
- setReloadCounter((c) => c + 1);
14
- }, []);
15
- const handleStageChange = useCallback((stage) => {
16
- setOverlayStage(stage);
17
- if (stage === "rebuilding") {
18
- // Simulate a 3-second rebuild then hide
19
- setTimeout(() => setOverlayStage("hidden"), 3000);
20
- }
21
- }, []);
22
- useEffect(() => {
23
- setCurrentView("preview");
24
- }, [setCurrentView]);
25
- // If isFrame, just return RightView directly
26
- if (isFrame) {
27
- return (React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }));
28
- }
29
- // If browser is maximized, render RightView at full size without the console
30
- if (isBrowserMaximized && isGuardian) {
31
- return (React.createElement("div", { className: "w-full h-full rounded-2xl border border-border overflow-hidden" },
32
- React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian, isBrowserMaximized: true })));
33
- }
34
- return (React.createElement(ConsoleWithApp, { containerClassName: "rounded-2xl border border-border", console: React.createElement(ConsoleWithGuide, { CustomConsole: CustomConsole, GuideView: GuideView, playgroundUid: playgroundUid, onReloadPreview: handleReloadPreview, onStageChange: handleStageChange, codeZipFile: codeZipFile, themeColor: themeColor }), app: React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }) }));
35
- }
@@ -1,28 +0,0 @@
1
- "use client";
2
- import React from "react";
3
- import { motion } from "framer-motion";
4
- import { cn } from "../../../../lib/utils";
5
- export default function SlidingEditPreviewToggle({ playgroundUid, variant = "default", buttonClassName = "", tabs = [
6
- { id: "editor", label: "Edit" },
7
- { id: "preview", label: "Preview" },
8
- ], currentView, setCurrentView, }) {
9
- // Outer div and button shape depending on variant
10
- const rootClasses = variant === "pill"
11
- ? "relative inline-flex items-center bg-muted/30 rounded-full p-1 border border-border/50"
12
- : "relative inline-flex items-center bg-muted/30 rounded-lg p-1";
13
- const btnShape = variant === "pill" ? "rounded-full" : "rounded-md";
14
- const highlightShape = variant === "pill" ? "rounded-full" : "rounded-md";
15
- // Default button padding if none provided
16
- const defaultButtonPadding = variant === "pill" ? "px-5 py-2" : "px-4 py-1.5";
17
- return (React.createElement("div", { className: rootClasses }, tabs.map((tab) => (React.createElement("button", { key: tab.id, onClick: () => setCurrentView(tab.id), className: cn(`relative ${defaultButtonPadding} text-sm font-medium transition-colors duration-150 ${btnShape} ${currentView === tab.id
18
- ? "text-foreground"
19
- : "text-muted-foreground hover:text-foreground/80"}`, buttonClassName), style: {
20
- WebkitTapHighlightColor: "transparent",
21
- } },
22
- currentView === tab.id && (React.createElement(motion.div, { layoutId: "activeTabGuide", className: cn(`absolute inset-0 bg-neutral-200 dark:bg-neutral-700 ${highlightShape} shadow-sm border border-border/50`), initial: false, transition: {
23
- type: "spring",
24
- stiffness: 500,
25
- damping: 30,
26
- } })),
27
- React.createElement("span", { className: "relative z-10" }, tab.label))))));
28
- }
@@ -1,49 +0,0 @@
1
- "use client";
2
- import React, { useMemo, useState } from "react";
3
- import SlidingConsoleGuideToggle from "./left-view/toggle";
4
- import AskAiView from "../ask-ai-view";
5
- import DefaultGuideView from "../default-guide-view";
6
- import { Markdown } from "../ui/markdown";
7
- export default function ConsoleWithGuide({ CustomConsole, GuideView, playgroundUid, onReloadPreview, onStageChange, codeZipFile, themeColor, }) {
8
- const [currentView, setCurrentView] = useState("console");
9
- const isConsoleView = useMemo(() => currentView === "console", [currentView]);
10
- const isGuideView = useMemo(() => currentView === "guide", [currentView]);
11
- const isChatView = useMemo(() => currentView === "chat", [currentView]);
12
- const renderCustomConsole = () => {
13
- if (typeof CustomConsole === "string") {
14
- return (React.createElement("div", { className: "h-full flex flex-col" },
15
- React.createElement("div", { className: "flex-1 px-8 py-6" },
16
- React.createElement(Markdown, { className: "text-gray-100", themeColor: themeColor }, CustomConsole))));
17
- }
18
- const CustomConsoleComponent = CustomConsole;
19
- return (React.createElement(CustomConsoleComponent, { onReloadPreview: onReloadPreview !== null && onReloadPreview !== void 0 ? onReloadPreview : (() => { }), onStageChange: onStageChange !== null && onStageChange !== void 0 ? onStageChange : (() => { }), themeColor: themeColor }));
20
- };
21
- // Determine which guide view to render
22
- const renderGuideView = () => {
23
- if (!GuideView) {
24
- // If no GuideView provided, render default
25
- return (React.createElement(DefaultGuideView, { onReloadPreview: onReloadPreview !== null && onReloadPreview !== void 0 ? onReloadPreview : (() => { }), onStageChange: onStageChange !== null && onStageChange !== void 0 ? onStageChange : (() => { }), themeColor: themeColor }));
26
- }
27
- // If GuideView is a string, render as markdown
28
- if (typeof GuideView === "string") {
29
- return (React.createElement("div", { className: "h-full flex flex-col" },
30
- React.createElement("div", { className: "flex-1 px-8 py-6" },
31
- React.createElement(Markdown, { className: "text-gray-100", themeColor: themeColor }, GuideView))));
32
- }
33
- // Otherwise, render as React component
34
- const GuideComponent = GuideView;
35
- return React.createElement(GuideComponent, null);
36
- };
37
- return (React.createElement("div", { className: "flex-1 min-h-0 relative" },
38
- React.createElement("div", { className: "flex justify-center border-b border-border" },
39
- React.createElement(SlidingConsoleGuideToggle, { playgroundUid: playgroundUid, variant: "pill", buttonClassName: "text-sm px-4 py-1", currentView: currentView, setCurrentView: setCurrentView, tabs: [
40
- { id: "console", label: "Guide" },
41
- ...(GuideView ? [{ id: "guide-og", label: "Guide OG" }] : []),
42
- { id: "chat", label: "Ask AI" },
43
- ] })),
44
- React.createElement("div", { className: "h-[calc(100vh-9.5rem)] min-h-0 overflow-hidden" },
45
- React.createElement("div", { className: "h-full min-h-0 overflow-y-auto" },
46
- isConsoleView && renderCustomConsole(),
47
- isGuideView && renderGuideView(),
48
- isChatView && (React.createElement(AskAiView, { codeZipFile: codeZipFile, playgroundUid: playgroundUid, themeColor: themeColor }))))));
49
- }
@@ -1,79 +0,0 @@
1
- "use client";
2
- import Header from "./header";
3
- import AppLayoutNoSidebar from "./app-layout-no-sidebar";
4
- import GuardianDemo from "./demo/guardian-demo";
5
- import React, { useEffect, useRef } from "react";
6
- import { useGuardianContext } from "./context/guardian-context";
7
- import { useSandboxUrlLoader } from "./hooks/use-sandbox-url-loader";
8
- import { useFrameMessages } from "./hooks/use-frame-messages";
9
- export default function GuardianComponent({ demoOptions, frameworkOptions, firstFrameworkByUseCase, currentFramework, currentUseCase, CustomConsole, GuideView, playgroundLogo, playgroundUid, browserUrl, useVm, sandboxUid, codeZipFile, consoleUrlConfigs, completeCodeZipFile, variant, themeColor, hasPreview = true, isFrame = false, }) {
10
- const { previewUrl, setPreviewUrl } = useGuardianContext();
11
- const { getSandboxUrl, loadSandboxUrl, preloadSandboxUrls } = useSandboxUrlLoader();
12
- // Initialize postMessage listener for iframe communication
13
- // This sends IFRAME_READY and listens for UPDATE_VIEW messages
14
- useFrameMessages();
15
- // Track which console configs we've preloaded to prevent duplicates
16
- const preloadedConfigsRef = useRef("");
17
- // Track which main sandbox we've loaded to prevent duplicates
18
- const loadedSandboxRef = useRef("");
19
- // Preload console URLs when component mounts
20
- useEffect(() => {
21
- if (consoleUrlConfigs && consoleUrlConfigs.length > 0) {
22
- // Create a key from the configs to detect changes
23
- const configKey = JSON.stringify(consoleUrlConfigs.map((c) => c.sandboxUid));
24
- // Only preload if we haven't already preloaded these configs
25
- if (preloadedConfigsRef.current !== configKey) {
26
- preloadedConfigsRef.current = configKey;
27
- preloadSandboxUrls(consoleUrlConfigs).catch((error) => {
28
- console.error("Failed to preload console URLs:", error);
29
- });
30
- }
31
- }
32
- // Only re-run if consoleUrlConfigs changes (not when preloadSandboxUrls changes)
33
- // eslint-disable-next-line react-hooks/exhaustive-deps
34
- }, [consoleUrlConfigs]);
35
- useEffect(() => {
36
- // Create a key for this sandbox load
37
- const sandboxKey = `${sandboxUid}-${browserUrl}-${useVm}`;
38
- // Check if we've already initiated a load for this exact sandbox config
39
- if (loadedSandboxRef.current === sandboxKey) {
40
- return;
41
- }
42
- // Check if URL is already cached for this sandboxUid + browserUrl combination
43
- const existingUrl = getSandboxUrl(sandboxUid, browserUrl);
44
- if (existingUrl !== undefined) {
45
- // Found cached URL for this exact combination, use it immediately
46
- setPreviewUrl(existingUrl);
47
- loadedSandboxRef.current = sandboxKey;
48
- return;
49
- }
50
- // Mark as loading to prevent duplicate requests
51
- loadedSandboxRef.current = sandboxKey;
52
- // Load the sandbox URL (will be cached by sandboxUid + browserUrl)
53
- // This allows switching between different browserUrls and reverting back
54
- // without losing the cached URLs
55
- setPreviewUrl("");
56
- loadSandboxUrl({
57
- sandboxUid,
58
- browserUrl,
59
- useVm,
60
- })
61
- .then((url) => {
62
- setPreviewUrl(url);
63
- })
64
- .catch((error) => {
65
- console.error("Failed to load sandbox URL:", error);
66
- // Keep preview URL empty on error
67
- });
68
- // Only re-run if the sandbox parameters change (not when functions change)
69
- // eslint-disable-next-line react-hooks/exhaustive-deps
70
- }, [sandboxUid, browserUrl, useVm]);
71
- // If isFrame, just render GuardianDemo without the header/layout wrapper
72
- if (isFrame) {
73
- return (React.createElement("div", { className: "h-[100vh]" },
74
- React.createElement(GuardianDemo, { CustomConsole: CustomConsole, GuideView: GuideView, browserUrl: previewUrl, playgroundUid: playgroundUid, useVm: useVm, codeZipFile: codeZipFile, completeCodeZipFile: completeCodeZipFile, variant: variant, themeColor: themeColor, hasPreview: hasPreview, isFrame: isFrame, isGuardian: true })));
75
- }
76
- return (React.createElement(AppLayoutNoSidebar, { header: React.createElement(Header, { demoOptions: demoOptions, frameworkOptions: frameworkOptions, currentFramework: currentFramework, currentUseCase: currentUseCase, playgroundLogo: playgroundLogo, firstFrameworkByUseCase: firstFrameworkByUseCase }) },
77
- React.createElement("div", { className: "absolute inset-0 mt-24 px-4 pb-4" },
78
- React.createElement(GuardianDemo, { CustomConsole: CustomConsole, GuideView: GuideView, browserUrl: previewUrl, playgroundUid: playgroundUid, useVm: useVm, codeZipFile: codeZipFile, completeCodeZipFile: completeCodeZipFile, variant: variant, themeColor: themeColor, hasPreview: hasPreview, isFrame: isFrame, isGuardian: true }))));
79
- }
@@ -1,35 +0,0 @@
1
- "use client";
2
- import React, { useEffect, useState, useCallback } from "react";
3
- import ConsoleWithApp from "./ui/console-with-app";
4
- import { useGuardianContext } from "./context/guardian-context";
5
- import ConsoleWithGuide from "./demo/left-view";
6
- import RightView from "./right-view/right-view";
7
- export default function GuardianDemo({ CustomConsole, GuideView, browserUrl, playgroundUid, useVm, codeZipFile, completeCodeZipFile, variant, themeColor, hasPreview, isFrame = false, isGuardian = false, }) {
8
- const { isBrowserMaximized } = useGuardianContext();
9
- const { setCurrentView } = useGuardianContext();
10
- const [reloadCounter, setReloadCounter] = useState(0);
11
- const [overlayStage, setOverlayStage] = useState("hidden");
12
- const handleReloadPreview = useCallback(() => {
13
- setReloadCounter((c) => c + 1);
14
- }, []);
15
- const handleStageChange = useCallback((stage) => {
16
- setOverlayStage(stage);
17
- if (stage === "rebuilding") {
18
- // Simulate a 3-second rebuild then hide
19
- setTimeout(() => setOverlayStage("hidden"), 3000);
20
- }
21
- }, []);
22
- useEffect(() => {
23
- setCurrentView("preview");
24
- }, [setCurrentView]);
25
- // If isFrame, just return RightView directly
26
- if (isFrame) {
27
- return (React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }));
28
- }
29
- // If browser is maximized, render RightView at full size without the console
30
- if (isBrowserMaximized && isGuardian) {
31
- return (React.createElement("div", { className: "w-full h-full rounded-2xl border overflow-hidden" },
32
- React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian, isBrowserMaximized: true })));
33
- }
34
- return (React.createElement(ConsoleWithApp, { containerClassName: "rounded-2xl border", console: React.createElement(ConsoleWithGuide, { CustomConsole: CustomConsole, GuideView: GuideView, playgroundUid: playgroundUid, onReloadPreview: handleReloadPreview, onStageChange: handleStageChange, codeZipFile: codeZipFile, themeColor: themeColor }), app: React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }) }));
35
- }
@@ -1,4 +0,0 @@
1
- import { GuardianNestedConfig } from "./types";
2
- export default function GuardianHome({ nestedConfig, }: {
3
- nestedConfig: GuardianNestedConfig;
4
- }): import("react").JSX.Element;
@@ -1,61 +0,0 @@
1
- "use client";
2
- import Link from "next/link";
3
- import AppLayoutNoSidebar from "./app-layout-no-sidebar";
4
- import { useSandboxUrlLoader } from "./hooks/use-sandbox-url-loader";
5
- import { useEffect, useRef } from "react";
6
- export default function GuardianHome({ nestedConfig, }) {
7
- var _a, _b, _c;
8
- const { preloadSandboxUrls } = useSandboxUrlLoader();
9
- const hasPreloadedRef = useRef(false);
10
- // Preload all sandbox URLs when the home page loads (only once)
11
- useEffect(() => {
12
- // Prevent multiple preload attempts
13
- if (hasPreloadedRef.current) {
14
- return;
15
- }
16
- hasPreloadedRef.current = true;
17
- // Extract all framework configs from nested structure
18
- const configs = Object.values(nestedConfig).flatMap((uc) => Object.values(uc.frameworks).flatMap((fw) => {
19
- // Include the main framework config
20
- const mainConfig = {
21
- sandboxUid: fw.sandboxUid,
22
- browserUrl: fw.browserUrl,
23
- useVm: fw.useVm,
24
- };
25
- // Include additional URLs from consoleUrlConfigs (urlsToPreload)
26
- const additionalConfigs = fw.consoleUrlConfigs || [];
27
- return [mainConfig, ...additionalConfigs];
28
- }));
29
- // Preload all URLs in the background
30
- preloadSandboxUrls(configs).catch((error) => {
31
- console.error("Failed to preload some sandbox URLs:", error);
32
- });
33
- }, [nestedConfig, preloadSandboxUrls]);
34
- // Build unique use cases list with first framework for each
35
- const uniqueUseCases = Object.entries(nestedConfig).map(([id, uc]) => {
36
- const firstFramework = Object.keys(uc.frameworks)[0];
37
- return {
38
- id,
39
- name: uc.name,
40
- description: uc.description,
41
- firstFramework,
42
- };
43
- });
44
- // Get playground logo from the first framework of the first use case
45
- const playgroundLogo = (_c = (_a = Object.values(nestedConfig)[0]) === null || _a === void 0 ? void 0 : _a.frameworks[Object.keys(((_b = Object.values(nestedConfig)[0]) === null || _b === void 0 ? void 0 : _b.frameworks) || {})[0]]) === null || _c === void 0 ? void 0 : _c.playgroundLogo;
46
- return (React.createElement(AppLayoutNoSidebar, { header: React.createElement("div", { className: "flex items-center gap-3 ml-6" }, playgroundLogo) },
47
- React.createElement("div", { className: "h-full flex flex-col" },
48
- React.createElement("div", { className: "flex-1 px-6 py-6 space-y-8" },
49
- React.createElement("div", { className: "space-y-3" },
50
- React.createElement("div", { className: "text-xs font-medium text-gray-400 tracking-wider uppercase" }, "Examples"),
51
- React.createElement("h1", { className: "text-2xl font-semibold text-gray-100" }, "Sample apps"),
52
- React.createElement("p", { className: "text-sm text-gray-400" }, "Select a sample app to explore and interact with")),
53
- React.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6" }, uniqueUseCases.map((useCase) => (React.createElement(Link, { href: `/${useCase.id}?framework=${useCase.firstFramework}`, key: useCase.id },
54
- React.createElement("div", { className: "bg-[#1a1b23] rounded-lg border border-gray-800 p-6 flex flex-col justify-between min-h-[180px] hover:border-gray-700 transition-colors cursor-pointer" },
55
- React.createElement("div", null,
56
- React.createElement("div", { className: "flex items-center gap-3 mb-2" },
57
- React.createElement("h2", { className: "font-semibold text-base text-gray-100" }, useCase.name)),
58
- React.createElement("div", { className: "text-gray-400 text-sm mb-6" }, useCase.description)),
59
- React.createElement("div", { className: "flex items-center gap-2" },
60
- React.createElement("span", { className: "text-xs text-gray-500" }, "View app \u2192")))))))))));
61
- }
@@ -1,45 +0,0 @@
1
- "use client";
2
- import React from "react";
3
- import GuardianComponent from "./guardian-component";
4
- import { useFrameParams } from "./hooks/use-frame-params";
5
- import { GuardianStyleWrapper } from "./guardian-style-wrapper";
6
- /**
7
- * Guardian Playground component with nested config structure.
8
- * Expects config[useCaseId].frameworks[frameworkKey] structure.
9
- *
10
- * When isFrame=true, reads framework from URL params client-side.
11
- */
12
- export default function GuardianPlayground({ nestedConfig, useCase, framework: serverFramework, isFrame = false, }) {
13
- var _a, _b;
14
- // When in frame mode, allow URL params to override framework
15
- const frameParams = useFrameParams();
16
- const framework = isFrame && frameParams.framework ? frameParams.framework : serverFramework;
17
- const useCaseConfig = nestedConfig[useCase];
18
- if (!useCaseConfig) {
19
- return (React.createElement("div", { className: "flex items-center justify-center h-screen" },
20
- React.createElement("p", { className: "text-red-500" },
21
- "Use case \"",
22
- useCase,
23
- "\" not found")));
24
- }
25
- const frameworkConfig = useCaseConfig.frameworks[framework];
26
- if (!frameworkConfig) {
27
- return (React.createElement("div", { className: "flex items-center justify-center h-screen" },
28
- React.createElement("p", { className: "text-red-500" },
29
- "Framework \"",
30
- framework,
31
- "\" not found in use case \"",
32
- useCase,
33
- "\"")));
34
- }
35
- // Build a map of use case ID to first available framework key
36
- const firstFrameworkByUseCase = {};
37
- Object.entries(nestedConfig).forEach(([useCaseId, uc]) => {
38
- const firstFrameworkKey = Object.keys(uc.frameworks)[0];
39
- if (firstFrameworkKey) {
40
- firstFrameworkByUseCase[useCaseId] = firstFrameworkKey;
41
- }
42
- });
43
- return (React.createElement(GuardianStyleWrapper, null,
44
- React.createElement(GuardianComponent, { demoOptions: frameworkConfig.demoOptions, frameworkOptions: frameworkConfig.frameworkOptions, firstFrameworkByUseCase: firstFrameworkByUseCase, currentFramework: frameworkConfig.currentFramework, CustomConsole: frameworkConfig.CustomConsole, GuideView: frameworkConfig.GuideView, playgroundUid: frameworkConfig.playgroundUid, browserUrl: (_a = frameParams.iframeUrl) !== null && _a !== void 0 ? _a : frameworkConfig.browserUrl, useVm: frameworkConfig.useVm, playgroundLogo: frameworkConfig.playgroundLogo, sandboxUid: frameworkConfig.sandboxUid, name: frameworkConfig.name, description: frameworkConfig.description, codeZipFile: frameworkConfig.codeZipFile, completeCodeZipFile: frameworkConfig.completeCodeZipFile, consoleUrlConfigs: frameworkConfig.consoleUrlConfigs, variant: frameworkConfig.variant, themeColor: frameworkConfig.themeColor, hasPreview: (_b = frameworkConfig.hasPreview) !== null && _b !== void 0 ? _b : true, currentUseCase: useCase, isFrame: isFrame })));
45
- }
@@ -1,29 +0,0 @@
1
- "use client";
2
- import React, { useEffect, useState } from "react";
3
- import { TAILWIND_CSS } from "../../lib/generated-css";
4
- /**
5
- * Style wrapper for Guardian components that injects Tailwind CSS
6
- * into the document without using Shadow DOM (preserves React context)
7
- */
8
- export const GuardianStyleWrapper = ({ children, }) => {
9
- const [stylesInjected, setStylesInjected] = useState(false);
10
- useEffect(() => {
11
- // Check if styles are already injected
12
- const existingStyle = document.getElementById("guardian-sdk-styles");
13
- if (existingStyle) {
14
- setStylesInjected(true);
15
- return;
16
- }
17
- // Inject styles into document head
18
- const styleElement = document.createElement("style");
19
- styleElement.id = "guardian-sdk-styles";
20
- // Scope styles to guardian-sdk class to avoid conflicts
21
- styleElement.textContent = TAILWIND_CSS;
22
- document.head.appendChild(styleElement);
23
- setStylesInjected(true);
24
- return () => {
25
- // Don't remove styles on unmount as other Guardian components might use them
26
- };
27
- }, []);
28
- return (React.createElement("div", { className: "guardian-sdk-root", style: { width: "100%", height: "100%" } }, children));
29
- };
@@ -1,14 +0,0 @@
1
- import React from "react";
2
- type UploadedFile = {
3
- name: string;
4
- size: number;
5
- type: string;
6
- content?: string;
7
- };
8
- type GuardianUploadSpecProps = {
9
- onBack: () => void;
10
- onContinue: (file: UploadedFile) => void;
11
- isLoading?: boolean;
12
- };
13
- export default function GuardianUploadSpec({ onBack, onContinue, isLoading, }: GuardianUploadSpecProps): React.JSX.Element;
14
- export {};
@@ -1,160 +0,0 @@
1
- "use client";
2
- import React from "react";
3
- "use client";
4
- import { useState, useCallback } from "react";
5
- import { Upload, FileText, X, Check, AlertCircle } from "lucide-react";
6
- import { cn } from "../../lib/utils";
7
- export default function GuardianUploadSpec({ onBack, onContinue, isLoading = false, }) {
8
- const [uploadedFile, setUploadedFile] = useState(null);
9
- const [isDragging, setIsDragging] = useState(false);
10
- const [error, setError] = useState(null);
11
- const [isValidating, setIsValidating] = useState(false);
12
- const validateFile = (file) => {
13
- // Check file size (max 10MB)
14
- if (file.size > 10 * 1024 * 1024) {
15
- return "File size must be less than 10MB";
16
- }
17
- // Check file type
18
- const validTypes = [
19
- "application/json",
20
- "application/x-yaml",
21
- "application/yaml",
22
- "text/yaml",
23
- "text/x-yaml",
24
- "text/plain",
25
- ];
26
- const validExtensions = [".json", ".yaml", ".yml"];
27
- const hasValidType = validTypes.includes(file.type);
28
- const hasValidExtension = validExtensions.some((ext) => file.name.toLowerCase().endsWith(ext));
29
- if (!hasValidType && !hasValidExtension) {
30
- return "Please upload a JSON or YAML file";
31
- }
32
- return null;
33
- };
34
- const handleFile = useCallback((file) => {
35
- setError(null);
36
- setIsValidating(true);
37
- const validationError = validateFile(file);
38
- if (validationError) {
39
- setError(validationError);
40
- setIsValidating(false);
41
- return;
42
- }
43
- const reader = new FileReader();
44
- reader.onload = (e) => {
45
- var _a;
46
- const content = (_a = e.target) === null || _a === void 0 ? void 0 : _a.result;
47
- // Basic validation that it's valid JSON or YAML
48
- try {
49
- if (file.name.toLowerCase().endsWith(".json")) {
50
- JSON.parse(content);
51
- }
52
- }
53
- catch (_b) {
54
- setError("Invalid JSON file");
55
- setIsValidating(false);
56
- return;
57
- }
58
- setUploadedFile({
59
- name: file.name,
60
- size: file.size,
61
- type: file.type,
62
- content,
63
- });
64
- setIsValidating(false);
65
- };
66
- reader.onerror = () => {
67
- setError("Failed to read file");
68
- setIsValidating(false);
69
- };
70
- reader.readAsText(file);
71
- }, []);
72
- const handleDrop = useCallback((e) => {
73
- e.preventDefault();
74
- setIsDragging(false);
75
- const files = Array.from(e.dataTransfer.files);
76
- if (files.length > 0) {
77
- handleFile(files[0]);
78
- }
79
- }, [handleFile]);
80
- const handleDragOver = useCallback((e) => {
81
- e.preventDefault();
82
- setIsDragging(true);
83
- }, []);
84
- const handleDragLeave = useCallback((e) => {
85
- e.preventDefault();
86
- setIsDragging(false);
87
- }, []);
88
- const handleFileInput = useCallback((e) => {
89
- const files = e.target.files;
90
- if (files && files.length > 0) {
91
- handleFile(files[0]);
92
- }
93
- }, [handleFile]);
94
- const handleRemoveFile = () => {
95
- setUploadedFile(null);
96
- setError(null);
97
- };
98
- const formatFileSize = (bytes) => {
99
- if (bytes < 1024)
100
- return bytes + " B";
101
- if (bytes < 1024 * 1024)
102
- return (bytes / 1024).toFixed(1) + " KB";
103
- return (bytes / (1024 * 1024)).toFixed(1) + " MB";
104
- };
105
- return (React.createElement("div", { className: "min-h-screen bg-white flex flex-col items-center justify-center p-8" },
106
- React.createElement("div", { className: "w-full max-w-xl" },
107
- React.createElement("div", { className: "mb-8" },
108
- React.createElement("button", { type: "button", onClick: onBack, disabled: isLoading, className: "text-sm text-gray-500 hover:text-gray-700 font-medium mb-4 flex items-center gap-1 disabled:opacity-50 disabled:cursor-not-allowed" }, isLoading ? (React.createElement(React.Fragment, null,
109
- React.createElement("div", { className: "h-3 w-3 animate-spin rounded-full border-2 border-gray-300 border-t-gray-700" }),
110
- React.createElement("span", null, "Back"))) : (React.createElement(React.Fragment, null, "\u2190 Back"))),
111
- React.createElement("h1", { className: "text-3xl font-semibold text-black mb-3" }, "Upload OpenAPI spec"),
112
- React.createElement("p", { className: "text-sm text-gray-600" }, "Upload your OpenAPI specification file (JSON or YAML format) to generate sample apps.")),
113
- !uploadedFile ? (React.createElement("div", { onDrop: handleDrop, onDragOver: handleDragOver, onDragLeave: handleDragLeave, className: cn("relative rounded-xl border-2 border-dashed transition-all", isDragging
114
- ? "border-blue-500 bg-blue-50"
115
- : "border-gray-200 bg-gray-50", error && "border-red-300 bg-red-50") },
116
- React.createElement("label", { className: "flex flex-col items-center justify-center px-8 py-12 cursor-pointer" },
117
- React.createElement("input", { type: "file", className: "hidden", accept: ".json,.yaml,.yml", onChange: handleFileInput, disabled: isValidating }),
118
- isValidating ? (React.createElement(React.Fragment, null,
119
- React.createElement("div", { className: "h-12 w-12 mb-4 animate-spin rounded-full border-4 border-gray-200 border-t-blue-600" }),
120
- React.createElement("p", { className: "text-sm font-medium text-gray-900 mb-1" }, "Validating file..."))) : (React.createElement(React.Fragment, null,
121
- React.createElement("div", { className: cn("flex h-14 w-14 items-center justify-center rounded-full mb-4 transition-colors", isDragging ? "bg-blue-100" : "bg-white", error && "bg-red-100") }, error ? (React.createElement(AlertCircle, { className: "h-7 w-7 text-red-600" })) : (React.createElement(Upload, { className: cn("h-7 w-7", isDragging ? "text-blue-600" : "text-gray-400") }))),
122
- React.createElement("p", { className: "text-sm font-medium text-gray-900 mb-1" }, isDragging ? ("Drop your file here") : (React.createElement(React.Fragment, null,
123
- React.createElement("span", { className: "text-blue-600" }, "Click to upload"),
124
- " ",
125
- "or drag and drop"))),
126
- React.createElement("p", { className: "text-xs text-gray-500 mb-2" }, "JSON or YAML (max 10MB)"))),
127
- error && (React.createElement("div", { className: "mt-3 text-xs text-red-600 font-medium flex items-center gap-1.5" },
128
- React.createElement(AlertCircle, { className: "h-3.5 w-3.5" }),
129
- error))))) : (React.createElement("div", { className: "space-y-4" },
130
- React.createElement("div", { className: "rounded-xl border border-gray-200 bg-white p-4 transition hover:bg-gray-50" },
131
- React.createElement("div", { className: "flex items-start justify-between gap-3" },
132
- React.createElement("div", { className: "flex items-start gap-3 flex-1" },
133
- React.createElement("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-green-50" },
134
- React.createElement(FileText, { className: "h-5 w-5 text-green-600" })),
135
- React.createElement("div", { className: "flex-1 min-w-0" },
136
- React.createElement("div", { className: "flex items-center gap-2 mb-1" },
137
- React.createElement("p", { className: "text-sm font-medium text-gray-900 truncate" }, uploadedFile.name),
138
- React.createElement("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-green-500 flex-shrink-0" },
139
- React.createElement(Check, { className: "h-3 w-3 text-white" }))),
140
- React.createElement("p", { className: "text-xs text-gray-500" }, formatFileSize(uploadedFile.size)))),
141
- React.createElement("button", { type: "button", onClick: handleRemoveFile, className: "flex h-8 w-8 items-center justify-center rounded-full hover:bg-gray-100 transition-colors text-gray-400 hover:text-gray-600" },
142
- React.createElement(X, { className: "h-4 w-4" })))),
143
- React.createElement("div", { className: "rounded-xl bg-blue-50 border border-blue-100 p-4" },
144
- React.createElement("p", { className: "text-xs text-blue-900 font-medium mb-2" }, "What happens next?"),
145
- React.createElement("ul", { className: "space-y-1.5 text-xs text-blue-800" },
146
- React.createElement("li", { className: "flex items-start gap-2" },
147
- React.createElement("span", null, "\u2022"),
148
- React.createElement("span", null, "We'll parse your OpenAPI spec and extract all endpoints")),
149
- React.createElement("li", { className: "flex items-start gap-2" },
150
- React.createElement("span", null, "\u2022"),
151
- React.createElement("span", null, "You'll choose frameworks for which to generate sample apps")),
152
- React.createElement("li", { className: "flex items-start gap-2" },
153
- React.createElement("span", null, "\u2022"),
154
- React.createElement("span", null, "Each app will be pre-configured with auth and example calls")))),
155
- React.createElement("div", { className: "flex items-center justify-end gap-3 pt-2" },
156
- React.createElement("button", { type: "button", onClick: handleRemoveFile, disabled: isLoading, className: "rounded-full border border-gray-200 bg-white px-5 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed" }, "Choose different file"),
157
- React.createElement("button", { type: "button", onClick: () => onContinue(uploadedFile), disabled: isLoading, className: "inline-flex items-center gap-2 rounded-full bg-[#2563EB] px-6 py-2.5 text-sm font-medium text-white hover:bg-[#1d4ed8] transition-colors disabled:opacity-50 disabled:cursor-not-allowed" }, isLoading ? (React.createElement(React.Fragment, null,
158
- React.createElement("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white" }),
159
- React.createElement("span", null, "Processing..."))) : (React.createElement("span", null, "Continue")))))))));
160
- }
@@ -1,15 +0,0 @@
1
- import React from "react";
2
- type Option = {
3
- label: string;
4
- value: string;
5
- href: string;
6
- };
7
- interface GlassmorphicComboboxProps {
8
- options: Option[];
9
- value: string;
10
- placeholder?: string;
11
- className?: string;
12
- searchPlaceholder?: string;
13
- }
14
- export default function GlassmorphicCombobox({ options, value, placeholder, className, searchPlaceholder, }: GlassmorphicComboboxProps): React.JSX.Element;
15
- export {};
@@ -1,30 +0,0 @@
1
- "use client";
2
- import React, { useState } from "react";
3
- import { Button } from "../ui/button";
4
- import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
5
- import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "../ui/command";
6
- import { CheckIcon, ChevronsUpDown } from "lucide-react";
7
- import { cn } from "../../../lib/utils";
8
- export default function GlassmorphicCombobox({ options, value, placeholder, className, searchPlaceholder, }) {
9
- var _a;
10
- const [open, setOpen] = useState(false);
11
- const selectedLabel = (_a = options.find((o) => o.value === value)) === null || _a === void 0 ? void 0 : _a.label;
12
- return (React.createElement(Popover, { open: open, onOpenChange: setOpen },
13
- React.createElement(PopoverTrigger, { asChild: true },
14
- React.createElement(Button, { variant: "outline", role: "combobox", "aria-expanded": open, className: cn("w-64 justify-between rounded-xl border-white/20 bg-white/10 backdrop-blur-md", "text-white/90 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.25)] hover:bg-white/15", "data-[state=open]:bg-white/15", className) },
15
- React.createElement("span", { className: "truncate min-w-0" }, selectedLabel !== null && selectedLabel !== void 0 ? selectedLabel : placeholder),
16
- React.createElement(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-70" }))),
17
- React.createElement(PopoverContent, { className: cn("w-64 p-0 rounded-xl border border-white/20 bg-black/40 backdrop-blur-xl", "shadow-xl") },
18
- React.createElement(Command, { className: "bg-transparent" },
19
- React.createElement(CommandInput, { placeholder: searchPlaceholder, className: "bg-transparent placeholder:text-white/60" }),
20
- React.createElement(CommandList, { className: "bg-transparent" },
21
- React.createElement(CommandEmpty, { className: "text-white/80" }, "No results found."),
22
- React.createElement(CommandGroup, { className: "bg-transparent" }, options.map((option) => (React.createElement(CommandItem, { key: option.value, value: option.value, className: "cursor-pointer", onSelect: () => {
23
- setOpen(false);
24
- if (option.href && typeof window !== "undefined") {
25
- window.location.href = option.href;
26
- }
27
- } },
28
- React.createElement(CheckIcon, { className: cn("mr-2 h-4 w-4", value === option.value ? "opacity-100" : "opacity-0") }),
29
- option.label)))))))));
30
- }