@payloadcms/plugin-search 3.1.1 → 3.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.
Files changed (58) hide show
  1. package/dist/Search/hooks/syncWithSearch.d.ts.map +1 -1
  2. package/dist/Search/hooks/syncWithSearch.js +3 -167
  3. package/dist/Search/hooks/syncWithSearch.js.map +1 -1
  4. package/dist/Search/index.d.ts +2 -2
  5. package/dist/Search/index.d.ts.map +1 -1
  6. package/dist/Search/index.js +30 -2
  7. package/dist/Search/index.js.map +1 -1
  8. package/dist/Search/ui/LinkToDoc/index.client.d.ts.map +1 -0
  9. package/dist/Search/ui/LinkToDoc/index.client.js.map +1 -0
  10. package/dist/Search/ui/LinkToDoc/index.d.ts.map +1 -0
  11. package/dist/Search/ui/LinkToDoc/index.js.map +1 -0
  12. package/dist/Search/ui/ReindexButton/ReindexButtonLabel/index.d.ts +2 -0
  13. package/dist/Search/ui/ReindexButton/ReindexButtonLabel/index.d.ts.map +1 -0
  14. package/dist/Search/ui/ReindexButton/ReindexButtonLabel/index.js +13 -0
  15. package/dist/Search/ui/ReindexButton/ReindexButtonLabel/index.js.map +1 -0
  16. package/dist/Search/ui/ReindexButton/ReindexConfirmModal/index.d.ts +11 -0
  17. package/dist/Search/ui/ReindexButton/ReindexConfirmModal/index.d.ts.map +1 -0
  18. package/dist/Search/ui/ReindexButton/ReindexConfirmModal/index.js +45 -0
  19. package/dist/Search/ui/ReindexButton/ReindexConfirmModal/index.js.map +1 -0
  20. package/dist/Search/ui/ReindexButton/index.client.d.ts +4 -0
  21. package/dist/Search/ui/ReindexButton/index.client.d.ts.map +1 -0
  22. package/dist/Search/ui/ReindexButton/index.client.js +138 -0
  23. package/dist/Search/ui/ReindexButton/index.client.js.map +1 -0
  24. package/dist/Search/ui/ReindexButton/index.d.ts +3 -0
  25. package/dist/Search/ui/ReindexButton/index.d.ts.map +1 -0
  26. package/dist/Search/ui/ReindexButton/index.js +36 -0
  27. package/dist/Search/ui/ReindexButton/index.js.map +1 -0
  28. package/dist/Search/ui/ReindexButton/types.d.ts +14 -0
  29. package/dist/Search/ui/ReindexButton/types.d.ts.map +1 -0
  30. package/dist/Search/ui/ReindexButton/types.js +3 -0
  31. package/dist/Search/ui/ReindexButton/types.js.map +1 -0
  32. package/dist/exports/client.d.ts +2 -1
  33. package/dist/exports/client.d.ts.map +1 -1
  34. package/dist/exports/client.js +2 -1
  35. package/dist/exports/client.js.map +1 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +8 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/types.d.ts +19 -3
  40. package/dist/types.d.ts.map +1 -1
  41. package/dist/types.js.map +1 -1
  42. package/dist/utilities/generateReindexHandler.d.ts +4 -0
  43. package/dist/utilities/generateReindexHandler.d.ts.map +1 -0
  44. package/dist/utilities/generateReindexHandler.js +172 -0
  45. package/dist/utilities/generateReindexHandler.js.map +1 -0
  46. package/dist/utilities/syncDocAsSearchIndex.d.ts +3 -0
  47. package/dist/utilities/syncDocAsSearchIndex.d.ts.map +1 -0
  48. package/dist/utilities/syncDocAsSearchIndex.js +173 -0
  49. package/dist/utilities/syncDocAsSearchIndex.js.map +1 -0
  50. package/package.json +6 -5
  51. package/dist/Search/ui/index.client.d.ts.map +0 -1
  52. package/dist/Search/ui/index.client.js.map +0 -1
  53. package/dist/Search/ui/index.d.ts.map +0 -1
  54. package/dist/Search/ui/index.js.map +0 -1
  55. /package/dist/Search/ui/{index.client.d.ts → LinkToDoc/index.client.d.ts} +0 -0
  56. /package/dist/Search/ui/{index.client.js → LinkToDoc/index.client.js} +0 -0
  57. /package/dist/Search/ui/{index.d.ts → LinkToDoc/index.d.ts} +0 -0
  58. /package/dist/Search/ui/{index.js → LinkToDoc/index.js} +0 -0
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ReindexButtonClient } from './index.client.js';
3
+ export const ReindexButton = (props)=>{
4
+ const { collectionLabels, i18n, searchCollections, searchSlug } = props;
5
+ const getStaticLocalizedPluralLabels = ()=>{
6
+ return Object.fromEntries(searchCollections.map((collection)=>{
7
+ const labels = collectionLabels[collection];
8
+ const pluralLabel = labels?.plural;
9
+ if (typeof pluralLabel === 'function') {
10
+ return [
11
+ collection,
12
+ pluralLabel({
13
+ t: i18n.t
14
+ })
15
+ ];
16
+ }
17
+ if (pluralLabel) {
18
+ return [
19
+ collection,
20
+ pluralLabel
21
+ ];
22
+ }
23
+ return [
24
+ collection,
25
+ collection
26
+ ];
27
+ }));
28
+ };
29
+ return /*#__PURE__*/ _jsx(ReindexButtonClient, {
30
+ collectionLabels: getStaticLocalizedPluralLabels(),
31
+ searchCollections: searchCollections,
32
+ searchSlug: searchSlug
33
+ });
34
+ };
35
+
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/Search/ui/ReindexButton/index.tsx"],"sourcesContent":["import type { SearchReindexButtonServerComponent } from './types.js'\n\nimport { ReindexButtonClient } from './index.client.js'\n\nexport const ReindexButton: SearchReindexButtonServerComponent = (props) => {\n const { collectionLabels, i18n, searchCollections, searchSlug } = props\n\n const getStaticLocalizedPluralLabels = () => {\n return Object.fromEntries(\n searchCollections.map((collection) => {\n const labels = collectionLabels[collection]\n const pluralLabel = labels?.plural\n\n if (typeof pluralLabel === 'function') {\n return [collection, pluralLabel({ t: i18n.t })]\n }\n\n if (pluralLabel) {\n return [collection, pluralLabel]\n }\n\n return [collection, collection]\n }),\n )\n }\n\n return (\n <ReindexButtonClient\n collectionLabels={getStaticLocalizedPluralLabels()}\n searchCollections={searchCollections}\n searchSlug={searchSlug}\n />\n )\n}\n"],"names":["ReindexButtonClient","ReindexButton","props","collectionLabels","i18n","searchCollections","searchSlug","getStaticLocalizedPluralLabels","Object","fromEntries","map","collection","labels","pluralLabel","plural","t"],"mappings":";AAEA,SAASA,mBAAmB,QAAQ,oBAAmB;AAEvD,OAAO,MAAMC,gBAAoD,CAACC;IAChE,MAAM,EAAEC,gBAAgB,EAAEC,IAAI,EAAEC,iBAAiB,EAAEC,UAAU,EAAE,GAAGJ;IAElE,MAAMK,iCAAiC;QACrC,OAAOC,OAAOC,WAAW,CACvBJ,kBAAkBK,GAAG,CAAC,CAACC;YACrB,MAAMC,SAAST,gBAAgB,CAACQ,WAAW;YAC3C,MAAME,cAAcD,QAAQE;YAE5B,IAAI,OAAOD,gBAAgB,YAAY;gBACrC,OAAO;oBAACF;oBAAYE,YAAY;wBAAEE,GAAGX,KAAKW,CAAC;oBAAC;iBAAG;YACjD;YAEA,IAAIF,aAAa;gBACf,OAAO;oBAACF;oBAAYE;iBAAY;YAClC;YAEA,OAAO;gBAACF;gBAAYA;aAAW;QACjC;IAEJ;IAEA,qBACE,KAACX;QACCG,kBAAkBI;QAClBF,mBAAmBA;QACnBC,YAAYA;;AAGlB,EAAC"}
@@ -0,0 +1,14 @@
1
+ import type { CustomComponent, PayloadServerReactComponent, StaticLabel } from 'payload';
2
+ import type { CollectionLabels } from '../../../types.js';
3
+ export type ReindexButtonProps = {
4
+ collectionLabels: Record<string, StaticLabel>;
5
+ searchCollections: string[];
6
+ searchSlug: string;
7
+ };
8
+ type ReindexButtonServerProps = {
9
+ collectionLabels: CollectionLabels;
10
+ } & ReindexButtonProps;
11
+ export type SearchReindexButtonClientComponent = ReindexButtonProps;
12
+ export type SearchReindexButtonServerComponent = PayloadServerReactComponent<CustomComponent<ReindexButtonServerProps>>;
13
+ export {};
14
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/Search/ui/ReindexButton/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,2BAA2B,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAExF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAC7C,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,KAAK,wBAAwB,GAAG;IAC9B,gBAAgB,EAAE,gBAAgB,CAAA;CACnC,GAAG,kBAAkB,CAAA;AAEtB,MAAM,MAAM,kCAAkC,GAAG,kBAAkB,CAAA;AACnE,MAAM,MAAM,kCAAkC,GAAG,2BAA2B,CAC1E,eAAe,CAAC,wBAAwB,CAAC,CAC1C,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/Search/ui/ReindexButton/types.ts"],"sourcesContent":["import type { CustomComponent, PayloadServerReactComponent, StaticLabel } from 'payload'\n\nimport type { CollectionLabels } from '../../../types.js'\n\nexport type ReindexButtonProps = {\n collectionLabels: Record<string, StaticLabel>\n searchCollections: string[]\n searchSlug: string\n}\n\ntype ReindexButtonServerProps = {\n collectionLabels: CollectionLabels\n} & ReindexButtonProps\n\nexport type SearchReindexButtonClientComponent = ReindexButtonProps\nexport type SearchReindexButtonServerComponent = PayloadServerReactComponent<\n CustomComponent<ReindexButtonServerProps>\n>\n"],"names":[],"mappings":"AAeA,WAEC"}
@@ -1,2 +1,3 @@
1
- export { LinkToDoc } from '../Search/ui/index.js';
1
+ export { LinkToDoc } from '../Search/ui/LinkToDoc/index.js';
2
+ export { ReindexButton } from '../Search/ui/ReindexButton/index.js';
2
3
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAA"}
@@ -1,3 +1,4 @@
1
- export { LinkToDoc } from '../Search/ui/index.js';
1
+ export { LinkToDoc } from '../Search/ui/LinkToDoc/index.js';
2
+ export { ReindexButton } from '../Search/ui/ReindexButton/index.js';
2
3
 
