diff --git a/ui/package-lock.json b/ui/package-lock.json index dd332a443..a95618229 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -11,6 +11,7 @@ "@contentstack/json-rte-serializer": "^3.0.5", "@contentstack/venus-components": "^3.0.3", "@reduxjs/toolkit": "^2.8.2", + "@testing-library/jest-dom": "^6.0.0", "@types/react": "^18.3.21", "@types/react-dom": "^18.2.13", "@types/react-redux": "^7.1.33", @@ -39,6 +40,12 @@ "prettier": "^3.3.3" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "license": "MIT" + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -269,6 +276,18 @@ "react-dom": "^16.8.6 || ^17 || ^18 || ^19" } }, + "node_modules/@contentstack/venus-components/node_modules/@babel/runtime": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", + "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@contentstack/venus-components/node_modules/@emotion/cache": { "version": "10.0.9", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.9.tgz", @@ -608,6 +627,12 @@ "@babel/runtime": "^7.9.2" } }, + "node_modules/@contentstack/venus-components/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, "node_modules/@contentstack/venus-components/node_modules/scheduler": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", @@ -2360,6 +2385,25 @@ "@swc/counter": "^0.1.3" } }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/@tippyjs/react": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz", @@ -2632,6 +2676,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", @@ -3237,6 +3290,12 @@ "integrity": "sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==", "license": "BSD" }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "license": "MIT" + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -3573,6 +3632,12 @@ "node": ">=6.0.0" } }, + "node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "license": "MIT" + }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -4934,6 +4999,15 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5821,6 +5895,15 @@ "dom-walk": "^0.1.0" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6680,6 +6763,15 @@ "react-dom": ">=16.8.3" } }, + "node_modules/react-mentions/node_modules/@babel/runtime": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", + "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.2" + } + }, "node_modules/react-modal": { "version": "3.16.3", "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.3.tgz", @@ -7075,6 +7167,19 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/redux": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", @@ -7121,8 +7226,7 @@ "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "peer": true + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", @@ -7900,6 +8004,18 @@ "node": ">=8" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", diff --git a/ui/src/components/AdvancePropertise/index.tsx b/ui/src/components/AdvancePropertise/index.tsx index 71498242c..605020e6d 100644 --- a/ui/src/components/AdvancePropertise/index.tsx +++ b/ui/src/components/AdvancePropertise/index.tsx @@ -942,7 +942,7 @@ const AdvancePropertise = (props: SchemaProps) => { )} )} - {props?.fieldtype !== 'Global Field' && props?.fieldtype !== 'Boolean' && ( + {props?.fieldtype !== 'Global Field' && props?.fieldtype !== 'Boolean' && props?.fieldtype !== 'Taxonomy' && (
{}; currentStep: number; - handleStepChange: (stepIndex: number, closeStep: boolean) => void; + handleStepChange: ( stepIndex: number, closeStep: boolean ) => void; } -interface Props { +interface Props +{ fileDetails: FileDetails; fileFormatId?: string; // from selectedFileFormat.fileformat_id (driven by legacyCms.json) } -interface UploadState { +interface UploadState +{ cmsType: string; fileExtension: string; fileFormat?: string; @@ -46,100 +49,106 @@ interface UploadState { * - !isLocalPath → AWS S3 details * No CMS-specific branches — adding a new CMS to legacyCms.json works automatically. */ -const FileComponent = ({ fileDetails, fileFormatId }: Props) => { +const FileComponent = ( { fileDetails, fileFormatId }: Props ) => +{ const isSQL = fileFormatId?.toLowerCase() === 'sql'; return (
- {isSQL ? ( + { isSQL ? ( // ✅ SQL format (from legacyCms.json allowed_file_formats): show MySQL details fileDetails?.mySQLDetails && (
-

Host: {fileDetails?.mySQLDetails?.host}

-

Database: {fileDetails?.mySQLDetails?.database}

-

User: {fileDetails?.mySQLDetails?.user}

+

Host: { fileDetails?.mySQLDetails?.host }

+

Database: { fileDetails?.mySQLDetails?.database }

+

User: { fileDetails?.mySQLDetails?.user }

) ) : fileDetails?.isLocalPath ? ( // ✅ Local path (file or directory — format driven by legacyCms.json)
- +
) : ( // ✅ AWS S3 details (isLocalPath is false)
-

AWS Region: {fileDetails?.awsData?.awsRegion}

-

Bucket Name: {fileDetails?.awsData?.bucketName}

-

Bucket Key: {fileDetails?.awsData?.bucketKey}

+

AWS Region: { fileDetails?.awsData?.awsRegion }

+

Bucket Name: { fileDetails?.awsData?.bucketName }

+

Bucket Key: { fileDetails?.awsData?.bucketKey }

- )} + ) }
); }; -const saveStateToLocalStorage = (state: UploadState, projectId: string) => { - sessionStorage.setItem(`uploadProgressState_${projectId}`, JSON.stringify(state)); +const saveStateToLocalStorage = ( state: UploadState, projectId: string ) => +{ + sessionStorage.setItem( `uploadProgressState_${projectId}`, JSON.stringify( state ) ); }; -const getStateFromLocalStorage = (projectId: string) => { - const state = sessionStorage.getItem(`uploadProgressState_${projectId}`); - return state ? JSON.parse(state) : null; +const getStateFromLocalStorage = ( projectId: string ) => +{ + const state = sessionStorage.getItem( `uploadProgressState_${projectId}` ); + return state ? JSON.parse( state ) : null; }; -const LoadUploadFile = (props: LoadUploadFileProps) => { +const LoadUploadFile = ( props: LoadUploadFileProps ) => +{ /**** ALL HOOKS HERE ****/ - const newMigrationData = useSelector((state: RootState) => state?.migration?.newMigrationData); - const migrationData = useSelector((state: RootState) => state?.migration?.migrationData); + const newMigrationData = useSelector( ( state: RootState ) => state?.migration?.newMigrationData ); + const migrationData = useSelector( ( state: RootState ) => state?.migration?.migrationData ); const selectedOrganisation = useSelector( - (state: RootState) => state?.authentication?.selectedOrganisation + ( state: RootState ) => state?.authentication?.selectedOrganisation ); - const newMigrationDataRef = useRef(newMigrationData); + const newMigrationDataRef = useRef( newMigrationData ); const dispatch = useDispatch(); - const [isLoading, setIsLoading] = useState(false); - const [isValidated, setIsValidated] = useState(newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.isValidated); - const [showMessage, setShowMessage] = useState(newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.isValidated); - const [validationMessgae, setValidationMessage] = useState(''); - const [isValidationAttempted, setIsValidationAttempted] = useState(false); - const [isDisabled, setIsDisabled] = useState( + const [ isLoading, setIsLoading ] = useState( false ); + const [ isValidated, setIsValidated ] = useState( newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.isValidated ); + const [ showMessage, setShowMessage ] = useState( newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.isValidated ); + const [ validationMessgae, setValidationMessage ] = useState( '' ); + const [ isValidationAttempted, setIsValidationAttempted ] = useState( false ); + const [ isDisabled, setIsDisabled ] = useState( newMigrationData?.legacy_cms?.uploadedFile?.isValidated || - isEmptyString(newMigrationDataRef?.current?.legacy_cms?.affix) + isEmptyString( newMigrationDataRef?.current?.legacy_cms?.affix ) ); - const [isConfigLoading, setIsConfigLoading] = useState(false); - const [cmsType, setCmsType]= useState(''); + const [ isConfigLoading, setIsConfigLoading ] = useState( false ); + const [ cmsType, setCmsType ] = useState( '' ); // Use newMigrationData directly from Redux, not the ref, so it updates when Redux changes - const [fileDetails, setFileDetails] = useState(newMigrationData?.legacy_cms?.uploadedFile?.file_details); - const [fileExtension, setFileExtension] = useState(''); - const [progressPercentage, setProgressPercentage] = useState(0); - const [showProgress, setShowProgress] = useState(false); - const [fileFormat, setFileFormat] = useState( + const [ fileDetails, setFileDetails ] = useState( newMigrationData?.legacy_cms?.uploadedFile?.file_details ); + const [ fileExtension, setFileExtension ] = useState( '' ); + const [ progressPercentage, setProgressPercentage ] = useState( 0 ); + const [ showProgress, setShowProgress ] = useState( false ); + const [ fileFormat, setFileFormat ] = useState( newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id ); - const [processing, setProcessing] = useState(''); - const [affix, setAffix] = useState(newMigrationData?.legacy_cms?.affix); - const [reValidate, setReValidate] = useState(newMigrationData?.legacy_cms?.uploadedFile?.reValidate || false); + const [ processing, setProcessing ] = useState( '' ); + const [ affix, setAffix ] = useState( newMigrationData?.legacy_cms?.affix ); + const [ reValidate, setReValidate ] = useState( newMigrationData?.legacy_cms?.uploadedFile?.reValidate || false ); const { projectId = '' } = useParams(); //Handle further action on file is uploaded to server - const handleOnFileUploadCompletion = async () => { - try { - setIsValidationAttempted(false); - setValidationMessage(''); - setIsLoading(true); - setProgressPercentage(30); - setShowProgress(true); - setProcessing('Processing...30%'); + const handleOnFileUploadCompletion = async () => + { + try + { + setIsValidationAttempted( false ); + setValidationMessage( '' ); + setIsLoading( true ); + setProgressPercentage( 30 ); + setShowProgress( true ); + setProcessing( 'Processing...30%' ); - await new Promise((resolve) => setTimeout(resolve, 1000)); + await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) ); - const { data, status } = await fileValidation(projectId, newMigrationData?.legacy_cms?.affix); - - setProgressPercentage(70); - setProcessing('Processing...70%'); + const { data, status } = await fileValidation( projectId, newMigrationData?.legacy_cms?.affix ); - await new Promise((resolve) => setTimeout(resolve, 1000)); + setProgressPercentage( 70 ); + setProcessing( 'Processing...70%' ); + + await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) ); // Preserve existing file_details from Redux when validation fails, // since the API response may not include file_details on error. @@ -153,8 +162,8 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { ...newMigrationDataRef?.current?.legacy_cms, uploadedFile: { ...newMigrationDataRef?.current?.legacy_cms?.uploadedFile, - name: isSuccess ? (responseFileDetails?.localPath || '') : (newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.name || ''), - url: isSuccess ? responseFileDetails?.localPath : (newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.url || ''), + name: isSuccess ? ( responseFileDetails?.localPath || '' ) : ( newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.name || '' ), + url: isSuccess ? responseFileDetails?.localPath : ( newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.url || '' ), validation: data?.message, isValidated: isSuccess, reValidate: false, @@ -181,7 +190,7 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { // On failure, preserve existing file_details so UI doesn't lose filled data ...existingFileDetails }, - cmsType: isSuccess ? data?.cmsType : (newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.cmsType || '') + cmsType: isSuccess ? data?.cmsType : ( newMigrationDataRef?.current?.legacy_cms?.uploadedFile?.cmsType || '' ) } } }; @@ -189,35 +198,40 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { // Ensure selectedFileFormat is preserved in the migration data update. // selectedFileFormat is already set by LoadSelectCms from legacyCms.json's allowed_file_formats. // If not yet set (edge case), fall back to the current Redux state. - if (status === 200 && !newMigrationDataObj.legacy_cms.selectedFileFormat) { + if ( status === 200 && !newMigrationDataObj.legacy_cms.selectedFileFormat ) + { newMigrationDataObj.legacy_cms.selectedFileFormat = newMigrationDataRef?.current?.legacy_cms?.selectedFileFormat; } // Update the ref immediately before dispatching to avoid stale data in subsequent operations newMigrationDataRef.current = newMigrationDataObj; - dispatch(updateNewMigrationData(newMigrationDataObj)); + dispatch( updateNewMigrationData( newMigrationDataObj ) ); // Derive SQL check from selectedFileFormat (data-driven via legacyCms.json) const currentFormatId = newMigrationDataObj?.legacy_cms?.selectedFileFormat?.fileformat_id?.toLowerCase(); const isSQL = currentFormatId === 'sql'; - if (status === 200) { - setIsValidated(true); + if ( status === 200 ) + { + setIsValidated( true ); setValidationMessage( - isSQL - ? 'Connection established successfully.' + isSQL + ? 'Connection established successfully.' : 'File validated successfully.' ); // 🔧 FIX: Fetch updated project data to get source_locales and dispatch to Redux // This ensures the Language Mapper has access to source locales immediately after validation - try { - if (selectedOrganisation?.value && projectId) { - const migrationDataResponse = await getMigrationData(selectedOrganisation?.value, projectId); + try + { + if ( selectedOrganisation?.value && projectId ) + { + const migrationDataResponse = await getMigrationData( selectedOrganisation?.value, projectId ); const projectData = migrationDataResponse?.data; - - if (projectData?.source_locales && Array.isArray(projectData.source_locales)) { + + if ( projectData?.source_locales && Array.isArray( projectData.source_locales ) ) + { // Dispatch source_locales to Redux so LanguageMapper can access them // Use newMigrationDataObj (the just-dispatched data) instead of stale ref const updatedMigrationData: INewMigration = { @@ -229,60 +243,66 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { }; // Update ref again before second dispatch newMigrationDataRef.current = updatedMigrationData; - dispatch(updateNewMigrationData(updatedMigrationData)); + dispatch( updateNewMigrationData( updatedMigrationData ) ); } } - } catch (fetchError) { - console.warn('⚠️ [LoadUploadFile] Could not fetch source_locales:', fetchError); + } catch ( fetchError ) + { + console.warn( '⚠️ [LoadUploadFile] Could not fetch source_locales:', fetchError ); // Don't block the flow if this fails } - setIsDisabled(true); + setIsDisabled( true ); if ( - !isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.cms_id) && - !isEmptyString(newMigrationDataObj?.legacy_cms?.selectedFileFormat?.fileformat_id) - ) { - props.handleStepChange(props?.currentStep, true); + !isEmptyString( newMigrationData?.legacy_cms?.selectedCms?.cms_id ) && + !isEmptyString( newMigrationDataObj?.legacy_cms?.selectedFileFormat?.fileformat_id ) + ) + { + props.handleStepChange( props?.currentStep, true ); } - } else if (status === 500) { - setIsValidated(false); + } else if ( status === 500 ) + { + setIsValidated( false ); setValidationMessage( - isSQL - ? 'Connection failed' + isSQL + ? 'Connection failed' : 'File not found' ); - setIsValidationAttempted(true); - setProgressPercentage(100); - } else if (status === 429) { - setIsValidated(false); - setValidationMessage('Rate limit exceeded. Please wait and try again.'); - setIsValidationAttempted(true); - setProgressPercentage(100); - } else { - setIsValidated(false); + setIsValidationAttempted( true ); + setProgressPercentage( 100 ); + } else if ( status === 429 ) + { + setIsValidated( false ); + setValidationMessage( 'Rate limit exceeded. Please wait and try again.' ); + setIsValidationAttempted( true ); + setProgressPercentage( 100 ); + } else + { + setIsValidated( false ); // For SQL connections, show the specific backend error message // For other formats, show generic validation failed message setValidationMessage( - isSQL && data?.message - ? data.message + isSQL && data?.message + ? data.message : 'Validation failed.' ); - setIsValidationAttempted(true); - setProgressPercentage(100); + setIsValidationAttempted( true ); + setProgressPercentage( 100 ); } - setProgressPercentage(100); - setProcessing('Processing...100%'); + setProgressPercentage( 100 ); + setProcessing( 'Processing...100%' ); - await new Promise((resolve) => setTimeout(resolve, 1000)); + await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) ); - setTimeout(() => { - setShowProgress(false); - setShowMessage(true); - }, 1000); + setTimeout( () => + { + setShowProgress( false ); + setShowMessage( true ); + }, 1000 ); - setIsLoading(false); + setIsLoading( false ); saveStateToLocalStorage( { @@ -301,81 +321,92 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { }, projectId ); - } catch (error) { + } catch ( error ) + { return error; } }; - const getFileExtension = (filePath: string): string => { - const fileName = filePath?.split('/')?.pop(); - const ext = fileName?.split('.')?.pop(); + const getFileExtension = ( filePath: string ): string => + { + const fileName = filePath?.split( '/' )?.pop(); + const ext = fileName?.split( '.' )?.pop(); const validExtensionRegex = /\.(pdf|zip|xml|json)$/i; - return ext && validExtensionRegex?.test(`.${ext}`) ? `${ext}` : 'zip'; + return ext && validExtensionRegex?.test( `.${ext}` ) ? `${ext}` : 'zip'; }; //function to get config details - const getConfigDetails = async () => { - try { + const getConfigDetails = async () => + { + try + { //setIsConfigLoading(true); - - if (!isEmptyString(fileDetails?.localPath) && newMigrationData?.legacy_cms?.uploadedFile?.file_details?.localPath !== fileDetails?.localPath && !isEmptyString(newMigrationDataRef?.current?.legacy_cms?.affix)) { - setIsDisabled(false); - setShowMessage(true); - setValidationMessage(''); - - } - + + if ( !isEmptyString( fileDetails?.localPath ) && newMigrationData?.legacy_cms?.uploadedFile?.file_details?.localPath !== fileDetails?.localPath && !isEmptyString( newMigrationDataRef?.current?.legacy_cms?.affix ) ) + { + setIsDisabled( false ); + setShowMessage( true ); + setValidationMessage( '' ); + + } + // Derive SQL check from selectedFileFormat (data-driven via legacyCms.json) const isSQL = newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id?.toLowerCase() === 'sql'; - + let extension = ''; let isFormatValid = false; - - if (isSQL) { + + if ( isSQL ) + { // For SQL connections, check if SQL format is allowed for the CMS extension = 'sql'; - const { all_cms = [] } = migrationData?.legacyCMSData || {}; + const { all_cms = [] } = migrationData?.legacyCMSData || {}; // Fix: Use file_details.cmsType instead of uploadedFile.cmsType - const cmsTypeValue = newMigrationData?.legacy_cms?.uploadedFile?.file_details?.cmsType || - newMigrationData?.legacy_cms?.uploadedFile?.cmsType || ''; - const filteredCmsData = all_cms?.filter((cms: ICMSType) => + const cmsTypeValue = newMigrationData?.legacy_cms?.uploadedFile?.file_details?.cmsType || + newMigrationData?.legacy_cms?.uploadedFile?.cmsType || ''; + const filteredCmsData = all_cms?.filter( ( cms: ICMSType ) => cms?.parent?.toLowerCase() === cmsTypeValue?.toLowerCase() ); - - isFormatValid = filteredCmsData[0]?.allowed_file_formats?.some((format: ICardType) => { + + isFormatValid = filteredCmsData[ 0 ]?.allowed_file_formats?.some( ( format: ICardType ) => + { return format?.fileformat_id?.toLowerCase() === 'sql'; - }) || false; - } else { + } ) || false; + } else + { // For file uploads, validate file extension - extension = getFileExtension(newMigrationData?.legacy_cms?.uploadedFile?.file_details?.localPath || ''); - const { all_cms = [] } = migrationData?.legacyCMSData || {}; - let filteredCmsData:ICMSType[] = all_cms; + extension = getFileExtension( newMigrationData?.legacy_cms?.uploadedFile?.file_details?.localPath || '' ); + const { all_cms = [] } = migrationData?.legacyCMSData || {}; + let filteredCmsData: ICMSType[] = all_cms; // Fix: Use file_details.cmsType instead of uploadedFile.cmsType - const cmsTypeValue = newMigrationData?.legacy_cms?.uploadedFile?.file_details?.cmsType || - newMigrationData?.legacy_cms?.uploadedFile?.cmsType || ''; - if (cmsTypeValue) { - filteredCmsData = all_cms?.filter((cms: ICMSType) => cms?.parent?.toLowerCase() === cmsTypeValue?.toLowerCase()); + const cmsTypeValue = newMigrationData?.legacy_cms?.uploadedFile?.file_details?.cmsType || + newMigrationData?.legacy_cms?.uploadedFile?.cmsType || ''; + if ( cmsTypeValue ) + { + filteredCmsData = all_cms?.filter( ( cms: ICMSType ) => cms?.parent?.toLowerCase() === cmsTypeValue?.toLowerCase() ); } - - isFormatValid = filteredCmsData[0]?.allowed_file_formats?.some((format: ICardType) => { + + isFormatValid = filteredCmsData[ 0 ]?.allowed_file_formats?.some( ( format: ICardType ) => + { const isValid = format?.fileformat_id?.toLowerCase() === extension; return isValid; - }) || false; + } ) || false; } - + // Fix: Use file_details.cmsType as primary source - setCmsType(newMigrationData?.legacy_cms?.uploadedFile?.file_details?.cmsType || - newMigrationData?.legacy_cms?.uploadedFile?.cmsType || ''); - setFileExtension(extension); + setCmsType( newMigrationData?.legacy_cms?.uploadedFile?.file_details?.cmsType || + newMigrationData?.legacy_cms?.uploadedFile?.cmsType || '' ); + setFileExtension( extension ); + - //setIsFormatValid(isFormatValid); - setIsDisabled(!isFormatValid || isEmptyString(newMigrationDataRef?.current?.legacy_cms?.affix)); - if(!isFormatValid){ - console.warn('⚠️ LoadUploadFile: File format is not valid, setting isValidated to false'); - setValidationMessage('⚠️ File format is not valid'); - setIsValidated(false); - dispatch(updateNewMigrationData({ + setIsDisabled( !isFormatValid || isEmptyString( newMigrationDataRef?.current?.legacy_cms?.affix ) ); + if ( !isFormatValid ) + { + console.warn( '⚠️ LoadUploadFile: File format is not valid, setting isValidated to false' ); + setValidationMessage( '⚠️ File format is not valid' ); + setIsValidated( false ); + dispatch( updateNewMigrationData( { ...newMigrationData, legacy_cms: { ...newMigrationData?.legacy_cms, @@ -384,71 +415,78 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { isValidated: false, } } - })) + } ) ) } - //} - // if((! isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.parent?.toLowerCase()) && - // newMigrationData?.legacy_cms?.selectedCms?.parent.toLowerCase() !== data?.cmsType.toLowerCase())) - // { - // setIsValidated(false); - // setValidationMessage('file format is not appropriate'); - // setIsValidationAttempted(true); - // setShowMessage(true); - // setIsLoading(false); - // setIsDisabled(true); - // } - setIsConfigLoading(false); - - } catch (error) { + //} + // if((! isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.parent?.toLowerCase()) && + // newMigrationData?.legacy_cms?.selectedCms?.parent.toLowerCase() !== data?.cmsType.toLowerCase())) + // { + // setIsValidated(false); + // setValidationMessage('file format is not appropriate'); + // setIsValidationAttempted(true); + // setShowMessage(true); + // setIsLoading(false); + // setIsDisabled(true); + // } + setIsConfigLoading( false ); + + } catch ( error ) + { return error; } }; // Update fileDetails whenever Redux state changes - useEffect(() => { + useEffect( () => + { const latestFileDetails = newMigrationData?.legacy_cms?.uploadedFile?.file_details; - + // Always update fileDetails from Redux, even if it's empty (to clear stale data) - setFileDetails(latestFileDetails); - - }, [newMigrationData?.legacy_cms?.uploadedFile?.file_details]); + setFileDetails( latestFileDetails ); + + }, [ newMigrationData?.legacy_cms?.uploadedFile?.file_details ] ); - useEffect(() => { - getConfigDetails(); + useEffect( () => + { + getConfigDetails(); }, [ // Re-run when selectedFileFormat or file_details change (e.g., after LoadSelectCms or fetchProjectData dispatches) newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id, newMigrationData?.legacy_cms?.uploadedFile?.file_details?.localPath - ]); - - useEffect(() => { - const savedState = getStateFromLocalStorage(projectId); - - if (savedState) { - setIsLoading(savedState.isLoading); - setIsConfigLoading(savedState.isConfigLoading); + ] ); + + useEffect( () => + { + const savedState = getStateFromLocalStorage( projectId ); + + if ( savedState ) + { + setIsLoading( savedState.isLoading ); + setIsConfigLoading( savedState.isConfigLoading ); //setIsValidated(savedState?.isValidated); - setValidationMessage(savedState?.validationMessage); + setValidationMessage( savedState?.validationMessage ); //setIsDisabled(savedState?.isDisabled); - setCmsType(savedState?.cmsType); + setCmsType( savedState?.cmsType ); //setFileDetails(savedState.fileDetails); - setFileExtension(savedState?.fileExtension); - setProgressPercentage(savedState?.progressPercentage); - setShowProgress(savedState?.showProgress); - setFileFormat(savedState?.fileFormat); - setProcessing(savedState?.processing); + setFileExtension( savedState?.fileExtension ); + setProgressPercentage( savedState?.progressPercentage ); + setShowProgress( savedState?.showProgress ); + setFileFormat( savedState?.fileFormat ); + setProcessing( savedState?.processing ); } if ( savedState && savedState?.isLoading && !newMigrationData?.legacy_cms?.uploadedFile?.isValidated - ) { + ) + { handleOnFileUploadCompletion(); } - }, []); + }, [] ); - useEffect(() => { + useEffect( () => + { saveStateToLocalStorage( { isLoading, @@ -479,115 +517,134 @@ const LoadUploadFile = (props: LoadUploadFileProps) => { showProgress, fileFormat, processing - ]); + ] ); - useEffect(() => { + useEffect( () => + { if ( newMigrationData?.legacy_cms?.uploadedFile?.isValidated && !showProgress && !newMigrationData?.legacy_cms?.uploadedFile?.reValidate - ) { - setIsValidated(true); - setShowMessage(true); + ) + { + setIsValidated( true ); + setShowMessage( true ); // Use selectedFileFormat.fileformat_id (data-driven via legacyCms.json) for SQL check setValidationMessage( newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id?.toLowerCase() === 'sql' - ? 'Connection established successfully.' + ? 'Connection established successfully.' : 'File validated successfully.' ); - setIsDisabled(true); + setIsDisabled( true ); if ( - !isEmptyString(newMigrationData?.legacy_cms?.selectedCms?.cms_id) || - !isEmptyString(newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id) - ) { - props.handleStepChange(props?.currentStep, true); + !isEmptyString( newMigrationData?.legacy_cms?.selectedCms?.cms_id ) || + !isEmptyString( newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id ) + ) + { + props.handleStepChange( props?.currentStep, true ); } } - if (newMigrationData?.legacy_cms?.uploadedFile?.reValidate) { - setValidationMessage(''); + if ( newMigrationData?.legacy_cms?.uploadedFile?.reValidate ) + { + setValidationMessage( '' ); } - if(!newMigrationData?.legacy_cms?.uploadedFile?.isValidated && !newMigrationData?.legacy_cms?.uploadedFile?.reValidate){ - setIsDisabled(false); + if ( !newMigrationData?.legacy_cms?.uploadedFile?.isValidated && !newMigrationData?.legacy_cms?.uploadedFile?.reValidate ) + { + setIsDisabled( false ); } - setReValidate(newMigrationData?.legacy_cms?.uploadedFile?.reValidate || false); - }, [isValidated, newMigrationData]); + setReValidate( newMigrationData?.legacy_cms?.uploadedFile?.reValidate || false ); + }, [ isValidated, newMigrationData ] ); - useEffect(() => { - if (newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id) { - setFileFormat(newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id); + useEffect( () => + { + if ( newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id ) + { + setFileFormat( newMigrationData?.legacy_cms?.selectedFileFormat?.fileformat_id ); } - }, [newMigrationData?.legacy_cms?.selectedFileFormat]); + }, [ newMigrationData?.legacy_cms?.selectedFileFormat ] ); - useEffect(() => { + useEffect( () => + { newMigrationDataRef.current = newMigrationData; - setAffix(newMigrationData?.legacy_cms?.affix); - }, [newMigrationData]); + setAffix( newMigrationData?.legacy_cms?.affix ); + }, [ newMigrationData ] ); + + const sanitizedCmsType = cmsType?.toLowerCase().replace( /[^\w\s-]/g, '' ); - const sanitizedCmsType = cmsType?.toLowerCase().replace(/[^\w\s-]/g, ''); + const documentationUrl = VALIDATION_DOCUMENTATION_URL?.[ sanitizedCmsType ]; - const documentationUrl = VALIDATION_DOCUMENTATION_URL?.[sanitizedCmsType]; - const validationClassName = isValidated ? 'success' : 'error'; - const containerClassName = `validation-container ${ - isValidationAttempted && !isValidated ? 'error-container pb-2' : '' - }`; + const containerClassName = `validation-container ${isValidationAttempted && !isValidated ? 'error-container pb-2' : '' + }`; return (
-
- {!isConfigLoading && (!isEmptyString(fileDetails?.localPath) || !isEmptyString(fileFormat)) ? ( +
+ { !isConfigLoading && ( !isEmptyString( fileDetails?.localPath ) || !isEmptyString( fileFormat ) ) ? ( //
- + ) : (
No file added. Please add the file to validate.
- )} - {showMessage && !showProgress && ( + ) } + { showMessage && !showProgress && (
- - {!isValidated && validationMessgae === 'Validation failed.' && fileFormat?.toLowerCase() !== 'sql' && ( -

- Please check the requirements{' '} - + { !isValidated && isValidationAttempted && fileFormat?.toLowerCase() === 'sql' && documentationUrl ? ( +

+ { validationMessgae }{ ' ' } + Please check the requirements{ ' ' } + here

- )} + ) : ( + <> + + { !isValidated && validationMessgae === 'Validation failed.' && fileFormat?.toLowerCase() !== 'sql' && ( +

+ Please check the requirements{ ' ' } + + here + +

+ ) } + + ) }
- )} - {showProgress && isLoading && ( + ) } + { showProgress && isLoading && ( - )} + ) }
- {showProgress && ( + { showProgress && (
- +
- )} + ) }
diff --git a/ui/src/utilities/constants.ts b/ui/src/utilities/constants.ts index b3ec34fc3..403f7a508 100644 --- a/ui/src/utilities/constants.ts +++ b/ui/src/utilities/constants.ts @@ -121,7 +121,7 @@ export const VALIDATION_DOCUMENTATION_URL: { [key: string]: string } = { contentful: 'https://assets.contentstack.io/v3/assets/bltc09cefc19ddf033f/bltb14c2df7c5e202ba/67ee3fcdb509b76f5f308ac4/contentful.pdf', wordpress: '', - drupal: '', + drupal: 'https://assets.contentstack.io/v3/assets/bltc09cefc19ddf033f/blt1baa953e3e9496ea/6996abbaab60c900082f2477/Drupal.pdf', aem: 'https://assets.contentstack.io/v3/assets/bltc09cefc19ddf033f/blt3df735914488e75d/AEM%20Data%20Requirements.pdf' }; diff --git a/upload-api/package-lock.json b/upload-api/package-lock.json index d3050ef3d..b92c93ee4 100644 --- a/upload-api/package-lock.json +++ b/upload-api/package-lock.json @@ -19,7 +19,6 @@ "cheerio": "^1.2.0", "cors": "^2.8.5", "dotenv": "^16.3.1", - "eslint": "^10.0.0", "express": "^5.2.1", "express-rate-limit": "^7.2.0", "fs-readdir-recursive": "^1.1.0", @@ -55,6 +54,7 @@ "@types/wordpress__blocks": "^12.5.18", "@types/xml2js": "^0.4.14", "@typescript-eslint/eslint-plugin": "^8.0.0", + "eslint": "^9.0.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "nodemon": "^3.1.10", @@ -2022,94 +2022,173 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.1.tgz", - "integrity": "sha512-uVSdg/V4dfQmTjJzR0szNczjOH/J+FyUMMjYtr07xFRXR7EDf9i1qdxrD0VusZH9knj1/ecxzCQQxyic5NzAiA==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^3.0.1", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^10.1.1" + "minimatch": "^3.1.2" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/config-array/node_modules/balanced-match": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", - "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", "dependencies": { - "jackspeak": "^4.2.3" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" }, "engines": { - "node": "20 || >=22" + "node": "*" } }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", - "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "license": "Apache-2.0", "dependencies": { - "balanced-match": "^4.0.2" + "@eslint/core": "^0.17.0" }, "engines": { - "node": "20 || >=22" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", - "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "license": "Apache-2.0", "dependencies": { - "brace-expansion": "^5.0.2" + "@types/json-schema": "^7.0.15" }, "engines": { - "node": "20 || >=22" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.2.tgz", - "integrity": "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", "dependencies": { - "@eslint/core": "^1.1.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">= 4" } }, - "node_modules/@eslint/core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz", - "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==", + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", "dependencies": { - "@types/json-schema": "^7.0.15" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.1.tgz", - "integrity": "sha512-P9cq2dpr+LU8j3qbLygLcSZrl2/ds/pUpfnHNNuk5HW7mnngHs+6WSq5C9mO3rqRX8A1poxqLTC9cu0KOyJlBg==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "license": "Apache-2.0", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.0.tgz", - "integrity": "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^1.1.0", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@floating-ui/core": { @@ -2209,6 +2288,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, "engines": { "node": ">=18" } @@ -3570,13 +3650,10 @@ "@types/node": "*" } }, - "node_modules/@types/esrecurse": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", - "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==" - }, "node_modules/@types/estree": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, "node_modules/@types/express": { @@ -3639,7 +3716,8 @@ "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" }, "node_modules/@types/lodash": { "version": "4.17.20", @@ -3683,7 +3761,7 @@ }, "node_modules/@types/node": { "version": "20.19.19", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -7966,6 +8044,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -8837,8 +8916,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/concat-stream": { "version": "2.0.0", @@ -9712,28 +9790,32 @@ } }, "node_modules/eslint": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.0.tgz", - "integrity": "sha512-O0piBKY36YSJhlFSG8p9VUdPV/SxxS4FYDWVpr/9GJuMaepzwlf4J8I4ov1b+ySQfDTPhc3DtLaxcT1fN0yqCg==", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.2", - "@eslint/config-array": "^0.23.0", - "@eslint/config-helpers": "^0.5.2", - "@eslint/core": "^1.1.0", - "@eslint/plugin-kit": "^0.6.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", + "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^9.1.0", - "eslint-visitor-keys": "^5.0.0", - "espree": "^11.1.0", - "esquery": "^1.7.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", @@ -9743,7 +9825,8 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.1.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -9751,7 +9834,7 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://eslint.org/donate" @@ -9806,17 +9889,16 @@ } }, "node_modules/eslint-scope": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.0.tgz", - "integrity": "sha512-CkWE42hOJsNj9FJRaoMX9waUFYhqY4jmyLFdAdzZr6VaCg3ynLYx4WnOdkaIifGfH4gsUcBTn4OZbHXkpLD0FQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "license": "BSD-2-Clause", "dependencies": { - "@types/esrecurse": "^4.3.1", - "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -9846,34 +9928,23 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/eslint/node_modules/balanced-match": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", - "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", - "dependencies": { - "jackspeak": "^4.2.3" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", - "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", - "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "license": "Apache-2.0", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -9891,41 +9962,41 @@ "license": "MIT" }, "node_modules/eslint/node_modules/minimatch": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", - "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/espree": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-11.1.0.tgz", - "integrity": "sha512-WFWYhO1fV4iYkqOOvq8FbqIhr2pYfoDY0kCotMkDeNtGpiGGkZ1iov2u8ydjtgM8yF8rzK7oaTbw2NAzbAbehw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^5.0.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", - "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "license": "Apache-2.0", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -9958,6 +10029,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -10540,6 +10612,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globalthis": { "version": "1.0.4", "license": "MIT", @@ -11883,6 +11967,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "dev": true, "dependencies": { "@isaacs/cliui": "^9.0.0" }, @@ -12155,6 +12240,12 @@ "version": "4.4.0", "license": "MIT" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "license": "MIT", @@ -14507,6 +14598,18 @@ "node": ">=8" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strnum": { "version": "2.1.2", "funding": [ @@ -14962,7 +15065,6 @@ }, "node_modules/typescript": { "version": "5.9.3", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -15003,7 +15105,7 @@ }, "node_modules/undici-types": { "version": "6.21.0", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/unique-string": { diff --git a/upload-api/package.json b/upload-api/package.json index 08e94b6ac..3432c547f 100644 --- a/upload-api/package.json +++ b/upload-api/package.json @@ -31,6 +31,7 @@ "@types/wordpress__blocks": "^12.5.18", "@types/xml2js": "^0.4.14", "@typescript-eslint/eslint-plugin": "^8.0.0", + "eslint": "^9.0.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "nodemon": "^3.1.10", @@ -49,7 +50,6 @@ "cheerio": "^1.2.0", "cors": "^2.8.5", "dotenv": "^16.3.1", - "eslint": "^10.0.0", "express": "^5.2.1", "express-rate-limit": "^7.2.0", "fs-readdir-recursive": "^1.1.0",