medusa-plugin-elasticsearch 0.0.1
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/LICENSE +21 -0
- package/README.md +179 -0
- package/dist/loaders/index.d.ts +4 -0
- package/dist/loaders/index.js +17 -0
- package/dist/loaders/index.js.map +1 -0
- package/dist/services/elasticsearch.d.ts +19 -0
- package/dist/services/elasticsearch.js +96 -0
- package/dist/services/elasticsearch.js.map +1 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/transformer.d.ts +1 -0
- package/dist/utils/transformer.js +42 -0
- package/dist/utils/transformer.js.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Peter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Elasticsearch
|
|
2
|
+
|
|
3
|
+
Provide powerful indexing and searching features in your commerce application with Elasticsearch.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Flexible configurations for specifying searchable and retrievable attributes.
|
|
8
|
+
- Utilize Elasticsearch's powerful search functionalities including possibility to configure custom mappings, indexes, tokenizers and more.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
- [Medusa backend](https://docs.medusajs.com/development/backend/install)
|
|
15
|
+
- Elasticsearch instance or cloud
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## How to Install
|
|
20
|
+
|
|
21
|
+
1\. Run the following command in the directory of the Medusa backend:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install medusa-plugin-elasticsearch
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
2\. Set the environment variables in `.env`, based on your configuration.
|
|
28
|
+
|
|
29
|
+
3\. In `medusa-config.js` add the following at the end of the `plugins` array:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
const plugins = [
|
|
33
|
+
// ...
|
|
34
|
+
{
|
|
35
|
+
resolve: `medusa-plugin-elasticsearch`,
|
|
36
|
+
options: {
|
|
37
|
+
config: {
|
|
38
|
+
cloud: {
|
|
39
|
+
id: process.env.ELASTIC_CLOUD_ID
|
|
40
|
+
},
|
|
41
|
+
auth: {
|
|
42
|
+
username: process.env.ELASTIC_USER_NAME,
|
|
43
|
+
password: process.env.ELASTIC_PASSWORD,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
settings: {
|
|
47
|
+
products: {
|
|
48
|
+
indexSettings: {
|
|
49
|
+
searchableAttributes: ["title", "description"],
|
|
50
|
+
attributesToRetrieve: [
|
|
51
|
+
"id",
|
|
52
|
+
"title",
|
|
53
|
+
"description",
|
|
54
|
+
"handle",
|
|
55
|
+
"thumbnail",
|
|
56
|
+
"variants",
|
|
57
|
+
"variant_sku",
|
|
58
|
+
"options",
|
|
59
|
+
"collection_title",
|
|
60
|
+
"collection_handle",
|
|
61
|
+
"images",
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
transformer: (product) => ({
|
|
65
|
+
id: product.id,
|
|
66
|
+
name: product.name,
|
|
67
|
+
description: product.description,
|
|
68
|
+
// other attributes...
|
|
69
|
+
}),
|
|
70
|
+
mappings: { // Not required, used in case if custom mapping configuration is needed
|
|
71
|
+
properties: {
|
|
72
|
+
id: {
|
|
73
|
+
type: 'keyword',
|
|
74
|
+
},
|
|
75
|
+
name: {
|
|
76
|
+
type: 'keyword',
|
|
77
|
+
},
|
|
78
|
+
description: {
|
|
79
|
+
type: 'text',
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
settings: { // Not required, used in case if custom index settings are needed
|
|
84
|
+
analysis: {
|
|
85
|
+
normalizer: {
|
|
86
|
+
sortable: {
|
|
87
|
+
type: 'lowercase',
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
tokenizer: {
|
|
91
|
+
autocomplete: {
|
|
92
|
+
type: 'edge_ngram',
|
|
93
|
+
min_gram: 2,
|
|
94
|
+
max_gram: 10,
|
|
95
|
+
token_chars: ['letter', 'digit'],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
analyzer: {
|
|
99
|
+
autocomplete_index: {
|
|
100
|
+
type: 'custom',
|
|
101
|
+
tokenizer: 'autocomplete',
|
|
102
|
+
filter: ['lowercase'],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Options
|
|
115
|
+
|
|
116
|
+
#### 1. Global options
|
|
117
|
+
|
|
118
|
+
| Name | Description | Required |
|
|
119
|
+
-------|-------------|----------|
|
|
120
|
+
| `config` | The Elasticsearch [client configuration](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-configuration.html). | true |
|
|
121
|
+
| `settings` | The indexes list and configurations. | true |
|
|
122
|
+
|
|
123
|
+
#### 2. Index Options
|
|
124
|
+
|
|
125
|
+
| Name | Description | Required |
|
|
126
|
+
-------|-------------|----------|
|
|
127
|
+
| `indexSettings` | Standard Medusa [index settings](https://docs.medusajs.com/plugins/search/algolia#index-settings). | true |
|
|
128
|
+
| `transformer` | Custom object transformer function. | false |
|
|
129
|
+
| `mappings` | Custom Elasticsearch mapping configuration. | false |
|
|
130
|
+
| `settings` | Custom Elasticsearch index configuration. | false |
|
|
131
|
+
|
|
132
|
+
## Test the Plugin
|
|
133
|
+
|
|
134
|
+
1\. Run the following command in the directory of the Medusa backend to run the backend:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npm run start
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
2\. Try searching products either using your storefront or using the [Store APIs](https://docs.medusajs.com/api/store#tag/Product/operation/PostProductsSearch).
|
|
141
|
+
|
|
142
|
+
3\. Example search response:
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"took": 1,
|
|
146
|
+
"timed_out": false,
|
|
147
|
+
"_shards": {
|
|
148
|
+
"total": 1,
|
|
149
|
+
"successful": 1,
|
|
150
|
+
"skipped": 0,
|
|
151
|
+
"failed": 0
|
|
152
|
+
},
|
|
153
|
+
"hits": {
|
|
154
|
+
"total": {
|
|
155
|
+
"value": 1,
|
|
156
|
+
"relation": "eq"
|
|
157
|
+
},
|
|
158
|
+
"max_score": 0.06801665,
|
|
159
|
+
"hits": [
|
|
160
|
+
{
|
|
161
|
+
"_index": "products",
|
|
162
|
+
"_id": "prod_01H2P51GTXD6Y4BB4C950VBQYN",
|
|
163
|
+
"_score": 0.06801665,
|
|
164
|
+
"_source": {
|
|
165
|
+
"id": "prod_01H2P51GTXD6Y4BB4C950VBQYN",
|
|
166
|
+
"title": "Medusa Sweatshirt",
|
|
167
|
+
"description": "Reimagine the feeling of a classic sweatshirt. With our cotton sweatshirt, everyday essentials no longer have to be ordinary."
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Additional Resources
|
|
178
|
+
|
|
179
|
+
- [Elasticsearch Node.js client](https://github.com/elastic/elasticsearch-js)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = async (container, options) => {
|
|
4
|
+
const logger = container.resolve('logger');
|
|
5
|
+
try {
|
|
6
|
+
const service = container.resolve('elasticsearchService');
|
|
7
|
+
const { settings } = options;
|
|
8
|
+
await Promise.all(Object.entries(settings ?? {}).map(([indexName, value]) => {
|
|
9
|
+
return service.updateSettings(indexName, value);
|
|
10
|
+
}));
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
// ignore
|
|
14
|
+
logger.warn('es: ', err);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/loaders/index.ts"],"names":[],"mappings":";;AAIA,kBAAe,KAAK,EAClB,SAA0B,EAC1B,OAAmC,EACnC,EAAE;IACF,MAAM,MAAM,GAAW,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEnD,IAAI;QACF,MAAM,OAAO,GAAyB,SAAS,CAAC,OAAO,CACrD,sBAAsB,CACvB,CAAC;QAEF,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAE7B,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE;YACxD,OAAO,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC,CAAC,CACH,CAAC;KACH;IAAC,OAAO,GAAG,EAAE;QACZ,SAAS;QACT,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC1B;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AbstractSearchService } from '@medusajs/utils';
|
|
2
|
+
import { Client } from '@elastic/elasticsearch';
|
|
3
|
+
import { ElasticsearchPluginOptions, IndexOptions } from '../types';
|
|
4
|
+
declare class ElasticsearchService extends AbstractSearchService {
|
|
5
|
+
isDefault: boolean;
|
|
6
|
+
protected readonly config_: ElasticsearchPluginOptions;
|
|
7
|
+
protected readonly client_: Client;
|
|
8
|
+
constructor(_: any, options: ElasticsearchPluginOptions);
|
|
9
|
+
createIndex(indexName: string, options: Record<string, any>): Promise<import("@elastic/elasticsearch/lib/api/types").IndicesCreateResponse>;
|
|
10
|
+
getIndex(indexName: string): Promise<import("@elastic/elasticsearch/lib/api/types").IndicesGetResponse>;
|
|
11
|
+
addDocuments(indexName: string, documents: Record<string, any>[], type: string): Promise<import("@elastic/elasticsearch/lib/api/types").BulkResponse>;
|
|
12
|
+
replaceDocuments(indexName: string, documents: Record<string, any>[], type: string): Promise<import("@elastic/elasticsearch/lib/api/types").BulkResponse>;
|
|
13
|
+
deleteDocument(indexName: string, document_id: string): Promise<import("@elastic/elasticsearch/lib/api/types").WriteResponseBase>;
|
|
14
|
+
deleteAllDocuments(indexName: string): Promise<import("@elastic/elasticsearch/lib/api/types").DeleteByQueryResponse>;
|
|
15
|
+
search(indexName: string, query: string, options: Record<string, any>): Promise<import("@elastic/elasticsearch/lib/api/types").SearchResponse<unknown, Record<string, import("@elastic/elasticsearch/lib/api/types").AggregationsAggregate>>>;
|
|
16
|
+
updateSettings(indexName: string, { mappings, settings }: IndexOptions): Promise<import("@elastic/elasticsearch/lib/api/types").IndicesCreateResponse>;
|
|
17
|
+
private getTransformedDocuments;
|
|
18
|
+
}
|
|
19
|
+
export default ElasticsearchService;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const types_1 = require("@medusajs/types");
|
|
4
|
+
const utils_1 = require("@medusajs/utils");
|
|
5
|
+
const elasticsearch_1 = require("@elastic/elasticsearch");
|
|
6
|
+
const transformer_1 = require("../utils/transformer");
|
|
7
|
+
class ElasticsearchService extends utils_1.AbstractSearchService {
|
|
8
|
+
constructor(_, options) {
|
|
9
|
+
super(_, options);
|
|
10
|
+
this.isDefault = false;
|
|
11
|
+
this.config_ = options;
|
|
12
|
+
this.client_ = new elasticsearch_1.Client(options.config);
|
|
13
|
+
}
|
|
14
|
+
createIndex(indexName, options) {
|
|
15
|
+
return this.client_.indices.create({
|
|
16
|
+
index: indexName,
|
|
17
|
+
...options,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
getIndex(indexName) {
|
|
21
|
+
return this.client_.indices.get({ index: indexName });
|
|
22
|
+
}
|
|
23
|
+
addDocuments(indexName, documents, type) {
|
|
24
|
+
return this.client_.bulk({
|
|
25
|
+
refresh: true,
|
|
26
|
+
operations: this.getTransformedDocuments(type, documents).flatMap((doc) => [{ index: { _index: indexName, _id: doc.id } }, doc]),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
replaceDocuments(indexName, documents, type) {
|
|
30
|
+
return this.client_.bulk({
|
|
31
|
+
refresh: true,
|
|
32
|
+
operations: this.getTransformedDocuments(type, documents).flatMap((doc) => [{ index: { _index: indexName, _id: doc.id } }, doc]),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
deleteDocument(indexName, document_id) {
|
|
36
|
+
return this.client_.delete({
|
|
37
|
+
index: indexName,
|
|
38
|
+
id: document_id,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
deleteAllDocuments(indexName) {
|
|
42
|
+
return this.client_.deleteByQuery({
|
|
43
|
+
index: indexName,
|
|
44
|
+
body: {
|
|
45
|
+
query: {
|
|
46
|
+
match_all: {},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
search(indexName, query, options) {
|
|
52
|
+
const { paginationOptions, filter, additionalOptions } = options;
|
|
53
|
+
return this.client_.search({
|
|
54
|
+
index: indexName,
|
|
55
|
+
q: query,
|
|
56
|
+
body: {
|
|
57
|
+
query: filter,
|
|
58
|
+
},
|
|
59
|
+
from: paginationOptions.offset,
|
|
60
|
+
size: paginationOptions.limit,
|
|
61
|
+
...additionalOptions,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async updateSettings(indexName, { mappings, settings }) {
|
|
65
|
+
// Check if index is already created with mappings
|
|
66
|
+
const exists = await this.client_.indices.exists({
|
|
67
|
+
index: indexName,
|
|
68
|
+
});
|
|
69
|
+
// drop index, to create new one with updated mapping
|
|
70
|
+
if (exists) {
|
|
71
|
+
await this.client_.indices.delete({
|
|
72
|
+
index: indexName,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// create new index
|
|
76
|
+
return this.createIndex(indexName, {
|
|
77
|
+
mappings,
|
|
78
|
+
settings,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
getTransformedDocuments(type, documents) {
|
|
82
|
+
if (!documents?.length) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
switch (type) {
|
|
86
|
+
case types_1.SearchTypes.indexTypes.PRODUCTS:
|
|
87
|
+
const productsTransformer = this.config_.settings?.[types_1.SearchTypes.indexTypes.PRODUCTS]
|
|
88
|
+
?.transformer ?? transformer_1.transformProduct;
|
|
89
|
+
return documents.map(productsTransformer);
|
|
90
|
+
default:
|
|
91
|
+
return documents;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.default = ElasticsearchService;
|
|
96
|
+
//# sourceMappingURL=elasticsearch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elasticsearch.js","sourceRoot":"","sources":["../../src/services/elasticsearch.ts"],"names":[],"mappings":";;AAAA,2CAA8C;AAC9C,2CAAwD;AACxD,0DAA+D;AAE/D,sDAAwD;AAExD,MAAM,oBAAqB,SAAQ,6BAAqB;IAMtD,YAAY,CAAC,EAAE,OAAmC;QAChD,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QANpB,cAAS,GAAG,KAAK,CAAC;QAQhB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,IAAI,sBAAM,CAAgB,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC;IAED,WAAW,CAAC,SAAiB,EAAE,OAA4B;QACzD,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;YACjC,KAAK,EAAE,SAAS;YAChB,GAAG,OAAO;SACX,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,SAAiB;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,YAAY,CACV,SAAiB,EACjB,SAAgC,EAChC,IAAY;QAEZ,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACvB,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,OAAO,CAC/D,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAC9D;SACF,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,CACd,SAAiB,EACjB,SAAgC,EAChC,IAAY;QAEZ,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACvB,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,OAAO,CAC/D,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAC9D;SACF,CAAC,CAAC;IACL,CAAC;IAED,cAAc,CAAC,SAAiB,EAAE,WAAmB;QACnD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACzB,KAAK,EAAE,SAAS;YAChB,EAAE,EAAE,WAAW;SAChB,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB,CAAC,SAAiB;QAClC,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;YAChC,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE;gBACJ,KAAK,EAAE;oBACL,SAAS,EAAE,EAAE;iBACd;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,SAAiB,EAAE,KAAa,EAAE,OAA4B;QACnE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;QAEjE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACzB,KAAK,EAAE,SAAS;YAChB,CAAC,EAAE,KAAK;YACR,IAAI,EAAE;gBACJ,KAAK,EAAE,MAAM;aACd;YACD,IAAI,EAAE,iBAAiB,CAAC,MAAM;YAC9B,IAAI,EAAE,iBAAiB,CAAC,KAAK;YAC7B,GAAG,iBAAiB;SACrB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,SAAiB,EACjB,EAAE,QAAQ,EAAE,QAAQ,EAAgB;QAEpC,kDAAkD;QAClD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;YAC/C,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,qDAAqD;QACrD,IAAI,MAAM,EAAE;YACV,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;gBAChC,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;SACJ;QAED,mBAAmB;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE;YACjC,QAAQ;YACR,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IAEO,uBAAuB,CAAC,IAAY,EAAE,SAAgB;QAC5D,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE;YACtB,OAAO,EAAE,CAAC;SACX;QAED,QAAQ,IAAI,EAAE;YACZ,KAAK,mBAAW,CAAC,UAAU,CAAC,QAAQ;gBAClC,MAAM,mBAAmB,GACvB,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,mBAAW,CAAC,UAAU,CAAC,QAAQ,CAAC;oBACtD,EAAE,WAAW,IAAI,8BAAgB,CAAC;gBAEtC,OAAO,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YAC5C;gBACE,OAAO,SAAS,CAAC;SACpB;IACH,CAAC;CACF;AAED,kBAAe,oBAAoB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SearchTypes } from '@medusajs/types';
|
|
2
|
+
import { ClientOptions } from '@elastic/elasticsearch';
|
|
3
|
+
import { IndicesIndexSettings, MappingTypeMapping } from '@elastic/elasticsearch/lib/api/types';
|
|
4
|
+
export type SearchOptions = {
|
|
5
|
+
paginationOptions: Record<string, unknown>;
|
|
6
|
+
filter: string;
|
|
7
|
+
additionalOptions: Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
type ElasticIndexOptions = {
|
|
10
|
+
mappings?: MappingTypeMapping;
|
|
11
|
+
settings?: IndicesIndexSettings;
|
|
12
|
+
};
|
|
13
|
+
export type IndexOptions = SearchTypes.IndexSettings & ElasticIndexOptions;
|
|
14
|
+
export type ElasticsearchPluginOptions = {
|
|
15
|
+
config: ClientOptions;
|
|
16
|
+
/**
|
|
17
|
+
* Index settings
|
|
18
|
+
*/
|
|
19
|
+
settings?: Record<string, IndexOptions>;
|
|
20
|
+
};
|
|
21
|
+
export {};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const transformProduct: (product: any) => any;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transformProduct = void 0;
|
|
4
|
+
const types_1 = require("@medusajs/types");
|
|
5
|
+
const prefix = `variant`;
|
|
6
|
+
const transformProduct = (product) => {
|
|
7
|
+
let transformedProduct = { ...product };
|
|
8
|
+
const initialObj = types_1.variantKeys.reduce((obj, key) => {
|
|
9
|
+
obj[`${prefix}_${key}`] = [];
|
|
10
|
+
return obj;
|
|
11
|
+
}, {});
|
|
12
|
+
initialObj[`${prefix}_options_value`] = [];
|
|
13
|
+
const flattenedVariantFields = product.variants.reduce((obj, variant) => {
|
|
14
|
+
types_1.variantKeys.forEach((k) => {
|
|
15
|
+
if (k === 'options' && variant[k]) {
|
|
16
|
+
const values = variant[k].map((option) => option.value);
|
|
17
|
+
obj[`${prefix}_options_value`] =
|
|
18
|
+
obj[`${prefix}_options_value`].concat(values);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
return variant[k] && obj[`${prefix}_${k}`].push(variant[k]);
|
|
22
|
+
});
|
|
23
|
+
return obj;
|
|
24
|
+
}, initialObj);
|
|
25
|
+
transformedProduct.objectID = product.id;
|
|
26
|
+
transformedProduct.type_value = product.type && product.type.value;
|
|
27
|
+
transformedProduct.collection_title =
|
|
28
|
+
product.collection && product.collection.title;
|
|
29
|
+
transformedProduct.collection_handle =
|
|
30
|
+
product.collection && product.collection.handle;
|
|
31
|
+
transformedProduct.tags_value = product.tags
|
|
32
|
+
? product.tags.map((t) => t.value)
|
|
33
|
+
: [];
|
|
34
|
+
transformedProduct.categories = (product?.categories || []).map((c) => c.name);
|
|
35
|
+
const prod = {
|
|
36
|
+
...transformedProduct,
|
|
37
|
+
...flattenedVariantFields,
|
|
38
|
+
};
|
|
39
|
+
return prod;
|
|
40
|
+
};
|
|
41
|
+
exports.transformProduct = transformProduct;
|
|
42
|
+
//# sourceMappingURL=transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformer.js","sourceRoot":"","sources":["../../src/utils/transformer.ts"],"names":[],"mappings":";;;AAAA,2CAA8C;AAE9C,MAAM,MAAM,GAAG,SAAS,CAAC;AAElB,MAAM,gBAAgB,GAAG,CAAC,OAAY,EAAE,EAAE;IAC/C,IAAI,kBAAkB,GAAG,EAAE,GAAG,OAAO,EAA6B,CAAC;IAEnE,MAAM,UAAU,GAAG,mBAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACjD,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,UAAU,CAAC,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,CAAC;IAE3C,MAAM,sBAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;QACtE,mBAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACxB,IAAI,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE;gBACjC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACxD,GAAG,CAAC,GAAG,MAAM,gBAAgB,CAAC;oBAC5B,GAAG,CAAC,GAAG,MAAM,gBAAgB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAChD,OAAO;aACR;YACD,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,UAAU,CAAC,CAAC;IAEf,kBAAkB,CAAC,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC;IACzC,kBAAkB,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;IACnE,kBAAkB,CAAC,gBAAgB;QACjC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC;IACjD,kBAAkB,CAAC,iBAAiB;QAClC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;IAClD,kBAAkB,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI;QAC1C,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,CAAC,CAAC,EAAE,CAAC;IACP,kBAAkB,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAC7D,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CACd,CAAC;IAEF,MAAM,IAAI,GAAG;QACX,GAAG,kBAAkB;QACrB,GAAG,sBAAsB;KAC1B,CAAC;IAEF,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAzCW,QAAA,gBAAgB,oBAyC3B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "medusa-plugin-elasticsearch",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Elasticsearch search plugin for Medusa",
|
|
5
|
+
"author": "Peter Borodatyy <peterborodatyy@gmail.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"medusa-plugin",
|
|
9
|
+
"medusa-plugin-search",
|
|
10
|
+
"elasticsearch"
|
|
11
|
+
],
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"clean": "cross-env ./node_modules/.bin/rimraf dist",
|
|
17
|
+
"build": "cross-env npm run clean && tsc -p tsconfig.json",
|
|
18
|
+
"watch": "cross-env tsc --watch",
|
|
19
|
+
"test": "cross-env jest"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@elastic/elasticsearch": "^8.8.1",
|
|
23
|
+
"@medusajs/modules-sdk": "^1.8.7",
|
|
24
|
+
"@medusajs/types": "^1.8.7",
|
|
25
|
+
"@medusajs/utils": "^1.9.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@babel/cli": "^7.14.3",
|
|
29
|
+
"@babel/core": "^7.14.3",
|
|
30
|
+
"@types/jest": "^27.4.0",
|
|
31
|
+
"babel-preset-medusa-package": "^1.1.13",
|
|
32
|
+
"cross-env": "^7.0.3",
|
|
33
|
+
"eslint": "^6.8.0",
|
|
34
|
+
"jest": "^27.3.1",
|
|
35
|
+
"rimraf": "^3.0.2",
|
|
36
|
+
"typescript": "^4.5.2"
|
|
37
|
+
},
|
|
38
|
+
"jest": {
|
|
39
|
+
"globals": {
|
|
40
|
+
"ts-jest": {
|
|
41
|
+
"tsconfig": "tsconfig.spec.json"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"moduleFileExtensions": [
|
|
45
|
+
"js",
|
|
46
|
+
"json",
|
|
47
|
+
"ts"
|
|
48
|
+
],
|
|
49
|
+
"testPathIgnorePatterns": [
|
|
50
|
+
"/node_modules/",
|
|
51
|
+
"<rootDir>/node_modules/"
|
|
52
|
+
],
|
|
53
|
+
"rootDir": "src",
|
|
54
|
+
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|js)$",
|
|
55
|
+
"transform": {
|
|
56
|
+
".ts": "ts-jest"
|
|
57
|
+
},
|
|
58
|
+
"collectCoverageFrom": [
|
|
59
|
+
"**/*.(t|j)s"
|
|
60
|
+
],
|
|
61
|
+
"coverageDirectory": "./coverage",
|
|
62
|
+
"testEnvironment": "node"
|
|
63
|
+
}
|
|
64
|
+
}
|