@payloadcms/plugin-search 3.19.0-canary.edf2c5e → 3.19.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.
|
@@ -1 +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,
|
|
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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addLocalesToRequestFromData } from '@payloadcms/next/utilities';
|
|
1
|
+
import { addLocalesToRequestFromData, headersWithCors } from '@payloadcms/next/utilities';
|
|
2
2
|
import { commitTransaction, getAccessResults, initTransaction, killTransaction } from 'payload';
|
|
3
3
|
import { syncDocAsSearchIndex } from './syncDocAsSearchIndex.js';
|
|
4
4
|
export const generateReindexHandler = (pluginConfig)=>async (req)=>{
|
|
@@ -47,11 +47,16 @@ export const generateReindexHandler = (pluginConfig)=>async (req)=>{
|
|
|
47
47
|
})
|
|
48
48
|
};
|
|
49
49
|
};
|
|
50
|
+
const headers = headersWithCors({
|
|
51
|
+
headers: new Headers(),
|
|
52
|
+
req
|
|
53
|
+
});
|
|
50
54
|
const { isValid: hasPermissions, message: permissionError } = await validatePermissions();
|
|
51
55
|
if (!hasPermissions) {
|
|
52
56
|
return Response.json({
|
|
53
57
|
message: permissionError
|
|
54
58
|
}, {
|
|
59
|
+
headers,
|
|
55
60
|
status: 401
|
|
56
61
|
});
|
|
57
62
|
}
|
|
@@ -60,6 +65,7 @@ export const generateReindexHandler = (pluginConfig)=>async (req)=>{
|
|
|
60
65
|
return Response.json({
|
|
61
66
|
message: collectionError
|
|
62
67
|
}, {
|
|
68
|
+
headers,
|
|
63
69
|
status: 400
|
|
64
70
|
});
|
|
65
71
|
}
|
|
@@ -144,6 +150,7 @@ export const generateReindexHandler = (pluginConfig)=>async (req)=>{
|
|
|
144
150
|
return Response.json({
|
|
145
151
|
message
|
|
146
152
|
}, {
|
|
153
|
+
headers,
|
|
147
154
|
status: 500
|
|
148
155
|
});
|
|
149
156
|
}
|
|
@@ -157,6 +164,7 @@ export const generateReindexHandler = (pluginConfig)=>async (req)=>{
|
|
|
157
164
|
return Response.json({
|
|
158
165
|
message
|
|
159
166
|
}, {
|
|
167
|
+
headers,
|
|
160
168
|
status: 200
|
|
161
169
|
});
|
|
162
170
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/generateReindexHandler.ts"],"sourcesContent":["import type { PayloadHandler } from 'payload'\n\nimport { addLocalesToRequestFromData } 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 { isValid: hasPermissions, message: permissionError } = await validatePermissions()\n if (!hasPermissions) {\n return Response.json({ message: permissionError }, { status: 401 })\n }\n\n const { isValid: validCollections, message: collectionError } = validateCollections()\n if (!validCollections) {\n return Response.json({ message: collectionError }, { 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 }, { 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 }, { status: 200 })\n }\n"],"names":["addLocalesToRequestFromData","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","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":"AAEA,SAASA,2BAA2B,QAAQ,6BAA4B;
|
|
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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-search",
|
|
3
|
-
"version": "3.19.0
|
|
3
|
+
"version": "3.19.0",
|
|
4
4
|
"description": "Search plugin for Payload",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"payload",
|
|
@@ -49,19 +49,19 @@
|
|
|
49
49
|
"dist"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@payloadcms/next": "3.19.0
|
|
53
|
-
"@payloadcms/ui": "3.19.0
|
|
52
|
+
"@payloadcms/next": "3.19.0",
|
|
53
|
+
"@payloadcms/ui": "3.19.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/react": "19.0.1",
|
|
57
57
|
"@types/react-dom": "19.0.1",
|
|
58
|
-
"
|
|
59
|
-
"
|
|
58
|
+
"payload": "3.19.0",
|
|
59
|
+
"@payloadcms/eslint-config": "3.9.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"react": "^19.0.0 || ^19.0.0-rc-65a56d0e-20241020",
|
|
63
63
|
"react-dom": "^19.0.0 || ^19.0.0-rc-65a56d0e-20241020",
|
|
64
|
-
"payload": "3.19.0
|
|
64
|
+
"payload": "3.19.0"
|
|
65
65
|
},
|
|
66
66
|
"publishConfig": {
|
|
67
67
|
"registry": "https://registry.npmjs.org/"
|