@extravirgin/payload-plugin-meilisearch 0.0.1 → 0.0.2

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.
Files changed (51) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js.map +1 -0
  3. package/dist/indexCollections.d.ts +3 -0
  4. package/dist/indexCollections.js +395 -0
  5. package/dist/indexCollections.js.map +1 -0
  6. package/dist/mocks/mockFile.d.ts +1 -0
  7. package/dist/mocks/mockFile.js +3 -0
  8. package/dist/mocks/mockFile.js.map +1 -0
  9. package/dist/onInitExtension.d.ts +3 -0
  10. package/dist/onInitExtension.js +17 -0
  11. package/dist/onInitExtension.js.map +1 -0
  12. package/dist/plugin.d.ts +3 -0
  13. package/dist/plugin.js +103 -0
  14. package/dist/plugin.js.map +1 -0
  15. package/dist/types.d.ts +18 -0
  16. package/dist/types.js +3 -0
  17. package/dist/types.js.map +1 -0
  18. package/dist/webpack.d.ts +3 -0
  19. package/dist/webpack.js +32 -0
  20. package/dist/webpack.js.map +1 -0
  21. package/package.json +4 -1
  22. package/.editorconfig +0 -10
  23. package/.eslintrc.js +0 -17
  24. package/.github/workflows/test.yml +0 -19
  25. package/.prettierrc.js +0 -8
  26. package/dev/.env.example +0 -2
  27. package/dev/Dockerfile +0 -27
  28. package/dev/docker-compose.yml +0 -31
  29. package/dev/jest.config.js +0 -12
  30. package/dev/nodemon.json +0 -6
  31. package/dev/package.json +0 -35
  32. package/dev/plugin.spec.ts +0 -30
  33. package/dev/src/collections/Examples.ts +0 -17
  34. package/dev/src/collections/Users.ts +0 -15
  35. package/dev/src/mocks/fileStub.js +0 -1
  36. package/dev/src/payload.config.ts +0 -44
  37. package/dev/src/server.ts +0 -29
  38. package/dev/tsconfig.json +0 -34
  39. package/eslint-config/index.js +0 -15
  40. package/eslint-config/rules/import.js +0 -38
  41. package/eslint-config/rules/prettier.js +0 -7
  42. package/eslint-config/rules/style.js +0 -21
  43. package/eslint-config/rules/typescript.js +0 -628
  44. package/src/index.ts +0 -2
  45. package/src/indexCollections.ts +0 -155
  46. package/src/mocks/mockFile.js +0 -1
  47. package/src/onInitExtension.ts +0 -16
  48. package/src/plugin.ts +0 -67
  49. package/src/types.ts +0 -20
  50. package/src/webpack.ts +0 -28
  51. package/tsconfig.json +0 -23
