@vegan-friendly/strapi-plugin-elasticsearch 0.2.9 → 0.3.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.
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vegan-friendly/strapi-plugin-elasticsearch",
3
- "version": "0.2.9",
3
+ "version": "0.3.0",
4
4
  "description": "A Strapi plugin to enable using Elasticsearch with Strapi CMS.",
5
5
  "homepage": "https://github.com/vegan-friendly/strapi-plugin-elasticsearch",
6
6
  "strapi": {
@@ -54,7 +54,7 @@
54
54
  }
55
55
  ],
56
56
  "engines": {
57
- "node": ">=16.0.0 <=20.x.x",
57
+ "node": ">=16.0.0",
58
58
  "npm": ">=6.0.0"
59
59
  },
60
60
  "license": "MIT",
@@ -34,6 +34,10 @@ declare const _default: {
34
34
  required: boolean;
35
35
  default: string;
36
36
  };
37
+ error_message: {
38
+ type: string;
39
+ required: boolean;
40
+ };
37
41
  full_site_indexing: {
38
42
  type: string;
39
43
  };
@@ -32,6 +32,10 @@ declare const _default: {
32
32
  required: boolean;
33
33
  default: string;
34
34
  };
35
+ error_message: {
36
+ type: string;
37
+ required: boolean;
38
+ };
35
39
  full_site_indexing: {
36
40
  type: string;
37
41
  };
@@ -30,10 +30,14 @@ exports.default = {
30
30
  },
31
31
  indexing_status: {
32
32
  type: 'enumeration',
33
- enum: ['to-be-done', 'in-progress', 'done'],
33
+ enum: ['to-be-done', 'in-progress', 'done', 'failed'],
34
34
  required: true,
35
35
  default: 'to-be-done',
36
36
  },
37
+ error_message: {
38
+ type: 'string',
39
+ required: false,
40
+ },
37
41
  full_site_indexing: {
38
42
  type: 'boolean',
39
43
  },
@@ -142,7 +142,7 @@ declare const _default: {
142
142
  recordId: any;
143
143
  }): Promise<void>;
144
144
  getItemsPendingToBeIndexed(): Promise<any>;
145
- markIndexingTaskComplete(recId: any): Promise<void>;
145
+ markIndexingTaskComplete(recId: any, error?: string | null): Promise<void>;
146
146
  markIndexingTaskInProgress(recId: any): Promise<void>;
147
147
  getFullIndexingInProgress(): Promise<any>;
148
148
  };
@@ -152,7 +152,7 @@ declare const _default: {
152
152
  indexer: ({ strapi }: {
153
153
  strapi: any;
154
154
  }) => {
155
- rebuildIndex(item?: any): Promise<boolean>;
155
+ rebuildIndex(task?: any): Promise<boolean>;
156
156
  indexCollection(collectionName: any, indexName?: string | null): Promise<number>;
157
157
  indexPendingData(): Promise<boolean>;
158
158
  };
@@ -215,6 +215,10 @@ declare const _default: {
215
215
  required: boolean;
216
216
  default: string;
217
217
  };
218
+ error_message: {
219
+ type: string;
220
+ required: boolean;
221
+ };
218
222
  full_site_indexing: {
219
223
  type: string;
220
224
  };
@@ -38,7 +38,7 @@ declare const _default: {
38
38
  recordId: any;
39
39
  }): Promise<void>;
40
40
  getItemsPendingToBeIndexed(): Promise<any>;
41
- markIndexingTaskComplete(recId: any): Promise<void>;
41
+ markIndexingTaskComplete(recId: any, error?: string | null): Promise<void>;
42
42
  markIndexingTaskInProgress(recId: any): Promise<void>;
43
43
  getFullIndexingInProgress(): Promise<any>;
44
44
  };
