@strapi/content-type-builder 5.49.0 → 5.50.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/AIChat/Chat.js +2 -4
- package/dist/admin/components/AIChat/Chat.js.map +1 -1
- package/dist/admin/components/AIChat/Chat.mjs +2 -4
- package/dist/admin/components/AIChat/Chat.mjs.map +1 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.js +1 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.js.map +1 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.mjs +1 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/Messages/Message.js +8 -3
- package/dist/admin/components/AIChat/components/Messages/Message.js.map +1 -1
- package/dist/admin/components/AIChat/components/Messages/Message.mjs +8 -3
- package/dist/admin/components/AIChat/components/Messages/Message.mjs.map +1 -1
- package/dist/admin/components/AIChat/lib/aiClient.js +8 -2
- package/dist/admin/components/AIChat/lib/aiClient.js.map +1 -1
- package/dist/admin/components/AIChat/lib/aiClient.mjs +8 -2
- package/dist/admin/components/AIChat/lib/aiClient.mjs.map +1 -1
- package/dist/admin/components/AIChat/lib/transforms/schemas/fromCTB.js +0 -3
- package/dist/admin/components/AIChat/lib/transforms/schemas/fromCTB.js.map +1 -1
- package/dist/admin/components/AIChat/lib/transforms/schemas/fromCTB.mjs +0 -3
- package/dist/admin/components/AIChat/lib/transforms/schemas/fromCTB.mjs.map +1 -1
- package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js +9 -7
- package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js.map +1 -1
- package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs +9 -7
- package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs.map +1 -1
- package/dist/admin/components/AIChat/providers/SchemaProvider.js +1 -1
- package/dist/admin/components/AIChat/providers/SchemaProvider.js.map +1 -1
- package/dist/admin/components/AIChat/providers/SchemaProvider.mjs +1 -1
- package/dist/admin/components/AIChat/providers/SchemaProvider.mjs.map +1 -1
- package/dist/admin/components/AllowedTypesSelect.js.map +1 -1
- package/dist/admin/components/AllowedTypesSelect.mjs.map +1 -1
- package/dist/admin/components/AttributeIcon.js +1 -1
- package/dist/admin/components/AttributeIcon.js.map +1 -1
- package/dist/admin/components/AttributeIcon.mjs +1 -1
- package/dist/admin/components/AttributeIcon.mjs.map +1 -1
- package/dist/admin/components/BooleanDefaultValueSelect.js +3 -2
- package/dist/admin/components/BooleanDefaultValueSelect.js.map +1 -1
- package/dist/admin/components/BooleanDefaultValueSelect.mjs +3 -2
- package/dist/admin/components/BooleanDefaultValueSelect.mjs.map +1 -1
- package/dist/admin/components/BooleanRadioGroup.js.map +1 -1
- package/dist/admin/components/BooleanRadioGroup.mjs.map +1 -1
- package/dist/admin/components/CTBSession/useCTBTracking.js +3 -3
- package/dist/admin/components/CTBSession/useCTBTracking.js.map +1 -1
- package/dist/admin/components/CTBSession/useCTBTracking.mjs +3 -3
- package/dist/admin/components/CTBSession/useCTBTracking.mjs.map +1 -1
- package/dist/admin/components/CheckboxWithNumberField.js +3 -2
- package/dist/admin/components/CheckboxWithNumberField.js.map +1 -1
- package/dist/admin/components/CheckboxWithNumberField.mjs +3 -2
- package/dist/admin/components/CheckboxWithNumberField.mjs.map +1 -1
- package/dist/admin/components/ComponentCard/ComponentCard.js.map +1 -1
- package/dist/admin/components/ComponentCard/ComponentCard.mjs.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.js +160 -162
- package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.js.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.mjs +160 -162
- package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.mjs.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.js +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.js.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.mjs +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.mjs.map +1 -1
- package/dist/admin/components/ContentTypeRadioGroup.js.map +1 -1
- package/dist/admin/components/ContentTypeRadioGroup.mjs.map +1 -1
- package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.js +6 -5
- package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.js.map +1 -1
- package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.mjs +6 -5
- package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.mjs.map +1 -1
- package/dist/admin/components/CustomRadioGroup/Styles.js.map +1 -1
- package/dist/admin/components/CustomRadioGroup/Styles.mjs.map +1 -1
- package/dist/admin/components/DataManager/DataManagerContext.js.map +1 -1
- package/dist/admin/components/DataManager/DataManagerContext.mjs.map +1 -1
- package/dist/admin/components/DataManager/DataManagerProvider.js +16 -4
- package/dist/admin/components/DataManager/DataManagerProvider.js.map +1 -1
- package/dist/admin/components/DataManager/DataManagerProvider.mjs +16 -4
- package/dist/admin/components/DataManager/DataManagerProvider.mjs.map +1 -1
- package/dist/admin/components/DataManager/reducer.js +2 -2
- package/dist/admin/components/DataManager/reducer.js.map +1 -1
- package/dist/admin/components/DataManager/reducer.mjs +2 -2
- package/dist/admin/components/DataManager/reducer.mjs.map +1 -1
- package/dist/admin/components/DataManager/useServerRestartWatcher.js.map +1 -1
- package/dist/admin/components/DataManager/useServerRestartWatcher.mjs.map +1 -1
- package/dist/admin/components/DataManager/utils/retrieveSpecificInfoFromComponents.js.map +1 -1
- package/dist/admin/components/DataManager/utils/retrieveSpecificInfoFromComponents.mjs.map +1 -1
- package/dist/admin/components/DraftAndPublishToggle.js.map +1 -1
- package/dist/admin/components/DraftAndPublishToggle.mjs.map +1 -1
- package/dist/admin/components/DynamicZoneList.js.map +1 -1
- package/dist/admin/components/DynamicZoneList.mjs.map +1 -1
- package/dist/admin/components/FormModal/FormModal.js +91 -71
- package/dist/admin/components/FormModal/FormModal.js.map +1 -1
- package/dist/admin/components/FormModal/FormModal.mjs +91 -70
- package/dist/admin/components/FormModal/FormModal.mjs.map +1 -1
- package/dist/admin/components/FormModal/attributes/ConditionForm.js +20 -17
- package/dist/admin/components/FormModal/attributes/ConditionForm.js.map +1 -1
- package/dist/admin/components/FormModal/attributes/ConditionForm.mjs +20 -17
- package/dist/admin/components/FormModal/attributes/ConditionForm.mjs.map +1 -1
- package/dist/admin/components/FormModal/attributes/validation/common.js.map +1 -1
- package/dist/admin/components/FormModal/attributes/validation/common.mjs.map +1 -1
- package/dist/admin/components/FormModal/component/createComponentSchema.js +1 -1
- package/dist/admin/components/FormModal/component/createComponentSchema.js.map +1 -1
- package/dist/admin/components/FormModal/component/createComponentSchema.mjs +1 -1
- package/dist/admin/components/FormModal/component/createComponentSchema.mjs.map +1 -1
- package/dist/admin/components/FormModal/forms/forms.js +4 -6
- package/dist/admin/components/FormModal/forms/forms.js.map +1 -1
- package/dist/admin/components/FormModal/forms/forms.mjs +4 -6
- package/dist/admin/components/FormModal/forms/forms.mjs.map +1 -1
- package/dist/admin/components/FormModal/forms/utils/getUsedAttributeNames.js.map +1 -1
- package/dist/admin/components/FormModal/forms/utils/getUsedAttributeNames.mjs.map +1 -1
- package/dist/admin/components/FormModal/reducer.js +9 -6
- package/dist/admin/components/FormModal/reducer.js.map +1 -1
- package/dist/admin/components/FormModal/reducer.mjs +9 -6
- package/dist/admin/components/FormModal/reducer.mjs.map +1 -1
- package/dist/admin/components/FormModal/utils/customFieldDefaultOptionsReducer.js +3 -3
- package/dist/admin/components/FormModal/utils/customFieldDefaultOptionsReducer.js.map +1 -1
- package/dist/admin/components/FormModal/utils/customFieldDefaultOptionsReducer.mjs +3 -3
- package/dist/admin/components/FormModal/utils/customFieldDefaultOptionsReducer.mjs.map +1 -1
- package/dist/admin/components/FormModal/utils/getFormInputNames.js +1 -1
- package/dist/admin/components/FormModal/utils/getFormInputNames.js.map +1 -1
- package/dist/admin/components/FormModal/utils/getFormInputNames.mjs +1 -1
- package/dist/admin/components/FormModal/utils/getFormInputNames.mjs.map +1 -1
- package/dist/admin/components/FormModal/utils/relations.js +2 -2
- package/dist/admin/components/FormModal/utils/relations.js.map +1 -1
- package/dist/admin/components/FormModal/utils/relations.mjs +2 -2
- package/dist/admin/components/FormModal/utils/relations.mjs.map +1 -1
- package/dist/admin/components/FormModalHeader.js.map +1 -1
- package/dist/admin/components/FormModalHeader.mjs.map +1 -1
- package/dist/admin/components/FormModalNavigation/FormModalNavigationContext.js.map +1 -1
- package/dist/admin/components/FormModalNavigation/FormModalNavigationContext.mjs.map +1 -1
- package/dist/admin/components/FormModalNavigation/FormModalNavigationProvider.js +13 -13
- package/dist/admin/components/FormModalNavigation/FormModalNavigationProvider.js.map +1 -1
- package/dist/admin/components/FormModalNavigation/FormModalNavigationProvider.mjs +13 -13
- package/dist/admin/components/FormModalNavigation/FormModalNavigationProvider.mjs.map +1 -1
- package/dist/admin/components/GenericInputs.js +24 -12
- package/dist/admin/components/GenericInputs.js.map +1 -1
- package/dist/admin/components/GenericInputs.mjs +24 -12
- package/dist/admin/components/GenericInputs.mjs.map +1 -1
- package/dist/admin/components/IconPicker/IconPicker.js.map +1 -1
- package/dist/admin/components/IconPicker/IconPicker.mjs.map +1 -1
- package/dist/admin/components/PluralName.js.map +1 -1
- package/dist/admin/components/PluralName.mjs.map +1 -1
- package/dist/admin/components/Relation/Relation.js +3 -3
- package/dist/admin/components/Relation/Relation.js.map +1 -1
- package/dist/admin/components/Relation/Relation.mjs +3 -3
- package/dist/admin/components/Relation/Relation.mjs.map +1 -1
- package/dist/admin/components/Relation/RelationField/RelationField.js +1 -1
- package/dist/admin/components/Relation/RelationField/RelationField.js.map +1 -1
- package/dist/admin/components/Relation/RelationField/RelationField.mjs +1 -1
- package/dist/admin/components/Relation/RelationField/RelationField.mjs.map +1 -1
- package/dist/admin/components/SelectCategory.js +6 -0
- package/dist/admin/components/SelectCategory.js.map +1 -1
- package/dist/admin/components/SelectCategory.mjs +6 -0
- package/dist/admin/components/SelectCategory.mjs.map +1 -1
- package/dist/admin/components/SelectComponent.js +1 -1
- package/dist/admin/components/SelectComponent.js.map +1 -1
- package/dist/admin/components/SelectComponent.mjs +1 -1
- package/dist/admin/components/SelectComponent.mjs.map +1 -1
- package/dist/admin/components/SingularName.js.map +1 -1
- package/dist/admin/components/SingularName.mjs.map +1 -1
- package/dist/admin/components/TabForm.js +50 -51
- package/dist/admin/components/TabForm.js.map +1 -1
- package/dist/admin/components/TabForm.mjs +51 -52
- package/dist/admin/components/TabForm.mjs.map +1 -1
- package/dist/admin/src/components/AIChat/components/AnimatedBox.d.ts +4 -5
- package/dist/admin/src/components/AIChat/components/Attachments/AttachmentPreview.d.ts +1 -1
- package/dist/admin/src/components/AIChat/components/Dropzone.d.ts +0 -1
- package/dist/admin/src/components/AIChat/components/FloatingPanel.d.ts +0 -1
- package/dist/admin/src/components/AIChat/components/Input.d.ts +2 -3
- package/dist/admin/src/components/AIChat/components/Messages/Message.d.ts +1 -2
- package/dist/admin/src/components/AIChat/components/ResizableTextArea.d.ts +0 -1
- package/dist/admin/src/components/AIChat/components/SimpleMenu.d.ts +9 -9
- package/dist/admin/src/components/AIChat/components/icons/FigmaIcon.d.ts +0 -1
- package/dist/admin/src/components/AIChat/components/icons/StopIcon.d.ts +0 -1
- package/dist/admin/src/components/AIChat/hooks/useAIFetch.d.ts +5 -5
- package/dist/admin/src/components/AIChat/lib/aiClient.d.ts +1 -1
- package/dist/admin/src/components/AIChat/lib/transforms/schemas/fromCTB.d.ts +6 -2
- package/dist/admin/src/components/AIChat/lib/transforms/schemas/toCTB.d.ts +1 -1
- package/dist/admin/src/components/AIChat/lib/types/schema.d.ts +5 -5
- package/dist/admin/src/components/AllowedTypesSelect.d.ts +3 -3
- package/dist/admin/src/components/AttributeOptions/OptionBoxWrapper.d.ts +2 -3
- package/dist/admin/src/components/AttributeRow.d.ts +7 -8
- package/dist/admin/src/components/BooleanDefaultValueSelect.d.ts +3 -3
- package/dist/admin/src/components/BooleanRadioGroup.d.ts +2 -2
- package/dist/admin/src/components/CTBSession/sessionContext.d.ts +0 -1
- package/dist/admin/src/components/CTBSession/useCTBTracking.d.ts +1 -1
- package/dist/admin/src/components/CheckboxWithNumberField.d.ts +6 -4
- package/dist/admin/src/components/ComponentRow.d.ts +6 -7
- package/dist/admin/src/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.d.ts +0 -1
- package/dist/admin/src/components/ContentTypeRadioGroup.d.ts +3 -2
- package/dist/admin/src/components/CustomRadioGroup/CustomRadioGroup.d.ts +3 -2
- package/dist/admin/src/components/CustomRadioGroup/Styles.d.ts +3 -4
- package/dist/admin/src/components/DataManager/DataManagerContext.d.ts +13 -12
- package/dist/admin/src/components/DataManager/reducer.d.ts +16 -12
- package/dist/admin/src/components/DataManager/utils/cleanData.d.ts +64 -64
- package/dist/admin/src/components/DataManager/utils/formatSchemas.d.ts +9 -3
- package/dist/admin/src/components/DataManager/utils/retrieveSpecificInfoFromComponents.d.ts +2 -1
- package/dist/admin/src/components/DraftAndPublishToggle.d.ts +1 -6
- package/dist/admin/src/components/DynamicZoneList.d.ts +2 -2
- package/dist/admin/src/components/FormModal/attributes/ConditionForm.d.ts +3 -2
- package/dist/admin/src/components/FormModal/attributes/form.d.ts +3 -3
- package/dist/admin/src/components/FormModal/attributes/validation/common.d.ts +4 -2
- package/dist/admin/src/components/FormModal/forms/forms.d.ts +61 -28
- package/dist/admin/src/components/FormModal/forms/utils/getUsedAttributeNames.d.ts +12 -2
- package/dist/admin/src/components/FormModal/reducer.d.ts +104 -32
- package/dist/admin/src/components/FormModal/utils/customFieldDefaultOptionsReducer.d.ts +11 -1
- package/dist/admin/src/components/FormModal/utils/getFormInputNames.d.ts +8 -1
- package/dist/admin/src/components/FormModal/utils/relations.d.ts +2 -2
- package/dist/admin/src/components/FormModalHeader.d.ts +5 -8
- package/dist/admin/src/components/FormModalNavigation/FormModalNavigationContext.d.ts +2 -2
- package/dist/admin/src/components/FormModalNavigation/FormModalNavigationProvider.d.ts +17 -2
- package/dist/admin/src/components/GenericInputs.d.ts +12 -7
- package/dist/admin/src/components/IconPicker/IconPicker.d.ts +2 -7
- package/dist/admin/src/components/List.d.ts +2 -3
- package/dist/admin/src/components/PluralName.d.ts +6 -14
- package/dist/admin/src/components/Relation/Relation.d.ts +12 -3
- package/dist/admin/src/components/Relation/RelationField/RelationField.d.ts +3 -2
- package/dist/admin/src/components/Relation/RelationNaturePicker/Components.d.ts +6 -7
- package/dist/admin/src/components/SelectCategory.d.ts +3 -12
- package/dist/admin/src/components/SelectComponent.d.ts +8 -7
- package/dist/admin/src/components/SingularName.d.ts +5 -8
- package/dist/admin/src/components/TabForm.d.ts +38 -7
- package/dist/admin/src/pages/ListView/LinkToCMSettingsView.d.ts +0 -1
- package/dist/admin/src/types.d.ts +20 -12
- package/dist/admin/src/utils/conditions.d.ts +13 -4
- package/dist/admin/src/utils/formAPI.d.ts +38 -33
- package/dist/admin/src/utils/getRelationType.d.ts +1 -1
- package/dist/admin/src/utils/isAllowedContentTypesForRelations.d.ts +1 -1
- package/dist/admin/src/utils/parseNumberInputValue.d.ts +1 -0
- package/dist/admin/translations/en.json.js +1 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +1 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/translations/ja.json.js +109 -50
- package/dist/admin/translations/ja.json.js.map +1 -1
- package/dist/admin/translations/ja.json.mjs +109 -50
- package/dist/admin/translations/ja.json.mjs.map +1 -1
- package/dist/admin/utils/conditions.js +38 -28
- package/dist/admin/utils/conditions.js.map +1 -1
- package/dist/admin/utils/conditions.mjs +37 -28
- package/dist/admin/utils/conditions.mjs.map +1 -1
- package/dist/admin/utils/formAPI.js +9 -6
- package/dist/admin/utils/formAPI.js.map +1 -1
- package/dist/admin/utils/formAPI.mjs +9 -6
- package/dist/admin/utils/formAPI.mjs.map +1 -1
- package/dist/admin/utils/getRelationType.js +3 -0
- package/dist/admin/utils/getRelationType.js.map +1 -1
- package/dist/admin/utils/getRelationType.mjs +3 -0
- package/dist/admin/utils/getRelationType.mjs.map +1 -1
- package/dist/admin/utils/getYupInnerErrors.js +6 -4
- package/dist/admin/utils/getYupInnerErrors.js.map +1 -1
- package/dist/admin/utils/getYupInnerErrors.mjs +6 -4
- package/dist/admin/utils/getYupInnerErrors.mjs.map +1 -1
- package/dist/admin/utils/parseNumberInputValue.js +15 -0
- package/dist/admin/utils/parseNumberInputValue.js.map +1 -0
- package/dist/admin/utils/parseNumberInputValue.mjs +13 -0
- package/dist/admin/utils/parseNumberInputValue.mjs.map +1 -0
- package/dist/server/controllers/validation/common.js +1 -1
- package/dist/server/controllers/validation/common.js.map +1 -1
- package/dist/server/controllers/validation/common.mjs +1 -1
- package/dist/server/controllers/validation/common.mjs.map +1 -1
- package/dist/server/controllers/validation/relations.js +1 -1
- package/dist/server/controllers/validation/relations.js.map +1 -1
- package/dist/server/controllers/validation/relations.mjs +1 -1
- package/dist/server/controllers/validation/relations.mjs.map +1 -1
- package/dist/server/controllers/validation/types.js +4 -3
- package/dist/server/controllers/validation/types.js.map +1 -1
- package/dist/server/controllers/validation/types.mjs +4 -3
- package/dist/server/controllers/validation/types.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/common.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/component-category.d.ts +1 -1
- package/dist/server/src/controllers/validation/component.d.ts +1 -1
- package/dist/server/src/controllers/validation/component.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/content-type.d.ts +1 -1
- package/dist/server/src/controllers/validation/content-type.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/data-transform.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/model-schema.d.ts +1 -1
- package/dist/server/src/controllers/validation/model-schema.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/schema.d.ts +1 -1
- package/dist/server/src/controllers/validation/types.d.ts.map +1 -1
- package/dist/server/src/middlewares/is-development-mode.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/services/builder.d.ts.map +1 -1
- package/dist/server/src/services/component-categories.d.ts.map +1 -1
- package/dist/server/src/services/components.d.ts.map +1 -1
- package/dist/server/src/services/content-types.d.ts +1 -1
- package/dist/server/src/services/content-types.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/component-builder.d.ts +12 -12
- package/dist/server/src/services/schema-builder/component-builder.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/content-type-builder.d.ts +14 -14
- package/dist/server/src/services/schema-builder/content-type-builder.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/index.d.ts +27 -27
- package/dist/server/src/services/schema-builder/index.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/schema-handler.d.ts +12 -12
- package/dist/server/src/services/schema-builder/schema-handler.d.ts.map +1 -1
- package/dist/server/src/services/schema.d.ts +66 -66
- package/dist/server/src/services/schema.d.ts.map +1 -1
- package/dist/server/src/utils/attributes.d.ts +2 -2
- package/dist/server/src/utils/attributes.d.ts.map +1 -1
- package/dist/server/src/utils/helpers.d.ts.map +1 -1
- package/dist/server/src/utils/typeguards.d.ts.map +1 -1
- package/package.json +13 -9
|
@@ -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, setMessages, 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","setMessages","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 (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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"}
|
|
@@ -81,7 +81,12 @@ const UserMessageTypography = styledComponents.styled(designSystem.Typography)`
|
|
|
81
81
|
overflow-wrap: anywhere;
|
|
82
82
|
word-break: break-word;
|
|
83
83
|
`;
|
|
84
|
-
const isSchemaToolPart = (part)=>
|
|
84
|
+
const isSchemaToolPart = (part)=>{
|
|
85
|
+
if (typeof part !== 'object' || part === null || !('type' in part)) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return part.type === 'tool-schemaGenerationTool';
|
|
89
|
+
};
|
|
85
90
|
const capitalize = (s)=>s ? s.charAt(0).toUpperCase() + s.slice(1) : '';
|
|
86
91
|
const getSchemaLink = (schema)=>{
|
|
87
92
|
const isComponent = (schema.kind ?? schema.modelType) === 'component';
|
|
@@ -113,7 +118,7 @@ const MessageContent = ({ part })=>{
|
|
|
113
118
|
return /*#__PURE__*/ jsxRuntime.jsx(MarkdownStyles, {
|
|
114
119
|
children: /*#__PURE__*/ jsxRuntime.jsx(Markdown__default.default, {
|
|
115
120
|
components: {
|
|
116
|
-
a: ({ node, ...props })=>/*#__PURE__*/ jsxRuntime.jsx("a", {
|
|
121
|
+
a: ({ node: _node, ...props })=>/*#__PURE__*/ jsxRuntime.jsx("a", {
|
|
117
122
|
target: "_blank",
|
|
118
123
|
rel: "noopener noreferrer",
|
|
119
124
|
...props
|
|
@@ -204,7 +209,7 @@ const AssistantMessage = ({ message, isLoading })=>{
|
|
|
204
209
|
]
|
|
205
210
|
});
|
|
206
211
|
};
|
|
207
|
-
const ChatMessage = ({ message
|
|
212
|
+
const ChatMessage = ({ message })=>{
|
|
208
213
|
/**
|
|
209
214
|
* IMPORTANT: Messages are rendered using react-markdown (heavy compute)
|
|
210
215
|
* Component re-renders on each message update, but AI SDK v5 provides
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.js","sources":["../../../../../../admin/src/components/AIChat/components/Messages/Message.tsx"],"sourcesContent":["import { Typography, Box, IconButton, Flex } from '@strapi/design-system';\nimport { ThumbUp, ThumbDown } from '@strapi/icons';\nimport Markdown from 'react-markdown';\nimport { styled } from 'styled-components';\n\nimport { useFeedbackModal } from '../../FeedbackModal';\nimport { useFeedback } from '../../hooks/useFeedback';\nimport {\n AIMessage,\n type UserMessage as UserMessageType,\n AssistantMessage as AssistantMessageType,\n type MarkerContent as MarkerContentType,\n} from '../../lib/types/messages';\nimport { AnimatedBox } from '../AnimatedBox';\nimport { AttachmentPreview } from '../Attachments/AttachmentPreview';\n\nimport { Marker } from './Marker';\n\nconst MarkdownStyles = styled(Typography)`\n max-width: 65ch;\n margin: 0 auto;\n overflow-wrap: anywhere;\n word-break: break-word;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-top: 1.25em;\n margin-bottom: 0.5em;\n font-weight: bold;\n }\n\n p {\n margin-bottom: 1em;\n }\n\n ul,\n ol {\n padding-left: 1.5em; /* indentation for bullet points */\n margin-bottom: 1em;\n }\n\n li {\n margin-bottom: 0.5em;\n list-style-type: disc; /* or whatever style you prefer */\n }\n\n strong {\n font-weight: bold;\n }\n\n /* code blocks, blockquotes, etc. */\n code {\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n font-family: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas,\n monospace;\n }\n\n /* links */\n a {\n color: ${({ theme }) => theme.colors.primary500};\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n text-decoration: none;\n\n &:hover {\n text-decoration: underline;\n }\n }\n`;\n\nconst UserMessageTypography = styled(Typography)`\n overflow-wrap: anywhere;\n word-break: break-word;\n`;\n\n// ---------------------------\n// Tool: schemaGenerationTool helpers\n// ---------------------------\n\ntype SchemaToolSchema = {\n action?: 'create' | 'update' | 'remove';\n uid?: string;\n name?: string;\n category?: string;\n kind?: 'collectionType' | 'singleType' | 'component';\n modelType?: 'component' | 'collectionType' | 'singleType';\n};\n\ntype SchemaToolPart = {\n type: 'tool-schemaGenerationTool';\n input?: { schemas?: SchemaToolSchema[] };\n output?: { schemas?: SchemaToolSchema[]; error?: unknown };\n toolCallId?: string;\n};\n\nconst isSchemaToolPart = (part: any): part is SchemaToolPart =>\n part && typeof part === 'object' && part.type === 'tool-schemaGenerationTool';\n\nconst capitalize = (s?: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : '');\n\nconst getSchemaLink = (schema: SchemaToolSchema): string | undefined => {\n const isComponent = (schema.kind ?? schema.modelType) === 'component';\n if (!schema.uid) return undefined;\n return isComponent\n ? `/plugins/content-type-builder/component-categories/${schema.category ?? ''}/${schema.uid}`\n : `/plugins/content-type-builder/content-types/${schema.uid}`;\n};\n\nconst toMarkerFromSchemaTool = (part: SchemaToolPart): MarkerContentType => {\n const outSchemas = part.output?.schemas ?? [];\n const inSchemas = part.input?.schemas ?? [];\n\n const schemas = (outSchemas.length ? outSchemas : inSchemas) as SchemaToolSchema[];\n const numSchemas = schemas.length;\n\n const state: 'loading' | 'success' | 'error' = part.output\n ? part.output.error\n ? 'error'\n : 'success'\n : 'loading';\n\n const steps = schemas.map((schema, index) => ({\n id: `${part.toolCallId ?? 'schemaGenerationTool'}-${schema.uid ?? schema.name ?? index}`,\n description: capitalize(schema.name ?? schema.uid ?? 'Schema'),\n status:\n schema.action === 'create' || schema.action === 'update' || schema.action === 'remove'\n ? schema.action\n : ('update' as const),\n link: getSchemaLink(schema),\n }));\n\n const title =\n state === 'success'\n ? `Updated ${numSchemas} schema${numSchemas === 1 ? '' : 's'}`\n : state === 'error'\n ? `Failed to update schema${numSchemas === 1 ? '' : 's'}`\n : 'Updating schemas';\n\n return {\n type: 'marker',\n title,\n state,\n steps,\n };\n};\n\nconst MessageContent = ({\n part,\n}: {\n part: AIMessage['parts'][number];\n status?: 'loading' | 'success' | 'error';\n}) => {\n if (part.type === 'text') {\n return (\n <MarkdownStyles>\n <Markdown\n components={{\n a: ({ node, ...props }) => <a target=\"_blank\" rel=\"noopener noreferrer\" {...props} />,\n }}\n >\n {part.text}\n </Markdown>\n </MarkdownStyles>\n );\n }\n\n if (isSchemaToolPart(part)) {\n const marker = toMarkerFromSchemaTool(part);\n return <Marker {...marker} />;\n }\n\n return null;\n};\n\nconst UserMessage = ({ message }: { message: UserMessageType }) => {\n const hasText = message.parts.some(\n (content) => content.type === 'text' && content.text.trim() !== ''\n );\n const attachments = message.parts.filter((content) => content.type === 'file');\n\n return (\n <AnimatedBox\n as={Flex}\n direction=\"column\"\n alignItems=\"flex-end\"\n style={{ alignSelf: 'flex-end' }}\n gap={2}\n maxWidth=\"80%\"\n >\n {hasText ? (\n <Box background=\"neutral150\" borderStyle=\"none\" padding={['10px', '16px']} hasRadius>\n {message.parts.map((content, index) => {\n if (content.type !== 'text') return null;\n return <UserMessageTypography key={index}>{content.text}</UserMessageTypography>;\n })}\n </Box>\n ) : null}\n\n {/* Attachments */}\n {attachments.map((attachment, idx) => (\n <AttachmentPreview\n key={`${attachment.type === 'file' ? attachment.filename : attachment.type}-${idx}`}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n attachment={{ ...attachment, status: 'ready' } as any}\n />\n ))}\n </AnimatedBox>\n );\n};\n\nconst AssistantMessage = ({\n message,\n isLoading,\n}: {\n message: AssistantMessageType;\n isLoading?: boolean;\n}) => {\n const { upvoteMessage } = useFeedback();\n const { openFeedbackModal } = useFeedbackModal();\n\n return (\n <Box style={{ alignSelf: 'flex-start' }} maxWidth=\"90%\">\n {message.parts.map((content, index) => (\n <MessageContent key={index} part={content} />\n ))}\n {isLoading ? (\n <Flex gap={1}>\n <IconButton\n label=\"Upvote\"\n size=\"XS\"\n variant=\"ghost\"\n onClick={() => upvoteMessage(message.id)}\n >\n <ThumbUp />\n </IconButton>\n <IconButton\n label=\"Downvote\"\n size=\"XS\"\n variant=\"ghost\"\n // For downvoting, user must provide specific feedback\n onClick={() => openFeedbackModal(message.id)}\n >\n <ThumbDown />\n </IconButton>\n </Flex>\n ) : null}\n </Box>\n );\n};\n\nexport const ChatMessage = ({\n message,\n isLoading,\n}: {\n message: AIMessage;\n isLoading?: boolean;\n}) => {\n /**\n * IMPORTANT: Messages are rendered using react-markdown (heavy compute)\n * Component re-renders on each message update, but AI SDK v5 provides\n * throttling (experimental_throttle: 100ms) which batches updates and reduces\n * re-render frequency during streaming.\n */\n if (message.role === 'user') {\n return <UserMessage message={message as UserMessageType} />;\n }\n return <AssistantMessage message={message as AssistantMessageType} />;\n};\n"],"names":["MarkdownStyles","styled","Typography","theme","colors","neutral100","borderRadius","neutral150","primary500","UserMessageTypography","isSchemaToolPart","part","type","capitalize","s","charAt","toUpperCase","slice","getSchemaLink","schema","isComponent","kind","modelType","uid","undefined","category","toMarkerFromSchemaTool","outSchemas","output","schemas","inSchemas","input","length","numSchemas","state","error","steps","map","index","id","toolCallId","name","description","status","action","link","title","MessageContent","_jsx","Markdown","components","a","node","props","target","rel","text","marker","Marker","UserMessage","message","hasText","parts","some","content","trim","attachments","filter","_jsxs","AnimatedBox","as","Flex","direction","alignItems","style","alignSelf","gap","maxWidth","Box","background","borderStyle","padding","hasRadius","attachment","idx","AttachmentPreview","filename","AssistantMessage","isLoading","upvoteMessage","useFeedback","openFeedbackModal","useFeedbackModal","IconButton","label","size","variant","onClick","ThumbUp","ThumbDown","ChatMessage","role"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Message.js","sources":["../../../../../../admin/src/components/AIChat/components/Messages/Message.tsx"],"sourcesContent":["import { Typography, Box, IconButton, Flex } from '@strapi/design-system';\nimport { ThumbUp, ThumbDown } from '@strapi/icons';\nimport Markdown from 'react-markdown';\nimport { styled } from 'styled-components';\n\nimport { useFeedbackModal } from '../../FeedbackModal';\nimport { useFeedback } from '../../hooks/useFeedback';\nimport {\n AIMessage,\n type UserMessage as UserMessageType,\n AssistantMessage as AssistantMessageType,\n type MarkerContent as MarkerContentType,\n} from '../../lib/types/messages';\nimport { AnimatedBox } from '../AnimatedBox';\nimport { AttachmentPreview } from '../Attachments/AttachmentPreview';\n\nimport { Marker } from './Marker';\n\nconst MarkdownStyles = styled(Typography)`\n max-width: 65ch;\n margin: 0 auto;\n overflow-wrap: anywhere;\n word-break: break-word;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-top: 1.25em;\n margin-bottom: 0.5em;\n font-weight: bold;\n }\n\n p {\n margin-bottom: 1em;\n }\n\n ul,\n ol {\n padding-left: 1.5em; /* indentation for bullet points */\n margin-bottom: 1em;\n }\n\n li {\n margin-bottom: 0.5em;\n list-style-type: disc; /* or whatever style you prefer */\n }\n\n strong {\n font-weight: bold;\n }\n\n /* code blocks, blockquotes, etc. */\n code {\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n font-family: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas,\n monospace;\n }\n\n /* links */\n a {\n color: ${({ theme }) => theme.colors.primary500};\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n text-decoration: none;\n\n &:hover {\n text-decoration: underline;\n }\n }\n`;\n\nconst UserMessageTypography = styled(Typography)`\n overflow-wrap: anywhere;\n word-break: break-word;\n`;\n\n// ---------------------------\n// Tool: schemaGenerationTool helpers\n// ---------------------------\n\ntype SchemaToolSchema = {\n action?: 'create' | 'update' | 'remove';\n uid?: string;\n name?: string;\n category?: string;\n kind?: 'collectionType' | 'singleType' | 'component';\n modelType?: 'component' | 'collectionType' | 'singleType';\n};\n\ntype SchemaToolPart = {\n type: 'tool-schemaGenerationTool';\n input?: { schemas?: SchemaToolSchema[] };\n output?: { schemas?: SchemaToolSchema[]; error?: unknown };\n toolCallId?: string;\n};\n\nconst isSchemaToolPart = (part: unknown): part is SchemaToolPart => {\n if (typeof part !== 'object' || part === null || !('type' in part)) {\n return false;\n }\n\n return part.type === 'tool-schemaGenerationTool';\n};\n\nconst capitalize = (s?: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : '');\n\nconst getSchemaLink = (schema: SchemaToolSchema): string | undefined => {\n const isComponent = (schema.kind ?? schema.modelType) === 'component';\n if (!schema.uid) return undefined;\n return isComponent\n ? `/plugins/content-type-builder/component-categories/${schema.category ?? ''}/${schema.uid}`\n : `/plugins/content-type-builder/content-types/${schema.uid}`;\n};\n\nconst toMarkerFromSchemaTool = (part: SchemaToolPart): MarkerContentType => {\n const outSchemas = part.output?.schemas ?? [];\n const inSchemas = part.input?.schemas ?? [];\n\n const schemas = (outSchemas.length ? outSchemas : inSchemas) as SchemaToolSchema[];\n const numSchemas = schemas.length;\n\n const state: 'loading' | 'success' | 'error' = part.output\n ? part.output.error\n ? 'error'\n : 'success'\n : 'loading';\n\n const steps = schemas.map((schema, index) => ({\n id: `${part.toolCallId ?? 'schemaGenerationTool'}-${schema.uid ?? schema.name ?? index}`,\n description: capitalize(schema.name ?? schema.uid ?? 'Schema'),\n status:\n schema.action === 'create' || schema.action === 'update' || schema.action === 'remove'\n ? schema.action\n : ('update' as const),\n link: getSchemaLink(schema),\n }));\n\n const title =\n state === 'success'\n ? `Updated ${numSchemas} schema${numSchemas === 1 ? '' : 's'}`\n : state === 'error'\n ? `Failed to update schema${numSchemas === 1 ? '' : 's'}`\n : 'Updating schemas';\n\n return {\n type: 'marker',\n title,\n state,\n steps,\n };\n};\n\nconst MessageContent = ({\n part,\n}: {\n part: AIMessage['parts'][number];\n status?: 'loading' | 'success' | 'error';\n}) => {\n if (part.type === 'text') {\n return (\n <MarkdownStyles>\n <Markdown\n components={{\n a: ({ node: _node, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props} />\n ),\n }}\n >\n {part.text}\n </Markdown>\n </MarkdownStyles>\n );\n }\n\n if (isSchemaToolPart(part)) {\n const marker = toMarkerFromSchemaTool(part);\n return <Marker {...marker} />;\n }\n\n return null;\n};\n\nconst UserMessage = ({ message }: { message: UserMessageType }) => {\n const hasText = message.parts.some(\n (content) => content.type === 'text' && content.text.trim() !== ''\n );\n const attachments = message.parts.filter((content) => content.type === 'file');\n\n return (\n <AnimatedBox\n as={Flex}\n direction=\"column\"\n alignItems=\"flex-end\"\n style={{ alignSelf: 'flex-end' }}\n gap={2}\n maxWidth=\"80%\"\n >\n {hasText ? (\n <Box background=\"neutral150\" borderStyle=\"none\" padding={['10px', '16px']} hasRadius>\n {message.parts.map((content, index) => {\n if (content.type !== 'text') return null;\n return <UserMessageTypography key={index}>{content.text}</UserMessageTypography>;\n })}\n </Box>\n ) : null}\n\n {/* Attachments */}\n {attachments.map((attachment, idx) => (\n <AttachmentPreview\n key={`${attachment.type === 'file' ? attachment.filename : attachment.type}-${idx}`}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n attachment={{ ...attachment, status: 'ready' } as any}\n />\n ))}\n </AnimatedBox>\n );\n};\n\nconst AssistantMessage = ({\n message,\n isLoading,\n}: {\n message: AssistantMessageType;\n isLoading?: boolean;\n}) => {\n const { upvoteMessage } = useFeedback();\n const { openFeedbackModal } = useFeedbackModal();\n\n return (\n <Box style={{ alignSelf: 'flex-start' }} maxWidth=\"90%\">\n {message.parts.map((content, index) => (\n <MessageContent key={index} part={content} />\n ))}\n {isLoading ? (\n <Flex gap={1}>\n <IconButton\n label=\"Upvote\"\n size=\"XS\"\n variant=\"ghost\"\n onClick={() => upvoteMessage(message.id)}\n >\n <ThumbUp />\n </IconButton>\n <IconButton\n label=\"Downvote\"\n size=\"XS\"\n variant=\"ghost\"\n // For downvoting, user must provide specific feedback\n onClick={() => openFeedbackModal(message.id)}\n >\n <ThumbDown />\n </IconButton>\n </Flex>\n ) : null}\n </Box>\n );\n};\n\nexport const ChatMessage = ({ message }: { message: AIMessage }) => {\n /**\n * IMPORTANT: Messages are rendered using react-markdown (heavy compute)\n * Component re-renders on each message update, but AI SDK v5 provides\n * throttling (experimental_throttle: 100ms) which batches updates and reduces\n * re-render frequency during streaming.\n */\n if (message.role === 'user') {\n return <UserMessage message={message as UserMessageType} />;\n }\n return <AssistantMessage message={message as AssistantMessageType} />;\n};\n"],"names":["MarkdownStyles","styled","Typography","theme","colors","neutral100","borderRadius","neutral150","primary500","UserMessageTypography","isSchemaToolPart","part","type","capitalize","s","charAt","toUpperCase","slice","getSchemaLink","schema","isComponent","kind","modelType","uid","undefined","category","toMarkerFromSchemaTool","outSchemas","output","schemas","inSchemas","input","length","numSchemas","state","error","steps","map","index","id","toolCallId","name","description","status","action","link","title","MessageContent","_jsx","Markdown","components","a","node","_node","props","target","rel","text","marker","Marker","UserMessage","message","hasText","parts","some","content","trim","attachments","filter","_jsxs","AnimatedBox","as","Flex","direction","alignItems","style","alignSelf","gap","maxWidth","Box","background","borderStyle","padding","hasRadius","attachment","idx","AttachmentPreview","filename","AssistantMessage","isLoading","upvoteMessage","useFeedback","openFeedbackModal","useFeedbackModal","IconButton","label","size","variant","onClick","ThumbUp","ThumbDown","ChatMessage","role"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,MAAMA,cAAAA,GAAiBC,uBAAAA,CAAOC,uBAAAA,CAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAsCnB,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAACC,UAAU,CAAC;;AAE5C,mBAAA,EAAE,CAAC,EAAEF,KAAK,EAAE,GAAKA,KAAAA,CAAMG,YAAY,CAAC;kBACrC,EAAE,CAAC,EAAEH,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAACG,UAAU,CAAC;;;;;;;;WAQhD,EAAE,CAAC,EAAEJ,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAACI,UAAU,CAAC;sBAC9B,EAAE,CAAC,EAAEL,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAACC,UAAU,CAAC;;AAE5C,mBAAA,EAAE,CAAC,EAAEF,KAAK,EAAE,GAAKA,KAAAA,CAAMG,YAAY,CAAC;kBACrC,EAAE,CAAC,EAAEH,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAACG,UAAU,CAAC;;;;;;;;AAQ3D,CAAC;AAED,MAAME,qBAAAA,GAAwBR,uBAAAA,CAAOC,uBAAAA,CAAW;;;AAGhD,CAAC;AAsBD,MAAMQ,mBAAmB,CAACC,IAAAA,GAAAA;IACxB,IAAI,OAAOA,SAAS,QAAA,IAAYA,IAAAA,KAAS,QAAQ,EAAE,MAAA,IAAUA,IAAG,CAAA,EAAI;QAClE,OAAO,KAAA;AACT,IAAA;IAEA,OAAOA,IAAAA,CAAKC,IAAI,KAAK,2BAAA;AACvB,CAAA;AAEA,MAAMC,UAAAA,GAAa,CAACC,CAAAA,GAAgBA,CAAAA,GAAIA,CAAAA,CAAEC,MAAM,CAAC,CAAA,CAAA,CAAGC,WAAW,EAAA,GAAKF,CAAAA,CAAEG,KAAK,CAAC,CAAA,CAAA,GAAK,EAAA;AAEjF,MAAMC,gBAAgB,CAACC,MAAAA,GAAAA;IACrB,MAAMC,WAAAA,GAAc,CAACD,MAAAA,CAAOE,IAAI,IAAIF,MAAAA,CAAOG,SAAQ,MAAO,WAAA;AAC1D,IAAA,IAAI,CAACH,MAAAA,CAAOI,GAAG,EAAE,OAAOC,SAAAA;AACxB,IAAA,OAAOJ,cACH,CAAC,mDAAmD,EAAED,MAAAA,CAAOM,QAAQ,IAAI,EAAA,CAAG,CAAC,EAAEN,MAAAA,CAAOI,GAAG,EAAE,GAC3F,CAAC,4CAA4C,EAAEJ,MAAAA,CAAOI,GAAG,CAAA,CAAE;AACjE,CAAA;AAEA,MAAMG,yBAAyB,CAACf,IAAAA,GAAAA;AAC9B,IAAA,MAAMgB,UAAAA,GAAahB,IAAAA,CAAKiB,MAAM,EAAEC,WAAW,EAAE;AAC7C,IAAA,MAAMC,SAAAA,GAAYnB,IAAAA,CAAKoB,KAAK,EAAEF,WAAW,EAAE;AAE3C,IAAA,MAAMA,OAAAA,GAAWF,UAAAA,CAAWK,MAAM,GAAGL,UAAAA,GAAaG,SAAAA;IAClD,MAAMG,UAAAA,GAAaJ,QAAQG,MAAM;IAEjC,MAAME,KAAAA,GAAyCvB,IAAAA,CAAKiB,MAAM,GACtDjB,IAAAA,CAAKiB,MAAM,CAACO,KAAK,GACf,OAAA,GACA,SAAA,GACF,SAAA;AAEJ,IAAA,MAAMC,QAAQP,OAAAA,CAAQQ,GAAG,CAAC,CAAClB,MAAAA,EAAQmB,SAAW;AAC5CC,YAAAA,EAAAA,EAAI,CAAA,EAAG5B,IAAAA,CAAK6B,UAAU,IAAI,sBAAA,CAAuB,CAAC,EAAErB,MAAAA,CAAOI,GAAG,IAAIJ,MAAAA,CAAOsB,IAAI,IAAIH,KAAAA,CAAAA,CAAO;AACxFI,YAAAA,WAAAA,EAAa7B,WAAWM,MAAAA,CAAOsB,IAAI,IAAItB,MAAAA,CAAOI,GAAG,IAAI,QAAA,CAAA;AACrDoB,YAAAA,MAAAA,EACExB,MAAAA,CAAOyB,MAAM,KAAK,QAAA,IAAYzB,OAAOyB,MAAM,KAAK,QAAA,IAAYzB,MAAAA,CAAOyB,MAAM,KAAK,QAAA,GAC1EzB,MAAAA,CAAOyB,MAAM,GACZ,QAAA;AACPC,YAAAA,IAAAA,EAAM3B,aAAAA,CAAcC,MAAAA;SACtB,CAAA,CAAA;IAEA,MAAM2B,KAAAA,GACJZ,UAAU,SAAA,GACN,CAAC,QAAQ,EAAED,UAAAA,CAAW,OAAO,EAAEA,UAAAA,KAAe,CAAA,GAAI,KAAK,GAAA,CAAA,CAAK,GAC5DC,KAAAA,KAAU,OAAA,GACR,CAAC,uBAAuB,EAAED,UAAAA,KAAe,CAAA,GAAI,EAAA,GAAK,GAAA,CAAA,CAAK,GACvD,kBAAA;IAER,OAAO;QACLrB,IAAAA,EAAM,QAAA;AACNkC,QAAAA,KAAAA;AACAZ,QAAAA,KAAAA;AACAE,QAAAA;AACF,KAAA;AACF,CAAA;AAEA,MAAMW,cAAAA,GAAiB,CAAC,EACtBpC,IAAI,EAIL,GAAA;IACC,IAAIA,IAAAA,CAAKC,IAAI,KAAK,MAAA,EAAQ;AACxB,QAAA,qBACEoC,cAAA,CAAChD,cAAAA,EAAAA;AACC,YAAA,QAAA,gBAAAgD,cAAA,CAACC,yBAAAA,EAAAA;gBACCC,UAAAA,EAAY;oBACVC,CAAAA,EAAG,CAAC,EAAEC,IAAAA,EAAMC,KAAK,EAAE,GAAGC,KAAAA,EAAO,iBAC3BN,cAAA,CAACG,GAAAA,EAAAA;4BAAEI,MAAAA,EAAO,QAAA;4BAASC,GAAAA,EAAI,qBAAA;AAAuB,4BAAA,GAAGF;;AAErD,iBAAA;AAEC3C,gBAAAA,QAAAA,EAAAA,IAAAA,CAAK8C;;;AAId,IAAA;AAEA,IAAA,IAAI/C,iBAAiBC,IAAAA,CAAAA,EAAO;AAC1B,QAAA,MAAM+C,SAAShC,sBAAAA,CAAuBf,IAAAA,CAAAA;AACtC,QAAA,qBAAOqC,cAAA,CAACW,aAAAA,EAAAA;AAAQ,YAAA,GAAGD;;AACrB,IAAA;IAEA,OAAO,IAAA;AACT,CAAA;AAEA,MAAME,WAAAA,GAAc,CAAC,EAAEC,OAAO,EAAgC,GAAA;AAC5D,IAAA,MAAMC,UAAUD,OAAAA,CAAQE,KAAK,CAACC,IAAI,CAChC,CAACC,OAAAA,GAAYA,OAAAA,CAAQrD,IAAI,KAAK,MAAA,IAAUqD,OAAAA,CAAQR,IAAI,CAACS,IAAI,EAAA,KAAO,EAAA,CAAA;IAElE,MAAMC,WAAAA,GAAcN,OAAAA,CAAQE,KAAK,CAACK,MAAM,CAAC,CAACH,OAAAA,GAAYA,OAAAA,CAAQrD,IAAI,KAAK,MAAA,CAAA;AAEvE,IAAA,qBACEyD,eAAA,CAACC,uBAAAA,EAAAA;QACCC,EAAAA,EAAIC,iBAAAA;QACJC,SAAAA,EAAU,QAAA;QACVC,UAAAA,EAAW,UAAA;QACXC,KAAAA,EAAO;YAAEC,SAAAA,EAAW;AAAW,SAAA;QAC/BC,GAAAA,EAAK,CAAA;QACLC,QAAAA,EAAS,KAAA;;AAERhB,YAAAA,OAAAA,iBACCd,cAAA,CAAC+B,gBAAAA,EAAAA;gBAAIC,UAAAA,EAAW,YAAA;gBAAaC,WAAAA,EAAY,MAAA;gBAAOC,OAAAA,EAAS;AAAC,oBAAA,MAAA;AAAQ,oBAAA;AAAO,iBAAA;gBAAEC,SAAS,EAAA,IAAA;AACjFtB,gBAAAA,QAAAA,EAAAA,OAAAA,CAAQE,KAAK,CAAC1B,GAAG,CAAC,CAAC4B,OAAAA,EAAS3B,KAAAA,GAAAA;AAC3B,oBAAA,IAAI2B,OAAAA,CAAQrD,IAAI,KAAK,MAAA,EAAQ,OAAO,IAAA;AACpC,oBAAA,qBAAOoC,cAAA,CAACvC,qBAAAA,EAAAA;AAAmCwD,wBAAAA,QAAAA,EAAAA,OAAAA,CAAQR;AAAhBnB,qBAAAA,EAAAA,KAAAA,CAAAA;AACrC,gBAAA,CAAA;AAEA,aAAA,CAAA,GAAA,IAAA;AAGH6B,YAAAA,WAAAA,CAAY9B,GAAG,CAAC,CAAC+C,UAAAA,EAAYC,oBAC5BrC,cAAA,CAACsC,mCAAAA,EAAAA;;oBAGCF,UAAAA,EAAY;AAAE,wBAAA,GAAGA,UAAU;wBAAEzC,MAAAA,EAAQ;AAAQ;AAFxC,iBAAA,EAAA,CAAA,EAAGyC,UAAAA,CAAWxE,IAAI,KAAK,MAAA,GAASwE,UAAAA,CAAWG,QAAQ,GAAGH,UAAAA,CAAWxE,IAAI,CAAC,CAAC,EAAEyE,GAAAA,CAAAA,CAAK,CAAA;;;AAO7F,CAAA;AAEA,MAAMG,mBAAmB,CAAC,EACxB3B,OAAO,EACP4B,SAAS,EAIV,GAAA;IACC,MAAM,EAAEC,aAAa,EAAE,GAAGC,uBAAAA,EAAAA;IAC1B,MAAM,EAAEC,iBAAiB,EAAE,GAAGC,8BAAAA,EAAAA;AAE9B,IAAA,qBACExB,eAAA,CAACU,gBAAAA,EAAAA;QAAIJ,KAAAA,EAAO;YAAEC,SAAAA,EAAW;AAAa,SAAA;QAAGE,QAAAA,EAAS,KAAA;;AAC/CjB,YAAAA,OAAAA,CAAQE,KAAK,CAAC1B,GAAG,CAAC,CAAC4B,OAAAA,EAAS3B,sBAC3BU,cAAA,CAACD,cAAAA,EAAAA;oBAA2BpC,IAAAA,EAAMsD;AAAb3B,iBAAAA,EAAAA,KAAAA,CAAAA,CAAAA;AAEtBmD,YAAAA,SAAAA,iBACCpB,eAAA,CAACG,iBAAAA,EAAAA;gBAAKK,GAAAA,EAAK,CAAA;;kCACT7B,cAAA,CAAC8C,uBAAAA,EAAAA;wBACCC,KAAAA,EAAM,QAAA;wBACNC,IAAAA,EAAK,IAAA;wBACLC,OAAAA,EAAQ,OAAA;wBACRC,OAAAA,EAAS,IAAMR,aAAAA,CAAc7B,OAAAA,CAAQtB,EAAE,CAAA;AAEvC,wBAAA,QAAA,gBAAAS,cAAA,CAACmD,aAAAA,EAAAA,EAAAA;;kCAEHnD,cAAA,CAAC8C,uBAAAA,EAAAA;wBACCC,KAAAA,EAAM,UAAA;wBACNC,IAAAA,EAAK,IAAA;wBACLC,OAAAA,EAAQ,OAAA;;wBAERC,OAAAA,EAAS,IAAMN,iBAAAA,CAAkB/B,OAAAA,CAAQtB,EAAE,CAAA;AAE3C,wBAAA,QAAA,gBAAAS,cAAA,CAACoD,eAAAA,EAAAA,EAAAA;;;AAGH,aAAA,CAAA,GAAA;;;AAGV,CAAA;AAEO,MAAMC,WAAAA,GAAc,CAAC,EAAExC,OAAO,EAA0B,GAAA;AAC7D;;;;;AAKC,MACD,IAAIA,OAAAA,CAAQyC,IAAI,KAAK,MAAA,EAAQ;AAC3B,QAAA,qBAAOtD,cAAA,CAACY,WAAAA,EAAAA;YAAYC,OAAAA,EAASA;;AAC/B,IAAA;AACA,IAAA,qBAAOb,cAAA,CAACwC,gBAAAA,EAAAA;QAAiB3B,OAAAA,EAASA;;AACpC;;;;"}
|
|
@@ -75,7 +75,12 @@ const UserMessageTypography = styled(Typography)`
|
|
|
75
75
|
overflow-wrap: anywhere;
|
|
76
76
|
word-break: break-word;
|
|
77
77
|
`;
|
|
78
|
-
const isSchemaToolPart = (part)=>
|
|
78
|
+
const isSchemaToolPart = (part)=>{
|
|
79
|
+
if (typeof part !== 'object' || part === null || !('type' in part)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return part.type === 'tool-schemaGenerationTool';
|
|
83
|
+
};
|
|
79
84
|
const capitalize = (s)=>s ? s.charAt(0).toUpperCase() + s.slice(1) : '';
|
|
80
85
|
const getSchemaLink = (schema)=>{
|
|
81
86
|
const isComponent = (schema.kind ?? schema.modelType) === 'component';
|
|
@@ -107,7 +112,7 @@ const MessageContent = ({ part })=>{
|
|
|
107
112
|
return /*#__PURE__*/ jsx(MarkdownStyles, {
|
|
108
113
|
children: /*#__PURE__*/ jsx(Markdown, {
|
|
109
114
|
components: {
|
|
110
|
-
a: ({ node, ...props })=>/*#__PURE__*/ jsx("a", {
|
|
115
|
+
a: ({ node: _node, ...props })=>/*#__PURE__*/ jsx("a", {
|
|
111
116
|
target: "_blank",
|
|
112
117
|
rel: "noopener noreferrer",
|
|
113
118
|
...props
|
|
@@ -198,7 +203,7 @@ const AssistantMessage = ({ message, isLoading })=>{
|
|
|
198
203
|
]
|
|
199
204
|
});
|
|
200
205
|
};
|
|
201
|
-
const ChatMessage = ({ message
|
|
206
|
+
const ChatMessage = ({ message })=>{
|
|
202
207
|
/**
|
|
203
208
|
* IMPORTANT: Messages are rendered using react-markdown (heavy compute)
|
|
204
209
|
* Component re-renders on each message update, but AI SDK v5 provides
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.mjs","sources":["../../../../../../admin/src/components/AIChat/components/Messages/Message.tsx"],"sourcesContent":["import { Typography, Box, IconButton, Flex } from '@strapi/design-system';\nimport { ThumbUp, ThumbDown } from '@strapi/icons';\nimport Markdown from 'react-markdown';\nimport { styled } from 'styled-components';\n\nimport { useFeedbackModal } from '../../FeedbackModal';\nimport { useFeedback } from '../../hooks/useFeedback';\nimport {\n AIMessage,\n type UserMessage as UserMessageType,\n AssistantMessage as AssistantMessageType,\n type MarkerContent as MarkerContentType,\n} from '../../lib/types/messages';\nimport { AnimatedBox } from '../AnimatedBox';\nimport { AttachmentPreview } from '../Attachments/AttachmentPreview';\n\nimport { Marker } from './Marker';\n\nconst MarkdownStyles = styled(Typography)`\n max-width: 65ch;\n margin: 0 auto;\n overflow-wrap: anywhere;\n word-break: break-word;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-top: 1.25em;\n margin-bottom: 0.5em;\n font-weight: bold;\n }\n\n p {\n margin-bottom: 1em;\n }\n\n ul,\n ol {\n padding-left: 1.5em; /* indentation for bullet points */\n margin-bottom: 1em;\n }\n\n li {\n margin-bottom: 0.5em;\n list-style-type: disc; /* or whatever style you prefer */\n }\n\n strong {\n font-weight: bold;\n }\n\n /* code blocks, blockquotes, etc. */\n code {\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n font-family: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas,\n monospace;\n }\n\n /* links */\n a {\n color: ${({ theme }) => theme.colors.primary500};\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n text-decoration: none;\n\n &:hover {\n text-decoration: underline;\n }\n }\n`;\n\nconst UserMessageTypography = styled(Typography)`\n overflow-wrap: anywhere;\n word-break: break-word;\n`;\n\n// ---------------------------\n// Tool: schemaGenerationTool helpers\n// ---------------------------\n\ntype SchemaToolSchema = {\n action?: 'create' | 'update' | 'remove';\n uid?: string;\n name?: string;\n category?: string;\n kind?: 'collectionType' | 'singleType' | 'component';\n modelType?: 'component' | 'collectionType' | 'singleType';\n};\n\ntype SchemaToolPart = {\n type: 'tool-schemaGenerationTool';\n input?: { schemas?: SchemaToolSchema[] };\n output?: { schemas?: SchemaToolSchema[]; error?: unknown };\n toolCallId?: string;\n};\n\nconst isSchemaToolPart = (part: any): part is SchemaToolPart =>\n part && typeof part === 'object' && part.type === 'tool-schemaGenerationTool';\n\nconst capitalize = (s?: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : '');\n\nconst getSchemaLink = (schema: SchemaToolSchema): string | undefined => {\n const isComponent = (schema.kind ?? schema.modelType) === 'component';\n if (!schema.uid) return undefined;\n return isComponent\n ? `/plugins/content-type-builder/component-categories/${schema.category ?? ''}/${schema.uid}`\n : `/plugins/content-type-builder/content-types/${schema.uid}`;\n};\n\nconst toMarkerFromSchemaTool = (part: SchemaToolPart): MarkerContentType => {\n const outSchemas = part.output?.schemas ?? [];\n const inSchemas = part.input?.schemas ?? [];\n\n const schemas = (outSchemas.length ? outSchemas : inSchemas) as SchemaToolSchema[];\n const numSchemas = schemas.length;\n\n const state: 'loading' | 'success' | 'error' = part.output\n ? part.output.error\n ? 'error'\n : 'success'\n : 'loading';\n\n const steps = schemas.map((schema, index) => ({\n id: `${part.toolCallId ?? 'schemaGenerationTool'}-${schema.uid ?? schema.name ?? index}`,\n description: capitalize(schema.name ?? schema.uid ?? 'Schema'),\n status:\n schema.action === 'create' || schema.action === 'update' || schema.action === 'remove'\n ? schema.action\n : ('update' as const),\n link: getSchemaLink(schema),\n }));\n\n const title =\n state === 'success'\n ? `Updated ${numSchemas} schema${numSchemas === 1 ? '' : 's'}`\n : state === 'error'\n ? `Failed to update schema${numSchemas === 1 ? '' : 's'}`\n : 'Updating schemas';\n\n return {\n type: 'marker',\n title,\n state,\n steps,\n };\n};\n\nconst MessageContent = ({\n part,\n}: {\n part: AIMessage['parts'][number];\n status?: 'loading' | 'success' | 'error';\n}) => {\n if (part.type === 'text') {\n return (\n <MarkdownStyles>\n <Markdown\n components={{\n a: ({ node, ...props }) => <a target=\"_blank\" rel=\"noopener noreferrer\" {...props} />,\n }}\n >\n {part.text}\n </Markdown>\n </MarkdownStyles>\n );\n }\n\n if (isSchemaToolPart(part)) {\n const marker = toMarkerFromSchemaTool(part);\n return <Marker {...marker} />;\n }\n\n return null;\n};\n\nconst UserMessage = ({ message }: { message: UserMessageType }) => {\n const hasText = message.parts.some(\n (content) => content.type === 'text' && content.text.trim() !== ''\n );\n const attachments = message.parts.filter((content) => content.type === 'file');\n\n return (\n <AnimatedBox\n as={Flex}\n direction=\"column\"\n alignItems=\"flex-end\"\n style={{ alignSelf: 'flex-end' }}\n gap={2}\n maxWidth=\"80%\"\n >\n {hasText ? (\n <Box background=\"neutral150\" borderStyle=\"none\" padding={['10px', '16px']} hasRadius>\n {message.parts.map((content, index) => {\n if (content.type !== 'text') return null;\n return <UserMessageTypography key={index}>{content.text}</UserMessageTypography>;\n })}\n </Box>\n ) : null}\n\n {/* Attachments */}\n {attachments.map((attachment, idx) => (\n <AttachmentPreview\n key={`${attachment.type === 'file' ? attachment.filename : attachment.type}-${idx}`}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n attachment={{ ...attachment, status: 'ready' } as any}\n />\n ))}\n </AnimatedBox>\n );\n};\n\nconst AssistantMessage = ({\n message,\n isLoading,\n}: {\n message: AssistantMessageType;\n isLoading?: boolean;\n}) => {\n const { upvoteMessage } = useFeedback();\n const { openFeedbackModal } = useFeedbackModal();\n\n return (\n <Box style={{ alignSelf: 'flex-start' }} maxWidth=\"90%\">\n {message.parts.map((content, index) => (\n <MessageContent key={index} part={content} />\n ))}\n {isLoading ? (\n <Flex gap={1}>\n <IconButton\n label=\"Upvote\"\n size=\"XS\"\n variant=\"ghost\"\n onClick={() => upvoteMessage(message.id)}\n >\n <ThumbUp />\n </IconButton>\n <IconButton\n label=\"Downvote\"\n size=\"XS\"\n variant=\"ghost\"\n // For downvoting, user must provide specific feedback\n onClick={() => openFeedbackModal(message.id)}\n >\n <ThumbDown />\n </IconButton>\n </Flex>\n ) : null}\n </Box>\n );\n};\n\nexport const ChatMessage = ({\n message,\n isLoading,\n}: {\n message: AIMessage;\n isLoading?: boolean;\n}) => {\n /**\n * IMPORTANT: Messages are rendered using react-markdown (heavy compute)\n * Component re-renders on each message update, but AI SDK v5 provides\n * throttling (experimental_throttle: 100ms) which batches updates and reduces\n * re-render frequency during streaming.\n */\n if (message.role === 'user') {\n return <UserMessage message={message as UserMessageType} />;\n }\n return <AssistantMessage message={message as AssistantMessageType} />;\n};\n"],"names":["MarkdownStyles","styled","Typography","theme","colors","neutral100","borderRadius","neutral150","primary500","UserMessageTypography","isSchemaToolPart","part","type","capitalize","s","charAt","toUpperCase","slice","getSchemaLink","schema","isComponent","kind","modelType","uid","undefined","category","toMarkerFromSchemaTool","outSchemas","output","schemas","inSchemas","input","length","numSchemas","state","error","steps","map","index","id","toolCallId","name","description","status","action","link","title","MessageContent","_jsx","Markdown","components","a","node","props","target","rel","text","marker","Marker","UserMessage","message","hasText","parts","some","content","trim","attachments","filter","_jsxs","AnimatedBox","as","Flex","direction","alignItems","style","alignSelf","gap","maxWidth","Box","background","borderStyle","padding","hasRadius","attachment","idx","AttachmentPreview","filename","AssistantMessage","isLoading","upvoteMessage","useFeedback","openFeedbackModal","useFeedbackModal","IconButton","label","size","variant","onClick","ThumbUp","ThumbDown","ChatMessage","role"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Message.mjs","sources":["../../../../../../admin/src/components/AIChat/components/Messages/Message.tsx"],"sourcesContent":["import { Typography, Box, IconButton, Flex } from '@strapi/design-system';\nimport { ThumbUp, ThumbDown } from '@strapi/icons';\nimport Markdown from 'react-markdown';\nimport { styled } from 'styled-components';\n\nimport { useFeedbackModal } from '../../FeedbackModal';\nimport { useFeedback } from '../../hooks/useFeedback';\nimport {\n AIMessage,\n type UserMessage as UserMessageType,\n AssistantMessage as AssistantMessageType,\n type MarkerContent as MarkerContentType,\n} from '../../lib/types/messages';\nimport { AnimatedBox } from '../AnimatedBox';\nimport { AttachmentPreview } from '../Attachments/AttachmentPreview';\n\nimport { Marker } from './Marker';\n\nconst MarkdownStyles = styled(Typography)`\n max-width: 65ch;\n margin: 0 auto;\n overflow-wrap: anywhere;\n word-break: break-word;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-top: 1.25em;\n margin-bottom: 0.5em;\n font-weight: bold;\n }\n\n p {\n margin-bottom: 1em;\n }\n\n ul,\n ol {\n padding-left: 1.5em; /* indentation for bullet points */\n margin-bottom: 1em;\n }\n\n li {\n margin-bottom: 0.5em;\n list-style-type: disc; /* or whatever style you prefer */\n }\n\n strong {\n font-weight: bold;\n }\n\n /* code blocks, blockquotes, etc. */\n code {\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n font-family: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas,\n monospace;\n }\n\n /* links */\n a {\n color: ${({ theme }) => theme.colors.primary500};\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n text-decoration: none;\n\n &:hover {\n text-decoration: underline;\n }\n }\n`;\n\nconst UserMessageTypography = styled(Typography)`\n overflow-wrap: anywhere;\n word-break: break-word;\n`;\n\n// ---------------------------\n// Tool: schemaGenerationTool helpers\n// ---------------------------\n\ntype SchemaToolSchema = {\n action?: 'create' | 'update' | 'remove';\n uid?: string;\n name?: string;\n category?: string;\n kind?: 'collectionType' | 'singleType' | 'component';\n modelType?: 'component' | 'collectionType' | 'singleType';\n};\n\ntype SchemaToolPart = {\n type: 'tool-schemaGenerationTool';\n input?: { schemas?: SchemaToolSchema[] };\n output?: { schemas?: SchemaToolSchema[]; error?: unknown };\n toolCallId?: string;\n};\n\nconst isSchemaToolPart = (part: unknown): part is SchemaToolPart => {\n if (typeof part !== 'object' || part === null || !('type' in part)) {\n return false;\n }\n\n return part.type === 'tool-schemaGenerationTool';\n};\n\nconst capitalize = (s?: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : '');\n\nconst getSchemaLink = (schema: SchemaToolSchema): string | undefined => {\n const isComponent = (schema.kind ?? schema.modelType) === 'component';\n if (!schema.uid) return undefined;\n return isComponent\n ? `/plugins/content-type-builder/component-categories/${schema.category ?? ''}/${schema.uid}`\n : `/plugins/content-type-builder/content-types/${schema.uid}`;\n};\n\nconst toMarkerFromSchemaTool = (part: SchemaToolPart): MarkerContentType => {\n const outSchemas = part.output?.schemas ?? [];\n const inSchemas = part.input?.schemas ?? [];\n\n const schemas = (outSchemas.length ? outSchemas : inSchemas) as SchemaToolSchema[];\n const numSchemas = schemas.length;\n\n const state: 'loading' | 'success' | 'error' = part.output\n ? part.output.error\n ? 'error'\n : 'success'\n : 'loading';\n\n const steps = schemas.map((schema, index) => ({\n id: `${part.toolCallId ?? 'schemaGenerationTool'}-${schema.uid ?? schema.name ?? index}`,\n description: capitalize(schema.name ?? schema.uid ?? 'Schema'),\n status:\n schema.action === 'create' || schema.action === 'update' || schema.action === 'remove'\n ? schema.action\n : ('update' as const),\n link: getSchemaLink(schema),\n }));\n\n const title =\n state === 'success'\n ? `Updated ${numSchemas} schema${numSchemas === 1 ? '' : 's'}`\n : state === 'error'\n ? `Failed to update schema${numSchemas === 1 ? '' : 's'}`\n : 'Updating schemas';\n\n return {\n type: 'marker',\n title,\n state,\n steps,\n };\n};\n\nconst MessageContent = ({\n part,\n}: {\n part: AIMessage['parts'][number];\n status?: 'loading' | 'success' | 'error';\n}) => {\n if (part.type === 'text') {\n return (\n <MarkdownStyles>\n <Markdown\n components={{\n a: ({ node: _node, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props} />\n ),\n }}\n >\n {part.text}\n </Markdown>\n </MarkdownStyles>\n );\n }\n\n if (isSchemaToolPart(part)) {\n const marker = toMarkerFromSchemaTool(part);\n return <Marker {...marker} />;\n }\n\n return null;\n};\n\nconst UserMessage = ({ message }: { message: UserMessageType }) => {\n const hasText = message.parts.some(\n (content) => content.type === 'text' && content.text.trim() !== ''\n );\n const attachments = message.parts.filter((content) => content.type === 'file');\n\n return (\n <AnimatedBox\n as={Flex}\n direction=\"column\"\n alignItems=\"flex-end\"\n style={{ alignSelf: 'flex-end' }}\n gap={2}\n maxWidth=\"80%\"\n >\n {hasText ? (\n <Box background=\"neutral150\" borderStyle=\"none\" padding={['10px', '16px']} hasRadius>\n {message.parts.map((content, index) => {\n if (content.type !== 'text') return null;\n return <UserMessageTypography key={index}>{content.text}</UserMessageTypography>;\n })}\n </Box>\n ) : null}\n\n {/* Attachments */}\n {attachments.map((attachment, idx) => (\n <AttachmentPreview\n key={`${attachment.type === 'file' ? attachment.filename : attachment.type}-${idx}`}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n attachment={{ ...attachment, status: 'ready' } as any}\n />\n ))}\n </AnimatedBox>\n );\n};\n\nconst AssistantMessage = ({\n message,\n isLoading,\n}: {\n message: AssistantMessageType;\n isLoading?: boolean;\n}) => {\n const { upvoteMessage } = useFeedback();\n const { openFeedbackModal } = useFeedbackModal();\n\n return (\n <Box style={{ alignSelf: 'flex-start' }} maxWidth=\"90%\">\n {message.parts.map((content, index) => (\n <MessageContent key={index} part={content} />\n ))}\n {isLoading ? (\n <Flex gap={1}>\n <IconButton\n label=\"Upvote\"\n size=\"XS\"\n variant=\"ghost\"\n onClick={() => upvoteMessage(message.id)}\n >\n <ThumbUp />\n </IconButton>\n <IconButton\n label=\"Downvote\"\n size=\"XS\"\n variant=\"ghost\"\n // For downvoting, user must provide specific feedback\n onClick={() => openFeedbackModal(message.id)}\n >\n <ThumbDown />\n </IconButton>\n </Flex>\n ) : null}\n </Box>\n );\n};\n\nexport const ChatMessage = ({ message }: { message: AIMessage }) => {\n /**\n * IMPORTANT: Messages are rendered using react-markdown (heavy compute)\n * Component re-renders on each message update, but AI SDK v5 provides\n * throttling (experimental_throttle: 100ms) which batches updates and reduces\n * re-render frequency during streaming.\n */\n if (message.role === 'user') {\n return <UserMessage message={message as UserMessageType} />;\n }\n return <AssistantMessage message={message as AssistantMessageType} />;\n};\n"],"names":["MarkdownStyles","styled","Typography","theme","colors","neutral100","borderRadius","neutral150","primary500","UserMessageTypography","isSchemaToolPart","part","type","capitalize","s","charAt","toUpperCase","slice","getSchemaLink","schema","isComponent","kind","modelType","uid","undefined","category","toMarkerFromSchemaTool","outSchemas","output","schemas","inSchemas","input","length","numSchemas","state","error","steps","map","index","id","toolCallId","name","description","status","action","link","title","MessageContent","_jsx","Markdown","components","a","node","_node","props","target","rel","text","marker","Marker","UserMessage","message","hasText","parts","some","content","trim","attachments","filter","_jsxs","AnimatedBox","as","Flex","direction","alignItems","style","alignSelf","gap","maxWidth","Box","background","borderStyle","padding","hasRadius","attachment","idx","AttachmentPreview","filename","AssistantMessage","isLoading","upvoteMessage","useFeedback","openFeedbackModal","useFeedbackModal","IconButton","label","size","variant","onClick","ThumbUp","ThumbDown","ChatMessage","role"],"mappings":"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"}
|
|
@@ -59,7 +59,7 @@ const getAIJwt = async ()=>{
|
|
|
59
59
|
const { data } = await get('/admin/ai-token');
|
|
60
60
|
const token = data?.token || data?.data?.token;
|
|
61
61
|
const expiresAt = data?.expiresAt || data?.data?.expiresAt;
|
|
62
|
-
if (token && expiresAt) {
|
|
62
|
+
if (typeof token === 'string' && typeof expiresAt === 'string') {
|
|
63
63
|
aiTokenCache = {
|
|
64
64
|
token,
|
|
65
65
|
expiresAt
|
|
@@ -108,11 +108,17 @@ const buildHeaders = (token, ctx, extra)=>{
|
|
|
108
108
|
...extra
|
|
109
109
|
};
|
|
110
110
|
};
|
|
111
|
+
const getErrorMessage = (body)=>{
|
|
112
|
+
if (typeof body !== 'object' || body === null || !('error' in body)) {
|
|
113
|
+
return '';
|
|
114
|
+
}
|
|
115
|
+
return String(body.error ?? '').toLowerCase();
|
|
116
|
+
};
|
|
111
117
|
const shouldRetryForToken = (status, body)=>{
|
|
112
118
|
if (status === 401 || status === 403) {
|
|
113
119
|
return true;
|
|
114
120
|
}
|
|
115
|
-
const msg = (body
|
|
121
|
+
const msg = getErrorMessage(body);
|
|
116
122
|
return msg.includes('expired') || msg.includes('invalid token');
|
|
117
123
|
};
|
|
118
124
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiClient.js","sources":["../../../../../admin/src/components/AIChat/lib/aiClient.ts"],"sourcesContent":["import { getFetchClient } from '@strapi/admin/strapi-admin';\n\n/**\n * Centralized AI client utilities:\n * - Token retrieval via admin endpoint using getFetchClient\n * - In-memory + sessionStorage caching with near-expiry buffer\n * - Safe JSON parsing for error handling\n * - Single-retry policy on token invalidation\n */\n\nexport interface AITokenData {\n token: string;\n expiresAt: string;\n}\n\nlet aiTokenCache: AITokenData | null = null;\nconst SESSION_STORAGE_KEY = 'strapi-ai-token';\nconst EXPIRY_BUFFER_MS = 60 * 1000;\n\nconst parseExpiryMs = (expiresAt: string): number | null => {\n const ms = Date.parse(expiresAt);\n return Number.isFinite(ms) ? ms : null;\n};\n\ntype TokenState = 'valid' | 'stale' | 'expired';\n\nconst getTokenState = (\n expiresAt: string,\n bufferMs = EXPIRY_BUFFER_MS,\n now = Date.now()\n): TokenState => {\n const expMs = parseExpiryMs(expiresAt);\n if (expMs === null) {\n return 'expired';\n }\n if (expMs <= now) {\n return 'expired';\n }\n if (expMs - bufferMs <= now) {\n return 'stale';\n }\n\n return 'valid';\n};\n\nconst isTokenUsable = (expiresAt: string, bufferMs = EXPIRY_BUFFER_MS, now = Date.now()): boolean =>\n getTokenState(expiresAt, bufferMs, now) === 'valid';\n\nexport const clearAIJwt = () => {\n aiTokenCache = null;\n sessionStorage.removeItem(SESSION_STORAGE_KEY);\n};\n\nconst readFromSession = (): AITokenData | null => {\n try {\n const raw = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!raw) {\n return null;\n }\n\n const parsed = JSON.parse(raw) as AITokenData;\n return parsed;\n } catch {\n return null;\n }\n};\n\nconst writeToSession = (data: AITokenData) => {\n sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(data));\n};\n\nexport const getAIJwt = async (): Promise<AITokenData | null> => {\n // Check memory cache\n if (aiTokenCache && isTokenUsable(aiTokenCache.expiresAt)) {\n return aiTokenCache;\n }\n\n // Check session storage\n const fromSession = readFromSession();\n if (fromSession && isTokenUsable(fromSession.expiresAt)) {\n aiTokenCache = fromSession;\n\n return aiTokenCache;\n }\n\n // Fetch from admin endpoint\n try {\n const { get } = getFetchClient();\n const { data } = await get('/admin/ai-token');\n\n const token = data?.token || data?.data?.token;\n const expiresAt = data?.expiresAt || data?.data?.expiresAt;\n\n if (token && expiresAt) {\n aiTokenCache = { token, expiresAt };\n writeToSession(aiTokenCache);\n\n return aiTokenCache;\n }\n return null;\n } catch {\n return null;\n }\n};\n\nexport const prefetchAIToken = async (): Promise<void> => {\n try {\n // If we already have a valid token (not expiring soon), do nothing\n const existing = await getAIJwt();\n if (existing) {\n return;\n }\n\n // Attempt a fetch to populate cache\n await getAIJwt();\n } catch {\n // no-op\n }\n};\n\nexport const safeParseJson = async (response: Response): Promise<any> => {\n try {\n return await response.json();\n } catch {\n try {\n const text = await response.text();\n\n return { error: text };\n } catch {\n return undefined;\n }\n }\n};\n\nexport interface StrapiContextHeaders {\n strapiVersion?: string | null;\n projectId?: string | null;\n userId?: string | null;\n}\n\nconst buildHeaders = (\n token: string,\n ctx?: StrapiContextHeaders,\n extra?: HeadersInit\n): Record<string, string> => {\n return {\n Authorization: `Bearer ${token}`,\n 'X-Strapi-Version': ctx?.strapiVersion || 'latest',\n 'X-Strapi-User': ctx?.userId || 'unknown',\n 'X-Strapi-Project-Id': ctx?.projectId || 'unknown',\n ...(extra as Record<string, string>),\n };\n};\n\nconst shouldRetryForToken = (status: number, body: any): boolean => {\n if (status === 401 || status === 403) {\n return true;\n }\n\n const msg = (body?.error || '').toString().toLowerCase();\n return msg.includes('expired') || msg.includes('invalid token');\n};\n\nexport interface FetchAIOptions extends RequestInit {\n ctx?: StrapiContextHeaders;\n}\n\n/**\n * Generic fetch wrapper for AI endpoints with token injection and single retry on invalidation\n */\nexport const fetchAI = async (\n input: RequestInfo | URL,\n options: FetchAIOptions = {}\n): Promise<Response> => {\n // Get token\n const tokenData = await getAIJwt();\n\n if (!tokenData?.token) {\n const error = new Error(\n 'Could not authorize with AI Server. Please contact your administrator.'\n );\n\n throw error;\n }\n\n const make = async (token: string): Promise<Response> => {\n const headers = buildHeaders(token, options.ctx, options.headers);\n return fetch(input, {\n ...options,\n headers,\n });\n };\n\n let response = await make(tokenData.token);\n\n let body: unknown | undefined = undefined;\n try {\n body = await safeParseJson(response.clone());\n } catch {\n // no-op\n }\n\n if (shouldRetryForToken(response.status, body)) {\n clearAIJwt();\n\n const refreshed = await getAIJwt();\n\n if (refreshed?.token && refreshed.token !== tokenData.token) {\n response = await make(refreshed.token);\n }\n }\n\n return response;\n};\n\n/**\n * Factory to provide a fetch implementation compatible with AI SDK useChat\n * that injects AI JWT + Strapi context headers and retries on token invalidation once.\n */\nexport const makeChatFetch = (ctx: StrapiContextHeaders) => {\n return async (input: RequestInfo | URL, options: RequestInit = {}): Promise<Response> => {\n return fetchAI(input, { ...options, ctx });\n };\n};\n"],"names":["aiTokenCache","SESSION_STORAGE_KEY","EXPIRY_BUFFER_MS","parseExpiryMs","expiresAt","ms","Date","parse","Number","isFinite","getTokenState","bufferMs","now","expMs","isTokenUsable","clearAIJwt","sessionStorage","removeItem","readFromSession","raw","getItem","parsed","JSON","writeToSession","data","setItem","stringify","getAIJwt","fromSession","get","getFetchClient","token","prefetchAIToken","existing","safeParseJson","response","json","text","error","undefined","buildHeaders","ctx","extra","Authorization","strapiVersion","userId","projectId","shouldRetryForToken","status","body","msg","toString","toLowerCase","includes","fetchAI","input","options","tokenData","Error","make","headers","fetch","clone","refreshed","makeChatFetch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"aiClient.js","sources":["../../../../../admin/src/components/AIChat/lib/aiClient.ts"],"sourcesContent":["import { getFetchClient } from '@strapi/admin/strapi-admin';\n\n/**\n * Centralized AI client utilities:\n * - Token retrieval via admin endpoint using getFetchClient\n * - In-memory + sessionStorage caching with near-expiry buffer\n * - Safe JSON parsing for error handling\n * - Single-retry policy on token invalidation\n */\n\nexport interface AITokenData {\n token: string;\n expiresAt: string;\n}\n\ntype AITokenResponse = Partial<AITokenData> & {\n data?: Partial<AITokenData>;\n};\n\nlet aiTokenCache: AITokenData | null = null;\nconst SESSION_STORAGE_KEY = 'strapi-ai-token';\nconst EXPIRY_BUFFER_MS = 60 * 1000;\n\nconst parseExpiryMs = (expiresAt: string): number | null => {\n const ms = Date.parse(expiresAt);\n return Number.isFinite(ms) ? ms : null;\n};\n\ntype TokenState = 'valid' | 'stale' | 'expired';\n\nconst getTokenState = (\n expiresAt: string,\n bufferMs = EXPIRY_BUFFER_MS,\n now = Date.now()\n): TokenState => {\n const expMs = parseExpiryMs(expiresAt);\n if (expMs === null) {\n return 'expired';\n }\n if (expMs <= now) {\n return 'expired';\n }\n if (expMs - bufferMs <= now) {\n return 'stale';\n }\n\n return 'valid';\n};\n\nconst isTokenUsable = (expiresAt: string, bufferMs = EXPIRY_BUFFER_MS, now = Date.now()): boolean =>\n getTokenState(expiresAt, bufferMs, now) === 'valid';\n\nexport const clearAIJwt = () => {\n aiTokenCache = null;\n sessionStorage.removeItem(SESSION_STORAGE_KEY);\n};\n\nconst readFromSession = (): AITokenData | null => {\n try {\n const raw = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!raw) {\n return null;\n }\n\n const parsed = JSON.parse(raw) as AITokenData;\n return parsed;\n } catch {\n return null;\n }\n};\n\nconst writeToSession = (data: AITokenData) => {\n sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(data));\n};\n\nexport const getAIJwt = async (): Promise<AITokenData | null> => {\n // Check memory cache\n if (aiTokenCache && isTokenUsable(aiTokenCache.expiresAt)) {\n return aiTokenCache;\n }\n\n // Check session storage\n const fromSession = readFromSession();\n if (fromSession && isTokenUsable(fromSession.expiresAt)) {\n aiTokenCache = fromSession;\n\n return aiTokenCache;\n }\n\n // Fetch from admin endpoint\n try {\n const { get } = getFetchClient();\n const { data } = await get<AITokenResponse>('/admin/ai-token');\n\n const token = data?.token || data?.data?.token;\n const expiresAt = data?.expiresAt || data?.data?.expiresAt;\n\n if (typeof token === 'string' && typeof expiresAt === 'string') {\n aiTokenCache = { token, expiresAt };\n writeToSession(aiTokenCache);\n\n return aiTokenCache;\n }\n return null;\n } catch {\n return null;\n }\n};\n\nexport const prefetchAIToken = async (): Promise<void> => {\n try {\n // If we already have a valid token (not expiring soon), do nothing\n const existing = await getAIJwt();\n if (existing) {\n return;\n }\n\n // Attempt a fetch to populate cache\n await getAIJwt();\n } catch {\n // no-op\n }\n};\n\nexport const safeParseJson = async (response: Response): Promise<unknown> => {\n try {\n return await response.json();\n } catch {\n try {\n const text = await response.text();\n\n return { error: text };\n } catch {\n return undefined;\n }\n }\n};\n\nexport interface StrapiContextHeaders {\n strapiVersion?: string | null;\n projectId?: string | null;\n userId?: string | null;\n}\n\nconst buildHeaders = (\n token: string,\n ctx?: StrapiContextHeaders,\n extra?: HeadersInit\n): Record<string, string> => {\n return {\n Authorization: `Bearer ${token}`,\n 'X-Strapi-Version': ctx?.strapiVersion || 'latest',\n 'X-Strapi-User': ctx?.userId || 'unknown',\n 'X-Strapi-Project-Id': ctx?.projectId || 'unknown',\n ...(extra as Record<string, string>),\n };\n};\n\ntype ErrorResponseBody = {\n error?: unknown;\n};\n\nconst getErrorMessage = (body: unknown): string => {\n if (typeof body !== 'object' || body === null || !('error' in body)) {\n return '';\n }\n\n return String((body as ErrorResponseBody).error ?? '').toLowerCase();\n};\n\nconst shouldRetryForToken = (status: number, body: unknown): boolean => {\n if (status === 401 || status === 403) {\n return true;\n }\n\n const msg = getErrorMessage(body);\n return msg.includes('expired') || msg.includes('invalid token');\n};\n\nexport interface FetchAIOptions extends RequestInit {\n ctx?: StrapiContextHeaders;\n}\n\n/**\n * Generic fetch wrapper for AI endpoints with token injection and single retry on invalidation\n */\nexport const fetchAI = async (\n input: RequestInfo | URL,\n options: FetchAIOptions = {}\n): Promise<Response> => {\n // Get token\n const tokenData = await getAIJwt();\n\n if (!tokenData?.token) {\n const error = new Error(\n 'Could not authorize with AI Server. Please contact your administrator.'\n );\n\n throw error;\n }\n\n const make = async (token: string): Promise<Response> => {\n const headers = buildHeaders(token, options.ctx, options.headers);\n return fetch(input, {\n ...options,\n headers,\n });\n };\n\n let response = await make(tokenData.token);\n\n let body: unknown | undefined = undefined;\n try {\n body = await safeParseJson(response.clone());\n } catch {\n // no-op\n }\n\n if (shouldRetryForToken(response.status, body)) {\n clearAIJwt();\n\n const refreshed = await getAIJwt();\n\n if (refreshed?.token && refreshed.token !== tokenData.token) {\n response = await make(refreshed.token);\n }\n }\n\n return response;\n};\n\n/**\n * Factory to provide a fetch implementation compatible with AI SDK useChat\n * that injects AI JWT + Strapi context headers and retries on token invalidation once.\n */\nexport const makeChatFetch = (ctx: StrapiContextHeaders) => {\n return async (input: RequestInfo | URL, options: RequestInit = {}): Promise<Response> => {\n return fetchAI(input, { ...options, ctx });\n };\n};\n"],"names":["aiTokenCache","SESSION_STORAGE_KEY","EXPIRY_BUFFER_MS","parseExpiryMs","expiresAt","ms","Date","parse","Number","isFinite","getTokenState","bufferMs","now","expMs","isTokenUsable","clearAIJwt","sessionStorage","removeItem","readFromSession","raw","getItem","parsed","JSON","writeToSession","data","setItem","stringify","getAIJwt","fromSession","get","getFetchClient","token","prefetchAIToken","existing","safeParseJson","response","json","text","error","undefined","buildHeaders","ctx","extra","Authorization","strapiVersion","userId","projectId","getErrorMessage","body","String","toLowerCase","shouldRetryForToken","status","msg","includes","fetchAI","input","options","tokenData","Error","make","headers","fetch","clone","refreshed","makeChatFetch"],"mappings":";;;;AAmBA,IAAIA,YAAAA,GAAmC,IAAA;AACvC,MAAMC,mBAAAA,GAAsB,iBAAA;AAC5B,MAAMC,mBAAmB,EAAA,GAAK,IAAA;AAE9B,MAAMC,gBAAgB,CAACC,SAAAA,GAAAA;IACrB,MAAMC,EAAAA,GAAKC,IAAAA,CAAKC,KAAK,CAACH,SAAAA,CAAAA;AACtB,IAAA,OAAOI,MAAAA,CAAOC,QAAQ,CAACJ,EAAAA,CAAAA,GAAMA,EAAAA,GAAK,IAAA;AACpC,CAAA;AAIA,MAAMK,aAAAA,GAAgB,CACpBN,SAAAA,EACAO,QAAAA,GAAWT,gBAAgB,EAC3BU,GAAAA,GAAMN,IAAAA,CAAKM,GAAG,EAAE,GAAA;AAEhB,IAAA,MAAMC,QAAQV,aAAAA,CAAcC,SAAAA,CAAAA;AAC5B,IAAA,IAAIS,UAAU,IAAA,EAAM;QAClB,OAAO,SAAA;AACT,IAAA;AACA,IAAA,IAAIA,SAASD,GAAAA,EAAK;QAChB,OAAO,SAAA;AACT,IAAA;IACA,IAAIC,KAAAA,GAAQF,YAAYC,GAAAA,EAAK;QAC3B,OAAO,OAAA;AACT,IAAA;IAEA,OAAO,OAAA;AACT,CAAA;AAEA,MAAME,aAAAA,GAAgB,CAACV,SAAAA,EAAmBO,QAAAA,GAAWT,gBAAgB,EAAEU,GAAAA,GAAMN,IAAAA,CAAKM,GAAG,EAAE,GACrFF,aAAAA,CAAcN,SAAAA,EAAWO,UAAUC,GAAAA,CAAAA,KAAS,OAAA;MAEjCG,UAAAA,GAAa,IAAA;IACxBf,YAAAA,GAAe,IAAA;AACfgB,IAAAA,cAAAA,CAAeC,UAAU,CAAChB,mBAAAA,CAAAA;AAC5B;AAEA,MAAMiB,eAAAA,GAAkB,IAAA;IACtB,IAAI;QACF,MAAMC,GAAAA,GAAMH,cAAAA,CAAeI,OAAO,CAACnB,mBAAAA,CAAAA;AACnC,QAAA,IAAI,CAACkB,GAAAA,EAAK;YACR,OAAO,IAAA;AACT,QAAA;QAEA,MAAME,MAAAA,GAASC,IAAAA,CAAKf,KAAK,CAACY,GAAAA,CAAAA;QAC1B,OAAOE,MAAAA;AACT,IAAA,CAAA,CAAE,OAAM;QACN,OAAO,IAAA;AACT,IAAA;AACF,CAAA;AAEA,MAAME,iBAAiB,CAACC,IAAAA,GAAAA;AACtBR,IAAAA,cAAAA,CAAeS,OAAO,CAACxB,mBAAAA,EAAqBqB,IAAAA,CAAKI,SAAS,CAACF,IAAAA,CAAAA,CAAAA;AAC7D,CAAA;MAEaG,QAAAA,GAAW,UAAA;;AAEtB,IAAA,IAAI3B,YAAAA,IAAgBc,aAAAA,CAAcd,YAAAA,CAAaI,SAAS,CAAA,EAAG;QACzD,OAAOJ,YAAAA;AACT,IAAA;;AAGA,IAAA,MAAM4B,WAAAA,GAAcV,eAAAA,EAAAA;AACpB,IAAA,IAAIU,WAAAA,IAAed,aAAAA,CAAcc,WAAAA,CAAYxB,SAAS,CAAA,EAAG;QACvDJ,YAAAA,GAAe4B,WAAAA;QAEf,OAAO5B,YAAAA;AACT,IAAA;;IAGA,IAAI;QACF,MAAM,EAAE6B,GAAG,EAAE,GAAGC,0BAAAA,EAAAA;AAChB,QAAA,MAAM,EAAEN,IAAI,EAAE,GAAG,MAAMK,GAAAA,CAAqB,iBAAA,CAAA;AAE5C,QAAA,MAAME,KAAAA,GAAQP,IAAAA,EAAMO,KAAAA,IAASP,IAAAA,EAAMA,IAAAA,EAAMO,KAAAA;AACzC,QAAA,MAAM3B,SAAAA,GAAYoB,IAAAA,EAAMpB,SAAAA,IAAaoB,IAAAA,EAAMA,IAAAA,EAAMpB,SAAAA;AAEjD,QAAA,IAAI,OAAO2B,KAAAA,KAAU,QAAA,IAAY,OAAO3B,cAAc,QAAA,EAAU;YAC9DJ,YAAAA,GAAe;AAAE+B,gBAAAA,KAAAA;AAAO3B,gBAAAA;AAAU,aAAA;YAClCmB,cAAAA,CAAevB,YAAAA,CAAAA;YAEf,OAAOA,YAAAA;AACT,QAAA;QACA,OAAO,IAAA;AACT,IAAA,CAAA,CAAE,OAAM;QACN,OAAO,IAAA;AACT,IAAA;AACF;MAEagC,eAAAA,GAAkB,UAAA;IAC7B,IAAI;;AAEF,QAAA,MAAMC,WAAW,MAAMN,QAAAA,EAAAA;AACvB,QAAA,IAAIM,QAAAA,EAAU;AACZ,YAAA;AACF,QAAA;;QAGA,MAAMN,QAAAA,EAAAA;AACR,IAAA,CAAA,CAAE,OAAM;;AAER,IAAA;AACF;AAEO,MAAMO,gBAAgB,OAAOC,QAAAA,GAAAA;IAClC,IAAI;QACF,OAAO,MAAMA,SAASC,IAAI,EAAA;AAC5B,IAAA,CAAA,CAAE,OAAM;QACN,IAAI;YACF,MAAMC,IAAAA,GAAO,MAAMF,QAAAA,CAASE,IAAI,EAAA;YAEhC,OAAO;gBAAEC,KAAAA,EAAOD;AAAK,aAAA;AACvB,QAAA,CAAA,CAAE,OAAM;YACN,OAAOE,SAAAA;AACT,QAAA;AACF,IAAA;AACF;AAQA,MAAMC,YAAAA,GAAe,CACnBT,KAAAA,EACAU,GAAAA,EACAC,KAAAA,GAAAA;IAEA,OAAO;QACLC,aAAAA,EAAe,CAAC,OAAO,EAAEZ,KAAAA,CAAAA,CAAO;AAChC,QAAA,kBAAA,EAAoBU,KAAKG,aAAAA,IAAiB,QAAA;AAC1C,QAAA,eAAA,EAAiBH,KAAKI,MAAAA,IAAU,SAAA;AAChC,QAAA,qBAAA,EAAuBJ,KAAKK,SAAAA,IAAa,SAAA;AACzC,QAAA,GAAIJ;AACN,KAAA;AACF,CAAA;AAMA,MAAMK,kBAAkB,CAACC,IAAAA,GAAAA;IACvB,IAAI,OAAOA,SAAS,QAAA,IAAYA,IAAAA,KAAS,QAAQ,EAAE,OAAA,IAAWA,IAAG,CAAA,EAAI;QACnE,OAAO,EAAA;AACT,IAAA;AAEA,IAAA,OAAOC,OAAO,IAACD,CAA2BV,KAAK,IAAI,IAAIY,WAAW,EAAA;AACpE,CAAA;AAEA,MAAMC,mBAAAA,GAAsB,CAACC,MAAAA,EAAgBJ,IAAAA,GAAAA;IAC3C,IAAII,MAAAA,KAAW,GAAA,IAAOA,MAAAA,KAAW,GAAA,EAAK;QACpC,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,MAAMC,MAAMN,eAAAA,CAAgBC,IAAAA,CAAAA;AAC5B,IAAA,OAAOK,IAAIC,QAAQ,CAAC,SAAA,CAAA,IAAcD,GAAAA,CAAIC,QAAQ,CAAC,eAAA,CAAA;AACjD,CAAA;AAMA;;AAEC,IACM,MAAMC,OAAAA,GAAU,OACrBC,KAAAA,EACAC,OAAAA,GAA0B,EAAE,GAAA;;AAG5B,IAAA,MAAMC,YAAY,MAAM/B,QAAAA,EAAAA;IAExB,IAAI,CAAC+B,WAAW3B,KAAAA,EAAO;QACrB,MAAMO,KAAAA,GAAQ,IAAIqB,KAAAA,CAChB,wEAAA,CAAA;QAGF,MAAMrB,KAAAA;AACR,IAAA;AAEA,IAAA,MAAMsB,OAAO,OAAO7B,KAAAA,GAAAA;AAClB,QAAA,MAAM8B,UAAUrB,YAAAA,CAAaT,KAAAA,EAAO0B,QAAQhB,GAAG,EAAEgB,QAAQI,OAAO,CAAA;AAChE,QAAA,OAAOC,MAAMN,KAAAA,EAAO;AAClB,YAAA,GAAGC,OAAO;AACVI,YAAAA;AACF,SAAA,CAAA;AACF,IAAA,CAAA;AAEA,IAAA,IAAI1B,QAAAA,GAAW,MAAMyB,IAAAA,CAAKF,SAAAA,CAAU3B,KAAK,CAAA;AAEzC,IAAA,IAAIiB,IAAAA,GAA4BT,SAAAA;IAChC,IAAI;QACFS,IAAAA,GAAO,MAAMd,aAAAA,CAAcC,QAAAA,CAAS4B,KAAK,EAAA,CAAA;AAC3C,IAAA,CAAA,CAAE,OAAM;;AAER,IAAA;AAEA,IAAA,IAAIZ,mBAAAA,CAAoBhB,QAAAA,CAASiB,MAAM,EAAEJ,IAAAA,CAAAA,EAAO;AAC9CjC,QAAAA,UAAAA,EAAAA;AAEA,QAAA,MAAMiD,YAAY,MAAMrC,QAAAA,EAAAA;AAExB,QAAA,IAAIqC,WAAWjC,KAAAA,IAASiC,SAAAA,CAAUjC,KAAK,KAAK2B,SAAAA,CAAU3B,KAAK,EAAE;YAC3DI,QAAAA,GAAW,MAAMyB,IAAAA,CAAKI,SAAAA,CAAUjC,KAAK,CAAA;AACvC,QAAA;AACF,IAAA;IAEA,OAAOI,QAAAA;AACT;AAEA;;;IAIO,MAAM8B,aAAAA,GAAgB,CAACxB,GAAAA,GAAAA;AAC5B,IAAA,OAAO,OAAOe,KAAAA,EAA0BC,OAAAA,GAAuB,EAAE,GAAA;AAC/D,QAAA,OAAOF,QAAQC,KAAAA,EAAO;AAAE,YAAA,GAAGC,OAAO;AAAEhB,YAAAA;AAAI,SAAA,CAAA;AAC1C,IAAA,CAAA;AACF;;;;;;;;;"}
|
|
@@ -57,7 +57,7 @@ const getAIJwt = async ()=>{
|
|
|
57
57
|
const { data } = await get('/admin/ai-token');
|
|
58
58
|
const token = data?.token || data?.data?.token;
|
|
59
59
|
const expiresAt = data?.expiresAt || data?.data?.expiresAt;
|
|
60
|
-
if (token && expiresAt) {
|
|
60
|
+
if (typeof token === 'string' && typeof expiresAt === 'string') {
|
|
61
61
|
aiTokenCache = {
|
|
62
62
|
token,
|
|
63
63
|
expiresAt
|
|
@@ -106,11 +106,17 @@ const buildHeaders = (token, ctx, extra)=>{
|
|
|
106
106
|
...extra
|
|
107
107
|
};
|
|
108
108
|
};
|
|
109
|
+
const getErrorMessage = (body)=>{
|
|
110
|
+
if (typeof body !== 'object' || body === null || !('error' in body)) {
|
|
111
|
+
return '';
|
|
112
|
+
}
|
|
113
|
+
return String(body.error ?? '').toLowerCase();
|
|
114
|
+
};
|
|
109
115
|
const shouldRetryForToken = (status, body)=>{
|
|
110
116
|
if (status === 401 || status === 403) {
|
|
111
117
|
return true;
|
|
112
118
|
}
|
|
113
|
-
const msg = (body
|
|
119
|
+
const msg = getErrorMessage(body);
|
|
114
120
|
return msg.includes('expired') || msg.includes('invalid token');
|
|
115
121
|
};
|
|
116
122
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiClient.mjs","sources":["../../../../../admin/src/components/AIChat/lib/aiClient.ts"],"sourcesContent":["import { getFetchClient } from '@strapi/admin/strapi-admin';\n\n/**\n * Centralized AI client utilities:\n * - Token retrieval via admin endpoint using getFetchClient\n * - In-memory + sessionStorage caching with near-expiry buffer\n * - Safe JSON parsing for error handling\n * - Single-retry policy on token invalidation\n */\n\nexport interface AITokenData {\n token: string;\n expiresAt: string;\n}\n\nlet aiTokenCache: AITokenData | null = null;\nconst SESSION_STORAGE_KEY = 'strapi-ai-token';\nconst EXPIRY_BUFFER_MS = 60 * 1000;\n\nconst parseExpiryMs = (expiresAt: string): number | null => {\n const ms = Date.parse(expiresAt);\n return Number.isFinite(ms) ? ms : null;\n};\n\ntype TokenState = 'valid' | 'stale' | 'expired';\n\nconst getTokenState = (\n expiresAt: string,\n bufferMs = EXPIRY_BUFFER_MS,\n now = Date.now()\n): TokenState => {\n const expMs = parseExpiryMs(expiresAt);\n if (expMs === null) {\n return 'expired';\n }\n if (expMs <= now) {\n return 'expired';\n }\n if (expMs - bufferMs <= now) {\n return 'stale';\n }\n\n return 'valid';\n};\n\nconst isTokenUsable = (expiresAt: string, bufferMs = EXPIRY_BUFFER_MS, now = Date.now()): boolean =>\n getTokenState(expiresAt, bufferMs, now) === 'valid';\n\nexport const clearAIJwt = () => {\n aiTokenCache = null;\n sessionStorage.removeItem(SESSION_STORAGE_KEY);\n};\n\nconst readFromSession = (): AITokenData | null => {\n try {\n const raw = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!raw) {\n return null;\n }\n\n const parsed = JSON.parse(raw) as AITokenData;\n return parsed;\n } catch {\n return null;\n }\n};\n\nconst writeToSession = (data: AITokenData) => {\n sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(data));\n};\n\nexport const getAIJwt = async (): Promise<AITokenData | null> => {\n // Check memory cache\n if (aiTokenCache && isTokenUsable(aiTokenCache.expiresAt)) {\n return aiTokenCache;\n }\n\n // Check session storage\n const fromSession = readFromSession();\n if (fromSession && isTokenUsable(fromSession.expiresAt)) {\n aiTokenCache = fromSession;\n\n return aiTokenCache;\n }\n\n // Fetch from admin endpoint\n try {\n const { get } = getFetchClient();\n const { data } = await get('/admin/ai-token');\n\n const token = data?.token || data?.data?.token;\n const expiresAt = data?.expiresAt || data?.data?.expiresAt;\n\n if (token && expiresAt) {\n aiTokenCache = { token, expiresAt };\n writeToSession(aiTokenCache);\n\n return aiTokenCache;\n }\n return null;\n } catch {\n return null;\n }\n};\n\nexport const prefetchAIToken = async (): Promise<void> => {\n try {\n // If we already have a valid token (not expiring soon), do nothing\n const existing = await getAIJwt();\n if (existing) {\n return;\n }\n\n // Attempt a fetch to populate cache\n await getAIJwt();\n } catch {\n // no-op\n }\n};\n\nexport const safeParseJson = async (response: Response): Promise<any> => {\n try {\n return await response.json();\n } catch {\n try {\n const text = await response.text();\n\n return { error: text };\n } catch {\n return undefined;\n }\n }\n};\n\nexport interface StrapiContextHeaders {\n strapiVersion?: string | null;\n projectId?: string | null;\n userId?: string | null;\n}\n\nconst buildHeaders = (\n token: string,\n ctx?: StrapiContextHeaders,\n extra?: HeadersInit\n): Record<string, string> => {\n return {\n Authorization: `Bearer ${token}`,\n 'X-Strapi-Version': ctx?.strapiVersion || 'latest',\n 'X-Strapi-User': ctx?.userId || 'unknown',\n 'X-Strapi-Project-Id': ctx?.projectId || 'unknown',\n ...(extra as Record<string, string>),\n };\n};\n\nconst shouldRetryForToken = (status: number, body: any): boolean => {\n if (status === 401 || status === 403) {\n return true;\n }\n\n const msg = (body?.error || '').toString().toLowerCase();\n return msg.includes('expired') || msg.includes('invalid token');\n};\n\nexport interface FetchAIOptions extends RequestInit {\n ctx?: StrapiContextHeaders;\n}\n\n/**\n * Generic fetch wrapper for AI endpoints with token injection and single retry on invalidation\n */\nexport const fetchAI = async (\n input: RequestInfo | URL,\n options: FetchAIOptions = {}\n): Promise<Response> => {\n // Get token\n const tokenData = await getAIJwt();\n\n if (!tokenData?.token) {\n const error = new Error(\n 'Could not authorize with AI Server. Please contact your administrator.'\n );\n\n throw error;\n }\n\n const make = async (token: string): Promise<Response> => {\n const headers = buildHeaders(token, options.ctx, options.headers);\n return fetch(input, {\n ...options,\n headers,\n });\n };\n\n let response = await make(tokenData.token);\n\n let body: unknown | undefined = undefined;\n try {\n body = await safeParseJson(response.clone());\n } catch {\n // no-op\n }\n\n if (shouldRetryForToken(response.status, body)) {\n clearAIJwt();\n\n const refreshed = await getAIJwt();\n\n if (refreshed?.token && refreshed.token !== tokenData.token) {\n response = await make(refreshed.token);\n }\n }\n\n return response;\n};\n\n/**\n * Factory to provide a fetch implementation compatible with AI SDK useChat\n * that injects AI JWT + Strapi context headers and retries on token invalidation once.\n */\nexport const makeChatFetch = (ctx: StrapiContextHeaders) => {\n return async (input: RequestInfo | URL, options: RequestInit = {}): Promise<Response> => {\n return fetchAI(input, { ...options, ctx });\n };\n};\n"],"names":["aiTokenCache","SESSION_STORAGE_KEY","EXPIRY_BUFFER_MS","parseExpiryMs","expiresAt","ms","Date","parse","Number","isFinite","getTokenState","bufferMs","now","expMs","isTokenUsable","clearAIJwt","sessionStorage","removeItem","readFromSession","raw","getItem","parsed","JSON","writeToSession","data","setItem","stringify","getAIJwt","fromSession","get","getFetchClient","token","prefetchAIToken","existing","safeParseJson","response","json","text","error","undefined","buildHeaders","ctx","extra","Authorization","strapiVersion","userId","projectId","shouldRetryForToken","status","body","msg","toString","toLowerCase","includes","fetchAI","input","options","tokenData","Error","make","headers","fetch","clone","refreshed","makeChatFetch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"aiClient.mjs","sources":["../../../../../admin/src/components/AIChat/lib/aiClient.ts"],"sourcesContent":["import { getFetchClient } from '@strapi/admin/strapi-admin';\n\n/**\n * Centralized AI client utilities:\n * - Token retrieval via admin endpoint using getFetchClient\n * - In-memory + sessionStorage caching with near-expiry buffer\n * - Safe JSON parsing for error handling\n * - Single-retry policy on token invalidation\n */\n\nexport interface AITokenData {\n token: string;\n expiresAt: string;\n}\n\ntype AITokenResponse = Partial<AITokenData> & {\n data?: Partial<AITokenData>;\n};\n\nlet aiTokenCache: AITokenData | null = null;\nconst SESSION_STORAGE_KEY = 'strapi-ai-token';\nconst EXPIRY_BUFFER_MS = 60 * 1000;\n\nconst parseExpiryMs = (expiresAt: string): number | null => {\n const ms = Date.parse(expiresAt);\n return Number.isFinite(ms) ? ms : null;\n};\n\ntype TokenState = 'valid' | 'stale' | 'expired';\n\nconst getTokenState = (\n expiresAt: string,\n bufferMs = EXPIRY_BUFFER_MS,\n now = Date.now()\n): TokenState => {\n const expMs = parseExpiryMs(expiresAt);\n if (expMs === null) {\n return 'expired';\n }\n if (expMs <= now) {\n return 'expired';\n }\n if (expMs - bufferMs <= now) {\n return 'stale';\n }\n\n return 'valid';\n};\n\nconst isTokenUsable = (expiresAt: string, bufferMs = EXPIRY_BUFFER_MS, now = Date.now()): boolean =>\n getTokenState(expiresAt, bufferMs, now) === 'valid';\n\nexport const clearAIJwt = () => {\n aiTokenCache = null;\n sessionStorage.removeItem(SESSION_STORAGE_KEY);\n};\n\nconst readFromSession = (): AITokenData | null => {\n try {\n const raw = sessionStorage.getItem(SESSION_STORAGE_KEY);\n if (!raw) {\n return null;\n }\n\n const parsed = JSON.parse(raw) as AITokenData;\n return parsed;\n } catch {\n return null;\n }\n};\n\nconst writeToSession = (data: AITokenData) => {\n sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(data));\n};\n\nexport const getAIJwt = async (): Promise<AITokenData | null> => {\n // Check memory cache\n if (aiTokenCache && isTokenUsable(aiTokenCache.expiresAt)) {\n return aiTokenCache;\n }\n\n // Check session storage\n const fromSession = readFromSession();\n if (fromSession && isTokenUsable(fromSession.expiresAt)) {\n aiTokenCache = fromSession;\n\n return aiTokenCache;\n }\n\n // Fetch from admin endpoint\n try {\n const { get } = getFetchClient();\n const { data } = await get<AITokenResponse>('/admin/ai-token');\n\n const token = data?.token || data?.data?.token;\n const expiresAt = data?.expiresAt || data?.data?.expiresAt;\n\n if (typeof token === 'string' && typeof expiresAt === 'string') {\n aiTokenCache = { token, expiresAt };\n writeToSession(aiTokenCache);\n\n return aiTokenCache;\n }\n return null;\n } catch {\n return null;\n }\n};\n\nexport const prefetchAIToken = async (): Promise<void> => {\n try {\n // If we already have a valid token (not expiring soon), do nothing\n const existing = await getAIJwt();\n if (existing) {\n return;\n }\n\n // Attempt a fetch to populate cache\n await getAIJwt();\n } catch {\n // no-op\n }\n};\n\nexport const safeParseJson = async (response: Response): Promise<unknown> => {\n try {\n return await response.json();\n } catch {\n try {\n const text = await response.text();\n\n return { error: text };\n } catch {\n return undefined;\n }\n }\n};\n\nexport interface StrapiContextHeaders {\n strapiVersion?: string | null;\n projectId?: string | null;\n userId?: string | null;\n}\n\nconst buildHeaders = (\n token: string,\n ctx?: StrapiContextHeaders,\n extra?: HeadersInit\n): Record<string, string> => {\n return {\n Authorization: `Bearer ${token}`,\n 'X-Strapi-Version': ctx?.strapiVersion || 'latest',\n 'X-Strapi-User': ctx?.userId || 'unknown',\n 'X-Strapi-Project-Id': ctx?.projectId || 'unknown',\n ...(extra as Record<string, string>),\n };\n};\n\ntype ErrorResponseBody = {\n error?: unknown;\n};\n\nconst getErrorMessage = (body: unknown): string => {\n if (typeof body !== 'object' || body === null || !('error' in body)) {\n return '';\n }\n\n return String((body as ErrorResponseBody).error ?? '').toLowerCase();\n};\n\nconst shouldRetryForToken = (status: number, body: unknown): boolean => {\n if (status === 401 || status === 403) {\n return true;\n }\n\n const msg = getErrorMessage(body);\n return msg.includes('expired') || msg.includes('invalid token');\n};\n\nexport interface FetchAIOptions extends RequestInit {\n ctx?: StrapiContextHeaders;\n}\n\n/**\n * Generic fetch wrapper for AI endpoints with token injection and single retry on invalidation\n */\nexport const fetchAI = async (\n input: RequestInfo | URL,\n options: FetchAIOptions = {}\n): Promise<Response> => {\n // Get token\n const tokenData = await getAIJwt();\n\n if (!tokenData?.token) {\n const error = new Error(\n 'Could not authorize with AI Server. Please contact your administrator.'\n );\n\n throw error;\n }\n\n const make = async (token: string): Promise<Response> => {\n const headers = buildHeaders(token, options.ctx, options.headers);\n return fetch(input, {\n ...options,\n headers,\n });\n };\n\n let response = await make(tokenData.token);\n\n let body: unknown | undefined = undefined;\n try {\n body = await safeParseJson(response.clone());\n } catch {\n // no-op\n }\n\n if (shouldRetryForToken(response.status, body)) {\n clearAIJwt();\n\n const refreshed = await getAIJwt();\n\n if (refreshed?.token && refreshed.token !== tokenData.token) {\n response = await make(refreshed.token);\n }\n }\n\n return response;\n};\n\n/**\n * Factory to provide a fetch implementation compatible with AI SDK useChat\n * that injects AI JWT + Strapi context headers and retries on token invalidation once.\n */\nexport const makeChatFetch = (ctx: StrapiContextHeaders) => {\n return async (input: RequestInfo | URL, options: RequestInit = {}): Promise<Response> => {\n return fetchAI(input, { ...options, ctx });\n };\n};\n"],"names":["aiTokenCache","SESSION_STORAGE_KEY","EXPIRY_BUFFER_MS","parseExpiryMs","expiresAt","ms","Date","parse","Number","isFinite","getTokenState","bufferMs","now","expMs","isTokenUsable","clearAIJwt","sessionStorage","removeItem","readFromSession","raw","getItem","parsed","JSON","writeToSession","data","setItem","stringify","getAIJwt","fromSession","get","getFetchClient","token","prefetchAIToken","existing","safeParseJson","response","json","text","error","undefined","buildHeaders","ctx","extra","Authorization","strapiVersion","userId","projectId","getErrorMessage","body","String","toLowerCase","shouldRetryForToken","status","msg","includes","fetchAI","input","options","tokenData","Error","make","headers","fetch","clone","refreshed","makeChatFetch"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
4
3
|
const transformAttributesFromCTBToChat = (attributes)=>{
|
|
5
4
|
return attributes.reduce((acc, attribute)=>{
|
|
6
5
|
const { name, ...rest } = attribute;
|
|
@@ -21,7 +20,6 @@ const transformCTBToChat = (schema)=>{
|
|
|
21
20
|
name: schema.info.displayName,
|
|
22
21
|
uid: schema.uid,
|
|
23
22
|
attributes: transformAttributesFromCTBToChat(schema.attributes),
|
|
24
|
-
// @ts-expect-error - injected from previous ai messages
|
|
25
23
|
sources: schema.sources
|
|
26
24
|
};
|
|
27
25
|
}
|
|
@@ -36,7 +34,6 @@ const transformCTBToChat = (schema)=>{
|
|
|
36
34
|
plugin: schema.plugin
|
|
37
35
|
} : {},
|
|
38
36
|
attributes: transformAttributesFromCTBToChat(schema.attributes),
|
|
39
|
-
// @ts-expect-error - injected from previous ai messages
|
|
40
37
|
sources: schema.sources,
|
|
41
38
|
options: {
|
|
42
39
|
draftAndPublish: schema.options?.draftAndPublish,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fromCTB.js","sources":["../../../../../../../admin/src/components/AIChat/lib/transforms/schemas/fromCTB.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"fromCTB.js","sources":["../../../../../../../admin/src/components/AIChat/lib/transforms/schemas/fromCTB.ts"],"sourcesContent":["import type { ContentType, Component, AnyAttribute } from '../../../../../types';\nimport type { Schema } from '../../types/schema';\n\ntype SchemaWithSources = (ContentType | Component) & { sources?: unknown };\n\nconst transformAttributesFromCTBToChat = (attributes: AnyAttribute[]) => {\n return attributes.reduce(\n (acc, attribute) => {\n const { name, ...rest } = attribute;\n\n return {\n ...acc,\n [name]: rest,\n };\n },\n {} as Record<string, Omit<AnyAttribute, 'name'>>\n );\n};\n\nexport const transformCTBToChat = (schema: SchemaWithSources): Schema => {\n if (schema.modelType === 'component') {\n return {\n category: schema.category,\n kind: 'component',\n action: 'create',\n modelType: 'component',\n description: schema.info.description,\n name: schema.info.displayName,\n\n uid: schema.uid,\n attributes: transformAttributesFromCTBToChat(schema.attributes),\n sources: schema.sources,\n } satisfies Schema;\n }\n\n return {\n kind: schema.kind,\n modelType: schema.modelType,\n description: schema.info.description,\n action: 'create',\n name: schema.info.pluralName,\n uid: schema.uid,\n ...(schema.plugin ? { plugin: schema.plugin } : {}),\n attributes: transformAttributesFromCTBToChat(schema.attributes),\n sources: schema.sources,\n options: {\n draftAndPublish: schema.options?.draftAndPublish,\n localized: false,\n },\n } satisfies Schema;\n};\n"],"names":["transformAttributesFromCTBToChat","attributes","reduce","acc","attribute","name","rest","transformCTBToChat","schema","modelType","category","kind","action","description","info","displayName","uid","sources","pluralName","plugin","options","draftAndPublish","localized"],"mappings":";;AAKA,MAAMA,mCAAmC,CAACC,UAAAA,GAAAA;AACxC,IAAA,OAAOA,UAAAA,CAAWC,MAAM,CACtB,CAACC,GAAAA,EAAKC,SAAAA,GAAAA;AACJ,QAAA,MAAM,EAAEC,IAAI,EAAE,GAAGC,MAAM,GAAGF,SAAAA;QAE1B,OAAO;AACL,YAAA,GAAGD,GAAG;AACN,YAAA,CAACE,OAAOC;AACV,SAAA;AACF,IAAA,CAAA,EACA,EAAC,CAAA;AAEL,CAAA;AAEO,MAAMC,qBAAqB,CAACC,MAAAA,GAAAA;IACjC,IAAIA,MAAAA,CAAOC,SAAS,KAAK,WAAA,EAAa;QACpC,OAAO;AACLC,YAAAA,QAAAA,EAAUF,OAAOE,QAAQ;YACzBC,IAAAA,EAAM,WAAA;YACNC,MAAAA,EAAQ,QAAA;YACRH,SAAAA,EAAW,WAAA;YACXI,WAAAA,EAAaL,MAAAA,CAAOM,IAAI,CAACD,WAAW;YACpCR,IAAAA,EAAMG,MAAAA,CAAOM,IAAI,CAACC,WAAW;AAE7BC,YAAAA,GAAAA,EAAKR,OAAOQ,GAAG;YACff,UAAAA,EAAYD,gCAAAA,CAAiCQ,OAAOP,UAAU,CAAA;AAC9DgB,YAAAA,OAAAA,EAAST,OAAOS;AAClB,SAAA;AACF,IAAA;IAEA,OAAO;AACLN,QAAAA,IAAAA,EAAMH,OAAOG,IAAI;AACjBF,QAAAA,SAAAA,EAAWD,OAAOC,SAAS;QAC3BI,WAAAA,EAAaL,MAAAA,CAAOM,IAAI,CAACD,WAAW;QACpCD,MAAAA,EAAQ,QAAA;QACRP,IAAAA,EAAMG,MAAAA,CAAOM,IAAI,CAACI,UAAU;AAC5BF,QAAAA,GAAAA,EAAKR,OAAOQ,GAAG;QACf,GAAIR,MAAAA,CAAOW,MAAM,GAAG;AAAEA,YAAAA,MAAAA,EAAQX,OAAOW;AAAO,SAAA,GAAI,EAAE;QAClDlB,UAAAA,EAAYD,gCAAAA,CAAiCQ,OAAOP,UAAU,CAAA;AAC9DgB,QAAAA,OAAAA,EAAST,OAAOS,OAAO;QACvBG,OAAAA,EAAS;YACPC,eAAAA,EAAiBb,MAAAA,CAAOY,OAAO,EAAEC,eAAAA;YACjCC,SAAAA,EAAW;AACb;AACF,KAAA;AACF;;;;"}
|