@strapi/content-type-builder 5.51.0 → 5.51.2

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 (105) hide show
  1. package/dist/admin/components/AIChat/Chat.js +1 -1
  2. package/dist/admin/components/AIChat/Chat.js.map +1 -1
  3. package/dist/admin/components/AIChat/Chat.mjs +1 -1
  4. package/dist/admin/components/AIChat/Chat.mjs.map +1 -1
  5. package/dist/admin/components/AIChat/FeedbackModal.js +1 -1
  6. package/dist/admin/components/AIChat/FeedbackModal.js.map +1 -1
  7. package/dist/admin/components/AIChat/FeedbackModal.mjs +1 -1
  8. package/dist/admin/components/AIChat/FeedbackModal.mjs.map +1 -1
  9. package/dist/admin/components/AIChat/UploadFigmaModal.js +1 -1
  10. package/dist/admin/components/AIChat/UploadFigmaModal.js.map +1 -1
  11. package/dist/admin/components/AIChat/UploadFigmaModal.mjs +1 -1
  12. package/dist/admin/components/AIChat/UploadFigmaModal.mjs.map +1 -1
  13. package/dist/admin/components/AIChat/components/Base64Image.js +1 -1
  14. package/dist/admin/components/AIChat/components/Base64Image.js.map +1 -1
  15. package/dist/admin/components/AIChat/components/Base64Image.mjs +1 -1
  16. package/dist/admin/components/AIChat/components/Base64Image.mjs.map +1 -1
  17. package/dist/admin/components/AIChat/hooks/useAIFetch.js +1 -1
  18. package/dist/admin/components/AIChat/hooks/useAIFetch.js.map +1 -1
  19. package/dist/admin/components/AIChat/hooks/useAIFetch.mjs +1 -1
  20. package/dist/admin/components/AIChat/hooks/useAIFetch.mjs.map +1 -1
  21. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js +2 -2
  22. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js.map +1 -1
  23. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs +2 -2
  24. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs.map +1 -1
  25. package/dist/admin/components/CTBSession/useCTBTracking.js +1 -1
  26. package/dist/admin/components/CTBSession/useCTBTracking.js.map +1 -1
  27. package/dist/admin/components/CTBSession/useCTBTracking.mjs +1 -1
  28. package/dist/admin/components/CTBSession/useCTBTracking.mjs.map +1 -1
  29. package/dist/admin/components/DataManager/useServerRestartWatcher.js +1 -1
  30. package/dist/admin/components/DataManager/useServerRestartWatcher.js.map +1 -1
  31. package/dist/admin/components/DataManager/useServerRestartWatcher.mjs +1 -1
  32. package/dist/admin/components/DataManager/useServerRestartWatcher.mjs.map +1 -1
  33. package/dist/admin/components/FormModal/attributes/ConditionForm.js +1 -1
  34. package/dist/admin/components/FormModal/attributes/ConditionForm.js.map +1 -1
  35. package/dist/admin/components/FormModal/attributes/ConditionForm.mjs +1 -1
  36. package/dist/admin/components/FormModal/attributes/ConditionForm.mjs.map +1 -1
  37. package/dist/admin/components/FormModal/attributes/advancedForm.js +1 -0
  38. package/dist/admin/components/FormModal/attributes/advancedForm.js.map +1 -1
  39. package/dist/admin/components/FormModal/attributes/advancedForm.mjs +1 -0
  40. package/dist/admin/components/FormModal/attributes/advancedForm.mjs.map +1 -1
  41. package/dist/admin/components/FormModal/attributes/types.js +6 -1
  42. package/dist/admin/components/FormModal/attributes/types.js.map +1 -1
  43. package/dist/admin/components/FormModal/attributes/types.mjs +6 -1
  44. package/dist/admin/components/FormModal/attributes/types.mjs.map +1 -1
  45. package/dist/admin/components/FormModal/attributes/validation/common.js +6 -4
  46. package/dist/admin/components/FormModal/attributes/validation/common.js.map +1 -1
  47. package/dist/admin/components/FormModal/attributes/validation/common.mjs +6 -4
  48. package/dist/admin/components/FormModal/attributes/validation/common.mjs.map +1 -1
  49. package/dist/admin/components/FormModal/forms/forms.js +1 -1
  50. package/dist/admin/components/FormModal/forms/forms.js.map +1 -1
  51. package/dist/admin/components/FormModal/forms/forms.mjs +1 -1
  52. package/dist/admin/components/FormModal/forms/forms.mjs.map +1 -1
  53. package/dist/admin/components/PluralName.js +1 -1
  54. package/dist/admin/components/PluralName.js.map +1 -1
  55. package/dist/admin/components/PluralName.mjs +1 -1
  56. package/dist/admin/components/PluralName.mjs.map +1 -1
  57. package/dist/admin/src/components/CTBSession/useCTBTracking.d.ts +1 -1
  58. package/dist/admin/src/components/DataManager/utils/cleanData.d.ts +8 -0
  59. package/dist/admin/src/components/FormModal/attributes/types.d.ts +2 -0
  60. package/dist/admin/src/types.d.ts +1 -0
  61. package/dist/admin/translations/en.json.js +1 -0
  62. package/dist/admin/translations/en.json.js.map +1 -1
  63. package/dist/admin/translations/en.json.mjs +1 -0
  64. package/dist/admin/translations/en.json.mjs.map +1 -1
  65. package/dist/server/controllers/validation/common.js +1 -1
  66. package/dist/server/controllers/validation/common.js.map +1 -1
  67. package/dist/server/controllers/validation/common.mjs +1 -1
  68. package/dist/server/controllers/validation/common.mjs.map +1 -1
  69. package/dist/server/controllers/validation/relations.js +1 -0
  70. package/dist/server/controllers/validation/relations.js.map +1 -1
  71. package/dist/server/controllers/validation/relations.mjs +1 -0
  72. package/dist/server/controllers/validation/relations.mjs.map +1 -1
  73. package/dist/server/controllers/validation/schema.js +2 -1
  74. package/dist/server/controllers/validation/schema.js.map +1 -1
  75. package/dist/server/controllers/validation/schema.mjs +2 -1
  76. package/dist/server/controllers/validation/schema.mjs.map +1 -1
  77. package/dist/server/services/content-types.js +1 -1
  78. package/dist/server/services/content-types.js.map +1 -1
  79. package/dist/server/services/content-types.mjs +1 -1
  80. package/dist/server/services/content-types.mjs.map +1 -1
  81. package/dist/server/services/schema-builder/content-type-builder.js +3 -2
  82. package/dist/server/services/schema-builder/content-type-builder.js.map +1 -1
  83. package/dist/server/services/schema-builder/content-type-builder.mjs +3 -2
  84. package/dist/server/services/schema-builder/content-type-builder.mjs.map +1 -1
  85. package/dist/server/services/schema.js +1 -5
  86. package/dist/server/services/schema.js.map +1 -1
  87. package/dist/server/services/schema.mjs +2 -2
  88. package/dist/server/services/schema.mjs.map +1 -1
  89. package/dist/server/src/controllers/validation/relations.d.ts +2 -0
  90. package/dist/server/src/controllers/validation/relations.d.ts.map +1 -1
  91. package/dist/server/src/controllers/validation/schema.d.ts +3234 -0
  92. package/dist/server/src/controllers/validation/schema.d.ts.map +1 -1
  93. package/dist/server/src/services/schema-builder/types.d.ts +1 -0
  94. package/dist/server/src/services/schema-builder/types.d.ts.map +1 -1
  95. package/dist/server/src/utils/attributes.d.ts +10 -10
  96. package/dist/server/src/utils/attributes.d.ts.map +1 -1
  97. package/dist/server/utils/attributes.js +2 -2
  98. package/dist/server/utils/attributes.js.map +1 -1
  99. package/dist/server/utils/attributes.mjs +3 -2
  100. package/dist/server/utils/attributes.mjs.map +1 -1
  101. package/package.json +7 -7
  102. package/dist/server/src/controllers/ai/auth.d.ts +0 -1
  103. package/dist/server/src/controllers/ai/auth.d.ts.map +0 -1
  104. package/dist/server/src/controllers/ai/index.d.ts +0 -1
  105. package/dist/server/src/controllers/ai/index.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"UploadFigmaModal.js","sources":["../../../../admin/src/components/AIChat/UploadFigmaModal.tsx"],"sourcesContent":["import { createContext, useContext, useState } from 'react';\n\nimport { Flex, Typography, Box, TextInput, Grid, Button, Link } from '@strapi/design-system'; // Added Link\n\nimport { ImagePreview } from './components/ImagePreview';\nimport { StepModal, useStepModal } from './components/StepModal';\nimport { useAttachments } from './hooks/useAttachments';\nimport {\n FigmaImage,\n useFigmaUpload,\n getFigmaToken,\n saveFigmaToken,\n hasFigmaToken,\n} from './hooks/useFigmaUpload';\nimport { useTranslations } from './hooks/useTranslations';\nimport { useStrapiChat } from './providers/ChatProvider';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface UploadFigmaContextType {\n isFigmaUploadOpen: boolean;\n submitOnFinish: boolean;\n openFigmaUpload: (submitOnFinish?: boolean) => void;\n closeFigmaUpload: () => void;\n}\n\nconst UploadFigmaContext = createContext<UploadFigmaContextType>({\n isFigmaUploadOpen: false,\n submitOnFinish: false,\n openFigmaUpload: () => {},\n closeFigmaUpload: () => {},\n});\n\nexport const useUploadFigmaToChat = () => {\n const context = useContext(UploadFigmaContext);\n if (!context) {\n throw new Error('useUploadFigmaToChat must be used within an UploadFigmaToChatProvider');\n }\n return context;\n};\n\nexport const UploadFigmaToChatProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFigmaUploadOpen, setIsFigmaUploadOpen] = useState(false); // Default to false\n const [submitOnFinish, setSubmitOnFinish] = useState(false);\n\n const openFigmaUpload = (submitOnFinishParam?: boolean) => {\n setIsFigmaUploadOpen(true);\n setSubmitOnFinish(submitOnFinishParam ?? false);\n };\n\n const closeFigmaUpload = () => setIsFigmaUploadOpen(false);\n\n return (\n <UploadFigmaContext.Provider\n value={{ isFigmaUploadOpen, submitOnFinish, openFigmaUpload, closeFigmaUpload }}\n >\n {isFigmaUploadOpen && <UploadFigmaModal />}\n {children}\n </UploadFigmaContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 1 - Input Figma URL\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaUrlInputStepProps {\n figmaUrl: string;\n setFigmaUrl: (url: string) => void;\n error: string | null; // Error state from useFigmaUpload\n}\n\nconst FigmaUrlInputStep = ({ figmaUrl, setFigmaUrl }: FigmaUrlInputStepProps) => {\n const { t } = useTranslations();\n const { isLoading } = useStepModal();\n const [showingTokenInput, setShowingTokenInput] = useState(!hasFigmaToken());\n const [figmaToken, setFigmaToken] = useState<string>(getFigmaToken);\n\n // Handle saving token and returning to URL input\n const handleSaveToken = () => {\n if (figmaToken.trim()) {\n saveFigmaToken(figmaToken);\n setShowingTokenInput(false);\n }\n };\n\n // If we need to show token step, render the token input\n if (showingTokenInput) {\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.token-title', 'Enter Figma API Token')}\n </Typography>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.token-description',\n 'To access your Figma designs, you need to provide a personal access token. This will be stored securely in your browser.'\n )}\n </Typography>\n <Link\n href=\"https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens\"\n isExternal\n >\n {t('chat.figma-upload.token-help', 'How to get a Figma API token')}\n </Link>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-token\"\n placeholder={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n aria-label={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n value={figmaToken}\n onChange={(e) => setFigmaToken(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"password\"\n />\n </Box>\n\n <Flex gap={2}>\n <Button onClick={handleSaveToken} disabled={!figmaToken.trim()} variant=\"secondary\">\n {t('chat.figma-upload.save-token', 'Save token')}\n </Button>\n <Button\n onClick={() => setShowingTokenInput(false)}\n variant=\"tertiary\"\n disabled={!hasFigmaToken()}\n >\n {t('chat.figma-upload.cancel', 'Cancel')}\n </Button>\n </Flex>\n </Flex>\n );\n }\n\n // Otherwise render the URL input\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\" width=\"100%\">\n <Flex justifyContent=\"space-between\" alignItems=\"center\" width=\"100%\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.title', 'Import Figma Design')}\n </Typography>\n <Button onClick={() => setShowingTokenInput(true)} variant=\"tertiary\" size=\"S\">\n {t('chat.figma-upload.edit-token', 'Edit API token')}\n </Button>\n </Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.description',\n 'Ask to turn your designs into schemas by attaching a link to one or multiple frames in your Figma files. (Max 15 frames)'\n )}\n </Typography>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-url\"\n placeholder={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n aria-label={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n value={figmaUrl}\n onChange={(e) => setFigmaUrl(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"url\"\n />\n </Box>\n\n {/* {error && (\n <Box padding={3} background=\"danger100\" color=\"danger600\" borderRadius=\"4px\" width=\"100%\">\n <Typography variant=\"pi\">{error}</Typography>\n </Box>\n )} */}\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 2 - Display Figma Images\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaImageDisplayStepProps {\n images: FigmaImage[];\n selectedImages: string[];\n setSelectedImages: (images: string[]) => void;\n}\n\nconst FigmaImageDisplayStep = ({\n images,\n selectedImages,\n setSelectedImages,\n}: FigmaImageDisplayStepProps) => {\n const { t } = useTranslations();\n\n // Handle select/deselect all\n const toggleSelectAll = () => {\n if (selectedImages.length === images.length) {\n // Deselect all if all or max allowed are selected\n setSelectedImages([]);\n } else {\n // Select all images up to the max limit\n const allImageIds = images.map((img) => img.id);\n setSelectedImages(allImageIds);\n }\n };\n\n if (images.length === 0) {\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"center\" padding={4}>\n <Typography variant=\"omega\">\n {t('chat.figma-upload.no-images', 'No frames found in the Figma file.')}\n </Typography>\n </Flex>\n );\n }\n\n // Handle individual frame selection\n const handleFrameSelection = (frameId: string) => {\n const newSelection = selectedImages.includes(frameId)\n ? selectedImages.filter((id) => id !== frameId)\n : [...selectedImages, frameId];\n\n setSelectedImages(newSelection);\n };\n\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"start\" width=\"100%\" height=\"min(45vh, 400px)\">\n <Flex justifyContent=\"space-between\" width=\"100%\" alignItems=\"center\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.select-images', 'Select Frames to Import')}\n </Typography>\n <Flex gap={3} alignItems=\"center\">\n <Typography>\n {selectedImages.length} of {images.length} selected\n </Typography>\n <Button onClick={toggleSelectAll} type=\"button\" variant=\"secondary\">\n {/* Determine if select all button should show \"Select All\" or \"Deselect All\" */}\n {selectedImages.length === images.length\n ? t('chat.figma-upload.deselect-all', 'Deselect All')\n : t('chat.figma-upload.select-all', 'Select All')}\n </Button>\n </Flex>\n </Flex>\n\n <Box paddingRight={4} width=\"100%\" style={{ overflowY: 'auto' }}>\n <Grid.Root gap={4}>\n {images.map((frame, index) => {\n const isSelected = selectedImages.includes(frame.id);\n return (\n <Grid.Item key={frame.id} col={6} xs={12} padding={'1px'}>\n <ImagePreview\n imageUrl={frame.url}\n imageName={frame.filename || `Frame ${index + 1}`}\n selected={isSelected}\n onSelect={() => handleFrameSelection(frame.id)}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\nexport const UploadFigmaModal = () => {\n const [figmaUrl, setFigmaUrl] = useState<string>('');\n const [figmaImages, setFigmaImages] = useState<FigmaImage[]>([]);\n const [selectedImages, setSelectedImages] = useState<string[]>([]);\n const { t } = useTranslations();\n\n const { addAttachments } = useAttachments();\n const { isFigmaUploadOpen, closeFigmaUpload, submitOnFinish } = useUploadFigmaToChat();\n const { input, setInput, sendMessage, openChat } = useStrapiChat();\n const { processFigmaUrl, isLoading, error } = useFigmaUpload({\n onSuccess: (images) => {\n setFigmaImages(images);\n // Initialize with first 15 images selected\n const initialSelection = images.slice(0, 15).map((img) => img.id);\n setSelectedImages(initialSelection);\n },\n });\n\n const handleImportStep = async () => {\n await processFigmaUrl(figmaUrl);\n return true;\n };\n\n // Validate if the URL is a valid Figma URL\n const isValidFigmaUrl = (url: string) => {\n if (!url) return false;\n try {\n const urlObj = new URL(url);\n return urlObj.hostname === 'www.figma.com' || urlObj.hostname === 'figma.com';\n } catch (e) {\n return false;\n }\n };\n\n const handleCancel = () => {\n // Reset all state on cancel\n setFigmaUrl('');\n setFigmaImages([]);\n setSelectedImages([]);\n closeFigmaUpload();\n };\n\n const handleComplete = () => {\n // Only attach the selected images\n const selectedFigmaImages = figmaImages.filter((img) => selectedImages.includes(img.id));\n if (selectedFigmaImages.length === 0) {\n closeFigmaUpload();\n return;\n }\n\n // Ensure chat is opened\n openChat();\n\n if (submitOnFinish) {\n // Auto-submit a message to chat with attachments\n sendMessage({\n role: 'user',\n parts: [\n { type: 'text', text: 'Create schemas from the attached images' },\n ...selectedFigmaImages,\n ],\n });\n\n closeFigmaUpload();\n } else {\n // If input is empty, set a predefined message\n if (!input) {\n setInput('Create schemas from the attached images');\n }\n addAttachments(selectedFigmaImages);\n closeFigmaUpload();\n }\n };\n\n return (\n <StepModal\n open={isFigmaUploadOpen}\n onOpenChange={(isOpen) => {\n if (!isOpen) handleCancel();\n }}\n title={t('chat.figma-upload.header', 'Import from Figma')}\n onCancel={handleCancel}\n onComplete={handleComplete}\n >\n <StepModal.Step\n title={t('chat.figma-upload.step1-title', 'Enter Figma URL')}\n nextLabel={t('chat.figma-upload.import-button', 'Import')}\n cancelLabel={t('form.button.cancel', 'Cancel')}\n disableNext={!figmaUrl || isLoading || !isValidFigmaUrl(figmaUrl)}\n onNext={handleImportStep}\n >\n <FigmaUrlInputStep figmaUrl={figmaUrl} setFigmaUrl={setFigmaUrl} error={error} />\n </StepModal.Step>\n\n <StepModal.Step\n title={t('chat.figma-upload.step2-title', 'Preview Images')}\n nextLabel={t('form.button.finish', 'Finish')}\n backLabel={t('form.button.back', 'Back')}\n disableNext={selectedImages.length === 0}\n >\n <FigmaImageDisplayStep\n images={figmaImages}\n selectedImages={selectedImages}\n setSelectedImages={setSelectedImages}\n />\n </StepModal.Step>\n </StepModal>\n );\n};\n"],"names":["UploadFigmaContext","createContext","isFigmaUploadOpen","submitOnFinish","openFigmaUpload","closeFigmaUpload","useUploadFigmaToChat","context","useContext","Error","UploadFigmaToChatProvider","children","setIsFigmaUploadOpen","useState","setSubmitOnFinish","submitOnFinishParam","_jsxs","Provider","value","_jsx","UploadFigmaModal","FigmaUrlInputStep","figmaUrl","setFigmaUrl","t","useTranslations","isLoading","useStepModal","showingTokenInput","setShowingTokenInput","hasFigmaToken","figmaToken","setFigmaToken","getFigmaToken","handleSaveToken","trim","saveFigmaToken","Flex","direction","gap","alignItems","Typography","variant","textColor","Link","href","isExternal","Box","width","TextInput","name","placeholder","aria-label","onChange","e","target","disabled","type","Button","onClick","justifyContent","size","FigmaImageDisplayStep","images","selectedImages","setSelectedImages","toggleSelectAll","length","allImageIds","map","img","id","padding","handleFrameSelection","frameId","newSelection","includes","filter","height","paddingRight","style","overflowY","Grid","Root","frame","index","isSelected","Item","col","xs","ImagePreview","imageUrl","url","imageName","filename","selected","onSelect","figmaImages","setFigmaImages","addAttachments","useAttachments","input","setInput","sendMessage","openChat","useStrapiChat","processFigmaUrl","error","useFigmaUpload","onSuccess","initialSelection","slice","handleImportStep","isValidFigmaUrl","urlObj","URL","hostname","handleCancel","handleComplete","selectedFigmaImages","role","parts","text","StepModal","open","onOpenChange","isOpen","title","onCancel","onComplete","Step","nextLabel","cancelLabel","disableNext","onNext","backLabel"],"mappings":"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"}
