@vegan-friendly/strapi-plugin-elasticsearch 0.0.11-alpha.6 → 0.0.11-alpha.7
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/.vscode/settings.json +3 -0
- package/README.md +0 -4
- package/admin/src/components/Initializer/index.js +26 -0
- package/admin/src/components/PluginIcon/index.js +12 -0
- package/admin/src/components/SubNavigation/index.js +48 -0
- package/admin/src/index.js +63 -0
- package/admin/src/pages/App/index.js +29 -0
- package/admin/src/pages/ConfigureCollection/index.js +225 -0
- package/admin/src/pages/ConfigureCollectionList/index.js +266 -0
- package/admin/src/pages/Homepage/index.js +168 -0
- package/admin/src/pages/ViewIndexingRunLog/index.js +124 -0
- package/admin/src/pluginId.js +5 -0
- package/admin/src/translations/en.json +1 -0
- package/admin/src/translations/fr.json +1 -0
- package/admin/src/utils/apiUrls.js +14 -0
- package/admin/src/utils/axiosInstance.js +40 -0
- package/admin/src/utils/getTrad.js +5 -0
- package/package.json +40 -80
- package/server/bootstrap.js +142 -0
- package/server/config/index.js +6 -0
- package/server/content-types/index.js +9 -0
- package/server/content-types/indexing-logs.js +35 -0
- package/server/content-types/name-prefix.js +0 -0
- package/server/content-types/tasks.js +52 -0
- package/server/controllers/configure-indexing.js +66 -0
- package/server/controllers/index.js +15 -0
- package/server/controllers/log-indexing.js +11 -0
- package/server/controllers/perform-indexing.js +28 -0
- package/server/controllers/perform-search.js +31 -0
- package/server/controllers/setup-info.js +14 -0
- package/server/destroy.js +5 -0
- package/server/index.js +25 -0
- package/server/middlewares/index.js +3 -0
- package/server/policies/index.js +3 -0
- package/server/register.js +5 -0
- package/server/routes/configure-indexing.js +42 -0
- package/server/routes/index.js +13 -0
- package/server/routes/perform-indexing.js +24 -0
- package/server/routes/perform-search.js +14 -0
- package/server/routes/run-log.js +12 -0
- package/server/routes/setup-info.js +12 -0
- package/server/services/configure-indexing.js +184 -0
- package/server/services/es-interface.js +187 -0
- package/server/services/helper.js +305 -0
- package/server/services/index.js +19 -0
- package/server/services/log-indexing.js +26 -0
- package/server/services/perform-indexing.js +173 -0
- package/server/services/schedule-indexing.js +65 -0
- package/server/services/transform-content.js +22 -0
- package/strapi-admin.js +3 -0
- package/strapi-server.js +3 -0
- package/dist/_chunks/App-Br53NnT1.mjs +0 -17315
- package/dist/_chunks/App-C3jMSu4l.js +0 -17314
- package/dist/_chunks/en-B4KWt_jN.js +0 -4
- package/dist/_chunks/en-Byx4XI2L.mjs +0 -4
- package/dist/_chunks/index-BlmgBQo2.js +0 -71
- package/dist/_chunks/index-CRnRLV0T.mjs +0 -72
- package/dist/admin/index.js +0 -3
- package/dist/admin/index.mjs +0 -4
- package/dist/server/index.js +0 -7330
- package/dist/server/index.mjs +0 -7307
| @@ -0,0 +1,168 @@ | |
| 1 | 
            +
            import React, { useState, useEffect } from 'react';
         | 
| 2 | 
            +
            import  { SubNavigation } from '../../components/SubNavigation';;
         | 
| 3 | 
            +
            import { Box, Flex, Tab } from '@strapi/design-system';
         | 
| 4 | 
            +
            import { Typography } from '@strapi/design-system';
         | 
| 5 | 
            +
            import { apiGetElasticsearchSetupInfo, apiRequestReIndexing,
         | 
| 6 | 
            +
                apiTriggerIndexing } from '../../utils/apiUrls';
         | 
| 7 | 
            +
            import axiosInstance  from '../../utils/axiosInstance';
         | 
| 8 | 
            +
            import { IconButton } from '@strapi/design-system';
         | 
| 9 | 
            +
            import { Table, Tr, Td } from '@strapi/design-system';
         | 
| 10 | 
            +
            import { Refresh } from '@strapi/icons';
         | 
| 11 | 
            +
            import { TwoColsLayout, Button } from '@strapi/design-system';
         | 
| 12 | 
            +
            import { Grid, GridItem, Divider } from '@strapi/design-system';
         | 