@@ -1,155 +0,0 @@
1
- import { CollectionConfig, Field } from "payload/dist/exports/types";
2
- import { PluginTypes } from "./types";
3
- import { MeiliSearch } from 'meilisearch';
4
- import { compile } from 'html-to-text';
5
- import {
6
- LexicalRichTextAdapter,
7
- convertLexicalToHTML,
8
- consolidateHTMLConverters,
9
- } from '@payloadcms/richtext-lexical';
10
-
11
- export const indexCollections = (collections: CollectionConfig[], config: PluginTypes) : CollectionConfig[] => {
12
-
13
- const getIndexName = (collectionSlug: string) => `${config?.indexPrefix ?? ''}${collectionSlug}`;
14
-
15
- const meilisearch = new MeiliSearch({
16
- host: config.host,
17
- apiKey: config.apiKey,
18
- });
19
-
20
- return collections.map((collection) => {
21
-
22
- if(config?.collections && !config?.collections.find(c => c.slug === collection.slug)) {
23
- return collection;
24
- }
25
-
26
- return {
27
- ...collection,
28
- hooks: {
29
- ...(collection.hooks || {}),
30
- afterChange: [
31
- ...(collection.hooks?.afterChange || []),
32
- async ({ doc, operation, req }) => {
33
- await upsertIndex(meilisearch, getIndexName(collection.slug));
34
- const index = meilisearch.index(getIndexName(collection.slug));
35
- if (operation === 'create' || operation === 'update') {
36
- const transformedDoc = { ...await transformDocumentForMeilisearch(doc, collection.fields, req), id: doc.id };
37
- await index.addDocuments([transformedDoc]);
38
- } else if (operation === 'delete') {
39
- await index.deleteDocument(doc.id);
40
- }
41
- },
42
- ],
43
- },
44
- };
45
- });
46
- }
47
-
48
- async function upsertIndex(client: MeiliSearch, indexUID: string) {
49
- try {
50
- // Attempt to retrieve the index
51
- await client.getIndex(indexUID)
52
- } catch (error) {
53
- // Check if the error is because the index was not found
54
- // @ts-ignore
55
- if (error?.cause?.code === 'index_not_found') {
56
- // Index doesn't exist; create it
57
- await client.createIndex(indexUID, {
58
- primaryKey: 'id',
59
- })
60
- console.log(`Index '${indexUID}' has been created.`)
61
- } else {
62
- // Rethrow any other errors
63
- throw error
64
- }
65
- }
66
- }
67
-
68
-
69
- const options = {
70
- wordwrap: 130,
71
- // ...
72
- };
73
-
74
- const compiledConvert = compile(options);
75
-
76
- // Helper function to extract text from HTML in nodejs
77
- function extractTextFromHTML(html: string): string {
78
- return compiledConvert(html);
79
- }
80
-
81
- // Helper function to transform a document for Meilisearch indexing
82
- async function transformDocumentForMeilisearch(doc: any, fields: Field[], req: Request): Promise<any> {
83
-
84
- const transformedDoc: any = {};
85
-
86
- await Promise.all(fields.map(async (field) => {
87
- if (field.type === 'richText') {
88
- // For rich text fields, convert Lexical to HTML, then extract text
89
-
90
- const lexicalAdapter: LexicalRichTextAdapter =
91
- field.editor as LexicalRichTextAdapter
92
-
93
- const sanitizedServerEditorConfig: any = lexicalAdapter.editorConfig
94
-
95
- const html = await convertLexicalToHTML({
96
- converters: consolidateHTMLConverters({editorConfig: sanitizedServerEditorConfig}),
97
- data: doc[field.name],
98
- });
99
-
100
- transformedDoc[field.name] = extractTextFromHTML(html);
101
-
102
- } else if (field.type === 'array' && field.fields) {
103
- // For array fields, transform each item
104
- transformedDoc[field.name] = await Promise.all(
105
- (doc[field.name] || []).map((item: any) =>
106
- transformDocumentForMeilisearch(item, field.fields, req)
107
- )
108
- );
109
- } else if (field.type === 'tabs') {
110
- // For tab fields, transform each tab
111
- (await Promise.all(
112
- field.tabs.map(async (tab, index) => {
113
- return await transformDocumentForMeilisearch(doc, tab.fields, req)
114
- })
115
- )).forEach((t) => Object.assign(transformedDoc, t));
116
- } else if (field.type === 'blocks') {
117
-
118
- // For block fields, transform each block
119
- transformedDoc[field.name] = await Promise.all(
120
- (doc[field.name] || []).map(async (block: any) => {
121
- const fields = field.blocks.find(b => b.slug === block.blockType)?.fields
122
-
123
- if (!fields) {
124
- return {
125
- type: block.blockType,
126
- data: "",
127
- }
128
- }
129
-
130
- return {
131
- type: block.blockType,
132
- data: await transformDocumentForMeilisearch(block, fields, req),
133
- };
134
- })
135
- );
136
-
137
- } else if (field.type === 'group' && field.fields) {
138
- // For group fields, transform the nested fields
139
- transformedDoc[field.name] = await transformDocumentForMeilisearch(doc[field.name], field.fields, req);
140
- } else if (field.type === 'relationship' || field.type === 'upload') {
141
- // For relationship and upload fields, just include the ID
142
- transformedDoc[field.name] = doc[field.name]?.id || doc[field.name];
143
- } else {
144
- // For other field types, include as-is
145
- try {
146
- // @ts-ignore
147
- transformedDoc[field.name] = doc[field.name];
148
- } catch(err) {
149
- console.log(err, field, doc)
150
- }
151
- }
152
- }));
153
-
154
- return transformedDoc;
155
- }
@@ -1 +0,0 @@
1
- module.exports = {}
@@ -1,16 +0,0 @@
1
- import type { Payload } from 'payload/dist/payload'
2
-
3
- import type { PluginTypes } from './types'
4
-
5
- export const onInitExtension = (pluginOptions: PluginTypes, payload: Payload): void => {
6
- const { express: app } = payload
7
-
8
- if (!app) return
9
-
10
- try {
11
- // You can use the existing express app here to add middleware, routes, etc.
12
- // app.use(...)
13
- } catch (err: unknown) {
14
- payload.logger.error({ msg: 'Error in onInitExtension', err })
15
- }
16
- }
package/src/plugin.ts DELETED
@@ -1,67 +0,0 @@
1
- import type { Config, Plugin } from 'payload/config'
2
-
3
- import { onInitExtension } from './onInitExtension'
4
- import type { PluginTypes } from './types'
5
- import { extendWebpackConfig } from './webpack'
6
- import { indexCollections } from './indexCollections'
7
-
8
- type PluginType = (pluginOptions: PluginTypes) => Plugin
9
-
10
- export const meilisearchPlugin =
11
- (pluginOptions: PluginTypes): Plugin =>
12
- (incomingConfig) => {
13
- let config = { ...incomingConfig }
14
-
15
- // If you need to add a webpack alias, use this function to extend the webpack config
16
- const webpack = extendWebpackConfig(incomingConfig)
17
-
18
- config.admin = {
19
- ...(config.admin || {}),
20
- // If you extended the webpack config, add it back in here
21
- // If you did not extend the webpack config, you can remove this line
22
- webpack,
23
-
24
- // Add additional admin config here
25
- }
26
-
27
- // If the plugin is disabled, return the config without modifying it
28
- // The order of this check is important, we still want any webpack extensions to be applied even if the plugin is disabled
29
- if (pluginOptions.enabled === false) {
30
- return config
31
- }
32
-
33
- config.collections = [
34
- ...(indexCollections(config.collections || [], pluginOptions)),
35
- ]
36
-
37
- config.endpoints = [
38
- ...(config.endpoints || []),
39
- // {
40
- // path: '/custom-endpoint',
41
- // method: 'get',
42
- // root: true,
43
- // handler: (req, res): void => {
44
- // res.json({ message: 'Here is a custom endpoint' });
45
- // },
46
- // },
47
- // Add additional endpoints here
48
- ]
49
-
50
- config.globals = [
51
- ...(config.globals || []),
52
- // Add additional globals here
53
- ]
54
-
55
- config.hooks = {
56
- ...(config.hooks || {}),
57
- // Add additional hooks here
58
- }
59
-
60
- config.onInit = async payload => {
61
- if (incomingConfig.onInit) await incomingConfig.onInit(payload)
62
- // Add additional onInit code by using the onInitExtension function
63
- onInitExtension(pluginOptions, payload)
64
- }
65
-
66
- return config
67
- }
package/src/types.ts DELETED
@@ -1,20 +0,0 @@
1
- export interface PluginTypes {
2
- /**
3
- * Enable or disable plugin
4
- * @default false
5
- */
6
- enabled?: boolean
7
- host: string;
8
- apiKey: string;
9
- indexPrefix?: string;
10
- collections?: PluginCollectionConfig[];
11
- }
12
-
13
- export interface PluginCollectionConfig {
14
- slug: string;
15
- }
16
-
17
-
18
- export interface NewCollectionTypes {
19
- title: string
20
- }
package/src/webpack.ts DELETED
@@ -1,28 +0,0 @@
1
- import path from 'path'
2
- import type { Config } from 'payload/config'
3
- import type { Configuration as WebpackConfig } from 'webpack'
4
-
5
- export const extendWebpackConfig =
6
- (config: Config): ((webpackConfig: WebpackConfig) => WebpackConfig) =>
7
- webpackConfig => {
8
- const existingWebpackConfig =
9
- typeof config.admin?.webpack === 'function'
10
- ? config.admin.webpack(webpackConfig)
11
- : webpackConfig
12
-
13
- const mockModulePath = path.resolve(__dirname, './mocks/mockFile.js')
14
-
15
- const newWebpack = {
16
- ...existingWebpackConfig,
17
- resolve: {
18
- ...(existingWebpackConfig.resolve || {}),
19
- alias: {
20
- ...(existingWebpackConfig.resolve?.alias ? existingWebpackConfig.resolve.alias : {}),
21
- // Add additional aliases here like so:
22
- [path.resolve(__dirname, './yourFileHere')]: mockModulePath,
23
- },
24
- },
25
- }
26
-
27
- return newWebpack
28
- }
package/tsconfig.json DELETED
@@ -1,23 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "lib": [
4
- "dom",
5
- "dom.iterable",
6
- "esnext"
7
- ],
8
- "target": "es5",
9
- "outDir": "./dist",
10
- "allowJs": true,
11
- "module": "commonjs",
12
- "sourceMap": true,
13
- "jsx": "react",
14
- "esModuleInterop": true,
15
- "declaration": true,
16
- "declarationDir": "./dist",
17
- "skipLibCheck": true,
18
- "strict": true,
19
- },
20
- "include": [
21
- "src/**/*",
22
- ],
23
- }