@payloadcms/plugin-seo 3.0.0-beta.7 → 3.0.0-beta.71
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/dist/defaults.js.map +1 -1
- package/dist/exports/fields.d.ts +6 -0
- package/dist/exports/fields.d.ts.map +1 -0
- package/dist/exports/fields.js +7 -0
- package/dist/exports/fields.js.map +1 -0
- package/dist/exports/types.d.ts +2 -0
- package/dist/exports/types.d.ts.map +1 -0
- package/dist/exports/types.js +3 -0
- package/dist/exports/types.js.map +1 -0
- package/dist/fields/MetaDescription/MetaDescriptionComponent.d.ts +9 -0
- package/dist/fields/MetaDescription/MetaDescriptionComponent.d.ts.map +1 -0
- package/dist/fields/MetaDescription/MetaDescriptionComponent.js +138 -0
- package/dist/fields/MetaDescription/MetaDescriptionComponent.js.map +1 -0
- package/dist/fields/MetaDescription/index.d.ts +12 -0
- package/dist/fields/MetaDescription/index.d.ts.map +1 -0
- package/dist/fields/MetaDescription/index.js +23 -0
- package/dist/fields/MetaDescription/index.js.map +1 -0
- package/dist/fields/MetaImage/MetaImageComponent.d.ts +8 -0
- package/dist/fields/MetaImage/MetaImageComponent.d.ts.map +1 -0
- package/dist/fields/MetaImage/MetaImageComponent.js +142 -0
- package/dist/fields/MetaImage/MetaImageComponent.js.map +1 -0
- package/dist/fields/MetaImage/index.d.ts +13 -0
- package/dist/fields/MetaImage/index.d.ts.map +1 -0
- package/dist/fields/MetaImage/index.js +26 -0
- package/dist/fields/MetaImage/index.js.map +1 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.d.ts +9 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.d.ts.map +1 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.js +140 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.js.map +1 -0
- package/dist/fields/MetaTitle/index.d.ts +12 -0
- package/dist/fields/MetaTitle/index.d.ts.map +1 -0
- package/dist/fields/MetaTitle/index.js +23 -0
- package/dist/fields/MetaTitle/index.js.map +1 -0
- package/dist/fields/Overview/OverviewComponent.d.ts +10 -0
- package/dist/fields/Overview/OverviewComponent.d.ts.map +1 -0
- package/dist/{ui/Overview.js → fields/Overview/OverviewComponent.js} +18 -12
- package/dist/fields/Overview/OverviewComponent.js.map +1 -0
- package/dist/fields/Overview/index.d.ts +26 -0
- package/dist/fields/Overview/index.d.ts.map +1 -0
- package/dist/fields/Overview/index.js +25 -0
- package/dist/fields/Overview/index.js.map +1 -0
- package/dist/fields/Preview/PreviewComponent.d.ts +10 -0
- package/dist/fields/Preview/PreviewComponent.d.ts.map +1 -0
- package/dist/fields/Preview/PreviewComponent.js +101 -0
- package/dist/fields/Preview/PreviewComponent.js.map +1 -0
- package/dist/fields/Preview/index.d.ts +24 -0
- package/dist/fields/Preview/index.d.ts.map +1 -0
- package/dist/fields/Preview/index.js +25 -0
- package/dist/fields/Preview/index.js.map +1 -0
- package/dist/fields/index.scss +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -36
- package/dist/index.js.map +1 -1
- package/dist/translations/index.d.ts +47 -0
- package/dist/translations/index.d.ts.map +1 -1
- package/dist/translations/index.js +44 -0
- package/dist/translations/index.js.map +1 -1
- package/dist/translations/ru.json +22 -0
- package/dist/translations/uk.json +22 -0
- package/dist/types.d.ts +14 -14
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/LengthIndicator.d.ts.map +1 -1
- package/dist/ui/LengthIndicator.js +62 -41
- package/dist/ui/LengthIndicator.js.map +1 -1
- package/dist/ui/Pill.js +7 -3
- package/dist/ui/Pill.js.map +1 -1
- package/package.json +52 -32
- package/dist/fields/MetaDescription.d.ts +0 -9
- package/dist/fields/MetaDescription.d.ts.map +0 -1
- package/dist/fields/MetaDescription.js +0 -117
- package/dist/fields/MetaDescription.js.map +0 -1
- package/dist/fields/MetaImage.d.ts +0 -8
- package/dist/fields/MetaImage.d.ts.map +0 -1
- package/dist/fields/MetaImage.js +0 -121
- package/dist/fields/MetaImage.js.map +0 -1
- package/dist/fields/MetaTitle.d.ts +0 -9
- package/dist/fields/MetaTitle.d.ts.map +0 -1
- package/dist/fields/MetaTitle.js +0 -118
- package/dist/fields/MetaTitle.js.map +0 -1
- package/dist/ui/Overview.d.ts +0 -3
- package/dist/ui/Overview.d.ts.map +0 -1
- package/dist/ui/Overview.js.map +0 -1
- package/dist/ui/Preview.d.ts +0 -8
- package/dist/ui/Preview.d.ts.map +0 -1
- package/dist/ui/Preview.js +0 -79
- package/dist/ui/Preview.js.map +0 -1
- package/src/index.tsx +0 -293
- package/types.d.ts +0 -1
- package/types.js +0 -1
package/dist/fields/MetaTitle.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { TextInput } from '@payloadcms/ui/fields/Text';
|
|
3
|
-
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel';
|
|
4
|
-
import { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider';
|
|
5
|
-
import { useAllFormFields } from '@payloadcms/ui/forms/Form';
|
|
6
|
-
import { useField } from '@payloadcms/ui/forms/useField';
|
|
7
|
-
import { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo';
|
|
8
|
-
import { useLocale } from '@payloadcms/ui/providers/Locale';
|
|
9
|
-
import { useTranslation } from '@payloadcms/ui/providers/Translation';
|
|
10
|
-
import React, { useCallback } from 'react';
|
|
11
|
-
import { defaults } from '../defaults.js';
|
|
12
|
-
import { LengthIndicator } from '../ui/LengthIndicator.js';
|
|
13
|
-
import './index.scss';
|
|
14
|
-
const { maxLength, minLength } = defaults.title;
|
|
15
|
-
export const MetaTitle = (props)=>{
|
|
16
|
-
const { CustomLabel, hasGenerateTitleFn, labelProps, path, required } = props || {};
|
|
17
|
-
const { path: pathFromContext } = useFieldProps();
|
|
18
|
-
const { t } = useTranslation();
|
|
19
|
-
const field = useField({
|
|
20
|
-
path
|
|
21
|
-
});
|
|
22
|
-
const locale = useLocale();
|
|
23
|
-
const [fields] = useAllFormFields();
|
|
24
|
-
const docInfo = useDocumentInfo();
|
|
25
|
-
const { errorMessage, setValue, showError, value } = field;
|
|
26
|
-
const regenerateTitle = useCallback(async ()=>{
|
|
27
|
-
if (!hasGenerateTitleFn) return;
|
|
28
|
-
const genTitleResponse = await fetch('/api/plugin-seo/generate-title', {
|
|
29
|
-
body: JSON.stringify({
|
|
30
|
-
...docInfo,
|
|
31
|
-
doc: {
|
|
32
|
-
...fields
|
|
33
|
-
},
|
|
34
|
-
locale: typeof locale === 'object' ? locale?.code : locale
|
|
35
|
-
}),
|
|
36
|
-
credentials: 'include',
|
|
37
|
-
headers: {
|
|
38
|
-
'Content-Type': 'application/json'
|
|
39
|
-
},
|
|
40
|
-
method: 'POST'
|
|
41
|
-
});
|
|
42
|
-
const { result: generatedTitle } = await genTitleResponse.json();
|
|
43
|
-
setValue(generatedTitle || '');
|
|
44
|
-
}, [
|
|
45
|
-
fields,
|
|
46
|
-
setValue,
|
|
47
|
-
hasGenerateTitleFn,
|
|
48
|
-
locale,
|
|
49
|
-
docInfo
|
|
50
|
-
]);
|
|
51
|
-
return /*#__PURE__*/ React.createElement("div", {
|
|
52
|
-
style: {
|
|
53
|
-
marginBottom: '20px'
|
|
54
|
-
}
|
|
55
|
-
}, /*#__PURE__*/ React.createElement("div", {
|
|
56
|
-
style: {
|
|
57
|
-
marginBottom: '5px',
|
|
58
|
-
position: 'relative'
|
|
59
|
-
}
|
|
60
|
-
}, /*#__PURE__*/ React.createElement("div", {
|
|
61
|
-
className: "plugin-seo__field"
|
|
62
|
-
}, CustomLabel !== undefined ? CustomLabel : /*#__PURE__*/ React.createElement(FieldLabel, labelProps || {}), required && /*#__PURE__*/ React.createElement("span", {
|
|
63
|
-
style: {
|
|
64
|
-
color: 'var(--theme-error-500)',
|
|
65
|
-
marginLeft: '5px'
|
|
66
|
-
}
|
|
67
|
-
}, "*"), hasGenerateTitleFn && /*#__PURE__*/ React.createElement(React.Fragment, null, " — ", /*#__PURE__*/ React.createElement("button", {
|
|
68
|
-
onClick: regenerateTitle,
|
|
69
|
-
style: {
|
|
70
|
-
background: 'none',
|
|
71
|
-
backgroundColor: 'transparent',
|
|
72
|
-
border: 'none',
|
|
73
|
-
color: 'currentcolor',
|
|
74
|
-
cursor: 'pointer',
|
|
75
|
-
padding: 0,
|
|
76
|
-
textDecoration: 'underline'
|
|
77
|
-
},
|
|
78
|
-
type: "button"
|
|
79
|
-
}, t('plugin-seo:autoGenerate')))), /*#__PURE__*/ React.createElement("div", {
|
|
80
|
-
style: {
|
|
81
|
-
color: '#9A9A9A'
|
|
82
|
-
}
|
|
83
|
-
}, t('plugin-seo:lengthTipTitle', {
|
|
84
|
-
maxLength,
|
|
85
|
-
minLength
|
|
86
|
-
}), /*#__PURE__*/ React.createElement("a", {
|
|
87
|
-
href: "https://developers.google.com/search/docs/advanced/appearance/title-link#page-titles",
|
|
88
|
-
rel: "noopener noreferrer",
|
|
89
|
-
target: "_blank"
|
|
90
|
-
}, t('plugin-seo:bestPractices')), ".")), /*#__PURE__*/ React.createElement("div", {
|
|
91
|
-
style: {
|
|
92
|
-
marginBottom: '10px',
|
|
93
|
-
position: 'relative'
|
|
94
|
-
}
|
|
95
|
-
}, /*#__PURE__*/ React.createElement(TextInput, {
|
|
96
|
-
CustomError: errorMessage,
|
|
97
|
-
onChange: setValue,
|
|
98
|
-
path: pathFromContext,
|
|
99
|
-
required: required,
|
|
100
|
-
showError: showError,
|
|
101
|
-
style: {
|
|
102
|
-
marginBottom: 0
|
|
103
|
-
},
|
|
104
|
-
value: value
|
|
105
|
-
})), /*#__PURE__*/ React.createElement("div", {
|
|
106
|
-
style: {
|
|
107
|
-
alignItems: 'center',
|
|
108
|
-
display: 'flex',
|
|
109
|
-
width: '100%'
|
|
110
|
-
}
|
|
111
|
-
}, /*#__PURE__*/ React.createElement(LengthIndicator, {
|
|
112
|
-
maxLength: maxLength,
|
|
113
|
-
minLength: minLength,
|
|
114
|
-
text: value
|
|
115
|
-
})));
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
//# sourceMappingURL=MetaTitle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/MetaTitle.tsx"],"sourcesContent":["'use client'\n\nimport type { FormFieldBase } from '@payloadcms/ui/fields/shared'\nimport type { Options } from '@payloadcms/ui/forms/useField'\nimport type { FieldType } from '@payloadcms/ui/forms/useField'\n\nimport { TextInput } from '@payloadcms/ui/fields/Text'\nimport { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'\nimport { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'\nimport { useAllFormFields } from '@payloadcms/ui/forms/Form'\nimport { useField } from '@payloadcms/ui/forms/useField'\nimport { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo'\nimport { useLocale } from '@payloadcms/ui/providers/Locale'\nimport { useTranslation } from '@payloadcms/ui/providers/Translation'\nimport React, { useCallback } from 'react'\n\nimport type { GenerateTitle } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { LengthIndicator } from '../ui/LengthIndicator.js'\nimport './index.scss'\n\nconst { maxLength, minLength } = defaults.title\n\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\ntype MetaTitleProps = FormFieldBase & {\n hasGenerateTitleFn: boolean\n}\n\nexport const MetaTitle: React.FC<MetaTitleProps> = (props) => {\n const { CustomLabel, hasGenerateTitleFn, labelProps, path, required } = props || {}\n const { path: pathFromContext } = useFieldProps()\n\n const { t } = useTranslation()\n\n const field: FieldType<string> = useField({\n path,\n } as Options)\n\n const locale = useLocale()\n const [fields] = useAllFormFields()\n const docInfo = useDocumentInfo()\n\n const { errorMessage, setValue, showError, value } = field\n\n const regenerateTitle = useCallback(async () => {\n if (!hasGenerateTitleFn) return\n\n const genTitleResponse = await fetch('/api/plugin-seo/generate-title', {\n body: JSON.stringify({\n ...docInfo,\n doc: { ...fields },\n locale: typeof locale === 'object' ? locale?.code : locale,\n } satisfies Parameters<GenerateTitle>[0]),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedTitle } = await genTitleResponse.json()\n\n setValue(generatedTitle || '')\n }, [fields, setValue, hasGenerateTitleFn, locale, docInfo])\n\n return (\n <div\n style={{\n marginBottom: '20px',\n }}\n >\n <div\n style={{\n marginBottom: '5px',\n position: 'relative',\n }}\n >\n <div className=\"plugin-seo__field\">\n {CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}\n {required && (\n <span\n style={{\n color: 'var(--theme-error-500)',\n marginLeft: '5px',\n }}\n >\n *\n </span>\n )}\n {hasGenerateTitleFn && (\n <React.Fragment>\n — \n <button\n onClick={regenerateTitle}\n style={{\n background: 'none',\n backgroundColor: 'transparent',\n border: 'none',\n color: 'currentcolor',\n cursor: 'pointer',\n padding: 0,\n textDecoration: 'underline',\n }}\n type=\"button\"\n >\n {t('plugin-seo:autoGenerate')}\n </button>\n </React.Fragment>\n )}\n </div>\n <div\n style={{\n color: '#9A9A9A',\n }}\n >\n {t('plugin-seo:lengthTipTitle', { maxLength, minLength })}\n <a\n href=\"https://developers.google.com/search/docs/advanced/appearance/title-link#page-titles\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n {t('plugin-seo:bestPractices')}\n </a>\n .\n </div>\n </div>\n <div\n style={{\n marginBottom: '10px',\n position: 'relative',\n }}\n >\n <TextInput\n CustomError={errorMessage}\n onChange={setValue}\n path={pathFromContext}\n required={required}\n showError={showError}\n style={{\n marginBottom: 0,\n }}\n value={value}\n />\n </div>\n <div\n style={{\n alignItems: 'center',\n display: 'flex',\n width: '100%',\n }}\n >\n <LengthIndicator maxLength={maxLength} minLength={minLength} text={value} />\n </div>\n </div>\n )\n}\n"],"names":["TextInput","FieldLabel","useFieldProps","useAllFormFields","useField","useDocumentInfo","useLocale","useTranslation","React","useCallback","defaults","LengthIndicator","maxLength","minLength","title","MetaTitle","props","CustomLabel","hasGenerateTitleFn","labelProps","path","required","pathFromContext","t","field","locale","fields","docInfo","errorMessage","setValue","showError","value","regenerateTitle","genTitleResponse","fetch","body","JSON","stringify","doc","code","credentials","headers","method","result","generatedTitle","json","div","style","marginBottom","position","className","undefined","span","color","marginLeft","Fragment","button","onClick","background","backgroundColor","border","cursor","padding","textDecoration","type","a","href","rel","target","CustomError","onChange","alignItems","display","width","text"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;AAMA,SAASA,SAAS,QAAQ,6BAA4B;AACtD,SAASC,UAAU,QAAQ,kCAAiC;AAC5D,SAASC,aAAa,QAAQ,0CAAyC;AACvE,SAASC,gBAAgB,QAAQ,4BAA2B;AAC5D,SAASC,QAAQ,QAAQ,gCAA+B;AACxD,SAASC,eAAe,QAAQ,wCAAuC;AACvE,SAASC,SAAS,QAAQ,kCAAiC;AAC3D,SAASC,cAAc,QAAQ,uCAAsC;AACrE,OAAOC,SAASC,WAAW,QAAQ,QAAO;AAI1C,SAASC,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,eAAe,QAAQ,2BAA0B;AAC1D,OAAO,eAAc;AAErB,MAAM,EAAEC,SAAS,EAAEC,SAAS,EAAE,GAAGH,SAASI,KAAK;AAO/C,OAAO,MAAMC,YAAsC,CAACC;IAClD,MAAM,EAAEC,WAAW,EAAEC,kBAAkB,EAAEC,UAAU,EAAEC,IAAI,EAAEC,QAAQ,EAAE,GAAGL,SAAS,CAAC;IAClF,MAAM,EAAEI,MAAME,eAAe,EAAE,GAAGpB;IAElC,MAAM,EAAEqB,CAAC,EAAE,GAAGhB;IAEd,MAAMiB,QAA2BpB,SAAS;QACxCgB;IACF;IAEA,MAAMK,SAASnB;IACf,MAAM,CAACoB,OAAO,GAAGvB;IACjB,MAAMwB,UAAUtB;IAEhB,MAAM,EAAEuB,YAAY,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAGP;IAErD,MAAMQ,kBAAkBvB,YAAY;QAClC,IAAI,CAACS,oBAAoB;QAEzB,MAAMe,mBAAmB,MAAMC,MAAM,kCAAkC;YACrEC,MAAMC,KAAKC,SAAS,CAAC;gBACnB,GAAGV,OAAO;gBACVW,KAAK;oBAAE,GAAGZ,MAAM;gBAAC;gBACjBD,QAAQ,OAAOA,WAAW,WAAWA,QAAQc,OAAOd;YACtD;YACAe,aAAa;YACbC,SAAS;gBACP,gBAAgB;YAClB;YACAC,QAAQ;QACV;QAEA,MAAM,EAAEC,QAAQC,cAAc,EAAE,GAAG,MAAMX,iBAAiBY,IAAI;QAE9DhB,SAASe,kBAAkB;IAC7B,GAAG;QAAClB;QAAQG;QAAUX;QAAoBO;QAAQE;KAAQ;IAE1D,qBACE,oBAACmB;QACCC,OAAO;YACLC,cAAc;QAChB;qBAEA,oBAACF;QACCC,OAAO;YACLC,cAAc;YACdC,UAAU;QACZ;qBAEA,oBAACH;QAAII,WAAU;OACZjC,gBAAgBkC,YAAYlC,4BAAc,oBAAChB,YAAgBkB,cAAc,CAAC,IAC1EE,0BACC,oBAAC+B;QACCL,OAAO;YACLM,OAAO;YACPC,YAAY;QACd;OACD,MAIFpC,oCACC,oBAACV,MAAM+C,QAAQ,QAAC,uBAEd,oBAACC;QACCC,SAASzB;QACTe,OAAO;YACLW,YAAY;YACZC,iBAAiB;YACjBC,QAAQ;YACRP,OAAO;YACPQ,QAAQ;YACRC,SAAS;YACTC,gBAAgB;QAClB;QACAC,MAAK;OAEJzC,EAAE,6CAKX,oBAACuB;QACCC,OAAO;YACLM,OAAO;QACT;OAEC9B,EAAE,6BAA6B;QAAEX;QAAWC;IAAU,kBACvD,oBAACoD;QACCC,MAAK;QACLC,KAAI;QACJC,QAAO;OAEN7C,EAAE,8BACD,qBAIR,oBAACuB;QACCC,OAAO;YACLC,cAAc;YACdC,UAAU;QACZ;qBAEA,oBAACjD;QACCqE,aAAazC;QACb0C,UAAUzC;QACVT,MAAME;QACND,UAAUA;QACVS,WAAWA;QACXiB,OAAO;YACLC,cAAc;QAChB;QACAjB,OAAOA;uBAGX,oBAACe;QACCC,OAAO;YACLwB,YAAY;YACZC,SAAS;YACTC,OAAO;QACT;qBAEA,oBAAC9D;QAAgBC,WAAWA;QAAWC,WAAWA;QAAW6D,MAAM3C;;AAI3E,EAAC"}
|
package/dist/ui/Overview.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Overview.d.ts","sourceRoot":"","sources":["../../src/ui/Overview.tsx"],"names":[],"mappings":"AAMA,OAAO,KAA2C,MAAM,OAAO,CAAA;AAS/D,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAoD5B,CAAA"}
|
package/dist/ui/Overview.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/Overview.tsx"],"sourcesContent":["'use client'\n\nimport type { FormField } from 'payload/types'\n\nimport { useAllFormFields, useForm } from '@payloadcms/ui/forms/Form'\nimport { useTranslation } from '@payloadcms/ui/providers/Translation'\nimport React, { useCallback, useEffect, useState } from 'react'\n\nimport { defaults } from '../defaults.js'\n\nconst {\n description: { maxLength: maxDesc, minLength: minDesc },\n title: { maxLength: maxTitle, minLength: minTitle },\n} = defaults\n\nexport const Overview: React.FC = () => {\n const {\n // dispatchFields,\n getFields,\n } = useForm()\n\n const [\n {\n 'meta.description': { value: metaDesc } = {} as FormField,\n 'meta.image': { value: metaImage } = {} as FormField,\n 'meta.title': { value: metaTitle } = {} as FormField,\n },\n ] = useAllFormFields()\n const { t } = useTranslation()\n\n const [titleIsValid, setTitleIsValid] = useState<boolean | undefined>()\n const [descIsValid, setDescIsValid] = useState<boolean | undefined>()\n const [imageIsValid, setImageIsValid] = useState<boolean | undefined>()\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const resetAll = useCallback(() => {\n const fields = getFields()\n const fieldsWithoutMeta = fields\n fieldsWithoutMeta['meta.title'].value = ''\n fieldsWithoutMeta['meta.description'].value = ''\n fieldsWithoutMeta['meta.image'].value = ''\n // dispatchFields(fieldsWithoutMeta);\n }, [getFields])\n\n useEffect(() => {\n if (typeof metaTitle === 'string')\n setTitleIsValid(metaTitle.length >= minTitle && metaTitle.length <= maxTitle)\n if (typeof metaDesc === 'string')\n setDescIsValid(metaDesc.length >= minDesc && metaDesc.length <= maxDesc)\n setImageIsValid(Boolean(metaImage))\n }, [metaTitle, metaDesc, metaImage])\n\n const testResults = [titleIsValid, descIsValid, imageIsValid]\n\n const numberOfPasses = testResults.filter(Boolean).length\n\n return (\n <div\n style={{\n marginBottom: '20px',\n }}\n >\n <div>\n {t('plugin-seo:checksPassing', { current: numberOfPasses, max: testResults.length })}\n </div>\n </div>\n )\n}\n"],"names":["useAllFormFields","useForm","useTranslation","React","useCallback","useEffect","useState","defaults","description","maxLength","maxDesc","minLength","minDesc","title","maxTitle","minTitle","Overview","getFields","value","metaDesc","metaImage","metaTitle","t","titleIsValid","setTitleIsValid","descIsValid","setDescIsValid","imageIsValid","setImageIsValid","resetAll","fields","fieldsWithoutMeta","length","Boolean","testResults","numberOfPasses","filter","div","style","marginBottom","current","max"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;AAIA,SAASA,gBAAgB,EAAEC,OAAO,QAAQ,4BAA2B;AACrE,SAASC,cAAc,QAAQ,uCAAsC;AACrE,OAAOC,SAASC,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAE/D,SAASC,QAAQ,QAAQ,iBAAgB;AAEzC,MAAM,EACJC,aAAa,EAAEC,WAAWC,OAAO,EAAEC,WAAWC,OAAO,EAAE,EACvDC,OAAO,EAAEJ,WAAWK,QAAQ,EAAEH,WAAWI,QAAQ,EAAE,EACpD,GAAGR;AAEJ,OAAO,MAAMS,WAAqB;IAChC,MAAM,EACJ,mBAAmB;IACnBC,SAAS,EACV,GAAGhB;IAEJ,MAAM,CACJ,EACE,oBAAoB,EAAEiB,OAAOC,QAAQ,EAAE,GAAG,CAAC,CAAc,EACzD,cAAc,EAAED,OAAOE,SAAS,EAAE,GAAG,CAAC,CAAc,EACpD,cAAc,EAAEF,OAAOG,SAAS,EAAE,GAAG,CAAC,CAAc,EACrD,CACF,GAAGrB;IACJ,MAAM,EAAEsB,CAAC,EAAE,GAAGpB;IAEd,MAAM,CAACqB,cAAcC,gBAAgB,GAAGlB;IACxC,MAAM,CAACmB,aAAaC,eAAe,GAAGpB;IACtC,MAAM,CAACqB,cAAcC,gBAAgB,GAAGtB;IAExC,6DAA6D;IAC7D,MAAMuB,WAAWzB,YAAY;QAC3B,MAAM0B,SAASb;QACf,MAAMc,oBAAoBD;QAC1BC,iBAAiB,CAAC,aAAa,CAACb,KAAK,GAAG;QACxCa,iBAAiB,CAAC,mBAAmB,CAACb,KAAK,GAAG;QAC9Ca,iBAAiB,CAAC,aAAa,CAACb,KAAK,GAAG;IACxC,qCAAqC;IACvC,GAAG;QAACD;KAAU;IAEdZ,UAAU;QACR,IAAI,OAAOgB,cAAc,UACvBG,gBAAgBH,UAAUW,MAAM,IAAIjB,YAAYM,UAAUW,MAAM,IAAIlB;QACtE,IAAI,OAAOK,aAAa,UACtBO,eAAeP,SAASa,MAAM,IAAIpB,WAAWO,SAASa,MAAM,IAAItB;QAClEkB,gBAAgBK,QAAQb;IAC1B,GAAG;QAACC;QAAWF;QAAUC;KAAU;IAEnC,MAAMc,cAAc;QAACX;QAAcE;QAAaE;KAAa;IAE7D,MAAMQ,iBAAiBD,YAAYE,MAAM,CAACH,SAASD,MAAM;IAEzD,qBACE,oBAACK;QACCC,OAAO;YACLC,cAAc;QAChB;qBAEA,oBAACF,aACEf,EAAE,4BAA4B;QAAEkB,SAASL;QAAgBM,KAAKP,YAAYF,MAAM;IAAC;AAI1F,EAAC"}
|
package/dist/ui/Preview.d.ts
DELETED
package/dist/ui/Preview.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Preview.d.ts","sourceRoot":"","sources":["../../src/ui/Preview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAa,OAAO,EAAE,MAAM,eAAe,CAAA;AAMvD,OAAO,KAA8B,MAAM,OAAO,CAAA;AAKlD,KAAK,YAAY,GAAG,OAAO,GAAG;IAC5B,gBAAgB,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CA+F1C,CAAA"}
|
package/dist/ui/Preview.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { useAllFormFields } from '@payloadcms/ui/forms/Form';
|
|
3
|
-
import { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo';
|
|
4
|
-
import { useLocale } from '@payloadcms/ui/providers/Locale';
|
|
5
|
-
import { useTranslation } from '@payloadcms/ui/providers/Translation';
|
|
6
|
-
import React, { useEffect, useState } from 'react';
|
|
7
|
-
export const Preview = ({ hasGenerateURLFn })=>{
|
|
8
|
-
const { t } = useTranslation();
|
|
9
|
-
const locale = useLocale();
|
|
10
|
-
const [fields] = useAllFormFields();
|
|
11
|
-
const docInfo = useDocumentInfo();
|
|
12
|
-
const { 'meta.description': { value: metaDescription } = {}, 'meta.title': { value: metaTitle } = {} } = fields;
|
|
13
|
-
const [href, setHref] = useState();
|
|
14
|
-
useEffect(()=>{
|
|
15
|
-
const getHref = async ()=>{
|
|
16
|
-
const genURLResponse = await fetch('/api/plugin-seo/generate-url', {
|
|
17
|
-
body: JSON.stringify({
|
|
18
|
-
...docInfo,
|
|
19
|
-
doc: {
|
|
20
|
-
...fields
|
|
21
|
-
},
|
|
22
|
-
locale: typeof locale === 'object' ? locale?.code : locale
|
|
23
|
-
}),
|
|
24
|
-
credentials: 'include',
|
|
25
|
-
headers: {
|
|
26
|
-
'Content-Type': 'application/json'
|
|
27
|
-
},
|
|
28
|
-
method: 'POST'
|
|
29
|
-
});
|
|
30
|
-
const { result: newHref } = await genURLResponse.json();
|
|
31
|
-
setHref(newHref);
|
|
32
|
-
};
|
|
33
|
-
if (hasGenerateURLFn && !href) {
|
|
34
|
-
void getHref();
|
|
35
|
-
}
|
|
36
|
-
}, [
|
|
37
|
-
fields,
|
|
38
|
-
href,
|
|
39
|
-
locale,
|
|
40
|
-
docInfo,
|
|
41
|
-
hasGenerateURLFn
|
|
42
|
-
]);
|
|
43
|
-
return /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement("div", null, t('plugin-seo:preview')), /*#__PURE__*/ React.createElement("div", {
|
|
44
|
-
style: {
|
|
45
|
-
color: '#9A9A9A',
|
|
46
|
-
marginBottom: '5px'
|
|
47
|
-
}
|
|
48
|
-
}, t('plugin-seo:previewDescription')), /*#__PURE__*/ React.createElement("div", {
|
|
49
|
-
style: {
|
|
50
|
-
background: 'var(--theme-elevation-50)',
|
|
51
|
-
borderRadius: '5px',
|
|
52
|
-
boxShadow: '0px 0px 10px rgba(0, 0, 0, 0.1)',
|
|
53
|
-
maxWidth: '600px',
|
|
54
|
-
padding: '20px',
|
|
55
|
-
pointerEvents: 'none',
|
|
56
|
-
width: '100%'
|
|
57
|
-
}
|
|
58
|
-
}, /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement("a", {
|
|
59
|
-
href: href,
|
|
60
|
-
style: {
|
|
61
|
-
textDecoration: 'none'
|
|
62
|
-
}
|
|
63
|
-
}, href || 'https://...')), /*#__PURE__*/ React.createElement("h4", {
|
|
64
|
-
style: {
|
|
65
|
-
margin: 0
|
|
66
|
-
}
|
|
67
|
-
}, /*#__PURE__*/ React.createElement("a", {
|
|
68
|
-
href: "/",
|
|
69
|
-
style: {
|
|
70
|
-
textDecoration: 'none'
|
|
71
|
-
}
|
|
72
|
-
}, metaTitle)), /*#__PURE__*/ React.createElement("p", {
|
|
73
|
-
style: {
|
|
74
|
-
margin: 0
|
|
75
|
-
}
|
|
76
|
-
}, metaDescription)));
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
//# sourceMappingURL=Preview.js.map
|
package/dist/ui/Preview.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/Preview.tsx"],"sourcesContent":["'use client'\n\nimport type { FormField, UIField } from 'payload/types'\n\nimport { useAllFormFields } from '@payloadcms/ui/forms/Form'\nimport { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo'\nimport { useLocale } from '@payloadcms/ui/providers/Locale'\nimport { useTranslation } from '@payloadcms/ui/providers/Translation'\nimport React, { useEffect, useState } from 'react'\n\nimport type { GenerateURL } from '../types.js'\n\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\ntype PreviewProps = UIField & {\n hasGenerateURLFn: boolean\n}\n\nexport const Preview: React.FC<PreviewProps> = ({ hasGenerateURLFn }) => {\n const { t } = useTranslation()\n\n const locale = useLocale()\n const [fields] = useAllFormFields()\n const docInfo = useDocumentInfo()\n\n const {\n 'meta.description': { value: metaDescription } = {} as FormField,\n 'meta.title': { value: metaTitle } = {} as FormField,\n } = fields\n\n const [href, setHref] = useState<string>()\n\n useEffect(() => {\n const getHref = async () => {\n const genURLResponse = await fetch('/api/plugin-seo/generate-url', {\n body: JSON.stringify({\n ...docInfo,\n doc: { ...fields },\n locale: typeof locale === 'object' ? locale?.code : locale,\n } satisfies Parameters<GenerateURL>[0]),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: newHref } = await genURLResponse.json()\n\n setHref(newHref)\n }\n\n if (hasGenerateURLFn && !href) {\n void getHref()\n }\n }, [fields, href, locale, docInfo, hasGenerateURLFn])\n\n return (\n <div>\n <div>{t('plugin-seo:preview')}</div>\n <div\n style={{\n color: '#9A9A9A',\n marginBottom: '5px',\n }}\n >\n {t('plugin-seo:previewDescription')}\n </div>\n <div\n style={{\n background: 'var(--theme-elevation-50)',\n borderRadius: '5px',\n boxShadow: '0px 0px 10px rgba(0, 0, 0, 0.1)',\n maxWidth: '600px',\n padding: '20px',\n pointerEvents: 'none',\n width: '100%',\n }}\n >\n <div>\n <a\n href={href}\n style={{\n textDecoration: 'none',\n }}\n >\n {href || 'https://...'}\n </a>\n </div>\n <h4\n style={{\n margin: 0,\n }}\n >\n <a\n href=\"/\"\n style={{\n textDecoration: 'none',\n }}\n >\n {metaTitle as string}\n </a>\n </h4>\n <p\n style={{\n margin: 0,\n }}\n >\n {metaDescription as string}\n </p>\n </div>\n </div>\n )\n}\n"],"names":["useAllFormFields","useDocumentInfo","useLocale","useTranslation","React","useEffect","useState","Preview","hasGenerateURLFn","t","locale","fields","docInfo","value","metaDescription","metaTitle","href","setHref","getHref","genURLResponse","fetch","body","JSON","stringify","doc","code","credentials","headers","method","result","newHref","json","div","style","color","marginBottom","background","borderRadius","boxShadow","maxWidth","padding","pointerEvents","width","a","textDecoration","h4","margin","p"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;AAIA,SAASA,gBAAgB,QAAQ,4BAA2B;AAC5D,SAASC,eAAe,QAAQ,wCAAuC;AACvE,SAASC,SAAS,QAAQ,kCAAiC;AAC3D,SAASC,cAAc,QAAQ,uCAAsC;AACrE,OAAOC,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AASlD,OAAO,MAAMC,UAAkC,CAAC,EAAEC,gBAAgB,EAAE;IAClE,MAAM,EAAEC,CAAC,EAAE,GAAGN;IAEd,MAAMO,SAASR;IACf,MAAM,CAACS,OAAO,GAAGX;IACjB,MAAMY,UAAUX;IAEhB,MAAM,EACJ,oBAAoB,EAAEY,OAAOC,eAAe,EAAE,GAAG,CAAC,CAAc,EAChE,cAAc,EAAED,OAAOE,SAAS,EAAE,GAAG,CAAC,CAAc,EACrD,GAAGJ;IAEJ,MAAM,CAACK,MAAMC,QAAQ,GAAGX;IAExBD,UAAU;QACR,MAAMa,UAAU;YACd,MAAMC,iBAAiB,MAAMC,MAAM,gCAAgC;gBACjEC,MAAMC,KAAKC,SAAS,CAAC;oBACnB,GAAGX,OAAO;oBACVY,KAAK;wBAAE,GAAGb,MAAM;oBAAC;oBACjBD,QAAQ,OAAOA,WAAW,WAAWA,QAAQe,OAAOf;gBACtD;gBACAgB,aAAa;gBACbC,SAAS;oBACP,gBAAgB;gBAClB;gBACAC,QAAQ;YACV;YAEA,MAAM,EAAEC,QAAQC,OAAO,EAAE,GAAG,MAAMX,eAAeY,IAAI;YAErDd,QAAQa;QACV;QAEA,IAAItB,oBAAoB,CAACQ,MAAM;YAC7B,KAAKE;QACP;IACF,GAAG;QAACP;QAAQK;QAAMN;QAAQE;QAASJ;KAAiB;IAEpD,qBACE,oBAACwB,2BACC,oBAACA,aAAKvB,EAAE,sCACR,oBAACuB;QACCC,OAAO;YACLC,OAAO;YACPC,cAAc;QAChB;OAEC1B,EAAE,iDAEL,oBAACuB;QACCC,OAAO;YACLG,YAAY;YACZC,cAAc;YACdC,WAAW;YACXC,UAAU;YACVC,SAAS;YACTC,eAAe;YACfC,OAAO;QACT;qBAEA,oBAACV,2BACC,oBAACW;QACC3B,MAAMA;QACNiB,OAAO;YACLW,gBAAgB;QAClB;OAEC5B,QAAQ,+BAGb,oBAAC6B;QACCZ,OAAO;YACLa,QAAQ;QACV;qBAEA,oBAACH;QACC3B,MAAK;QACLiB,OAAO;YACLW,gBAAgB;QAClB;OAEC7B,2BAGL,oBAACgC;QACCd,OAAO;YACLa,QAAQ;QACV;OAEChC;AAKX,EAAC"}
|
package/src/index.tsx
DELETED
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
import type { Config } from 'payload/config'
|
|
2
|
-
import type { Field, GroupField, TabsField, TextField } from 'payload/types'
|
|
3
|
-
|
|
4
|
-
import { deepMerge } from 'payload/utilities'
|
|
5
|
-
import React from 'react'
|
|
6
|
-
|
|
7
|
-
import type {
|
|
8
|
-
GenerateDescription,
|
|
9
|
-
GenerateImage,
|
|
10
|
-
GenerateTitle,
|
|
11
|
-
GenerateURL,
|
|
12
|
-
PluginConfig,
|
|
13
|
-
} from './types.js'
|
|
14
|
-
|
|
15
|
-
import { MetaDescription } from './fields/MetaDescription.js'
|
|
16
|
-
import { MetaImage } from './fields/MetaImage.js'
|
|
17
|
-
import { MetaTitle } from './fields/MetaTitle.js'
|
|
18
|
-
import { translations } from './translations/index.js'
|
|
19
|
-
import { Overview } from './ui/Overview.js'
|
|
20
|
-
import { Preview } from './ui/Preview.js'
|
|
21
|
-
|
|
22
|
-
const seo =
|
|
23
|
-
(pluginConfig: PluginConfig) =>
|
|
24
|
-
(config: Config): Config => {
|
|
25
|
-
const seoFields: GroupField[] = [
|
|
26
|
-
{
|
|
27
|
-
name: 'meta',
|
|
28
|
-
type: 'group',
|
|
29
|
-
fields: [
|
|
30
|
-
{
|
|
31
|
-
name: 'overview',
|
|
32
|
-
type: 'ui',
|
|
33
|
-
admin: {
|
|
34
|
-
components: {
|
|
35
|
-
Field: Overview,
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
label: 'Overview',
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
name: 'title',
|
|
42
|
-
type: 'text',
|
|
43
|
-
admin: {
|
|
44
|
-
components: {
|
|
45
|
-
Field: (props) => (
|
|
46
|
-
<MetaTitle
|
|
47
|
-
{...props}
|
|
48
|
-
hasGenerateTitleFn={typeof pluginConfig.generateTitle === 'function'}
|
|
49
|
-
/>
|
|
50
|
-
),
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
localized: true,
|
|
54
|
-
...((pluginConfig?.fieldOverrides?.title as unknown as TextField) ?? {}),
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
name: 'description',
|
|
58
|
-
type: 'textarea',
|
|
59
|
-
admin: {
|
|
60
|
-
components: {
|
|
61
|
-
Field: (props) => (
|
|
62
|
-
<MetaDescription
|
|
63
|
-
{...props}
|
|
64
|
-
hasGenerateDescriptionFn={
|
|
65
|
-
typeof pluginConfig.generateDescription === 'function'
|
|
66
|
-
}
|
|
67
|
-
/>
|
|
68
|
-
),
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
localized: true,
|
|
72
|
-
...(pluginConfig?.fieldOverrides?.description ?? {}),
|
|
73
|
-
},
|
|
74
|
-
...(pluginConfig?.uploadsCollection
|
|
75
|
-
? [
|
|
76
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
77
|
-
{
|
|
78
|
-
name: 'image',
|
|
79
|
-
type: 'upload',
|
|
80
|
-
admin: {
|
|
81
|
-
components: {
|
|
82
|
-
Field: (props) => (
|
|
83
|
-
<MetaImage
|
|
84
|
-
{...props}
|
|
85
|
-
hasGenerateImageFn={typeof pluginConfig.generateImage === 'function'}
|
|
86
|
-
/>
|
|
87
|
-
),
|
|
88
|
-
},
|
|
89
|
-
description:
|
|
90
|
-
'Maximum upload file size: 12MB. Recommended file size for images is <500KB.',
|
|
91
|
-
},
|
|
92
|
-
label: 'Meta Image',
|
|
93
|
-
localized: true,
|
|
94
|
-
relationTo: pluginConfig?.uploadsCollection,
|
|
95
|
-
...(pluginConfig?.fieldOverrides?.image ?? {}),
|
|
96
|
-
} as Field,
|
|
97
|
-
]
|
|
98
|
-
: []),
|
|
99
|
-
...(pluginConfig?.fields || []),
|
|
100
|
-
{
|
|
101
|
-
name: 'preview',
|
|
102
|
-
type: 'ui',
|
|
103
|
-
admin: {
|
|
104
|
-
components: {
|
|
105
|
-
Field: (props) => (
|
|
106
|
-
<Preview
|
|
107
|
-
{...props}
|
|
108
|
-
hasGenerateURLFn={typeof pluginConfig.generateURL === 'function'}
|
|
109
|
-
/>
|
|
110
|
-
),
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
label: 'Preview',
|
|
114
|
-
},
|
|
115
|
-
],
|
|
116
|
-
interfaceName: pluginConfig.interfaceName,
|
|
117
|
-
label: 'SEO',
|
|
118
|
-
},
|
|
119
|
-
]
|
|
120
|
-
|
|
121
|
-
return {
|
|
122
|
-
...config,
|
|
123
|
-
collections:
|
|
124
|
-
config.collections?.map((collection) => {
|
|
125
|
-
const { slug } = collection
|
|
126
|
-
const isEnabled = pluginConfig?.collections?.includes(slug)
|
|
127
|
-
|
|
128
|
-
if (isEnabled) {
|
|
129
|
-
if (pluginConfig?.tabbedUI) {
|
|
130
|
-
// prevent issues with auth enabled collections having an email field that shouldn't be moved to the SEO tab
|
|
131
|
-
const emailField =
|
|
132
|
-
(collection.auth ||
|
|
133
|
-
!(typeof collection.auth === 'object' && collection.auth.disableLocalStrategy)) &&
|
|
134
|
-
collection.fields?.find((field) => 'name' in field && field.name === 'email')
|
|
135
|
-
const hasOnlyEmailField = collection.fields?.length === 1 && emailField
|
|
136
|
-
|
|
137
|
-
const seoTabs: TabsField[] = hasOnlyEmailField
|
|
138
|
-
? [
|
|
139
|
-
{
|
|
140
|
-
type: 'tabs',
|
|
141
|
-
tabs: [
|
|
142
|
-
{
|
|
143
|
-
fields: seoFields,
|
|
144
|
-
label: 'SEO',
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
},
|
|
148
|
-
]
|
|
149
|
-
: [
|
|
150
|
-
{
|
|
151
|
-
type: 'tabs',
|
|
152
|
-
tabs: [
|
|
153
|
-
// append a new tab onto the end of the tabs array, if there is one at the first index
|
|
154
|
-
// if needed, create a new `Content` tab in the first index for this collection's base fields
|
|
155
|
-
...(collection?.fields?.[0]?.type === 'tabs' &&
|
|
156
|
-
collection?.fields?.[0]?.tabs
|
|
157
|
-
? collection.fields[0].tabs
|
|
158
|
-
: [
|
|
159
|
-
{
|
|
160
|
-
fields: [
|
|
161
|
-
...(emailField
|
|
162
|
-
? collection.fields.filter(
|
|
163
|
-
(field) => 'name' in field && field.name !== 'email',
|
|
164
|
-
)
|
|
165
|
-
: collection.fields),
|
|
166
|
-
],
|
|
167
|
-
label: collection?.labels?.singular || 'Content',
|
|
168
|
-
},
|
|
169
|
-
]),
|
|
170
|
-
{
|
|
171
|
-
fields: seoFields,
|
|
172
|
-
label: 'SEO',
|
|
173
|
-
},
|
|
174
|
-
],
|
|
175
|
-
},
|
|
176
|
-
]
|
|
177
|
-
|
|
178
|
-
return {
|
|
179
|
-
...collection,
|
|
180
|
-
fields: [
|
|
181
|
-
...(emailField ? [emailField] : []),
|
|
182
|
-
...seoTabs,
|
|
183
|
-
...(collection?.fields?.[0]?.type === 'tabs' ? collection.fields.slice(1) : []),
|
|
184
|
-
],
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return {
|
|
189
|
-
...collection,
|
|
190
|
-
fields: [...(collection?.fields || []), ...seoFields],
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return collection
|
|
195
|
-
}) || [],
|
|
196
|
-
endpoints: [
|
|
197
|
-
{
|
|
198
|
-
handler: async (req) => {
|
|
199
|
-
const args: Parameters<GenerateTitle>[0] =
|
|
200
|
-
req.data as unknown as Parameters<GenerateTitle>[0]
|
|
201
|
-
const result = await pluginConfig.generateTitle(args)
|
|
202
|
-
return new Response(JSON.stringify({ result }), { status: 200 })
|
|
203
|
-
},
|
|
204
|
-
method: 'post',
|
|
205
|
-
path: '/plugin-seo/generate-title',
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
handler: async (req) => {
|
|
209
|
-
const args: Parameters<GenerateDescription>[0] =
|
|
210
|
-
req.data as unknown as Parameters<GenerateDescription>[0]
|
|
211
|
-
const result = await pluginConfig.generateDescription(args)
|
|
212
|
-
return new Response(JSON.stringify({ result }), { status: 200 })
|
|
213
|
-
},
|
|
214
|
-
method: 'post',
|
|
215
|
-
path: '/plugin-seo/generate-description',
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
handler: async (req) => {
|
|
219
|
-
const args: Parameters<GenerateURL>[0] =
|
|
220
|
-
req.data as unknown as Parameters<GenerateURL>[0]
|
|
221
|
-
const result = await pluginConfig.generateURL(args)
|
|
222
|
-
return new Response(JSON.stringify({ result }), { status: 200 })
|
|
223
|
-
},
|
|
224
|
-
method: 'post',
|
|
225
|
-
path: '/plugin-seo/generate-url',
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
handler: async (req) => {
|
|
229
|
-
const args: Parameters<GenerateImage>[0] =
|
|
230
|
-
req.data as unknown as Parameters<GenerateImage>[0]
|
|
231
|
-
const result = await pluginConfig.generateImage(args)
|
|
232
|
-
return new Response(result, { status: 200 })
|
|
233
|
-
},
|
|
234
|
-
method: 'post',
|
|
235
|
-
path: '/plugin-seo/generate-image',
|
|
236
|
-
},
|
|
237
|
-
],
|
|
238
|
-
globals:
|
|
239
|
-
config.globals?.map((global) => {
|
|
240
|
-
const { slug } = global
|
|
241
|
-
const isEnabled = pluginConfig?.globals?.includes(slug)
|
|
242
|
-
|
|
243
|
-
if (isEnabled) {
|
|
244
|
-
if (pluginConfig?.tabbedUI) {
|
|
245
|
-
const seoTabs: TabsField[] = [
|
|
246
|
-
{
|
|
247
|
-
type: 'tabs',
|
|
248
|
-
tabs: [
|
|
249
|
-
// append a new tab onto the end of the tabs array, if there is one at the first index
|
|
250
|
-
// if needed, create a new `Content` tab in the first index for this global's base fields
|
|
251
|
-
...(global?.fields?.[0].type === 'tabs' && global?.fields?.[0].tabs
|
|
252
|
-
? global.fields[0].tabs
|
|
253
|
-
: [
|
|
254
|
-
{
|
|
255
|
-
fields: [...(global?.fields || [])],
|
|
256
|
-
label: global?.label || 'Content',
|
|
257
|
-
},
|
|
258
|
-
]),
|
|
259
|
-
{
|
|
260
|
-
fields: seoFields,
|
|
261
|
-
label: 'SEO',
|
|
262
|
-
},
|
|
263
|
-
],
|
|
264
|
-
},
|
|
265
|
-
]
|
|
266
|
-
|
|
267
|
-
return {
|
|
268
|
-
...global,
|
|
269
|
-
fields: [
|
|
270
|
-
...seoTabs,
|
|
271
|
-
...(global?.fields?.[0].type === 'tabs' ? global.fields.slice(1) : []),
|
|
272
|
-
],
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return {
|
|
277
|
-
...global,
|
|
278
|
-
fields: [...(global?.fields || []), ...seoFields],
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return global
|
|
283
|
-
}) || [],
|
|
284
|
-
i18n: {
|
|
285
|
-
...config.i18n,
|
|
286
|
-
translations: {
|
|
287
|
-
...deepMerge(translations, config.i18n?.translations),
|
|
288
|
-
},
|
|
289
|
-
},
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
export { seo }
|
package/types.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './dist/types'
|
package/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./dist/types')
|