@websolutespa/payload-plugin-seo 2.0.1-next.2 → 2.0.1-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/api/tokens.service.js +3 -3
- package/dist/api/tokens.service.js.map +1 -1
- package/dist/components/TextWithTokens.js +55 -13
- package/dist/components/TextWithTokens.js.map +1 -1
- package/dist/components/Tokens.js +12 -13
- package/dist/components/Tokens.js.map +1 -1
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +1 -0
- package/dist/exports/client.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/seo.js +5 -3
- package/dist/seo.js.map +1 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @websolutespa/payload-plugin-seo
|
|
2
2
|
|
|
3
|
+
## 2.0.1-next.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- - Changed token autocomplete library
|
|
8
|
+
|
|
9
|
+
## 2.0.1-next.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- - Fix token list retrieval, richText replacement (payload3)
|
|
14
|
+
|
|
3
15
|
## 2.0.1-next.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ResponseError, ResponseSuccess } from '@websolutespa/payload-utils/server';
|
|
2
|
-
import payload from 'payload';
|
|
3
2
|
import { options } from '../options';
|
|
4
3
|
import { eachTokenizableField } from '../utils/fields';
|
|
5
|
-
const getTokens = (collections)=>{
|
|
4
|
+
const getTokens = (req, collections)=>{
|
|
5
|
+
const { payload } = req;
|
|
6
6
|
const collectionConfigs = collections.length ? payload.config.collections.filter((config)=>collections.includes(config.slug)) : payload.config.collections.filter((config)=>options.collections.includes(config.slug));
|
|
7
7
|
// retrieve common tokens between collections
|
|
8
8
|
let tokens = collectionConfigs.reduce((acc, config)=>{
|
|
@@ -30,7 +30,7 @@ export const tokensGet = ()=>({
|
|
|
30
30
|
try {
|
|
31
31
|
const qsCollections = req.query.collections || '';
|
|
32
32
|
const collections = qsCollections !== '' ? qsCollections.split(',') : [];
|
|
33
|
-
const tokens = getTokens(collections);
|
|
33
|
+
const tokens = getTokens(req, collections);
|
|
34
34
|
return ResponseSuccess(tokens);
|
|
35
35
|
} catch (error) {
|
|
36
36
|
return ResponseError(error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/tokens.service.ts"],"sourcesContent":["import { ResponseError, ResponseSuccess } from '@websolutespa/payload-utils/server';\r\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/api/tokens.service.ts"],"sourcesContent":["import { ResponseError, ResponseSuccess } from '@websolutespa/payload-utils/server';\r\nimport { Endpoint, PayloadRequest } from 'payload';\r\nimport { options } from '../options';\r\nimport { eachTokenizableField } from '../utils/fields';\r\n\r\nconst getTokens = (req: PayloadRequest, collections: string[]) => {\r\n const { payload } = req;\r\n const collectionConfigs = collections.length ?\r\n payload.config.collections.filter((config) => collections.includes(config.slug))\r\n : payload.config.collections.filter((config) => options.collections.includes(config.slug));\r\n\r\n // retrieve common tokens between collections\r\n let tokens: string[] = collectionConfigs.reduce((acc, config) => {\r\n const fields: string[] = [];\r\n eachTokenizableField(config.fields, (field) => {\r\n fields.push(`[${field.name}]`);\r\n });\r\n return acc.length ? acc.filter((field) => fields.includes(field)) : fields;\r\n }, [] as string[]);\r\n // remove duplicates\r\n tokens = [...new Set(tokens)];\r\n\r\n // merge collections tokens with custom tokens\r\n tokens = [...tokens, ...options.customTokens.map(token => `[${token.name}]`)];\r\n\r\n return tokens;\r\n};\r\n\r\nexport const tokensGet: (() => Endpoint) = () => ({\r\n path: '/seo/tokens',\r\n method: 'get',\r\n handler: async (req: PayloadRequest) => {\r\n try {\r\n const qsCollections = (req.query.collections || '') as string;\r\n const collections = qsCollections !== '' ? qsCollections.split(',') : [];\r\n const tokens = getTokens(req, collections);\r\n return ResponseSuccess(tokens);\r\n } catch (error) {\r\n return ResponseError(error);\r\n }\r\n },\r\n});\r\n"],"names":["ResponseError","ResponseSuccess","options","eachTokenizableField","getTokens","req","collections","payload","collectionConfigs","length","config","filter","includes","slug","tokens","reduce","acc","fields","field","push","name","Set","customTokens","map","token","tokensGet","path","method","handler","qsCollections","query","split","error"],"mappings":"AAAA,SAASA,aAAa,EAAEC,eAAe,QAAQ,qCAAqC;AAEpF,SAASC,OAAO,QAAQ,aAAa;AACrC,SAASC,oBAAoB,QAAQ,kBAAkB;AAEvD,MAAMC,YAAY,CAACC,KAAqBC;IACtC,MAAM,EAAEC,OAAO,EAAE,GAAGF;IACpB,MAAMG,oBAAoBF,YAAYG,MAAM,GAC1CF,QAAQG,MAAM,CAACJ,WAAW,CAACK,MAAM,CAAC,CAACD,SAAWJ,YAAYM,QAAQ,CAACF,OAAOG,IAAI,KAC5EN,QAAQG,MAAM,CAACJ,WAAW,CAACK,MAAM,CAAC,CAACD,SAAWR,QAAQI,WAAW,CAACM,QAAQ,CAACF,OAAOG,IAAI;IAE1F,6CAA6C;IAC7C,IAAIC,SAAmBN,kBAAkBO,MAAM,CAAC,CAACC,KAAKN;QACpD,MAAMO,SAAmB,EAAE;QAC3Bd,qBAAqBO,OAAOO,MAAM,EAAE,CAACC;YACnCD,OAAOE,IAAI,CAAC,CAAC,CAAC,EAAED,MAAME,IAAI,CAAC,CAAC,CAAC;QAC/B;QACA,OAAOJ,IAAIP,MAAM,GAAGO,IAAIL,MAAM,CAAC,CAACO,QAAUD,OAAOL,QAAQ,CAACM,UAAUD;IACtE,GAAG,EAAE;IACL,oBAAoB;IACpBH,SAAS;WAAI,IAAIO,IAAIP;KAAQ;IAE7B,8CAA8C;IAC9CA,SAAS;WAAIA;WAAWZ,QAAQoB,YAAY,CAACC,GAAG,CAACC,CAAAA,QAAS,CAAC,CAAC,EAAEA,MAAMJ,IAAI,CAAC,CAAC,CAAC;KAAE;IAE7E,OAAON;AACT;AAEA,OAAO,MAAMW,YAA8B,IAAO,CAAA;QAChDC,MAAM;QACNC,QAAQ;QACRC,SAAS,OAAOvB;YACd,IAAI;gBACF,MAAMwB,gBAAiBxB,IAAIyB,KAAK,CAACxB,WAAW,IAAI;gBAChD,MAAMA,cAAcuB,kBAAkB,KAAKA,cAAcE,KAAK,CAAC,OAAO,EAAE;gBACxE,MAAMjB,SAASV,UAAUC,KAAKC;gBAC9B,OAAOL,gBAAgBa;YACzB,EAAE,OAAOkB,OAAO;gBACd,OAAOhC,cAAcgC;YACvB;QACF;IACF,CAAA,EAAG"}
|
|
@@ -2,15 +2,53 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { FieldLabel, useField, useFormFields } from '@payloadcms/ui';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import
|
|
5
|
+
import { Mention, MentionsInput } from 'react-mentions';
|
|
6
6
|
const baseClass = 'text-with-tokens';
|
|
7
|
+
const mentionsStyle = {
|
|
8
|
+
control: {
|
|
9
|
+
display: 'block',
|
|
10
|
+
width: '100%'
|
|
11
|
+
},
|
|
12
|
+
'&singleLine': {
|
|
13
|
+
input: {
|
|
14
|
+
width: '100%',
|
|
15
|
+
padding: '0.375rem 0.75rem',
|
|
16
|
+
border: '1px solid var(--theme-elevation-150)',
|
|
17
|
+
borderRadius: 'var(--border-radius)',
|
|
18
|
+
backgroundColor: 'var(--theme-input-bg)',
|
|
19
|
+
color: 'var(--theme-text)',
|
|
20
|
+
fontSize: '1rem',
|
|
21
|
+
lineHeight: '1.5',
|
|
22
|
+
outline: 'none'
|
|
23
|
+
},
|
|
24
|
+
highlighter: {
|
|
25
|
+
padding: '0.375rem 0.75rem',
|
|
26
|
+
border: '1px solid transparent'
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
suggestions: {
|
|
30
|
+
list: {
|
|
31
|
+
backgroundColor: 'var(--theme-bg)',
|
|
32
|
+
border: '1px solid var(--theme-elevation-150)',
|
|
33
|
+
borderRadius: 'var(--border-radius)',
|
|
34
|
+
maxHeight: '200px',
|
|
35
|
+
overflowY: 'auto'
|
|
36
|
+
},
|
|
37
|
+
item: {
|
|
38
|
+
padding: '4px 12px',
|
|
39
|
+
'&focused': {
|
|
40
|
+
backgroundColor: 'var(--theme-elevation-50)'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
7
45
|
export const TextWithTokens = (props)=>{
|
|
8
46
|
const { path, field } = props;
|
|
9
47
|
const { label, required } = field;
|
|
10
48
|
const { value, setValue } = useField({
|
|
11
49
|
path
|
|
12
50
|
});
|
|
13
|
-
const tokensField = useFormFields(([fields
|
|
51
|
+
const tokensField = useFormFields(([fields])=>fields.tokens);
|
|
14
52
|
let tokens = tokensField?.value || [];
|
|
15
53
|
tokens = tokens.map((token)=>token.replace('[', '').replace(']', ''));
|
|
16
54
|
const classes = [
|
|
@@ -26,17 +64,21 @@ export const TextWithTokens = (props)=>{
|
|
|
26
64
|
path: path,
|
|
27
65
|
required: required
|
|
28
66
|
}),
|
|
29
|
-
/*#__PURE__*/ _jsx(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
67
|
+
/*#__PURE__*/ _jsx(MentionsInput, {
|
|
68
|
+
singleLine: true,
|
|
69
|
+
value: value ?? '',
|
|
70
|
+
onChange: (_, newValue)=>setValue(newValue),
|
|
71
|
+
style: mentionsStyle,
|
|
72
|
+
children: /*#__PURE__*/ _jsx(Mention, {
|
|
73
|
+
trigger: "[",
|
|
74
|
+
data: tokens.map((t)=>({
|
|
75
|
+
id: t,
|
|
76
|
+
display: t
|
|
77
|
+
})),
|
|
78
|
+
markup: "[__display__]",
|
|
79
|
+
displayTransform: (_, display)=>`[${display}]`,
|
|
80
|
+
appendSpaceOnAdd: true
|
|
81
|
+
})
|
|
40
82
|
})
|
|
41
83
|
]
|
|
42
84
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/TextWithTokens.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { FieldLabel, useField, useFormFields } from '@payloadcms/ui';\r\nimport { TextFieldClientProps } from 'payload';\r\nimport * as React from 'react';\r\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/components/TextWithTokens.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { FieldLabel, useField, useFormFields } from '@payloadcms/ui';\r\nimport { TextFieldClientProps } from 'payload';\r\nimport * as React from 'react';\r\nimport { Mention, MentionsInput } from 'react-mentions';\r\n\r\nconst baseClass = 'text-with-tokens';\r\n\r\nconst mentionsStyle = {\r\n control: {\r\n display: 'block',\r\n width: '100%',\r\n },\r\n '&singleLine': {\r\n input: {\r\n width: '100%',\r\n padding: '0.375rem 0.75rem',\r\n border: '1px solid var(--theme-elevation-150)',\r\n borderRadius: 'var(--border-radius)',\r\n backgroundColor: 'var(--theme-input-bg)',\r\n color: 'var(--theme-text)',\r\n fontSize: '1rem',\r\n lineHeight: '1.5',\r\n outline: 'none',\r\n },\r\n highlighter: {\r\n padding: '0.375rem 0.75rem',\r\n border: '1px solid transparent',\r\n },\r\n },\r\n suggestions: {\r\n list: {\r\n backgroundColor: 'var(--theme-bg)',\r\n border: '1px solid var(--theme-elevation-150)',\r\n borderRadius: 'var(--border-radius)',\r\n maxHeight: '200px',\r\n overflowY: 'auto' as const,\r\n },\r\n item: {\r\n padding: '4px 12px',\r\n '&focused': {\r\n backgroundColor: 'var(--theme-elevation-50)',\r\n },\r\n },\r\n },\r\n};\r\n\r\nexport const TextWithTokens: React.FC<TextFieldClientProps> = (props) => {\r\n const { path, field } = props;\r\n const { label, required } = field;\r\n const { value, setValue } = useField<string>({ path });\r\n\r\n const tokensField = useFormFields(([fields]) => fields.tokens);\r\n let tokens = (tokensField?.value as string[]) || [];\r\n tokens = tokens.map((token) => token.replace('[', '').replace(']', ''));\r\n\r\n const classes = ['field-type', 'textarea', baseClass].join(' ');\r\n\r\n return (\r\n <div className={classes}>\r\n <FieldLabel label={label} path={path} required={required} />\r\n <MentionsInput\r\n singleLine\r\n value={value ?? ''}\r\n onChange={(_, newValue) => setValue(newValue)}\r\n style={mentionsStyle}\r\n >\r\n <Mention\r\n trigger=\"[\"\r\n data={tokens.map((t) => ({ id: t, display: t }))}\r\n markup=\"[__display__]\"\r\n displayTransform={(_, display) => `[${display}]`}\r\n appendSpaceOnAdd\r\n />\r\n </MentionsInput>\r\n </div>\r\n );\r\n};\r\n"],"names":["FieldLabel","useField","useFormFields","React","Mention","MentionsInput","baseClass","mentionsStyle","control","display","width","input","padding","border","borderRadius","backgroundColor","color","fontSize","lineHeight","outline","highlighter","suggestions","list","maxHeight","overflowY","item","TextWithTokens","props","path","field","label","required","value","setValue","tokensField","fields","tokens","map","token","replace","classes","join","div","className","singleLine","onChange","_","newValue","style","trigger","data","t","id","markup","displayTransform","appendSpaceOnAdd"],"mappings":"AAAA;;AAEA,SAASA,UAAU,EAAEC,QAAQ,EAAEC,aAAa,QAAQ,iBAAiB;AAErE,YAAYC,WAAW,QAAQ;AAC/B,SAASC,OAAO,EAAEC,aAAa,QAAQ,iBAAiB;AAExD,MAAMC,YAAY;AAElB,MAAMC,gBAAgB;IACpBC,SAAS;QACPC,SAAS;QACTC,OAAO;IACT;IACA,eAAe;QACbC,OAAO;YACLD,OAAO;YACPE,SAAS;YACTC,QAAQ;YACRC,cAAc;YACdC,iBAAiB;YACjBC,OAAO;YACPC,UAAU;YACVC,YAAY;YACZC,SAAS;QACX;QACAC,aAAa;YACXR,SAAS;YACTC,QAAQ;QACV;IACF;IACAQ,aAAa;QACXC,MAAM;YACJP,iBAAiB;YACjBF,QAAQ;YACRC,cAAc;YACdS,WAAW;YACXC,WAAW;QACb;QACAC,MAAM;YACJb,SAAS;YACT,YAAY;gBACVG,iBAAiB;YACnB;QACF;IACF;AACF;AAEA,OAAO,MAAMW,iBAAiD,CAACC;IAC7D,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAE,GAAGF;IACxB,MAAM,EAAEG,KAAK,EAAEC,QAAQ,EAAE,GAAGF;IAC5B,MAAM,EAAEG,KAAK,EAAEC,QAAQ,EAAE,GAAGhC,SAAiB;QAAE2B;IAAK;IAEpD,MAAMM,cAAchC,cAAc,CAAC,CAACiC,OAAO,GAAKA,OAAOC,MAAM;IAC7D,IAAIA,SAAS,AAACF,aAAaF,SAAsB,EAAE;IACnDI,SAASA,OAAOC,GAAG,CAAC,CAACC,QAAUA,MAAMC,OAAO,CAAC,KAAK,IAAIA,OAAO,CAAC,KAAK;IAEnE,MAAMC,UAAU;QAAC;QAAc;QAAYlC;KAAU,CAACmC,IAAI,CAAC;IAE3D,qBACE,MAACC;QAAIC,WAAWH;;0BACd,KAACxC;gBAAW8B,OAAOA;gBAAOF,MAAMA;gBAAMG,UAAUA;;0BAChD,KAAC1B;gBACCuC,UAAU;gBACVZ,OAAOA,SAAS;gBAChBa,UAAU,CAACC,GAAGC,WAAad,SAASc;gBACpCC,OAAOzC;0BAEP,cAAA,KAACH;oBACC6C,SAAQ;oBACRC,MAAMd,OAAOC,GAAG,CAAC,CAACc,IAAO,CAAA;4BAAEC,IAAID;4BAAG1C,SAAS0C;wBAAE,CAAA;oBAC7CE,QAAO;oBACPC,kBAAkB,CAACR,GAAGrC,UAAY,CAAC,CAAC,EAAEA,QAAQ,CAAC,CAAC;oBAChD8C,gBAAgB;;;;;AAK1B,EAAE"}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { useConfig, useFormFields } from '@payloadcms/ui';
|
|
4
|
+
import { getRouteResolver } from '@websolutespa/payload-utils';
|
|
4
5
|
import * as React from 'react';
|
|
5
6
|
export const Tokens = (props)=>{
|
|
6
|
-
const {
|
|
7
|
-
const { label, required } = field;
|
|
7
|
+
const { config } = useConfig();
|
|
8
8
|
const collectionsField = useFormFields(([fields])=>fields['collections']);
|
|
9
|
-
const
|
|
10
|
-
path
|
|
11
|
-
});
|
|
9
|
+
const [tokens, setTokens] = React.useState([]);
|
|
12
10
|
React.useEffect(()=>{
|
|
13
11
|
const fetchOptions = async ()=>{
|
|
14
12
|
try {
|
|
15
13
|
const collections = collectionsField?.value;
|
|
16
|
-
const
|
|
14
|
+
const routeResolver = getRouteResolver(config);
|
|
15
|
+
const url = routeResolver.api(`/seo/tokens?collections=${collections?.join(',') || ''}`);
|
|
17
16
|
const response = await fetch(url, {
|
|
18
17
|
method: 'GET',
|
|
19
18
|
credentials: 'include',
|
|
@@ -22,11 +21,10 @@ export const Tokens = (props)=>{
|
|
|
22
21
|
}
|
|
23
22
|
});
|
|
24
23
|
if (response.ok) {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
setValue(tokens);
|
|
24
|
+
const fetchedTokens = await response.json();
|
|
25
|
+
setTokens(fetchedTokens);
|
|
28
26
|
} else {
|
|
29
|
-
|
|
27
|
+
setTokens([]);
|
|
30
28
|
}
|
|
31
29
|
} catch (error) {
|
|
32
30
|
console.error('Error fetching data:', error);
|
|
@@ -34,12 +32,13 @@ export const Tokens = (props)=>{
|
|
|
34
32
|
};
|
|
35
33
|
fetchOptions();
|
|
36
34
|
}, [
|
|
37
|
-
collectionsField
|
|
35
|
+
collectionsField?.value,
|
|
36
|
+
config
|
|
38
37
|
]);
|
|
39
38
|
return /*#__PURE__*/ _jsx("div", {
|
|
40
39
|
className: "tokens-list",
|
|
41
40
|
children: /*#__PURE__*/ _jsx("ul", {
|
|
42
|
-
children:
|
|
41
|
+
children: tokens.map((token)=>/*#__PURE__*/ _jsx("li", {
|
|
43
42
|
children: token
|
|
44
43
|
}, token))
|
|
45
44
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Tokens.tsx"],"sourcesContent":["'use client';\r\n\r\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/components/Tokens.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useConfig, useFormFields } from '@payloadcms/ui';\r\nimport { getRouteResolver } from '@websolutespa/payload-utils';\r\nimport { TextFieldClientProps } from 'payload';\r\nimport * as React from 'react';\r\n\r\nexport const Tokens: React.FC<TextFieldClientProps> = (props) => {\r\n const { config } = useConfig();\r\n const collectionsField = useFormFields(([fields]) => fields['collections']);\r\n const [tokens, setTokens] = React.useState<string[]>([]);\r\n\r\n React.useEffect(() => {\r\n const fetchOptions = async () => {\r\n try {\r\n const collections = collectionsField?.value as string[] | undefined;\r\n const routeResolver = getRouteResolver(config);\r\n const url = routeResolver.api(`/seo/tokens?collections=${(collections?.join(',') || '')}`);\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n credentials: 'include',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n if (response.ok) {\r\n const fetchedTokens = (await response.json()) as string[];\r\n setTokens(fetchedTokens);\r\n } else {\r\n setTokens([]);\r\n }\r\n } catch (error) {\r\n console.error('Error fetching data:', error);\r\n }\r\n };\r\n\r\n fetchOptions();\r\n }, [collectionsField?.value, config]);\r\n\r\n return (\r\n <div className=\"tokens-list\">\r\n <ul>\r\n {tokens.map((token) => (\r\n <li key={token}>{token}</li>\r\n ))}\r\n </ul>\r\n </div>\r\n );\r\n};\r\n"],"names":["useConfig","useFormFields","getRouteResolver","React","Tokens","props","config","collectionsField","fields","tokens","setTokens","useState","useEffect","fetchOptions","collections","value","routeResolver","url","api","join","response","fetch","method","credentials","headers","ok","fetchedTokens","json","error","console","div","className","ul","map","token","li"],"mappings":"AAAA;;AAEA,SAASA,SAAS,EAAEC,aAAa,QAAQ,iBAAiB;AAC1D,SAASC,gBAAgB,QAAQ,8BAA8B;AAE/D,YAAYC,WAAW,QAAQ;AAE/B,OAAO,MAAMC,SAAyC,CAACC;IACrD,MAAM,EAAEC,MAAM,EAAE,GAAGN;IACnB,MAAMO,mBAAmBN,cAAc,CAAC,CAACO,OAAO,GAAKA,MAAM,CAAC,cAAc;IAC1E,MAAM,CAACC,QAAQC,UAAU,GAAGP,MAAMQ,QAAQ,CAAW,EAAE;IAEvDR,MAAMS,SAAS,CAAC;QACd,MAAMC,eAAe;YACnB,IAAI;gBACF,MAAMC,cAAcP,kBAAkBQ;gBACtC,MAAMC,gBAAgBd,iBAAiBI;gBACvC,MAAMW,MAAMD,cAAcE,GAAG,CAAC,CAAC,wBAAwB,EAAGJ,aAAaK,KAAK,QAAQ,GAAI,CAAC;gBACzF,MAAMC,WAAW,MAAMC,MAAMJ,KAAK;oBAChCK,QAAQ;oBACRC,aAAa;oBACbC,SAAS;wBACP,gBAAgB;oBAClB;gBACF;gBACA,IAAIJ,SAASK,EAAE,EAAE;oBACf,MAAMC,gBAAiB,MAAMN,SAASO,IAAI;oBAC1CjB,UAAUgB;gBACZ,OAAO;oBACLhB,UAAU,EAAE;gBACd;YACF,EAAE,OAAOkB,OAAO;gBACdC,QAAQD,KAAK,CAAC,wBAAwBA;YACxC;QACF;QAEAf;IACF,GAAG;QAACN,kBAAkBQ;QAAOT;KAAO;IAEpC,qBACE,KAACwB;QAAIC,WAAU;kBACb,cAAA,KAACC;sBACEvB,OAAOwB,GAAG,CAAC,CAACC,sBACX,KAACC;8BAAgBD;mBAARA;;;AAKnB,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","names":[],"sources":["../../src/components/TextWithTokens.tsx","../../src/components/Tokens.tsx"],"sourcesContent":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"client.d.ts","names":[],"sources":["../../src/components/TextWithTokens.tsx","../../src/components/Tokens.tsx"],"sourcesContent":[],"mappings":";;;;cAgDa,gBAAgB,KAAA,CAAM,GAAG;;;;cCzCzB,QAAQ,KAAA,CAAM,GAAG"}
|
package/dist/exports/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["'use client';\r\n\r\nexport { TextWithTokens } from '../components/TextWithTokens';\r\nexport { Tokens } from '../components/Tokens';\r\n\r\n"],"names":["TextWithTokens","Tokens"],"mappings":"AAAA;AAEA,SAASA,cAAc,QAAQ,+BAA+B;AAC9D,SAASC,MAAM,QAAQ,uBAAuB"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/utils/fields.ts","../src/utils/findVal.ts","../src/seo.ts"],"sourcesContent":[],"mappings":";;;;KAGY,cAAA;;EAAA,gBAAA,CAAc,EAEL,SAFK,EAAA;EAAA,YAAA,CAAA,EAGT,QAHS,EAAA;EAAA,eAEL,CAAA,EAAA,MAAA;EAAS,mBACb,CAAA,EAEO,kBAFP;EAAQ,OAED,CAAA,EAAA,OAAA;AAAkB,CAAA;AAI9B,KAAA,OAAA,GAAU,MAAH,CAAA,MAAA,EAAkB,cAAlB,CAAA,GAAA;EAAA,YAAA,EACH,cADG;CAAA;AAAG,KAIV,QAAA,GAJU;EAAM,GACZ,EAAA,MAAA;EAAc,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAG9B,CAAA;AAKY,KAAA,QAAA,GAAQ;EAAA,IAAA,EAAA,MAAA;EAAA,mBAGX,EAAA,CAAA,GAAA,EAAA,cAAA,EAAA,UAAA,EACO,gBADP,EAAA,GAAA,EAAA;IACO,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,GAAA;EAAgB,CAAA,EAEpB,MAAA,EAAA,MAAA,GAAA,IAAA,EAAA,GACL,OADK,CAAA,MAAA,CAAA,GAAA,MAAA;CAAM;AACJ,KAGF,kBAAA,GAHE;EAGF,MAAA,CAAA,EACD,MADC;EAAkB,IAAA,CAAA,EAErB,MAFqB;EAAA,YACnB,CAAA,EAEM,MAFN;EAAM,MACR,CAAA,EAEE,MAFF;EAAM,MACE,CAAA,EAEN,MAFM;EAAM,KACZ,CAAA,EAAA,CAAA,IAAA,CAAA,EAAA,GAAA,EAAA,GAAA,OAAA,GAEyB,OAFzB,CAAA,OAAA,CAAA;EAAM,MACN,CAAA,EAEA,MAFA;CAAM;AAEN,KAGC,UAAA,GAHD;EAAM,WAAA,EAAA,MAAA,EAAA;EAGL,YAAA,EAEI,QAFM,EAAA;EAAA,gBAAA,EAGF,SAHE,EAAA;EAAA,eAEN,EAAA,MAAA;EAAQ,aACJ,EAAA,MAAA;EAAS,aAIpB,EAAA,MAAA;EAAQ,KACK,EADb,QACa;EAAM,OACpB,EAAA,MAAA,EAAA,GADc,MACd,EAAA;EAAO,IACC,EADR,OACQ;EAAQ,YAAA,EAAR,QAAQ;;;;;KChDZ,QAAA,GAAW,YAAY,gBAAgB,gBAAgB;iBAEnD,UAAA,QAAkB,iBAAiB;ADFvC,cCMC,kBDNa,EAAA,MAAA,EAAA;AAAA,KCQd,gBAAA,GAAmB,SDRL,GCQiB,aDRjB,GCQiC,aDRjC,GCQiD,iBDRjD;AAEL,iBCQL,kBAAA,CDRK,KAAA,ECQqB,KDRrB,CAAA,EAAA,KAAA,ICQsC,gBDRtC;AACJ,iBCWD,oBAAA,CDXC,MAAA,ECW4B,KDX5B,EAAA,EAAA,QAAA,EAAA,CAAA,KAAA,ECWuD,gBDXvD,EAAA,KAAA,EAAA,MAAA,EAAA,EAAA,MAAA,CAAA,ECWmG,KDXnG,GCW2G,KDX3G,GCWmH,GDXnH,EAAA,GAAA,OAAA,GAAA,IAAA,EAAA,QAAA,CAAA,EAAA,MAAA,CAAA,EAAA,OAAA,GAAA,IAAA;AAEO,iBCiBR,YAAA,CDjBQ,MAAA,ECiBa,KDjBb,EAAA,EAAA,IAAA,EAAA,MAAA,CAAA,ECiBqC,SDjBrC,GAAA,SAAA;AAAkB,iBC4B1B,oBAAA,CD5B0B,UAAA,EC4BO,gBD5BP,CAAA,EC4BuB,gBD5BvB,EAAA;AAI1C;;;cEZa;;;;;AFqBO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/utils/fields.ts","../src/utils/findVal.ts","../src/seo.ts"],"sourcesContent":[],"mappings":";;;;KAGY,cAAA;;EAAA,gBAAA,CAAc,EAEL,SAFK,EAAA;EAAA,YAAA,CAAA,EAGT,QAHS,EAAA;EAAA,eAEL,CAAA,EAAA,MAAA;EAAS,mBACb,CAAA,EAEO,kBAFP;EAAQ,OAED,CAAA,EAAA,OAAA;AAAkB,CAAA;AAI9B,KAAA,OAAA,GAAU,MAAH,CAAA,MAAA,EAAkB,cAAlB,CAAA,GAAA;EAAA,YAAA,EACH,cADG;CAAA;AAAG,KAIV,QAAA,GAJU;EAAM,GACZ,EAAA,MAAA;EAAc,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAG9B,CAAA;AAKY,KAAA,QAAA,GAAQ;EAAA,IAAA,EAAA,MAAA;EAAA,mBAGX,EAAA,CAAA,GAAA,EAAA,cAAA,EAAA,UAAA,EACO,gBADP,EAAA,GAAA,EAAA;IACO,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,GAAA;EAAgB,CAAA,EAEpB,MAAA,EAAA,MAAA,GAAA,IAAA,EAAA,GACL,OADK,CAAA,MAAA,CAAA,GAAA,MAAA;CAAM;AACJ,KAGF,kBAAA,GAHE;EAGF,MAAA,CAAA,EACD,MADC;EAAkB,IAAA,CAAA,EAErB,MAFqB;EAAA,YACnB,CAAA,EAEM,MAFN;EAAM,MACR,CAAA,EAEE,MAFF;EAAM,MACE,CAAA,EAEN,MAFM;EAAM,KACZ,CAAA,EAAA,CAAA,IAAA,CAAA,EAAA,GAAA,EAAA,GAAA,OAAA,GAEyB,OAFzB,CAAA,OAAA,CAAA;EAAM,MACN,CAAA,EAEA,MAFA;CAAM;AAEN,KAGC,UAAA,GAHD;EAAM,WAAA,EAAA,MAAA,EAAA;EAGL,YAAA,EAEI,QAFM,EAAA;EAAA,gBAAA,EAGF,SAHE,EAAA;EAAA,eAEN,EAAA,MAAA;EAAQ,aACJ,EAAA,MAAA;EAAS,aAIpB,EAAA,MAAA;EAAQ,KACK,EADb,QACa;EAAM,OACpB,EAAA,MAAA,EAAA,GADc,MACd,EAAA;EAAO,IACC,EADR,OACQ;EAAQ,YAAA,EAAR,QAAQ;;;;;KChDZ,QAAA,GAAW,YAAY,gBAAgB,gBAAgB;iBAEnD,UAAA,QAAkB,iBAAiB;ADFvC,cCMC,kBDNa,EAAA,MAAA,EAAA;AAAA,KCQd,gBAAA,GAAmB,SDRL,GCQiB,aDRjB,GCQiC,aDRjC,GCQiD,iBDRjD;AAEL,iBCQL,kBAAA,CDRK,KAAA,ECQqB,KDRrB,CAAA,EAAA,KAAA,ICQsC,gBDRtC;AACJ,iBCWD,oBAAA,CDXC,MAAA,ECW4B,KDX5B,EAAA,EAAA,QAAA,EAAA,CAAA,KAAA,ECWuD,gBDXvD,EAAA,KAAA,EAAA,MAAA,EAAA,EAAA,MAAA,CAAA,ECWmG,KDXnG,GCW2G,KDX3G,GCWmH,GDXnH,EAAA,GAAA,OAAA,GAAA,IAAA,EAAA,QAAA,CAAA,EAAA,MAAA,CAAA,EAAA,OAAA,GAAA,IAAA;AAEO,iBCiBR,YAAA,CDjBQ,MAAA,ECiBa,KDjBb,EAAA,EAAA,IAAA,EAAA,MAAA,CAAA,ECiBqC,SDjBrC,GAAA,SAAA;AAAkB,iBC4B1B,oBAAA,CD5B0B,UAAA,EC4BO,gBD5BP,CAAA,EC4BuB,gBD5BvB,EAAA;AAI1C;;;cEZa;;;;;AFqBO,cGiPP,GHjPO,EAAA,CAAA,aAAA,EGiPe,cHjPf,EAAA,GGiPgC,MHjPhC"}
|
package/dist/seo.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isObject } from '@websolutespa/bom-core';
|
|
2
|
-
import { richTextToText } from '@websolutespa/payload-utils';
|
|
2
|
+
import { richTextToText, stripHtml } from '@websolutespa/payload-utils';
|
|
3
3
|
import { tokensGet } from './api/tokens.service';
|
|
4
4
|
import { MetatagsRule } from './collections/MetatagsRule';
|
|
5
5
|
import { options } from './options';
|
|
@@ -43,7 +43,9 @@ const replaceTokens = async (req, collection, doc, str, locale)=>{
|
|
|
43
43
|
}
|
|
44
44
|
case 'richText':
|
|
45
45
|
{
|
|
46
|
-
|
|
46
|
+
const val = locale && fieldConfig?.localized ? fieldValue[locale.code] ?? fieldValue[defaultLocale] ?? (typeof fieldValue === 'object' && fieldValue !== null ? Object.values(fieldValue)[0] : fieldValue) : fieldValue;
|
|
47
|
+
const textVal = typeof val === 'string' ? stripHtml(val) : richTextToText(val);
|
|
48
|
+
str = str.replace(token, textVal || '');
|
|
47
49
|
break;
|
|
48
50
|
}
|
|
49
51
|
case 'relationship':
|
|
@@ -89,7 +91,7 @@ const replaceTokens = async (req, collection, doc, str, locale)=>{
|
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
|
-
return str;
|
|
94
|
+
return str.trim();
|
|
93
95
|
};
|
|
94
96
|
const setDocMetatags = async ({ req, doc, collection })=>{
|
|
95
97
|
try {
|
package/dist/seo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/seo.ts"],"sourcesContent":["import { isObject } from '@websolutespa/bom-core';\r\nimport { richTextToText } from '@websolutespa/payload-utils';\r\nimport { CollectionAfterOperationHook, CollectionConfig, Config, Field, Locale, Payload, PayloadRequest, Plugin, TypeWithID } from 'payload';\r\nimport { tokensGet } from './api/tokens.service';\r\nimport { MetatagsRule } from './collections/MetatagsRule';\r\nimport { options } from './options';\r\nimport { SeoInitOptions } from './types';\r\nimport { fromCache } from './utils/cache';\r\nimport { getTokenizableFields } from './utils/fields';\r\nimport { findVal } from './utils/findVal';\r\n\r\nexport type MetatagsRule = {\r\n id: string;\r\n title: Record<string, string>;\r\n description: Record<string, string>;\r\n keywords: Record<string, string>;\r\n [key: string]: Record<string, string> | string;\r\n};\r\n\r\nexport type DocWithMetas = TypeWithID & {\r\n [key: string]: unknown;\r\n meta?: {\r\n title?: string;\r\n description?: string;\r\n keywords?: string;\r\n [key: string]: any;\r\n };\r\n};\r\n\r\nconst replaceTokens = async (req: PayloadRequest, collection: CollectionConfig, doc: DocWithMetas, str: string, locale: Locale | null) => {\r\n const tokens: string[] = str.match(/\\[(.*?)\\]/g) || [];\r\n\r\n const defaultLocale = req.payload.config.localization ? req.payload.config.localization.defaultLocale : 'en';\r\n const fields = getTokenizableFields(collection);\r\n\r\n for (const token of tokens) {\r\n const customToken = options.customTokens.find(customToken => `[${customToken.name}]` === token);\r\n\r\n if (customToken) {\r\n // token is a custom token\r\n try {\r\n str = str.replace(token, await customToken.replacementFunction(req, collection, doc, locale));\r\n }\r\n catch (error) {\r\n console.error(`Error while replacing customtoken \"${token}\": ${error}`);\r\n }\r\n }\r\n else {\r\n // token is a doc field\r\n const fieldName = token.replace(/[[\\]]/g, '');\r\n\r\n const fieldConfig = fields.find(f => f.name === fieldName);\r\n if (!fieldConfig) {\r\n // remove token if field not found\r\n str = str.replace(token, '');\r\n continue;\r\n }\r\n\r\n const fieldValue = findVal(doc, fieldName);\r\n if (!fieldValue || Object.keys(fieldValue).length === 0) {\r\n // remove token if field is empty\r\n str = str.replace(token, '');\r\n continue;\r\n }\r\n\r\n switch (fieldConfig?.type) {\r\n case 'text':\r\n case 'textarea': {\r\n str = str.replace(token, locale && fieldConfig?.localized ?\r\n fieldValue[locale.code] ?? fieldValue[defaultLocale] ?? Object.values(fieldValue)[0] :\r\n fieldValue\r\n );\r\n break;\r\n }\r\n\r\n case 'richText': {\r\n str = str.replace(token, locale && fieldConfig?.localized ?\r\n richTextToText(fieldValue[locale.code]) ?? richTextToText(fieldValue[defaultLocale]) :\r\n richTextToText(fieldValue)\r\n );\r\n break;\r\n }\r\n\r\n case 'relationship': {\r\n const isPolymorphicRel = Array.isArray(fieldConfig.relationTo);\r\n if (!isPolymorphicRel) {\r\n if (locale && fieldConfig.hasMany) {\r\n // payload seems to return an array of ids for hasMany relationships (when requesting locale=all).\r\n // We replace the token with a comma-separated list of ids.\r\n str = str.replace(token, fieldValue.map((id: string) => id).join(', '));\r\n }\r\n else {\r\n // hasMany = false or request is specific locale\r\n const relatedConfig = req.payload.config.collections.find(c => c.slug === fieldConfig.relationTo);\r\n if (relatedConfig) {\r\n const relatedCollfields = getTokenizableFields(relatedConfig);\r\n const titleField = relatedConfig?.admin?.useAsTitle ?\r\n relatedCollfields.find(f => f.name === relatedConfig.admin.useAsTitle) : relatedCollfields.find(f => f.name === 'title');\r\n if (titleField) {\r\n if (fieldConfig.hasMany) {\r\n // hasMany = true and request is specific locale\r\n const titleFieldValue = fieldValue.map((value: any) => findVal(value, titleField.name)).join(', ');\r\n str = str.replace(token, titleFieldValue);\r\n }\r\n else {\r\n // hasMany = false and request is either specific locale or all locales\r\n const titleFieldValue = findVal(fieldValue, titleField.name);\r\n if (!titleFieldValue || Object.keys(titleFieldValue).length === 0) {\r\n str = str.replace(token, '');\r\n }\r\n else {\r\n str = str.replace(token, locale && titleField?.localized ?\r\n titleFieldValue[locale.code] ?? titleFieldValue[defaultLocale] : titleFieldValue);\r\n }\r\n }\r\n }\r\n else {\r\n // remove token if neither title nor default fallback title field found\r\n str = str.replace(token, '');\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n // todo: handle polymorphic relationships\r\n str = str.replace(token, '');\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return str;\r\n};\r\n\r\nconst setDocMetatags = async ({\r\n req,\r\n doc,\r\n collection,\r\n}: {\r\n req: PayloadRequest;\r\n doc: DocWithMetas;\r\n collection: CollectionConfig;\r\n}): Promise<DocWithMetas> => {\r\n try {\r\n const { payload } = req;\r\n const defaultLocale = req.payload.config.localization ? req.payload.config.localization.defaultLocale : 'en';\r\n\r\n // get all rules for this collection\r\n const result = await fromCache(\r\n async () => await payload.find({\r\n collection: options.slug.metatagsRule,\r\n where: {\r\n or: [\r\n { collections: { equals: '' } },\r\n { collections: { equals: [] } },\r\n { collections: { equals: null } },\r\n { collections: { exists: false } },\r\n { collections: { contains: collection.slug } },\r\n ],\r\n },\r\n pagination: false,\r\n overrideAccess: true,\r\n locale: 'all',\r\n }),\r\n 'metatags-rules-' + collection.slug,\r\n 60 // TODO: add to plugin options\r\n );\r\n let rules = result.docs as MetatagsRule[];\r\n // sort rules by \"priority\": global (empty collections) last\r\n rules = rules.sort((a, b) => (a.collections || []).length === 0 ? 1 : (b.collections || []).length === 0 ? -1 : 0);\r\n\r\n // set meta fields values\r\n const metaFields = ['title', 'description', 'keywords', ...options.additionalFields.map(field => field.name)];\r\n for (const rule of rules) {\r\n for (const metafield of metaFields) {\r\n doc.meta = doc.meta || {};\r\n\r\n if (doc.meta[metafield]) {\r\n // if doc meta field is already set, skip\r\n continue;\r\n }\r\n\r\n if (req.locale === 'all') {\r\n const locales = req.payload?.config.localization ? req.payload.config.localization.locales : [];\r\n for (const locale of locales) {\r\n // put rule value in doc meta field (for this specific locale) and replace tokens\r\n let ruleValue = rule[metafield];\r\n if (isObject(ruleValue)) {\r\n ruleValue = ruleValue[locale.code] ?? ruleValue[defaultLocale] ?? Object.values(ruleValue)[0];\r\n }\r\n if (ruleValue) {\r\n doc.meta[metafield] = doc.meta[metafield] || {};\r\n doc.meta[metafield][locale.code] = await replaceTokens(req, collection, doc, ruleValue, locale);\r\n }\r\n }\r\n }\r\n else {\r\n // put rule value in doc meta field and replace tokens\r\n let ruleValue = rule[metafield];\r\n if (isObject(ruleValue)) {\r\n ruleValue = ruleValue[req.locale ?? defaultLocale] ?? ruleValue[defaultLocale] ?? Object.values(ruleValue)[0];\r\n }\r\n if (ruleValue) {\r\n doc.meta[metafield] = await replaceTokens(req, collection, doc, ruleValue, null);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n catch (error) {\r\n console.error(`Error while setting seo metatags: ${error}`);\r\n }\r\n\r\n return doc;\r\n};\r\n\r\nconst setCollectionMetatags: CollectionAfterOperationHook = async ({\r\n args,\r\n operation,\r\n result,\r\n}) => {\r\n const { req, collection } = args;\r\n\r\n if (req?.query && req.query[options.qsMetatagsRules] === undefined) {\r\n return result;\r\n }\r\n\r\n if (operation !== 'find') {\r\n if (result && typeof result === 'object' && !Array.isArray(result) && !('docs' in result)) {\r\n const updatedDoc = await setDocMetatags({\r\n req: req as PayloadRequest,\r\n doc: result as DocWithMetas,\r\n collection: collection.config,\r\n });\r\n\r\n return updatedDoc;\r\n }\r\n } else if (operation === 'find' && req?.pathname === '/store') {\r\n if (result && typeof result === 'object' && 'docs' in result && Array.isArray(result.docs)) {\r\n const documentPromises = result.docs.map(async doc => {\r\n return await setDocMetatags({\r\n req: req as PayloadRequest,\r\n doc: doc as DocWithMetas,\r\n collection: collection.config,\r\n });\r\n });\r\n\r\n const updatedDocs = await Promise.all(documentPromises);\r\n result.docs = updatedDocs;\r\n\r\n return result;\r\n }\r\n }\r\n\r\n return result;\r\n};\r\n\r\nexport const seo = (sourceOptions: SeoInitOptions): Plugin => (sourceConfig: Config): Config => {\r\n if (sourceOptions.enabled === false) {\r\n return sourceConfig;\r\n }\r\n // set plugin options\r\n options.collections = sourceOptions.collections ? Object.assign(options.collections, sourceOptions.collections)\r\n : Object.assign(options.collections, sourceConfig.collections?.map(x => x.slug));\r\n options.additionalFields = sourceOptions.additionalFields || [];\r\n options.customTokens = sourceOptions.customTokens ? Object.assign(options.customTokens, sourceOptions.customTokens) : [];\r\n options.qsMetatagsRules = sourceOptions.qsMetatagsRules || 'seoMetatagsRules';\r\n\r\n // replace meta tokens\r\n const collections = sourceConfig.collections?.filter(collection => options.collections.includes(collection.slug));\r\n collections?.forEach(collection => {\r\n collection.hooks = {\r\n ...collection.hooks,\r\n afterOperation: [\r\n ...(collection.hooks?.afterOperation || []),\r\n setCollectionMetatags,\r\n ],\r\n };\r\n });\r\n\r\n const targetConfig: Config = {\r\n ...sourceConfig,\r\n collections: [\r\n ...(sourceConfig.collections || []),\r\n {\r\n ...MetatagsRule,\r\n fields: [\r\n ...MetatagsRule.fields,\r\n ...options.additionalFields.map(field => field.type == 'text' || field.type == 'textarea' ?\r\n {\r\n ...field,\r\n admin: {\r\n ...field.admin,\r\n components: {\r\n ...field.admin?.components,\r\n Field: '@websolutespa/payload-plugin-seo/client#TextWithTokens',\r\n },\r\n },\r\n } : field),\r\n ] as Field[],\r\n access: {\r\n ...MetatagsRule.access,\r\n ...sourceOptions.metatagsRulesAccess,\r\n },\r\n },\r\n ],\r\n endpoints: [\r\n ...sourceConfig.endpoints || [],\r\n tokensGet(),\r\n ],\r\n onInit: async (payload: Payload) => {\r\n if (typeof sourceConfig.onInit === 'function') {\r\n await sourceConfig.onInit(payload);\r\n }\r\n console.log('@websolutespa/payload-plugin-seo.onInit');\r\n },\r\n };\r\n\r\n return targetConfig;\r\n};\r\n\r\nexport default seo;\r\n"],"names":["isObject","richTextToText","tokensGet","MetatagsRule","options","fromCache","getTokenizableFields","findVal","replaceTokens","req","collection","doc","str","locale","tokens","match","defaultLocale","payload","config","localization","fields","token","customToken","customTokens","find","name","replace","replacementFunction","error","console","fieldName","fieldConfig","f","fieldValue","Object","keys","length","type","localized","code","values","isPolymorphicRel","Array","isArray","relationTo","hasMany","map","id","join","relatedConfig","collections","c","slug","relatedCollfields","titleField","admin","useAsTitle","titleFieldValue","value","setDocMetatags","result","metatagsRule","where","or","equals","exists","contains","pagination","overrideAccess","rules","docs","sort","a","b","metaFields","additionalFields","field","rule","metafield","meta","locales","ruleValue","setCollectionMetatags","args","operation","query","qsMetatagsRules","undefined","updatedDoc","pathname","documentPromises","updatedDocs","Promise","all","seo","sourceOptions","sourceConfig","enabled","assign","x","filter","includes","forEach","hooks","afterOperation","targetConfig","components","Field","access","metatagsRulesAccess","endpoints","onInit","log"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/seo.ts"],"sourcesContent":["import { isObject } from '@websolutespa/bom-core';\r\nimport { richTextToText, stripHtml } from '@websolutespa/payload-utils';\r\nimport { CollectionAfterOperationHook, CollectionConfig, Config, Field, Locale, Payload, PayloadRequest, Plugin, TypeWithID } from 'payload';\r\nimport { tokensGet } from './api/tokens.service';\r\nimport { MetatagsRule } from './collections/MetatagsRule';\r\nimport { options } from './options';\r\nimport { SeoInitOptions } from './types';\r\nimport { fromCache } from './utils/cache';\r\nimport { getTokenizableFields } from './utils/fields';\r\nimport { findVal } from './utils/findVal';\r\n\r\nexport type MetatagsRule = {\r\n id: string;\r\n title: Record<string, string>;\r\n description: Record<string, string>;\r\n keywords: Record<string, string>;\r\n [key: string]: Record<string, string> | string;\r\n};\r\n\r\nexport type DocWithMetas = TypeWithID & {\r\n [key: string]: unknown;\r\n meta?: {\r\n title?: string;\r\n description?: string;\r\n keywords?: string;\r\n [key: string]: any;\r\n };\r\n};\r\n\r\nconst replaceTokens = async (req: PayloadRequest, collection: CollectionConfig, doc: DocWithMetas, str: string, locale: Locale | null) => {\r\n const tokens: string[] = str.match(/\\[(.*?)\\]/g) || [];\r\n\r\n const defaultLocale = req.payload.config.localization ? req.payload.config.localization.defaultLocale : 'en';\r\n const fields = getTokenizableFields(collection);\r\n\r\n for (const token of tokens) {\r\n const customToken = options.customTokens.find(customToken => `[${customToken.name}]` === token);\r\n\r\n if (customToken) {\r\n // token is a custom token\r\n try {\r\n str = str.replace(token, await customToken.replacementFunction(req, collection, doc, locale));\r\n }\r\n catch (error) {\r\n console.error(`Error while replacing customtoken \"${token}\": ${error}`);\r\n }\r\n }\r\n else {\r\n // token is a doc field\r\n const fieldName = token.replace(/[[\\]]/g, '');\r\n\r\n const fieldConfig = fields.find(f => f.name === fieldName);\r\n if (!fieldConfig) {\r\n // remove token if field not found\r\n str = str.replace(token, '');\r\n continue;\r\n }\r\n\r\n const fieldValue = findVal(doc, fieldName);\r\n if (!fieldValue || Object.keys(fieldValue).length === 0) {\r\n // remove token if field is empty\r\n str = str.replace(token, '');\r\n continue;\r\n }\r\n\r\n switch (fieldConfig?.type) {\r\n case 'text':\r\n case 'textarea': {\r\n str = str.replace(token, locale && fieldConfig?.localized ?\r\n fieldValue[locale.code] ?? fieldValue[defaultLocale] ?? Object.values(fieldValue)[0] :\r\n fieldValue\r\n );\r\n break;\r\n }\r\n\r\n case 'richText': {\r\n const val = locale && fieldConfig?.localized ?\r\n (fieldValue[locale.code] ?? fieldValue[defaultLocale] ?? (typeof fieldValue === 'object' && fieldValue !== null ? Object.values(fieldValue)[0] : fieldValue)) :\r\n fieldValue;\r\n\r\n const textVal = typeof val === 'string' ? stripHtml(val) : richTextToText(val);\r\n\r\n str = str.replace(token, textVal || '');\r\n break;\r\n }\r\n\r\n case 'relationship': {\r\n const isPolymorphicRel = Array.isArray(fieldConfig.relationTo);\r\n if (!isPolymorphicRel) {\r\n if (locale && fieldConfig.hasMany) {\r\n // payload seems to return an array of ids for hasMany relationships (when requesting locale=all).\r\n // We replace the token with a comma-separated list of ids.\r\n str = str.replace(token, fieldValue.map((id: string) => id).join(', '));\r\n }\r\n else {\r\n // hasMany = false or request is specific locale\r\n const relatedConfig = req.payload.config.collections.find(c => c.slug === fieldConfig.relationTo);\r\n if (relatedConfig) {\r\n const relatedCollfields = getTokenizableFields(relatedConfig);\r\n const titleField = relatedConfig?.admin?.useAsTitle ?\r\n relatedCollfields.find(f => f.name === relatedConfig.admin.useAsTitle) : relatedCollfields.find(f => f.name === 'title');\r\n if (titleField) {\r\n if (fieldConfig.hasMany) {\r\n // hasMany = true and request is specific locale\r\n const titleFieldValue = fieldValue.map((value: any) => findVal(value, titleField.name)).join(', ');\r\n str = str.replace(token, titleFieldValue);\r\n }\r\n else {\r\n // hasMany = false and request is either specific locale or all locales\r\n const titleFieldValue = findVal(fieldValue, titleField.name);\r\n if (!titleFieldValue || Object.keys(titleFieldValue).length === 0) {\r\n str = str.replace(token, '');\r\n }\r\n else {\r\n str = str.replace(token, locale && titleField?.localized ?\r\n titleFieldValue[locale.code] ?? titleFieldValue[defaultLocale] : titleFieldValue);\r\n }\r\n }\r\n }\r\n else {\r\n // remove token if neither title nor default fallback title field found\r\n str = str.replace(token, '');\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n // todo: handle polymorphic relationships\r\n str = str.replace(token, '');\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return str.trim();\r\n};\r\n\r\nconst setDocMetatags = async ({\r\n req,\r\n doc,\r\n collection,\r\n}: {\r\n req: PayloadRequest;\r\n doc: DocWithMetas;\r\n collection: CollectionConfig;\r\n}): Promise<DocWithMetas> => {\r\n try {\r\n const { payload } = req;\r\n const defaultLocale = req.payload.config.localization ? req.payload.config.localization.defaultLocale : 'en';\r\n\r\n // get all rules for this collection\r\n const result = await fromCache(\r\n async () => await payload.find({\r\n collection: options.slug.metatagsRule,\r\n where: {\r\n or: [\r\n { collections: { equals: '' } },\r\n { collections: { equals: [] } },\r\n { collections: { equals: null } },\r\n { collections: { exists: false } },\r\n { collections: { contains: collection.slug } },\r\n ],\r\n },\r\n pagination: false,\r\n overrideAccess: true,\r\n locale: 'all',\r\n }),\r\n 'metatags-rules-' + collection.slug,\r\n 60 // TODO: add to plugin options\r\n );\r\n let rules = result.docs as MetatagsRule[];\r\n // sort rules by \"priority\": global (empty collections) last\r\n rules = rules.sort((a, b) => (a.collections || []).length === 0 ? 1 : (b.collections || []).length === 0 ? -1 : 0);\r\n\r\n // set meta fields values\r\n const metaFields = ['title', 'description', 'keywords', ...options.additionalFields.map(field => field.name)];\r\n for (const rule of rules) {\r\n for (const metafield of metaFields) {\r\n doc.meta = doc.meta || {};\r\n\r\n if (doc.meta[metafield]) {\r\n // if doc meta field is already set, skip\r\n continue;\r\n }\r\n\r\n if (req.locale === 'all') {\r\n const locales = req.payload?.config.localization ? req.payload.config.localization.locales : [];\r\n for (const locale of locales) {\r\n // put rule value in doc meta field (for this specific locale) and replace tokens\r\n let ruleValue = rule[metafield];\r\n if (isObject(ruleValue)) {\r\n ruleValue = ruleValue[locale.code] ?? ruleValue[defaultLocale] ?? Object.values(ruleValue)[0];\r\n }\r\n if (ruleValue) {\r\n doc.meta[metafield] = doc.meta[metafield] || {};\r\n doc.meta[metafield][locale.code] = await replaceTokens(req, collection, doc, ruleValue, locale);\r\n }\r\n }\r\n }\r\n else {\r\n // put rule value in doc meta field and replace tokens\r\n let ruleValue = rule[metafield];\r\n if (isObject(ruleValue)) {\r\n ruleValue = ruleValue[req.locale ?? defaultLocale] ?? ruleValue[defaultLocale] ?? Object.values(ruleValue)[0];\r\n }\r\n if (ruleValue) {\r\n doc.meta[metafield] = await replaceTokens(req, collection, doc, ruleValue, null);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n catch (error) {\r\n console.error(`Error while setting seo metatags: ${error}`);\r\n }\r\n\r\n return doc;\r\n};\r\n\r\nconst setCollectionMetatags: CollectionAfterOperationHook = async ({\r\n args,\r\n operation,\r\n result,\r\n}) => {\r\n const { req, collection } = args;\r\n\r\n if (req?.query && req.query[options.qsMetatagsRules] === undefined) {\r\n return result;\r\n }\r\n\r\n if (operation !== 'find') {\r\n if (result && typeof result === 'object' && !Array.isArray(result) && !('docs' in result)) {\r\n const updatedDoc = await setDocMetatags({\r\n req: req as PayloadRequest,\r\n doc: result as DocWithMetas,\r\n collection: collection.config,\r\n });\r\n\r\n return updatedDoc;\r\n }\r\n } else if (operation === 'find' && req?.pathname === '/store') {\r\n if (result && typeof result === 'object' && 'docs' in result && Array.isArray(result.docs)) {\r\n const documentPromises = result.docs.map(async doc => {\r\n return await setDocMetatags({\r\n req: req as PayloadRequest,\r\n doc: doc as DocWithMetas,\r\n collection: collection.config,\r\n });\r\n });\r\n\r\n const updatedDocs = await Promise.all(documentPromises);\r\n result.docs = updatedDocs;\r\n\r\n return result;\r\n }\r\n }\r\n\r\n return result;\r\n};\r\n\r\nexport const seo = (sourceOptions: SeoInitOptions): Plugin => (sourceConfig: Config): Config => {\r\n if (sourceOptions.enabled === false) {\r\n return sourceConfig;\r\n }\r\n // set plugin options\r\n options.collections = sourceOptions.collections ? Object.assign(options.collections, sourceOptions.collections)\r\n : Object.assign(options.collections, sourceConfig.collections?.map(x => x.slug));\r\n options.additionalFields = sourceOptions.additionalFields || [];\r\n options.customTokens = sourceOptions.customTokens ? Object.assign(options.customTokens, sourceOptions.customTokens) : [];\r\n options.qsMetatagsRules = sourceOptions.qsMetatagsRules || 'seoMetatagsRules';\r\n\r\n // replace meta tokens\r\n const collections = sourceConfig.collections?.filter(collection => options.collections.includes(collection.slug));\r\n collections?.forEach(collection => {\r\n collection.hooks = {\r\n ...collection.hooks,\r\n afterOperation: [\r\n ...(collection.hooks?.afterOperation || []),\r\n setCollectionMetatags,\r\n ],\r\n };\r\n });\r\n\r\n const targetConfig: Config = {\r\n ...sourceConfig,\r\n collections: [\r\n ...(sourceConfig.collections || []),\r\n {\r\n ...MetatagsRule,\r\n fields: [\r\n ...MetatagsRule.fields,\r\n ...options.additionalFields.map(field => field.type == 'text' || field.type == 'textarea' ?\r\n {\r\n ...field,\r\n admin: {\r\n ...field.admin,\r\n components: {\r\n ...field.admin?.components,\r\n Field: '@websolutespa/payload-plugin-seo/client#TextWithTokens',\r\n },\r\n },\r\n } : field),\r\n ] as Field[],\r\n access: {\r\n ...MetatagsRule.access,\r\n ...sourceOptions.metatagsRulesAccess,\r\n },\r\n },\r\n ],\r\n endpoints: [\r\n ...sourceConfig.endpoints || [],\r\n tokensGet(),\r\n ],\r\n onInit: async (payload: Payload) => {\r\n if (typeof sourceConfig.onInit === 'function') {\r\n await sourceConfig.onInit(payload);\r\n }\r\n console.log('@websolutespa/payload-plugin-seo.onInit');\r\n },\r\n };\r\n\r\n return targetConfig;\r\n};\r\n\r\nexport default seo;\r\n"],"names":["isObject","richTextToText","stripHtml","tokensGet","MetatagsRule","options","fromCache","getTokenizableFields","findVal","replaceTokens","req","collection","doc","str","locale","tokens","match","defaultLocale","payload","config","localization","fields","token","customToken","customTokens","find","name","replace","replacementFunction","error","console","fieldName","fieldConfig","f","fieldValue","Object","keys","length","type","localized","code","values","val","textVal","isPolymorphicRel","Array","isArray","relationTo","hasMany","map","id","join","relatedConfig","collections","c","slug","relatedCollfields","titleField","admin","useAsTitle","titleFieldValue","value","trim","setDocMetatags","result","metatagsRule","where","or","equals","exists","contains","pagination","overrideAccess","rules","docs","sort","a","b","metaFields","additionalFields","field","rule","metafield","meta","locales","ruleValue","setCollectionMetatags","args","operation","query","qsMetatagsRules","undefined","updatedDoc","pathname","documentPromises","updatedDocs","Promise","all","seo","sourceOptions","sourceConfig","enabled","assign","x","filter","includes","forEach","hooks","afterOperation","targetConfig","components","Field","access","metatagsRulesAccess","endpoints","onInit","log"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@websolutespa/payload-plugin-seo",
|
|
3
|
-
"version": "2.0.1-next.
|
|
3
|
+
"version": "2.0.1-next.4",
|
|
4
4
|
"description": "SEO plugin for PayloadCms",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"payload",
|
|
@@ -29,14 +29,14 @@
|
|
|
29
29
|
"types": "tsc --noemit"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"react-
|
|
32
|
+
"react-mentions": "^4.4.10",
|
|
33
33
|
"ts-deepmerge": "^2.0.1"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@payloadcms/db-mongodb": "3.70.0",
|
|
37
|
+
"@payloadcms/ui": "3.70.0",
|
|
37
38
|
"@websolutespa/bom-core": "2.0.1-next.2",
|
|
38
39
|
"@websolutespa/payload-utils": "2.0.1-next.2",
|
|
39
|
-
"@payloadcms/ui": "3.70.0",
|
|
40
40
|
"payload": "3.70.0",
|
|
41
41
|
"react": "19.2.1",
|
|
42
42
|
"react-dom": "19.2.1",
|
|
@@ -49,8 +49,9 @@
|
|
|
49
49
|
"@swc/cli": "0.6.0",
|
|
50
50
|
"@swc/core": "1.6.4",
|
|
51
51
|
"@types/express": "^4.17.15",
|
|
52
|
-
"@types/react-dom": "19.2.1",
|
|
53
52
|
"@types/react": "19.2.1",
|
|
53
|
+
"@types/react-dom": "19.2.1",
|
|
54
|
+
"@types/react-mentions": "^4.4.1",
|
|
54
55
|
"@types/uuid": "^9.0.2",
|
|
55
56
|
"@websolutespa/bom-core": "2.0.1-next.2",
|
|
56
57
|
"@websolutespa/eslint-config": "2.0.1-next.2",
|
|
@@ -63,8 +64,8 @@
|
|
|
63
64
|
"mongodb-memory-server": "10.1.4",
|
|
64
65
|
"npm-run-all": "4.1.5",
|
|
65
66
|
"payload": "3.70.0",
|
|
66
|
-
"react-dom": "19.2.1",
|
|
67
67
|
"react": "19.2.1",
|
|
68
|
+
"react-dom": "19.2.1",
|
|
68
69
|
"tsdown": "0.12.9",
|
|
69
70
|
"typescript": "5.8.3",
|
|
70
71
|
"uuid": "9.0.1"
|