3
4
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { LinkToDoc } from '../Search/ui/index.js'\n"],"names":["LinkToDoc"],"mappings":"AAAA,SAASA,SAAS,QAAQ,wBAAuB"}
1
+ {"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { LinkToDoc } from '../Search/ui/LinkToDoc/index.js'\nexport { ReindexButton } from '../Search/ui/ReindexButton/index.js'\n"],"names":["LinkToDoc","ReindexButton"],"mappings":"AAAA,SAASA,SAAS,QAAQ,kCAAiC;AAC3D,SAASC,aAAa,QAAQ,sCAAqC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAwD,MAAM,EAAE,MAAM,SAAS,CAAA;AAE3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AASpD,eAAO,MAAM,YAAY,yBACA,kBAAkB,cAChC,MAAM,KAAG,MAoEjB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAwD,MAAM,EAAE,MAAM,SAAS,CAAA;AAE3F,OAAO,KAAK,EAAE,kBAAkB,EAAiC,MAAM,YAAY,CAAA;AASnF,eAAO,MAAM,YAAY,yBACA,kBAAkB,cAChC,MAAM,KAAG,MAmFjB,CAAA"}
package/dist/index.js CHANGED
@@ -8,9 +8,17 @@ export const searchPlugin = (incomingPluginConfig)=>(config)=>{
8
8
  const shouldLocalize = typeof incomingPluginConfig.localize === 'boolean' ? incomingPluginConfig.localize : Boolean(config.localization);
9
9
  incomingPluginConfig.localize = shouldLocalize;
10
10
  if (collections) {
11
+ const locales = config.localization ? config.localization.locales.map((localeConfig)=>typeof localeConfig === 'string' ? localeConfig : localeConfig.code) : [];
12
+ const labels = Object.fromEntries(collections.filter(({ slug })=>incomingPluginConfig.collections?.includes(slug)).map((collection)=>[
13
+ collection.slug,
14
+ collection.labels
15
+ ]));
11
16
  const pluginConfig = {
12
17
  // write any config defaults here
13
18
  deleteDrafts: true,
19
+ labels,
20
+ locales,
21
+ reindexBatchSize: incomingPluginConfig?.reindexBatchSize || 50,
14
22
  syncDrafts: false,
15
23
  ...incomingPluginConfig
16
24
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionAfterDeleteHook, Config } from 'payload'\n\nimport type { SearchPluginConfig } from './types.js'\n\nimport { deleteFromSearch } from './Search/hooks/deleteFromSearch.js'\nimport { syncWithSearch } from './Search/hooks/syncWithSearch.js'\nimport { generateSearchCollection } from './Search/index.js'\n\ntype CollectionAfterChangeHookArgs = Parameters<CollectionAfterChangeHook>[0]\ntype CollectionAfterDeleteHookArgs = Parameters<CollectionAfterDeleteHook>[0]\n\nexport const searchPlugin =\n (incomingPluginConfig: SearchPluginConfig) =>\n (config: Config): Config => {\n const { collections } = config\n\n // If the user defines `localize` to either true or false, use that\n // Otherwise, set it based on if their config has localization enabled or disabled\n const shouldLocalize =\n typeof incomingPluginConfig.localize === 'boolean'\n ? incomingPluginConfig.localize\n : Boolean(config.localization)\n incomingPluginConfig.localize = shouldLocalize\n\n if (collections) {\n const pluginConfig: SearchPluginConfig = {\n // write any config defaults here\n deleteDrafts: true,\n syncDrafts: false,\n ...incomingPluginConfig,\n }\n\n // add afterChange and afterDelete hooks to every search-enabled collection\n const collectionsWithSearchHooks = config?.collections\n ?.map((collection) => {\n const { hooks: existingHooks } = collection\n\n const enabledCollections = pluginConfig.collections || []\n const isEnabled = enabledCollections.indexOf(collection.slug) > -1\n if (isEnabled) {\n return {\n ...collection,\n hooks: {\n ...collection.hooks,\n afterChange: [\n ...(existingHooks?.afterChange || []),\n async (args: CollectionAfterChangeHookArgs) => {\n await syncWithSearch({\n ...args,\n collection: collection.slug,\n pluginConfig,\n })\n },\n ],\n afterDelete: [\n ...(existingHooks?.afterDelete || []),\n async (args: CollectionAfterDeleteHookArgs) => {\n await deleteFromSearch({\n ...args,\n pluginConfig,\n })\n },\n ],\n },\n }\n }\n\n return collection\n })\n .filter(Boolean)\n\n return {\n ...config,\n collections: [\n ...(collectionsWithSearchHooks || []),\n generateSearchCollection(pluginConfig),\n ],\n }\n }\n\n return config\n }\n"],"names":["deleteFromSearch","syncWithSearch","generateSearchCollection","searchPlugin","incomingPluginConfig","config","collections","shouldLocalize","localize","Boolean","localization","pluginConfig","deleteDrafts","syncDrafts","collectionsWithSearchHooks","map","collection","hooks","existingHooks","enabledCollections","isEnabled","indexOf","slug","afterChange","args","afterDelete","filter"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,qCAAoC;AACrE,SAASC,cAAc,QAAQ,mCAAkC;AACjE,SAASC,wBAAwB,QAAQ,oBAAmB;AAK5D,OAAO,MAAMC,eACX,CAACC,uBACD,CAACC;QACC,MAAM,EAAEC,WAAW,EAAE,GAAGD;QAExB,mEAAmE;QACnE,kFAAkF;QAClF,MAAME,iBACJ,OAAOH,qBAAqBI,QAAQ,KAAK,YACrCJ,qBAAqBI,QAAQ,GAC7BC,QAAQJ,OAAOK,YAAY;QACjCN,qBAAqBI,QAAQ,GAAGD;QAEhC,IAAID,aAAa;YACf,MAAMK,eAAmC;gBACvC,iCAAiC;gBACjCC,cAAc;gBACdC,YAAY;gBACZ,GAAGT,oBAAoB;YACzB;YAEA,2EAA2E;YAC3E,MAAMU,6BAA6BT,QAAQC,aACvCS,IAAI,CAACC;gBACL,MAAM,EAAEC,OAAOC,aAAa,EAAE,GAAGF;gBAEjC,MAAMG,qBAAqBR,aAAaL,WAAW,IAAI,EAAE;gBACzD,MAAMc,YAAYD,mBAAmBE,OAAO,CAACL,WAAWM,IAAI,IAAI,CAAC;gBACjE,IAAIF,WAAW;oBACb,OAAO;wBACL,GAAGJ,UAAU;wBACbC,OAAO;4BACL,GAAGD,WAAWC,KAAK;4BACnBM,aAAa;mCACPL,eAAeK,eAAe,EAAE;gCACpC,OAAOC;oCACL,MAAMvB,eAAe;wCACnB,GAAGuB,IAAI;wCACPR,YAAYA,WAAWM,IAAI;wCAC3BX;oCACF;gCACF;6BACD;4BACDc,aAAa;mCACPP,eAAeO,eAAe,EAAE;gCACpC,OAAOD;oCACL,MAAMxB,iBAAiB;wCACrB,GAAGwB,IAAI;wCACPb;oCACF;gCACF;6BACD;wBACH;oBACF;gBACF;gBAEA,OAAOK;YACT,GACCU,OAAOjB;YAEV,OAAO;gBACL,GAAGJ,MAAM;gBACTC,aAAa;uBACPQ,8BAA8B,EAAE;oBACpCZ,yBAAyBS;iBAC1B;YACH;QACF;QAEA,OAAON;IACT,EAAC"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionAfterDeleteHook, Config } from 'payload'\n\nimport type { SearchPluginConfig, SearchPluginConfigWithLocales } from './types.js'\n\nimport { deleteFromSearch } from './Search/hooks/deleteFromSearch.js'\nimport { syncWithSearch } from './Search/hooks/syncWithSearch.js'\nimport { generateSearchCollection } from './Search/index.js'\n\ntype CollectionAfterChangeHookArgs = Parameters<CollectionAfterChangeHook>[0]\ntype CollectionAfterDeleteHookArgs = Parameters<CollectionAfterDeleteHook>[0]\n\nexport const searchPlugin =\n (incomingPluginConfig: SearchPluginConfig) =>\n (config: Config): Config => {\n const { collections } = config\n\n // If the user defines `localize` to either true or false, use that\n // Otherwise, set it based on if their config has localization enabled or disabled\n const shouldLocalize =\n typeof incomingPluginConfig.localize === 'boolean'\n ? incomingPluginConfig.localize\n : Boolean(config.localization)\n incomingPluginConfig.localize = shouldLocalize\n\n if (collections) {\n const locales = config.localization\n ? config.localization.locales.map((localeConfig) =>\n typeof localeConfig === 'string' ? localeConfig : localeConfig.code,\n )\n : []\n\n const labels = Object.fromEntries(\n collections\n .filter(({ slug }) => incomingPluginConfig.collections?.includes(slug))\n .map((collection) => [collection.slug, collection.labels]),\n )\n\n const pluginConfig: SearchPluginConfigWithLocales = {\n // write any config defaults here\n deleteDrafts: true,\n labels,\n locales,\n reindexBatchSize: incomingPluginConfig?.reindexBatchSize || 50,\n syncDrafts: false,\n ...incomingPluginConfig,\n }\n\n // add afterChange and afterDelete hooks to every search-enabled collection\n const collectionsWithSearchHooks = config?.collections\n ?.map((collection) => {\n const { hooks: existingHooks } = collection\n\n const enabledCollections = pluginConfig.collections || []\n const isEnabled = enabledCollections.indexOf(collection.slug) > -1\n if (isEnabled) {\n return {\n ...collection,\n hooks: {\n ...collection.hooks,\n afterChange: [\n ...(existingHooks?.afterChange || []),\n async (args: CollectionAfterChangeHookArgs) => {\n await syncWithSearch({\n ...args,\n collection: collection.slug,\n pluginConfig,\n })\n },\n ],\n afterDelete: [\n ...(existingHooks?.afterDelete || []),\n async (args: CollectionAfterDeleteHookArgs) => {\n await deleteFromSearch({\n ...args,\n pluginConfig,\n })\n },\n ],\n },\n }\n }\n\n return collection\n })\n .filter(Boolean)\n\n return {\n ...config,\n collections: [\n ...(collectionsWithSearchHooks || []),\n generateSearchCollection(pluginConfig),\n ],\n }\n }\n\n return config\n }\n"],"names":["deleteFromSearch","syncWithSearch","generateSearchCollection","searchPlugin","incomingPluginConfig","config","collections","shouldLocalize","localize","Boolean","localization","locales","map","localeConfig","code","labels","Object","fromEntries","filter","slug","includes","collection","pluginConfig","deleteDrafts","reindexBatchSize","syncDrafts","collectionsWithSearchHooks","hooks","existingHooks","enabledCollections","isEnabled","indexOf","afterChange","args","afterDelete"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,qCAAoC;AACrE,SAASC,cAAc,QAAQ,mCAAkC;AACjE,SAASC,wBAAwB,QAAQ,oBAAmB;AAK5D,OAAO,MAAMC,eACX,CAACC,uBACD,CAACC;QACC,MAAM,EAAEC,WAAW,EAAE,GAAGD;QAExB,mEAAmE;QACnE,kFAAkF;QAClF,MAAME,iBACJ,OAAOH,qBAAqBI,QAAQ,KAAK,YACrCJ,qBAAqBI,QAAQ,GAC7BC,QAAQJ,OAAOK,YAAY;QACjCN,qBAAqBI,QAAQ,GAAGD;QAEhC,IAAID,aAAa;YACf,MAAMK,UAAUN,OAAOK,YAAY,GAC/BL,OAAOK,YAAY,CAACC,OAAO,CAACC,GAAG,CAAC,CAACC,eAC/B,OAAOA,iBAAiB,WAAWA,eAAeA,aAAaC,IAAI,IAErE,EAAE;YAEN,MAAMC,SAASC,OAAOC,WAAW,CAC/BX,YACGY,MAAM,CAAC,CAAC,EAAEC,IAAI,EAAE,GAAKf,qBAAqBE,WAAW,EAAEc,SAASD,OAChEP,GAAG,CAAC,CAACS,aAAe;oBAACA,WAAWF,IAAI;oBAAEE,WAAWN,MAAM;iBAAC;YAG7D,MAAMO,eAA8C;gBAClD,iCAAiC;gBACjCC,cAAc;gBACdR;gBACAJ;gBACAa,kBAAkBpB,sBAAsBoB,oBAAoB;gBAC5DC,YAAY;gBACZ,GAAGrB,oBAAoB;YACzB;YAEA,2EAA2E;YAC3E,MAAMsB,6BAA6BrB,QAAQC,aACvCM,IAAI,CAACS;gBACL,MAAM,EAAEM,OAAOC,aAAa,EAAE,GAAGP;gBAEjC,MAAMQ,qBAAqBP,aAAahB,WAAW,IAAI,EAAE;gBACzD,MAAMwB,YAAYD,mBAAmBE,OAAO,CAACV,WAAWF,IAAI,IAAI,CAAC;gBACjE,IAAIW,WAAW;oBACb,OAAO;wBACL,GAAGT,UAAU;wBACbM,OAAO;4BACL,GAAGN,WAAWM,KAAK;4BACnBK,aAAa;mCACPJ,eAAeI,eAAe,EAAE;gCACpC,OAAOC;oCACL,MAAMhC,eAAe;wCACnB,GAAGgC,IAAI;wCACPZ,YAAYA,WAAWF,IAAI;wCAC3BG;oCACF;gCACF;6BACD;4BACDY,aAAa;mCACPN,eAAeM,eAAe,EAAE;gCACpC,OAAOD;oCACL,MAAMjC,iBAAiB;wCACrB,GAAGiC,IAAI;wCACPX;oCACF;gCACF;6BACD;wBACH;oBACF;gBACF;gBAEA,OAAOD;YACT,GACCH,OAAOT;YAEV,OAAO;gBACL,GAAGJ,MAAM;gBACTC,aAAa;uBACPoB,8BAA8B,EAAE;oBACpCxB,yBAAyBoB;iBAC1B;YACH;QACF;QAEA,OAAOjB;IACT,EAAC"}
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { CollectionAfterChangeHook, CollectionAfterDeleteHook, CollectionConfig, Field, Payload, PayloadRequest } from 'payload';
1
+ import type { CollectionAfterChangeHook, CollectionAfterDeleteHook, CollectionConfig, Field, LabelFunction, Payload, PayloadRequest, StaticLabel } from 'payload';
2
2
  export type DocToSync = {
3
3
  [key: string]: any;
4
4
  doc: {
@@ -26,15 +26,31 @@ export type SearchPluginConfig = {
26
26
  };
27
27
  deleteDrafts?: boolean;
28
28
  localize?: boolean;
29
+ reindexBatchSize?: number;
29
30
  searchOverrides?: {
30
31
  fields?: FieldsOverride;
31
32
  } & Partial<Omit<CollectionConfig, 'fields'>>;
32
33
  syncDrafts?: boolean;
33
34
  };
34
- export type SyncWithSearch = (Args: {
35
+ export type CollectionLabels = {
36
+ [collection: string]: {
37
+ plural?: LabelFunction | StaticLabel;
38
+ singular?: LabelFunction | StaticLabel;
39
+ };
40
+ };
41
+ export type SearchPluginConfigWithLocales = {
42
+ labels?: CollectionLabels;
43
+ locales?: string[];
44
+ } & SearchPluginConfig;
45
+ export type SyncWithSearchArgs = {
35
46
  collection: string;
36
47
  pluginConfig: SearchPluginConfig;
37
- } & Omit<Parameters<CollectionAfterChangeHook>[0], 'collection'>) => ReturnType<CollectionAfterChangeHook>;
48
+ } & Omit<Parameters<CollectionAfterChangeHook>[0], 'collection'>;
49
+ export type SyncDocArgs = {
50
+ locale?: string;
51
+ onSyncError?: () => void;
52
+ } & Omit<SyncWithSearchArgs, 'context' | 'previousDoc'>;
53
+ export type SyncWithSearch = (Args: SyncWithSearchArgs) => ReturnType<CollectionAfterChangeHook>;
38
54
  export type DeleteFromSearch = (Args: {
39
55
  pluginConfig: SearchPluginConfig;
40
56
  } & Omit<Parameters<CollectionAfterDeleteHook>[0], 'collection'>) => ReturnType<CollectionAfterDeleteHook>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,KAAK,EACL,OAAO,EACP,cAAc,EACf,MAAM,SAAS,CAAA;AAEhB,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;IAClB,GAAG,EAAE;QACH,UAAU,EAAE,MAAM,CAAA;QAClB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE;IAC9B,WAAW,EAAE;QACX,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KACnB,CAAA;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,cAAc,CAAA;IACnB,SAAS,EAAE,SAAS,CAAA;CACrB,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;AAEpC,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE;IAAE,aAAa,EAAE,KAAK,EAAE,CAAA;CAAE,KAAK,KAAK,EAAE,CAAA;AAE1E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,iBAAiB,CAAC,EAAE;QAClB,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAA;KACxE,CAAA;IACD,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,eAAe,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAA;IACzF,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAID,MAAM,MAAM,cAAc,GAAG,CAC3B,IAAI,EAAE;IACJ,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,kBAAkB,CAAA;CACjC,GAAG,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,KAC7D,UAAU,CAAC,yBAAyB,CAAC,CAAA;AAE1C,MAAM,MAAM,gBAAgB,GAAG,CAC7B,IAAI,EAAE;IACJ,YAAY,EAAE,kBAAkB,CAAA;CACjC,GAAG,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,KAC7D,UAAU,CAAC,yBAAyB,CAAC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,KAAK,EACL,aAAa,EAEb,OAAO,EACP,cAAc,EACd,WAAW,EACZ,MAAM,SAAS,CAAA;AAEhB,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;IAClB,GAAG,EAAE;QACH,UAAU,EAAE,MAAM,CAAA;QAClB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE;IAC9B,WAAW,EAAE;QACX,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KACnB,CAAA;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,cAAc,CAAA;IACnB,SAAS,EAAE,SAAS,CAAA;CACrB,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;AAEpC,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE;IAAE,aAAa,EAAE,KAAK,EAAE,CAAA;CAAE,KAAK,KAAK,EAAE,CAAA;AAE1E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,iBAAiB,CAAC,EAAE;QAClB,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAA;KACxE,CAAA;IACD,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAA;IACzF,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,CAAC,UAAU,EAAE,MAAM,GAAG;QACpB,MAAM,CAAC,EAAE,aAAa,GAAG,WAAW,CAAA;QACpC,QAAQ,CAAC,EAAE,aAAa,GAAG,WAAW,CAAA;KACvC,CAAA;CACF,CAAA;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB,GAAG,kBAAkB,CAAA;AAEtB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,kBAAkB,CAAA;CACjC,GAAG,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;AAEhE,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;CACzB,GAAG,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,aAAa,CAAC,CAAA;AAIvD,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,kBAAkB,KAAK,UAAU,CAAC,yBAAyB,CAAC,CAAA;AAEhG,MAAM,MAAM,gBAAgB,GAAG,CAC7B,IAAI,EAAE;IACJ,YAAY,EAAE,kBAAkB,CAAA;CACjC,GAAG,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,KAC7D,UAAU,CAAC,yBAAyB,CAAC,CAAA"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n CollectionAfterChangeHook,\n CollectionAfterDeleteHook,\n CollectionConfig,\n Field,\n Payload,\n PayloadRequest,\n} from 'payload'\n\nexport type DocToSync = {\n [key: string]: any\n doc: {\n relationTo: string\n value: string\n }\n title: string\n}\n\nexport type BeforeSync = (args: {\n originalDoc: {\n [key: string]: any\n }\n payload: Payload\n req: PayloadRequest\n searchDoc: DocToSync\n}) => DocToSync | Promise<DocToSync>\n\nexport type FieldsOverride = (args: { defaultFields: Field[] }) => Field[]\n\nexport type SearchPluginConfig = {\n beforeSync?: BeforeSync\n collections?: string[]\n defaultPriorities?: {\n [collection: string]: ((doc: any) => number | Promise<number>) | number\n }\n deleteDrafts?: boolean\n localize?: boolean\n searchOverrides?: { fields?: FieldsOverride } & Partial<Omit<CollectionConfig, 'fields'>>\n syncDrafts?: boolean\n}\n\n// Extend the `CollectionAfterChangeHook` with more function args\n// Convert the `collection` arg from `SanitizedCollectionConfig` to a string\nexport type SyncWithSearch = (\n Args: {\n collection: string\n pluginConfig: SearchPluginConfig\n } & Omit<Parameters<CollectionAfterChangeHook>[0], 'collection'>,\n) => ReturnType<CollectionAfterChangeHook>\n\nexport type DeleteFromSearch = (\n Args: {\n pluginConfig: SearchPluginConfig\n } & Omit<Parameters<CollectionAfterDeleteHook>[0], 'collection'>,\n) => ReturnType<CollectionAfterDeleteHook>\n"],"names":[],"mappings":"AAkDA,WAI0C"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n CollectionAfterChangeHook,\n CollectionAfterDeleteHook,\n CollectionConfig,\n Field,\n LabelFunction,\n Locale,\n Payload,\n PayloadRequest,\n StaticLabel,\n} from 'payload'\n\nexport type DocToSync = {\n [key: string]: any\n doc: {\n relationTo: string\n value: string\n }\n title: string\n}\n\nexport type BeforeSync = (args: {\n originalDoc: {\n [key: string]: any\n }\n payload: Payload\n req: PayloadRequest\n searchDoc: DocToSync\n}) => DocToSync | Promise<DocToSync>\n\nexport type FieldsOverride = (args: { defaultFields: Field[] }) => Field[]\n\nexport type SearchPluginConfig = {\n beforeSync?: BeforeSync\n collections?: string[]\n defaultPriorities?: {\n [collection: string]: ((doc: any) => number | Promise<number>) | number\n }\n deleteDrafts?: boolean\n localize?: boolean\n reindexBatchSize?: number\n searchOverrides?: { fields?: FieldsOverride } & Partial<Omit<CollectionConfig, 'fields'>>\n syncDrafts?: boolean\n}\n\nexport type CollectionLabels = {\n [collection: string]: {\n plural?: LabelFunction | StaticLabel\n singular?: LabelFunction | StaticLabel\n }\n}\n\nexport type SearchPluginConfigWithLocales = {\n labels?: CollectionLabels\n locales?: string[]\n} & SearchPluginConfig\n\nexport type SyncWithSearchArgs = {\n collection: string\n pluginConfig: SearchPluginConfig\n} & Omit<Parameters<CollectionAfterChangeHook>[0], 'collection'>\n\nexport type SyncDocArgs = {\n locale?: string\n onSyncError?: () => void\n} & Omit<SyncWithSearchArgs, 'context' | 'previousDoc'>\n\n// Extend the `CollectionAfterChangeHook` with more function args\n// Convert the `collection` arg from `SanitizedCollectionConfig` to a string\nexport type SyncWithSearch = (Args: SyncWithSearchArgs) => ReturnType<CollectionAfterChangeHook>\n\nexport type DeleteFromSearch = (\n Args: {\n pluginConfig: SearchPluginConfig\n } & Omit<Parameters<CollectionAfterDeleteHook>[0], 'collection'>,\n) => ReturnType<CollectionAfterDeleteHook>\n"],"names":[],"mappings":"AAuEA,WAI0C"}
@@ -0,0 +1,4 @@
1
+ import type { PayloadHandler } from 'payload';
2
+ import type { SearchPluginConfigWithLocales } from '../types.js';
3
+ export declare const generateReindexHandler: (pluginConfig: SearchPluginConfigWithLocales) => PayloadHandler;
4
+ //# sourceMappingURL=generateReindexHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateReindexHandler.d.ts","sourceRoot":"","sources":["../../src/utilities/generateReindexHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAK7C,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAA;AAShE,eAAO,MAAM,sBAAsB,iBAClB,6BAA6B,KAAG,cAiJ9C,CAAA"}
@@ -0,0 +1,172 @@
1
+ import { addLocalesToRequestFromData, headersWithCors } from '@payloadcms/next/utilities';
2
+ import { commitTransaction, getAccessResults, initTransaction, killTransaction } from 'payload';
3
+ import { syncDocAsSearchIndex } from './syncDocAsSearchIndex.js';
4
+ export const generateReindexHandler = (pluginConfig)=>async (req)=>{
5
+ addLocalesToRequestFromData(req);
6
+ const { collections = [] } = await req.json();
7
+ const t = req.t;
8
+ const searchSlug = pluginConfig?.searchOverrides?.slug || 'search';
9
+ const searchCollections = pluginConfig?.collections || [];
10
+ const reindexLocales = pluginConfig?.locales?.length ? pluginConfig.locales : [
11
+ req.locale
12
+ ];
13
+ const validatePermissions = async ()=>{
14
+ const accessResults = await getAccessResults({
15
+ req
16
+ });
17
+ const searchAccessResults = accessResults.collections[searchSlug];
18
+ const permissions = [
19
+ searchAccessResults.delete,
20
+ searchAccessResults.update
21
+ ];
22
+ // plugin doesn't allow create by default:
23
+ // if user provided, then add it to check
24
+ if (pluginConfig.searchOverrides?.access?.create) {
25
+ permissions.push(searchAccessResults.create);
26
+ }
27
+ // plugin allows reads by anyone by default:
28
+ // so if user provided, then add to check
29
+ if (pluginConfig.searchOverrides?.access?.read) {
30
+ permissions.push(searchAccessResults.read);
31
+ }
32
+ return permissions.every(Boolean) ? {
33
+ isValid: true
34
+ } : {
35
+ isValid: false,
36
+ message: t('error:notAllowedToPerformAction')
37
+ };
38
+ };
39
+ const validateCollections = ()=>{
40
+ const collectionsAreValid = collections.every((col)=>searchCollections.includes(col));
41
+ return collections.length && collectionsAreValid ? {
42
+ isValid: true
43
+ } : {
44
+ isValid: false,
45
+ message: t('error:invalidRequestArgs', {
46
+ args: `'collections'`
47
+ })
48
+ };
49
+ };
50
+ const headers = headersWithCors({
51
+ headers: new Headers(),
52
+ req
53
+ });
54
+ const { isValid: hasPermissions, message: permissionError } = await validatePermissions();
55
+ if (!hasPermissions) {
56
+ return Response.json({
57
+ message: permissionError
58
+ }, {
59
+ headers,
60
+ status: 401
61
+ });
62
+ }
63
+ const { isValid: validCollections, message: collectionError } = validateCollections();
64
+ if (!validCollections) {
65
+ return Response.json({
66
+ message: collectionError
67
+ }, {
68
+ headers,
69
+ status: 400
70
+ });
71
+ }
72
+ const payload = req.payload;
73
+ const batchSize = pluginConfig.reindexBatchSize;
74
+ const defaultLocalApiProps = {
75
+ overrideAccess: false,
76
+ req,
77
+ user: req.user
78
+ };
79
+ let aggregateErrors = 0;
80
+ let aggregateDocs = 0;
81
+ const countDocuments = async (collection)=>{
82
+ const { totalDocs } = await payload.count({
83
+ collection,
84
+ ...defaultLocalApiProps,
85
+ req: undefined
86
+ });
87
+ return totalDocs;
88
+ };
89
+ const deleteIndexes = async (collection)=>{
90
+ await payload.delete({
91
+ collection: searchSlug,
92
+ depth: 0,
93
+ select: {
94
+ id: true
95
+ },
96
+ where: {
97
+ 'doc.relationTo': {
98
+ equals: collection
99
+ }
100
+ },
101
+ ...defaultLocalApiProps
102
+ });
103
+ };
104
+ const reindexCollection = async (collection)=>{
105
+ const totalDocs = await countDocuments(collection);
106
+ const totalBatches = Math.ceil(totalDocs / batchSize);
107
+ aggregateDocs += totalDocs;
108
+ for(let j = 0; j < reindexLocales.length; j++){
109
+ // create first index, then we update with other locales accordingly
110
+ const operation = j === 0 ? 'create' : 'update';
111
+ const localeToSync = reindexLocales[j];
112
+ for(let i = 0; i < totalBatches; i++){
113
+ const { docs } = await payload.find({
114
+ collection,
115
+ limit: batchSize,
116
+ locale: localeToSync,
117
+ page: i + 1,
118
+ ...defaultLocalApiProps
119
+ });
120
+ const promises = docs.map((doc)=>syncDocAsSearchIndex({
121
+ collection,
122
+ doc,
123
+ locale: localeToSync,
124
+ onSyncError: ()=>operation === 'create' && aggregateErrors++,
125
+ operation,
126
+ pluginConfig,
127
+ req
128
+ }));
129
+ // Sequentially await promises to avoid transaction issues
130
+ for (const promise of promises){
131
+ await promise;
132
+ }
133
+ }
134
+ }
135
+ };
136
+ await initTransaction(req);
137
+ for (const collection of collections){
138
+ try {
139
+ await deleteIndexes(collection);
140
+ await reindexCollection(collection);
141
+ } catch (err) {
142
+ const message = t('error:unableToReindexCollection', {
143
+ collection
144
+ });
145
+ payload.logger.error({
146
+ err,
147
+ msg: message
148
+ });
149
+ await killTransaction(req);
150
+ return Response.json({
151
+ message
152
+ }, {
153
+ headers,
154
+ status: 500
155
+ });
156
+ }
157
+ }
158
+ const message = t('general:successfullyReindexed', {
159
+ collections: collections.join(', '),
160
+ count: aggregateDocs - aggregateErrors,
161
+ total: aggregateDocs
162
+ });
163
+ await commitTransaction(req);
164
+ return Response.json({
165
+ message
166
+ }, {
167
+ headers,
168
+ status: 200
169
+ });
170
+ };
171
+
172
+ //# sourceMappingURL=generateReindexHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utilities/generateReindexHandler.ts"],"sourcesContent":["import type { PayloadHandler } from 'payload'\n\nimport { addLocalesToRequestFromData, headersWithCors } from '@payloadcms/next/utilities'\nimport { commitTransaction, getAccessResults, initTransaction, killTransaction } from 'payload'\n\nimport type { SearchPluginConfigWithLocales } from '../types.js'\n\nimport { syncDocAsSearchIndex } from './syncDocAsSearchIndex.js'\n\ntype ValidationResult = {\n isValid: boolean\n message?: string\n}\n\nexport const generateReindexHandler =\n (pluginConfig: SearchPluginConfigWithLocales): PayloadHandler =>\n async (req) => {\n addLocalesToRequestFromData(req)\n const { collections = [] } = (await req.json()) as { collections: string[] }\n const t = req.t\n\n const searchSlug = pluginConfig?.searchOverrides?.slug || 'search'\n const searchCollections = pluginConfig?.collections || []\n const reindexLocales = pluginConfig?.locales?.length ? pluginConfig.locales : [req.locale]\n\n const validatePermissions = async (): Promise<ValidationResult> => {\n const accessResults = await getAccessResults({ req })\n const searchAccessResults = accessResults.collections[searchSlug]\n\n const permissions = [searchAccessResults.delete, searchAccessResults.update]\n // plugin doesn't allow create by default:\n // if user provided, then add it to check\n if (pluginConfig.searchOverrides?.access?.create) {\n permissions.push(searchAccessResults.create)\n }\n // plugin allows reads by anyone by default:\n // so if user provided, then add to check\n if (pluginConfig.searchOverrides?.access?.read) {\n permissions.push(searchAccessResults.read)\n }\n return permissions.every(Boolean)\n ? { isValid: true }\n : { isValid: false, message: t('error:notAllowedToPerformAction') }\n }\n\n const validateCollections = (): ValidationResult => {\n const collectionsAreValid = collections.every((col) => searchCollections.includes(col))\n return collections.length && collectionsAreValid\n ? { isValid: true }\n : { isValid: false, message: t('error:invalidRequestArgs', { args: `'collections'` }) }\n }\n\n const headers = headersWithCors({\n headers: new Headers(),\n req,\n })\n\n const { isValid: hasPermissions, message: permissionError } = await validatePermissions()\n if (!hasPermissions) {\n return Response.json({ message: permissionError }, { headers, status: 401 })\n }\n\n const { isValid: validCollections, message: collectionError } = validateCollections()\n if (!validCollections) {\n return Response.json({ message: collectionError }, { headers, status: 400 })\n }\n\n const payload = req.payload\n const batchSize = pluginConfig.reindexBatchSize\n\n const defaultLocalApiProps = {\n overrideAccess: false,\n req,\n user: req.user,\n }\n let aggregateErrors = 0\n let aggregateDocs = 0\n\n const countDocuments = async (collection: string): Promise<number> => {\n const { totalDocs } = await payload.count({\n collection,\n ...defaultLocalApiProps,\n req: undefined,\n })\n return totalDocs\n }\n\n const deleteIndexes = async (collection: string) => {\n await payload.delete({\n collection: searchSlug,\n depth: 0,\n select: { id: true },\n where: { 'doc.relationTo': { equals: collection } },\n ...defaultLocalApiProps,\n })\n }\n\n const reindexCollection = async (collection: string) => {\n const totalDocs = await countDocuments(collection)\n const totalBatches = Math.ceil(totalDocs / batchSize)\n aggregateDocs += totalDocs\n\n for (let j = 0; j < reindexLocales.length; j++) {\n // create first index, then we update with other locales accordingly\n const operation = j === 0 ? 'create' : 'update'\n const localeToSync = reindexLocales[j]\n\n for (let i = 0; i < totalBatches; i++) {\n const { docs } = await payload.find({\n collection,\n limit: batchSize,\n locale: localeToSync,\n page: i + 1,\n ...defaultLocalApiProps,\n })\n\n const promises = docs.map((doc) =>\n syncDocAsSearchIndex({\n collection,\n doc,\n locale: localeToSync,\n onSyncError: () => operation === 'create' && aggregateErrors++,\n operation,\n pluginConfig,\n req,\n }),\n )\n\n // Sequentially await promises to avoid transaction issues\n for (const promise of promises) {\n await promise\n }\n }\n }\n }\n\n await initTransaction(req)\n\n for (const collection of collections) {\n try {\n await deleteIndexes(collection)\n await reindexCollection(collection)\n } catch (err) {\n const message = t('error:unableToReindexCollection', { collection })\n payload.logger.error({ err, msg: message })\n\n await killTransaction(req)\n return Response.json({ message }, { headers, status: 500 })\n }\n }\n\n const message = t('general:successfullyReindexed', {\n collections: collections.join(', '),\n count: aggregateDocs - aggregateErrors,\n total: aggregateDocs,\n })\n\n await commitTransaction(req)\n\n return Response.json({ message }, { headers, status: 200 })\n }\n"],"names":["addLocalesToRequestFromData","headersWithCors","commitTransaction","getAccessResults","initTransaction","killTransaction","syncDocAsSearchIndex","generateReindexHandler","pluginConfig","req","collections","json","t","searchSlug","searchOverrides","slug","searchCollections","reindexLocales","locales","length","locale","validatePermissions","accessResults","searchAccessResults","permissions","delete","update","access","create","push","read","every","Boolean","isValid","message","validateCollections","collectionsAreValid","col","includes","args","headers","Headers","hasPermissions","permissionError","Response","status","validCollections","collectionError","payload","batchSize","reindexBatchSize","defaultLocalApiProps","overrideAccess","user","aggregateErrors","aggregateDocs","countDocuments","collection","totalDocs","count","undefined","deleteIndexes","depth","select","id","where","equals","reindexCollection","totalBatches","Math","ceil","j","operation","localeToSync","i","docs","find","limit","page","promises","map","doc","onSyncError","promise","err","logger","error","msg","join","total"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SyncDocArgs } from '../types.js';
2
+ export declare const syncDocAsSearchIndex: ({ collection, doc, locale, onSyncError, operation, pluginConfig, req: { payload }, req, }: SyncDocArgs) => Promise<any>;
3
+ //# sourceMappingURL=syncDocAsSearchIndex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncDocAsSearchIndex.d.ts","sourceRoot":"","sources":["../../src/utilities/syncDocAsSearchIndex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzD,eAAO,MAAM,oBAAoB,8FAS9B,WAAW,iBA+Kb,CAAA"}
@@ -0,0 +1,173 @@
1
+ export const syncDocAsSearchIndex = async ({ collection, doc, locale, onSyncError, operation, pluginConfig, req: { payload }, req })=>{
2
+ const { id, _status: status, title } = doc || {};
3
+ const { beforeSync, defaultPriorities, deleteDrafts, searchOverrides, syncDrafts } = pluginConfig;
4
+ const searchSlug = searchOverrides?.slug || 'search';
5
+ const syncLocale = locale || req.locale;
6
+ let dataToSave = {
7
+ doc: {
8
+ relationTo: collection,
9
+ value: id
10
+ },
11
+ title
12
+ };
13
+ if (typeof beforeSync === 'function') {
14
+ let docToSyncWith = doc;
15
+ if (payload.config?.localization) {
16
+ docToSyncWith = await payload.findByID({
17
+ id,
18
+ collection,
19
+ locale: syncLocale,
20
+ req
21
+ });
22
+ }
23
+ dataToSave = await beforeSync({
24
+ originalDoc: docToSyncWith,
25
+ payload,
26
+ req,
27
+ searchDoc: dataToSave
28
+ });
29
+ }
30
+ let defaultPriority = 0;
31
+ if (defaultPriorities) {
32
+ const { [collection]: priority } = defaultPriorities;
33
+ if (typeof priority === 'function') {
34
+ try {
35
+ defaultPriority = await priority(doc);
36
+ } catch (err) {
37
+ payload.logger.error(err);
38
+ payload.logger.error(`Error gathering default priority for ${searchSlug} documents related to ${collection}`);
39
+ }
40
+ } else {
41
+ defaultPriority = priority;
42
+ }
43
+ }
44
+ const doSync = syncDrafts || !syncDrafts && status !== 'draft';
45
+ try {
46
+ if (operation === 'create') {
47
+ if (doSync) {
48
+ await payload.create({
49
+ collection: searchSlug,
50
+ data: {
51
+ ...dataToSave,
52
+ priority: defaultPriority
53
+ },
54
+ locale: syncLocale,
55
+ req
56
+ });
57
+ }
58
+ }
59
+ if (operation === 'update') {
60
+ try {
61
+ // find the correct doc to sync with
62
+ const searchDocQuery = await payload.find({
63
+ collection: searchSlug,
64
+ depth: 0,
65
+ locale: syncLocale,
66
+ req,
67
+ where: {
68
+ 'doc.relationTo': {
69
+ equals: collection
70
+ },
71
+ 'doc.value': {
72
+ equals: id
73
+ }
74
+ }
75
+ });
76
+ const docs = searchDocQuery?.docs || [];
77
+ const [foundDoc, ...duplicativeDocs] = docs;
78
+ // delete all duplicative search docs (docs that reference the same page)
79
+ // to ensure the same, out-of-date result does not appear twice (where only syncing the first found doc)
80
+ if (duplicativeDocs.length > 0) {
81
+ try {
82
+ const duplicativeDocIDs = duplicativeDocs.map(({ id })=>id);
83
+ await payload.delete({
84
+ collection: searchSlug,
85
+ req,
86
+ where: {
87
+ id: {
88
+ in: duplicativeDocIDs
89
+ }
90
+ }
91
+ });
92
+ } catch (err) {
93
+ payload.logger.error({
94
+ err,
95
+ msg: `Error deleting duplicative ${searchSlug} documents.`
96
+ });
97
+ }
98
+ }
99
+ if (foundDoc) {
100
+ const { id: searchDocID } = foundDoc;
101
+ if (doSync) {
102
+ // update the doc normally
103
+ try {
104
+ await payload.update({
105
+ id: searchDocID,
106
+ collection: searchSlug,
107
+ data: {
108
+ ...dataToSave,
109
+ priority: foundDoc.priority || defaultPriority
110
+ },
111
+ locale: syncLocale,
112
+ req
113
+ });
114
+ } catch (err) {
115
+ payload.logger.error({
116
+ err,
117
+ msg: `Error updating ${searchSlug} document.`
118
+ });
119
+ }
120
+ }
121
+ if (deleteDrafts && status === 'draft') {
122
+ // do not include draft docs in search results, so delete the record
123
+ try {
124
+ await payload.delete({
125
+ id: searchDocID,
126
+ collection: searchSlug,
127
+ req
128
+ });
129
+ } catch (err) {
130
+ payload.logger.error({
131
+ err,
132
+ msg: `Error deleting ${searchSlug} document.`
133
+ });
134
+ }
135
+ }
136
+ } else if (doSync) {
137
+ try {
138
+ await payload.create({
139
+ collection: searchSlug,
140
+ data: {
141
+ ...dataToSave,
142
+ priority: defaultPriority
143
+ },
144
+ locale: syncLocale,
145
+ req
146
+ });
147
+ } catch (err) {
148
+ payload.logger.error({
149
+ err,
150
+ msg: `Error creating ${searchSlug} document.`
151
+ });
152
+ }
153
+ }
154
+ } catch (err) {
155
+ payload.logger.error({
156
+ err,
157
+ msg: `Error finding ${searchSlug} document.`
158
+ });
159
+ }
160
+ }
161
+ } catch (err) {
162
+ payload.logger.error({
163
+ err,
164
+ msg: `Error syncing ${searchSlug} document related to ${collection} with id: '${id}'.`
165
+ });
166
+ if (onSyncError) {
167
+ onSyncError();
168
+ }
169
+ }
170
+ return doc;
171
+ };
172
+
173
+ //# sourceMappingURL=syncDocAsSearchIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utilities/syncDocAsSearchIndex.ts"],"sourcesContent":["import type { DocToSync, SyncDocArgs } from '../types.js'\n\nexport const syncDocAsSearchIndex = async ({\n collection,\n doc,\n locale,\n onSyncError,\n operation,\n pluginConfig,\n req: { payload },\n req,\n}: SyncDocArgs) => {\n const { id, _status: status, title } = doc || {}\n\n const { beforeSync, defaultPriorities, deleteDrafts, searchOverrides, syncDrafts } = pluginConfig\n\n const searchSlug = searchOverrides?.slug || 'search'\n const syncLocale = locale || req.locale\n\n let dataToSave: DocToSync = {\n doc: {\n relationTo: collection,\n value: id,\n },\n title,\n }\n\n if (typeof beforeSync === 'function') {\n let docToSyncWith = doc\n if (payload.config?.localization) {\n docToSyncWith = await payload.findByID({\n id,\n collection,\n locale: syncLocale,\n req,\n })\n }\n dataToSave = await beforeSync({\n originalDoc: docToSyncWith,\n payload,\n req,\n searchDoc: dataToSave,\n })\n }\n\n let defaultPriority = 0\n if (defaultPriorities) {\n const { [collection]: priority } = defaultPriorities\n\n if (typeof priority === 'function') {\n try {\n defaultPriority = await priority(doc)\n } catch (err: unknown) {\n payload.logger.error(err)\n payload.logger.error(\n `Error gathering default priority for ${searchSlug} documents related to ${collection}`,\n )\n }\n } else {\n defaultPriority = priority\n }\n }\n\n const doSync = syncDrafts || (!syncDrafts && status !== 'draft')\n\n try {\n if (operation === 'create') {\n if (doSync) {\n await payload.create({\n collection: searchSlug,\n data: {\n ...dataToSave,\n priority: defaultPriority,\n },\n locale: syncLocale,\n req,\n })\n }\n }\n\n if (operation === 'update') {\n try {\n // find the correct doc to sync with\n const searchDocQuery = await payload.find({\n collection: searchSlug,\n depth: 0,\n locale: syncLocale,\n req,\n where: {\n 'doc.relationTo': {\n equals: collection,\n },\n 'doc.value': {\n equals: id,\n },\n },\n })\n\n const docs: Array<{\n id: number | string\n priority?: number\n }> = searchDocQuery?.docs || []\n\n const [foundDoc, ...duplicativeDocs] = docs\n\n // delete all duplicative search docs (docs that reference the same page)\n // to ensure the same, out-of-date result does not appear twice (where only syncing the first found doc)\n if (duplicativeDocs.length > 0) {\n try {\n const duplicativeDocIDs = duplicativeDocs.map(({ id }) => id)\n await payload.delete({\n collection: searchSlug,\n req,\n where: { id: { in: duplicativeDocIDs } },\n })\n } catch (err: unknown) {\n payload.logger.error({\n err,\n msg: `Error deleting duplicative ${searchSlug} documents.`,\n })\n }\n }\n\n if (foundDoc) {\n const { id: searchDocID } = foundDoc\n\n if (doSync) {\n // update the doc normally\n try {\n await payload.update({\n id: searchDocID,\n collection: searchSlug,\n data: {\n ...dataToSave,\n priority: foundDoc.priority || defaultPriority,\n },\n locale: syncLocale,\n req,\n })\n } catch (err: unknown) {\n payload.logger.error({ err, msg: `Error updating ${searchSlug} document.` })\n }\n }\n if (deleteDrafts && status === 'draft') {\n // do not include draft docs in search results, so delete the record\n try {\n await payload.delete({\n id: searchDocID,\n collection: searchSlug,\n req,\n })\n } catch (err: unknown) {\n payload.logger.error({ err, msg: `Error deleting ${searchSlug} document.` })\n }\n }\n } else if (doSync) {\n try {\n await payload.create({\n collection: searchSlug,\n data: {\n ...dataToSave,\n priority: defaultPriority,\n },\n locale: syncLocale,\n req,\n })\n } catch (err: unknown) {\n payload.logger.error({ err, msg: `Error creating ${searchSlug} document.` })\n }\n }\n } catch (err: unknown) {\n payload.logger.error({ err, msg: `Error finding ${searchSlug} document.` })\n }\n }\n } catch (err: unknown) {\n payload.logger.error({\n err,\n msg: `Error syncing ${searchSlug} document related to ${collection} with id: '${id}'.`,\n })\n\n if (onSyncError) {\n onSyncError()\n }\n }\n\n return doc\n}\n"],"names":["syncDocAsSearchIndex","collection","doc","locale","onSyncError","operation","pluginConfig","req","payload","id","_status","status","title","beforeSync","defaultPriorities","deleteDrafts","searchOverrides","syncDrafts","searchSlug","slug","syncLocale","dataToSave","relationTo","value","docToSyncWith","config","localization","findByID","originalDoc","searchDoc","defaultPriority","priority","err","logger","error","doSync","create","data","searchDocQuery","find","depth","where","equals","docs","foundDoc","duplicativeDocs","length","duplicativeDocIDs","map","delete","in","msg","searchDocID","update"],"mappings":"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"}