| 13 | 
            +
            import {LoadingIndicatorPage, useNotification} from '@strapi/helper-plugin';
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            const loadElasticsearchSetupInfo = () => {
         | 
| 16 | 
            +
                return axiosInstance.get(apiGetElasticsearchSetupInfo)
         | 
| 17 | 
            +
                    .then((resp) => resp.data)
         | 
| 18 | 
            +
                    .then((data) => {
         | 
| 19 | 
            +
                      return data;
         | 
| 20 | 
            +
                    });
         | 
| 21 | 
            +
            }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            const Homepage = () => {
         | 
| 24 | 
            +
                const [setupInfo, setSetupInfo] = useState(null);
         | 
| 25 | 
            +
                const [isInProgress, setIsInProgress] = useState(false);
         | 
| 26 | 
            +
                const toggleNotification = useNotification();
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                const displayLabels = {'connected' : 'Connected',
         | 
| 29 | 
            +
                    'elasticCertificate' : 'Certificate',
         | 
| 30 | 
            +
                    'elasticHost' : 'Elasticsearch host',
         | 
| 31 | 
            +
                    'elasticIndexAlias' : 'Elasticsearch index Alias name',
         | 
| 32 | 
            +
                    'elasticUserName' : 'Elasticsearch username',
         | 
| 33 | 
            +
                    'indexingCronSchedule' : 'Indexing cron schedule',
         | 
| 34 | 
            +
                    'initialized' : 'Elasticsearch configuration loaded'};
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                const reloadElasticsearchSetupInfo = ({showNotification}) => {
         | 
| 37 | 
            +
                    setIsInProgress(true);
         | 
| 38 | 
            +
                    loadElasticsearchSetupInfo()
         | 
| 39 | 
            +
                    .then(setSetupInfo)
         | 
| 40 | 
            +
                    .then(() => {
         | 
| 41 | 
            +
                        if (showNotification)
         | 
| 42 | 
            +
                            toggleNotification({
         | 
| 43 | 
            +
                                type: "success", message: "Elasticsearch setup information reloaded.", timeout: 5000
         | 
| 44 | 
            +
                            });
         | 
| 45 | 
            +
                    })
         | 
| 46 | 
            +
                    .finally(() => setIsInProgress(false));
         | 
| 47 | 
            +
                }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                const requestFullSiteReindexing = () => {
         | 
| 50 | 
            +
                    setIsInProgress(true);
         | 
| 51 | 
            +
                    return axiosInstance.get(apiRequestReIndexing)
         | 
| 52 | 
            +
                        .then(() => {
         | 
| 53 | 
            +
                            toggleNotification({
         | 
| 54 | 
            +
                                type: "success", message: "Rebuilding the index is triggered.", timeout: 5000
         | 
| 55 | 
            +
                            });
         | 
| 56 | 
            +
                        })
         | 
| 57 | 
            +
                        .catch(() => {
         | 
| 58 | 
            +
                            toggleNotification({
         | 
| 59 | 
            +
                                type: "warning", message: "An error was encountered.", timeout: 5000
         | 
| 60 | 
            +
                            });
         | 
| 61 | 
            +
                        })
         | 
| 62 | 
            +
                        .finally(() => setIsInProgress(false));
         | 
| 63 | 
            +
                }
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                const triggerIndexingRun = () => {
         | 
| 66 | 
            +
                    setIsInProgress(true);
         | 
| 67 | 
            +
                    return axiosInstance.get(apiTriggerIndexing)
         | 
| 68 | 
            +
                    .then(() => {
         | 
| 69 | 
            +
                        toggleNotification({
         | 
| 70 | 
            +
                            type: "success", message: "The indexing job to process the pending tasks is started.", timeout: 5000
         | 
| 71 | 
            +
                        });
         | 
| 72 | 
            +
                    })
         | 
| 73 | 
            +
                    .catch(() => {
         | 
| 74 | 
            +
                        toggleNotification({
         | 
| 75 | 
            +
                            type: "warning", message: "An error was encountered.", timeout: 5000
         | 
| 76 | 
            +
                        });
         | 
| 77 | 
            +
                    })
         | 
| 78 | 
            +
                    .finally(() => setIsInProgress(false));
         | 
| 79 | 
            +
                }
         | 
| 80 | 
            +
                useEffect(() => {
         | 
| 81 | 
            +
                    reloadElasticsearchSetupInfo({showNotification: false});
         | 
| 82 | 
            +
                }, []);
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                if (setupInfo === null)
         | 
| 85 | 
            +
                    return <LoadingIndicatorPage />
         | 
| 86 | 
            +
                else
         | 
| 87 | 
            +
                    return (
         | 
| 88 | 
            +
                    <Flex alignItems="stretch" gap={4}>
         | 
| 89 | 
            +
                    <SubNavigation />
         | 
| 90 | 
            +
                    <Box padding={8} background="neutral100" width="100%">
         | 
| 91 | 
            +
                    <Box paddingBottom={4}>
         | 
| 92 | 
            +
                        <Typography variant="alpha">Setup Information</Typography>
         | 
| 93 | 
            +
                    </Box>   
         | 
| 94 | 
            +
                    <Box  width="100%" paddingBottom={4}>
         | 
| 95 | 
            +
                        <TwoColsLayout startCol={
         | 
| 96 | 
            +
                            <>
         | 
| 97 | 
            +
                        <Table>
         | 
| 98 | 
            +
                        {
         | 
| 99 | 
            +
                            setupInfo && (
         | 
| 100 | 
            +
                                Object.keys(setupInfo).map((k, idx) => {
         | 
| 101 | 
            +
                                    return (
         | 
| 102 | 
            +
                                        <Tr key={idx}>
         | 
| 103 | 
            +
                                            <Td><Box padding={2}>
         | 
| 104 | 
            +
                                                <Typography textColor="neutral600">{displayLabels[k]} :</Typography>
         | 
| 105 | 
            +
                                            </Box></Td>
         | 
| 106 | 
            +
                                            <Td>
         | 
| 107 | 
            +
                                                <Box padding={2}>
         | 
| 108 | 
            +
                                                <Grid>
         | 
| 109 | 
            +
                                                    <GridItem padding={2}>
         | 
| 110 | 
            +
                                                        { 
         | 
| 111 | 
            +
                                                            k === 'connected' && setupInfo[k] === true && 
         | 
| 112 | 
            +
                                                            (
         | 
| 113 | 
            +
                                                                <Typography fontWeight="bold" textColor="success500">Yes</Typography>
         | 
| 114 | 
            +
                                                            )
         | 
| 115 | 
            +
                                                        }
         | 
| 116 | 
            +
                                                        { 
         | 
| 117 | 
            +
                                                            k === 'connected' && setupInfo[k] === false && 
         | 
| 118 | 
            +
                                                            (
         | 
| 119 | 
            +
                                                                <Typography fontWeight="bold" textColor="danger500">No</Typography>
         | 
| 120 | 
            +
                                                            )
         | 
| 121 | 
            +
                                                        }
         | 
| 122 | 
            +
                                                        {
         | 
| 123 | 
            +
                                                            k !== 'connected' && 
         | 
| 124 | 
            +
                                                            (
         | 
| 125 | 
            +
                                                                <Typography textColor="neutral600">{String(setupInfo[k])}</Typography>
         | 
| 126 | 
            +
                                                            )
         | 
| 127 | 
            +
                                                        }
         | 
| 128 | 
            +
                                                    </GridItem>
         | 
| 129 | 
            +
                                                    <GridItem padding={1}>
         | 
| 130 | 
            +
                                                        {
         | 
| 131 | 
            +
                                                            k === 'connected' ?
         | 
| 132 | 
            +
                                                            <IconButton disabled={isInProgress} onClick={() => reloadElasticsearchSetupInfo({showNotification: true})} label="Refresh" icon={<Refresh />} /> : null                                            
         | 
| 133 | 
            +
                                                        }
         | 
| 134 | 
            +
                                                    </GridItem>
         | 
| 135 | 
            +
                                                </Grid>
         | 
| 136 | 
            +
                                                </Box>
         | 
| 137 | 
            +
                                            </Td>
         | 
| 138 | 
            +
                                        </Tr>
         | 
| 139 | 
            +
                                    );
         | 
| 140 | 
            +
                                })
         | 
| 141 | 
            +
                            )
         | 
| 142 | 
            +
                        }
         | 
| 143 | 
            +
                        </Table></>}
         | 
| 144 | 
            +
                        endCol={<>
         | 
| 145 | 
            +
                        <Box paddingLeft={2} paddingRight={2} paddingTop={4} paddingBottom={4} >
         | 
| 146 | 
            +
                            <Box paddingTop={4} paddingBottom={4}>
         | 
| 147 | 
            +
                                <Typography variant="pi" fontWeight="bold" textColor="neutral600" >ACTIONS</Typography>
         | 
| 148 | 
            +
                            </Box>
         | 
| 149 | 
            +
                            <Divider />
         | 
| 150 | 
            +
                            <Box paddingTop={4} paddingBottom={4}>
         | 
| 151 | 
            +
                                <Box paddingTop={2} paddingBottom={2}>
         | 
| 152 | 
            +
                                    <Button loading={isInProgress} fullWidth variant="secondary" onClick={requestFullSiteReindexing}>Rebuild Index</Button>
         | 
| 153 | 
            +
                                </Box>
         | 
| 154 | 
            +
                                <Box paddingTop={2} paddingBottom={2}>
         | 
| 155 | 
            +
                                    <Button loading={isInProgress} fullWidth variant="secondary" onClick={triggerIndexingRun}>Trigger Indexing</Button>
         | 
| 156 | 
            +
                                </Box>
         | 
| 157 | 
            +
                            </Box>
         | 
| 158 | 
            +
                        </Box>
         | 
| 159 | 
            +
                        </>
         | 
| 160 | 
            +
                        } />
         | 
| 161 | 
            +
                    </Box>
         | 
| 162 | 
            +
                    </Box>
         | 
| 163 | 
            +
                    </Flex>
         | 
| 164 | 
            +
                    );
         | 
| 165 | 
            +
            };
         | 