1
+ {"version":3,"file":"UploadFigmaModal.js","sources":["../../../../admin/src/components/AIChat/UploadFigmaModal.tsx"],"sourcesContent":["import { createContext, useContext, useState } from 'react';\n\nimport { Flex, Typography, Box, TextInput, Grid, Button, Link } from '@strapi/design-system'; // Added Link\n\nimport { ImagePreview } from './components/ImagePreview';\nimport { StepModal, useStepModal } from './components/StepModal';\nimport { useAttachments } from './hooks/useAttachments';\nimport {\n FigmaImage,\n useFigmaUpload,\n getFigmaToken,\n saveFigmaToken,\n hasFigmaToken,\n} from './hooks/useFigmaUpload';\nimport { useTranslations } from './hooks/useTranslations';\nimport { useStrapiChat } from './providers/ChatProvider';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface UploadFigmaContextType {\n isFigmaUploadOpen: boolean;\n submitOnFinish: boolean;\n openFigmaUpload: (submitOnFinish?: boolean) => void;\n closeFigmaUpload: () => void;\n}\n\nconst UploadFigmaContext = createContext<UploadFigmaContextType>({\n isFigmaUploadOpen: false,\n submitOnFinish: false,\n openFigmaUpload: () => {},\n closeFigmaUpload: () => {},\n});\n\nexport const useUploadFigmaToChat = () => {\n const context = useContext(UploadFigmaContext);\n if (!context) {\n throw new Error('useUploadFigmaToChat must be used within an UploadFigmaToChatProvider');\n }\n return context;\n};\n\nexport const UploadFigmaToChatProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFigmaUploadOpen, setIsFigmaUploadOpen] = useState(false); // Default to false\n const [submitOnFinish, setSubmitOnFinish] = useState(false);\n\n const openFigmaUpload = (submitOnFinishParam?: boolean) => {\n setIsFigmaUploadOpen(true);\n setSubmitOnFinish(submitOnFinishParam ?? false);\n };\n\n const closeFigmaUpload = () => setIsFigmaUploadOpen(false);\n\n return (\n <UploadFigmaContext.Provider\n value={{ isFigmaUploadOpen, submitOnFinish, openFigmaUpload, closeFigmaUpload }}\n >\n {isFigmaUploadOpen && <UploadFigmaModal />}\n {children}\n </UploadFigmaContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 1 - Input Figma URL\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaUrlInputStepProps {\n figmaUrl: string;\n setFigmaUrl: (url: string) => void;\n error: string | null; // Error state from useFigmaUpload\n}\n\nconst FigmaUrlInputStep = ({ figmaUrl, setFigmaUrl }: FigmaUrlInputStepProps) => {\n const { t } = useTranslations();\n const { isLoading } = useStepModal();\n const [showingTokenInput, setShowingTokenInput] = useState(!hasFigmaToken());\n const [figmaToken, setFigmaToken] = useState<string>(getFigmaToken);\n\n // Handle saving token and returning to URL input\n const handleSaveToken = () => {\n if (figmaToken.trim()) {\n saveFigmaToken(figmaToken);\n setShowingTokenInput(false);\n }\n };\n\n // If we need to show token step, render the token input\n if (showingTokenInput) {\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.token-title', 'Enter Figma API Token')}\n </Typography>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.token-description',\n 'To access your Figma designs, you need to provide a personal access token. This will be stored securely in your browser.'\n )}\n </Typography>\n <Link\n href=\"https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens\"\n isExternal\n >\n {t('chat.figma-upload.token-help', 'How to get a Figma API token')}\n </Link>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-token\"\n placeholder={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n aria-label={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n value={figmaToken}\n onChange={(e) => setFigmaToken(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"password\"\n />\n </Box>\n\n <Flex gap={2}>\n <Button onClick={handleSaveToken} disabled={!figmaToken.trim()} variant=\"secondary\">\n {t('chat.figma-upload.save-token', 'Save token')}\n </Button>\n <Button\n onClick={() => setShowingTokenInput(false)}\n variant=\"tertiary\"\n disabled={!hasFigmaToken()}\n >\n {t('chat.figma-upload.cancel', 'Cancel')}\n </Button>\n </Flex>\n </Flex>\n );\n }\n\n // Otherwise render the URL input\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\" width=\"100%\">\n <Flex justifyContent=\"space-between\" alignItems=\"center\" width=\"100%\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.title', 'Import Figma Design')}\n </Typography>\n <Button onClick={() => setShowingTokenInput(true)} variant=\"tertiary\" size=\"S\">\n {t('chat.figma-upload.edit-token', 'Edit API token')}\n </Button>\n </Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.description',\n 'Ask to turn your designs into schemas by attaching a link to one or multiple frames in your Figma files. (Max 15 frames)'\n )}\n </Typography>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-url\"\n placeholder={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n aria-label={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n value={figmaUrl}\n onChange={(e) => setFigmaUrl(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"url\"\n />\n </Box>\n\n {/* {error && (\n <Box padding={3} background=\"danger100\" color=\"danger600\" borderRadius=\"4px\" width=\"100%\">\n <Typography variant=\"pi\">{error}</Typography>\n </Box>\n )} */}\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 2 - Display Figma Images\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaImageDisplayStepProps {\n images: FigmaImage[];\n selectedImages: string[];\n setSelectedImages: (images: string[]) => void;\n}\n\nconst FigmaImageDisplayStep = ({\n images,\n selectedImages,\n setSelectedImages,\n}: FigmaImageDisplayStepProps) => {\n const { t } = useTranslations();\n\n // Handle select/deselect all\n const toggleSelectAll = () => {\n if (selectedImages.length === images.length) {\n // Deselect all if all or max allowed are selected\n setSelectedImages([]);\n } else {\n // Select all images up to the max limit\n const allImageIds = images.map((img) => img.id);\n setSelectedImages(allImageIds);\n }\n };\n\n if (images.length === 0) {\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"center\" padding={4}>\n <Typography variant=\"omega\">\n {t('chat.figma-upload.no-images', 'No frames found in the Figma file.')}\n </Typography>\n </Flex>\n );\n }\n\n // Handle individual frame selection\n const handleFrameSelection = (frameId: string) => {\n const newSelection = selectedImages.includes(frameId)\n ? selectedImages.filter((id) => id !== frameId)\n : [...selectedImages, frameId];\n\n setSelectedImages(newSelection);\n };\n\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"start\" width=\"100%\" height=\"min(45vh, 400px)\">\n <Flex justifyContent=\"space-between\" width=\"100%\" alignItems=\"center\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.select-images', 'Select Frames to Import')}\n </Typography>\n <Flex gap={3} alignItems=\"center\">\n <Typography>\n {selectedImages.length} of {images.length} selected\n </Typography>\n <Button onClick={toggleSelectAll} type=\"button\" variant=\"secondary\">\n {/* Determine if select all button should show \"Select All\" or \"Deselect All\" */}\n {selectedImages.length === images.length\n ? t('chat.figma-upload.deselect-all', 'Deselect All')\n : t('chat.figma-upload.select-all', 'Select All')}\n </Button>\n </Flex>\n </Flex>\n\n <Box paddingRight={4} width=\"100%\" style={{ overflowY: 'auto' }}>\n <Grid.Root gap={4}>\n {images.map((frame, index) => {\n const isSelected = selectedImages.includes(frame.id);\n return (\n <Grid.Item key={frame.id} col={6} xs={12} padding={'1px'}>\n <ImagePreview\n imageUrl={frame.url}\n imageName={frame.filename || `Frame ${index + 1}`}\n selected={isSelected}\n onSelect={() => handleFrameSelection(frame.id)}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\nexport const UploadFigmaModal = () => {\n const [figmaUrl, setFigmaUrl] = useState<string>('');\n const [figmaImages, setFigmaImages] = useState<FigmaImage[]>([]);\n const [selectedImages, setSelectedImages] = useState<string[]>([]);\n const { t } = useTranslations();\n\n const { addAttachments } = useAttachments();\n const { isFigmaUploadOpen, closeFigmaUpload, submitOnFinish } = useUploadFigmaToChat();\n const { input, setInput, sendMessage, openChat } = useStrapiChat();\n const { processFigmaUrl, isLoading, error } = useFigmaUpload({\n onSuccess: (images) => {\n setFigmaImages(images);\n // Initialize with first 15 images selected\n const initialSelection = images.slice(0, 15).map((img) => img.id);\n setSelectedImages(initialSelection);\n },\n });\n\n const handleImportStep = async () => {\n await processFigmaUrl(figmaUrl);\n return true;\n };\n\n // Validate if the URL is a valid Figma URL\n const isValidFigmaUrl = (url: string) => {\n if (!url) return false;\n try {\n const urlObj = new URL(url);\n return urlObj.hostname === 'www.figma.com' || urlObj.hostname === 'figma.com';\n } catch {\n return false;\n }\n };\n\n const handleCancel = () => {\n // Reset all state on cancel\n setFigmaUrl('');\n setFigmaImages([]);\n setSelectedImages([]);\n closeFigmaUpload();\n };\n\n const handleComplete = () => {\n // Only attach the selected images\n const selectedFigmaImages = figmaImages.filter((img) => selectedImages.includes(img.id));\n if (selectedFigmaImages.length === 0) {\n closeFigmaUpload();\n return;\n }\n\n // Ensure chat is opened\n openChat();\n\n if (submitOnFinish) {\n // Auto-submit a message to chat with attachments\n sendMessage({\n role: 'user',\n parts: [\n { type: 'text', text: 'Create schemas from the attached images' },\n ...selectedFigmaImages,\n ],\n });\n\n closeFigmaUpload();\n } else {\n // If input is empty, set a predefined message\n if (!input) {\n setInput('Create schemas from the attached images');\n }\n addAttachments(selectedFigmaImages);\n closeFigmaUpload();\n }\n };\n\n return (\n <StepModal\n open={isFigmaUploadOpen}\n onOpenChange={(isOpen) => {\n if (!isOpen) handleCancel();\n }}\n title={t('chat.figma-upload.header', 'Import from Figma')}\n onCancel={handleCancel}\n onComplete={handleComplete}\n >\n <StepModal.Step\n title={t('chat.figma-upload.step1-title', 'Enter Figma URL')}\n nextLabel={t('chat.figma-upload.import-button', 'Import')}\n cancelLabel={t('form.button.cancel', 'Cancel')}\n disableNext={!figmaUrl || isLoading || !isValidFigmaUrl(figmaUrl)}\n onNext={handleImportStep}\n >\n <FigmaUrlInputStep figmaUrl={figmaUrl} setFigmaUrl={setFigmaUrl} error={error} />\n </StepModal.Step>\n\n <StepModal.Step\n title={t('chat.figma-upload.step2-title', 'Preview Images')}\n nextLabel={t('form.button.finish', 'Finish')}\n backLabel={t('form.button.back', 'Back')}\n disableNext={selectedImages.length === 0}\n >\n <FigmaImageDisplayStep\n images={figmaImages}\n selectedImages={selectedImages}\n setSelectedImages={setSelectedImages}\n />\n </StepModal.Step>\n </StepModal>\n );\n};\n"],"names":["UploadFigmaContext","createContext","isFigmaUploadOpen","submitOnFinish","openFigmaUpload","closeFigmaUpload","useUploadFigmaToChat","context","useContext","Error","UploadFigmaToChatProvider","children","setIsFigmaUploadOpen","useState","setSubmitOnFinish","submitOnFinishParam","_jsxs","Provider","value","_jsx","UploadFigmaModal","FigmaUrlInputStep","figmaUrl","setFigmaUrl","t","useTranslations","isLoading","useStepModal","showingTokenInput","setShowingTokenInput","hasFigmaToken","figmaToken","setFigmaToken","getFigmaToken","handleSaveToken","trim","saveFigmaToken","Flex","direction","gap","alignItems","Typography","variant","textColor","Link","href","isExternal","Box","width","TextInput","name","placeholder","aria-label","onChange","e","target","disabled","type","Button","onClick","justifyContent","size","FigmaImageDisplayStep","images","selectedImages","setSelectedImages","toggleSelectAll","length","allImageIds","map","img","id","padding","handleFrameSelection","frameId","newSelection","includes","filter","height","paddingRight","style","overflowY","Grid","Root","frame","index","isSelected","Item","col","xs","ImagePreview","imageUrl","url","imageName","filename","selected","onSelect","figmaImages","setFigmaImages","addAttachments","useAttachments","input","setInput","sendMessage","openChat","useStrapiChat","processFigmaUrl","error","useFigmaUpload","onSuccess","initialSelection","slice","handleImportStep","isValidFigmaUrl","urlObj","URL","hostname","handleCancel","handleComplete","selectedFigmaImages","role","parts","text","StepModal","open","onOpenChange","isOpen","title","onCancel","onComplete","Step","nextLabel","cancelLabel","disableNext","onNext","backLabel"],"mappings":"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"}
@@ -293,7 +293,7 @@ const FigmaImageDisplayStep = ({ images, selectedImages, setSelectedImages })=>{
293
293
  try {
294
294
  const urlObj = new URL(url);
295
295
  return urlObj.hostname === 'www.figma.com' || urlObj.hostname === 'figma.com';
296
- } catch (e) {
296
+ } catch {
297
297
  return false;
298
298
  }
299
299
  };
