@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vegan-friendly/strapi-plugin-elasticsearch",
3
- "version": "0.2.4",
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"
@@ -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 = helper.getIndexItemId({ collectionName, itemId });
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 = helper.getIndexItemId({ collectionName, itemId: itemData.id });
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') && triggerIsOnIndexCollection && id === result.id;
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 = helper.getIndexItemId({ collectionName, itemId });
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
- const config = strapi.plugin('elasticsearch').config('virtualCollections');
18
- return config || [];
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,7 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- let a = {
4
- a: 1,
5
- };
6
- const example = { foo: "bar" };
7
- a = example;
@@ -1,5 +1,5 @@
1
1
  import { MappingTypeMapping } from '@elastic/elasticsearch/lib/api/types';
2
- export type VirtualCollectionConfig<T extends StrapiEntity> = {
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<T[]>;
16
- extractByIds: (ids: number[]) => Promise<T[]>;
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
- getIdsToReindex: (result: any) => Promise<number[]>;
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<any>>;
39
- get(collectionName: string): VirtualCollectionConfig<any> | null;
40
- findTriggersByCollection(collectionUID: string): Array<VirtualCollectionConfig<any>>;
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<T extends StrapiEntity>(collection: VirtualCollectionConfig<T>): Promise<any>;
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.5",
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"
@@ -1,8 +0,0 @@
1
- declare const _default: {
2
- register(app: any): void;
3
- bootstrap(app: any): void;
4
- registerTrads({ locales }: {
5
- locales: any;
6
- }): Promise<any[]>;
7
- };
8
- export default _default;
@@ -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
- };
@@ -1,2 +0,0 @@
1
- declare const pluginId: string;
2
- export default pluginId;
@@ -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
- }
@@ -1,2 +0,0 @@
1
- 'use strict';
2
- Object.defineProperty(exports, "__esModule", { value: true });