| 166 | 
            +
             | 
| 167 | 
            +
             | 
| 168 | 
            +
            export default Homepage;
         | 
| @@ -0,0 +1,124 @@ | |
| 1 | 
            +
            /*
         | 
| 2 | 
            +
             *
         | 
| 3 | 
            +
             * HomePage
         | 
| 4 | 
            +
             *
         | 
| 5 | 
            +
             */
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            import React, { useState, useEffect } from 'react';
         | 
| 8 | 
            +
            // import PropTypes from 'prop-types';
         | 
| 9 | 
            +
            import pluginId from '../../pluginId';
         | 
| 10 | 
            +
            import  { SubNavigation } from '../../components/SubNavigation';;
         | 
| 11 | 
            +
            import { Box, Flex } from '@strapi/design-system';
         | 
| 12 | 
            +
            import { apiFetchRecentIndexingRunLog } from "../../utils/apiUrls";
         | 
| 13 | 
            +
            import axiosInstance  from '../../utils/axiosInstance';
         | 
| 14 | 
            +
            import { Table, Thead, Tbody, Tr, Td, Th } from '@strapi/design-system';
         | 
| 15 | 
            +
            import { Typography } from '@strapi/design-system';
         | 
| 16 | 
            +
            import {LoadingIndicatorPage} from '@strapi/helper-plugin';
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            const loadRecentIndexingRuns = () => {
         | 
| 19 | 
            +
              return axiosInstance.get(apiFetchRecentIndexingRunLog)
         | 
| 20 | 
            +
                  .then((resp) => resp.data)
         | 
| 21 | 
            +
                  .then((data) => {
         | 
| 22 | 
            +
                    return data;
         | 
| 23 | 
            +
                  });
         | 
| 24 | 
            +
            } 
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            const formattedDate = (dateString) => {
         | 
| 27 | 
            +
              const date = new Date(dateString);
         | 
| 28 | 
            +
              const options = {
         | 
| 29 | 
            +
                weekday: 'long',
         | 
| 30 | 
            +
                year: 'numeric',
         | 
| 31 | 
            +
                month: 'numeric',
         | 
| 32 | 
            +
                day: 'numeric',
         | 
| 33 | 
            +
                hour: 'numeric',
         | 
| 34 | 
            +
                minute: 'numeric',
         | 
| 35 | 
            +
              };
         | 
| 36 | 
            +
              
         | 
| 37 | 
            +
              const dateTimeFormat = new Intl.DateTimeFormat('en-US', options);
         | 
| 38 | 
            +
              const parts = dateTimeFormat.formatToParts(date);
         | 
| 39 | 
            +
              
         | 
| 40 | 
            +
              let formattedDate = '';
         | 
| 41 | 
            +
              parts.forEach((part) => {
         | 
| 42 | 
            +
                  if (part.type === "weekday") 
         | 
| 43 | 
            +
                      formattedDate+= `${part.value}, `;
         | 
| 44 | 
            +
                   if (part.type === "day") 
         | 
| 45 | 
            +
                      formattedDate+= `${part.value}/`;   
         | 
| 46 | 
            +
                   if (part.type === "month") 
         | 
| 47 | 
            +
                      formattedDate+= `${part.value}/`;  
         | 
| 48 | 
            +
                   if (part.type === "year") 
         | 
| 49 | 
            +
                      formattedDate+= `${part.value}  `;
         | 
| 50 | 
            +
                   if (part.type === "hour") 
         | 
| 51 | 
            +
                      formattedDate+= `${part.value}:`;
         | 
| 52 | 
            +
                   if (part.type === "minute") 
         | 
| 53 | 
            +
                      formattedDate+= `${part.value}`;         
         | 
| 54 | 
            +
              });
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              return formattedDate;
         | 
| 57 | 
            +
            }
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            const ViewIndexingRunLog = () => {
         | 
| 60 | 
            +
              const [logTable, setLogTable] = useState(null);
         | 
| 61 | 
            +
              useEffect(() => {
         | 
| 62 | 
            +
                loadRecentIndexingRuns()
         | 
| 63 | 
            +
                .then(setLogTable)
         | 
| 64 | 
            +
                }, []);
         | 
| 65 | 
            +
              
         | 
| 66 | 
            +
              if (logTable === null)
         | 
| 67 | 
            +
                    return <LoadingIndicatorPage />
         | 
| 68 | 
            +
              else
         | 
| 69 | 
            +
                return (
         | 
| 70 | 
            +
                    <Flex alignItems="stretch" gap={4}>
         | 
| 71 | 
            +
                        <SubNavigation />
         | 
| 72 | 
            +
                        <Box padding={8} background="neutral100" width="100%">
         | 
| 73 | 
            +
                          <Box paddingBottom={4}>
         | 
| 74 | 
            +
                            <Typography variant="alpha">Recent Indexing Run Logs</Typography>
         | 
| 75 | 
            +
                          </Box>
         | 
| 76 | 
            +
                          {
         | 
| 77 | 
            +
                            logTable && logTable.length > 0 && (
         | 
| 78 | 
            +
                              <>
         | 
| 79 | 
            +
                                <Table colCount={3} rowCount={logTable.length}>
         | 
| 80 | 
            +
                                  <Thead>
         | 
| 81 | 
            +
                                    <Tr>
         | 
| 82 | 
            +
                                      <Th>
         | 
| 83 | 
            +
                                        <Typography variant="sigma">Date</Typography>
         | 
| 84 | 
            +
                                      </Th>
         | 
| 85 | 
            +
                                      <Th>
         | 
| 86 | 
            +
                                        <Typography variant="sigma">Status</Typography>
         | 
| 87 | 
            +
                                      </Th>
         | 
| 88 | 
            +
                                      <Th>
         | 
| 89 | 
            +
                                        <Typography variant="sigma">Details</Typography>
         | 
| 90 | 
            +
                                      </Th>
         | 
| 91 | 
            +
                                    </Tr>
         | 
| 92 | 
            +
                                  </Thead>
         | 
| 93 | 
            +
                                  <Tbody>
         | 
| 94 | 
            +
                                  {
         | 
| 95 | 
            +
                                    logTable.map((data, index) => {
         | 
| 96 | 
            +
                                      return (
         | 
| 97 | 
            +
                                        <Tr key={index}>
         | 
| 98 | 
            +
                                          <Td>
         | 
| 99 | 
            +
                                            <Typography textColor="neutral600">{formattedDate(data.createdAt)}</Typography>
         | 
| 100 | 
            +
                                          </Td>
         | 
| 101 | 
            +
                                          <Td>
         | 
| 102 | 
            +
                                            <Typography textColor="neutral600">{data.status}</Typography>
         | 
| 103 | 
            +
                                          </Td>
         | 
| 104 | 
            +
                                          <Td>
         | 
| 105 | 
            +
                                            <Typography textColor="neutral600">{data.details}</Typography>
         | 
| 106 | 
            +
                                          </Td>                                 
         | 
| 107 | 
            +
                                        </Tr>
         | 
| 108 | 
            +
                                      );
         | 
| 109 | 
            +
                                    })
         | 
| 110 | 
            +
                                  }
         | 
| 111 | 
            +
                                  </Tbody>
         | 
| 112 | 
            +
                                </Table>
         | 
| 113 | 
            +
                                <Box paddingTop={2} paddingBottom={2}>
         | 
| 114 | 
            +
                                  <Typography textColor="neutral600">This view lists the details of the 50 recent-most indexing runs.</Typography>
         | 
| 115 | 
            +
                                </Box>
         | 
| 116 | 
            +
                              </>
         | 
| 117 | 
            +
                            )
         | 
| 118 | 
            +
                          }
         | 
| 119 | 
            +
                        </Box>    
         | 
| 120 | 
            +
                    </Flex>
         | 
| 121 | 
            +
              );
         | 
| 122 | 
            +
            };
         | 
