@vegan-friendly/strapi-plugin-elasticsearch 0.2.5 → 0.2.6
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 +3 -2
- package/dist/server/bootstrap.js +3 -0
- package/dist/server/services/virtual-collections-indexer.js +4 -5
- package/dist/server/services/virtual-collections-registry.js +63 -5
- package/dist/server/types/helper-service.type.js +0 -5
- package/dist/server/types/virtual-collections.type.d.ts +36 -14
- package/package.json +3 -2
- package/dist/admin/index.d.ts +0 -8
- package/dist/admin/index.js +0 -92
- package/dist/admin/pluginId.d.ts +0 -2
- package/dist/admin/pluginId.js +0 -8
- package/dist/server/types/virtual-collections.d.ts +0 -30
- package/dist/server/types/virtual-collections.js +0 -2
package/dist/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vegan-friendly/strapi-plugin-elasticsearch",
|
3
|
-
"version": "0.2.
|
3
|
+
"version": "0.2.6",
|
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": {
|
@@ -40,7 +40,8 @@
|
|
40
40
|
"@elastic/elasticsearch": "^8.9.0",
|
41
41
|
"@strapi/design-system": "^1.19.0",
|
42
42
|
"humanize-duration": "^3.32.1",
|
43
|
-
"markdown-to-txt": "^2.0.1"
|
43
|
+
"markdown-to-txt": "^2.0.1",
|
44
|
+
"yup": "^1.6.1"
|
44
45
|
},
|
45
46
|
"peerDependencies": {
|
46
47
|
"@strapi/strapi": "^4.0.0"
|
package/dist/server/bootstrap.js
CHANGED
@@ -146,6 +146,9 @@ exports.default = async ({ strapi }) => {
|
|
146
146
|
}
|
147
147
|
catch (err) {
|
148
148
|
console.error('An error was encountered while initializing the strapi-plugin-elasticsearch plugin.');
|
149
|
+
if (err.name == 'ValidationError') {
|
150
|
+
throw err; // fail strapi startup if the config is invalid
|
151
|
+
}
|
149
152
|
console.error(err);
|
150
153
|
}
|
151
154
|
};
|
@@ -30,7 +30,7 @@ exports.default = ({ strapi }) => {
|
|
30
30
|
const itemData = results[0];
|
31
31
|
const esInterface = getElasticsearchService();
|
32
32
|
const helper = getHelperService();
|
33
|
-
const indexItemId =
|
33
|
+
const indexItemId = collection.getIndexItemId(itemId, collectionName);
|
34
34
|
const indexName = await helper.getCurrentIndexName(collection.indexAlias);
|
35
35
|
await esInterface.indexDataToSpecificIndex({ itemId: indexItemId, itemData }, indexName);
|
36
36
|
strapi.log.debug(`Indexed virtual item: ${collectionName}:${itemId}`);
|
@@ -81,7 +81,7 @@ exports.default = ({ strapi }) => {
|
|
81
81
|
}
|
82
82
|
const operations = [];
|
83
83
|
for (const itemData of pageData) {
|
84
|
-
const itemId =
|
84
|
+
const itemId = collection.getIndexItemId(itemData.id, collectionName);
|
85
85
|
operations.push({ itemId, itemData });
|
86
86
|
}
|
87
87
|
if (operations.length > 0) {
|
@@ -117,7 +117,6 @@ exports.default = ({ strapi }) => {
|
|
117
117
|
for (const collection of affectedCollections) {
|
118
118
|
// Find the specific trigger for this collection
|
119
119
|
const trigger = collection.triggers.find((t) => t.collection === model.uid);
|
120
|
-
const triggerIsOnIndexCollection = model.uid === collection.collectionName;
|
121
120
|
if (trigger?.getIdsToReindex == null) {
|
122
121
|
strapi.log.error(`Trigger for ${collection.collectionName} (triggered by ${model.uid}) does not have getIdsToReindex function.`);
|
123
122
|
return;
|
@@ -126,7 +125,7 @@ exports.default = ({ strapi }) => {
|
|
126
125
|
const idsToReindex = await trigger.getIdsToReindex(result);
|
127
126
|
// Reindex each item
|
128
127
|
for (const id of idsToReindex) {
|
129
|
-
const isDelete = event.action?.toLowerCase()?.includes('delete') &&
|
128
|
+
const isDelete = event.action?.toLowerCase()?.includes('delete') && trigger.alsoTriggerDelete && id === result.id;
|
130
129
|
if (isDelete) {
|
131
130
|
//delete the item from the index, if the item being delete is the one being reindexed
|
132
131
|
await this.deleteItem(collection.collectionName, id);
|
@@ -149,7 +148,7 @@ exports.default = ({ strapi }) => {
|
|
149
148
|
}
|
150
149
|
try {
|
151
150
|
const esInterface = getElasticsearchService();
|
152
|
-
const indexItemId =
|
151
|
+
const indexItemId = collection.getIndexItemId(itemId, collectionName);
|
153
152
|
const indexName = collection.indexAlias || (await helper.getCurrentIndexName());
|
154
153
|
await esInterface.removeItemFromIndex({ indexName, itemId: indexItemId });
|
155
154
|
strapi.log.debug(`Deleted indexed item: ${collectionName}:${itemId}`);
|
@@ -1,5 +1,56 @@
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
19
|
+
var ownKeys = function(o) {
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
21
|
+
var ar = [];
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
23
|
+
return ar;
|
24
|
+
};
|
25
|
+
return ownKeys(o);
|
26
|
+
};
|
27
|
+
return function (mod) {
|
28
|
+
if (mod && mod.__esModule) return mod;
|
29
|
+
var result = {};
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
31
|
+
__setModuleDefault(result, mod);
|
32
|
+
return result;
|
33
|
+
};
|
34
|
+
})();
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
36
|
+
const yup = __importStar(require("yup"));
|
37
|
+
const isFunction = () => yup.mixed().test('is-function', `must be a function`, (value) => typeof value === 'function');
|
38
|
+
const configSchema = yup.object({
|
39
|
+
indexAlias: yup.string().nullable(),
|
40
|
+
collectionName: yup.string().required(),
|
41
|
+
extractData: isFunction().required(),
|
42
|
+
extractByIds: isFunction().required(),
|
43
|
+
getIndexItemId: isFunction(),
|
44
|
+
triggers: yup
|
45
|
+
.array()
|
46
|
+
.of(yup.object({
|
47
|
+
collection: yup.string().required(),
|
48
|
+
getIdsToReindex: isFunction(),
|
49
|
+
alsoTriggerDelete: yup.boolean().default(false),
|
50
|
+
}))
|
51
|
+
.default([]),
|
52
|
+
mappings: yup.object().default({}),
|
53
|
+
});
|
3
54
|
/**
|
4
55
|
* Service to handle indexing of virtual collections
|
5
56
|
*/
|
@@ -12,17 +63,24 @@ exports.default = ({ strapi }) => {
|
|
12
63
|
// const get = (collectionName) => {
|
13
64
|
// return getAll().find((collection) => collection.collectionName === collectionName);
|
14
65
|
// };
|
66
|
+
let config;
|
15
67
|
return {
|
16
68
|
getAll() {
|
17
|
-
|
18
|
-
|
69
|
+
if (!config) {
|
70
|
+
const helper = strapi.plugin('elasticsearch').service('helper');
|
71
|
+
const defaultConf = configSchema.getDefault();
|
72
|
+
config = strapi.plugin('elasticsearch').config('virtualCollections') || [];
|
73
|
+
config = config.map((collection) => {
|
74
|
+
const collectionConfig = configSchema.validateSync(collection, { strict: true });
|
75
|
+
collectionConfig.getIndexItemId = collectionConfig.getIndexItemId || ((id) => helper.getIndexItemId({ collectionName: collectionConfig.collectionName, itemId: id }));
|
76
|
+
return { ...defaultConf, ...collectionConfig };
|
77
|
+
});
|
78
|
+
}
|
79
|
+
return config;
|
19
80
|
},
|
20
81
|
get(collectionName) {
|
21
82
|
return this.getAll().find((collection) => collection.collectionName === collectionName) ?? null;
|
22
83
|
},
|
23
|
-
register: function (config) {
|
24
|
-
throw new Error('Function not implemented.');
|
25
|
-
},
|
26
84
|
findTriggersByCollection: function (collectionUID) {
|
27
85
|
return this.getAll().filter((collection) => {
|
28
86
|
return collection.triggers.some((trigger) => trigger.collection === collectionUID);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { MappingTypeMapping } from '@elastic/elasticsearch/lib/api/types';
|
2
|
-
export type VirtualCollectionConfig
|
2
|
+
export type VirtualCollectionConfig = {
|
3
3
|
/**
|
4
4
|
* Optional -
|
5
5
|
* The alias of the latest index in Elasticsearch.
|
@@ -11,12 +11,40 @@ export type VirtualCollectionConfig<T extends StrapiEntity> = {
|
|
11
11
|
* Omit this property if you want to use the default index for all collections.
|
12
12
|
*/
|
13
13
|
indexAlias?: string;
|
14
|
+
/**
|
15
|
+
* The name of the virtual-collection.
|
16
|
+
* You can use whatever name you want, but it's recommended to use the underlying collection api name,
|
17
|
+
* e.g 'api::restaurants.restaurants'.
|
18
|
+
*/
|
14
19
|
collectionName: string;
|
15
|
-
extractData: (page: number, pageSize?: number) => Promise<
|
16
|
-
extractByIds: (ids: number[]) => Promise<
|
20
|
+
extractData: (page: number, pageSize?: number) => Promise<StrapiEntity[]>;
|
21
|
+
extractByIds: (ids: number[]) => Promise<StrapiEntity[]>;
|
22
|
+
/**
|
23
|
+
* Optional -
|
24
|
+
* A function that takes an item and returns the id of the item to be used in the index.
|
25
|
+
* The default is <collectionName>::<itemId>
|
26
|
+
*
|
27
|
+
* @param itemId itemId in strapi
|
28
|
+
* @param collectionName collection name. you probably want to use this to create a unique id for the item, especially if it is saved to the default index.
|
29
|
+
* @returns the id of the item to be used in the index, _id. must be unique accross the index.
|
30
|
+
*/
|
31
|
+
getIndexItemId?: (itemId: number, collectionName: string) => string;
|
17
32
|
triggers: Array<{
|
33
|
+
/**
|
34
|
+
* collection name to listen to for changes.
|
35
|
+
*/
|
18
36
|
collection: string;
|
19
|
-
|
37
|
+
/**
|
38
|
+
* gets an event on the given collection, and returns the ids of virtual-collection items to be reindexed.
|
39
|
+
* @param event - The event object containing the data to be indexed.
|
40
|
+
* @returns ids of the items to be reindexed.
|
41
|
+
*/
|
42
|
+
getIdsToReindex: (event: any) => Promise<number[]>;
|
43
|
+
/**
|
44
|
+
* 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.
|
45
|
+
* defaults to false.
|
46
|
+
*/
|
47
|
+
alsoTriggerDelete?: boolean;
|
20
48
|
}>;
|
21
49
|
/**
|
22
50
|
* Optional schema to be sent to Elasticsearch when creating the index.
|
@@ -25,19 +53,13 @@ export type VirtualCollectionConfig<T extends StrapiEntity> = {
|
|
25
53
|
mappings?: MappingTypeMapping;
|
26
54
|
};
|
27
55
|
export interface VirtualCollectionsRegistryService {
|
28
|
-
/**
|
29
|
-
* Register a virtual collection
|
30
|
-
* @param config - The configuration for the virtual collection
|
31
|
-
* @returns The current instance of the registry
|
32
|
-
*/
|
33
|
-
register<T extends StrapiEntity>(config: VirtualCollectionConfig<T>): this;
|
34
56
|
/**
|
35
57
|
* get all registered virtual collections
|
36
58
|
* @returns An array of all registered virtual collections
|
37
59
|
*/
|
38
|
-
getAll(): Array<VirtualCollectionConfig
|
39
|
-
get(collectionName: string): VirtualCollectionConfig
|
40
|
-
findTriggersByCollection(collectionUID: string): Array<VirtualCollectionConfig
|
60
|
+
getAll(): Array<VirtualCollectionConfig>;
|
61
|
+
get(collectionName: string): VirtualCollectionConfig | null;
|
62
|
+
findTriggersByCollection(collectionUID: string): Array<VirtualCollectionConfig>;
|
41
63
|
}
|
42
64
|
export type StrapiEntity = {
|
43
65
|
id: number;
|
@@ -58,7 +80,7 @@ export interface VirtualCollectionsIndexerService {
|
|
58
80
|
* Reindex all items in a virtual collection.
|
59
81
|
* @param collection - The virtual collection config.
|
60
82
|
*/
|
61
|
-
reindex
|
83
|
+
reindex(collection: VirtualCollectionConfig): Promise<any>;
|
62
84
|
/**
|
63
85
|
* Handle a trigger event from a collection.
|
64
86
|
* @param event - The trigger event.
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vegan-friendly/strapi-plugin-elasticsearch",
|
3
|
-
"version": "0.2.
|
3
|
+
"version": "0.2.6",
|
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": {
|
@@ -40,7 +40,8 @@
|
|
40
40
|
"@elastic/elasticsearch": "^8.9.0",
|
41
41
|
"@strapi/design-system": "^1.19.0",
|
42
42
|
"humanize-duration": "^3.32.1",
|
43
|
-
"markdown-to-txt": "^2.0.1"
|
43
|
+
"markdown-to-txt": "^2.0.1",
|
44
|
+
"yup": "^1.6.1"
|
44
45
|
},
|
45
46
|
"peerDependencies": {
|
46
47
|
"@strapi/strapi": "^4.0.0"
|
package/dist/admin/index.d.ts
DELETED
package/dist/admin/index.js
DELETED
@@ -1,92 +0,0 @@
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
-
}) : function(o, v) {
|
16
|
-
o["default"] = v;
|
17
|
-
});
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
19
|
-
var ownKeys = function(o) {
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
21
|
-
var ar = [];
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
23
|
-
return ar;
|
24
|
-
};
|
25
|
-
return ownKeys(o);
|
26
|
-
};
|
27
|
-
return function (mod) {
|
28
|
-
if (mod && mod.__esModule) return mod;
|
29
|
-
var result = {};
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
31
|
-
__setModuleDefault(result, mod);
|
32
|
-
return result;
|
33
|
-
};
|
34
|
-
})();
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
37
|
-
};
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
39
|
-
const helper_plugin_1 = require("@strapi/helper-plugin");
|
40
|
-
const package_json_1 = __importDefault(require("../package.json"));
|
41
|
-
const pluginId_1 = __importDefault(require("./pluginId"));
|
42
|
-
const Initializer_1 = __importDefault(require("./src/components/Initializer"));
|
43
|
-
const PluginIcon_1 = __importDefault(require("./src/components/PluginIcon"));
|
44
|
-
const name = package_json_1.default.strapi.name;
|
45
|
-
exports.default = {
|
46
|
-
register(app) {
|
47
|
-
app.addMenuLink({
|
48
|
-
to: `/plugins/${pluginId_1.default}`,
|
49
|
-
icon: PluginIcon_1.default,
|
50
|
-
intlLabel: {
|
51
|
-
id: `${pluginId_1.default}.plugin.name`,
|
52
|
-
defaultMessage: 'Elasticsearch',
|
53
|
-
},
|
54
|
-
Component: async () => {
|
55
|
-
const component = await Promise.resolve().then(() => __importStar(require(/* webpackChunkName: "[request]" */ './src/pages/App')));
|
56
|
-
return component;
|
57
|
-
},
|
58
|
-
permissions: [
|
59
|
-
// Uncomment to set the permissions of the plugin here
|
60
|
-
// {
|
61
|
-
// action: '', // the action name should be plugin::plugin-name.actionType
|
62
|
-
// subject: null,
|
63
|
-
// },
|
64
|
-
],
|
65
|
-
});
|
66
|
-
app.registerPlugin({
|
67
|
-
id: pluginId_1.default,
|
68
|
-
initializer: Initializer_1.default,
|
69
|
-
isReady: false,
|
70
|
-
name,
|
71
|
-
});
|
72
|
-
},
|
73
|
-
bootstrap(app) { },
|
74
|
-
async registerTrads({ locales }) {
|
75
|
-
const importedTrads = await Promise.all(locales.map((locale) => {
|
76
|
-
return Promise.resolve(`${
|
77
|
-
/* webpackChunkName: "translation-[request]" */ `./translations/${locale}.json`}`).then(s => __importStar(require(s))).then(({ default: data }) => {
|
78
|
-
return {
|
79
|
-
data: (0, helper_plugin_1.prefixPluginTranslations)(data, pluginId_1.default),
|
80
|
-
locale,
|
81
|
-
};
|
82
|
-
})
|
83
|
-
.catch(() => {
|
84
|
-
return {
|
85
|
-
data: {},
|
86
|
-
locale,
|
87
|
-
};
|
88
|
-
});
|
89
|
-
}));
|
90
|
-
return Promise.resolve(importedTrads);
|
91
|
-
},
|
92
|
-
};
|
package/dist/admin/pluginId.d.ts
DELETED
package/dist/admin/pluginId.js
DELETED
@@ -1,8 +0,0 @@
|
|
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 package_json_1 = __importDefault(require("../package.json"));
|
7
|
-
const pluginId = package_json_1.default.strapi.name;
|
8
|
-
exports.default = pluginId;
|
@@ -1,30 +0,0 @@
|
|
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
|
-
}
|