@payloadcms/plugin-seo 3.89.0 → 3.90.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,SAAS,CAAA;AAInE,OAAO,KAAK,EAKV,eAAe,EAChB,MAAM,YAAY,CAAA;AASnB,eAAO,MAAM,SAAS,iBACL,eAAe,cACrB,MAAM,KAAG,MAqQjB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAgD,MAAM,SAAS,CAAA;AAKnF,OAAO,KAAK,EAKV,eAAe,EAChB,MAAM,YAAY,CAAA;AASnB,eAAO,MAAM,SAAS,iBACL,eAAe,cACrB,MAAM,KAAG,MA4XjB,CAAA"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { canAccessAdmin, executeAccess, Forbidden, UnauthorizedError } from 'payload';
1
2
  import { deepMergeSimple } from 'payload/shared';
2
3
  import { MetaDescriptionField } from './fields/MetaDescription/index.js';
3
4
  import { MetaImageField } from './fields/MetaImage/index.js';
@@ -37,6 +38,91 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
37
38
  label: 'SEO'
38
39
  }
39
40
  ];
41
+ const authorizeGenerateTarget = async ({ data, req })=>{
42
+ if (!data || typeof data !== 'object') {
43
+ throw new Forbidden(req.t);
44
+ }
45
+ const collectionConfig = data.collectionSlug && pluginConfig.collections?.includes(data.collectionSlug) ? config.collections?.find(({ slug })=>slug === data.collectionSlug) : undefined;
46
+ const globalConfig = data.globalSlug && pluginConfig.globals?.includes(data.globalSlug) ? config.globals?.find(({ slug })=>slug === data.globalSlug) : undefined;
47
+ if (collectionConfig && !data.globalSlug) {
48
+ const dataDocumentID = data.doc && typeof data.doc === 'object' && 'id' in data.doc ? data.doc.id : undefined;
49
+ const documentIDs = [
50
+ data.id,
51
+ dataDocumentID
52
+ ].filter((id)=>id !== null && id !== undefined);
53
+ if (documentIDs.some((id)=>typeof id !== 'string' && typeof id !== 'number')) {
54
+ throw new Forbidden(req.t);
55
+ }
56
+ if (documentIDs.length === 2 && String(documentIDs[0]) !== String(documentIDs[1])) {
57
+ throw new Forbidden(req.t);
58
+ }
59
+ const documentID = documentIDs[0];
60
+ if (documentID !== undefined) {
61
+ const accessibleDoc = await req.payload.findByID({
62
+ id: documentID,
63
+ collection: collectionConfig.slug,
64
+ depth: 0,
65
+ disableErrors: true,
66
+ draft: true,
67
+ overrideAccess: false,
68
+ req,
69
+ trash: true,
70
+ user: req.user
71
+ });
72
+ if (!accessibleDoc) {
73
+ const { totalDocs } = await req.payload.count({
74
+ collection: collectionConfig.slug,
75
+ disableErrors: true,
76
+ overrideAccess: true,
77
+ req,
78
+ trash: true,
79
+ where: {
80
+ id: {
81
+ equals: documentID
82
+ }
83
+ }
84
+ });
85
+ if (totalDocs > 0) {
86
+ throw new Forbidden(req.t);
87
+ }
88
+ if (collectionConfig.access?.create) {
89
+ await executeAccess({
90
+ data: data.doc,
91
+ req
92
+ }, collectionConfig.access.create);
93
+ }
94
+ }
95
+ } else if (collectionConfig.access?.create) {
96
+ await executeAccess({
97
+ data: data.doc,
98
+ req
99
+ }, collectionConfig.access.create);
100
+ }
101
+ return {
102
+ collectionConfig,
103
+ globalConfig: undefined
104
+ };
105
+ }
106
+ if (globalConfig && !data.collectionSlug) {
107
+ const doc = await req.payload.findGlobal({
108
+ slug: globalConfig.slug,
109
+ depth: 0,
110
+ disableErrors: true,
111
+ draft: true,
112
+ overrideAccess: false,
113
+ req,
114
+ user: req.user
115
+ });
116
+ if (!doc) {
117
+ throw new Forbidden(req.t);
118
+ }
119
+ return {
120
+ collectionConfig: undefined,
121
+ globalConfig
122
+ };
123
+ }
124
+ throw new Forbidden(req.t);
125
+ };
40
126
  return {
41
127
  ...config,
42
128
  collections: config.collections?.map((collection)=>{
@@ -103,12 +189,19 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
103
189
  ...config.endpoints ?? [],
104
190
  {
105
191
  handler: async (req)=>{
192
+ await authorizeGenerate({
193
+ req
194
+ });
106
195
  const data = await req.json?.();
107
196
  const reqData = data ?? req.data;
197
+ const { collectionConfig, globalConfig } = await authorizeGenerateTarget({
198
+ data: reqData,
199
+ req
200
+ });
108
201
  const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle({
109
202
  ...data,
110
- collectionConfig: config.collections?.find((c)=>c.slug === reqData.collectionSlug),
111
- globalConfig: config.globals?.find((g)=>g.slug === reqData.globalSlug),
203
+ collectionConfig,
204
+ globalConfig,
112
205
  req
113
206
  }) : '';
114
207
  return new Response(JSON.stringify({
@@ -122,12 +215,19 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
122
215
  },
123
216
  {
124
217
  handler: async (req)=>{
218
+ await authorizeGenerate({
219
+ req
220
+ });
125
221
  const data = await req.json?.();
126
222
  const reqData = data ?? req.data;
223
+ const { collectionConfig, globalConfig } = await authorizeGenerateTarget({
224
+ data: reqData,
225
+ req
226
+ });
127
227
  const result = pluginConfig.generateDescription ? await pluginConfig.generateDescription({
128
228
  ...data,
129
- collectionConfig: config.collections?.find((c)=>c.slug === reqData.collectionSlug),
130
- globalConfig: config.globals?.find((g)=>g.slug === reqData.globalSlug),
229
+ collectionConfig,
230
+ globalConfig,
131
231
  req
132
232
  }) : '';
133
233
  return new Response(JSON.stringify({
@@ -141,12 +241,19 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
141
241
  },
142
242
  {
143
243
  handler: async (req)=>{
244
+ await authorizeGenerate({
245
+ req
246
+ });
144
247
  const data = await req.json?.();
145
248
  const reqData = data ?? req.data;
249
+ const { collectionConfig, globalConfig } = await authorizeGenerateTarget({
250
+ data: reqData,
251
+ req
252
+ });
146
253
  const result = pluginConfig.generateURL ? await pluginConfig.generateURL({
147
254
  ...data,
148
- collectionConfig: config.collections?.find((c)=>c.slug === reqData.collectionSlug),
149
- globalConfig: config.globals?.find((g)=>g.slug === reqData.globalSlug),
255
+ collectionConfig,
256
+ globalConfig,
150
257
  req
151
258
  }) : '';
152
259
  return new Response(JSON.stringify({
@@ -160,12 +267,19 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
160
267
  },
161
268
  {
162
269
  handler: async (req)=>{
270
+ await authorizeGenerate({
271
+ req
272
+ });
163
273
  const data = await req.json?.();
164
274
  const reqData = data ?? req.data;
275
+ const { collectionConfig, globalConfig } = await authorizeGenerateTarget({
276
+ data: reqData,
277
+ req
278
+ });
165
279
  const result = pluginConfig.generateImage ? await pluginConfig.generateImage({
166
280
  ...data,
167
- collectionConfig: config.collections?.find((c)=>c.slug === reqData.collectionSlug),
168
- globalConfig: config.globals?.find((g)=>g.slug === reqData.globalSlug),
281
+ collectionConfig,
282
+ globalConfig,
169
283
  req
170
284
  }) : '';
171
285
  return new Response(JSON.stringify({
@@ -228,5 +342,13 @@ export const seoPlugin = (pluginConfig)=>(config)=>{
228
342
  }
229
343
  };
230
344
  };
345
+ const authorizeGenerate = async ({ req })=>{
346
+ if (!req.user) {
347
+ throw new UnauthorizedError(req.t);
348
+ }
349
+ await canAccessAdmin({
350
+ req
351
+ });
352
+ };
231
353
 
232
354
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config, Field, GroupField, TabsField } from 'payload'\n\nimport { deepMergeSimple } from 'payload/shared'\n\nimport type {\n GenerateDescription,\n GenerateImage,\n GenerateTitle,\n GenerateURL,\n SEOPluginConfig,\n} from './types.js'\n\nimport { MetaDescriptionField } from './fields/MetaDescription/index.js'\nimport { MetaImageField } from './fields/MetaImage/index.js'\nimport { MetaTitleField } from './fields/MetaTitle/index.js'\nimport { OverviewField } from './fields/Overview/index.js'\nimport { PreviewField } from './fields/Preview/index.js'\nimport { translations } from './translations/index.js'\n\nexport const seoPlugin =\n (pluginConfig: SEOPluginConfig) =>\n (config: Config): Config => {\n const defaultFields: Field[] = [\n OverviewField({}),\n MetaTitleField({\n hasGenerateFn: typeof pluginConfig?.generateTitle === 'function',\n }),\n MetaDescriptionField({\n hasGenerateFn: typeof pluginConfig?.generateDescription === 'function',\n }),\n ...(pluginConfig?.uploadsCollection\n ? [\n MetaImageField({\n hasGenerateFn: typeof pluginConfig?.generateImage === 'function',\n relationTo: pluginConfig.uploadsCollection as string,\n }),\n ]\n : []),\n PreviewField({\n hasGenerateFn: typeof pluginConfig?.generateURL === 'function',\n }),\n ]\n\n const seoFields: GroupField[] = [\n {\n name: 'meta',\n type: 'group',\n fields: [\n ...(pluginConfig?.fields && typeof pluginConfig.fields === 'function'\n ? pluginConfig.fields({ defaultFields })\n : defaultFields),\n ],\n interfaceName: pluginConfig.interfaceName,\n label: 'SEO',\n },\n ]\n\n return {\n ...config,\n collections:\n config.collections?.map((collection) => {\n const { slug } = collection\n const isEnabled = pluginConfig?.collections?.includes(slug)\n\n if (isEnabled) {\n if (pluginConfig?.tabbedUI) {\n // prevent issues with auth enabled collections having an email field that shouldn't be moved to the SEO tab\n const emailField =\n collection.auth &&\n !(typeof collection.auth === 'object' && collection.auth.disableLocalStrategy) &&\n collection.fields?.find((field) => 'name' in field && field.name === 'email')\n const hasOnlyEmailField = collection.fields?.length === 1 && emailField\n\n const seoTabs: TabsField[] = hasOnlyEmailField\n ? [\n {\n type: 'tabs',\n tabs: [\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n : [\n {\n type: 'tabs',\n tabs: [\n // append a new tab onto the end of the tabs array, if there is one at the first index\n // if needed, create a new `Content` tab in the first index for this collection's base fields\n ...(collection?.fields?.[0]?.type === 'tabs' &&\n collection?.fields?.[0]?.tabs\n ? collection.fields[0].tabs\n : [\n {\n fields: [\n ...(emailField\n ? collection.fields.filter(\n (field) => 'name' in field && field.name !== 'email',\n )\n : collection.fields),\n ],\n label: collection?.labels?.singular || 'Content',\n },\n ]),\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n\n return {\n ...collection,\n fields: [\n ...(emailField ? [emailField] : []),\n ...seoTabs,\n ...(collection?.fields?.[0]?.type === 'tabs' ? collection.fields.slice(1) : []),\n ],\n }\n }\n\n return {\n ...collection,\n fields: [...(collection?.fields || []), ...seoFields],\n }\n }\n\n return collection\n }) || [],\n endpoints: [\n ...(config.endpoints ?? []),\n {\n handler: async (req) => {\n const data: Omit<\n Parameters<GenerateTitle>[0],\n 'collectionConfig' | 'globalConfig' | 'req'\n > = await req.json?.()\n\n const reqData = data ?? req.data\n\n const result = pluginConfig.generateTitle\n ? await pluginConfig.generateTitle({\n ...data,\n collectionConfig: config.collections?.find(\n (c) => c.slug === reqData.collectionSlug,\n ),\n globalConfig: config.globals?.find((g) => g.slug === reqData.globalSlug),\n req,\n } satisfies Parameters<GenerateTitle>[0])\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-title',\n },\n {\n handler: async (req) => {\n const data: Omit<\n Parameters<GenerateTitle>[0],\n 'collectionConfig' | 'globalConfig' | 'req'\n > = await req.json?.()\n\n const reqData = data ?? req.data\n\n const result = pluginConfig.generateDescription\n ? await pluginConfig.generateDescription({\n ...data,\n collectionConfig: config.collections?.find(\n (c) => c.slug === reqData.collectionSlug,\n ),\n globalConfig: config.globals?.find((g) => g.slug === reqData.globalSlug),\n req,\n } satisfies Parameters<GenerateDescription>[0])\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-description',\n },\n {\n handler: async (req) => {\n const data: Omit<\n Parameters<GenerateTitle>[0],\n 'collectionConfig' | 'globalConfig' | 'req'\n > = await req.json?.()\n\n const reqData = data ?? req.data\n\n const result = pluginConfig.generateURL\n ? await pluginConfig.generateURL({\n ...data,\n collectionConfig: config.collections?.find(\n (c) => c.slug === reqData.collectionSlug,\n ),\n globalConfig: config.globals?.find((g) => g.slug === reqData.globalSlug),\n req,\n } satisfies Parameters<GenerateURL>[0])\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-url',\n },\n {\n handler: async (req) => {\n const data: Omit<\n Parameters<GenerateTitle>[0],\n 'collectionConfig' | 'globalConfig' | 'req'\n > = await req.json?.()\n\n const reqData = data ?? req.data\n\n const result = pluginConfig.generateImage\n ? await pluginConfig.generateImage({\n ...data,\n collectionConfig: config.collections?.find(\n (c) => c.slug === reqData.collectionSlug,\n ),\n globalConfig: config.globals?.find((g) => g.slug === reqData.globalSlug),\n req,\n } satisfies Parameters<GenerateImage>[0])\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-image',\n },\n ],\n globals:\n config.globals?.map((global) => {\n const { slug } = global\n const isEnabled = pluginConfig?.globals?.includes(slug)\n\n if (isEnabled) {\n if (pluginConfig?.tabbedUI) {\n const seoTabs: TabsField[] = [\n {\n type: 'tabs',\n tabs: [\n // append a new tab onto the end of the tabs array, if there is one at the first index\n // if needed, create a new `Content` tab in the first index for this global's base fields\n ...(global?.fields?.[0]?.type === 'tabs' && global?.fields?.[0].tabs\n ? global.fields[0].tabs\n : [\n {\n fields: [...(global?.fields || [])],\n label: global?.label || 'Content',\n },\n ]),\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n\n return {\n ...global,\n fields: [\n ...seoTabs,\n ...(global?.fields?.[0]?.type === 'tabs' ? global.fields.slice(1) : []),\n ],\n }\n }\n\n return {\n ...global,\n fields: [...(global?.fields || []), ...seoFields],\n }\n }\n\n return global\n }) || [],\n i18n: {\n ...config.i18n,\n translations: deepMergeSimple(translations, config.i18n?.translations ?? {}),\n },\n }\n }\n"],"names":["deepMergeSimple","MetaDescriptionField","MetaImageField","MetaTitleField","OverviewField","PreviewField","translations","seoPlugin","pluginConfig","config","defaultFields","hasGenerateFn","generateTitle","generateDescription","uploadsCollection","generateImage","relationTo","generateURL","seoFields","name","type","fields","interfaceName","label","collections","map","collection","slug","isEnabled","includes","tabbedUI","emailField","auth","disableLocalStrategy","find","field","hasOnlyEmailField","length","seoTabs","tabs","filter","labels","singular","slice","endpoints","handler","req","data","json","reqData","result","collectionConfig","c","collectionSlug","globalConfig","globals","g","globalSlug","Response","JSON","stringify","status","method","path","global","i18n"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config, Field, GroupField, PayloadRequest, TabsField } from 'payload'\n\nimport { canAccessAdmin, executeAccess, Forbidden, UnauthorizedError } from 'payload'\nimport { deepMergeSimple } from 'payload/shared'\n\nimport type {\n GenerateDescription,\n GenerateImage,\n GenerateTitle,\n GenerateURL,\n SEOPluginConfig,\n} from './types.js'\n\nimport { MetaDescriptionField } from './fields/MetaDescription/index.js'\nimport { MetaImageField } from './fields/MetaImage/index.js'\nimport { MetaTitleField } from './fields/MetaTitle/index.js'\nimport { OverviewField } from './fields/Overview/index.js'\nimport { PreviewField } from './fields/Preview/index.js'\nimport { translations } from './translations/index.js'\n\nexport const seoPlugin =\n (pluginConfig: SEOPluginConfig) =>\n (config: Config): Config => {\n const defaultFields: Field[] = [\n OverviewField({}),\n MetaTitleField({\n hasGenerateFn: typeof pluginConfig?.generateTitle === 'function',\n }),\n MetaDescriptionField({\n hasGenerateFn: typeof pluginConfig?.generateDescription === 'function',\n }),\n ...(pluginConfig?.uploadsCollection\n ? [\n MetaImageField({\n hasGenerateFn: typeof pluginConfig?.generateImage === 'function',\n relationTo: pluginConfig.uploadsCollection as string,\n }),\n ]\n : []),\n PreviewField({\n hasGenerateFn: typeof pluginConfig?.generateURL === 'function',\n }),\n ]\n\n const seoFields: GroupField[] = [\n {\n name: 'meta',\n type: 'group',\n fields: [\n ...(pluginConfig?.fields && typeof pluginConfig.fields === 'function'\n ? pluginConfig.fields({ defaultFields })\n : defaultFields),\n ],\n interfaceName: pluginConfig.interfaceName,\n label: 'SEO',\n },\n ]\n\n const authorizeGenerateTarget = async ({\n data,\n req,\n }: {\n data:\n | null\n | Omit<Parameters<GenerateTitle>[0], 'collectionConfig' | 'globalConfig' | 'req'>\n | undefined\n req: PayloadRequest\n }) => {\n if (!data || typeof data !== 'object') {\n throw new Forbidden(req.t)\n }\n\n const collectionConfig =\n data.collectionSlug && pluginConfig.collections?.includes(data.collectionSlug)\n ? config.collections?.find(({ slug }) => slug === data.collectionSlug)\n : undefined\n const globalConfig =\n data.globalSlug && pluginConfig.globals?.includes(data.globalSlug)\n ? config.globals?.find(({ slug }) => slug === data.globalSlug)\n : undefined\n\n if (collectionConfig && !data.globalSlug) {\n const dataDocumentID =\n data.doc && typeof data.doc === 'object' && 'id' in data.doc ? data.doc.id : undefined\n const documentIDs = [data.id, dataDocumentID].filter(\n (id) => id !== null && id !== undefined,\n )\n\n if (documentIDs.some((id) => typeof id !== 'string' && typeof id !== 'number')) {\n throw new Forbidden(req.t)\n }\n\n if (documentIDs.length === 2 && String(documentIDs[0]) !== String(documentIDs[1])) {\n throw new Forbidden(req.t)\n }\n\n const documentID = documentIDs[0] as number | string | undefined\n\n if (documentID !== undefined) {\n const accessibleDoc = await req.payload.findByID({\n id: documentID,\n collection: collectionConfig.slug,\n depth: 0,\n disableErrors: true,\n draft: true,\n overrideAccess: false,\n req,\n trash: true,\n user: req.user,\n })\n\n if (!accessibleDoc) {\n const { totalDocs } = await req.payload.count({\n collection: collectionConfig.slug,\n disableErrors: true,\n overrideAccess: true,\n req,\n trash: true,\n where: {\n id: {\n equals: documentID,\n },\n },\n })\n\n if (totalDocs > 0) {\n throw new Forbidden(req.t)\n }\n\n if (collectionConfig.access?.create) {\n await executeAccess({ data: data.doc, req }, collectionConfig.access.create)\n }\n }\n } else if (collectionConfig.access?.create) {\n await executeAccess({ data: data.doc, req }, collectionConfig.access.create)\n }\n\n return { collectionConfig, globalConfig: undefined }\n }\n\n if (globalConfig && !data.collectionSlug) {\n const doc = await req.payload.findGlobal({\n slug: globalConfig.slug,\n depth: 0,\n disableErrors: true,\n draft: true,\n overrideAccess: false,\n req,\n user: req.user,\n })\n\n if (!doc) {\n throw new Forbidden(req.t)\n }\n\n return { collectionConfig: undefined, globalConfig }\n }\n\n throw new Forbidden(req.t)\n }\n\n return {\n ...config,\n collections:\n config.collections?.map((collection) => {\n const { slug } = collection\n const isEnabled = pluginConfig?.collections?.includes(slug)\n\n if (isEnabled) {\n if (pluginConfig?.tabbedUI) {\n // prevent issues with auth enabled collections having an email field that shouldn't be moved to the SEO tab\n const emailField =\n collection.auth &&\n !(typeof collection.auth === 'object' && collection.auth.disableLocalStrategy) &&\n collection.fields?.find((field) => 'name' in field && field.name === 'email')\n const hasOnlyEmailField = collection.fields?.length === 1 && emailField\n\n const seoTabs: TabsField[] = hasOnlyEmailField\n ? [\n {\n type: 'tabs',\n tabs: [\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n : [\n {\n type: 'tabs',\n tabs: [\n // append a new tab onto the end of the tabs array, if there is one at the first index\n // if needed, create a new `Content` tab in the first index for this collection's base fields\n ...(collection?.fields?.[0]?.type === 'tabs' &&\n collection?.fields?.[0]?.tabs\n ? collection.fields[0].tabs\n : [\n {\n fields: [\n ...(emailField\n ? collection.fields.filter(\n (field) => 'name' in field && field.name !== 'email',\n )\n : collection.fields),\n ],\n label: collection?.labels?.singular || 'Content',\n },\n ]),\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n\n return {\n ...collection,\n fields: [\n ...(emailField ? [emailField] : []),\n ...seoTabs,\n ...(collection?.fields?.[0]?.type === 'tabs' ? collection.fields.slice(1) : []),\n ],\n }\n }\n\n return {\n ...collection,\n fields: [...(collection?.fields || []), ...seoFields],\n }\n }\n\n return collection\n }) || [],\n endpoints: [\n ...(config.endpoints ?? []),\n {\n handler: async (req) => {\n await authorizeGenerate({ req })\n\n const data: Omit<\n Parameters<GenerateTitle>[0],\n 'collectionConfig' | 'globalConfig' | 'req'\n > = await req.json?.()\n\n const reqData = data ?? req.data\n const { collectionConfig, globalConfig } = await authorizeGenerateTarget({\n data: reqData,\n req,\n })\n\n const result = pluginConfig.generateTitle\n ? await pluginConfig.generateTitle({\n ...data,\n collectionConfig,\n globalConfig,\n req,\n } satisfies Parameters<GenerateTitle>[0])\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-title',\n },\n {\n handler: async (req) => {\n await authorizeGenerate({ req })\n\n const data: Omit<\n Parameters<GenerateTitle>[0],\n 'collectionConfig' | 'globalConfig' | 'req'\n > = await req.json?.()\n\n const reqData = data ?? req.data\n const { collectionConfig, globalConfig } = await authorizeGenerateTarget({\n data: reqData,\n req,\n })\n\n const result = pluginConfig.generateDescription\n ? await pluginConfig.generateDescription({\n ...data,\n collectionConfig,\n globalConfig,\n req,\n } satisfies Parameters<GenerateDescription>[0])\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-description',\n },\n {\n handler: async (req) => {\n await authorizeGenerate({ req })\n\n const data: Omit<\n Parameters<GenerateTitle>[0],\n 'collectionConfig' | 'globalConfig' | 'req'\n > = await req.json?.()\n\n const reqData = data ?? req.data\n const { collectionConfig, globalConfig } = await authorizeGenerateTarget({\n data: reqData,\n req,\n })\n\n const result = pluginConfig.generateURL\n ? await pluginConfig.generateURL({\n ...data,\n collectionConfig,\n globalConfig,\n req,\n } satisfies Parameters<GenerateURL>[0])\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-url',\n },\n {\n handler: async (req) => {\n await authorizeGenerate({ req })\n\n const data: Omit<\n Parameters<GenerateTitle>[0],\n 'collectionConfig' | 'globalConfig' | 'req'\n > = await req.json?.()\n\n const reqData = data ?? req.data\n const { collectionConfig, globalConfig } = await authorizeGenerateTarget({\n data: reqData,\n req,\n })\n\n const result = pluginConfig.generateImage\n ? await pluginConfig.generateImage({\n ...data,\n collectionConfig,\n globalConfig,\n req,\n } satisfies Parameters<GenerateImage>[0])\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-image',\n },\n ],\n globals:\n config.globals?.map((global) => {\n const { slug } = global\n const isEnabled = pluginConfig?.globals?.includes(slug)\n\n if (isEnabled) {\n if (pluginConfig?.tabbedUI) {\n const seoTabs: TabsField[] = [\n {\n type: 'tabs',\n tabs: [\n // append a new tab onto the end of the tabs array, if there is one at the first index\n // if needed, create a new `Content` tab in the first index for this global's base fields\n ...(global?.fields?.[0]?.type === 'tabs' && global?.fields?.[0].tabs\n ? global.fields[0].tabs\n : [\n {\n fields: [...(global?.fields || [])],\n label: global?.label || 'Content',\n },\n ]),\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n\n return {\n ...global,\n fields: [\n ...seoTabs,\n ...(global?.fields?.[0]?.type === 'tabs' ? global.fields.slice(1) : []),\n ],\n }\n }\n\n return {\n ...global,\n fields: [...(global?.fields || []), ...seoFields],\n }\n }\n\n return global\n }) || [],\n i18n: {\n ...config.i18n,\n translations: deepMergeSimple(translations, config.i18n?.translations ?? {}),\n },\n }\n }\n\nconst authorizeGenerate = async ({ req }: { req: PayloadRequest }): Promise<void> => {\n if (!req.user) {\n throw new UnauthorizedError(req.t)\n }\n\n await canAccessAdmin({ req })\n}\n"],"names":["canAccessAdmin","executeAccess","Forbidden","UnauthorizedError","deepMergeSimple","MetaDescriptionField","MetaImageField","MetaTitleField","OverviewField","PreviewField","translations","seoPlugin","pluginConfig","config","defaultFields","hasGenerateFn","generateTitle","generateDescription","uploadsCollection","generateImage","relationTo","generateURL","seoFields","name","type","fields","interfaceName","label","authorizeGenerateTarget","data","req","t","collectionConfig","collectionSlug","collections","includes","find","slug","undefined","globalConfig","globalSlug","globals","dataDocumentID","doc","id","documentIDs","filter","some","length","String","documentID","accessibleDoc","payload","findByID","collection","depth","disableErrors","draft","overrideAccess","trash","user","totalDocs","count","where","equals","access","create","findGlobal","map","isEnabled","tabbedUI","emailField","auth","disableLocalStrategy","field","hasOnlyEmailField","seoTabs","tabs","labels","singular","slice","endpoints","handler","authorizeGenerate","json","reqData","result","Response","JSON","stringify","status","method","path","global","i18n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-seo",
3
- "version": "3.89.0",
3
+ "version": "3.90.1",
4
4
  "description": "SEO plugin for Payload",
5
5
  "keywords": [
6
6
  "payload",
@@ -58,20 +58,20 @@
58
58
  "dist"
59
59
  ],
60
60
  "dependencies": {
61
- "@payloadcms/translations": "3.89.0",
62
- "@payloadcms/ui": "3.89.0"
61
+ "@payloadcms/translations": "3.90.1",
62
+ "@payloadcms/ui": "3.90.1"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@types/react": "19.2.14",
66
66
  "@types/react-dom": "19.2.3",
67
- "@payloadcms/next": "3.89.0",
68
- "payload": "3.89.0",
69
- "@payloadcms/eslint-config": "3.28.0"
67
+ "payload": "3.90.1",
68
+ "@payloadcms/eslint-config": "3.28.0",
69
+ "@payloadcms/next": "3.90.1"
70
70
  },
71
71
  "peerDependencies": {
72
72
  "react": "^19.0.1 || ^19.1.2 || ^19.2.1",
73
73
  "react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1",
74
- "payload": "3.89.0"
74
+ "payload": "3.90.1"
75
75
  },
76
76
  "publishConfig": {
77
77
  "registry": "https://registry.npmjs.org/"