| 123 | 
            +
             | 
| 124 | 
            +
            export default ViewIndexingRunLog;
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            {}
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            {}
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            import { collectionName } from "../../../server/content-types/tasks";
         | 
| 2 | 
            +
            import pluginId from "../pluginId";
         | 
| 3 | 
            +
            export const apiGetContentConfig = `/${pluginId}/content-config/`
         | 
| 4 | 
            +
            export const apiGetCollectionConfig = (collectionName) => `/${pluginId}/collection-config/${collectionName}`
         | 
| 5 | 
            +
            export const apiSaveCollectionConfig = (collectionName) => `/${pluginId}/collection-config/${collectionName}`
         | 
| 6 | 
            +
            export const apiGetElasticsearchSetupInfo = `/${pluginId}/setup-info`
         | 
| 7 | 
            +
            export const apiFetchRecentIndexingRunLog = `/${pluginId}/indexing-run-log`
         | 
| 8 | 
            +
            export const apiRequestReIndexing = `/${pluginId}/reindex`
         | 
| 9 | 
            +
            export const apiRequestCollectionIndexing = (collectionName) => `/${pluginId}/collection-reindex/${collectionName}`
         | 
| 10 | 
            +
            export const apiTriggerIndexing = `/${pluginId}/trigger-indexing/`
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            export const apiExportContentConfig = `/${pluginId}/export-content-config/`
         | 