@@ -1 +1 @@
1
- {"version":3,"file":"UploadFigmaModal.mjs","sources":["../../../../admin/src/components/AIChat/UploadFigmaModal.tsx"],"sourcesContent":["import { createContext, useContext, useState } from 'react';\n\nimport { Flex, Typography, Box, TextInput, Grid, Button, Link } from '@strapi/design-system'; // Added Link\n\nimport { ImagePreview } from './components/ImagePreview';\nimport { StepModal, useStepModal } from './components/StepModal';\nimport { useAttachments } from './hooks/useAttachments';\nimport {\n FigmaImage,\n useFigmaUpload,\n getFigmaToken,\n saveFigmaToken,\n hasFigmaToken,\n} from './hooks/useFigmaUpload';\nimport { useTranslations } from './hooks/useTranslations';\nimport { useStrapiChat } from './providers/ChatProvider';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface UploadFigmaContextType {\n isFigmaUploadOpen: boolean;\n submitOnFinish: boolean;\n openFigmaUpload: (submitOnFinish?: boolean) => void;\n closeFigmaUpload: () => void;\n}\n\nconst UploadFigmaContext = createContext<UploadFigmaContextType>({\n isFigmaUploadOpen: false,\n submitOnFinish: false,\n openFigmaUpload: () => {},\n closeFigmaUpload: () => {},\n});\n\nexport const useUploadFigmaToChat = () => {\n const context = useContext(UploadFigmaContext);\n if (!context) {\n throw new Error('useUploadFigmaToChat must be used within an UploadFigmaToChatProvider');\n }\n return context;\n};\n\nexport const UploadFigmaToChatProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFigmaUploadOpen, setIsFigmaUploadOpen] = useState(false); // Default to false\n const [submitOnFinish, setSubmitOnFinish] = useState(false);\n\n const openFigmaUpload = (submitOnFinishParam?: boolean) => {\n setIsFigmaUploadOpen(true);\n setSubmitOnFinish(submitOnFinishParam ?? false);\n };\n\n const closeFigmaUpload = () => setIsFigmaUploadOpen(false);\n\n return (\n <UploadFigmaContext.Provider\n value={{ isFigmaUploadOpen, submitOnFinish, openFigmaUpload, closeFigmaUpload }}\n >\n {isFigmaUploadOpen && <UploadFigmaModal />}\n {children}\n </UploadFigmaContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 1 - Input Figma URL\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaUrlInputStepProps {\n figmaUrl: string;\n setFigmaUrl: (url: string) => void;\n error: string | null; // Error state from useFigmaUpload\n}\n\nconst FigmaUrlInputStep = ({ figmaUrl, setFigmaUrl }: FigmaUrlInputStepProps) => {\n const { t } = useTranslations();\n const { isLoading } = useStepModal();\n const [showingTokenInput, setShowingTokenInput] = useState(!hasFigmaToken());\n const [figmaToken, setFigmaToken] = useState<string>(getFigmaToken);\n\n // Handle saving token and returning to URL input\n const handleSaveToken = () => {\n if (figmaToken.trim()) {\n saveFigmaToken(figmaToken);\n setShowingTokenInput(false);\n }\n };\n\n // If we need to show token step, render the token input\n if (showingTokenInput) {\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.token-title', 'Enter Figma API Token')}\n </Typography>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.token-description',\n 'To access your Figma designs, you need to provide a personal access token. This will be stored securely in your browser.'\n )}\n </Typography>\n <Link\n href=\"https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens\"\n isExternal\n >\n {t('chat.figma-upload.token-help', 'How to get a Figma API token')}\n </Link>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-token\"\n placeholder={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n aria-label={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n value={figmaToken}\n onChange={(e) => setFigmaToken(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"password\"\n />\n </Box>\n\n <Flex gap={2}>\n <Button onClick={handleSaveToken} disabled={!figmaToken.trim()} variant=\"secondary\">\n {t('chat.figma-upload.save-token', 'Save token')}\n </Button>\n <Button\n onClick={() => setShowingTokenInput(false)}\n variant=\"tertiary\"\n disabled={!hasFigmaToken()}\n >\n {t('chat.figma-upload.cancel', 'Cancel')}\n </Button>\n </Flex>\n </Flex>\n );\n }\n\n // Otherwise render the URL input\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\" width=\"100%\">\n <Flex justifyContent=\"space-between\" alignItems=\"center\" width=\"100%\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.title', 'Import Figma Design')}\n </Typography>\n <Button onClick={() => setShowingTokenInput(true)} variant=\"tertiary\" size=\"S\">\n {t('chat.figma-upload.edit-token', 'Edit API token')}\n </Button>\n </Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.description',\n 'Ask to turn your designs into schemas by attaching a link to one or multiple frames in your Figma files. (Max 15 frames)'\n )}\n </Typography>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-url\"\n placeholder={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n aria-label={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n value={figmaUrl}\n onChange={(e) => setFigmaUrl(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"url\"\n />\n </Box>\n\n {/* {error && (\n <Box padding={3} background=\"danger100\" color=\"danger600\" borderRadius=\"4px\" width=\"100%\">\n <Typography variant=\"pi\">{error}</Typography>\n </Box>\n )} */}\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 2 - Display Figma Images\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaImageDisplayStepProps {\n images: FigmaImage[];\n selectedImages: string[];\n setSelectedImages: (images: string[]) => void;\n}\n\nconst FigmaImageDisplayStep = ({\n images,\n selectedImages,\n setSelectedImages,\n}: FigmaImageDisplayStepProps) => {\n const { t } = useTranslations();\n\n // Handle select/deselect all\n const toggleSelectAll = () => {\n if (selectedImages.length === images.length) {\n // Deselect all if all or max allowed are selected\n setSelectedImages([]);\n } else {\n // Select all images up to the max limit\n const allImageIds = images.map((img) => img.id);\n setSelectedImages(allImageIds);\n }\n };\n\n if (images.length === 0) {\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"center\" padding={4}>\n <Typography variant=\"omega\">\n {t('chat.figma-upload.no-images', 'No frames found in the Figma file.')}\n </Typography>\n </Flex>\n );\n }\n\n // Handle individual frame selection\n const handleFrameSelection = (frameId: string) => {\n const newSelection = selectedImages.includes(frameId)\n ? selectedImages.filter((id) => id !== frameId)\n : [...selectedImages, frameId];\n\n setSelectedImages(newSelection);\n };\n\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"start\" width=\"100%\" height=\"min(45vh, 400px)\">\n <Flex justifyContent=\"space-between\" width=\"100%\" alignItems=\"center\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.select-images', 'Select Frames to Import')}\n </Typography>\n <Flex gap={3} alignItems=\"center\">\n <Typography>\n {selectedImages.length} of {images.length} selected\n </Typography>\n <Button onClick={toggleSelectAll} type=\"button\" variant=\"secondary\">\n {/* Determine if select all button should show \"Select All\" or \"Deselect All\" */}\n {selectedImages.length === images.length\n ? t('chat.figma-upload.deselect-all', 'Deselect All')\n : t('chat.figma-upload.select-all', 'Select All')}\n </Button>\n </Flex>\n </Flex>\n\n <Box paddingRight={4} width=\"100%\" style={{ overflowY: 'auto' }}>\n <Grid.Root gap={4}>\n {images.map((frame, index) => {\n const isSelected = selectedImages.includes(frame.id);\n return (\n <Grid.Item key={frame.id} col={6} xs={12} padding={'1px'}>\n <ImagePreview\n imageUrl={frame.url}\n imageName={frame.filename || `Frame ${index + 1}`}\n selected={isSelected}\n onSelect={() => handleFrameSelection(frame.id)}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\nexport const UploadFigmaModal = () => {\n const [figmaUrl, setFigmaUrl] = useState<string>('');\n const [figmaImages, setFigmaImages] = useState<FigmaImage[]>([]);\n const [selectedImages, setSelectedImages] = useState<string[]>([]);\n const { t } = useTranslations();\n\n const { addAttachments } = useAttachments();\n const { isFigmaUploadOpen, closeFigmaUpload, submitOnFinish } = useUploadFigmaToChat();\n const { input, setInput, sendMessage, openChat } = useStrapiChat();\n const { processFigmaUrl, isLoading, error } = useFigmaUpload({\n onSuccess: (images) => {\n setFigmaImages(images);\n // Initialize with first 15 images selected\n const initialSelection = images.slice(0, 15).map((img) => img.id);\n setSelectedImages(initialSelection);\n },\n });\n\n const handleImportStep = async () => {\n await processFigmaUrl(figmaUrl);\n return true;\n };\n\n // Validate if the URL is a valid Figma URL\n const isValidFigmaUrl = (url: string) => {\n if (!url) return false;\n try {\n const urlObj = new URL(url);\n return urlObj.hostname === 'www.figma.com' || urlObj.hostname === 'figma.com';\n } catch (e) {\n return false;\n }\n };\n\n const handleCancel = () => {\n // Reset all state on cancel\n setFigmaUrl('');\n setFigmaImages([]);\n setSelectedImages([]);\n closeFigmaUpload();\n };\n\n const handleComplete = () => {\n // Only attach the selected images\n const selectedFigmaImages = figmaImages.filter((img) => selectedImages.includes(img.id));\n if (selectedFigmaImages.length === 0) {\n closeFigmaUpload();\n return;\n }\n\n // Ensure chat is opened\n openChat();\n\n if (submitOnFinish) {\n // Auto-submit a message to chat with attachments\n sendMessage({\n role: 'user',\n parts: [\n { type: 'text', text: 'Create schemas from the attached images' },\n ...selectedFigmaImages,\n ],\n });\n\n closeFigmaUpload();\n } else {\n // If input is empty, set a predefined message\n if (!input) {\n setInput('Create schemas from the attached images');\n }\n addAttachments(selectedFigmaImages);\n closeFigmaUpload();\n }\n };\n\n return (\n <StepModal\n open={isFigmaUploadOpen}\n onOpenChange={(isOpen) => {\n if (!isOpen) handleCancel();\n }}\n title={t('chat.figma-upload.header', 'Import from Figma')}\n onCancel={handleCancel}\n onComplete={handleComplete}\n >\n <StepModal.Step\n title={t('chat.figma-upload.step1-title', 'Enter Figma URL')}\n nextLabel={t('chat.figma-upload.import-button', 'Import')}\n cancelLabel={t('form.button.cancel', 'Cancel')}\n disableNext={!figmaUrl || isLoading || !isValidFigmaUrl(figmaUrl)}\n onNext={handleImportStep}\n >\n <FigmaUrlInputStep figmaUrl={figmaUrl} setFigmaUrl={setFigmaUrl} error={error} />\n </StepModal.Step>\n\n <StepModal.Step\n title={t('chat.figma-upload.step2-title', 'Preview Images')}\n nextLabel={t('form.button.finish', 'Finish')}\n backLabel={t('form.button.back', 'Back')}\n disableNext={selectedImages.length === 0}\n >\n <FigmaImageDisplayStep\n images={figmaImages}\n selectedImages={selectedImages}\n setSelectedImages={setSelectedImages}\n />\n </StepModal.Step>\n </StepModal>\n );\n};\n"],"names":["UploadFigmaContext","createContext","isFigmaUploadOpen","submitOnFinish","openFigmaUpload","closeFigmaUpload","useUploadFigmaToChat","context","useContext","Error","UploadFigmaToChatProvider","children","setIsFigmaUploadOpen","useState","setSubmitOnFinish","submitOnFinishParam","_jsxs","Provider","value","_jsx","UploadFigmaModal","FigmaUrlInputStep","figmaUrl","setFigmaUrl","t","useTranslations","isLoading","useStepModal","showingTokenInput","setShowingTokenInput","hasFigmaToken","figmaToken","setFigmaToken","getFigmaToken","handleSaveToken","trim","saveFigmaToken","Flex","direction","gap","alignItems","Typography","variant","textColor","Link","href","isExternal","Box","width","TextInput","name","placeholder","aria-label","onChange","e","target","disabled","type","Button","onClick","justifyContent","size","FigmaImageDisplayStep","images","selectedImages","setSelectedImages","toggleSelectAll","length","allImageIds","map","img","id","padding","handleFrameSelection","frameId","newSelection","includes","filter","height","paddingRight","style","overflowY","Grid","Root","frame","index","isSelected","Item","col","xs","ImagePreview","imageUrl","url","imageName","filename","selected","onSelect","figmaImages","setFigmaImages","addAttachments","useAttachments","input","setInput","sendMessage","openChat","useStrapiChat","processFigmaUrl","error","useFigmaUpload","onSuccess","initialSelection","slice","handleImportStep","isValidFigmaUrl","urlObj","URL","hostname","handleCancel","handleComplete","selectedFigmaImages","role","parts","text","StepModal","open","onOpenChange","isOpen","title","onCancel","onComplete","Step","nextLabel","cancelLabel","disableNext","onNext","backLabel"],"mappings":"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"}
1
+ {"version":3,"file":"UploadFigmaModal.mjs","sources":["../../../../admin/src/components/AIChat/UploadFigmaModal.tsx"],"sourcesContent":["import { createContext, useContext, useState } from 'react';\n\nimport { Flex, Typography, Box, TextInput, Grid, Button, Link } from '@strapi/design-system'; // Added Link\n\nimport { ImagePreview } from './components/ImagePreview';\nimport { StepModal, useStepModal } from './components/StepModal';\nimport { useAttachments } from './hooks/useAttachments';\nimport {\n FigmaImage,\n useFigmaUpload,\n getFigmaToken,\n saveFigmaToken,\n hasFigmaToken,\n} from './hooks/useFigmaUpload';\nimport { useTranslations } from './hooks/useTranslations';\nimport { useStrapiChat } from './providers/ChatProvider';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface UploadFigmaContextType {\n isFigmaUploadOpen: boolean;\n submitOnFinish: boolean;\n openFigmaUpload: (submitOnFinish?: boolean) => void;\n closeFigmaUpload: () => void;\n}\n\nconst UploadFigmaContext = createContext<UploadFigmaContextType>({\n isFigmaUploadOpen: false,\n submitOnFinish: false,\n openFigmaUpload: () => {},\n closeFigmaUpload: () => {},\n});\n\nexport const useUploadFigmaToChat = () => {\n const context = useContext(UploadFigmaContext);\n if (!context) {\n throw new Error('useUploadFigmaToChat must be used within an UploadFigmaToChatProvider');\n }\n return context;\n};\n\nexport const UploadFigmaToChatProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFigmaUploadOpen, setIsFigmaUploadOpen] = useState(false); // Default to false\n const [submitOnFinish, setSubmitOnFinish] = useState(false);\n\n const openFigmaUpload = (submitOnFinishParam?: boolean) => {\n setIsFigmaUploadOpen(true);\n setSubmitOnFinish(submitOnFinishParam ?? false);\n };\n\n const closeFigmaUpload = () => setIsFigmaUploadOpen(false);\n\n return (\n <UploadFigmaContext.Provider\n value={{ isFigmaUploadOpen, submitOnFinish, openFigmaUpload, closeFigmaUpload }}\n >\n {isFigmaUploadOpen && <UploadFigmaModal />}\n {children}\n </UploadFigmaContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 1 - Input Figma URL\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaUrlInputStepProps {\n figmaUrl: string;\n setFigmaUrl: (url: string) => void;\n error: string | null; // Error state from useFigmaUpload\n}\n\nconst FigmaUrlInputStep = ({ figmaUrl, setFigmaUrl }: FigmaUrlInputStepProps) => {\n const { t } = useTranslations();\n const { isLoading } = useStepModal();\n const [showingTokenInput, setShowingTokenInput] = useState(!hasFigmaToken());\n const [figmaToken, setFigmaToken] = useState<string>(getFigmaToken);\n\n // Handle saving token and returning to URL input\n const handleSaveToken = () => {\n if (figmaToken.trim()) {\n saveFigmaToken(figmaToken);\n setShowingTokenInput(false);\n }\n };\n\n // If we need to show token step, render the token input\n if (showingTokenInput) {\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.token-title', 'Enter Figma API Token')}\n </Typography>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.token-description',\n 'To access your Figma designs, you need to provide a personal access token. This will be stored securely in your browser.'\n )}\n </Typography>\n <Link\n href=\"https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens\"\n isExternal\n >\n {t('chat.figma-upload.token-help', 'How to get a Figma API token')}\n </Link>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-token\"\n placeholder={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n aria-label={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n value={figmaToken}\n onChange={(e) => setFigmaToken(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"password\"\n />\n </Box>\n\n <Flex gap={2}>\n <Button onClick={handleSaveToken} disabled={!figmaToken.trim()} variant=\"secondary\">\n {t('chat.figma-upload.save-token', 'Save token')}\n </Button>\n <Button\n onClick={() => setShowingTokenInput(false)}\n variant=\"tertiary\"\n disabled={!hasFigmaToken()}\n >\n {t('chat.figma-upload.cancel', 'Cancel')}\n </Button>\n </Flex>\n </Flex>\n );\n }\n\n // Otherwise render the URL input\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\" width=\"100%\">\n <Flex justifyContent=\"space-between\" alignItems=\"center\" width=\"100%\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.title', 'Import Figma Design')}\n </Typography>\n <Button onClick={() => setShowingTokenInput(true)} variant=\"tertiary\" size=\"S\">\n {t('chat.figma-upload.edit-token', 'Edit API token')}\n </Button>\n </Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.description',\n 'Ask to turn your designs into schemas by attaching a link to one or multiple frames in your Figma files. (Max 15 frames)'\n )}\n </Typography>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-url\"\n placeholder={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n aria-label={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n value={figmaUrl}\n onChange={(e) => setFigmaUrl(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"url\"\n />\n </Box>\n\n {/* {error && (\n <Box padding={3} background=\"danger100\" color=\"danger600\" borderRadius=\"4px\" width=\"100%\">\n <Typography variant=\"pi\">{error}</Typography>\n </Box>\n )} */}\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 2 - Display Figma Images\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaImageDisplayStepProps {\n images: FigmaImage[];\n selectedImages: string[];\n setSelectedImages: (images: string[]) => void;\n}\n\nconst FigmaImageDisplayStep = ({\n images,\n selectedImages,\n setSelectedImages,\n}: FigmaImageDisplayStepProps) => {\n const { t } = useTranslations();\n\n // Handle select/deselect all\n const toggleSelectAll = () => {\n if (selectedImages.length === images.length) {\n // Deselect all if all or max allowed are selected\n setSelectedImages([]);\n } else {\n // Select all images up to the max limit\n const allImageIds = images.map((img) => img.id);\n setSelectedImages(allImageIds);\n }\n };\n\n if (images.length === 0) {\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"center\" padding={4}>\n <Typography variant=\"omega\">\n {t('chat.figma-upload.no-images', 'No frames found in the Figma file.')}\n </Typography>\n </Flex>\n );\n }\n\n // Handle individual frame selection\n const handleFrameSelection = (frameId: string) => {\n const newSelection = selectedImages.includes(frameId)\n ? selectedImages.filter((id) => id !== frameId)\n : [...selectedImages, frameId];\n\n setSelectedImages(newSelection);\n };\n\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"start\" width=\"100%\" height=\"min(45vh, 400px)\">\n <Flex justifyContent=\"space-between\" width=\"100%\" alignItems=\"center\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.select-images', 'Select Frames to Import')}\n </Typography>\n <Flex gap={3} alignItems=\"center\">\n <Typography>\n {selectedImages.length} of {images.length} selected\n </Typography>\n <Button onClick={toggleSelectAll} type=\"button\" variant=\"secondary\">\n {/* Determine if select all button should show \"Select All\" or \"Deselect All\" */}\n {selectedImages.length === images.length\n ? t('chat.figma-upload.deselect-all', 'Deselect All')\n : t('chat.figma-upload.select-all', 'Select All')}\n </Button>\n </Flex>\n </Flex>\n\n <Box paddingRight={4} width=\"100%\" style={{ overflowY: 'auto' }}>\n <Grid.Root gap={4}>\n {images.map((frame, index) => {\n const isSelected = selectedImages.includes(frame.id);\n return (\n <Grid.Item key={frame.id} col={6} xs={12} padding={'1px'}>\n <ImagePreview\n imageUrl={frame.url}\n imageName={frame.filename || `Frame ${index + 1}`}\n selected={isSelected}\n onSelect={() => handleFrameSelection(frame.id)}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\nexport const UploadFigmaModal = () => {\n const [figmaUrl, setFigmaUrl] = useState<string>('');\n const [figmaImages, setFigmaImages] = useState<FigmaImage[]>([]);\n const [selectedImages, setSelectedImages] = useState<string[]>([]);\n const { t } = useTranslations();\n\n const { addAttachments } = useAttachments();\n const { isFigmaUploadOpen, closeFigmaUpload, submitOnFinish } = useUploadFigmaToChat();\n const { input, setInput, sendMessage, openChat } = useStrapiChat();\n const { processFigmaUrl, isLoading, error } = useFigmaUpload({\n onSuccess: (images) => {\n setFigmaImages(images);\n // Initialize with first 15 images selected\n const initialSelection = images.slice(0, 15).map((img) => img.id);\n setSelectedImages(initialSelection);\n },\n });\n\n const handleImportStep = async () => {\n await processFigmaUrl(figmaUrl);\n return true;\n };\n\n // Validate if the URL is a valid Figma URL\n const isValidFigmaUrl = (url: string) => {\n if (!url) return false;\n try {\n const urlObj = new URL(url);\n return urlObj.hostname === 'www.figma.com' || urlObj.hostname === 'figma.com';\n } catch {\n return false;\n }\n };\n\n const handleCancel = () => {\n // Reset all state on cancel\n setFigmaUrl('');\n setFigmaImages([]);\n setSelectedImages([]);\n closeFigmaUpload();\n };\n\n const handleComplete = () => {\n // Only attach the selected images\n const selectedFigmaImages = figmaImages.filter((img) => selectedImages.includes(img.id));\n if (selectedFigmaImages.length === 0) {\n closeFigmaUpload();\n return;\n }\n\n // Ensure chat is opened\n openChat();\n\n if (submitOnFinish) {\n // Auto-submit a message to chat with attachments\n sendMessage({\n role: 'user',\n parts: [\n { type: 'text', text: 'Create schemas from the attached images' },\n ...selectedFigmaImages,\n ],\n });\n\n closeFigmaUpload();\n } else {\n // If input is empty, set a predefined message\n if (!input) {\n setInput('Create schemas from the attached images');\n }\n addAttachments(selectedFigmaImages);\n closeFigmaUpload();\n }\n };\n\n return (\n <StepModal\n open={isFigmaUploadOpen}\n onOpenChange={(isOpen) => {\n if (!isOpen) handleCancel();\n }}\n title={t('chat.figma-upload.header', 'Import from Figma')}\n onCancel={handleCancel}\n onComplete={handleComplete}\n >\n <StepModal.Step\n title={t('chat.figma-upload.step1-title', 'Enter Figma URL')}\n nextLabel={t('chat.figma-upload.import-button', 'Import')}\n cancelLabel={t('form.button.cancel', 'Cancel')}\n disableNext={!figmaUrl || isLoading || !isValidFigmaUrl(figmaUrl)}\n onNext={handleImportStep}\n >\n <FigmaUrlInputStep figmaUrl={figmaUrl} setFigmaUrl={setFigmaUrl} error={error} />\n </StepModal.Step>\n\n <StepModal.Step\n title={t('chat.figma-upload.step2-title', 'Preview Images')}\n nextLabel={t('form.button.finish', 'Finish')}\n backLabel={t('form.button.back', 'Back')}\n disableNext={selectedImages.length === 0}\n >\n <FigmaImageDisplayStep\n images={figmaImages}\n selectedImages={selectedImages}\n setSelectedImages={setSelectedImages}\n />\n </StepModal.Step>\n </StepModal>\n );\n};\n"],"names":["UploadFigmaContext","createContext","isFigmaUploadOpen","submitOnFinish","openFigmaUpload","closeFigmaUpload","useUploadFigmaToChat","context","useContext","Error","UploadFigmaToChatProvider","children","setIsFigmaUploadOpen","useState","setSubmitOnFinish","submitOnFinishParam","_jsxs","Provider","value","_jsx","UploadFigmaModal","FigmaUrlInputStep","figmaUrl","setFigmaUrl","t","useTranslations","isLoading","useStepModal","showingTokenInput","setShowingTokenInput","hasFigmaToken","figmaToken","setFigmaToken","getFigmaToken","handleSaveToken","trim","saveFigmaToken","Flex","direction","gap","alignItems","Typography","variant","textColor","Link","href","isExternal","Box","width","TextInput","name","placeholder","aria-label","onChange","e","target","disabled","type","Button","onClick","justifyContent","size","FigmaImageDisplayStep","images","selectedImages","setSelectedImages","toggleSelectAll","length","allImageIds","map","img","id","padding","handleFrameSelection","frameId","newSelection","includes","filter","height","paddingRight","style","overflowY","Grid","Root","frame","index","isSelected","Item","col","xs","ImagePreview","imageUrl","url","imageName","filename","selected","onSelect","figmaImages","setFigmaImages","addAttachments","useAttachments","input","setInput","sendMessage","openChat","useStrapiChat","processFigmaUrl","error","useFigmaUpload","onSuccess","initialSelection","slice","handleImportStep","isValidFigmaUrl","urlObj","URL","hostname","handleCancel","handleComplete","selectedFigmaImages","role","parts","text","StepModal","open","onOpenChange","isOpen","title","onCancel","onComplete","Step","nextLabel","cancelLabel","disableNext","onNext","backLabel"],"mappings":"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"}
@@ -45,7 +45,7 @@ const Base64Img = ({ src, alt, inferSize = false, onLoad: externalOnLoad, onErro
45
45
  setIsLoading(false);
46
46
  return;
47
47
  }
48
- } catch (e) {
48
+ } catch {
49
49
  // If URL parsing fails, continue with the fetch attempt
50
50
  }
