@vegan-friendly/strapi-plugin-elasticsearch 0.0.11-alpha.6 → 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/.prettierrc +7 -0
  2. package/.vscode/settings.json +24 -0
  3. package/README.md +0 -4
  4. package/admin/src/components/Initializer/index.js +26 -0
  5. package/admin/src/components/PluginIcon/index.js +12 -0
  6. package/admin/src/components/SubNavigation/index.js +48 -0
  7. package/admin/src/index.js +63 -0
  8. package/admin/src/pages/App/index.js +29 -0
  9. package/admin/src/pages/ConfigureCollection/index.js +225 -0
  10. package/admin/src/pages/ConfigureCollectionList/index.js +266 -0
  11. package/admin/src/pages/Homepage/index.js +168 -0
  12. package/admin/src/pages/ViewIndexingRunLog/index.js +124 -0
  13. package/admin/src/pluginId.js +5 -0
  14. package/admin/src/translations/en.json +1 -0
  15. package/admin/src/translations/fr.json +1 -0
  16. package/admin/src/utils/apiUrls.js +14 -0
  17. package/admin/src/utils/axiosInstance.js +40 -0
  18. package/admin/src/utils/getTrad.js +5 -0
  19. package/package.json +40 -80
  20. package/server/bootstrap.js +142 -0
  21. package/server/config/index.js +6 -0
  22. package/server/content-types/index.js +9 -0
  23. package/server/content-types/indexing-logs.js +35 -0
  24. package/server/content-types/name-prefix.js +0 -0
  25. package/server/content-types/tasks.js +52 -0
  26. package/server/controllers/configure-indexing.js +66 -0
  27. package/server/controllers/index.js +15 -0
  28. package/server/controllers/log-indexing.js +11 -0
  29. package/server/controllers/perform-indexing.js +28 -0
  30. package/server/controllers/perform-search.js +31 -0
  31. package/server/controllers/setup-info.js +14 -0
  32. package/server/destroy.js +5 -0
  33. package/server/index.js +25 -0
  34. package/server/middlewares/index.js +3 -0
  35. package/server/policies/index.js +3 -0
  36. package/server/register.js +5 -0
  37. package/server/routes/configure-indexing.js +42 -0
  38. package/server/routes/index.js +13 -0
  39. package/server/routes/perform-indexing.js +24 -0
  40. package/server/routes/perform-search.js +14 -0
  41. package/server/routes/run-log.js +12 -0
  42. package/server/routes/setup-info.js +12 -0
  43. package/server/services/configure-indexing.js +184 -0
  44. package/server/services/es-interface.js +187 -0
  45. package/server/services/helper.js +305 -0
  46. package/server/services/index.js +21 -0
  47. package/server/services/log-indexing.js +26 -0
  48. package/server/services/perform-indexing.js +173 -0
  49. package/server/services/schedule-indexing.js +65 -0
  50. package/server/services/transform-content.js +22 -0
  51. package/server/services/virtual-collections-registry.js +445 -0
  52. package/strapi-admin.js +3 -0
  53. package/strapi-server.js +3 -0
  54. package/dist/_chunks/App-Br53NnT1.mjs +0 -17315
  55. package/dist/_chunks/App-C3jMSu4l.js +0 -17314
  56. package/dist/_chunks/en-B4KWt_jN.js +0 -4
  57. package/dist/_chunks/en-Byx4XI2L.mjs +0 -4
  58. package/dist/_chunks/index-BlmgBQo2.js +0 -71
  59. package/dist/_chunks/index-CRnRLV0T.mjs +0 -72
  60. package/dist/admin/index.js +0 -3
  61. package/dist/admin/index.mjs +0 -4
  62. package/dist/server/index.js +0 -7330
  63. package/dist/server/index.mjs +0 -7307
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ // accessible only from admin UI
3
+ type: 'content-api',
4
+ routes: [
5
+ {
6
+ method: 'GET',
7
+ path: '/search',
8
+ handler: 'performSearch.search',
9
+ config: {
10
+ policies: []
11
+ },
12
+ }
13
+ ],
14
+ };
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ // accessible only from admin UI
3
+ type: 'admin',
4
+ routes: [
5
+ {
6
+ method: 'GET',
7
+ path: '/indexing-run-log',
8
+ handler: 'logIndexing.fetchRecentRunsLog',
9
+ config: { policies: [] },
10
+ }
11
+ ],
12
+ };
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ // accessible only from admin UI
3
+ type: 'admin',
4
+ routes: [
5
+ {
6
+ method: 'GET',
7
+ path: '/setup-info',
8
+ handler: 'setupInfo.getElasticsearchInfo',
9
+ config: { policies: [] },
10
+ }
11
+ ],
12
+ };
@@ -0,0 +1,184 @@
1
+ 'use strict';
2
+
3
+ const getPluginStore = () => {
4
+ return strapi.store({
5
+ environment: '',
6
+ type: 'plugin',
7
+ name: 'elasticsearch',
8
+ });
9
+ }
10
+
11
+ module.exports = ({ strapi }) => ({
12
+ async initializeStrapiElasticsearch() {
13
+ await this.cacheConfig();
14
+ },
15
+ async markInitialized() {
16
+ if (!strapi.elasticsearch)
17
+ strapi.elasticsearch = {}
18
+ strapi.elasticsearch.initialized = true;
19
+ },
20
+ isInitialized() {
21
+ return strapi.elasticsearch?.initialized || false
22
+ },
23
+ async cacheConfig() {
24
+ if (!strapi.elasticsearch)
25
+ strapi.elasticsearch = {}
26
+ strapi.elasticsearch.collectionsconfig = await this.getCollectionsConfiguredForIndexing();
27
+ strapi.elasticsearch.collections = await this.getCollectionsConfiguredForIndexing();
28
+ },
29
+ async getCollectionConfig({collectionName}) {
30
+ const contentConfig = await this.getContentConfig();
31
+ if (Object.keys(contentConfig).includes(collectionName))
32
+ {
33
+ const ob = {}
34
+ ob[collectionName] = contentConfig[collectionName];
35
+ return ob;
36
+ }
37
+ else
38
+ return null;
39
+ },
40
+ async getCollectionsConfiguredForIndexing() {
41
+ const contentConfig = await this.getContentConfig();
42
+ if (contentConfig)
43
+ return Object.keys(contentConfig).filter((i) => {
44
+ let hasAtleastOneIndexableAttribute = false;
45
+ const attribs = Object.keys(contentConfig[i])
46
+ for (let k=0; k<attribs.length; k++)
47
+ {
48
+ if (contentConfig[i][attribs[k]]['index'] === true)
49
+ {
50
+ hasAtleastOneIndexableAttribute = true;
51
+ break;
52
+ }
53
+ }
54
+ return hasAtleastOneIndexableAttribute;
55
+ })
56
+ else
57
+ return [];
58
+ },
59
+ async isCollectionConfiguredToBeIndexed({collectionName}) {
60
+ const collectionsToIndex = await this.getCollectionsConfiguredForIndexing();
61
+ return collectionsToIndex.includes(collectionName);
62
+ },
63
+ async getContentConfig() {
64
+ const fieldsToExclude = ['createdAt', 'createdBy', 'publishedAt', 'publishedBy', 'updatedAt', 'updatedBy']
65
+ const pluginStore = getPluginStore();
66
+ const settings = await pluginStore.get({ key: 'configsettings' });
67
+ const contentTypes = strapi.contentTypes;
68
+ const apiContentTypes = Object.keys(contentTypes).filter((c) => c.includes('api::'));
69
+ const apiContentConfig = {};
70
+ for (let r = 0; r < apiContentTypes.length; r++)
71
+ {
72
+ apiContentConfig[apiContentTypes[r]] = {};
73
+ const collectionAttributes = contentTypes[apiContentTypes[r]].attributes
74
+ const listOfAttributes = Object.keys(collectionAttributes).filter(
75
+ (i) => fieldsToExclude.includes(i) === false
76
+ );
77
+
78
+ for (let k = 0; k < listOfAttributes.length; k++)
79
+ {
80
+ const currentAttribute = listOfAttributes[k];
81
+ let attributeType = "regular";
82
+ if (typeof collectionAttributes[currentAttribute]["type"] !== "undefined"
83
+ && collectionAttributes[currentAttribute]["type"] !== null)
84
+ {
85
+ if (collectionAttributes[currentAttribute]["type"] === "component")
86
+ attributeType = "component"
87
+ else if (collectionAttributes[currentAttribute]["type"] === "dynamiczone")
88
+ attributeType = "dynamiczone"
89
+ }
90
+ apiContentConfig[apiContentTypes[r]][listOfAttributes[k]] = {index: false,
91
+ type: attributeType}
92
+ }
93
+
94
+ }
95
+ if (settings)
96
+ {
97
+ const objSettings = JSON.parse(settings);
98
+ if (Object.keys(objSettings).includes('contentConfig'))
99
+ {
100
+ const collections = Object.keys(apiContentConfig);
101
+ for (let r=0; r< collections.length; r++)
102
+ {
103
+ if (Object.keys(objSettings['contentConfig']).includes(collections[r]))
104
+ {
105
+ const attribsForCollection = Object.keys(apiContentConfig[collections[r]])
106
+ for (let s = 0; s < attribsForCollection.length; s++)
107
+ {
108
+ if (!Object.keys(objSettings['contentConfig'][collections[r]]).includes(attribsForCollection[s]))
109
+ {
110
+ objSettings['contentConfig'][collections[r]][attribsForCollection[s]] = {index: false,
111
+ type: apiContentConfig[collections[r]][attribsForCollection[s]].type}
112
+ }
113
+ else
114
+ {
115
+ if (!Object.keys(objSettings['contentConfig'][collections[r]][attribsForCollection[s]]).includes('type'))
116
+ objSettings['contentConfig'][collections[r]][attribsForCollection[s]]['type'] = apiContentConfig[collections[r]][attribsForCollection[s]].type
117
+ }
118
+ }
119
+ }
120
+ else
121
+ objSettings['contentConfig'][collections[r]] = apiContentConfig[collections[r]]
122
+ }
123
+ return objSettings['contentConfig'];
124
+ }
125
+ else
126
+ return apiContentConfig
127
+ }
128
+ else
129
+ return apiContentConfig;
130
+ },
131
+ async importContentConfig({config}){
132
+ const pluginStore = getPluginStore();
133
+ const settings = await pluginStore.get({ key: 'configsettings' });
134
+ if (settings)
135
+ {
136
+ const objSettings = JSON.parse(settings);
137
+ objSettings['contentConfig'] = JSON.parse(config)
138
+ const stringifySettings = JSON.stringify(objSettings);
139
+ await pluginStore.set({ key: 'configsettings', value : stringifySettings });
140
+ }
141
+ else
142
+ {
143
+ const newSettings = JSON.stringify({'contentConfig' : config})
144
+ await pluginStore.set({ key: 'configsettings', value : newSettings});
145
+ }
146
+ const updatedSettings = await pluginStore.get({ key: 'configsettings' });
147
+ await this.cacheConfig();
148
+ if (updatedSettings && Object.keys(updatedSettings).includes('contentConfig'))
149
+ return updatedSettings['contentConfig']
150
+ else
151
+ return {};
152
+ },
153
+ async setContentConfig({collection, config}){
154
+ const pluginStore = getPluginStore();
155
+ const settings = await pluginStore.get({ key: 'configsettings' });
156
+ if (settings)
157
+ {
158
+ const objSettings = JSON.parse(settings);
159
+ if (Object.keys(objSettings).includes('contentConfig'))
160
+ {
161
+ const prevConfig = objSettings['contentConfig'];
162
+ const changedConfigKey = Object.keys(config)[0];
163
+ const newConfig = prevConfig;
164
+ newConfig[changedConfigKey] = config[changedConfigKey]
165
+ objSettings['contentConfig'] = newConfig
166
+ }
167
+ else
168
+ objSettings['contentConfig'] = config;
169
+ const stringifySettings = JSON.stringify(objSettings);
170
+ await pluginStore.set({ key: 'configsettings', value : stringifySettings });
171
+ }
172
+ else
173
+ {
174
+ const newSettings = JSON.stringify({'contentConfig' : config})
175
+ await pluginStore.set({ key: 'configsettings', value : newSettings});
176
+ }
177
+ const updatedSettings = await pluginStore.get({ key: 'configsettings' });
178
+ await this.cacheConfig();
179
+ if (updatedSettings && Object.keys(updatedSettings).includes('contentConfig'))
180
+ return updatedSettings['contentConfig']
181
+ else
182
+ return {};
183
+ },
184
+ });
@@ -0,0 +1,187 @@
1
+ const { Client } = require('@elastic/elasticsearch')
2
+ const fs = require('fs')
3
+ const path = require('path');
4
+
5
+
6
+
7
+ let client = null;
8
+
9
+ module.exports = ({ strapi }) => ({
10
+ async initializeSearchEngine({host, uname, password, cert}){
11
+ try
12
+ {
13
+ client = new Client({
14
+ node: host,
15
+ auth: {
16
+ username: uname,
17
+ password: password
18
+ },
19
+ tls: {
20
+ ca: cert,
21
+ rejectUnauthorized: false
22
+ }
23
+ });
24
+ }
25
+ catch (err)
26
+ {
27
+ if (err.message.includes('ECONNREFUSED'))
28
+ {
29
+ console.error('strapi-plugin-elasticsearch : Connection to ElasticSearch at ', host, ' refused.')
30
+ console.error(err);
31
+ }
32
+ else
33
+ {
34
+ console.error('strapi-plugin-elasticsearch : Error while initializing connection to ElasticSearch.')
35
+ console.error(err);
36
+ }
37
+ throw(err);
38
+ }
39
+ },
40
+ async createIndex(indexName){
41
+ try{
42
+ const exists = await client.indices.exists({index: indexName});
43
+ if (!exists)
44
+ {
45
+ console.log('strapi-plugin-elasticsearch : Search index ', indexName, ' does not exist. Creating index.');
46
+
47
+ await client.indices.create({
48
+ index: indexName,
49
+ });
50
+ }
51
+ }
52
+ catch (err)
53
+ {
54
+ if (err.message.includes('ECONNREFUSED'))
55
+ {
56
+ console.log('strapi-plugin-elasticsearch : Error while creating index - connection to ElasticSearch refused.')
57
+ console.log(err);
58
+ }
59
+ else
60
+ {
61
+ console.log('strapi-plugin-elasticsearch : Error while creating index.')
62
+ console.log(err);
63
+ }
64
+ }
65
+ },
66
+ async deleteIndex(indexName){
67
+ try{
68
+ await client.indices.delete({
69
+ index: indexName
70
+ });
71
+ }
72
+ catch(err)
73
+ {
74
+ if (err.message.includes('ECONNREFUSED'))
75
+ {
76
+ console.log('strapi-plugin-elasticsearch : Connection to ElasticSearch refused.')
77
+ console.log(err);
78
+ }
79
+ else
80
+ {
81
+ console.log('strapi-plugin-elasticsearch : Error while deleting index to ElasticSearch.')
82
+ console.log(err);
83
+ }
84
+ }
85
+ },
86
+ async attachAliasToIndex(indexName) {
87
+ try{
88
+ const pluginConfig = await strapi.config.get('plugin.elasticsearch');
89
+ const aliasName = pluginConfig.indexAliasName;
90
+ const aliasExists = await client.indices.existsAlias({name: aliasName});
91
+ if (aliasExists)
92
+ {
93
+ console.log('strapi-plugin-elasticsearch : Alias with this name already exists, removing it.');
94
+ await client.indices.deleteAlias({index: '*', name: aliasName});
95
+ }
96
+ const indexExists = await client.indices.exists({index: indexName});
97
+ if (!indexExists)
98
+ await this.createIndex(indexName);
99
+ console.log('strapi-plugin-elasticsearch : Attaching the alias ', aliasName, ' to index : ', indexName);
100
+ await client.indices.putAlias({index: indexName, name: aliasName})
101
+ }
102
+ catch(err)
103
+ {
104
+ if (err.message.includes('ECONNREFUSED'))
105
+ {
106
+ console.log('strapi-plugin-elasticsearch : Attaching alias to the index - Connection to ElasticSearch refused.')
107
+ console.log(err);
108
+ }
109
+ else
110
+ {
111
+ console.log('strapi-plugin-elasticsearch : Attaching alias to the index - Error while setting up alias within ElasticSearch.')
112
+ console.log(err);
113
+ }
114
+ }
115
+ },
116
+ async checkESConnection() {
117
+ if (!client)
118
+ return false;
119
+ try {
120
+ await client.ping();
121
+ return true;
122
+ }
123
+ catch(error)
124
+ {
125
+ console.error('strapi-plugin-elasticsearch : Could not connect to Elastic search.')
126
+ console.error(error);
127
+ return false;
128
+ }
129
+
130
+ },
131
+ async indexDataToSpecificIndex({itemId, itemData}, iName){
132
+ try
133
+ {
134
+ await client.index({
135
+ index: iName,
136
+ id: itemId,
137
+ document: itemData
138
+ })
139
+ await client.indices.refresh({ index: iName });
140
+ }
141
+ catch(err){
142
+ console.log('strapi-plugin-elasticsearch : Error encountered while indexing data to ElasticSearch.')
143
+ console.log(err);
144
+ throw err;
145
+ }
146
+ },
147
+ async indexData({itemId, itemData}) {
148
+ const pluginConfig = await strapi.config.get('plugin.elasticsearch');
149
+ return await this.indexDataToSpecificIndex({itemId, itemData}, pluginConfig.indexAliasName);
150
+ },
151
+ async removeItemFromIndex({itemId}) {
152
+ const pluginConfig = await strapi.config.get('plugin.elasticsearch');
153
+ try
154
+ {
155
+ await client.delete({
156
+ index: pluginConfig.indexAliasName,
157
+ id: itemId
158
+ });
159
+ await client.indices.refresh({ index: pluginConfig.indexAliasName });
160
+ }
161
+ catch(err){
162
+ if (err.meta.statusCode === 404)
163
+ console.error('strapi-plugin-elasticsearch : The entry to be removed from the index already does not exist.')
164
+ else
165
+ {
166
+ console.error('strapi-plugin-elasticsearch : Error encountered while removing indexed data from ElasticSearch.')
167
+ throw err;
168
+ }
169
+ }
170
+ },
171
+ async searchData(searchQuery){
172
+ try
173
+ {
174
+ const pluginConfig = await strapi.config.get('plugin.elasticsearch');
175
+ const result= await client.search({
176
+ index: pluginConfig.indexAliasName,
177
+ ...searchQuery
178
+ });
179
+ return result;
180
+ }
181
+ catch(err)
182
+ {
183
+ console.log('Search : elasticClient.searchData : Error encountered while making a search request to ElasticSearch.')
184
+ throw err;
185
+ }
186
+ }
187
+ });