| 13 | 
            +
            export const apiImportContentConfig = `/${pluginId}/import-content-config/`
         | 
| 14 | 
            +
             | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            /**
         | 
| 2 | 
            +
             * axios with a custom config.
         | 
| 3 | 
            +
             */
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            import axios from 'axios';
         | 
| 6 | 
            +
            import { auth } from '@strapi/helper-plugin';
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            const instance = axios.create({
         | 
| 9 | 
            +
              baseURL: process.env.STRAPI_ADMIN_BACKEND_URL,
         | 
| 10 | 
            +
            });
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            instance.interceptors.request.use(
         | 
| 13 | 
            +
              async config => {
         | 
| 14 | 
            +
                config.headers = {
         | 
| 15 | 
            +
                  Authorization: `Bearer ${auth.getToken()}`,
         | 
| 16 | 
            +
                  Accept: 'application/json',
         | 
| 17 | 
            +
                  'Content-Type': 'application/json',
         | 
| 18 | 
            +
                };
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                return config;
         | 
| 21 | 
            +
              },
         | 
| 22 | 
            +
              error => {
         | 
| 23 | 
            +
                Promise.reject(error);
         | 
| 24 | 
            +
              }
         | 
| 25 | 
            +
            );
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            instance.interceptors.response.use(
         | 
| 28 | 
            +
              response => response,
         | 
| 29 | 
            +
              error => {
         | 
| 30 | 
            +
                // whatever you want to do with the error
         | 
| 31 | 
            +
                if (error.response?.status === 401) {
         | 
| 32 | 
            +
                  auth.clearAppStorage();
         | 
| 33 | 
            +
                  window.location.reload();
         | 
| 34 | 
            +
                }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                throw error;
         | 
| 37 | 
            +
              }
         | 
| 38 | 
            +
            );
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            export default instance;
         | 
    
        package/package.json
    CHANGED
    
    | @@ -1,80 +1,40 @@ | |
| 1 | 
            -
            {
         | 
| 2 | 
            -
              "name": "@vegan-friendly/strapi-plugin-elasticsearch",
         | 
| 3 | 
            -
              " | 
| 4 | 
            -
              " | 
| 5 | 
            -
              " | 
| 6 | 
            -
              " | 
| 7 | 
            -
             | 
| 8 | 
            -
                " | 
| 9 | 
            -
                " | 
| 10 | 
            -
             | 
| 11 | 
            -
               | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
                " | 
| 20 | 
            -
             | 
| 21 | 
            -
               | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
               | 
| 25 | 
            -
              " | 
| 26 | 
            -
                " | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
                  " | 
| 31 | 
            -
                  " | 
| 32 | 
            -
             | 
| 33 | 
            -
                 | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
               | 
| 40 | 
            -
             | 
| 41 | 
            -
                "dist"
         | 
| 42 | 
            -
              ],
         | 