51
51
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"Base64Image.js","sources":["../../../../../admin/src/components/AIChat/components/Base64Image.tsx"],"sourcesContent":["import { useState, useEffect, ImgHTMLAttributes } from 'react';\n\nimport { Flex, Loader } from '@strapi/design-system';\nimport { CrossCircle } from '@strapi/icons';\n\nconst blobToBase64 = (blob: Blob): Promise<string | ArrayBuffer | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\n// Check if a string is already a data URL (base64 image)\nconst isBase64Image = (src: string): boolean => {\n return src.startsWith('data:image/');\n};\n\ninterface Base64ImgProps extends ImgHTMLAttributes<HTMLImageElement> {\n src: string;\n inferSize?: boolean;\n onLoad?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n}\n\nexport const Base64Img: React.FC<Base64ImgProps> = ({\n src,\n alt,\n inferSize = false,\n onLoad: externalOnLoad,\n onError: externalOnError,\n ...rest\n}) => {\n const [base64Src, setBase64Src] = useState<string | null>(null);\n const [dimensions, setDimensions] = useState<{ width?: number; height?: number }>({});\n const [isLoading, setIsLoading] = useState(true);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n const fetchAndConvert = async () => {\n setIsLoading(true);\n setHasError(false);\n\n // If src is already a base64 string, use it directly\n if (isBase64Image(src)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n\n try {\n // TODO: Find a better way of doing this\n // If url is from strapi-ai-staging.s3.us-east-1.amazonaws.com or strapi-ai-production.s3.us-east-1.amazonaws.com, use it directly\n const url = new URL(src);\n const allowedDomains = [\n 'strapi-ai-staging.s3.us-east-1.amazonaws.com',\n 'strapi-ai-production.s3.us-east-1.amazonaws.com',\n ];\n\n if (allowedDomains.includes(url.hostname)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n } catch (e) {\n // If URL parsing fails, continue with the fetch attempt\n }\n\n try {\n // Only fetch if it's a URL and not already a base64 string\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const blob = await response.blob();\n const dataUrl = await blobToBase64(blob);\n setBase64Src(dataUrl as string);\n setIsLoading(false);\n } catch (error) {\n console.error('Error converting image to base64:', error);\n setHasError(true);\n setIsLoading(false);\n }\n };\n\n fetchAndConvert();\n }, [src, externalOnError]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {\n if (inferSize) {\n const { naturalWidth, naturalHeight } = e.currentTarget;\n setDimensions({ width: naturalWidth, height: naturalHeight });\n }\n\n if (externalOnLoad) {\n externalOnLoad(e);\n }\n };\n\n if (isLoading) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <Loader small />\n </Flex>\n );\n }\n\n if (hasError) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <CrossCircle width={24} height={24} fill=\"danger600\" />\n </Flex>\n );\n }\n\n // Build props for the img element\n const imgProps: ImgHTMLAttributes<HTMLImageElement> = {\n src: base64Src || '',\n alt,\n onLoad: handleImageLoad,\n ...rest,\n };\n\n // If inferSize is enabled and width/height weren't explicitly provided,\n // merge the inferred dimensions into the props once available.\n if (inferSize && !rest.width && !rest.height && dimensions.width && dimensions.height) {\n imgProps.width = dimensions.width;\n imgProps.height = dimensions.height;\n }\n\n return base64Src ? <img {...imgProps} /> : null;\n};\n"],"names":["blobToBase64","blob","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","readAsDataURL","isBase64Image","src","startsWith","Base64Img","alt","inferSize","onLoad","externalOnLoad","onError","externalOnError","rest","base64Src","setBase64Src","useState","dimensions","setDimensions","isLoading","setIsLoading","hasError","setHasError","useEffect","fetchAndConvert","url","URL","allowedDomains","includes","hostname","e","response","fetch","ok","Error","status","dataUrl","error","console","handleImageLoad","naturalWidth","naturalHeight","currentTarget","width","height","_jsx","Flex","direction","gap","alignItems","Loader","small","CrossCircle","fill","imgProps","img"],"mappings":"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"}
1
+ {"version":3,"file":"Base64Image.js","sources":["../../../../../admin/src/components/AIChat/components/Base64Image.tsx"],"sourcesContent":["import { useState, useEffect, ImgHTMLAttributes } from 'react';\n\nimport { Flex, Loader } from '@strapi/design-system';\nimport { CrossCircle } from '@strapi/icons';\n\nconst blobToBase64 = (blob: Blob): Promise<string | ArrayBuffer | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\n// Check if a string is already a data URL (base64 image)\nconst isBase64Image = (src: string): boolean => {\n return src.startsWith('data:image/');\n};\n\ninterface Base64ImgProps extends ImgHTMLAttributes<HTMLImageElement> {\n src: string;\n inferSize?: boolean;\n onLoad?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n}\n\nexport const Base64Img: React.FC<Base64ImgProps> = ({\n src,\n alt,\n inferSize = false,\n onLoad: externalOnLoad,\n onError: externalOnError,\n ...rest\n}) => {\n const [base64Src, setBase64Src] = useState<string | null>(null);\n const [dimensions, setDimensions] = useState<{ width?: number; height?: number }>({});\n const [isLoading, setIsLoading] = useState(true);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n const fetchAndConvert = async () => {\n setIsLoading(true);\n setHasError(false);\n\n // If src is already a base64 string, use it directly\n if (isBase64Image(src)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n\n try {\n // TODO: Find a better way of doing this\n // If url is from strapi-ai-staging.s3.us-east-1.amazonaws.com or strapi-ai-production.s3.us-east-1.amazonaws.com, use it directly\n const url = new URL(src);\n const allowedDomains = [\n 'strapi-ai-staging.s3.us-east-1.amazonaws.com',\n 'strapi-ai-production.s3.us-east-1.amazonaws.com',\n ];\n\n if (allowedDomains.includes(url.hostname)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n } catch {\n // If URL parsing fails, continue with the fetch attempt\n }\n\n try {\n // Only fetch if it's a URL and not already a base64 string\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const blob = await response.blob();\n const dataUrl = await blobToBase64(blob);\n setBase64Src(dataUrl as string);\n setIsLoading(false);\n } catch (error) {\n console.error('Error converting image to base64:', error);\n setHasError(true);\n setIsLoading(false);\n }\n };\n\n fetchAndConvert();\n }, [src, externalOnError]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {\n if (inferSize) {\n const { naturalWidth, naturalHeight } = e.currentTarget;\n setDimensions({ width: naturalWidth, height: naturalHeight });\n }\n\n if (externalOnLoad) {\n externalOnLoad(e);\n }\n };\n\n if (isLoading) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <Loader small />\n </Flex>\n );\n }\n\n if (hasError) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <CrossCircle width={24} height={24} fill=\"danger600\" />\n </Flex>\n );\n }\n\n // Build props for the img element\n const imgProps: ImgHTMLAttributes<HTMLImageElement> = {\n src: base64Src || '',\n alt,\n onLoad: handleImageLoad,\n ...rest,\n };\n\n // If inferSize is enabled and width/height weren't explicitly provided,\n // merge the inferred dimensions into the props once available.\n if (inferSize && !rest.width && !rest.height && dimensions.width && dimensions.height) {\n imgProps.width = dimensions.width;\n imgProps.height = dimensions.height;\n }\n\n return base64Src ? <img {...imgProps} /> : null;\n};\n"],"names":["blobToBase64","blob","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","readAsDataURL","isBase64Image","src","startsWith","Base64Img","alt","inferSize","onLoad","externalOnLoad","onError","externalOnError","rest","base64Src","setBase64Src","useState","dimensions","setDimensions","isLoading","setIsLoading","hasError","setHasError","useEffect","fetchAndConvert","url","URL","allowedDomains","includes","hostname","response","fetch","ok","Error","status","dataUrl","error","console","handleImageLoad","e","naturalWidth","naturalHeight","currentTarget","width","height","_jsx","Flex","direction","gap","alignItems","Loader","small","CrossCircle","fill","imgProps","img"],"mappings":"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"}
@@ -43,7 +43,7 @@ const Base64Img = ({ src, alt, inferSize = false, onLoad: externalOnLoad, onErro
43
43
  setIsLoading(false);
44
44
  return;
45
45
  }
46
- } catch (e) {
46
+ } catch {
47
47
  // If URL parsing fails, continue with the fetch attempt
48
48
  }
