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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/admin/src/components/Initializer/index.d.ts +15 -0
  2. package/dist/admin/src/components/Initializer/index.js +25 -0
  3. package/dist/admin/src/components/PluginIcon/index.d.ts +8 -0
  4. package/dist/admin/src/components/PluginIcon/index.js +14 -0
  5. package/dist/admin/src/components/SubNavigation/index.d.ts +4 -0
  6. package/dist/admin/src/components/SubNavigation/index.js +40 -0
  7. package/dist/admin/src/index.d.ts +8 -0
  8. package/dist/admin/src/index.js +92 -0
  9. package/dist/admin/src/pages/App/index.d.ts +9 -0
  10. package/dist/admin/src/pages/App/index.js +29 -0
  11. package/dist/admin/src/pages/ConfigureCollection/index.d.ts +3 -0
  12. package/dist/admin/src/pages/ConfigureCollection/index.js +193 -0
  13. package/dist/admin/src/pages/ConfigureCollectionList/index.d.ts +3 -0
  14. package/dist/admin/src/pages/ConfigureCollectionList/index.js +228 -0
  15. package/dist/admin/src/pages/Homepage/index.d.ts +3 -0
  16. package/dist/admin/src/pages/Homepage/index.js +155 -0
  17. package/dist/admin/src/pages/ViewIndexingRunLog/index.d.ts +3 -0
  18. package/dist/admin/src/pages/ViewIndexingRunLog/index.js +125 -0
  19. package/dist/admin/src/pluginId.d.ts +2 -0
  20. package/dist/admin/src/pluginId.js +8 -0
  21. package/dist/admin/src/utils/apiUrls.d.ts +10 -0
  22. package/dist/admin/src/utils/apiUrls.js +20 -0
  23. package/dist/admin/src/utils/axiosInstance.d.ts +5 -0
  24. package/dist/admin/src/utils/axiosInstance.js +33 -0
  25. package/dist/admin/src/utils/getTrad.d.ts +2 -0
  26. package/dist/admin/src/utils/getTrad.js +8 -0
  27. package/dist/server/bootstrap.js +125 -0
  28. package/dist/server/config/index.d.ts +0 -0
  29. package/dist/server/config/index.js +5 -0
  30. package/dist/server/content-types/index.d.ts +2 -0
  31. package/{server → dist/server}/content-types/index.js +7 -9
  32. package/dist/server/content-types/indexing-logs.d.ts +0 -0
  33. package/dist/server/content-types/indexing-logs.js +35 -0
  34. package/dist/server/content-types/name-prefix.d.ts +0 -0
  35. package/dist/server/content-types/name-prefix.js +1 -0
  36. package/dist/server/content-types/tasks.d.ts +0 -0
  37. package/dist/server/content-types/tasks.js +52 -0
  38. package/dist/server/controllers/configure-indexing.d.ts +0 -0
  39. package/dist/server/controllers/configure-indexing.js +58 -0
  40. package/dist/server/controllers/index.d.ts +5 -0
  41. package/{server → dist/server}/controllers/index.js +13 -15
  42. package/dist/server/controllers/log-indexing.d.ts +0 -0
  43. package/{server → dist/server}/controllers/log-indexing.js +10 -11
  44. package/dist/server/controllers/perform-indexing.d.ts +0 -0
  45. package/{server → dist/server}/controllers/perform-indexing.js +22 -28
  46. package/dist/server/controllers/perform-search.d.ts +1 -0
  47. package/dist/server/controllers/perform-search.js +29 -0
  48. package/dist/server/controllers/setup-info.d.ts +0 -0
  49. package/{server → dist/server}/controllers/setup-info.js +10 -14
  50. package/dist/server/destroy.d.ts +0 -0
  51. package/{server → dist/server}/destroy.js +4 -5
  52. package/dist/server/index.d.ts +10 -0
  53. package/{server → dist/server}/index.js +23 -25
  54. package/dist/server/middlewares/index.d.ts +0 -0
  55. package/{server → dist/server}/middlewares/index.js +2 -3
  56. package/dist/server/policies/index.d.ts +0 -0
  57. package/{server → dist/server}/policies/index.js +2 -3
  58. package/dist/server/register.d.ts +0 -0
  59. package/{server → dist/server}/register.js +4 -5
  60. package/dist/server/routes/configure-indexing.d.ts +0 -0
  61. package/dist/server/routes/configure-indexing.js +43 -0
  62. package/dist/server/routes/index.d.ts +5 -0
  63. package/{server → dist/server}/routes/index.js +13 -13
  64. package/dist/server/routes/perform-indexing.d.ts +0 -0
  65. package/dist/server/routes/perform-indexing.js +25 -0
  66. package/dist/server/routes/perform-search.d.ts +0 -0
  67. package/dist/server/routes/perform-search.js +15 -0
  68. package/dist/server/routes/run-log.d.ts +0 -0
  69. package/dist/server/routes/run-log.js +13 -0
  70. package/dist/server/routes/setup-info.d.ts +0 -0
  71. package/dist/server/routes/setup-info.js +13 -0
  72. package/dist/server/services/configure-indexing.d.ts +24 -0
  73. package/dist/server/services/configure-indexing.js +161 -0
  74. package/dist/server/services/es-interface.d.ts +4 -0
  75. package/dist/server/services/es-interface.js +161 -0
  76. package/dist/server/services/helper.d.ts +34 -0
  77. package/{server → dist/server}/services/helper.js +269 -305
  78. package/dist/server/services/index.d.ts +7 -0
  79. package/{server → dist/server}/services/index.js +17 -21
  80. package/dist/server/services/log-indexing.d.ts +0 -0
  81. package/{server → dist/server}/services/log-indexing.js +27 -26
  82. package/dist/server/services/perform-indexing.d.ts +0 -0
  83. package/{server → dist/server}/services/perform-indexing.js +147 -173
  84. package/dist/server/services/schedule-indexing.d.ts +0 -0
  85. package/{server → dist/server}/services/schedule-indexing.js +61 -65
  86. package/dist/server/services/transform-content.d.ts +2 -0
  87. package/{server → dist/server}/services/transform-content.js +21 -22
  88. package/dist/strapi-admin.d.ts +0 -0
  89. package/{strapi-admin.js → dist/strapi-admin.js} +2 -3
  90. package/dist/strapi-server.d.ts +0 -0
  91. package/{strapi-server.js → dist/strapi-server.js} +2 -3
  92. package/package.json +24 -3
  93. package/.prettierrc +0 -7
  94. package/.vscode/settings.json +0 -24
  95. package/admin/src/components/Initializer/index.js +0 -26
  96. package/admin/src/components/PluginIcon/index.js +0 -12
  97. package/admin/src/components/SubNavigation/index.js +0 -48
  98. package/admin/src/index.js +0 -63
  99. package/admin/src/pages/App/index.js +0 -29
  100. package/admin/src/pages/ConfigureCollection/index.js +0 -225
  101. package/admin/src/pages/ConfigureCollectionList/index.js +0 -266
  102. package/admin/src/pages/Homepage/index.js +0 -168
  103. package/admin/src/pages/ViewIndexingRunLog/index.js +0 -124
  104. package/admin/src/pluginId.js +0 -5
  105. package/admin/src/translations/en.json +0 -1
  106. package/admin/src/translations/fr.json +0 -1
  107. package/admin/src/utils/apiUrls.js +0 -14
  108. package/admin/src/utils/axiosInstance.js +0 -40
  109. package/admin/src/utils/getTrad.js +0 -5
  110. package/server/bootstrap.js +0 -142
  111. package/server/config/index.js +0 -6
  112. package/server/content-types/indexing-logs.js +0 -35
  113. package/server/content-types/tasks.js +0 -52
  114. package/server/controllers/configure-indexing.js +0 -66
  115. package/server/controllers/perform-search.js +0 -31
  116. package/server/routes/configure-indexing.js +0 -42
  117. package/server/routes/perform-indexing.js +0 -24
  118. package/server/routes/perform-search.js +0 -14
  119. package/server/routes/run-log.js +0 -12
  120. package/server/routes/setup-info.js +0 -12
  121. package/server/services/configure-indexing.js +0 -184
  122. package/server/services/es-interface.js +0 -187
  123. package/server/services/virtual-collections-registry.js +0 -445
  124. /package/{server/content-types/name-prefix.js → dist/server/bootstrap.d.ts} +0 -0