| 43 | 
            -
              "scripts": {
         | 
| 44 | 
            -
                "build": "strapi-plugin build",
         | 
| 45 | 
            -
                "watch": "strapi-plugin watch",
         | 
| 46 | 
            -
                "watch:link": "strapi-plugin watch:link",
         | 
| 47 | 
            -
                "verify": "strapi-plugin verify"
         | 
| 48 | 
            -
              },
         | 
| 49 | 
            -
              "dependencies": {
         | 
| 50 | 
            -
                "@elastic/elasticsearch": "^8.17.1",
         | 
| 51 | 
            -
                "@radix-ui/react-tooltip": "^1.1.8",
         | 
| 52 | 
            -
                "@strapi/design-system": "^2.0.0-rc.18",
         | 
| 53 | 
            -
                "@strapi/icons": "^2.0.0-rc.18",
         | 
| 54 | 
            -
                "markdown-to-txt": "^2.0.1",
         | 
| 55 | 
            -
                "react-intl": "^7.1.9"
         | 
| 56 | 
            -
              },
         | 
| 57 | 
            -
              "devDependencies": {
         | 
| 58 | 
            -
                "@strapi/sdk-plugin": "^5.3.2 || ^4.0.0",
         | 
| 59 | 
            -
                "@strapi/strapi": "^5.11.3 || ^4.0.0",
         | 
| 60 | 
            -
                "prettier": "^3.5.3",
         | 
| 61 | 
            -
                "react": "^18.3.1",
         | 
| 62 | 
            -
                "react-dom": "^18.3.1",
         | 
| 63 | 
            -
                "react-router-dom": "^6.30.0 || ^5",
         | 
| 64 | 
            -
                "styled-components": "^6.1.16 || ^5"
         | 
| 65 | 
            -
              },
         | 
| 66 | 
            -
              "peerDependencies": {
         | 
| 67 | 
            -
                "@strapi/sdk-plugin": "^5.3.2 || ^4.0.0",
         | 
| 68 | 
            -
                "@strapi/strapi": "^5.11.3 || ^4.0.0",
         | 
| 69 | 
            -
                "react": "^18.3.1",
         | 
| 70 | 
            -
                "react-dom": "^18.3.1",
         | 
| 71 | 
            -
                "react-router-dom": "^6.30.0 || ^5",
         | 
| 72 | 
            -
                "styled-components": "^6.1.16 || ^5"
         | 
| 73 | 
            -
              },
         | 
| 74 | 
            -
              "strapi": {
         | 
| 75 | 
            -
                "name": "elasticsearch",
         | 
| 76 | 
            -
                "description": "A plugin to enable using Elasticsearch with Strapi CMS.",
         | 
| 77 | 
            -
                "kind": "plugin",
         | 
| 78 | 
            -
                "displayName": "Strapi <-> Elasticsearch"
         | 
| 79 | 
            -
              }
         | 
| 80 | 
            -
            }
         | 
| 1 | 
            +
            {
         | 
| 2 | 
            +
              "name": "@vegan-friendly/strapi-plugin-elasticsearch",
         | 
| 3 | 
            +
              "version": "0.0.11-alpha.7",
         | 
| 4 | 
            +
              "description": "A Strapi plugin to enable using Elasticsearch with Strapi CMS.",
         | 
| 5 | 
            +
              "homepage": "https://github.com/vegan-friendly/strapi-plugin-elasticsearch",
         | 
| 6 | 
            +
              "strapi": {
         | 
| 7 | 
            +
                "name": "elasticsearch",
         | 
| 8 | 
            +
                "description": "A plugin to enable using Elasticsearch with Strapi CMS.",
         | 
| 9 | 
            +
                "kind": "plugin",
         | 
| 10 | 
            +
                "displayName": "Strapi <-> Elasticsearch"
         | 
| 11 | 
            +
              },
         | 
| 12 | 
            +
              "repository": {
         | 
| 13 | 
            +
                "type": "git",
         | 
| 14 | 
            +
                "url": "git://github.com/vegan-friendly/strapi-plugin-elasticsearch.git"
         | 
| 15 | 
            +
              },
         | 
| 16 | 
            +
              "author": {
         | 
| 17 | 
            +
                "name": "Punit Sethi",
         | 
| 18 | 
            +
                "email": "punit@tezify.com",
         | 
| 19 | 
            +
                "url": "https://punits.dev"
         | 
| 20 | 
            +
              },
         | 
| 21 | 
            +
              "dependencies": {
         | 
| 22 | 
            +
                "@elastic/elasticsearch": "^8.9.0",
         | 
| 23 | 
            +
                "markdown-to-txt": "^2.0.1"
         | 
| 24 | 
            +
              },
         | 
| 25 | 
            +
              "peerDependencies": {
         | 
| 26 | 
            +
                "@strapi/strapi": "^4.0.0"
         | 
| 27 | 
            +
              },
         | 
| 28 | 
            +
              "maintainers": [
         | 
| 29 | 
            +
                {
         | 
| 30 | 
            +
                  "name": "Punit Sethi",
         | 
| 31 | 
            +
                  "email": "punit@tezify.com",
         | 
| 32 | 
            +
                  "url": "https://punits.dev"
         | 
| 33 | 
            +
                }
         | 
| 34 | 
            +
              ],
         | 
| 35 | 
            +
              "engines": {
         | 
| 36 | 
            +
                "node": ">=16.0.0 <=20.x.x",
         | 
| 37 | 
            +
                "npm": ">=6.0.0"
         | 
| 38 | 
            +
              },
         | 
| 39 | 
            +
              "license": "MIT"
         | 
| 40 | 
            +
            }
         | 
