@vegan-friendly/strapi-plugin-elasticsearch 0.1.0 → 0.2.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/admin/src/utils/axiosInstance.js +2 -2
- package/dist/package.json +3 -2
- package/dist/server/bootstrap.js +28 -2
- package/dist/server/index.d.ts +9 -25
- package/dist/server/index.js +15 -0
- package/dist/server/services/configure-indexing.js +2 -2
- package/dist/server/services/es-interface.d.ts +2 -24
- package/dist/server/services/es-interface.js +6 -6
- package/dist/server/services/helper.js +45 -49
- package/dist/server/services/index.d.ts +8 -25
- package/dist/server/services/index.js +4 -0
- package/dist/server/services/perform-indexing.d.ts +1 -1
- package/dist/server/services/perform-indexing.js +6 -1
- package/dist/server/services/virtual-collections-indexer.d.ts +8 -0
- package/dist/server/services/virtual-collections-indexer.js +142 -0
- package/dist/server/services/virtual-collections-registry.d.ts +8 -0
- package/dist/server/services/virtual-collections-registry.js +32 -0
- package/dist/server/types/esInterface.type.d.ts +70 -0
- package/dist/server/types/esInterface.type.js +2 -0
- package/dist/server/types/index.d.ts +2 -0
- package/dist/server/types/index.js +18 -0
- package/dist/server/types/virtual-collections.d.ts +30 -0
- package/dist/server/types/virtual-collections.js +2 -0
- package/dist/server/types/virtual-collections.type.d.ts +57 -0
- package/dist/server/types/virtual-collections.type.js +2 -0
- package/package.json +3 -2
@@ -13,8 +13,8 @@ const instance = axios_1.default.create({
|
|
13
13
|
});
|
14
14
|
instance.interceptors.request.use(async (config) => {
|
15
15
|
config.headers = {
|
16
|
-
Authorization: `Bearer ${helper_plugin_1.auth.getToken()}`,
|
17
|
-
Accept: 'application/json',
|
16
|
+
'Authorization': `Bearer ${helper_plugin_1.auth.getToken()}`,
|
17
|
+
'Accept': 'application/json',
|
18
18
|
'Content-Type': 'application/json',
|
19
19
|
};
|
20
20
|
return config;
|
package/dist/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vegan-friendly/strapi-plugin-elasticsearch",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.2.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": {
|
@@ -37,7 +37,8 @@
|
|
37
37
|
"dependencies": {
|
38
38
|
"@elastic/elasticsearch": "^8.9.0",
|
39
39
|
"@strapi/design-system": "^1.19.0",
|
40
|
-
"markdown-to-txt": "^2.0.1"
|
40
|
+
"markdown-to-txt": "^2.0.1",
|
41
|
+
"pretty-ms": "^9.2.0"
|
41
42
|
},
|
42
43
|
"peerDependencies": {
|
43
44
|
"@strapi/strapi": "^4.0.0"
|
package/dist/server/bootstrap.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
'use strict';
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
console.log('strapi-plugin-elasticsearch : 00 Initializing strapi-plugin-elasticsearch plugin.');
|
4
3
|
exports.default = async ({ strapi }) => {
|
5
4
|
const pluginConfig = await strapi.config.get('plugin.elasticsearch');
|
6
5
|
const configureIndexingService = strapi.plugins['elasticsearch'].services.configureIndexing;
|
@@ -8,8 +7,8 @@ exports.default = async ({ strapi }) => {
|
|
8
7
|
const esInterface = strapi.plugins['elasticsearch'].services.esInterface;
|
9
8
|
const indexer = strapi.plugins['elasticsearch'].services.indexer;
|
10
9
|
const helper = strapi.plugins['elasticsearch'].services.helper;
|
10
|
+
const virtualCollectionIndexer = strapi.plugins['elasticsearch'].services.virtualCollectionsIndexer;
|
11
11
|
try {
|
12
|
-
console.log('strapi-plugin-elasticsearch 1: Initializing strapi-plugin-elasticsearch plugin.');
|
13
12
|
await configureIndexingService.initializeStrapiElasticsearch();
|
14
13
|
if (!Object.keys(pluginConfig).includes('indexingCronSchedule'))
|
15
14
|
console.warn('The plugin strapi-plugin-elasticsearch is enabled but the indexingCronSchedule is not configured.');
|
@@ -116,6 +115,33 @@ exports.default = async ({ strapi }) => {
|
|
116
115
|
}
|
117
116
|
}
|
118
117
|
});
|
118
|
+
// Register virtual collections //
|
119
|
+
const registry = strapi.service('plugin::elasticsearch.virtualCollectionsRegistry');
|
120
|
+
// Setup lifecycle hooks
|
121
|
+
const virtualCollections = registry.getAll();
|
122
|
+
// Create a set of all collections that need hooks
|
123
|
+
const collectionsToHook = new Set();
|
124
|
+
virtualCollections.forEach((collection) => {
|
125
|
+
collection.triggers.forEach((trigger) => {
|
126
|
+
collectionsToHook.add(trigger.collection);
|
127
|
+
});
|
128
|
+
});
|
129
|
+
// Setup hooks for each collection
|
130
|
+
collectionsToHook.forEach((collectionUID) => {
|
131
|
+
strapi.log.info(`Setting up Elasticsearch lifecycle hooks for collection: ${collectionUID}`);
|
132
|
+
strapi.db.lifecycles.subscribe({
|
133
|
+
models: [collectionUID],
|
134
|
+
afterCreate: async (event) => {
|
135
|
+
await virtualCollectionIndexer.handleTriggerEvent(event);
|
136
|
+
},
|
137
|
+
afterUpdate: async (event) => {
|
138
|
+
await virtualCollectionIndexer.handleTriggerEvent(event);
|
139
|
+
},
|
140
|
+
afterDelete: async (event) => {
|
141
|
+
await virtualCollectionIndexer.handleTriggerEvent(event);
|
142
|
+
},
|
143
|
+
});
|
144
|
+
});
|
119
145
|
configureIndexingService.markInitialized();
|
120
146
|
}
|
121
147
|
catch (err) {
|
package/dist/server/index.d.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
export * from './types';
|
1
2
|
declare const _default: {
|
2
3
|
register: ({ strapi }: {
|
3
4
|
strapi: any;
|
@@ -145,34 +146,11 @@ declare const _default: {
|
|
145
146
|
};
|
146
147
|
esInterface: ({ strapi }: {
|
147
148
|
strapi: any;
|
148
|
-
}) =>
|
149
|
-
initializeSearchEngine({ host, uname, password, cert }: {
|
150
|
-
host: any;
|
151
|
-
uname: any;
|
152
|
-
password: any;
|
153
|
-
cert: any;
|
154
|
-
}): Promise<void>;
|
155
|
-
createIndex(indexName: any): Promise<void>;
|
156
|
-
deleteIndex(indexName: any): Promise<void>;
|
157
|
-
attachAliasToIndex(indexName: any): Promise<void>;
|
158
|
-
checkESConnection(): Promise<boolean>;
|
159
|
-
indexDataToSpecificIndex({ itemId, itemData }: {
|
160
|
-
itemId: any;
|
161
|
-
itemData: any;
|
162
|
-
}, iName: any): Promise<void>;
|
163
|
-
indexData({ itemId, itemData }: {
|
164
|
-
itemId: any;
|
165
|
-
itemData: any;
|
166
|
-
}): Promise<void>;
|
167
|
-
removeItemFromIndex({ itemId }: {
|
168
|
-
itemId: any;
|
169
|
-
}): Promise<void>;
|
170
|
-
searchData(searchQuery: any): Promise<any>;
|
171
|
-
};
|
149
|
+
}) => import("./types").EsInterfaceService;
|
172
150
|
indexer: ({ strapi }: {
|
173
151
|
strapi: any;
|
174
152
|
}) => {
|
175
|
-
rebuildIndex(): Promise<boolean
|
153
|
+
rebuildIndex(): Promise<boolean>;
|
176
154
|
indexCollection(collectionName: any, indexName?: null): Promise<boolean>;
|
177
155
|
indexPendingData(): Promise<boolean>;
|
178
156
|
};
|
@@ -223,6 +201,12 @@ declare const _default: {
|
|
223
201
|
from: any;
|
224
202
|
}): any;
|
225
203
|
};
|
204
|
+
virtualCollectionsRegistry: ({ strapi }: {
|
205
|
+
strapi: any;
|
206
|
+
}) => import("./types").VirtualCollectionsRegistryService;
|
207
|
+
virtualCollectionsIndexer: ({ strapi }: {
|
208
|
+
strapi: any;
|
209
|
+
}) => import("./types").VirtualCollectionsIndexerService;
|
226
210
|
};
|
227
211
|
contentTypes: {
|
228
212
|
task: {
|
package/dist/server/index.js
CHANGED
@@ -1,4 +1,18 @@
|
|
1
1
|
'use strict';
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
2
16
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
18
|
};
|
@@ -13,6 +27,7 @@ const routes_1 = __importDefault(require("./routes"));
|
|
13
27
|
const middlewares_1 = __importDefault(require("./middlewares"));
|
14
28
|
const policies_1 = __importDefault(require("./policies"));
|
15
29
|
const services_1 = __importDefault(require("./services"));
|
30
|
+
__exportStar(require("./types"), exports);
|
16
31
|
exports.default = {
|
17
32
|
register: register_1.default,
|
18
33
|
bootstrap: bootstrap_1.default,
|
@@ -124,7 +124,7 @@ exports.default = ({ strapi }) => ({
|
|
124
124
|
},
|
125
125
|
async importContentConfig({ config }) {
|
126
126
|
const pluginStore = getPluginStore();
|
127
|
-
const settings = await pluginStore.get({ key: 'configsettings' });
|
127
|
+
const settings = (await pluginStore.get({ key: 'configsettings' }));
|
128
128
|
if (settings) {
|
129
129
|
const objSettings = JSON.parse(settings);
|
130
130
|
objSettings['contentConfig'] = JSON.parse(config);
|
@@ -144,7 +144,7 @@ exports.default = ({ strapi }) => ({
|
|
144
144
|
},
|
145
145
|
async setContentConfig({ collection, config }) {
|
146
146
|
const pluginStore = getPluginStore();
|
147
|
-
const settings = await pluginStore.get({ key: 'configsettings' });
|
147
|
+
const settings = (await pluginStore.get({ key: 'configsettings' }));
|
148
148
|
if (settings) {
|
149
149
|
const objSettings = JSON.parse(settings);
|
150
150
|
if (Object.keys(objSettings).includes('contentConfig')) {
|
@@ -1,27 +1,5 @@
|
|
1
|
+
import { EsInterfaceService } from '../types';
|
1
2
|
declare const _default: ({ strapi }: {
|
2
3
|
strapi: any;
|
3
|
-
}) =>
|
4
|
-
initializeSearchEngine({ host, uname, password, cert }: {
|
5
|
-
host: any;
|
6
|
-
uname: any;
|
7
|
-
password: any;
|
8
|
-
cert: any;
|
9
|
-
}): Promise<void>;
|
10
|
-
createIndex(indexName: any): Promise<void>;
|
11
|
-
deleteIndex(indexName: any): Promise<void>;
|
12
|
-
attachAliasToIndex(indexName: any): Promise<void>;
|
13
|
-
checkESConnection(): Promise<boolean>;
|
14
|
-
indexDataToSpecificIndex({ itemId, itemData }: {
|
15
|
-
itemId: any;
|
16
|
-
itemData: any;
|
17
|
-
}, iName: any): Promise<void>;
|
18
|
-
indexData({ itemId, itemData }: {
|
19
|
-
itemId: any;
|
20
|
-
itemData: any;
|
21
|
-
}): Promise<void>;
|
22
|
-
removeItemFromIndex({ itemId }: {
|
23
|
-
itemId: any;
|
24
|
-
}): Promise<void>;
|
25
|
-
searchData(searchQuery: any): Promise<any>;
|
26
|
-
};
|
4
|
+
}) => EsInterfaceService;
|
27
5
|
export default _default;
|
@@ -18,7 +18,7 @@ exports.default = ({ strapi }) => ({
|
|
18
18
|
});
|
19
19
|
}
|
20
20
|
catch (err) {
|
21
|
-
if (err
|
21
|
+
if (err?.message?.includes('ECONNREFUSED')) {
|
22
22
|
console.error('strapi-plugin-elasticsearch : Connection to ElasticSearch at ', host, ' refused.');
|
23
23
|
console.error(err);
|
24
24
|
}
|
@@ -40,7 +40,7 @@ exports.default = ({ strapi }) => ({
|
|
40
40
|
}
|
41
41
|
}
|
42
42
|
catch (err) {
|
43
|
-
if (err
|
43
|
+
if (err?.message?.includes('ECONNREFUSED')) {
|
44
44
|
console.log('strapi-plugin-elasticsearch : Error while creating index - connection to ElasticSearch refused.');
|
45
45
|
console.log(err);
|
46
46
|
}
|
@@ -57,7 +57,7 @@ exports.default = ({ strapi }) => ({
|
|
57
57
|
});
|
58
58
|
}
|
59
59
|
catch (err) {
|
60
|
-
if (err
|
60
|
+
if (err?.message?.includes('ECONNREFUSED')) {
|
61
61
|
console.log('strapi-plugin-elasticsearch : Connection to ElasticSearch refused.');
|
62
62
|
console.log(err);
|
63
63
|
}
|
@@ -83,7 +83,7 @@ exports.default = ({ strapi }) => ({
|
|
83
83
|
await client.indices.putAlias({ index: indexName, name: aliasName });
|
84
84
|
}
|
85
85
|
catch (err) {
|
86
|
-
if (err
|
86
|
+
if (err?.message?.includes('ECONNREFUSED')) {
|
87
87
|
console.log('strapi-plugin-elasticsearch : Attaching alias to the index - Connection to ElasticSearch refused.');
|
88
88
|
console.log(err);
|
89
89
|
}
|
@@ -97,7 +97,7 @@ exports.default = ({ strapi }) => ({
|
|
97
97
|
if (!client)
|
98
98
|
return false;
|
99
99
|
try {
|
100
|
-
await client
|
100
|
+
await client?.ping();
|
101
101
|
return true;
|
102
102
|
}
|
103
103
|
catch (error) {
|
@@ -135,7 +135,7 @@ exports.default = ({ strapi }) => ({
|
|
135
135
|
await client.indices.refresh({ index: pluginConfig.indexAliasName });
|
136
136
|
}
|
137
137
|
catch (err) {
|
138
|
-
if (err
|
138
|
+
if (err?.meta?.statusCode === 404)
|
139
139
|
console.error('strapi-plugin-elasticsearch : The entry to be removed from the index already does not exist.');
|
140
140
|
else {
|
141
141
|
console.error('strapi-plugin-elasticsearch : Error encountered while removing indexed data from ElasticSearch.');
|
@@ -25,34 +25,35 @@ const getFullPopulateObject = (modelUid, maxDepth = 20, ignore) => {
|
|
25
25
|
if (maxDepth <= 1) {
|
26
26
|
return true;
|
27
27
|
}
|
28
|
-
if (modelUid ===
|
28
|
+
if (modelUid === 'admin::user' && skipCreatorFields) {
|
29
29
|
return undefined;
|
30
30
|
}
|
31
31
|
const populate = {};
|
32
32
|
const model = strapi.getModel(modelUid);
|
33
33
|
if (ignore && !ignore.includes(model.collectionName))
|
34
34
|
ignore.push(model.collectionName);
|
35
|
-
for (const [key,
|
35
|
+
for (const [key, valueRaw] of Object.entries(getModelPopulationAttributes(model))) {
|
36
36
|
if (ignore?.includes(key))
|
37
37
|
continue;
|
38
|
+
const value = valueRaw;
|
38
39
|
if (value) {
|
39
|
-
if (value.type ===
|
40
|
+
if (value.type === 'component') {
|
40
41
|
populate[key] = getFullPopulateObject(value.component, maxDepth - 1);
|
41
42
|
}
|
42
|
-
else if (value.type ===
|
43
|
-
const dynamicPopulate = value.components
|
43
|
+
else if (value.type === 'dynamiczone') {
|
44
|
+
const dynamicPopulate = value.components?.reduce((prev, cur) => {
|
44
45
|
const curPopulate = getFullPopulateObject(cur, maxDepth - 1);
|
45
46
|
return curPopulate === true ? prev : (0, fp_1.merge)(prev, curPopulate);
|
46
47
|
}, {});
|
47
48
|
populate[key] = (0, fp_1.isEmpty)(dynamicPopulate) ? true : dynamicPopulate;
|
48
49
|
}
|
49
|
-
else if (value.type ===
|
50
|
-
const relationPopulate = getFullPopulateObject(value.target,
|
50
|
+
else if (value.type === 'relation') {
|
51
|
+
const relationPopulate = getFullPopulateObject(value.target, key === 'localizations' && maxDepth > 2 ? 1 : maxDepth - 1, ignore);
|
51
52
|
if (relationPopulate) {
|
52
53
|
populate[key] = relationPopulate;
|
53
54
|
}
|
54
55
|
}
|
55
|
-
else if (value.type ===
|
56
|
+
else if (value.type === 'media') {
|
56
57
|
populate[key] = true;
|
57
58
|
}
|
58
59
|
}
|
@@ -108,52 +109,56 @@ function extractSubfieldData({ config, data }) {
|
|
108
109
|
if (Object.keys(extractItem).includes('__component')) {
|
109
110
|
if (conf.component === extractItem.__component &&
|
110
111
|
!Object.keys(conf).includes('subfields') &&
|
111
|
-
typeof extractItem[conf['field']] !==
|
112
|
+
typeof extractItem[conf['field']] !== 'undefined' &&
|
112
113
|
extractItem[conf['field']]) {
|
113
114
|
let val = extractItem[conf['field']];
|
114
|
-
if (Object.keys(conf).includes('transform')
|
115
|
-
&& conf['transform'] === 'markdown')
|
115
|
+
if (Object.keys(conf).includes('transform') && conf['transform'] === 'markdown')
|
116
116
|
val = transform_content_1.default.transform({ content: val, from: 'markdown' });
|
117
117
|
returnData = returnData + '\n' + val;
|
118
118
|
}
|
119
|
-
else if (conf.component === extractItem.__component &&
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
119
|
+
else if (conf.component === extractItem.__component && Object.keys(conf).includes('subfields')) {
|
120
|
+
returnData =
|
121
|
+
returnData +
|
122
|
+
'\n' +
|
123
|
+
extractSubfieldData({
|
124
|
+
config: conf['subfields'],
|
125
|
+
data: extractItem[conf['field']],
|
126
|
+
});
|
124
127
|
}
|
125
128
|
}
|
126
129
|
else {
|
127
|
-
if (!Object.keys(conf).includes('subfields') &&
|
128
|
-
typeof extractItem[conf['field']] !== "undefined" &&
|
129
|
-
extractItem[conf['field']]) {
|
130
|
+
if (!Object.keys(conf).includes('subfields') && typeof extractItem[conf['field']] !== 'undefined' && extractItem[conf['field']]) {
|
130
131
|
let val = extractItem[conf['field']];
|
131
|
-
if (Object.keys(conf).includes('transform')
|
132
|
-
&& conf['transform'] === 'markdown')
|
132
|
+
if (Object.keys(conf).includes('transform') && conf['transform'] === 'markdown')
|
133
133
|
val = transform_content_1.default.transform({ content: val, from: 'markdown' });
|
134
134
|
returnData = returnData + '\n' + val;
|
135
135
|
}
|
136
136
|
else if (Object.keys(conf).includes('subfields')) {
|
137
|
-
returnData =
|
138
|
-
|
139
|
-
|
137
|
+
returnData =
|
138
|
+
returnData +
|
139
|
+
'\n' +
|
140
|
+
extractSubfieldData({
|
141
|
+
config: conf['subfields'],
|
142
|
+
data: extractItem[conf['field']],
|
143
|
+
});
|
140
144
|
}
|
141
145
|
}
|
142
146
|
}
|
143
147
|
}
|
144
|
-
}
|
145
|
-
else
|
146
|
-
{
|
148
|
+
} //for single component as a field
|
149
|
+
else {
|
147
150
|
for (let s = 0; s < config.length; s++) {
|
148
151
|
const conf = config[s];
|
149
|
-
if (!Object.keys(conf).includes('subfields') &&
|
150
|
-
typeof data[conf['field']] !== "undefined" &&
|
151
|
-
data[conf['field']])
|
152
|
+
if (!Object.keys(conf).includes('subfields') && typeof data[conf['field']] !== 'undefined' && data[conf['field']])
|
152
153
|
returnData = returnData + '\n' + data[conf['field']];
|
153
154
|
else if (Object.keys(conf).includes('subfields')) {
|
154
|
-
returnData =
|
155
|
-
|
156
|
-
|
155
|
+
returnData =
|
156
|
+
returnData +
|
157
|
+
'\n' +
|
158
|
+
extractSubfieldData({
|
159
|
+
config: conf['subfields'],
|
160
|
+
data: data[conf['field']],
|
161
|
+
});
|
157
162
|
}
|
158
163
|
}
|
159
164
|
}
|
@@ -164,20 +169,12 @@ exports.default = ({ strapi }) => ({
|
|
164
169
|
const configureService = strapi.plugins['elasticsearch'].services.configureIndexing;
|
165
170
|
const esInterface = strapi.plugins['elasticsearch'].services.esInterface;
|
166
171
|
const pluginConfig = await strapi.config.get('plugin.elasticsearch');
|
167
|
-
const connected = pluginConfig.searchConnector && pluginConfig.searchConnector.host
|
168
|
-
? await esInterface.checkESConnection()
|
169
|
-
: false;
|
172
|
+
const connected = pluginConfig.searchConnector && pluginConfig.searchConnector.host ? await esInterface.checkESConnection() : false;
|
170
173
|
return {
|
171
174
|
indexingCronSchedule: pluginConfig.indexingCronSchedule || 'Not configured',
|
172
|
-
elasticHost: pluginConfig.searchConnector
|
173
|
-
|
174
|
-
|
175
|
-
elasticUserName: pluginConfig.searchConnector
|
176
|
-
? pluginConfig.searchConnector.username || 'Not configured'
|
177
|
-
: 'Not configured',
|
178
|
-
elasticCertificate: pluginConfig.searchConnector
|
179
|
-
? pluginConfig.searchConnector.certificate || 'Not configured'
|
180
|
-
: 'Not configured',
|
175
|
+
elasticHost: pluginConfig.searchConnector ? pluginConfig.searchConnector.host || 'Not configured' : 'Not configured',
|
176
|
+
elasticUserName: pluginConfig.searchConnector ? pluginConfig.searchConnector.username || 'Not configured' : 'Not configured',
|
177
|
+
elasticCertificate: pluginConfig.searchConnector ? pluginConfig.searchConnector.certificate || 'Not configured' : 'Not configured',
|
181
178
|
elasticIndexAlias: pluginConfig.indexAliasName || 'Not configured',
|
182
179
|
connected: connected,
|
183
180
|
initialized: configureService.isInitialized(),
|
@@ -197,7 +194,7 @@ exports.default = ({ strapi }) => ({
|
|
197
194
|
},
|
198
195
|
async getCurrentIndexName() {
|
199
196
|
const pluginStore = getPluginStore();
|
200
|
-
const settings = await pluginStore.get({ key: 'configsettings' });
|
197
|
+
const settings = (await pluginStore.get({ key: 'configsettings' }));
|
201
198
|
let indexName = 'strapi-plugin-elasticsearch-index_000001';
|
202
199
|
if (settings) {
|
203
200
|
const objSettings = JSON.parse(settings);
|
@@ -215,7 +212,7 @@ exports.default = ({ strapi }) => ({
|
|
215
212
|
},
|
216
213
|
async storeCurrentIndexName(indexName) {
|
217
214
|
const pluginStore = getPluginStore();
|
218
|
-
const settings = await pluginStore.get({ key: 'configsettings' });
|
215
|
+
const settings = (await pluginStore.get({ key: 'configsettings' }));
|
219
216
|
if (settings) {
|
220
217
|
const objSettings = JSON.parse(settings);
|
221
218
|
objSettings['indexConfig'] = { name: indexName };
|
@@ -262,8 +259,7 @@ exports.default = ({ strapi }) => ({
|
|
262
259
|
}
|
263
260
|
else {
|
264
261
|
val = data[fti[k]];
|
265
|
-
if (Object.keys(fieldConfig).includes('transform') &&
|
266
|
-
fieldConfig['transform'] === 'markdown')
|
262
|
+
if (Object.keys(fieldConfig).includes('transform') && fieldConfig['transform'] === 'markdown')
|
267
263
|
val = transform_content_1.default.transform({ content: val, from: 'markdown' });
|
268
264
|
}
|
269
265
|
if (Object.keys(fieldConfig).includes('searchFieldName'))
|
@@ -42,34 +42,11 @@ declare const _default: {
|
|
42
42
|
};
|
43
43
|
esInterface: ({ strapi }: {
|
44
44
|
strapi: any;
|
45
|
-
}) =>
|
46
|
-
initializeSearchEngine({ host, uname, password, cert }: {
|
47
|
-
host: any;
|
48
|
-
uname: any;
|
49
|
-
password: any;
|
50
|
-
cert: any;
|
51
|
-
}): Promise<void>;
|
52
|
-
createIndex(indexName: any): Promise<void>;
|
53
|
-
deleteIndex(indexName: any): Promise<void>;
|
54
|
-
attachAliasToIndex(indexName: any): Promise<void>;
|
55
|
-
checkESConnection(): Promise<boolean>;
|
56
|
-
indexDataToSpecificIndex({ itemId, itemData }: {
|
57
|
-
itemId: any;
|
58
|
-
itemData: any;
|
59
|
-
}, iName: any): Promise<void>;
|
60
|
-
indexData({ itemId, itemData }: {
|
61
|
-
itemId: any;
|
62
|
-
itemData: any;
|
63
|
-
}): Promise<void>;
|
64
|
-
removeItemFromIndex({ itemId }: {
|
65
|
-
itemId: any;
|
66
|
-
}): Promise<void>;
|
67
|
-
searchData(searchQuery: any): Promise<any>;
|
68
|
-
};
|
45
|
+
}) => import("..").EsInterfaceService;
|
69
46
|
indexer: ({ strapi }: {
|
70
47
|
strapi: any;
|
71
48
|
}) => {
|
72
|
-
rebuildIndex(): Promise<boolean
|
49
|
+
rebuildIndex(): Promise<boolean>;
|
73
50
|
indexCollection(collectionName: any, indexName?: null): Promise<boolean>;
|
74
51
|
indexPendingData(): Promise<boolean>;
|
75
52
|
};
|
@@ -120,5 +97,11 @@ declare const _default: {
|
|
120
97
|
from: any;
|
121
98
|
}): any;
|
122
99
|
};
|
100
|
+
virtualCollectionsRegistry: ({ strapi }: {
|
101
|
+
strapi: any;
|
102
|
+
}) => import("..").VirtualCollectionsRegistryService;
|
103
|
+
virtualCollectionsIndexer: ({ strapi }: {
|
104
|
+
strapi: any;
|
105
|
+
}) => import("..").VirtualCollectionsIndexerService;
|
123
106
|
};
|
124
107
|
export default _default;
|
@@ -10,6 +10,8 @@ const perform_indexing_1 = __importDefault(require("./perform-indexing"));
|
|
10
10
|
const log_indexing_1 = __importDefault(require("./log-indexing"));
|
11
11
|
const helper_1 = __importDefault(require("./helper"));
|
12
12
|
const transform_content_1 = __importDefault(require("./transform-content"));
|
13
|
+
const virtual_collections_registry_1 = __importDefault(require("./virtual-collections-registry"));
|
14
|
+
const virtual_collections_indexer_1 = __importDefault(require("./virtual-collections-indexer"));
|
13
15
|
exports.default = {
|
14
16
|
configureIndexing: configure_indexing_1.default,
|
15
17
|
scheduleIndexing: schedule_indexing_1.default,
|
@@ -18,4 +20,6 @@ exports.default = {
|
|
18
20
|
logIndexing: log_indexing_1.default,
|
19
21
|
helper: helper_1.default,
|
20
22
|
transformContent: transform_content_1.default,
|
23
|
+
virtualCollectionsRegistry: virtual_collections_registry_1.default,
|
24
|
+
virtualCollectionsIndexer: virtual_collections_indexer_1.default,
|
21
25
|
};
|
@@ -1,7 +1,7 @@
|
|
1
1
|
declare const _default: ({ strapi }: {
|
2
2
|
strapi: any;
|
3
3
|
}) => {
|
4
|
-
rebuildIndex(): Promise<boolean
|
4
|
+
rebuildIndex(): Promise<boolean>;
|
5
5
|
indexCollection(collectionName: any, indexName?: null): Promise<boolean>;
|
6
6
|
indexPendingData(): Promise<boolean>;
|
7
7
|
};
|
@@ -7,6 +7,7 @@ exports.default = ({ strapi }) => ({
|
|
7
7
|
const scheduleIndexingService = strapi.plugins['elasticsearch'].services.scheduleIndexing;
|
8
8
|
const configureIndexingService = strapi.plugins['elasticsearch'].services.configureIndexing;
|
9
9
|
const logIndexingService = strapi.plugins['elasticsearch'].services.logIndexing;
|
10
|
+
const virtualCollectionsIndexer = strapi.plugins['elasticsearch'].services['virtualCollectionsIndexer'];
|
10
11
|
try {
|
11
12
|
console.log('strapi-plugin-elasticsearch : Request to rebuild the index received.');
|
12
13
|
const oldIndexName = await helper.getCurrentIndexName();
|
@@ -22,6 +23,9 @@ exports.default = ({ strapi }) => ({
|
|
22
23
|
const cols = await configureIndexingService.getCollectionsConfiguredForIndexing();
|
23
24
|
for (let r = 0; r < cols.length; r++)
|
24
25
|
await this.indexCollection(cols[r], newIndexName);
|
26
|
+
// Indexing the virtual collections
|
27
|
+
console.log('strapi-plugin-elasticsearch : Starting to index virtual collections.');
|
28
|
+
const totalIndexed = await virtualCollectionsIndexer.reindexAll(newIndexName);
|
25
29
|
await scheduleIndexingService.markIndexingTaskComplete(item.id);
|
26
30
|
console.log('strapi-plugin-elasticsearch : Indexing of data into the new index complete.');
|
27
31
|
//Step 4 : Move the alias to this new index
|
@@ -44,6 +48,7 @@ exports.default = ({ strapi }) => ({
|
|
44
48
|
console.log('strapi-plugin-elasticsearch : searchController : An error was encountered while re-indexing.');
|
45
49
|
console.log(err);
|
46
50
|
await logIndexingService.recordIndexingFail(err);
|
51
|
+
throw err;
|
47
52
|
}
|
48
53
|
},
|
49
54
|
async indexCollection(collectionName, indexName = null) {
|
@@ -54,7 +59,7 @@ exports.default = ({ strapi }) => ({
|
|
54
59
|
const esInterface = strapi.plugins['elasticsearch'].services.esInterface;
|
55
60
|
if (indexName === null)
|
56
61
|
indexName = await helper.getCurrentIndexName();
|
57
|
-
let entries = [];
|
62
|
+
let entries = []; //TODO: strapi should provide a type for this
|
58
63
|
if (isCollectionDraftPublish) {
|
59
64
|
entries = await strapi.entityService.findMany(collectionName, {
|
60
65
|
sort: { createdAt: 'DESC' },
|
@@ -0,0 +1,142 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const pretty_ms_1 = __importDefault(require("pretty-ms"));
|
7
|
+
/**
|
8
|
+
* Service to handle indexing of virtual collections
|
9
|
+
*/
|
10
|
+
exports.default = ({ strapi }) => {
|
11
|
+
const getElasticsearchService = () => strapi.plugin('elasticsearch').service('esInterface');
|
12
|
+
const getRegistryService = () => strapi.service('plugin::elasticsearch.virtualCollectionsRegistry');
|
13
|
+
const getHelperService = () => strapi.plugins['elasticsearch'].services.helper;
|
14
|
+
return {
|
15
|
+
/**
|
16
|
+
* Index a single item from a virtual collection
|
17
|
+
*/
|
18
|
+
async indexItem(collectionName, itemId) {
|
19
|
+
const registry = getRegistryService();
|
20
|
+
const collection = registry.get(collectionName);
|
21
|
+
if (!collection) {
|
22
|
+
throw new Error(`Virtual collection not found: ${collectionName}`);
|
23
|
+
}
|
24
|
+
try {
|
25
|
+
const results = await collection.extractById([itemId]);
|
26
|
+
if (!results || !Array.isArray(results) || results.length === 0) {
|
27
|
+
strapi.log.warn(`No data extracted for ${collectionName} with ID ${itemId}`);
|
28
|
+
return null;
|
29
|
+
}
|
30
|
+
const data = results[0];
|
31
|
+
const indexData = collection.mapToIndex ? data : data;
|
32
|
+
const esService = getElasticsearchService();
|
33
|
+
const helper = getHelperService();
|
34
|
+
const indexItemId = helper.getIndexItemId(collectionName, itemId);
|
35
|
+
await esService.indexDataToSpecificIndex({ itemId: indexItemId, itemData: indexData }, collection.indexName);
|
36
|
+
strapi.log.debug(`Indexed virtual item: ${collectionName}:${itemId}`);
|
37
|
+
return indexData;
|
38
|
+
}
|
39
|
+
catch (error) {
|
40
|
+
strapi.log.error(`Error indexing ${collectionName}:${itemId}: ${error?.message}`);
|
41
|
+
throw error;
|
42
|
+
}
|
43
|
+
},
|
44
|
+
async reindexAll(indexName) {
|
45
|
+
const registry = getRegistryService();
|
46
|
+
const collections = registry.getAll();
|
47
|
+
let totalIndexed = 0;
|
48
|
+
for (const collection of collections) {
|
49
|
+
totalIndexed += await this.reindex(collection.collectionName, indexName);
|
50
|
+
}
|
51
|
+
console.log(`strapi-plugin-elasticsearch : Reindexed ${totalIndexed} items across all ${collections.length} virtual collections`);
|
52
|
+
return totalIndexed;
|
53
|
+
},
|
54
|
+
/**
|
55
|
+
* Reindex all items in a virtual collection
|
56
|
+
*/
|
57
|
+
async reindex(collectionName, indexName) {
|
58
|
+
const registry = getRegistryService();
|
59
|
+
const collection = registry.get(collectionName);
|
60
|
+
if (!collection) {
|
61
|
+
throw new Error(`Virtual collection not found: ${collectionName}`);
|
62
|
+
}
|
63
|
+
const timestamp = Date.now();
|
64
|
+
try {
|
65
|
+
const esService = getElasticsearchService();
|
66
|
+
const helper = getHelperService();
|
67
|
+
// await esService.createIndex(tempIndexName);
|
68
|
+
let page = 0;
|
69
|
+
let hasMoreData = true;
|
70
|
+
let totalIndexed = 0;
|
71
|
+
while (hasMoreData) {
|
72
|
+
const pageData = await collection.extractData(page);
|
73
|
+
if (!Array.isArray(pageData) || pageData.length === 0) {
|
74
|
+
hasMoreData = false;
|
75
|
+
break;
|
76
|
+
}
|
77
|
+
const operations = [];
|
78
|
+
for (const item of pageData) {
|
79
|
+
const itemId = helper.getIndexItemId({ collectionName, itemId: item.id });
|
80
|
+
const itemData = collection.mapToIndex ? item : item;
|
81
|
+
operations.push({ itemId, itemData });
|
82
|
+
}
|
83
|
+
if (operations.length > 0) {
|
84
|
+
await Promise.all(operations.map((op) => esService.indexDataToSpecificIndex(op, indexName)));
|
85
|
+
}
|
86
|
+
totalIndexed += pageData.length;
|
87
|
+
page++;
|
88
|
+
}
|
89
|
+
strapi.log.info(`Reindexed ${totalIndexed} items for virtual collection: ${collectionName}. took ${(0, pretty_ms_1.default)(Date.now() - timestamp)}`);
|
90
|
+
return totalIndexed;
|
91
|
+
}
|
92
|
+
catch (error) {
|
93
|
+
strapi.log.error(`Error reindexing ${collectionName}: ${error?.message} after ${(0, pretty_ms_1.default)(Date.now() - timestamp)}`);
|
94
|
+
throw error;
|
95
|
+
}
|
96
|
+
},
|
97
|
+
/**
|
98
|
+
* Handle a trigger event from a collection
|
99
|
+
*/
|
100
|
+
async handleTriggerEvent(event) {
|
101
|
+
const { model, result } = event;
|
102
|
+
const registry = getRegistryService();
|
103
|
+
// Find virtual collections that should be triggered by this model
|
104
|
+
const affectedCollections = registry.findTriggersByCollection(model);
|
105
|
+
for (const collection of affectedCollections) {
|
106
|
+
// Find the specific trigger for this collection
|
107
|
+
const trigger = collection.triggers.find((t) => t.collection === model);
|
108
|
+
if (trigger && trigger.getIdsToReindex) {
|
109
|
+
// Get IDs that need to be reindexed
|
110
|
+
const idsToReindex = await trigger.getIdsToReindex(result);
|
111
|
+
// Reindex each item
|
112
|
+
for (const id of idsToReindex) {
|
113
|
+
await this.indexItem(collection.collectionName, id);
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
},
|
118
|
+
/**
|
119
|
+
* Delete an item from a virtual collection index
|
120
|
+
*/
|
121
|
+
async deleteItem(collectionName, itemId) {
|
122
|
+
const registry = getRegistryService();
|
123
|
+
const collection = registry.get(collectionName);
|
124
|
+
if (!collection) {
|
125
|
+
throw new Error(`Virtual collection not found: ${collectionName}`);
|
126
|
+
}
|
127
|
+
try {
|
128
|
+
const esService = getElasticsearchService();
|
129
|
+
await esService.removeItemFromIndex({ itemId });
|
130
|
+
strapi.log.debug(`Deleted indexed item: ${collectionName}:${itemId}`);
|
131
|
+
return true;
|
132
|
+
}
|
133
|
+
catch (error) {
|
134
|
+
if (error?.meta?.statusCode === 404) {
|
135
|
+
return false;
|
136
|
+
}
|
137
|
+
strapi.log.error(`Error deleting ${collectionName}:${itemId}: ${error.message}`);
|
138
|
+
throw error;
|
139
|
+
}
|
140
|
+
},
|
141
|
+
};
|
142
|
+
};
|
@@ -0,0 +1,32 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
/**
|
4
|
+
* Service to handle indexing of virtual collections
|
5
|
+
*/
|
6
|
+
exports.default = ({ strapi }) => {
|
7
|
+
// const getElasticsearchService = () => strapi.plugin('elasticsearch').service('esInterface');
|
8
|
+
// const getAll = () => {
|
9
|
+
// const config = strapi.plugin('elasticsearch').config('virtualCollections');
|
10
|
+
// return config || [];
|
11
|
+
// };
|
12
|
+
// const get = (collectionName) => {
|
13
|
+
// return getAll().find((collection) => collection.collectionName === collectionName);
|
14
|
+
// };
|
15
|
+
return {
|
16
|
+
getAll() {
|
17
|
+
const config = strapi.plugin('elasticsearch').config('virtualCollections');
|
18
|
+
return config || [];
|
19
|
+
},
|
20
|
+
get(collectionName) {
|
21
|
+
return this.getAll().find((collection) => collection.collectionName === collectionName) ?? null;
|
22
|
+
},
|
23
|
+
register: function (config) {
|
24
|
+
throw new Error('Function not implemented.');
|
25
|
+
},
|
26
|
+
findTriggersByCollection: function (collectionUID) {
|
27
|
+
return this.getAll().filter((collection) => {
|
28
|
+
return collection.triggers.some((trigger) => trigger.collection === collectionUID);
|
29
|
+
});
|
30
|
+
},
|
31
|
+
};
|
32
|
+
};
|
@@ -0,0 +1,70 @@
|
|
1
|
+
export interface EsInterfaceService {
|
2
|
+
/**
|
3
|
+
* Initializes the search engine connection.
|
4
|
+
* @param params - Connection parameters that include host, uname, password, and cert.
|
5
|
+
* @returns A promise that resolves when the initialization is complete.
|
6
|
+
*/
|
7
|
+
initializeSearchEngine(params: {
|
8
|
+
host: string;
|
9
|
+
uname: string;
|
10
|
+
password: string;
|
11
|
+
cert: string;
|
12
|
+
}): Promise<void>;
|
13
|
+
/**
|
14
|
+
* Creates an index in the search engine.
|
15
|
+
* @param indexName - The name of the index to create.
|
16
|
+
* @returns A promise that resolves when the index is created.
|
17
|
+
*/
|
18
|
+
createIndex(indexName: string): Promise<void>;
|
19
|
+
/**
|
20
|
+
* Deletes an index from the search engine.
|
21
|
+
* @param indexName - The name of the index to delete.
|
22
|
+
* @returns A promise that resolves when the index is deleted.
|
23
|
+
*/
|
24
|
+
deleteIndex(indexName: string): Promise<void>;
|
25
|
+
/**
|
26
|
+
* Attaches an alias to a specific index.
|
27
|
+
* @param indexName - The index to which the alias should be attached.
|
28
|
+
* @returns A promise that resolves when the alias is set.
|
29
|
+
*/
|
30
|
+
attachAliasToIndex(indexName: string): Promise<void>;
|
31
|
+
/**
|
32
|
+
* Checks the connection status of the search engine.
|
33
|
+
* @returns A promise that resolves with the connection status.
|
34
|
+
*/
|
35
|
+
checkESConnection(): Promise<any>;
|
36
|
+
/**
|
37
|
+
* Indexes data to a specific index.
|
38
|
+
* @param data - An object containing the itemId and itemData to index.
|
39
|
+
* @param data.itemId - The full ID of the item to index, in format `collectionName + '::' + itemId`.
|
40
|
+
* @param indexName - The target index name.
|
41
|
+
* @returns A promise that resolves when the data is indexed.
|
42
|
+
*/
|
43
|
+
indexDataToSpecificIndex(data: {
|
44
|
+
itemId: string;
|
45
|
+
itemData: any;
|
46
|
+
}, indexName: string): Promise<any>;
|
47
|
+
/**
|
48
|
+
* Indexes data.
|
49
|
+
* @param data - An object containing the itemId and itemData to index.
|
50
|
+
* @returns A promise that resolves when the data is indexed.
|
51
|
+
*/
|
52
|
+
indexData(data: {
|
53
|
+
itemId: string;
|
54
|
+
itemData: any;
|
55
|
+
}): Promise<any>;
|
56
|
+
/**
|
57
|
+
* Removes an item from the index.
|
58
|
+
* @param data - An object containing the itemId.
|
59
|
+
* @returns A promise that resolves when the item is removed.
|
60
|
+
*/
|
61
|
+
removeItemFromIndex(data: {
|
62
|
+
itemId: string;
|
63
|
+
}): Promise<any>;
|
64
|
+
/**
|
65
|
+
* Searches data in the search engine.
|
66
|
+
* @param searchQuery - The search query.
|
67
|
+
* @returns A promise that resolves with the search results.
|
68
|
+
*/
|
69
|
+
searchData(searchQuery: any): Promise<any>;
|
70
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
__exportStar(require("./virtual-collections.type"), exports);
|
18
|
+
__exportStar(require("./esInterface.type"), exports);
|
@@ -0,0 +1,30 @@
|
|
1
|
+
export type VirtualCollectionConfig<T extends {}> = {
|
2
|
+
indexName: string;
|
3
|
+
collectionName: string;
|
4
|
+
extractData: (page: number, pageSize?: number) => Promise<T[]>;
|
5
|
+
extractById: (ids: number[]) => Promise<T[]>;
|
6
|
+
triggers: Array<{
|
7
|
+
collection: string;
|
8
|
+
getIdsToReindex: (result: any) => Promise<number[]>;
|
9
|
+
}>;
|
10
|
+
mapToIndex: (item: T) => Promise<object>;
|
11
|
+
};
|
12
|
+
export interface VirtualCollectionsRegistryService {
|
13
|
+
/**
|
14
|
+
* Initialize indexes for all registered virtual collections
|
15
|
+
*/
|
16
|
+
initializeIndexes(): Promise<void>;
|
17
|
+
/**
|
18
|
+
* Register a virtual collection
|
19
|
+
* @param config - The configuration for the virtual collection
|
20
|
+
* @returns The current instance of the registry
|
21
|
+
*/
|
22
|
+
register<T extends {}>(config: VirtualCollectionConfig<T>): this;
|
23
|
+
/**
|
24
|
+
* get all registered virtual collections
|
25
|
+
* @returns An array of all registered virtual collections
|
26
|
+
*/
|
27
|
+
getAll(): Array<VirtualCollectionConfig<any>>;
|
28
|
+
get(collectionName: string): VirtualCollectionConfig<any> | null;
|
29
|
+
findTriggersByCollection(collectionUID: string): Array<VirtualCollectionConfig<any>>;
|
30
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
export type VirtualCollectionConfig<T extends {}> = {
|
2
|
+
indexName: string;
|
3
|
+
collectionName: string;
|
4
|
+
extractData: (page: number, pageSize?: number) => Promise<T[]>;
|
5
|
+
extractById: (ids: number[]) => Promise<T[]>;
|
6
|
+
triggers: Array<{
|
7
|
+
collection: string;
|
8
|
+
getIdsToReindex: (result: any) => Promise<number[]>;
|
9
|
+
}>;
|
10
|
+
mapToIndex?: (item: T) => Promise<object>;
|
11
|
+
};
|
12
|
+
export interface VirtualCollectionsRegistryService {
|
13
|
+
/**
|
14
|
+
* Register a virtual collection
|
15
|
+
* @param config - The configuration for the virtual collection
|
16
|
+
* @returns The current instance of the registry
|
17
|
+
*/
|
18
|
+
register<T extends {}>(config: VirtualCollectionConfig<T>): this;
|
19
|
+
/**
|
20
|
+
* get all registered virtual collections
|
21
|
+
* @returns An array of all registered virtual collections
|
22
|
+
*/
|
23
|
+
getAll(): Array<VirtualCollectionConfig<any>>;
|
24
|
+
get(collectionName: string): VirtualCollectionConfig<any> | null;
|
25
|
+
findTriggersByCollection(collectionUID: string): Array<VirtualCollectionConfig<any>>;
|
26
|
+
}
|
27
|
+
export interface VirtualCollectionsIndexerService {
|
28
|
+
/**
|
29
|
+
* Index a single item from a virtual collection.
|
30
|
+
* @param collectionName - The name of the virtual collection.
|
31
|
+
* @param itemId - The id of the item to be indexed.
|
32
|
+
*/
|
33
|
+
indexItem(collectionName: string, itemId: number): Promise<any>;
|
34
|
+
/**
|
35
|
+
* Reindex all items in a virtual collection index.
|
36
|
+
* @param indexName - The target index name.
|
37
|
+
*/
|
38
|
+
reindexAll(indexName: string): Promise<any>;
|
39
|
+
/**
|
40
|
+
* Reindex all items in a virtual collection.
|
41
|
+
* @param collectionName - The name of the virtual collection.
|
42
|
+
* @param indexName - The target index name.
|
43
|
+
*/
|
44
|
+
reindex(collectionName: string, indexName: string): Promise<any>;
|
45
|
+
/**
|
46
|
+
* Handle a trigger event from a collection.
|
47
|
+
* @param event - The trigger event.
|
48
|
+
*/
|
49
|
+
handleTriggerEvent(event: any): Promise<any>;
|
50
|
+
/**
|
51
|
+
* Delete an item from a virtual collection index.
|
52
|
+
* @param collectionName - The name of the virtual collection.
|
53
|
+
* @param itemId - The id of the item to be deleted.
|
54
|
+
* @returns A promise that resolves to a boolean indicating success.
|
55
|
+
*/
|
56
|
+
deleteItem(collectionName: string, itemId: string): Promise<boolean>;
|
57
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vegan-friendly/strapi-plugin-elasticsearch",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.2.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": {
|
@@ -37,7 +37,8 @@
|
|
37
37
|
"dependencies": {
|
38
38
|
"@elastic/elasticsearch": "^8.9.0",
|
39
39
|
"@strapi/design-system": "^1.19.0",
|
40
|
-
"markdown-to-txt": "^2.0.1"
|
40
|
+
"markdown-to-txt": "^2.0.1",
|
41
|
+
"pretty-ms": "^9.2.0"
|
41
42
|
},
|
42
43
|
"peerDependencies": {
|
43
44
|
"@strapi/strapi": "^4.0.0"
|