@@ -1,187 +0,0 @@
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
- });
@@ -1,445 +0,0 @@
1
- /**
2
- * Service to manage virtual collections for Elasticsearch indexing
3
- */
4
- module.exports = ({ strapi }) => {
5
- // Registry to hold all virtual collection definitions
6
- const virtualCollections = new Map();
7
-
8
- return {
9
- /**
10
- * Initialize the registry from the plugin configuration
11
- */
12
- initialize() {
13
- // Get the plugin configuration
14
- const pluginConfig = strapi.config.get('plugin.elasticsearch') || {};
15
- const virtualCollectionsConfig = pluginConfig.virtualCollections || [];
16
-
17
- // Register each virtual collection from the config
18
- virtualCollectionsConfig.forEach((config) => {
19
- this.register(config);
20
- });
21
-
22
- strapi.log.info(
23
- `Initialized ${virtualCollections.size} virtual collections for Elasticsearch indexing`
24
- );
25
- },
26
-
27
- /**
28
- * Register a new virtual collection for indexing
29
- * @param {Object} config - Configuration for the virtual collection
30
- * @param {string} config.indexName - Name of the index in Elasticsearch
31
- * @param {string} config.collectionName - Name identifier for the virtual collection
32
- * @param {Function} config.extractData - Function that returns data to be indexed (with pagination)
33
- * @param {Array<Object>} config.triggers - Array of collection triggers that should cause reindexing
34
- * @param {Function} config.mapToIndex - Function that maps extracted data to Elasticsearch document
35
- */
36
- register(config) {
37
- if (!config.indexName || typeof config.indexName !== 'string') {
38
- throw new Error('Virtual collection must have an indexName');
39
- }
40
-
41
- if (!config.collectionName || typeof config.collectionName !== 'string') {
42
- throw new Error('Virtual collection must have a collectionName');
43
- }
44
-
45
- if (typeof config.extractData !== 'function') {
46
- throw new Error('Virtual collection must have an extractData function');
47
- }
48
-
49
- if (!Array.isArray(config.triggers)) {
50
- throw new Error('Virtual collection must have triggers defined');
51
- }
52
-
53
- if (typeof config.mapToIndex !== 'function') {
54
- throw new Error('Virtual collection must have a mapToIndex function');
55
- }
56
-
57
- virtualCollections.set(config.collectionName, config);
58
- strapi.log.info(
59
- `Registered virtual collection for Elasticsearch: ${config.collectionName} -> ${config.indexName}`
60
- );
61
-
62
- return this;
63
- },
64
-
65
- /**
66
- * Get all registered virtual collections
67
- */
68
- getAll() {
69
- return Array.from(virtualCollections.values());
70
- },
71
-
72
- /**
73
- * Get a specific virtual collection by name
74
- */
75
- get(collectionName) {
76
- return virtualCollections.get(collectionName);
77
- },
78
-
79
- /**
80
- * Find virtual collections that should be triggered when a specific collection changes
81
- */
82
- findTriggersByCollection(collectionUID) {
83
- const results = [];
84
-
85
- virtualCollections.forEach((config) => {
86
- const hasTrigger = config.triggers.some((trigger) => trigger.collection === collectionUID);
87
-
88
- if (hasTrigger) {
89
- results.push(config);
90
- }
91
- });
92
-
93
- return results;
94
- },
95
- };
96
- };
97
-
98
- // path: ./src/extensions/strapi-plugin-elasticsearch/services/virtual-collections-indexer.js
99
-
100
- /**
101
- * Service to handle indexing of virtual collections
102
- */
103
- module.exports = ({ strapi }) => {
104
- const getElasticsearchService = () => strapi.plugin('elasticsearch').service('elasticsearch');
105
- const getRegistryService = () =>
106
- strapi.service('plugin::elasticsearch.virtual-collections-registry');
107
-
108
- return {
109
- /**
110
- * Initialize indexes for all registered virtual collections
111
- */
112
- async initializeIndexes() {
113
- const registry = getRegistryService();
114
- const collections = registry.getAll();
115
-
116
- for (const collection of collections) {
117
- await this.createIndexIfNotExists(collection.indexName);
118
- }
119
- },
120
-
121
- /**
122
- * Create an Elasticsearch index if it doesn't exist
123
- */
124
- async createIndexIfNotExists(indexName) {
125
- const esService = getElasticsearchService();
126
- const indexExists = await esService.indices.exists({ index: indexName });
127
-
128
- if (!indexExists) {
129
- await esService.indices.create({
130
- index: indexName,
131
- body: {
132
- settings: {
133
- analysis: {
134
- analyzer: {
135
- default: {
136
- type: 'standard',
137
- },
138
- },
139
- },
140
- },
141
- },
142
- });
143
-
144
- strapi.log.info(`Created Elasticsearch index: ${indexName}`);
145
- }
146
- },
147
-
148
- /**
149
- * Index a single item from a virtual collection
150
- */
151
- async indexItem(collectionName, itemId) {
152
- const registry = getRegistryService();
153
- const collection = registry.get(collectionName);
154
-
155
- if (!collection) {
156
- throw new Error(`Virtual collection not found: ${collectionName}`);
157
- }
158
-
159
- try {
160
- // Extract data using the collection's extractData
161
- // For a single item, we'll pass the ID as a filter parameter
162
- const results = await collection.extractData(0, { id: itemId });
163
-
164
- if (!results || !Array.isArray(results) || results.length === 0) {
165
- strapi.log.warn(`No data extracted for ${collectionName} with ID ${itemId}`);
166
- return null;
167
- }
168
-
169
- const data = results[0];
170
-
171
- // Map the data to the index format
172
- const indexData = collection.mapToIndex(data);
173
-
174
- // Index the data
175
- const esService = getElasticsearchService();
176
- await esService.index({
177
- index: collection.indexName,
178
- id: itemId,
179
- body: indexData,
180
- refresh: true,
181
- });
182
-
183
- strapi.log.debug(`Indexed virtual item: ${collectionName}:${itemId}`);
184
- return indexData;
185
- } catch (error) {
186
- strapi.log.error(`Error indexing ${collectionName}:${itemId}: ${error.message}`);
187
- throw error;
188
- }
189
- },
190
-
191
- /**
192
- * Reindex all items in a virtual collection
193
- */
194
- async reindexAll(collectionName) {
195
- const registry = getRegistryService();
196
- const collection = registry.get(collectionName);
197
-
198
- if (!collection) {
199
- throw new Error(`Virtual collection not found: ${collectionName}`);
200
- }
201
-
202
- try {
203
- // Create a new index with a timestamp
204
- const timestamp = Date.now();
205
- const tempIndexName = `${collection.indexName}_${timestamp}`;
206
-
207
- // Create the temporary index
208
- const esService = getElasticsearchService();
209
- await esService.indices.create({
210
- index: tempIndexName,
211
- body: {
212
- settings: {
213
- analysis: {
214
- analyzer: {
215
- default: {
216
- type: 'standard',
217
- },
218
- },
219
- },
220
- },
221
- },
222
- });
223
-
224
- // Pagination variables
225
- let page = 0;
226
- let hasMoreData = true;
227
- let totalIndexed = 0;
228
-
229
- // Process data in batches
230
- while (hasMoreData) {
231
- // Extract data for current page
232
- const pageData = await collection.extractData(page);
233
-
234
- if (!Array.isArray(pageData) || pageData.length === 0) {
235
- hasMoreData = false;
236
- break;
237
- }
238
-
239
- // Bulk index items in this page
240
- const operations = [];
241
-
242
- for (const item of pageData) {
243
- const indexData = collection.mapToIndex(item);
244
- operations.push({
245
- index: {
246
- _index: tempIndexName,
247
- _id: item.id,
248
- },
249
- });
250
- operations.push(indexData);
251
- }
252
-
253
- if (operations.length > 0) {
254
- await esService.bulk({ body: operations, refresh: true });
255
- }
256
-
257
- totalIndexed += pageData.length;
258
- page++;
259
- }
260
-
261
- // Swap the indices
262
- const oldIndex = collection.indexName;
263
- const indexExists = await esService.indices.exists({ index: oldIndex });
264
-
265
- if (indexExists) {
266
- // Create or update alias
267
- const aliasExists = await esService.indices.existsAlias({
268
- name: collection.indexName,
269
- });
270
-
271
- if (aliasExists) {
272
- // Update existing alias
273
- await esService.indices.updateAliases({
274
- body: {
275
- actions: [
276
- { remove: { index: '_all', alias: collection.indexName } },
277
- { add: { index: tempIndexName, alias: collection.indexName } },
278
- ],
279
- },
280
- });
281
- } else {
282
- // Create new alias
283
- await esService.indices.putAlias({
284
- index: tempIndexName,
285
- name: collection.indexName,
286
- });
287
- }
288
-
289
- // Delete old indices with this prefix
290
- const { body: indices } = await esService.indices.get({
291
- index: `${collection.indexName}_*`,
292
- });
293
-
294
- for (const indexName in indices) {
295
- if (indexName !== tempIndexName) {
296
- await esService.indices.delete({ index: indexName });
297
- }
298
- }
299
- } else {
300
- // Just add the alias if the original index doesn't exist
301
- await esService.indices.putAlias({
302
- index: tempIndexName,
303
- name: collection.indexName,
304
- });
305
- }
306
-
307
- strapi.log.info(
308
- `Reindexed ${totalIndexed} items for virtual collection: ${collectionName}`
309
- );
310
- return totalIndexed;
311
- } catch (error) {
312
- strapi.log.error(`Error reindexing ${collectionName}: ${error.message}`);
313
- throw error;
314
- }
315
- },
316
-
317
- /**
318
- * Handle a trigger event from a collection
319
- */
320
- async handleTriggerEvent(event) {
321
- const { model, result } = event;
322
- const registry = getRegistryService();
323
-
324
- // Find virtual collections that should be triggered by this model
325
- const affectedCollections = registry.findTriggersByCollection(model);
326
-
327
- for (const collection of affectedCollections) {
328
- // Find the specific trigger for this collection
329
- const trigger = collection.triggers.find((t) => t.collection === model);
330
-
331
- if (trigger && trigger.getIdsToReindex) {
332
- // Get IDs that need to be reindexed
333
- const idsToReindex = await trigger.getIdsToReindex(result);
334
-
335
- // Reindex each item
336
- for (const id of idsToReindex) {
337
- await this.indexItem(collection.collectionName, id);
338
- }
339
- }
340
- }
341
- },
342
-
343
- /**
344
- * Delete an item from a virtual collection index
345
- */
346
- async deleteItem(collectionName, itemId) {
347
- const registry = getRegistryService();
348
- const collection = registry.get(collectionName);
349
-
350
- if (!collection) {
351
- throw new Error(`Virtual collection not found: ${collectionName}`);
352
- }
353
-
354
- try {
355
- const esService = getElasticsearchService();
356
- await esService.delete({
357
- index: collection.indexName,
358
- id: itemId,
359
- refresh: true,
360
- });
361
-
362
- strapi.log.debug(`Deleted indexed item: ${collectionName}:${itemId}`);
363
- return true;
364
- } catch (error) {
365
- if (error.meta && error.meta.statusCode === 404) {
366
- // Item not found - that's fine
367
- return false;
368
- }
369
- strapi.log.error(`Error deleting ${collectionName}:${itemId}: ${error.message}`);
370
- throw error;
371
- }
372
- },
373
- };
374
- };
375
-
376
- // path: ./src/extensions/strapi-plugin-elasticsearch/strapi-server.js
377
-
378
- module.exports = (plugin) => {
379
- // Preserve original services, controllers, etc.
380
- const originalServices = plugin.services || {};
381
-
382
- // Add our new services
383
- plugin.services = {
384
- ...originalServices,
385
- 'virtual-collections-registry': require('./services/virtual-collections-registry'),
386
- 'virtual-collections-indexer': require('./services/virtual-collections-indexer'),
387
- };
388
-
389
- // Extend the bootstrap function
390
- const originalBootstrap = plugin.bootstrap;
391
- plugin.bootstrap = async ({ strapi }) => {
392
- // Call the original bootstrap if it exists
393
- if (originalBootstrap) {
394
- await originalBootstrap({ strapi });
395
- }
396
-
397
- // Initialize the registry from config
398
- strapi.service('plugin::elasticsearch.virtual-collections-registry').initialize();
399
-
400
- // Setup lifecycle hooks
401
- const registry = strapi.service('plugin::elasticsearch.virtual-collections-registry');
402
- const virtualCollections = registry.getAll();
403
-
404
- // Create a set of all collections that need hooks
405
- const collectionsToHook = new Set();
406
-
407
- virtualCollections.forEach((collection) => {
408
- collection.triggers.forEach((trigger) => {
409
- collectionsToHook.add(trigger.collection);
410
- });
411
- });
412
-
413
- // Setup hooks for each collection
414
- collectionsToHook.forEach((collectionUID) => {
415
- strapi.log.info(`Setting up Elasticsearch lifecycle hooks for collection: ${collectionUID}`);
416
-
417
- strapi.db.lifecycles.subscribe({
418
- models: [collectionUID],
419
-
420
- afterCreate: async (event) => {
421
- await strapi
422
- .service('plugin::elasticsearch.virtual-collections-indexer')
423
- .handleTriggerEvent(event);
424
- },
425
-
426
- afterUpdate: async (event) => {
427
- await strapi
428
- .service('plugin::elasticsearch.virtual-collections-indexer')
429
- .handleTriggerEvent(event);
430
- },
431
-
432
- afterDelete: async (event) => {
433
- await strapi
434
- .service('plugin::elasticsearch.virtual-collections-indexer')
435
- .handleTriggerEvent(event);
436
- },
437
- });
438
- });
439
-
440
- // Initialize indexes
441
- await strapi.service('plugin::elasticsearch.virtual-collections-indexer').initializeIndexes();
442
- };
443
-
444
- return plugin;
445
- };