| @@ -0,0 +1,142 @@ | |
| 1 | 
            +
            'use strict';
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module.exports = async ({ strapi }) => {
         | 
| 4 | 
            +
                const pluginConfig = await strapi.config.get('plugin.elasticsearch');
         | 
| 5 | 
            +
                const configureIndexingService = strapi.plugins['elasticsearch'].services.configureIndexing;
         | 
| 6 | 
            +
                const scheduleIndexingService = strapi.plugins['elasticsearch'].services.scheduleIndexing;
         | 
| 7 | 
            +
                const esInterface = strapi.plugins['elasticsearch'].services.esInterface;
         | 
| 8 | 
            +
                const indexer = strapi.plugins['elasticsearch'].services.indexer;
         | 
| 9 | 
            +
                const helper = strapi.plugins['elasticsearch'].services.helper; 
         | 
| 10 | 
            +
                try
         | 
| 11 | 
            +
                {
         | 
| 12 | 
            +
                  await configureIndexingService.initializeStrapiElasticsearch();
         | 
| 13 | 
            +
                
         | 
| 14 | 
            +
                  if (!Object.keys(pluginConfig).includes('indexingCronSchedule'))
         | 
| 15 | 
            +
                    console.warn("The plugin strapi-plugin-elasticsearch is enabled but the indexingCronSchedule is not configured.");
         | 
| 16 | 
            +
                  else if (!Object.keys(pluginConfig).includes('searchConnector'))
         | 
| 17 | 
            +
                    console.warn("The plugin strapi-plugin-elasticsearch is enabled but the searchConnector is not configured.");
         | 
| 18 | 
            +
                  else
         | 
| 19 | 
            +
                  {
         | 
| 20 | 
            +
                    const connector = pluginConfig['searchConnector'];
         | 
| 21 | 
            +
                    await esInterface.initializeSearchEngine({host : connector.host, uname: connector.username, 
         | 
| 22 | 
            +
                          password: connector.password, cert: connector.certificate});
         | 
| 23 | 
            +
                    strapi.cron.add({
         | 
| 24 | 
            +
                      elasticsearchIndexing: {
         | 
| 25 | 
            +
                        task: async ({ strapi }) => {
         | 
| 26 | 
            +
                          await indexer.indexPendingData();
         | 
| 27 | 
            +
                        },
         | 
| 28 | 
            +
                        options: {
         | 
| 29 | 
            +
                          rule: pluginConfig['indexingCronSchedule'],
         | 
| 30 | 
            +
                        },
         | 
| 31 | 
            +
                      },
         | 
| 32 | 
            +
                    });   
         | 
| 33 | 
            +
                    
         | 
| 34 | 
            +
                    if (await esInterface.checkESConnection())
         | 
| 35 | 
            +
                    {
         | 
| 36 | 
            +
                      //Attach the alias to the current index:
         | 
| 37 | 
            +
                      const idxName = await helper.getCurrentIndexName();
         | 
| 38 | 
            +
                      await esInterface.attachAliasToIndex(idxName);
         | 
| 39 | 
            +
                    }
         | 
| 40 | 
            +
                      
         | 
| 41 | 
            +
                  }
         | 
| 42 | 
            +
              
         | 
| 43 | 
            +
                  strapi.db.lifecycles.subscribe(async (event) => {
         | 
| 44 | 
            +
                    if (event.action === 'afterCreate' || event.action === 'afterUpdate') {
         | 
| 45 | 
            +
                      if (strapi.elasticsearch.collections.includes(event.model.uid))
         | 
| 46 | 
            +
                      {
         | 
| 47 | 
            +
                        //collection without draft-publish
         | 
| 48 | 
            +
                        if (typeof event.model.attributes.publishedAt === "undefined")
         | 
| 49 | 
            +
                        {
         | 
| 50 | 
            +
                          await scheduleIndexingService.addItemToIndex({
         | 
| 51 | 
            +
                            collectionUid: event.model.uid,
         | 
| 52 | 
            +
                            recordId: event.result.id
         | 
| 53 | 
            +
                          });  
         | 
| 54 | 
            +
                        }
         | 
| 55 | 
            +
                        else if (event.model.attributes.publishedAt)
         | 
| 56 | 
            +
                        {
         | 
| 57 | 
            +
                          if (event.result.publishedAt)
         | 
| 58 | 
            +
                          {
         | 
| 59 | 
            +
                            await scheduleIndexingService.addItemToIndex({
         | 
| 60 | 
            +
                              collectionUid: event.model.uid,
         | 
| 61 | 
            +
                              recordId: event.result.id
         | 
| 62 | 
            +
                            });    
         | 
| 63 | 
            +
                          }
         | 
| 64 | 
            +
                          else
         | 
| 65 | 
            +
                          {
         | 
| 66 | 
            +
                            //unpublish
         | 
| 67 | 
            +
                            await scheduleIndexingService.removeItemFromIndex({
         | 
| 68 | 
            +
                              collectionUid: event.model.uid,
         | 
| 69 | 
            +
                              recordId: event.result.id
         | 
| 70 | 
            +
                            });    
         | 
| 71 | 
            +
                          }
         | 
| 72 | 
            +
                        }
         | 
| 73 | 
            +
                      }
         | 
| 74 | 
            +
                    }
         | 
| 75 | 
            +
                    //bulk publish-unpublish from list view
         | 
| 76 | 
            +
                    if (event.action === 'afterCreateMany' || event.action === 'afterUpdateMany') {
         | 
| 77 | 
            +
                      if (strapi.elasticsearch.collections.includes(event.model.uid))
         | 
| 78 | 
            +
                      {
         | 
| 79 | 
            +
                        if (Object.keys(event.params.where.id).includes('$in'))
         | 
| 80 | 
            +
                        {
         | 
| 81 | 
            +
                          const updatedItemIds = event.params.where.id['$in']
         | 
| 82 | 
            +
                          //bulk unpublish
         | 
| 83 | 
            +
                          if (typeof event.params.data.publishedAt === "undefined" || 
         | 
| 84 | 
            +
                            event.params.data.publishedAt === null)
         | 
| 85 | 
            +
                            {
         | 
| 86 | 
            +
                              for (let k = 0; k< updatedItemIds.length; k++)
         | 
| 87 | 
            +
                              {
         | 
| 88 | 
            +
                                await scheduleIndexingService.removeItemFromIndex({
         | 
| 89 | 
            +
                                  collectionUid: event.model.uid,
         | 
| 90 | 
            +
                                  recordId: updatedItemIds[k]
         | 
| 91 | 
            +
                                });            
         | 
| 92 | 
            +
                              }    
         | 
| 93 | 
            +
                            }
         | 
| 94 | 
            +
                          else
         | 
| 95 | 
            +
                          {
         | 
| 96 | 
            +
                            for (let k = 0; k< updatedItemIds.length; k++)
         | 
| 97 | 
            +
                            {
         | 
| 98 | 
            +
                              await scheduleIndexingService.addItemToIndex({
         | 
| 99 | 
            +
                                collectionUid: event.model.uid,
         | 
| 100 | 
            +
                                recordId: updatedItemIds[k]
         | 
| 101 | 
            +
                              });   
         | 
| 102 | 
            +
                            }
         | 
| 103 | 
            +
                          }
         | 
| 104 | 
            +
                        }
         | 
| 105 | 
            +
                      }
         | 
| 106 | 
            +
                    }    
         | 
| 107 | 
            +
                    if (event.action === 'afterDelete') {
         | 
| 108 | 
            +
                      if (strapi.elasticsearch.collections.includes(event.model.uid))
         | 
| 109 | 
            +
                      {
         | 
| 110 | 
            +
                        await scheduleIndexingService.removeItemFromIndex({
         | 
| 111 | 
            +
                          collectionUid: event.model.uid,
         | 
| 112 | 
            +
                          recordId: event.result.id
         | 
| 113 | 
            +
                        });  
         | 
| 114 | 
            +
                      }
         | 
| 115 | 
            +
                    }
         | 
| 116 | 
            +
                    if (event.action === 'afterDeleteMany') {
         | 
| 117 | 
            +
                      if (strapi.elasticsearch.collections.includes(event.model.uid))
         | 
| 118 | 
            +
                      {
         | 
| 119 | 
            +
                        if (Object.keys(event.params.where).includes('$and') &&
         | 
| 120 | 
            +
                        Array.isArray(event.params.where['$and']) &&
         | 
| 121 | 
            +
                        Object.keys(event.params.where['$and'][0]).includes('id') && 
         | 
| 122 | 
            +
                        Object.keys(event.params.where['$and'][0]['id']).includes('$in'))
         | 
| 123 | 
            +
                        {
         | 
| 124 | 
            +
                          const deletedItemIds = event.params.where['$and'][0]['id']['$in']
         | 
| 125 | 
            +
                          for (let k = 0; k< deletedItemIds.length; k++)
         | 
| 126 | 
            +
                          {
         | 
| 127 | 
            +
                            await scheduleIndexingService.removeItemFromIndex({
         | 
| 128 | 
            +
                              collectionUid: event.model.uid,
         | 
| 129 | 
            +
                              recordId: deletedItemIds[k]
         | 
| 130 | 
            +
                            });            
         | 
| 131 | 
            +
                          }
         | 
| 132 | 
            +
                        }        
         | 
| 133 | 
            +
                      }
         | 
| 134 | 
            +
                    }
         | 
| 135 | 
            +
                  });   
         | 
| 136 | 
            +
                  configureIndexingService.markInitialized(); 
         | 
| 137 | 
            +
                }
         | 
| 138 | 
            +
                catch(err) {
         | 
| 139 | 
            +
                  console.error('An error was encountered while initializing the strapi-plugin-elasticsearch plugin.')
         | 
| 140 | 
            +
                  console.error(err);
         | 
| 141 | 
            +
                }  
         | 
| 142 | 
            +
            };
         |