@@ -48,7 +48,7 @@ declare const _default: {
48
48
  indexer: ({ strapi }: {
49
49
  strapi: any;
50
50
  }) => {
51
- rebuildIndex(item?: any): Promise<boolean>;
51
+ rebuildIndex(task?: any): Promise<boolean>;
52
52
  indexCollection(collectionName: any, indexName?: string | null): Promise<number>;
53
53
  indexPendingData(): Promise<boolean>;
54
54
  };
@@ -1,7 +1,7 @@
1
1
  declare const _default: ({ strapi }: {
2
2
  strapi: any;
3
3
  }) => {
4
- rebuildIndex(item?: any): Promise<boolean>;
4
+ rebuildIndex(task?: any): Promise<boolean>;
5
5
  indexCollection(collectionName: any, indexName?: string | null): Promise<number>;
6
6
  indexPendingData(): Promise<boolean>;
7
7
  };
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = ({ strapi }) => ({
4
- async rebuildIndex(item = null) {
4
+ async rebuildIndex(task = null) {
5
5
  const helper = strapi.plugins['elasticsearch'].services.helper;
6
6
  const esInterface = strapi.plugins['elasticsearch'].services.esInterface;
7
7
  const scheduleIndexingService = strapi.plugins['elasticsearch'].services.scheduleIndexing;
@@ -9,6 +9,7 @@ exports.default = ({ strapi }) => ({
9
9
  const logIndexingService = strapi.plugins['elasticsearch'].services.logIndexing;
10
10
  const virtualCollectionsIndexer = strapi.plugins['elasticsearch'].services['virtualCollectionsIndexer'];
11
11
  const virtualCollectionsRegistry = strapi.plugins['elasticsearch'].services['virtualCollectionsRegistry'];
12
+ let taskError = null;
12
13
  try {
13
14
  console.log('strapi-plugin-elasticsearch : Request to rebuild the index received.');
14
15
  const fullIndexingInProgress = await scheduleIndexingService.getFullIndexingInProgress();
@@ -35,19 +36,19 @@ exports.default = ({ strapi }) => ({
35
36
  }
36
37
  //Step 2 : Index all the stuff on this new index
37
38
  console.log('strapi-plugin-elasticsearch : Starting to index all data into the new index.');
38
- if (item == null) {
39
- item = await scheduleIndexingService.addFullSiteIndexingTask();
39
+ if (task == null) {
40
+ task = await scheduleIndexingService.addFullSiteIndexingTask();
40
41
  }
41
- if (item?.id) {
42
- await scheduleIndexingService.markIndexingTaskInProgress(item.id);
42
+ if (task?.id) {
43
+ await scheduleIndexingService.markIndexingTaskInProgress(task.id);
43
44
  let entitiesIndexed = 0;
44
45
  for (let r = 0; r < cols.length; r++) {
45
46
  entitiesIndexed += await this.indexCollection(cols[r], newIndexName);
46
47
  }
47
48
  // Indexing the virtual collections
48
- console.log('strapi-plugin-elasticsearch : Starting to index virtual collections. task id : ', item.id);
49
+ console.log('strapi-plugin-elasticsearch : Starting to index virtual collections. task id : ', task.id);
49
50
  const virtualEntriesIndexed = await virtualCollectionsIndexer.reindexAll(newIndexName);
50
- await scheduleIndexingService.markIndexingTaskComplete(item.id);
51
+ await scheduleIndexingService.markIndexingTaskComplete(task.id);
51
52
  console.log('strapi-plugin-elasticsearch : Indexing of data into the new index complete.');
52
53
  //Step 4 : Move the alias to this new index
53
54
  await esInterface.attachAliasToIndex(newIndexName);
@@ -64,14 +65,15 @@ exports.default = ({ strapi }) => ({
64
65
  }
65
66
  }
66
67
  catch (err) {
68
+ taskError = err.message || String(err);
67
69
  console.log('strapi-plugin-elasticsearch : searchController : An error was encountered while re-indexing.');
68
70
  console.log(err);
69
71
  await logIndexingService.recordIndexingFail(err);
70
72
  throw err;
71
73
  }
72
74
  finally {
73
- if (item?.id) {
74
- await scheduleIndexingService.markIndexingTaskComplete(item.id);
75
+ if (task?.id) {
76
+ await scheduleIndexingService.markIndexingTaskComplete(task.id, taskError);
75
77
  }
76
78
  }
77
79
  },
@@ -14,7 +14,7 @@ declare const _default: ({ strapi }: {
14
14
  recordId: any;
15
15
  }): Promise<void>;
16
16
  getItemsPendingToBeIndexed(): Promise<any>;
17
- markIndexingTaskComplete(recId: any): Promise<void>;
17
+ markIndexingTaskComplete(recId: any, error?: string | null): Promise<void>;
18
18
  markIndexingTaskInProgress(recId: any): Promise<void>;
19
19
  getFullIndexingInProgress(): Promise<any>;
20
20
  };
@@ -52,10 +52,12 @@ exports.default = ({ strapi }) => ({
52
52
  });
53
53
  return entries;
54
54
  },
55
- async markIndexingTaskComplete(recId) {
55
+ async markIndexingTaskComplete(recId, error = null) {
56
+ const status = error ? 'failed' : 'done';
56
57
  const entries = await strapi.entityService.update('plugin::elasticsearch.task', recId, {
57
58
  data: {
58
- indexing_status: 'done',
59
+ indexing_status: status,
60
+ error_message: error,
59
61
  },
60
62
  });
61
63
  },
@@ -24,7 +24,9 @@ exports.default = ({ strapi }) => {
24
24
  try {
25
25
  const results = await collection.extractByIds([itemId]);
26
26
  if (!results || !Array.isArray(results) || results.length === 0) {
27
- strapi.log.warn(`No data extracted for ${collectionName} with ID ${itemId}`);
27
+ // item does not exit - delete it from index
28
+ await this.deleteItem(collectionName, itemId);
29
+ strapi.log.debug(`Deleted virtual item: ${collectionName}:${itemId}`);
28
30
  return null;
29
31
  }
30
32
  const itemData = results[0];
@@ -58,9 +60,11 @@ exports.default = ({ strapi }) => {
58
60
  async reindex(collection) {
59
61
  const collectionName = collection.collectionName;
60
62
  const privateIndexAlias = collection.indexAlias;
63
+ const pageSize = 100;
61
64
  const helper = getHelperService();
62
65
  let timestamp = Date.now();
63
66
  let indexName = '';
67
+ let errors = 0;
64
68
  try {
65
69
  const esInterface = getElasticsearchService();
66
70
  if (privateIndexAlias) {
@@ -75,7 +79,16 @@ exports.default = ({ strapi }) => {
75
79
  let totalIndexed = 0;
76
80
  const pageLimit = 10000;
77
81
  while (page <= pageLimit) {
78
- const pageData = await collection.extractData(page);
82
+ let pageData;
83
+ try {
84
+ pageData = await collection.extractData(page, pageSize);
85
+ }
86
+ catch (error) {
87
+ strapi.log.error(`Error extracting data for page ${page} of ${collectionName}: ${error.message}`);
88
+ errors += pageSize;
89
+ page++;
90
+ continue;
91
+ }
79
92
  strapi.log.debug(`Extracted ${pageData.length} items from ${collectionName} for page ${page}`);
80
93
  if (!Array.isArray(pageData) || pageData.length === 0) {
81
94
  break;
@@ -97,12 +110,18 @@ exports.default = ({ strapi }) => {
97
110
  operations.push({ itemId, itemData });
98
111
  }
99
112
  if (operations.length > 0) {
100
- await Promise.all(operations.map((op) => esInterface.indexDataToSpecificIndex(op, indexName)));
113
+ await Promise.all(operations.map((op) => esInterface.indexDataToSpecificIndex(op, indexName).catch((err) => {
114
+ strapi.log.error(`Failed to index item ${op.itemId} in ${collectionName}: ${err}`);
115
+ errors++;
116
+ })));
101
117
  }
102
118
  totalIndexed += pageData.length;
103
119
  prevPageData = pageData;
104
120
  page++;
105
121
  }
122
+ if (errors > 0) {
123
+ throw new Error(`Failed to index ${errors} of ${totalIndexed} items for virtual collection ${collectionName}. Errors were logged. Alias was not updated. took ${(0, humanize_duration_1.default)(Date.now() - timestamp)}`);
124
+ }
106
125
  strapi.log.info(`Reindexed ${totalIndexed} items for virtual collection: ${collectionName}. took ${(0, humanize_duration_1.default)(Date.now() - timestamp)}. now updating alias.`);
107
126
  if (privateIndexAlias) {
108
127
  timestamp = Date.now();
@@ -138,14 +157,7 @@ exports.default = ({ strapi }) => {
138
157
  const idsToReindex = await trigger.getIdsToReindex(result);
139
158
  // Reindex each item
140
159
  for (const id of idsToReindex) {
141
- const isDelete = event.action?.toLowerCase()?.includes('delete') && trigger.alsoTriggerDelete && id === result.id;
142
- if (isDelete) {
143
- //delete the item from the index, if the item being delete is the one being reindexed
144
- await this.deleteItem(collection.collectionName, id);
145
- }
146
- else {
147
- await this.indexItem(collection.collectionName, id);
148
- }
160
+ await this.indexItem(collection.collectionName, id);
149
161
  }
150
162
  }
151
163
  },
@@ -47,7 +47,6 @@ const configSchema = yup.object({
47
47
  .of(yup.object({
48
48
  collection: yup.string().required(),
49
49
  getIdsToReindex: isFunction().required(),
50
- alsoTriggerDelete: yup.boolean().default(false),
51
50
  }))
52
51
  .default([]),
53
52
  mappings: yup.object().optional(),
@@ -45,11 +45,6 @@ export type VirtualCollectionConfig = {
45
45
  * @returns ids of the items to be reindexed.
46
46
  */
47
47
  getIdsToReindex: GetIdsToIndexFunction;
48
- /**
49
- * if true, and the trigger is a delete event, the item of the virtual collection will be deleted as well if the id returned from getIdsToReindex match.
50
- * defaults to false.
51
- */
52
- alsoTriggerDelete?: boolean;
53
48
  }>;
54
49
  /**
55
50
  * Optional schema to be sent to Elasticsearch when creating the index.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vegan-friendly/strapi-plugin-elasticsearch",
3
- "version": "0.2.9",
3
+ "version": "0.3.0",
4
4
  "description": "A Strapi plugin to enable using Elasticsearch with Strapi CMS.",
5
5
  "homepage": "https://github.com/vegan-friendly/strapi-plugin-elasticsearch",
6
6
  "strapi": {
@@ -54,7 +54,7 @@
54
54
  }
55
55
  ],
56
56
  "engines": {
57
- "node": ">=16.0.0 <=20.x.x",
57
+ "node": ">=16.0.0",
58
58
  "npm": ">=6.0.0"
59
59
  },
60
60
  "license": "MIT",
@@ -64,4 +64,4 @@
64
64
  "ts-node": "^10.9.2",
65
65
  "typescript": "^5.8.3"
66
66
  }
67
- }
67
+ }