49
49
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"Base64Image.mjs","sources":["../../../../../admin/src/components/AIChat/components/Base64Image.tsx"],"sourcesContent":["import { useState, useEffect, ImgHTMLAttributes } from 'react';\n\nimport { Flex, Loader } from '@strapi/design-system';\nimport { CrossCircle } from '@strapi/icons';\n\nconst blobToBase64 = (blob: Blob): Promise<string | ArrayBuffer | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\n// Check if a string is already a data URL (base64 image)\nconst isBase64Image = (src: string): boolean => {\n return src.startsWith('data:image/');\n};\n\ninterface Base64ImgProps extends ImgHTMLAttributes<HTMLImageElement> {\n src: string;\n inferSize?: boolean;\n onLoad?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n}\n\nexport const Base64Img: React.FC<Base64ImgProps> = ({\n src,\n alt,\n inferSize = false,\n onLoad: externalOnLoad,\n onError: externalOnError,\n ...rest\n}) => {\n const [base64Src, setBase64Src] = useState<string | null>(null);\n const [dimensions, setDimensions] = useState<{ width?: number; height?: number }>({});\n const [isLoading, setIsLoading] = useState(true);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n const fetchAndConvert = async () => {\n setIsLoading(true);\n setHasError(false);\n\n // If src is already a base64 string, use it directly\n if (isBase64Image(src)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n\n try {\n // TODO: Find a better way of doing this\n // If url is from strapi-ai-staging.s3.us-east-1.amazonaws.com or strapi-ai-production.s3.us-east-1.amazonaws.com, use it directly\n const url = new URL(src);\n const allowedDomains = [\n 'strapi-ai-staging.s3.us-east-1.amazonaws.com',\n 'strapi-ai-production.s3.us-east-1.amazonaws.com',\n ];\n\n if (allowedDomains.includes(url.hostname)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n } catch (e) {\n // If URL parsing fails, continue with the fetch attempt\n }\n\n try {\n // Only fetch if it's a URL and not already a base64 string\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const blob = await response.blob();\n const dataUrl = await blobToBase64(blob);\n setBase64Src(dataUrl as string);\n setIsLoading(false);\n } catch (error) {\n console.error('Error converting image to base64:', error);\n setHasError(true);\n setIsLoading(false);\n }\n };\n\n fetchAndConvert();\n }, [src, externalOnError]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {\n if (inferSize) {\n const { naturalWidth, naturalHeight } = e.currentTarget;\n setDimensions({ width: naturalWidth, height: naturalHeight });\n }\n\n if (externalOnLoad) {\n externalOnLoad(e);\n }\n };\n\n if (isLoading) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <Loader small />\n </Flex>\n );\n }\n\n if (hasError) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <CrossCircle width={24} height={24} fill=\"danger600\" />\n </Flex>\n );\n }\n\n // Build props for the img element\n const imgProps: ImgHTMLAttributes<HTMLImageElement> = {\n src: base64Src || '',\n alt,\n onLoad: handleImageLoad,\n ...rest,\n };\n\n // If inferSize is enabled and width/height weren't explicitly provided,\n // merge the inferred dimensions into the props once available.\n if (inferSize && !rest.width && !rest.height && dimensions.width && dimensions.height) {\n imgProps.width = dimensions.width;\n imgProps.height = dimensions.height;\n }\n\n return base64Src ? <img {...imgProps} /> : null;\n};\n"],"names":["blobToBase64","blob","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","readAsDataURL","isBase64Image","src","startsWith","Base64Img","alt","inferSize","onLoad","externalOnLoad","onError","externalOnError","rest","base64Src","setBase64Src","useState","dimensions","setDimensions","isLoading","setIsLoading","hasError","setHasError","useEffect","fetchAndConvert","url","URL","allowedDomains","includes","hostname","e","response","fetch","ok","Error","status","dataUrl","error","console","handleImageLoad","naturalWidth","naturalHeight","currentTarget","width","height","_jsx","Flex","direction","gap","alignItems","Loader","small","CrossCircle","fill","imgProps","img"],"mappings":"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"}
1
+ {"version":3,"file":"Base64Image.mjs","sources":["../../../../../admin/src/components/AIChat/components/Base64Image.tsx"],"sourcesContent":["import { useState, useEffect, ImgHTMLAttributes } from 'react';\n\nimport { Flex, Loader } from '@strapi/design-system';\nimport { CrossCircle } from '@strapi/icons';\n\nconst blobToBase64 = (blob: Blob): Promise<string | ArrayBuffer | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\n// Check if a string is already a data URL (base64 image)\nconst isBase64Image = (src: string): boolean => {\n return src.startsWith('data:image/');\n};\n\ninterface Base64ImgProps extends ImgHTMLAttributes<HTMLImageElement> {\n src: string;\n inferSize?: boolean;\n onLoad?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n}\n\nexport const Base64Img: React.FC<Base64ImgProps> = ({\n src,\n alt,\n inferSize = false,\n onLoad: externalOnLoad,\n onError: externalOnError,\n ...rest\n}) => {\n const [base64Src, setBase64Src] = useState<string | null>(null);\n const [dimensions, setDimensions] = useState<{ width?: number; height?: number }>({});\n const [isLoading, setIsLoading] = useState(true);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n const fetchAndConvert = async () => {\n setIsLoading(true);\n setHasError(false);\n\n // If src is already a base64 string, use it directly\n if (isBase64Image(src)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n\n try {\n // TODO: Find a better way of doing this\n // If url is from strapi-ai-staging.s3.us-east-1.amazonaws.com or strapi-ai-production.s3.us-east-1.amazonaws.com, use it directly\n const url = new URL(src);\n const allowedDomains = [\n 'strapi-ai-staging.s3.us-east-1.amazonaws.com',\n 'strapi-ai-production.s3.us-east-1.amazonaws.com',\n ];\n\n if (allowedDomains.includes(url.hostname)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n } catch {\n // If URL parsing fails, continue with the fetch attempt\n }\n\n try {\n // Only fetch if it's a URL and not already a base64 string\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const blob = await response.blob();\n const dataUrl = await blobToBase64(blob);\n setBase64Src(dataUrl as string);\n setIsLoading(false);\n } catch (error) {\n console.error('Error converting image to base64:', error);\n setHasError(true);\n setIsLoading(false);\n }\n };\n\n fetchAndConvert();\n }, [src, externalOnError]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {\n if (inferSize) {\n const { naturalWidth, naturalHeight } = e.currentTarget;\n setDimensions({ width: naturalWidth, height: naturalHeight });\n }\n\n if (externalOnLoad) {\n externalOnLoad(e);\n }\n };\n\n if (isLoading) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <Loader small />\n </Flex>\n );\n }\n\n if (hasError) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <CrossCircle width={24} height={24} fill=\"danger600\" />\n </Flex>\n );\n }\n\n // Build props for the img element\n const imgProps: ImgHTMLAttributes<HTMLImageElement> = {\n src: base64Src || '',\n alt,\n onLoad: handleImageLoad,\n ...rest,\n };\n\n // If inferSize is enabled and width/height weren't explicitly provided,\n // merge the inferred dimensions into the props once available.\n if (inferSize && !rest.width && !rest.height && dimensions.width && dimensions.height) {\n imgProps.width = dimensions.width;\n imgProps.height = dimensions.height;\n }\n\n return base64Src ? <img {...imgProps} /> : null;\n};\n"],"names":["blobToBase64","blob","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","readAsDataURL","isBase64Image","src","startsWith","Base64Img","alt","inferSize","onLoad","externalOnLoad","onError","externalOnError","rest","base64Src","setBase64Src","useState","dimensions","setDimensions","isLoading","setIsLoading","hasError","setHasError","useEffect","fetchAndConvert","url","URL","allowedDomains","includes","hostname","response","fetch","ok","Error","status","dataUrl","error","console","handleImageLoad","e","naturalWidth","naturalHeight","currentTarget","width","height","_jsx","Flex","direction","gap","alignItems","Loader","small","CrossCircle","fill","imgProps","img"],"mappings":"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"}
@@ -39,7 +39,7 @@ const CHAT_TOO_LONG_ERROR = 'Chat too long';
39
39
  method: 'POST',
40
40
  headers: isJson ? {
41
41
  'Content-Type': 'application/json',
42
- ...options.headers || {}
42
+ ...options.headers
43
43
  } : options.headers,
44
44
  body: options.formData ? options.formData : isJson ? JSON.stringify(options.body || {}) : undefined,
45
45
  ctx: {
@@ -1 +1 @@
1
- {"version":3,"file":"useAIFetch.js","sources":["../../../../../admin/src/components/AIChat/hooks/useAIFetch.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-namespace */\n\n/**\n * In charge of fetching data from Strapi AI endpoints\n */\n\nimport { useState } from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAppInfo } from '@strapi/admin/strapi-admin';\nimport { useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';\nimport { DefaultChatTransport } from 'ai';\n\nimport { fetchAI, makeChatFetch, safeParseJson } from '../lib/aiClient';\nimport { STRAPI_AI_CHAT_URL, STRAPI_AI_URL } from '../lib/constants';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Chat title\n */\nexport namespace GenerateTitle {\n export interface Request {\n body: {\n chatId: string;\n message: string;\n };\n }\n export interface Response {\n data: {\n title: string;\n };\n error?: string;\n }\n}\n\n/**\n * Upload a project to the chat\n */\nexport namespace UploadProject {\n export interface Request {\n body: {\n chatId: string;\n name: string;\n type: 'code';\n files: {\n path: string;\n content: string;\n }[];\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Send chat feedback\n */\nexport type FeedbackReasonIds =\n | 'invalid_schema'\n | 'bad_recommendation'\n | 'slow'\n | 'instructions_ignored'\n | 'being_lazy'\n | 'other';\n\nnamespace SendFeedback {\n export interface Request {\n body: {\n chatId: string;\n type: 'upvote' | 'downvote';\n feedback?: string;\n reasons?: FeedbackReasonIds[];\n messageId: string;\n messages: UIMessage[];\n schemas: Schema[];\n };\n }\n}\n\n/**\n * Upload media\n */\nexport namespace UploadMedia {\n export interface Request {\n body: {\n url: string; // base64 image\n filename: string;\n chatId: string;\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Collection of API endpoints and their corresponding request/response types\n */\ntype AIEndpoints = {\n '/schemas/chat/generate-title': {\n request: GenerateTitle.Request;\n response: GenerateTitle.Response;\n };\n '/schemas/chat/attachment': {\n request: UploadProject.Request;\n response: UploadProject.Response;\n };\n '/schemas/chat/feedback': {\n request: SendFeedback.Request;\n response: void;\n };\n '/media/upload': {\n request: UploadMedia.Request;\n response: UploadMedia.Response;\n };\n};\n\n// Helper type to extract the request type for a given endpoint\ntype RequestType<T extends keyof AIEndpoints> = AIEndpoints[T]['request'];\n\n// Helper type to extract the response type for a given endpoint\ntype ResponseType<T extends keyof AIEndpoints> = AIEndpoints[T]['response'];\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\nexport const TOO_MANY_REQUESTS_ERROR = 'Too many requests';\nexport const LICENSE_LIMIT_REACHED_ERROR = 'License limit';\nexport const LICENSE_LIMIT_EXCEEDED_ERROR = 'AI credit limit exceeded';\nexport const CHAT_TOO_LONG_ERROR = 'Chat too long';\nexport const ATTACHMENT_TOO_BIG_ERROR = 'Attachment too big';\nexport const ATTACHMENT_NOT_FOUND_ERROR = 'Attachment not found';\nexport const INVALID_REQUEST_ERROR = 'Invalid request';\n\n/**\n * Base hook factory for making type-safe API calls to Strapi AI endpoints.\n * Creates a hook specific to a single endpoint.\n */\nexport const createAIFetchHook = <T extends keyof AIEndpoints>(endpoint: T) => {\n return () => {\n const strapiVersion = useAppInfo('useAIFetch', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIFetch-user', (state) => state.userId);\n const aiUsage = useGetAiUsageQuery(undefined, { refetchOnMountOrArgChange: true });\n\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * Make a type-safe API call to the specified Strapi AI endpoint with retry logic\n */\n const fetchData = async (\n options: Omit<RequestInit, 'body'> & Partial<RequestType<T>> & { formData?: FormData } = {}\n ): Promise<ResponseType<T> | null> => {\n setIsPending(true);\n setError(null);\n\n try {\n const fullUrl = `${STRAPI_AI_URL}${endpoint}`;\n const isJson = !!options.body && !options.formData;\n\n const response = await fetchAI(fullUrl, {\n method: 'POST',\n headers: isJson\n ? { 'Content-Type': 'application/json', ...(options.headers || {}) }\n : options.headers,\n body: options.formData\n ? options.formData\n : isJson\n ? JSON.stringify(options.body || {})\n : undefined,\n ctx: { strapiVersion, projectId, userId },\n });\n // refetch ai usage data on every successful request\n aiUsage.refetch();\n\n const body = await safeParseJson(response);\n\n if (!response.ok) {\n throw new Error(`Error: ${response.statusText}`);\n }\n return body as ResponseType<T>;\n } catch (err) {\n setError(err instanceof Error ? err.message : `Failed to fetch data from ${endpoint}`);\n return null;\n } finally {\n setIsPending(false);\n }\n };\n\n return {\n isPending,\n error,\n fetch: fetchData,\n };\n };\n};\n\n// Create specific hooks for each endpoint\nexport const useFetchGenerateTitle = createAIFetchHook('/schemas/chat/generate-title');\nexport const useFetchUploadProject = createAIFetchHook('/schemas/chat/attachment');\nexport const useFetchSendFeedback = createAIFetchHook('/schemas/chat/feedback');\nexport const useFetchUploadMedia = createAIFetchHook('/media/upload');\n\n/**\n * Hook wrapper for AI SDK's useChat with Strapi-specific configuration\n */\nexport const useAIChat: typeof useChat = (props) => {\n const strapiVersion = useAppInfo('useAIChat', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIChat-user', (state) => state.userId);\n\n const customFetch = makeChatFetch({ strapiVersion, projectId, userId });\n\n return useChat({\n ...props,\n transport: new DefaultChatTransport({\n api: STRAPI_AI_CHAT_URL,\n fetch: customFetch,\n }),\n });\n};\n"],"names":["TOO_MANY_REQUESTS_ERROR","LICENSE_LIMIT_REACHED_ERROR","LICENSE_LIMIT_EXCEEDED_ERROR","CHAT_TOO_LONG_ERROR","createAIFetchHook","endpoint","strapiVersion","useAppInfo","state","projectId","userId","aiUsage","useGetAiUsageQuery","undefined","refetchOnMountOrArgChange","isPending","setIsPending","useState","error","setError","fetchData","options","fullUrl","STRAPI_AI_URL","isJson","body","formData","response","fetchAI","method","headers","JSON","stringify","ctx","refetch","safeParseJson","ok","Error","statusText","err","message","fetch","useFetchGenerateTitle","useFetchUploadProject","useFetchSendFeedback","useFetchUploadMedia","useAIChat","props","customFetch","makeChatFetch","useChat","transport","DefaultChatTransport","api","STRAPI_AI_CHAT_URL"],"mappings":"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"}
1
+ {"version":3,"file":"useAIFetch.js","sources":["../../../../../admin/src/components/AIChat/hooks/useAIFetch.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-namespace */\n\n/**\n * In charge of fetching data from Strapi AI endpoints\n */\n\nimport { useState } from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAppInfo } from '@strapi/admin/strapi-admin';\nimport { useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';\nimport { DefaultChatTransport } from 'ai';\n\nimport { fetchAI, makeChatFetch, safeParseJson } from '../lib/aiClient';\nimport { STRAPI_AI_CHAT_URL, STRAPI_AI_URL } from '../lib/constants';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Chat title\n */\nexport namespace GenerateTitle {\n export interface Request {\n body: {\n chatId: string;\n message: string;\n };\n }\n export interface Response {\n data: {\n title: string;\n };\n error?: string;\n }\n}\n\n/**\n * Upload a project to the chat\n */\nexport namespace UploadProject {\n export interface Request {\n body: {\n chatId: string;\n name: string;\n type: 'code';\n files: {\n path: string;\n content: string;\n }[];\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Send chat feedback\n */\nexport type FeedbackReasonIds =\n | 'invalid_schema'\n | 'bad_recommendation'\n | 'slow'\n | 'instructions_ignored'\n | 'being_lazy'\n | 'other';\n\nnamespace SendFeedback {\n export interface Request {\n body: {\n chatId: string;\n type: 'upvote' | 'downvote';\n feedback?: string;\n reasons?: FeedbackReasonIds[];\n messageId: string;\n messages: UIMessage[];\n schemas: Schema[];\n };\n }\n}\n\n/**\n * Upload media\n */\nexport namespace UploadMedia {\n export interface Request {\n body: {\n url: string; // base64 image\n filename: string;\n chatId: string;\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Collection of API endpoints and their corresponding request/response types\n */\ntype AIEndpoints = {\n '/schemas/chat/generate-title': {\n request: GenerateTitle.Request;\n response: GenerateTitle.Response;\n };\n '/schemas/chat/attachment': {\n request: UploadProject.Request;\n response: UploadProject.Response;\n };\n '/schemas/chat/feedback': {\n request: SendFeedback.Request;\n response: void;\n };\n '/media/upload': {\n request: UploadMedia.Request;\n response: UploadMedia.Response;\n };\n};\n\n// Helper type to extract the request type for a given endpoint\ntype RequestType<T extends keyof AIEndpoints> = AIEndpoints[T]['request'];\n\n// Helper type to extract the response type for a given endpoint\ntype ResponseType<T extends keyof AIEndpoints> = AIEndpoints[T]['response'];\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\nexport const TOO_MANY_REQUESTS_ERROR = 'Too many requests';\nexport const LICENSE_LIMIT_REACHED_ERROR = 'License limit';\nexport const LICENSE_LIMIT_EXCEEDED_ERROR = 'AI credit limit exceeded';\nexport const CHAT_TOO_LONG_ERROR = 'Chat too long';\nexport const ATTACHMENT_TOO_BIG_ERROR = 'Attachment too big';\nexport const ATTACHMENT_NOT_FOUND_ERROR = 'Attachment not found';\nexport const INVALID_REQUEST_ERROR = 'Invalid request';\n\n/**\n * Base hook factory for making type-safe API calls to Strapi AI endpoints.\n * Creates a hook specific to a single endpoint.\n */\nexport const createAIFetchHook = <T extends keyof AIEndpoints>(endpoint: T) => {\n return () => {\n const strapiVersion = useAppInfo('useAIFetch', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIFetch-user', (state) => state.userId);\n const aiUsage = useGetAiUsageQuery(undefined, { refetchOnMountOrArgChange: true });\n\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * Make a type-safe API call to the specified Strapi AI endpoint with retry logic\n */\n const fetchData = async (\n options: Omit<RequestInit, 'body'> & Partial<RequestType<T>> & { formData?: FormData } = {}\n ): Promise<ResponseType<T> | null> => {\n setIsPending(true);\n setError(null);\n\n try {\n const fullUrl = `${STRAPI_AI_URL}${endpoint}`;\n const isJson = !!options.body && !options.formData;\n\n const response = await fetchAI(fullUrl, {\n method: 'POST',\n headers: isJson\n ? { 'Content-Type': 'application/json', ...options.headers }\n : options.headers,\n body: options.formData\n ? options.formData\n : isJson\n ? JSON.stringify(options.body || {})\n : undefined,\n ctx: { strapiVersion, projectId, userId },\n });\n // refetch ai usage data on every successful request\n aiUsage.refetch();\n\n const body = await safeParseJson(response);\n\n if (!response.ok) {\n throw new Error(`Error: ${response.statusText}`);\n }\n return body as ResponseType<T>;\n } catch (err) {\n setError(err instanceof Error ? err.message : `Failed to fetch data from ${endpoint}`);\n return null;\n } finally {\n setIsPending(false);\n }\n };\n\n return {\n isPending,\n error,\n fetch: fetchData,\n };\n };\n};\n\n// Create specific hooks for each endpoint\nexport const useFetchGenerateTitle = createAIFetchHook('/schemas/chat/generate-title');\nexport const useFetchUploadProject = createAIFetchHook('/schemas/chat/attachment');\nexport const useFetchSendFeedback = createAIFetchHook('/schemas/chat/feedback');\nexport const useFetchUploadMedia = createAIFetchHook('/media/upload');\n\n/**\n * Hook wrapper for AI SDK's useChat with Strapi-specific configuration\n */\nexport const useAIChat: typeof useChat = (props) => {\n const strapiVersion = useAppInfo('useAIChat', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIChat-user', (state) => state.userId);\n\n const customFetch = makeChatFetch({ strapiVersion, projectId, userId });\n\n return useChat({\n ...props,\n transport: new DefaultChatTransport({\n api: STRAPI_AI_CHAT_URL,\n fetch: customFetch,\n }),\n });\n};\n"],"names":["TOO_MANY_REQUESTS_ERROR","LICENSE_LIMIT_REACHED_ERROR","LICENSE_LIMIT_EXCEEDED_ERROR","CHAT_TOO_LONG_ERROR","createAIFetchHook","endpoint","strapiVersion","useAppInfo","state","projectId","userId","aiUsage","useGetAiUsageQuery","undefined","refetchOnMountOrArgChange","isPending","setIsPending","useState","error","setError","fetchData","options","fullUrl","STRAPI_AI_URL","isJson","body","formData","response","fetchAI","method","headers","JSON","stringify","ctx","refetch","safeParseJson","ok","Error","statusText","err","message","fetch","useFetchGenerateTitle","useFetchUploadProject","useFetchSendFeedback","useFetchUploadMedia","useAIChat","props","customFetch","makeChatFetch","useChat","transport","DefaultChatTransport","api","STRAPI_AI_CHAT_URL"],"mappings":"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"}
@@ -37,7 +37,7 @@ const CHAT_TOO_LONG_ERROR = 'Chat too long';
37
37
  method: 'POST',
38
38
  headers: isJson ? {
39
39
  'Content-Type': 'application/json',
40
- ...options.headers || {}
40
+ ...options.headers
41
41
  } : options.headers,
42
42
  body: options.formData ? options.formData : isJson ? JSON.stringify(options.body || {}) : undefined,
43
43
  ctx: {
@@ -1 +1 @@
1
- {"version":3,"file":"useAIFetch.mjs","sources":["../../../../../admin/src/components/AIChat/hooks/useAIFetch.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-namespace */\n\n/**\n * In charge of fetching data from Strapi AI endpoints\n */\n\nimport { useState } from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAppInfo } from '@strapi/admin/strapi-admin';\nimport { useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';\nimport { DefaultChatTransport } from 'ai';\n\nimport { fetchAI, makeChatFetch, safeParseJson } from '../lib/aiClient';\nimport { STRAPI_AI_CHAT_URL, STRAPI_AI_URL } from '../lib/constants';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Chat title\n */\nexport namespace GenerateTitle {\n export interface Request {\n body: {\n chatId: string;\n message: string;\n };\n }\n export interface Response {\n data: {\n title: string;\n };\n error?: string;\n }\n}\n\n/**\n * Upload a project to the chat\n */\nexport namespace UploadProject {\n export interface Request {\n body: {\n chatId: string;\n name: string;\n type: 'code';\n files: {\n path: string;\n content: string;\n }[];\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Send chat feedback\n */\nexport type FeedbackReasonIds =\n | 'invalid_schema'\n | 'bad_recommendation'\n | 'slow'\n | 'instructions_ignored'\n | 'being_lazy'\n | 'other';\n\nnamespace SendFeedback {\n export interface Request {\n body: {\n chatId: string;\n type: 'upvote' | 'downvote';\n feedback?: string;\n reasons?: FeedbackReasonIds[];\n messageId: string;\n messages: UIMessage[];\n schemas: Schema[];\n };\n }\n}\n\n/**\n * Upload media\n */\nexport namespace UploadMedia {\n export interface Request {\n body: {\n url: string; // base64 image\n filename: string;\n chatId: string;\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Collection of API endpoints and their corresponding request/response types\n */\ntype AIEndpoints = {\n '/schemas/chat/generate-title': {\n request: GenerateTitle.Request;\n response: GenerateTitle.Response;\n };\n '/schemas/chat/attachment': {\n request: UploadProject.Request;\n response: UploadProject.Response;\n };\n '/schemas/chat/feedback': {\n request: SendFeedback.Request;\n response: void;\n };\n '/media/upload': {\n request: UploadMedia.Request;\n response: UploadMedia.Response;\n };\n};\n\n// Helper type to extract the request type for a given endpoint\ntype RequestType<T extends keyof AIEndpoints> = AIEndpoints[T]['request'];\n\n// Helper type to extract the response type for a given endpoint\ntype ResponseType<T extends keyof AIEndpoints> = AIEndpoints[T]['response'];\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\nexport const TOO_MANY_REQUESTS_ERROR = 'Too many requests';\nexport const LICENSE_LIMIT_REACHED_ERROR = 'License limit';\nexport const LICENSE_LIMIT_EXCEEDED_ERROR = 'AI credit limit exceeded';\nexport const CHAT_TOO_LONG_ERROR = 'Chat too long';\nexport const ATTACHMENT_TOO_BIG_ERROR = 'Attachment too big';\nexport const ATTACHMENT_NOT_FOUND_ERROR = 'Attachment not found';\nexport const INVALID_REQUEST_ERROR = 'Invalid request';\n\n/**\n * Base hook factory for making type-safe API calls to Strapi AI endpoints.\n * Creates a hook specific to a single endpoint.\n */\nexport const createAIFetchHook = <T extends keyof AIEndpoints>(endpoint: T) => {\n return () => {\n const strapiVersion = useAppInfo('useAIFetch', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIFetch-user', (state) => state.userId);\n const aiUsage = useGetAiUsageQuery(undefined, { refetchOnMountOrArgChange: true });\n\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * Make a type-safe API call to the specified Strapi AI endpoint with retry logic\n */\n const fetchData = async (\n options: Omit<RequestInit, 'body'> & Partial<RequestType<T>> & { formData?: FormData } = {}\n ): Promise<ResponseType<T> | null> => {\n setIsPending(true);\n setError(null);\n\n try {\n const fullUrl = `${STRAPI_AI_URL}${endpoint}`;\n const isJson = !!options.body && !options.formData;\n\n const response = await fetchAI(fullUrl, {\n method: 'POST',\n headers: isJson\n ? { 'Content-Type': 'application/json', ...(options.headers || {}) }\n : options.headers,\n body: options.formData\n ? options.formData\n : isJson\n ? JSON.stringify(options.body || {})\n : undefined,\n ctx: { strapiVersion, projectId, userId },\n });\n // refetch ai usage data on every successful request\n aiUsage.refetch();\n\n const body = await safeParseJson(response);\n\n if (!response.ok) {\n throw new Error(`Error: ${response.statusText}`);\n }\n return body as ResponseType<T>;\n } catch (err) {\n setError(err instanceof Error ? err.message : `Failed to fetch data from ${endpoint}`);\n return null;\n } finally {\n setIsPending(false);\n }\n };\n\n return {\n isPending,\n error,\n fetch: fetchData,\n };\n };\n};\n\n// Create specific hooks for each endpoint\nexport const useFetchGenerateTitle = createAIFetchHook('/schemas/chat/generate-title');\nexport const useFetchUploadProject = createAIFetchHook('/schemas/chat/attachment');\nexport const useFetchSendFeedback = createAIFetchHook('/schemas/chat/feedback');\nexport const useFetchUploadMedia = createAIFetchHook('/media/upload');\n\n/**\n * Hook wrapper for AI SDK's useChat with Strapi-specific configuration\n */\nexport const useAIChat: typeof useChat = (props) => {\n const strapiVersion = useAppInfo('useAIChat', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIChat-user', (state) => state.userId);\n\n const customFetch = makeChatFetch({ strapiVersion, projectId, userId });\n\n return useChat({\n ...props,\n transport: new DefaultChatTransport({\n api: STRAPI_AI_CHAT_URL,\n fetch: customFetch,\n }),\n });\n};\n"],"names":["TOO_MANY_REQUESTS_ERROR","LICENSE_LIMIT_REACHED_ERROR","LICENSE_LIMIT_EXCEEDED_ERROR","CHAT_TOO_LONG_ERROR","createAIFetchHook","endpoint","strapiVersion","useAppInfo","state","projectId","userId","aiUsage","useGetAiUsageQuery","undefined","refetchOnMountOrArgChange","isPending","setIsPending","useState","error","setError","fetchData","options","fullUrl","STRAPI_AI_URL","isJson","body","formData","response","fetchAI","method","headers","JSON","stringify","ctx","refetch","safeParseJson","ok","Error","statusText","err","message","fetch","useFetchGenerateTitle","useFetchUploadProject","useFetchSendFeedback","useFetchUploadMedia","useAIChat","props","customFetch","makeChatFetch","useChat","transport","DefaultChatTransport","api","STRAPI_AI_CHAT_URL"],"mappings":";;;;;;;;AAkIA;;qGAIO,MAAMA,uBAAAA,GAA0B;AAChC,MAAMC,8BAA8B;AACpC,MAAMC,+BAA+B;AACrC,MAAMC,sBAAsB;AAKnC;;;IAIO,MAAMC,iBAAAA,GAAoB,CAA8BC,QAAAA,GAAAA;IAC7D,OAAO,IAAA;AACL,QAAA,MAAMC,gBAAgBC,UAAAA,CAAW,YAAA,EAAc,CAACC,KAAAA,GAAUA,MAAMF,aAAa,CAAA;AAC7E,QAAA,MAAMG,YAAYF,UAAAA,CAAW,YAAA,EAAc,CAACC,KAAAA,GAAUA,MAAMC,SAAS,CAAA;AACrE,QAAA,MAAMC,SAASH,UAAAA,CAAW,iBAAA,EAAmB,CAACC,KAAAA,GAAUA,MAAME,MAAM,CAAA;QACpE,MAAMC,OAAAA,GAAUC,mBAAmBC,SAAAA,EAAW;YAAEC,yBAAAA,EAA2B;AAAK,SAAA,CAAA;AAEhF,QAAA,MAAM,CAACC,SAAAA,EAAWC,YAAAA,CAAa,GAAGC,QAAAA,CAAS,KAAA,CAAA;AAC3C,QAAA,MAAM,CAACC,KAAAA,EAAOC,QAAAA,CAAS,GAAGF,QAAAA,CAAwB,IAAA,CAAA;AAElD;;AAEC,QACD,MAAMG,SAAAA,GAAY,OAChBC,OAAAA,GAAyF,EAAE,GAAA;YAE3FL,YAAAA,CAAa,IAAA,CAAA;YACbG,QAAAA,CAAS,IAAA,CAAA;YAET,IAAI;gBACF,MAAMG,OAAAA,GAAU,CAAA,EAAGC,aAAAA,CAAAA,EAAgBlB,QAAAA,CAAAA,CAAU;gBAC7C,MAAMmB,MAAAA,GAAS,CAAC,CAACH,OAAAA,CAAQI,IAAI,IAAI,CAACJ,QAAQK,QAAQ;gBAElD,MAAMC,QAAAA,GAAW,MAAMC,OAAAA,CAAQN,OAAAA,EAAS;oBACtCO,MAAAA,EAAQ,MAAA;AACRC,oBAAAA,OAAAA,EAASN,MAAAA,GACL;wBAAE,cAAA,EAAgB,kBAAA;AAAoB,wBAAA,GAAIH,OAAAA,CAAQS,OAAO,IAAI;AAAI,qBAAA,GACjET,QAAQS,OAAO;AACnBL,oBAAAA,IAAAA,EAAMJ,OAAAA,CAAQK,QAAQ,GAClBL,OAAAA,CAAQK,QAAQ,GAChBF,MAAAA,GACEO,IAAAA,CAAKC,SAAS,CAACX,OAAAA,CAAQI,IAAI,IAAI,EAAC,CAAA,GAChCZ,SAAAA;oBACNoB,GAAAA,EAAK;AAAE3B,wBAAAA,aAAAA;AAAeG,wBAAAA,SAAAA;AAAWC,wBAAAA;AAAO;AAC1C,iBAAA,CAAA;;AAEAC,gBAAAA,OAAAA,CAAQuB,OAAO,EAAA;gBAEf,MAAMT,IAAAA,GAAO,MAAMU,aAAAA,CAAcR,QAAAA,CAAAA;gBAEjC,IAAI,CAACA,QAAAA,CAASS,EAAE,EAAE;AAChB,oBAAA,MAAM,IAAIC,KAAAA,CAAM,CAAC,OAAO,EAAEV,QAAAA,CAASW,UAAU,CAAA,CAAE,CAAA;AACjD,gBAAA;gBACA,OAAOb,IAAAA;AACT,YAAA,CAAA,CAAE,OAAOc,GAAAA,EAAK;gBACZpB,QAAAA,CAASoB,GAAAA,YAAeF,QAAQE,GAAAA,CAAIC,OAAO,GAAG,CAAC,0BAA0B,EAAEnC,QAAAA,CAAAA,CAAU,CAAA;gBACrF,OAAO,IAAA;YACT,CAAA,QAAU;gBACRW,YAAAA,CAAa,KAAA,CAAA;AACf,YAAA;AACF,QAAA,CAAA;QAEA,OAAO;AACLD,YAAAA,SAAAA;AACAG,YAAAA,KAAAA;YACAuB,KAAAA,EAAOrB;AACT,SAAA;AACF,IAAA,CAAA;AACF;AAEA;AACO,MAAMsB,qBAAAA,GAAwBtC,iBAAAA,CAAkB,8BAAA;AAChD,MAAMuC,qBAAAA,GAAwBvC,iBAAAA,CAAkB,0BAAA;AAChD,MAAMwC,oBAAAA,GAAuBxC,iBAAAA,CAAkB,wBAAA;AAC/C,MAAMyC,mBAAAA,GAAsBzC,iBAAAA,CAAkB,eAAA;AAErD;;IAGO,MAAM0C,SAAAA,GAA4B,CAACC,KAAAA,GAAAA;AACxC,IAAA,MAAMzC,gBAAgBC,UAAAA,CAAW,WAAA,EAAa,CAACC,KAAAA,GAAUA,MAAMF,aAAa,CAAA;AAC5E,IAAA,MAAMG,YAAYF,UAAAA,CAAW,YAAA,EAAc,CAACC,KAAAA,GAAUA,MAAMC,SAAS,CAAA;AACrE,IAAA,MAAMC,SAASH,UAAAA,CAAW,gBAAA,EAAkB,CAACC,KAAAA,GAAUA,MAAME,MAAM,CAAA;AAEnE,IAAA,MAAMsC,cAAcC,aAAAA,CAAc;AAAE3C,QAAAA,aAAAA;AAAeG,QAAAA,SAAAA;AAAWC,QAAAA;AAAO,KAAA,CAAA;AAErE,IAAA,OAAOwC,OAAAA,CAAQ;AACb,QAAA,GAAGH,KAAK;AACRI,QAAAA,SAAAA,EAAW,IAAIC,oBAAAA,CAAqB;YAClCC,GAAAA,EAAKC,kBAAAA;YACLb,KAAAA,EAAOO;AACT,SAAA;AACF,KAAA,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"useAIFetch.mjs","sources":["../../../../../admin/src/components/AIChat/hooks/useAIFetch.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-namespace */\n\n/**\n * In charge of fetching data from Strapi AI endpoints\n */\n\nimport { useState } from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAppInfo } from '@strapi/admin/strapi-admin';\nimport { useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';\nimport { DefaultChatTransport } from 'ai';\n\nimport { fetchAI, makeChatFetch, safeParseJson } from '../lib/aiClient';\nimport { STRAPI_AI_CHAT_URL, STRAPI_AI_URL } from '../lib/constants';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Chat title\n */\nexport namespace GenerateTitle {\n export interface Request {\n body: {\n chatId: string;\n message: string;\n };\n }\n export interface Response {\n data: {\n title: string;\n };\n error?: string;\n }\n}\n\n/**\n * Upload a project to the chat\n */\nexport namespace UploadProject {\n export interface Request {\n body: {\n chatId: string;\n name: string;\n type: 'code';\n files: {\n path: string;\n content: string;\n }[];\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Send chat feedback\n */\nexport type FeedbackReasonIds =\n | 'invalid_schema'\n | 'bad_recommendation'\n | 'slow'\n | 'instructions_ignored'\n | 'being_lazy'\n | 'other';\n\nnamespace SendFeedback {\n export interface Request {\n body: {\n chatId: string;\n type: 'upvote' | 'downvote';\n feedback?: string;\n reasons?: FeedbackReasonIds[];\n messageId: string;\n messages: UIMessage[];\n schemas: Schema[];\n };\n }\n}\n\n/**\n * Upload media\n */\nexport namespace UploadMedia {\n export interface Request {\n body: {\n url: string; // base64 image\n filename: string;\n chatId: string;\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Collection of API endpoints and their corresponding request/response types\n */\ntype AIEndpoints = {\n '/schemas/chat/generate-title': {\n request: GenerateTitle.Request;\n response: GenerateTitle.Response;\n };\n '/schemas/chat/attachment': {\n request: UploadProject.Request;\n response: UploadProject.Response;\n };\n '/schemas/chat/feedback': {\n request: SendFeedback.Request;\n response: void;\n };\n '/media/upload': {\n request: UploadMedia.Request;\n response: UploadMedia.Response;\n };\n};\n\n// Helper type to extract the request type for a given endpoint\ntype RequestType<T extends keyof AIEndpoints> = AIEndpoints[T]['request'];\n\n// Helper type to extract the response type for a given endpoint\ntype ResponseType<T extends keyof AIEndpoints> = AIEndpoints[T]['response'];\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\nexport const TOO_MANY_REQUESTS_ERROR = 'Too many requests';\nexport const LICENSE_LIMIT_REACHED_ERROR = 'License limit';\nexport const LICENSE_LIMIT_EXCEEDED_ERROR = 'AI credit limit exceeded';\nexport const CHAT_TOO_LONG_ERROR = 'Chat too long';\nexport const ATTACHMENT_TOO_BIG_ERROR = 'Attachment too big';\nexport const ATTACHMENT_NOT_FOUND_ERROR = 'Attachment not found';\nexport const INVALID_REQUEST_ERROR = 'Invalid request';\n\n/**\n * Base hook factory for making type-safe API calls to Strapi AI endpoints.\n * Creates a hook specific to a single endpoint.\n */\nexport const createAIFetchHook = <T extends keyof AIEndpoints>(endpoint: T) => {\n return () => {\n const strapiVersion = useAppInfo('useAIFetch', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIFetch-user', (state) => state.userId);\n const aiUsage = useGetAiUsageQuery(undefined, { refetchOnMountOrArgChange: true });\n\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * Make a type-safe API call to the specified Strapi AI endpoint with retry logic\n */\n const fetchData = async (\n options: Omit<RequestInit, 'body'> & Partial<RequestType<T>> & { formData?: FormData } = {}\n ): Promise<ResponseType<T> | null> => {\n setIsPending(true);\n setError(null);\n\n try {\n const fullUrl = `${STRAPI_AI_URL}${endpoint}`;\n const isJson = !!options.body && !options.formData;\n\n const response = await fetchAI(fullUrl, {\n method: 'POST',\n headers: isJson\n ? { 'Content-Type': 'application/json', ...options.headers }\n : options.headers,\n body: options.formData\n ? options.formData\n : isJson\n ? JSON.stringify(options.body || {})\n : undefined,\n ctx: { strapiVersion, projectId, userId },\n });\n // refetch ai usage data on every successful request\n aiUsage.refetch();\n\n const body = await safeParseJson(response);\n\n if (!response.ok) {\n throw new Error(`Error: ${response.statusText}`);\n }\n return body as ResponseType<T>;\n } catch (err) {\n setError(err instanceof Error ? err.message : `Failed to fetch data from ${endpoint}`);\n return null;\n } finally {\n setIsPending(false);\n }\n };\n\n return {\n isPending,\n error,\n fetch: fetchData,\n };\n };\n};\n\n// Create specific hooks for each endpoint\nexport const useFetchGenerateTitle = createAIFetchHook('/schemas/chat/generate-title');\nexport const useFetchUploadProject = createAIFetchHook('/schemas/chat/attachment');\nexport const useFetchSendFeedback = createAIFetchHook('/schemas/chat/feedback');\nexport const useFetchUploadMedia = createAIFetchHook('/media/upload');\n\n/**\n * Hook wrapper for AI SDK's useChat with Strapi-specific configuration\n */\nexport const useAIChat: typeof useChat = (props) => {\n const strapiVersion = useAppInfo('useAIChat', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIChat-user', (state) => state.userId);\n\n const customFetch = makeChatFetch({ strapiVersion, projectId, userId });\n\n return useChat({\n ...props,\n transport: new DefaultChatTransport({\n api: STRAPI_AI_CHAT_URL,\n fetch: customFetch,\n }),\n });\n};\n"],"names":["TOO_MANY_REQUESTS_ERROR","LICENSE_LIMIT_REACHED_ERROR","LICENSE_LIMIT_EXCEEDED_ERROR","CHAT_TOO_LONG_ERROR","createAIFetchHook","endpoint","strapiVersion","useAppInfo","state","projectId","userId","aiUsage","useGetAiUsageQuery","undefined","refetchOnMountOrArgChange","isPending","setIsPending","useState","error","setError","fetchData","options","fullUrl","STRAPI_AI_URL","isJson","body","formData","response","fetchAI","method","headers","JSON","stringify","ctx","refetch","safeParseJson","ok","Error","statusText","err","message","fetch","useFetchGenerateTitle","useFetchUploadProject","useFetchSendFeedback","useFetchUploadMedia","useAIChat","props","customFetch","makeChatFetch","useChat","transport","DefaultChatTransport","api","STRAPI_AI_CHAT_URL"],"mappings":"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"}
@@ -188,8 +188,8 @@ const ACTION_TO_STATUS = {
188
188
  ...prev.pluginOptions,
189
189
  ...contentTypeBase.pluginOptions,
190
190
  i18n: {
191
- ...prev.pluginOptions?.i18n ?? {},
192
- ...contentTypeBase.pluginOptions?.i18n ?? {},
191
+ ...prev.pluginOptions?.i18n,
192
+ ...contentTypeBase.pluginOptions?.i18n,
193
193
  localized: schema.options?.localized ?? prev.pluginOptions?.i18n?.localized ?? false
194
194
  }
195
195
  },