@payloadcms/plugin-seo 3.0.0-beta.9 → 3.0.0-canary.f6e77b8
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/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.d.ts.map +1 -1
- package/dist/fields/MetaDescription.js +6 -7
- package/dist/fields/MetaDescription.js.map +1 -1
- package/dist/fields/MetaImage.d.ts.map +1 -1
- package/dist/fields/MetaImage.js +6 -7
- package/dist/fields/MetaImage.js.map +1 -1
- package/dist/fields/MetaTitle.d.ts.map +1 -1
- package/dist/fields/MetaTitle.js +6 -7
- package/dist/fields/MetaTitle.js.map +1 -1
- package/dist/fields/index.scss +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -11
- package/dist/index.js.map +1 -1
- package/dist/translations/index.d.ts +22 -0
- package/dist/translations/index.d.ts.map +1 -1
- package/dist/translations/index.js +22 -0
- package/dist/translations/index.js.map +1 -1
- package/dist/translations/uk.json +22 -0
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +37 -28
- package/src/index.tsx +0 -296
- package/types.d.ts +0 -1
- package/types.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,WAAW,EACX,IAAI,EACJ,eAAe,GAChB,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type {\n GenerateDescription,\n GenerateImage,\n GenerateTitle,\n GenerateURL,\n Meta,\n SEOPluginConfig,\n} from '../types.js'\n"],"names":[],"rangeMappings":"","mappings":"AAAA,WAOoB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetaDescription.d.ts","sourceRoot":"","sources":["../../src/fields/MetaDescription.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAWjE,OAAO,KAAsB,MAAM,OAAO,CAAA;AAU1C,KAAK,oBAAoB,GAAG,aAAa,GAAG;IAC1C,wBAAwB,EAAE,OAAO,CAAA;IACjC,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"MetaDescription.d.ts","sourceRoot":"","sources":["../../src/fields/MetaDescription.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAWjE,OAAO,KAAsB,MAAM,OAAO,CAAA;AAU1C,KAAK,oBAAoB,GAAG,aAAa,GAAG;IAC1C,wBAAwB,EAAE,OAAO,CAAA;IACjC,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAoH1D,CAAA"}
|
|
@@ -12,7 +12,7 @@ import { defaults } from '../defaults.js';
|
|
|
12
12
|
import { LengthIndicator } from '../ui/LengthIndicator.js';
|
|
13
13
|
const { maxLength, minLength } = defaults.description;
|
|
14
14
|
export const MetaDescription = (props)=>{
|
|
15
|
-
const { CustomLabel, hasGenerateDescriptionFn, labelProps, path, required } = props;
|
|
15
|
+
const { CustomLabel, hasGenerateDescriptionFn, label, labelProps, path, required } = props;
|
|
16
16
|
const { path: pathFromContext } = useFieldProps();
|
|
17
17
|
const { t } = useTranslation();
|
|
18
18
|
const locale = useLocale();
|
|
@@ -58,12 +58,11 @@ export const MetaDescription = (props)=>{
|
|
|
58
58
|
}
|
|
59
59
|
}, /*#__PURE__*/ React.createElement("div", {
|
|
60
60
|
className: "plugin-seo__field"
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}, "*"), hasGenerateDescriptionFn && /*#__PURE__*/ React.createElement(React.Fragment, null, " — ", /*#__PURE__*/ React.createElement("button", {
|
|
61
|
+
}, /*#__PURE__*/ React.createElement(FieldLabel, {
|
|
62
|
+
CustomLabel: CustomLabel,
|
|
63
|
+
label: label,
|
|
64
|
+
...labelProps || {}
|
|
65
|
+
}), hasGenerateDescriptionFn && /*#__PURE__*/ React.createElement(React.Fragment, null, " — ", /*#__PURE__*/ React.createElement("button", {
|
|
67
66
|
onClick: regenerateDescription,
|
|
68
67
|
style: {
|
|
69
68
|
background: 'none',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/MetaDescription.tsx"],"sourcesContent":["'use client'\n\nimport type { FormFieldBase } from '@payloadcms/ui/fields/shared'\nimport type { FieldType, Options } from '@payloadcms/ui/forms/useField'\n\nimport { TextareaInput } from '@payloadcms/ui/fields/Textarea'\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 { GenerateDescription } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { LengthIndicator } from '../ui/LengthIndicator.js'\n\nconst { maxLength, minLength } = defaults.description\n\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\ntype MetaDescriptionProps = FormFieldBase & {\n hasGenerateDescriptionFn: boolean\n path: string\n}\n\nexport const MetaDescription: React.FC<MetaDescriptionProps> = (props) => {\n const { CustomLabel, hasGenerateDescriptionFn, labelProps, path, required } = props\n const { path: pathFromContext } = useFieldProps()\n\n const { t } = useTranslation()\n\n const locale = useLocale()\n const [fields] = useAllFormFields()\n const docInfo = useDocumentInfo()\n\n const field: FieldType<string> = useField({\n path,\n } as Options)\n\n const { errorMessage, setValue, showError, value } = field\n\n const regenerateDescription = useCallback(async () => {\n if (!hasGenerateDescriptionFn) return\n\n const genDescriptionResponse = await fetch('/api/plugin-seo/generate-description', {\n body: JSON.stringify({\n ...docInfo,\n doc: { ...fields },\n locale: typeof locale === 'object' ? locale?.code : locale,\n } satisfies Parameters<GenerateDescription>[0]),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedDescription } = await genDescriptionResponse.json()\n\n setValue(generatedDescription || '')\n }, [fields, setValue, hasGenerateDescriptionFn, 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
|
|
1
|
+
{"version":3,"sources":["../../src/fields/MetaDescription.tsx"],"sourcesContent":["'use client'\n\nimport type { FormFieldBase } from '@payloadcms/ui/fields/shared'\nimport type { FieldType, Options } from '@payloadcms/ui/forms/useField'\n\nimport { TextareaInput } from '@payloadcms/ui/fields/Textarea'\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 { GenerateDescription } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { LengthIndicator } from '../ui/LengthIndicator.js'\n\nconst { maxLength, minLength } = defaults.description\n\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\ntype MetaDescriptionProps = FormFieldBase & {\n hasGenerateDescriptionFn: boolean\n path: string\n}\n\nexport const MetaDescription: React.FC<MetaDescriptionProps> = (props) => {\n const { CustomLabel, hasGenerateDescriptionFn, label, labelProps, path, required } = props\n const { path: pathFromContext } = useFieldProps()\n\n const { t } = useTranslation()\n\n const locale = useLocale()\n const [fields] = useAllFormFields()\n const docInfo = useDocumentInfo()\n\n const field: FieldType<string> = useField({\n path,\n } as Options)\n\n const { errorMessage, setValue, showError, value } = field\n\n const regenerateDescription = useCallback(async () => {\n if (!hasGenerateDescriptionFn) return\n\n const genDescriptionResponse = await fetch('/api/plugin-seo/generate-description', {\n body: JSON.stringify({\n ...docInfo,\n doc: { ...fields },\n locale: typeof locale === 'object' ? locale?.code : locale,\n } satisfies Parameters<GenerateDescription>[0]),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedDescription } = await genDescriptionResponse.json()\n\n setValue(generatedDescription || '')\n }, [fields, setValue, hasGenerateDescriptionFn, 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 <FieldLabel CustomLabel={CustomLabel} label={label} {...(labelProps || {})} />\n {hasGenerateDescriptionFn && (\n <React.Fragment>\n — \n <button\n onClick={regenerateDescription}\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:lengthTipDescription', { maxLength, minLength })}\n <a\n href=\"https://developers.google.com/search/docs/advanced/appearance/snippet#meta-descriptions\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n {t('plugin-seo:bestPractices')}\n </a>\n </div>\n </div>\n <div\n style={{\n marginBottom: '10px',\n position: 'relative',\n }}\n >\n <TextareaInput\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":["TextareaInput","FieldLabel","useFieldProps","useAllFormFields","useField","useDocumentInfo","useLocale","useTranslation","React","useCallback","defaults","LengthIndicator","maxLength","minLength","description","MetaDescription","props","CustomLabel","hasGenerateDescriptionFn","label","labelProps","path","required","pathFromContext","t","locale","fields","docInfo","field","errorMessage","setValue","showError","value","regenerateDescription","genDescriptionResponse","fetch","body","JSON","stringify","doc","code","credentials","headers","method","result","generatedDescription","json","div","style","marginBottom","position","className","Fragment","button","onClick","background","backgroundColor","border","color","cursor","padding","textDecoration","type","a","href","rel","target","CustomError","onChange","alignItems","display","width","text"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;AAKA,SAASA,aAAa,QAAQ,iCAAgC;AAC9D,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;AAE1D,MAAM,EAAEC,SAAS,EAAEC,SAAS,EAAE,GAAGH,SAASI,WAAW;AAQrD,OAAO,MAAMC,kBAAkD,CAACC;IAC9D,MAAM,EAAEC,WAAW,EAAEC,wBAAwB,EAAEC,KAAK,EAAEC,UAAU,EAAEC,IAAI,EAAEC,QAAQ,EAAE,GAAGN;IACrF,MAAM,EAAEK,MAAME,eAAe,EAAE,GAAGrB;IAElC,MAAM,EAAEsB,CAAC,EAAE,GAAGjB;IAEd,MAAMkB,SAASnB;IACf,MAAM,CAACoB,OAAO,GAAGvB;IACjB,MAAMwB,UAAUtB;IAEhB,MAAMuB,QAA2BxB,SAAS;QACxCiB;IACF;IAEA,MAAM,EAAEQ,YAAY,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAGJ;IAErD,MAAMK,wBAAwBxB,YAAY;QACxC,IAAI,CAACS,0BAA0B;QAE/B,MAAMgB,yBAAyB,MAAMC,MAAM,wCAAwC;YACjFC,MAAMC,KAAKC,SAAS,CAAC;gBACnB,GAAGX,OAAO;gBACVY,KAAK;oBAAE,GAAGb,MAAM;gBAAC;gBACjBD,QAAQ,OAAOA,WAAW,WAAWA,QAAQe,OAAOf;YACtD;YACAgB,aAAa;YACbC,SAAS;gBACP,gBAAgB;YAClB;YACAC,QAAQ;QACV;QAEA,MAAM,EAAEC,QAAQC,oBAAoB,EAAE,GAAG,MAAMX,uBAAuBY,IAAI;QAE1EhB,SAASe,wBAAwB;IACnC,GAAG;QAACnB;QAAQI;QAAUZ;QAA0BO;QAAQE;KAAQ;IAEhE,qBACE,oBAACoB;QACCC,OAAO;YACLC,cAAc;QAChB;qBAEA,oBAACF;QACCC,OAAO;YACLC,cAAc;YACdC,UAAU;QACZ;qBAEA,oBAACH;QAAII,WAAU;qBACb,oBAAClD;QAAWgB,aAAaA;QAAaE,OAAOA;QAAQ,GAAIC,cAAc,CAAC,CAAC;QACxEF,0CACC,oBAACV,MAAM4C,QAAQ,QAAC,uBAEd,oBAACC;QACCC,SAASrB;QACTe,OAAO;YACLO,YAAY;YACZC,iBAAiB;YACjBC,QAAQ;YACRC,OAAO;YACPC,QAAQ;YACRC,SAAS;YACTC,gBAAgB;QAClB;QACAC,MAAK;OAEJtC,EAAE,6CAKX,oBAACuB;QACCC,OAAO;YACLU,OAAO;QACT;OAEClC,EAAE,mCAAmC;QAAEZ;QAAWC;IAAU,kBAC7D,oBAACkD;QACCC,MAAK;QACLC,KAAI;QACJC,QAAO;OAEN1C,EAAE,8CAIT,oBAACuB;QACCC,OAAO;YACLC,cAAc;YACdC,UAAU;QACZ;qBAEA,oBAAClD;QACCmE,aAAatC;QACbuC,UAAUtC;QACVT,MAAME;QACND,UAAUA;QACVS,WAAWA;QACXiB,OAAO;YACLC,cAAc;QAChB;QACAjB,OAAOA;uBAGX,oBAACe;QACCC,OAAO;YACLqB,YAAY;YACZC,SAAS;YACTC,OAAO;QACT;qBAEA,oBAAC5D;QAAgBC,WAAWA;QAAWC,WAAWA;QAAW2D,MAAMxC;;AAI3E,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetaImage.d.ts","sourceRoot":"","sources":["../../src/fields/MetaImage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAWpE,OAAO,KAAsB,MAAM,OAAO,CAAA;AAO1C,KAAK,cAAc,GAAG,gBAAgB,GAAG;IACvC,kBAAkB,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"MetaImage.d.ts","sourceRoot":"","sources":["../../src/fields/MetaImage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAWpE,OAAO,KAAsB,MAAM,OAAO,CAAA;AAO1C,KAAK,cAAc,GAAG,gBAAgB,GAAG;IACvC,kBAAkB,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAoI9C,CAAA"}
|
package/dist/fields/MetaImage.js
CHANGED
|
@@ -10,7 +10,7 @@ import { useTranslation } from '@payloadcms/ui/providers/Translation';
|
|
|
10
10
|
import React, { useCallback } from 'react';
|
|
11
11
|
import { Pill } from '../ui/Pill.js';
|
|
12
12
|
export const MetaImage = (props)=>{
|
|
13
|
-
const { CustomLabel, hasGenerateImageFn, labelProps, relationTo, required } = props || {};
|
|
13
|
+
const { CustomLabel, hasGenerateImageFn, label, labelProps, relationTo, required } = props || {};
|
|
14
14
|
const field = useField(props);
|
|
15
15
|
const { t } = useTranslation();
|
|
16
16
|
const locale = useLocale();
|
|
@@ -57,12 +57,11 @@ export const MetaImage = (props)=>{
|
|
|
57
57
|
}
|
|
58
58
|
}, /*#__PURE__*/ React.createElement("div", {
|
|
59
59
|
className: "plugin-seo__field"
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}, "*"), hasGenerateImageFn && /*#__PURE__*/ React.createElement(React.Fragment, null, " — ", /*#__PURE__*/ React.createElement("button", {
|
|
60
|
+
}, /*#__PURE__*/ React.createElement(FieldLabel, {
|
|
61
|
+
CustomLabel: CustomLabel,
|
|
62
|
+
label: label,
|
|
63
|
+
...labelProps || {}
|
|
64
|
+
}), hasGenerateImageFn && /*#__PURE__*/ React.createElement(React.Fragment, null, " — ", /*#__PURE__*/ React.createElement("button", {
|
|
66
65
|
onClick: regenerateImage,
|
|
67
66
|
style: {
|
|
68
67
|
background: 'none',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/MetaImage.tsx"],"sourcesContent":["'use client'\n\nimport type { UploadInputProps } from '@payloadcms/ui/fields/Upload'\nimport type { FieldType, Options } from '@payloadcms/ui/forms/useField'\n\nimport { UploadInput } from '@payloadcms/ui/fields/Upload'\nimport { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'\nimport { useAllFormFields } from '@payloadcms/ui/forms/Form'\nimport { useField } from '@payloadcms/ui/forms/useField'\nimport { useConfig } from '@payloadcms/ui/providers/Config'\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 { GenerateImage } from '../types.js'\n\nimport { Pill } from '../ui/Pill.js'\n\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\ntype MetaImageProps = UploadInputProps & {\n hasGenerateImageFn: boolean\n}\n\nexport const MetaImage: React.FC<MetaImageProps> = (props) => {\n const { CustomLabel, hasGenerateImageFn, labelProps, relationTo, required } = props || {}\n\n const field: FieldType<string> = useField(props as Options)\n\n const { t } = useTranslation()\n\n const locale = useLocale()\n const [fields] = useAllFormFields()\n const docInfo = useDocumentInfo()\n\n const { errorMessage, setValue, showError, value } = field\n\n const regenerateImage = useCallback(async () => {\n if (!hasGenerateImageFn) return\n\n const genImageResponse = await fetch('/api/plugin-seo/generate-image', {\n body: JSON.stringify({\n ...docInfo,\n doc: { ...fields },\n locale: typeof locale === 'object' ? locale?.code : locale,\n } satisfies Parameters<GenerateImage>[0]),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedImage } = await genImageResponse.json()\n\n setValue(generatedImage || '')\n }, [fields, setValue, hasGenerateImageFn, locale, docInfo])\n\n const hasImage = Boolean(value)\n\n const config = useConfig()\n\n const { collections, routes: { api } = {}, serverURL } = config\n\n const collection = collections?.find((coll) => coll.slug === relationTo) || undefined\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
|
|
1
|
+
{"version":3,"sources":["../../src/fields/MetaImage.tsx"],"sourcesContent":["'use client'\n\nimport type { UploadInputProps } from '@payloadcms/ui/fields/Upload'\nimport type { FieldType, Options } from '@payloadcms/ui/forms/useField'\n\nimport { UploadInput } from '@payloadcms/ui/fields/Upload'\nimport { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'\nimport { useAllFormFields } from '@payloadcms/ui/forms/Form'\nimport { useField } from '@payloadcms/ui/forms/useField'\nimport { useConfig } from '@payloadcms/ui/providers/Config'\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 { GenerateImage } from '../types.js'\n\nimport { Pill } from '../ui/Pill.js'\n\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\ntype MetaImageProps = UploadInputProps & {\n hasGenerateImageFn: boolean\n}\n\nexport const MetaImage: React.FC<MetaImageProps> = (props) => {\n const { CustomLabel, hasGenerateImageFn, label, labelProps, relationTo, required } = props || {}\n\n const field: FieldType<string> = useField(props as Options)\n\n const { t } = useTranslation()\n\n const locale = useLocale()\n const [fields] = useAllFormFields()\n const docInfo = useDocumentInfo()\n\n const { errorMessage, setValue, showError, value } = field\n\n const regenerateImage = useCallback(async () => {\n if (!hasGenerateImageFn) return\n\n const genImageResponse = await fetch('/api/plugin-seo/generate-image', {\n body: JSON.stringify({\n ...docInfo,\n doc: { ...fields },\n locale: typeof locale === 'object' ? locale?.code : locale,\n } satisfies Parameters<GenerateImage>[0]),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedImage } = await genImageResponse.json()\n\n setValue(generatedImage || '')\n }, [fields, setValue, hasGenerateImageFn, locale, docInfo])\n\n const hasImage = Boolean(value)\n\n const config = useConfig()\n\n const { collections, routes: { api } = {}, serverURL } = config\n\n const collection = collections?.find((coll) => coll.slug === relationTo) || undefined\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 <FieldLabel CustomLabel={CustomLabel} label={label} {...(labelProps || {})} />\n {hasGenerateImageFn && (\n <React.Fragment>\n — \n <button\n onClick={regenerateImage}\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 {hasGenerateImageFn && (\n <div\n style={{\n color: '#9A9A9A',\n }}\n >\n {t('plugin-seo:imageAutoGenerationTip')}\n </div>\n )}\n </div>\n <div\n style={{\n marginBottom: '10px',\n position: 'relative',\n }}\n >\n <UploadInput\n CustomError={errorMessage}\n api={api}\n collection={collection}\n filterOptions={{}}\n label={undefined}\n onChange={(incomingImage) => {\n if (incomingImage !== null) {\n const { id: incomingID } = incomingImage\n setValue(incomingID)\n } else {\n setValue(null)\n }\n }}\n relationTo={relationTo}\n required={required}\n serverURL={serverURL}\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 <Pill\n backgroundColor={hasImage ? 'green' : 'red'}\n color=\"white\"\n label={hasImage ? t('plugin-seo:good') : t('plugin-seo:noImage')}\n />\n </div>\n </div>\n )\n}\n"],"names":["UploadInput","FieldLabel","useAllFormFields","useField","useConfig","useDocumentInfo","useLocale","useTranslation","React","useCallback","Pill","MetaImage","props","CustomLabel","hasGenerateImageFn","label","labelProps","relationTo","required","field","t","locale","fields","docInfo","errorMessage","setValue","showError","value","regenerateImage","genImageResponse","fetch","body","JSON","stringify","doc","code","credentials","headers","method","result","generatedImage","json","hasImage","Boolean","config","collections","routes","api","serverURL","collection","find","coll","slug","undefined","div","style","marginBottom","position","className","Fragment","button","onClick","background","backgroundColor","border","color","cursor","padding","textDecoration","type","CustomError","filterOptions","onChange","incomingImage","id","incomingID","alignItems","display","width"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetaTitle.d.ts","sourceRoot":"","sources":["../../src/fields/MetaTitle.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAYjE,OAAO,KAAsB,MAAM,OAAO,CAAA;AAM1C,OAAO,cAAc,CAAA;AAKrB,KAAK,cAAc,GAAG,aAAa,GAAG;IACpC,kBAAkB,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"MetaTitle.d.ts","sourceRoot":"","sources":["../../src/fields/MetaTitle.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAYjE,OAAO,KAAsB,MAAM,OAAO,CAAA;AAM1C,OAAO,cAAc,CAAA;AAKrB,KAAK,cAAc,GAAG,aAAa,GAAG;IACpC,kBAAkB,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAqH9C,CAAA"}
|
package/dist/fields/MetaTitle.js
CHANGED
|
@@ -13,7 +13,7 @@ import { LengthIndicator } from '../ui/LengthIndicator.js';
|
|
|
13
13
|
import './index.scss';
|
|
14
14
|
const { maxLength, minLength } = defaults.title;
|
|
15
15
|
export const MetaTitle = (props)=>{
|
|
16
|
-
const { CustomLabel, hasGenerateTitleFn, labelProps, path, required } = props || {};
|
|
16
|
+
const { CustomLabel, hasGenerateTitleFn, label, labelProps, path, required } = props || {};
|
|
17
17
|
const { path: pathFromContext } = useFieldProps();
|
|
18
18
|
const { t } = useTranslation();
|
|
19
19
|
const field = useField({
|
|
@@ -59,12 +59,11 @@ export const MetaTitle = (props)=>{
|
|
|
59
59
|
}
|
|
60
60
|
}, /*#__PURE__*/ React.createElement("div", {
|
|
61
61
|
className: "plugin-seo__field"
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}, "*"), hasGenerateTitleFn && /*#__PURE__*/ React.createElement(React.Fragment, null, " — ", /*#__PURE__*/ React.createElement("button", {
|
|
62
|
+
}, /*#__PURE__*/ React.createElement(FieldLabel, {
|
|
63
|
+
CustomLabel: CustomLabel,
|
|
64
|
+
label: label,
|
|
65
|
+
...labelProps || {}
|
|
66
|
+
}), hasGenerateTitleFn && /*#__PURE__*/ React.createElement(React.Fragment, null, " — ", /*#__PURE__*/ React.createElement("button", {
|
|
68
67
|
onClick: regenerateTitle,
|
|
69
68
|
style: {
|
|
70
69
|
background: 'none',
|
|
@@ -1 +1 @@
|
|
|
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
|
|
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, label, 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 <FieldLabel CustomLabel={CustomLabel} label={label} {...(labelProps || {})} />\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","label","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","Fragment","button","onClick","background","backgroundColor","border","color","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,KAAK,EAAEC,UAAU,EAAEC,IAAI,EAAEC,QAAQ,EAAE,GAAGN,SAAS,CAAC;IACzF,MAAM,EAAEK,MAAME,eAAe,EAAE,GAAGrB;IAElC,MAAM,EAAEsB,CAAC,EAAE,GAAGjB;IAEd,MAAMkB,QAA2BrB,SAAS;QACxCiB;IACF;IAEA,MAAMK,SAASpB;IACf,MAAM,CAACqB,OAAO,GAAGxB;IACjB,MAAMyB,UAAUvB;IAEhB,MAAM,EAAEwB,YAAY,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAGP;IAErD,MAAMQ,kBAAkBxB,YAAY;QAClC,IAAI,CAACS,oBAAoB;QAEzB,MAAMgB,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;QAAUZ;QAAoBQ;QAAQE;KAAQ;IAE1D,qBACE,oBAACmB;QACCC,OAAO;YACLC,cAAc;QAChB;qBAEA,oBAACF;QACCC,OAAO;YACLC,cAAc;YACdC,UAAU;QACZ;qBAEA,oBAACH;QAAII,WAAU;qBACb,oBAAClD;QAAWgB,aAAaA;QAAaE,OAAOA;QAAQ,GAAIC,cAAc,CAAC,CAAC;QACxEF,oCACC,oBAACV,MAAM4C,QAAQ,QAAC,uBAEd,oBAACC;QACCC,SAASrB;QACTe,OAAO;YACLO,YAAY;YACZC,iBAAiB;YACjBC,QAAQ;YACRC,OAAO;YACPC,QAAQ;YACRC,SAAS;YACTC,gBAAgB;QAClB;QACAC,MAAK;OAEJtC,EAAE,6CAKX,oBAACuB;QACCC,OAAO;YACLU,OAAO;QACT;OAEClC,EAAE,6BAA6B;QAAEZ;QAAWC;IAAU,kBACvD,oBAACkD;QACCC,MAAK;QACLC,KAAI;QACJC,QAAO;OAEN1C,EAAE,8BACD,qBAIR,oBAACuB;QACCC,OAAO;YACLC,cAAc;YACdC,UAAU;QACZ;qBAEA,oBAAClD;QACCmE,aAAatC;QACbuC,UAAUtC;QACVT,MAAME;QACND,UAAUA;QACVS,WAAWA;QACXiB,OAAO;YACLC,cAAc;QAChB;QACAjB,OAAOA;uBAGX,oBAACe;QACCC,OAAO;YACLqB,YAAY;YACZC,SAAS;YACTC,OAAO;QACT;qBAEA,oBAAC5D;QAAgBC,WAAWA;QAAWC,WAAWA;QAAW2D,MAAMxC;;AAI3E,EAAC"}
|
package/dist/fields/index.scss
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Config } from 'payload/config';
|
|
2
|
-
import type {
|
|
3
|
-
declare const
|
|
4
|
-
export { seo };
|
|
2
|
+
import type { SEOPluginConfig } from './types.js';
|
|
3
|
+
export declare const seoPlugin: (pluginConfig: SEOPluginConfig) => (config: Config) => Config;
|
|
5
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAO5C,OAAO,KAAK,EAKV,eAAe,EAChB,MAAM,YAAY,CAAA;AASnB,eAAO,MAAM,SAAS,iBACL,eAAe,cACrB,MAAM,KAAG,MAkRjB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { addDataAndFileToRequest } from '@payloadcms/next/utilities';
|
|
1
2
|
import { deepMerge } from 'payload/utilities';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { MetaDescription } from './fields/MetaDescription.js';
|
|
@@ -6,7 +7,7 @@ import { MetaTitle } from './fields/MetaTitle.js';
|
|
|
6
7
|
import { translations } from './translations/index.js';
|
|
7
8
|
import { Overview } from './ui/Overview.js';
|
|
8
9
|
import { Preview } from './ui/Preview.js';
|
|
9
|
-
const
|
|
10
|
+
export const seoPlugin = (pluginConfig)=>(config)=>{
|
|
10
11
|
const seoFields = [
|
|
11
12
|
{
|
|
12
13
|
name: 'meta',
|
|
@@ -27,7 +28,7 @@ const seo = (pluginConfig)=>(config)=>{
|
|
|
27
28
|
type: 'text',
|
|
28
29
|
admin: {
|
|
29
30
|
components: {
|
|
30
|
-
Field: (props)=>/*#__PURE__*/ React.createElement(MetaTitle, {
|
|
31
|
+
Field: ({ payload: _payload, ...props })=>/*#__PURE__*/ React.createElement(MetaTitle, {
|
|
31
32
|
...props,
|
|
32
33
|
hasGenerateTitleFn: typeof pluginConfig?.generateTitle === 'function'
|
|
33
34
|
})
|
|
@@ -41,7 +42,7 @@ const seo = (pluginConfig)=>(config)=>{
|
|
|
41
42
|
type: 'textarea',
|
|
42
43
|
admin: {
|
|
43
44
|
components: {
|
|
44
|
-
Field: (props)=>/*#__PURE__*/ React.createElement(MetaDescription, {
|
|
45
|
+
Field: ({ payload: _payload, ...props })=>/*#__PURE__*/ React.createElement(MetaDescription, {
|
|
45
46
|
...props,
|
|
46
47
|
hasGenerateDescriptionFn: typeof pluginConfig?.generateDescription === 'function'
|
|
47
48
|
})
|
|
@@ -57,7 +58,7 @@ const seo = (pluginConfig)=>(config)=>{
|
|
|
57
58
|
type: 'upload',
|
|
58
59
|
admin: {
|
|
59
60
|
components: {
|
|
60
|
-
Field: (props)=>/*#__PURE__*/ React.createElement(MetaImage, {
|
|
61
|
+
Field: ({ payload: _payload, ...props })=>/*#__PURE__*/ React.createElement(MetaImage, {
|
|
61
62
|
...props,
|
|
62
63
|
hasGenerateImageFn: typeof pluginConfig?.generateImage === 'function'
|
|
63
64
|
})
|
|
@@ -76,7 +77,7 @@ const seo = (pluginConfig)=>(config)=>{
|
|
|
76
77
|
type: 'ui',
|
|
77
78
|
admin: {
|
|
78
79
|
components: {
|
|
79
|
-
Field: (props)=>/*#__PURE__*/ React.createElement(Preview, {
|
|
80
|
+
Field: ({ payload: _payload, ...props })=>/*#__PURE__*/ React.createElement(Preview, {
|
|
80
81
|
...props,
|
|
81
82
|
hasGenerateURLFn: typeof pluginConfig?.generateURL === 'function'
|
|
82
83
|
})
|
|
@@ -152,10 +153,13 @@ const seo = (pluginConfig)=>(config)=>{
|
|
|
152
153
|
return collection;
|
|
153
154
|
}) || [],
|
|
154
155
|
endpoints: [
|
|
155
|
-
...config.endpoints,
|
|
156
|
+
...config.endpoints ?? [],
|
|
156
157
|
{
|
|
157
158
|
handler: async (req)=>{
|
|
158
|
-
const
|
|
159
|
+
const reqWithData = await addDataAndFileToRequest({
|
|
160
|
+
request: req
|
|
161
|
+
});
|
|
162
|
+
const args = reqWithData.data;
|
|
159
163
|
const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(args) : '';
|
|
160
164
|
return new Response(JSON.stringify({
|
|
161
165
|
result
|
|
@@ -168,7 +172,10 @@ const seo = (pluginConfig)=>(config)=>{
|
|
|
168
172
|
},
|
|
169
173
|
{
|
|
170
174
|
handler: async (req)=>{
|
|
171
|
-
const
|
|
175
|
+
const reqWithData = await addDataAndFileToRequest({
|
|
176
|
+
request: req
|
|
177
|
+
});
|
|
178
|
+
const args = reqWithData.data;
|
|
172
179
|
const result = pluginConfig.generateDescription ? await pluginConfig.generateDescription(args) : '';
|
|
173
180
|
return new Response(JSON.stringify({
|
|
174
181
|
result
|
|
@@ -181,7 +188,10 @@ const seo = (pluginConfig)=>(config)=>{
|
|
|
181
188
|
},
|
|
182
189
|
{
|
|
183
190
|
handler: async (req)=>{
|
|
184
|
-
const
|
|
191
|
+
const reqWithData = await addDataAndFileToRequest({
|
|
192
|
+
request: req
|
|
193
|
+
});
|
|
194
|
+
const args = reqWithData.data;
|
|
185
195
|
const result = pluginConfig.generateURL ? await pluginConfig.generateURL(args) : '';
|
|
186
196
|
return new Response(JSON.stringify({
|
|
187
197
|
result
|
|
@@ -194,7 +204,10 @@ const seo = (pluginConfig)=>(config)=>{
|
|
|
194
204
|
},
|
|
195
205
|
{
|
|
196
206
|
handler: async (req)=>{
|
|
197
|
-
const
|
|
207
|
+
const reqWithData = await addDataAndFileToRequest({
|
|
208
|
+
request: req
|
|
209
|
+
});
|
|
210
|
+
const args = reqWithData.data;
|
|
198
211
|
const result = pluginConfig.generateImage ? await pluginConfig.generateImage(args) : '';
|
|
199
212
|
return new Response(result, {
|
|
200
213
|
status: 200
|
|
@@ -256,6 +269,5 @@ const seo = (pluginConfig)=>(config)=>{
|
|
|
256
269
|
}
|
|
257
270
|
};
|
|
258
271
|
};
|
|
259
|
-
export { seo };
|
|
260
272
|
|
|
261
273
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import type { Config } from 'payload/config'\nimport type { Field, GroupField, TabsField, TextField } from 'payload/types'\n\nimport { deepMerge } from 'payload/utilities'\nimport React from 'react'\n\nimport type {\n GenerateDescription,\n GenerateImage,\n GenerateTitle,\n GenerateURL,\n PluginConfig,\n} from './types.js'\n\nimport { MetaDescription } from './fields/MetaDescription.js'\nimport { MetaImage } from './fields/MetaImage.js'\nimport { MetaTitle } from './fields/MetaTitle.js'\nimport { translations } from './translations/index.js'\nimport { Overview } from './ui/Overview.js'\nimport { Preview } from './ui/Preview.js'\n\nconst seo =\n (pluginConfig: PluginConfig) =>\n (config: Config): Config => {\n const seoFields: GroupField[] = [\n {\n name: 'meta',\n type: 'group',\n fields: [\n {\n name: 'overview',\n type: 'ui',\n admin: {\n components: {\n Field: Overview,\n },\n },\n label: 'Overview',\n },\n {\n name: 'title',\n type: 'text',\n admin: {\n components: {\n Field: (props) => (\n <MetaTitle\n {...props}\n hasGenerateTitleFn={typeof pluginConfig?.generateTitle === 'function'}\n />\n ),\n },\n },\n localized: true,\n ...((pluginConfig?.fieldOverrides?.title as unknown as TextField) ?? {}),\n },\n {\n name: 'description',\n type: 'textarea',\n admin: {\n components: {\n Field: (props) => (\n <MetaDescription\n {...props}\n hasGenerateDescriptionFn={\n typeof pluginConfig?.generateDescription === 'function'\n }\n />\n ),\n },\n },\n localized: true,\n ...(pluginConfig?.fieldOverrides?.description ?? {}),\n },\n ...(pluginConfig?.uploadsCollection\n ? [\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n {\n name: 'image',\n type: 'upload',\n admin: {\n components: {\n Field: (props) => (\n <MetaImage\n {...props}\n hasGenerateImageFn={typeof pluginConfig?.generateImage === 'function'}\n />\n ),\n },\n description:\n 'Maximum upload file size: 12MB. Recommended file size for images is <500KB.',\n },\n label: 'Meta Image',\n localized: true,\n relationTo: pluginConfig?.uploadsCollection,\n ...(pluginConfig?.fieldOverrides?.image ?? {}),\n } as Field,\n ]\n : []),\n ...(pluginConfig?.fields || []),\n {\n name: 'preview',\n type: 'ui',\n admin: {\n components: {\n Field: (props) => (\n <Preview\n {...props}\n hasGenerateURLFn={typeof pluginConfig?.generateURL === 'function'}\n />\n ),\n },\n },\n label: 'Preview',\n },\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 args: Parameters<GenerateTitle>[0] =\n req.data as unknown as Parameters<GenerateTitle>[0]\n const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(args) : ''\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 args: Parameters<GenerateDescription>[0] =\n req.data as unknown as Parameters<GenerateDescription>[0]\n const result = pluginConfig.generateDescription\n ? await pluginConfig.generateDescription(args)\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 args: Parameters<GenerateURL>[0] =\n req.data as unknown as Parameters<GenerateURL>[0]\n const result = pluginConfig.generateURL ? await pluginConfig.generateURL(args) : ''\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 args: Parameters<GenerateImage>[0] =\n req.data as unknown as Parameters<GenerateImage>[0]\n const result = pluginConfig.generateImage ? await pluginConfig.generateImage(args) : ''\n return new Response(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: {\n ...deepMerge(translations, config.i18n?.translations),\n },\n },\n }\n }\n\nexport { seo }\n"],"names":["deepMerge","React","MetaDescription","MetaImage","MetaTitle","translations","Overview","Preview","seo","pluginConfig","config","seoFields","name","type","fields","admin","components","Field","label","props","hasGenerateTitleFn","generateTitle","localized","fieldOverrides","title","hasGenerateDescriptionFn","generateDescription","description","uploadsCollection","hasGenerateImageFn","generateImage","relationTo","image","hasGenerateURLFn","generateURL","interfaceName","collections","map","collection","slug","isEnabled","includes","tabbedUI","emailField","auth","disableLocalStrategy","find","field","hasOnlyEmailField","length","seoTabs","tabs","filter","labels","singular","slice","endpoints","handler","req","args","data","result","Response","JSON","stringify","status","method","path","globals","global","i18n"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAGA,SAASA,SAAS,QAAQ,oBAAmB;AAC7C,OAAOC,WAAW,QAAO;AAUzB,SAASC,eAAe,QAAQ,8BAA6B;AAC7D,SAASC,SAAS,QAAQ,wBAAuB;AACjD,SAASC,SAAS,QAAQ,wBAAuB;AACjD,SAASC,YAAY,QAAQ,0BAAyB;AACtD,SAASC,QAAQ,QAAQ,mBAAkB;AAC3C,SAASC,OAAO,QAAQ,kBAAiB;AAEzC,MAAMC,MACJ,CAACC,eACD,CAACC;QACC,MAAMC,YAA0B;YAC9B;gBACEC,MAAM;gBACNC,MAAM;gBACNC,QAAQ;oBACN;wBACEF,MAAM;wBACNC,MAAM;wBACNE,OAAO;4BACLC,YAAY;gCACVC,OAAOX;4BACT;wBACF;wBACAY,OAAO;oBACT;oBACA;wBACEN,MAAM;wBACNC,MAAM;wBACNE,OAAO;4BACLC,YAAY;gCACVC,OAAO,CAACE,sBACN,oBAACf;wCACE,GAAGe,KAAK;wCACTC,oBAAoB,OAAOX,cAAcY,kBAAkB;;4BAGjE;wBACF;wBACAC,WAAW;wBACX,GAAI,AAACb,cAAcc,gBAAgBC,SAAkC,CAAC,CAAC;oBACzE;oBACA;wBACEZ,MAAM;wBACNC,MAAM;wBACNE,OAAO;4BACLC,YAAY;gCACVC,OAAO,CAACE,sBACN,oBAACjB;wCACE,GAAGiB,KAAK;wCACTM,0BACE,OAAOhB,cAAciB,wBAAwB;;4BAIrD;wBACF;wBACAJ,WAAW;wBACX,GAAIb,cAAcc,gBAAgBI,eAAe,CAAC,CAAC;oBACrD;uBACIlB,cAAcmB,oBACd;wBACE,yEAAyE;wBACzE;4BACEhB,MAAM;4BACNC,MAAM;4BACNE,OAAO;gCACLC,YAAY;oCACVC,OAAO,CAACE,sBACN,oBAAChB;4CACE,GAAGgB,KAAK;4CACTU,oBAAoB,OAAOpB,cAAcqB,kBAAkB;;gCAGjE;gCACAH,aACE;4BACJ;4BACAT,OAAO;4BACPI,WAAW;4BACXS,YAAYtB,cAAcmB;4BAC1B,GAAInB,cAAcc,gBAAgBS,SAAS,CAAC,CAAC;wBAC/C;qBACD,GACD,EAAE;uBACFvB,cAAcK,UAAU,EAAE;oBAC9B;wBACEF,MAAM;wBACNC,MAAM;wBACNE,OAAO;4BACLC,YAAY;gCACVC,OAAO,CAACE,sBACN,oBAACZ;wCACE,GAAGY,KAAK;wCACTc,kBAAkB,OAAOxB,cAAcyB,gBAAgB;;4BAG7D;wBACF;wBACAhB,OAAO;oBACT;iBACD;gBACDiB,eAAe1B,aAAa0B,aAAa;gBACzCjB,OAAO;YACT;SACD;QAED,OAAO;YACL,GAAGR,MAAM;YACT0B,aACE1B,OAAO0B,WAAW,EAAEC,IAAI,CAACC;gBACvB,MAAM,EAAEC,IAAI,EAAE,GAAGD;gBACjB,MAAME,YAAY/B,cAAc2B,aAAaK,SAASF;gBAEtD,IAAIC,WAAW;oBACb,IAAI/B,cAAciC,UAAU;wBAC1B,4GAA4G;wBAC5G,MAAMC,aACJ,AAACL,CAAAA,WAAWM,IAAI,IACd,CAAE,CAAA,OAAON,WAAWM,IAAI,KAAK,YAAYN,WAAWM,IAAI,CAACC,oBAAoB,AAAD,CAAC,KAC/EP,WAAWxB,MAAM,EAAEgC,KAAK,CAACC,QAAU,UAAUA,SAASA,MAAMnC,IAAI,KAAK;wBACvE,MAAMoC,oBAAoBV,WAAWxB,MAAM,EAAEmC,WAAW,KAAKN;wBAE7D,MAAMO,UAAuBF,oBACzB;4BACE;gCACEnC,MAAM;gCACNsC,MAAM;oCACJ;wCACErC,QAAQH;wCACRO,OAAO;oCACT;iCACD;4BACH;yBACD,GACD;4BACE;gCACEL,MAAM;gCACNsC,MAAM;oCACJ,sFAAsF;oCACtF,6FAA6F;uCACzFb,YAAYxB,QAAQ,CAAC,EAAE,EAAED,SAAS,UACtCyB,YAAYxB,QAAQ,CAAC,EAAE,EAAEqC,OACrBb,WAAWxB,MAAM,CAAC,EAAE,CAACqC,IAAI,GACzB;wCACE;4CACErC,QAAQ;mDACF6B,aACAL,WAAWxB,MAAM,CAACsC,MAAM,CACtB,CAACL,QAAU,UAAUA,SAASA,MAAMnC,IAAI,KAAK,WAE/C0B,WAAWxB,MAAM;6CACtB;4CACDI,OAAOoB,YAAYe,QAAQC,YAAY;wCACzC;qCACD;oCACL;wCACExC,QAAQH;wCACRO,OAAO;oCACT;iCACD;4BACH;yBACD;wBAEL,OAAO;4BACL,GAAGoB,UAAU;4BACbxB,QAAQ;mCACF6B,aAAa;oCAACA;iCAAW,GAAG,EAAE;mCAC/BO;mCACCZ,YAAYxB,QAAQ,CAAC,EAAE,EAAED,SAAS,SAASyB,WAAWxB,MAAM,CAACyC,KAAK,CAAC,KAAK,EAAE;6BAC/E;wBACH;oBACF;oBAEA,OAAO;wBACL,GAAGjB,UAAU;wBACbxB,QAAQ;+BAAKwB,YAAYxB,UAAU,EAAE;+BAAMH;yBAAU;oBACvD;gBACF;gBAEA,OAAO2B;YACT,MAAM,EAAE;YACVkB,WAAW;mBACN9C,OAAO8C,SAAS;gBACnB;oBACEC,SAAS,OAAOC;wBACd,MAAMC,OACJD,IAAIE,IAAI;wBACV,MAAMC,SAASpD,aAAaY,aAAa,GAAG,MAAMZ,aAAaY,aAAa,CAACsC,QAAQ;wBACrF,OAAO,IAAIG,SAASC,KAAKC,SAAS,CAAC;4BAAEH;wBAAO,IAAI;4BAAEI,QAAQ;wBAAI;oBAChE;oBACAC,QAAQ;oBACRC,MAAM;gBACR;gBACA;oBACEV,SAAS,OAAOC;wBACd,MAAMC,OACJD,IAAIE,IAAI;wBACV,MAAMC,SAASpD,aAAaiB,mBAAmB,GAC3C,MAAMjB,aAAaiB,mBAAmB,CAACiC,QACvC;wBACJ,OAAO,IAAIG,SAASC,KAAKC,SAAS,CAAC;4BAAEH;wBAAO,IAAI;4BAAEI,QAAQ;wBAAI;oBAChE;oBACAC,QAAQ;oBACRC,MAAM;gBACR;gBACA;oBACEV,SAAS,OAAOC;wBACd,MAAMC,OACJD,IAAIE,IAAI;wBACV,MAAMC,SAASpD,aAAayB,WAAW,GAAG,MAAMzB,aAAayB,WAAW,CAACyB,QAAQ;wBACjF,OAAO,IAAIG,SAASC,KAAKC,SAAS,CAAC;4BAAEH;wBAAO,IAAI;4BAAEI,QAAQ;wBAAI;oBAChE;oBACAC,QAAQ;oBACRC,MAAM;gBACR;gBACA;oBACEV,SAAS,OAAOC;wBACd,MAAMC,OACJD,IAAIE,IAAI;wBACV,MAAMC,SAASpD,aAAaqB,aAAa,GAAG,MAAMrB,aAAaqB,aAAa,CAAC6B,QAAQ;wBACrF,OAAO,IAAIG,SAASD,QAAQ;4BAAEI,QAAQ;wBAAI;oBAC5C;oBACAC,QAAQ;oBACRC,MAAM;gBACR;aACD;YACDC,SACE1D,OAAO0D,OAAO,EAAE/B,IAAI,CAACgC;gBACnB,MAAM,EAAE9B,IAAI,EAAE,GAAG8B;gBACjB,MAAM7B,YAAY/B,cAAc2D,SAAS3B,SAASF;gBAElD,IAAIC,WAAW;oBACb,IAAI/B,cAAciC,UAAU;wBAC1B,MAAMQ,UAAuB;4BAC3B;gCACErC,MAAM;gCACNsC,MAAM;oCACJ,sFAAsF;oCACtF,yFAAyF;uCACrFkB,QAAQvD,QAAQ,CAAC,EAAE,CAACD,SAAS,UAAUwD,QAAQvD,QAAQ,CAAC,EAAE,CAACqC,OAC3DkB,OAAOvD,MAAM,CAAC,EAAE,CAACqC,IAAI,GACrB;wCACE;4CACErC,QAAQ;mDAAKuD,QAAQvD,UAAU,EAAE;6CAAE;4CACnCI,OAAOmD,QAAQnD,SAAS;wCAC1B;qCACD;oCACL;wCACEJ,QAAQH;wCACRO,OAAO;oCACT;iCACD;4BACH;yBACD;wBAED,OAAO;4BACL,GAAGmD,MAAM;4BACTvD,QAAQ;mCACHoC;mCACCmB,QAAQvD,QAAQ,CAAC,EAAE,CAACD,SAAS,SAASwD,OAAOvD,MAAM,CAACyC,KAAK,CAAC,KAAK,EAAE;6BACtE;wBACH;oBACF;oBAEA,OAAO;wBACL,GAAGc,MAAM;wBACTvD,QAAQ;+BAAKuD,QAAQvD,UAAU,EAAE;+BAAMH;yBAAU;oBACnD;gBACF;gBAEA,OAAO0D;YACT,MAAM,EAAE;YACVC,MAAM;gBACJ,GAAG5D,OAAO4D,IAAI;gBACdjE,cAAc;oBACZ,GAAGL,UAAUK,cAAcK,OAAO4D,IAAI,EAAEjE,aAAa;gBACvD;YACF;QACF;IACF;AAEF,SAASG,GAAG,GAAE"}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import type { Config } from 'payload/config'\nimport type { Field, GroupField, TabsField, TextField } from 'payload/types'\n\nimport { addDataAndFileToRequest } from '@payloadcms/next/utilities'\nimport { deepMerge } from 'payload/utilities'\nimport React from 'react'\n\nimport type {\n GenerateDescription,\n GenerateImage,\n GenerateTitle,\n GenerateURL,\n SEOPluginConfig,\n} from './types.js'\n\nimport { MetaDescription } from './fields/MetaDescription.js'\nimport { MetaImage } from './fields/MetaImage.js'\nimport { MetaTitle } from './fields/MetaTitle.js'\nimport { translations } from './translations/index.js'\nimport { Overview } from './ui/Overview.js'\nimport { Preview } from './ui/Preview.js'\n\nexport const seoPlugin =\n (pluginConfig: SEOPluginConfig) =>\n (config: Config): Config => {\n const seoFields: GroupField[] = [\n {\n name: 'meta',\n type: 'group',\n fields: [\n {\n name: 'overview',\n type: 'ui',\n admin: {\n components: {\n Field: Overview,\n },\n },\n label: 'Overview',\n },\n {\n name: 'title',\n type: 'text',\n admin: {\n components: {\n Field: ({ payload: _payload, ...props }) => (\n <MetaTitle\n {...props}\n hasGenerateTitleFn={typeof pluginConfig?.generateTitle === 'function'}\n />\n ),\n },\n },\n localized: true,\n ...((pluginConfig?.fieldOverrides?.title as unknown as TextField) ?? {}),\n },\n {\n name: 'description',\n type: 'textarea',\n admin: {\n components: {\n Field: ({ payload: _payload, ...props }) => (\n <MetaDescription\n {...props}\n hasGenerateDescriptionFn={\n typeof pluginConfig?.generateDescription === 'function'\n }\n />\n ),\n },\n },\n localized: true,\n ...(pluginConfig?.fieldOverrides?.description ?? {}),\n },\n ...(pluginConfig?.uploadsCollection\n ? [\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n {\n name: 'image',\n type: 'upload',\n admin: {\n components: {\n Field: ({ payload: _payload, ...props }) => (\n <MetaImage\n {...props}\n hasGenerateImageFn={typeof pluginConfig?.generateImage === 'function'}\n />\n ),\n },\n description:\n 'Maximum upload file size: 12MB. Recommended file size for images is <500KB.',\n },\n label: 'Meta Image',\n localized: true,\n relationTo: pluginConfig?.uploadsCollection,\n ...(pluginConfig?.fieldOverrides?.image ?? {}),\n } as Field,\n ]\n : []),\n ...(pluginConfig?.fields || []),\n {\n name: 'preview',\n type: 'ui',\n admin: {\n components: {\n Field: ({ payload: _payload, ...props }) => (\n <Preview\n {...props}\n hasGenerateURLFn={typeof pluginConfig?.generateURL === 'function'}\n />\n ),\n },\n },\n label: 'Preview',\n },\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 reqWithData = await addDataAndFileToRequest({ request: req })\n const args: Parameters<GenerateTitle>[0] =\n reqWithData.data as unknown as Parameters<GenerateTitle>[0]\n const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(args) : ''\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 reqWithData = await addDataAndFileToRequest({ request: req })\n const args: Parameters<GenerateDescription>[0] =\n reqWithData.data as unknown as Parameters<GenerateDescription>[0]\n const result = pluginConfig.generateDescription\n ? await pluginConfig.generateDescription(args)\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 reqWithData = await addDataAndFileToRequest({ request: req })\n const args: Parameters<GenerateURL>[0] =\n reqWithData.data as unknown as Parameters<GenerateURL>[0]\n const result = pluginConfig.generateURL ? await pluginConfig.generateURL(args) : ''\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 reqWithData = await addDataAndFileToRequest({ request: req })\n const args: Parameters<GenerateImage>[0] =\n reqWithData.data as unknown as Parameters<GenerateImage>[0]\n const result = pluginConfig.generateImage ? await pluginConfig.generateImage(args) : ''\n return new Response(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: {\n ...deepMerge(translations, config.i18n?.translations),\n },\n },\n }\n }\n"],"names":["addDataAndFileToRequest","deepMerge","React","MetaDescription","MetaImage","MetaTitle","translations","Overview","Preview","seoPlugin","pluginConfig","config","seoFields","name","type","fields","admin","components","Field","label","payload","_payload","props","hasGenerateTitleFn","generateTitle","localized","fieldOverrides","title","hasGenerateDescriptionFn","generateDescription","description","uploadsCollection","hasGenerateImageFn","generateImage","relationTo","image","hasGenerateURLFn","generateURL","interfaceName","collections","map","collection","slug","isEnabled","includes","tabbedUI","emailField","auth","disableLocalStrategy","find","field","hasOnlyEmailField","length","seoTabs","tabs","filter","labels","singular","slice","endpoints","handler","req","reqWithData","request","args","data","result","Response","JSON","stringify","status","method","path","globals","global","i18n"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAGA,SAASA,uBAAuB,QAAQ,6BAA4B;AACpE,SAASC,SAAS,QAAQ,oBAAmB;AAC7C,OAAOC,WAAW,QAAO;AAUzB,SAASC,eAAe,QAAQ,8BAA6B;AAC7D,SAASC,SAAS,QAAQ,wBAAuB;AACjD,SAASC,SAAS,QAAQ,wBAAuB;AACjD,SAASC,YAAY,QAAQ,0BAAyB;AACtD,SAASC,QAAQ,QAAQ,mBAAkB;AAC3C,SAASC,OAAO,QAAQ,kBAAiB;AAEzC,OAAO,MAAMC,YACX,CAACC,eACD,CAACC;QACC,MAAMC,YAA0B;YAC9B;gBACEC,MAAM;gBACNC,MAAM;gBACNC,QAAQ;oBACN;wBACEF,MAAM;wBACNC,MAAM;wBACNE,OAAO;4BACLC,YAAY;gCACVC,OAAOX;4BACT;wBACF;wBACAY,OAAO;oBACT;oBACA;wBACEN,MAAM;wBACNC,MAAM;wBACNE,OAAO;4BACLC,YAAY;gCACVC,OAAO,CAAC,EAAEE,SAASC,QAAQ,EAAE,GAAGC,OAAO,iBACrC,oBAACjB;wCACE,GAAGiB,KAAK;wCACTC,oBAAoB,OAAOb,cAAcc,kBAAkB;;4BAGjE;wBACF;wBACAC,WAAW;wBACX,GAAI,AAACf,cAAcgB,gBAAgBC,SAAkC,CAAC,CAAC;oBACzE;oBACA;wBACEd,MAAM;wBACNC,MAAM;wBACNE,OAAO;4BACLC,YAAY;gCACVC,OAAO,CAAC,EAAEE,SAASC,QAAQ,EAAE,GAAGC,OAAO,iBACrC,oBAACnB;wCACE,GAAGmB,KAAK;wCACTM,0BACE,OAAOlB,cAAcmB,wBAAwB;;4BAIrD;wBACF;wBACAJ,WAAW;wBACX,GAAIf,cAAcgB,gBAAgBI,eAAe,CAAC,CAAC;oBACrD;uBACIpB,cAAcqB,oBACd;wBACE,yEAAyE;wBACzE;4BACElB,MAAM;4BACNC,MAAM;4BACNE,OAAO;gCACLC,YAAY;oCACVC,OAAO,CAAC,EAAEE,SAASC,QAAQ,EAAE,GAAGC,OAAO,iBACrC,oBAAClB;4CACE,GAAGkB,KAAK;4CACTU,oBAAoB,OAAOtB,cAAcuB,kBAAkB;;gCAGjE;gCACAH,aACE;4BACJ;4BACAX,OAAO;4BACPM,WAAW;4BACXS,YAAYxB,cAAcqB;4BAC1B,GAAIrB,cAAcgB,gBAAgBS,SAAS,CAAC,CAAC;wBAC/C;qBACD,GACD,EAAE;uBACFzB,cAAcK,UAAU,EAAE;oBAC9B;wBACEF,MAAM;wBACNC,MAAM;wBACNE,OAAO;4BACLC,YAAY;gCACVC,OAAO,CAAC,EAAEE,SAASC,QAAQ,EAAE,GAAGC,OAAO,iBACrC,oBAACd;wCACE,GAAGc,KAAK;wCACTc,kBAAkB,OAAO1B,cAAc2B,gBAAgB;;4BAG7D;wBACF;wBACAlB,OAAO;oBACT;iBACD;gBACDmB,eAAe5B,aAAa4B,aAAa;gBACzCnB,OAAO;YACT;SACD;QAED,OAAO;YACL,GAAGR,MAAM;YACT4B,aACE5B,OAAO4B,WAAW,EAAEC,IAAI,CAACC;gBACvB,MAAM,EAAEC,IAAI,EAAE,GAAGD;gBACjB,MAAME,YAAYjC,cAAc6B,aAAaK,SAASF;gBAEtD,IAAIC,WAAW;oBACb,IAAIjC,cAAcmC,UAAU;wBAC1B,4GAA4G;wBAC5G,MAAMC,aACJ,AAACL,CAAAA,WAAWM,IAAI,IACd,CAAE,CAAA,OAAON,WAAWM,IAAI,KAAK,YAAYN,WAAWM,IAAI,CAACC,oBAAoB,AAAD,CAAC,KAC/EP,WAAW1B,MAAM,EAAEkC,KAAK,CAACC,QAAU,UAAUA,SAASA,MAAMrC,IAAI,KAAK;wBACvE,MAAMsC,oBAAoBV,WAAW1B,MAAM,EAAEqC,WAAW,KAAKN;wBAE7D,MAAMO,UAAuBF,oBACzB;4BACE;gCACErC,MAAM;gCACNwC,MAAM;oCACJ;wCACEvC,QAAQH;wCACRO,OAAO;oCACT;iCACD;4BACH;yBACD,GACD;4BACE;gCACEL,MAAM;gCACNwC,MAAM;oCACJ,sFAAsF;oCACtF,6FAA6F;uCACzFb,YAAY1B,QAAQ,CAAC,EAAE,EAAED,SAAS,UACtC2B,YAAY1B,QAAQ,CAAC,EAAE,EAAEuC,OACrBb,WAAW1B,MAAM,CAAC,EAAE,CAACuC,IAAI,GACzB;wCACE;4CACEvC,QAAQ;mDACF+B,aACAL,WAAW1B,MAAM,CAACwC,MAAM,CACtB,CAACL,QAAU,UAAUA,SAASA,MAAMrC,IAAI,KAAK,WAE/C4B,WAAW1B,MAAM;6CACtB;4CACDI,OAAOsB,YAAYe,QAAQC,YAAY;wCACzC;qCACD;oCACL;wCACE1C,QAAQH;wCACRO,OAAO;oCACT;iCACD;4BACH;yBACD;wBAEL,OAAO;4BACL,GAAGsB,UAAU;4BACb1B,QAAQ;mCACF+B,aAAa;oCAACA;iCAAW,GAAG,EAAE;mCAC/BO;mCACCZ,YAAY1B,QAAQ,CAAC,EAAE,EAAED,SAAS,SAAS2B,WAAW1B,MAAM,CAAC2C,KAAK,CAAC,KAAK,EAAE;6BAC/E;wBACH;oBACF;oBAEA,OAAO;wBACL,GAAGjB,UAAU;wBACb1B,QAAQ;+BAAK0B,YAAY1B,UAAU,EAAE;+BAAMH;yBAAU;oBACvD;gBACF;gBAEA,OAAO6B;YACT,MAAM,EAAE;YACVkB,WAAW;mBACLhD,OAAOgD,SAAS,IAAI,EAAE;gBAC1B;oBACEC,SAAS,OAAOC;wBACd,MAAMC,cAAc,MAAM9D,wBAAwB;4BAAE+D,SAASF;wBAAI;wBACjE,MAAMG,OACJF,YAAYG,IAAI;wBAClB,MAAMC,SAASxD,aAAac,aAAa,GAAG,MAAMd,aAAac,aAAa,CAACwC,QAAQ;wBACrF,OAAO,IAAIG,SAASC,KAAKC,SAAS,CAAC;4BAAEH;wBAAO,IAAI;4BAAEI,QAAQ;wBAAI;oBAChE;oBACAC,QAAQ;oBACRC,MAAM;gBACR;gBACA;oBACEZ,SAAS,OAAOC;wBACd,MAAMC,cAAc,MAAM9D,wBAAwB;4BAAE+D,SAASF;wBAAI;wBACjE,MAAMG,OACJF,YAAYG,IAAI;wBAClB,MAAMC,SAASxD,aAAamB,mBAAmB,GAC3C,MAAMnB,aAAamB,mBAAmB,CAACmC,QACvC;wBACJ,OAAO,IAAIG,SAASC,KAAKC,SAAS,CAAC;4BAAEH;wBAAO,IAAI;4BAAEI,QAAQ;wBAAI;oBAChE;oBACAC,QAAQ;oBACRC,MAAM;gBACR;gBACA;oBACEZ,SAAS,OAAOC;wBACd,MAAMC,cAAc,MAAM9D,wBAAwB;4BAAE+D,SAASF;wBAAI;wBACjE,MAAMG,OACJF,YAAYG,IAAI;wBAClB,MAAMC,SAASxD,aAAa2B,WAAW,GAAG,MAAM3B,aAAa2B,WAAW,CAAC2B,QAAQ;wBACjF,OAAO,IAAIG,SAASC,KAAKC,SAAS,CAAC;4BAAEH;wBAAO,IAAI;4BAAEI,QAAQ;wBAAI;oBAChE;oBACAC,QAAQ;oBACRC,MAAM;gBACR;gBACA;oBACEZ,SAAS,OAAOC;wBACd,MAAMC,cAAc,MAAM9D,wBAAwB;4BAAE+D,SAASF;wBAAI;wBACjE,MAAMG,OACJF,YAAYG,IAAI;wBAClB,MAAMC,SAASxD,aAAauB,aAAa,GAAG,MAAMvB,aAAauB,aAAa,CAAC+B,QAAQ;wBACrF,OAAO,IAAIG,SAASD,QAAQ;4BAAEI,QAAQ;wBAAI;oBAC5C;oBACAC,QAAQ;oBACRC,MAAM;gBACR;aACD;YACDC,SACE9D,OAAO8D,OAAO,EAAEjC,IAAI,CAACkC;gBACnB,MAAM,EAAEhC,IAAI,EAAE,GAAGgC;gBACjB,MAAM/B,YAAYjC,cAAc+D,SAAS7B,SAASF;gBAElD,IAAIC,WAAW;oBACb,IAAIjC,cAAcmC,UAAU;wBAC1B,MAAMQ,UAAuB;4BAC3B;gCACEvC,MAAM;gCACNwC,MAAM;oCACJ,sFAAsF;oCACtF,yFAAyF;uCACrFoB,QAAQ3D,QAAQ,CAAC,EAAE,CAACD,SAAS,UAAU4D,QAAQ3D,QAAQ,CAAC,EAAE,CAACuC,OAC3DoB,OAAO3D,MAAM,CAAC,EAAE,CAACuC,IAAI,GACrB;wCACE;4CACEvC,QAAQ;mDAAK2D,QAAQ3D,UAAU,EAAE;6CAAE;4CACnCI,OAAOuD,QAAQvD,SAAS;wCAC1B;qCACD;oCACL;wCACEJ,QAAQH;wCACRO,OAAO;oCACT;iCACD;4BACH;yBACD;wBAED,OAAO;4BACL,GAAGuD,MAAM;4BACT3D,QAAQ;mCACHsC;mCACCqB,QAAQ3D,QAAQ,CAAC,EAAE,CAACD,SAAS,SAAS4D,OAAO3D,MAAM,CAAC2C,KAAK,CAAC,KAAK,EAAE;6BACtE;wBACH;oBACF;oBAEA,OAAO;wBACL,GAAGgB,MAAM;wBACT3D,QAAQ;+BAAK2D,QAAQ3D,UAAU,EAAE;+BAAMH;yBAAU;oBACnD;gBACF;gBAEA,OAAO8D;YACT,MAAM,EAAE;YACVC,MAAM;gBACJ,GAAGhE,OAAOgE,IAAI;gBACdrE,cAAc;oBACZ,GAAGL,UAAUK,cAAcK,OAAOgE,IAAI,EAAErE,aAAa;gBACvD;YACF;QACF;IACF,EAAC"}
|
|
@@ -131,5 +131,27 @@ export declare const translations: {
|
|
|
131
131
|
tooShort: string;
|
|
132
132
|
};
|
|
133
133
|
};
|
|
134
|
+
uk: {
|
|
135
|
+
$schema: string;
|
|
136
|
+
'plugin-seo': {
|
|
137
|
+
almostThere: string;
|
|
138
|
+
autoGenerate: string;
|
|
139
|
+
bestPractices: string;
|
|
140
|
+
characterCount: string;
|
|
141
|
+
charactersLeftOver: string;
|
|
142
|
+
charactersToGo: string;
|
|
143
|
+
charactersTooMany: string;
|
|
144
|
+
checksPassing: string;
|
|
145
|
+
good: string;
|
|
146
|
+
imageAutoGenerationTip: string;
|
|
147
|
+
lengthTipDescription: string;
|
|
148
|
+
lengthTipTitle: string;
|
|
149
|
+
noImage: string;
|
|
150
|
+
preview: string;
|
|
151
|
+
previewDescription: string;
|
|
152
|
+
tooLong: string;
|
|
153
|
+
tooShort: string;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
134
156
|
};
|
|
135
157
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/translations/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/translations/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6KxB,CAAA"}
|
|
@@ -130,6 +130,28 @@ export const translations = {
|
|
|
130
130
|
tooLong: 'Zbyt długie',
|
|
131
131
|
tooShort: 'Zbyt krótkie'
|
|
132
132
|
}
|
|
133
|
+
},
|
|
134
|
+
uk: {
|
|
135
|
+
$schema: './translation-schema.json',
|
|
136
|
+
'plugin-seo': {
|
|
137
|
+
almostThere: 'Ще трошки',
|
|
138
|
+
autoGenerate: 'Згенерувати',
|
|
139
|
+
bestPractices: 'найкращі практики',
|
|
140
|
+
characterCount: '{{current}}/{{minLength}}-{{maxLength}} символів, ',
|
|
141
|
+
charactersLeftOver: 'залишилось {{characters}} символів',
|
|
142
|
+
charactersToGo: ' на {{characters}} символів коротше',
|
|
143
|
+
charactersTooMany: 'на {{characters}} символів довше',
|
|
144
|
+
checksPassing: '{{current}}/{{max}} перевірок пройдено',
|
|
145
|
+
good: 'Чудово',
|
|
146
|
+
imageAutoGenerationTip: 'Автоматична генерація використає зображення з головного блоку',
|
|
147
|
+
lengthTipDescription: 'Має бути від {{minLength}} до {{maxLength}} символів. Щоб дізнатися, як писати якісні метаописи — перегляньте ',
|
|
148
|
+
lengthTipTitle: 'Має бути від {{minLength}} до {{maxLength}} символів. Щоб дізнатися, як писати якісні метазаголовки — перегляньте ',
|
|
149
|
+
noImage: 'Немає зображення',
|
|
150
|
+
preview: 'Попередній перегляд',
|
|
151
|
+
previewDescription: 'Реальне відображення може відрізнятися в залежності від вмісту та релевантності пошуку.',
|
|
152
|
+
tooLong: 'Задовгий',
|
|
153
|
+
tooShort: 'Закороткий'
|
|
154
|
+
}
|
|
133
155
|
}
|
|
134
156
|
};
|
|
135
157
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/translations/index.ts"],"sourcesContent":["export const translations = {\n en: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'Almost there',\n autoGenerate: 'Auto-generate',\n bestPractices: 'best practices',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} chars, ',\n charactersLeftOver: '{{characters}} left over',\n charactersToGo: '{{characters}} to go',\n charactersTooMany: '{{characters}} too many',\n checksPassing: '{{current}}/{{max}} checks are passing',\n good: 'Good',\n imageAutoGenerationTip: 'Auto-generation will retrieve the selected hero image.',\n lengthTipDescription:\n 'This should be between {{minLength}} and {{maxLength}} characters. For help in writing quality meta descriptions, see ',\n lengthTipTitle:\n 'This should be between {{minLength}} and {{maxLength}} characters. For help in writing quality meta titles, see ',\n noImage: 'No image',\n preview: 'Preview',\n previewDescription: 'Exact result listings may vary based on content and search relevancy.',\n tooLong: 'Too long',\n tooShort: 'Too short',\n },\n },\n es: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'Ya casi está',\n autoGenerate: 'Autogénerar',\n bestPractices: 'mejores prácticas',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} letras, ',\n charactersLeftOver: '{{characters}} letras sobrantes',\n charactersToGo: '{{characters}} letras sobrantes',\n charactersTooMany: '{{characters}} letras demasiados',\n checksPassing: '{{current}}/{{max}} las comprobaciones están pasando',\n good: 'Bien',\n imageAutoGenerationTip: 'La autogeneración recuperará la imagen de héroe seleccionada.',\n lengthTipDescription:\n 'Esto debe estar entre {{minLength}} y {{maxLength}} caracteres. Para obtener ayuda sobre cómo escribir meta descripciones de calidad, consulte ',\n lengthTipTitle:\n 'Debe tener entre {{minLength}} y {{maxLength}} caracteres. Para obtener ayuda sobre cómo escribir metatítulos de calidad, consulte ',\n noImage: 'Sin imagen',\n preview: 'Vista previa',\n previewDescription:\n 'Las listas de resultados pueden variar segun la relevancia de buesqueda y el contenido.',\n tooLong: 'Demasiado largo',\n tooShort: 'Demasiado corto',\n },\n },\n fa: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'چیزیی باقی نمونده',\n autoGenerate: 'تولید خودکار',\n bestPractices: 'آموزش بیشتر',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} کلمه، ',\n charactersLeftOver: '{{characters}} باقی مانده',\n charactersToGo: '{{characters}} باقی مانده',\n charactersTooMany: '{{characters}} بیش از حد',\n checksPassing: '{{current}}/{{max}} بررسیها با موفقیت انجام شده است',\n good: 'خوب',\n imageAutoGenerationTip:\n 'این قابلیت، تصویر فعلی بارگذاری شده در مجموعه محتوای شما را بازیابی میکند',\n lengthTipDescription:\n 'این باید بین {{minLength}} و {{maxLength}} کلمه باشد. برای کمک در نوشتن توضیحات متا با کیفیت، مراجعه کنید به ',\n lengthTipTitle:\n 'این باید بین {{minLength}} و {{maxLength}} کلمه باشد. برای کمک در نوشتن عناوین متا با کیفیت، مراجعه کنید به ',\n noImage: 'بدون تصویر',\n preview: 'پیشنمایش',\n previewDescription:\n 'فهرست نتایج ممکن است بر اساس محتوا و متناسب با کلمه کلیدی جستجو شده باشند',\n tooLong: 'خیلی طولانی',\n tooShort: 'خیلی کوتاه',\n },\n },\n fr: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'On y est presque',\n autoGenerate: 'Auto-générer',\n bestPractices: 'bonnes pratiques',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} caractères, ',\n charactersLeftOver: '{{characters}} restants',\n charactersToGo: '{{characters}} à ajouter',\n charactersTooMany: '{{characters}} en trop',\n checksPassing: '{{current}}/{{max}} vérifications réussies',\n good: 'Bien',\n imageAutoGenerationTip: \"L'auto-génération récupérera l'image principale sélectionnée.\",\n lengthTipDescription:\n \"Ceci devrait contenir entre {{minLength}} et {{maxLength}} caractères. Pour obtenir de l'aide pour rédiger des descriptions meta de qualité, consultez les \",\n lengthTipTitle:\n \"Ceci devrait contenir entre {{minLength}} et {{maxLength}} caractères. Pour obtenir de l'aide pour rédiger des titres meta de qualité, consultez les \",\n noImage: \"Pas d'image\",\n preview: 'Aperçu',\n previewDescription:\n 'Les résultats exacts peuvent varier en fonction du contenu et de la pertinence de la recherche.',\n tooLong: 'Trop long',\n tooShort: 'Trop court',\n },\n },\n nb: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'Nesten der',\n autoGenerate: 'Auto-generer',\n bestPractices: 'beste praksis',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} tegn, ',\n charactersLeftOver: '{{characters}} til overs',\n charactersToGo: '{{characters}} igjen',\n charactersTooMany: '{{characters}} for mange',\n checksPassing: '{{current}}/{{max}} sjekker bestått',\n good: 'Bra',\n imageAutoGenerationTip: 'Auto-generering vil hente det valgte hero-bildet.',\n lengthTipDescription:\n 'Dette bør være mellom {{minLength}} og {{maxLength}} tegn. For hjelp til å skrive beskrivelser av god kvalitet, se ',\n lengthTipTitle:\n 'Dette bør være mellom {{minLength}} og {{maxLength}} tegn. For hjelp til å skrive metatitler av god kvalitet, se ',\n noImage: 'Bilde mangler',\n preview: 'Forhåndsvisning',\n previewDescription:\n 'Eksakte resultatoppføringer kan variere basert på innhold og søke relevans.',\n tooLong: 'For lang',\n tooShort: 'For kort',\n },\n },\n pl: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'Prawie gotowe',\n autoGenerate: 'Wygeneruj automatycznie',\n bestPractices: 'najlepsze praktyki',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} znaków, ',\n charactersLeftOver: 'zostało {{characters}} znaków',\n charactersToGo: 'pozostało {{characters}} znaków',\n charactersTooMany: '{{characters}} znaków za dużo',\n checksPassing: '{{current}}/{{max}} testów zakończonych pomyślnie',\n good: 'Dobrze',\n imageAutoGenerationTip: 'Automatyczne generowanie pobierze wybrany główny obraz.',\n lengthTipDescription:\n 'Długość powinna wynosić od {{minLength}} do {{maxLength}} znaków. Po porady dotyczące pisania wysokiej jakości meta opisów zobacz ',\n lengthTipTitle:\n 'Długość powinna wynosić od {{minLength}} do {{maxLength}} znaków. Po porady dotyczące pisania wysokiej jakości meta tytułów zobacz ',\n noImage: 'Brak obrazu',\n preview: 'Podgląd',\n previewDescription:\n 'Dokładne wyniki listowania mogą się różnić w zależności od treści i zgodności z kryteriami wyszukiwania.',\n tooLong: 'Zbyt długie',\n tooShort: 'Zbyt krótkie',\n },\n },\n}\n"],"names":["translations","en","$schema","almostThere","autoGenerate","bestPractices","characterCount","charactersLeftOver","charactersToGo","charactersTooMany","checksPassing","good","imageAutoGenerationTip","lengthTipDescription","lengthTipTitle","noImage","preview","previewDescription","tooLong","tooShort","es","fa","fr","nb","pl"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAO,MAAMA,eAAe;IAC1BC,IAAI;QACFC,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBAAoB;YACpBC,SAAS;YACTC,UAAU;QACZ;IACF;IACAC,IAAI;QACFlB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;IACAE,IAAI;QACFnB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBACE;YACFC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;IACAG,IAAI;QACFpB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;IACAI,IAAI;QACFrB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;IACAK,IAAI;QACFtB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;AACF,EAAC"}
|
|
1
|
+
{"version":3,"sources":["../../src/translations/index.ts"],"sourcesContent":["export const translations = {\n en: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'Almost there',\n autoGenerate: 'Auto-generate',\n bestPractices: 'best practices',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} chars, ',\n charactersLeftOver: '{{characters}} left over',\n charactersToGo: '{{characters}} to go',\n charactersTooMany: '{{characters}} too many',\n checksPassing: '{{current}}/{{max}} checks are passing',\n good: 'Good',\n imageAutoGenerationTip: 'Auto-generation will retrieve the selected hero image.',\n lengthTipDescription:\n 'This should be between {{minLength}} and {{maxLength}} characters. For help in writing quality meta descriptions, see ',\n lengthTipTitle:\n 'This should be between {{minLength}} and {{maxLength}} characters. For help in writing quality meta titles, see ',\n noImage: 'No image',\n preview: 'Preview',\n previewDescription: 'Exact result listings may vary based on content and search relevancy.',\n tooLong: 'Too long',\n tooShort: 'Too short',\n },\n },\n es: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'Ya casi está',\n autoGenerate: 'Autogénerar',\n bestPractices: 'mejores prácticas',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} letras, ',\n charactersLeftOver: '{{characters}} letras sobrantes',\n charactersToGo: '{{characters}} letras sobrantes',\n charactersTooMany: '{{characters}} letras demasiados',\n checksPassing: '{{current}}/{{max}} las comprobaciones están pasando',\n good: 'Bien',\n imageAutoGenerationTip: 'La autogeneración recuperará la imagen de héroe seleccionada.',\n lengthTipDescription:\n 'Esto debe estar entre {{minLength}} y {{maxLength}} caracteres. Para obtener ayuda sobre cómo escribir meta descripciones de calidad, consulte ',\n lengthTipTitle:\n 'Debe tener entre {{minLength}} y {{maxLength}} caracteres. Para obtener ayuda sobre cómo escribir metatítulos de calidad, consulte ',\n noImage: 'Sin imagen',\n preview: 'Vista previa',\n previewDescription:\n 'Las listas de resultados pueden variar segun la relevancia de buesqueda y el contenido.',\n tooLong: 'Demasiado largo',\n tooShort: 'Demasiado corto',\n },\n },\n fa: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'چیزیی باقی نمونده',\n autoGenerate: 'تولید خودکار',\n bestPractices: 'آموزش بیشتر',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} کلمه، ',\n charactersLeftOver: '{{characters}} باقی مانده',\n charactersToGo: '{{characters}} باقی مانده',\n charactersTooMany: '{{characters}} بیش از حد',\n checksPassing: '{{current}}/{{max}} بررسیها با موفقیت انجام شده است',\n good: 'خوب',\n imageAutoGenerationTip:\n 'این قابلیت، تصویر فعلی بارگذاری شده در مجموعه محتوای شما را بازیابی میکند',\n lengthTipDescription:\n 'این باید بین {{minLength}} و {{maxLength}} کلمه باشد. برای کمک در نوشتن توضیحات متا با کیفیت، مراجعه کنید به ',\n lengthTipTitle:\n 'این باید بین {{minLength}} و {{maxLength}} کلمه باشد. برای کمک در نوشتن عناوین متا با کیفیت، مراجعه کنید به ',\n noImage: 'بدون تصویر',\n preview: 'پیشنمایش',\n previewDescription:\n 'فهرست نتایج ممکن است بر اساس محتوا و متناسب با کلمه کلیدی جستجو شده باشند',\n tooLong: 'خیلی طولانی',\n tooShort: 'خیلی کوتاه',\n },\n },\n fr: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'On y est presque',\n autoGenerate: 'Auto-générer',\n bestPractices: 'bonnes pratiques',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} caractères, ',\n charactersLeftOver: '{{characters}} restants',\n charactersToGo: '{{characters}} à ajouter',\n charactersTooMany: '{{characters}} en trop',\n checksPassing: '{{current}}/{{max}} vérifications réussies',\n good: 'Bien',\n imageAutoGenerationTip: \"L'auto-génération récupérera l'image principale sélectionnée.\",\n lengthTipDescription:\n \"Ceci devrait contenir entre {{minLength}} et {{maxLength}} caractères. Pour obtenir de l'aide pour rédiger des descriptions meta de qualité, consultez les \",\n lengthTipTitle:\n \"Ceci devrait contenir entre {{minLength}} et {{maxLength}} caractères. Pour obtenir de l'aide pour rédiger des titres meta de qualité, consultez les \",\n noImage: \"Pas d'image\",\n preview: 'Aperçu',\n previewDescription:\n 'Les résultats exacts peuvent varier en fonction du contenu et de la pertinence de la recherche.',\n tooLong: 'Trop long',\n tooShort: 'Trop court',\n },\n },\n nb: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'Nesten der',\n autoGenerate: 'Auto-generer',\n bestPractices: 'beste praksis',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} tegn, ',\n charactersLeftOver: '{{characters}} til overs',\n charactersToGo: '{{characters}} igjen',\n charactersTooMany: '{{characters}} for mange',\n checksPassing: '{{current}}/{{max}} sjekker bestått',\n good: 'Bra',\n imageAutoGenerationTip: 'Auto-generering vil hente det valgte hero-bildet.',\n lengthTipDescription:\n 'Dette bør være mellom {{minLength}} og {{maxLength}} tegn. For hjelp til å skrive beskrivelser av god kvalitet, se ',\n lengthTipTitle:\n 'Dette bør være mellom {{minLength}} og {{maxLength}} tegn. For hjelp til å skrive metatitler av god kvalitet, se ',\n noImage: 'Bilde mangler',\n preview: 'Forhåndsvisning',\n previewDescription:\n 'Eksakte resultatoppføringer kan variere basert på innhold og søke relevans.',\n tooLong: 'For lang',\n tooShort: 'For kort',\n },\n },\n pl: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'Prawie gotowe',\n autoGenerate: 'Wygeneruj automatycznie',\n bestPractices: 'najlepsze praktyki',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} znaków, ',\n charactersLeftOver: 'zostało {{characters}} znaków',\n charactersToGo: 'pozostało {{characters}} znaków',\n charactersTooMany: '{{characters}} znaków za dużo',\n checksPassing: '{{current}}/{{max}} testów zakończonych pomyślnie',\n good: 'Dobrze',\n imageAutoGenerationTip: 'Automatyczne generowanie pobierze wybrany główny obraz.',\n lengthTipDescription:\n 'Długość powinna wynosić od {{minLength}} do {{maxLength}} znaków. Po porady dotyczące pisania wysokiej jakości meta opisów zobacz ',\n lengthTipTitle:\n 'Długość powinna wynosić od {{minLength}} do {{maxLength}} znaków. Po porady dotyczące pisania wysokiej jakości meta tytułów zobacz ',\n noImage: 'Brak obrazu',\n preview: 'Podgląd',\n previewDescription:\n 'Dokładne wyniki listowania mogą się różnić w zależności od treści i zgodności z kryteriami wyszukiwania.',\n tooLong: 'Zbyt długie',\n tooShort: 'Zbyt krótkie',\n },\n },\n uk: {\n $schema: './translation-schema.json',\n 'plugin-seo': {\n almostThere: 'Ще трошки',\n autoGenerate: 'Згенерувати',\n bestPractices: 'найкращі практики',\n characterCount: '{{current}}/{{minLength}}-{{maxLength}} символів, ',\n charactersLeftOver: 'залишилось {{characters}} символів',\n charactersToGo: ' на {{characters}} символів коротше',\n charactersTooMany: 'на {{characters}} символів довше',\n checksPassing: '{{current}}/{{max}} перевірок пройдено',\n good: 'Чудово',\n imageAutoGenerationTip: 'Автоматична генерація використає зображення з головного блоку',\n lengthTipDescription: 'Має бути від {{minLength}} до {{maxLength}} символів. Щоб дізнатися, як писати якісні метаописи — перегляньте ',\n lengthTipTitle: 'Має бути від {{minLength}} до {{maxLength}} символів. Щоб дізнатися, як писати якісні метазаголовки — перегляньте ',\n noImage: 'Немає зображення',\n preview: 'Попередній перегляд',\n previewDescription: 'Реальне відображення може відрізнятися в залежності від вмісту та релевантності пошуку.',\n tooLong: 'Задовгий',\n tooShort: 'Закороткий',\n },\n },\n}\n"],"names":["translations","en","$schema","almostThere","autoGenerate","bestPractices","characterCount","charactersLeftOver","charactersToGo","charactersTooMany","checksPassing","good","imageAutoGenerationTip","lengthTipDescription","lengthTipTitle","noImage","preview","previewDescription","tooLong","tooShort","es","fa","fr","nb","pl","uk"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAO,MAAMA,eAAe;IAC1BC,IAAI;QACFC,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBAAoB;YACpBC,SAAS;YACTC,UAAU;QACZ;IACF;IACAC,IAAI;QACFlB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;IACAE,IAAI;QACFnB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBACE;YACFC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;IACAG,IAAI;QACFpB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;IACAI,IAAI;QACFrB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;IACAK,IAAI;QACFtB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBACE;YACFC,gBACE;YACFC,SAAS;YACTC,SAAS;YACTC,oBACE;YACFC,SAAS;YACTC,UAAU;QACZ;IACF;IACAM,IAAI;QACFvB,SAAS;QACT,cAAc;YACZC,aAAa;YACbC,cAAc;YACdC,eAAe;YACfC,gBAAgB;YAChBC,oBAAoB;YACpBC,gBAAgB;YAChBC,mBAAmB;YACnBC,eAAe;YACfC,MAAM;YACNC,wBAAwB;YACxBC,sBAAsB;YACtBC,gBAAgB;YAChBC,SAAS;YACTC,SAAS;YACTC,oBAAoB;YACpBC,SAAS;YACTC,UAAU;QACZ;IACF;AACF,EAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./translation-schema.json",
|
|
3
|
+
"plugin-seo": {
|
|
4
|
+
"almostThere": "Ще трошки",
|
|
5
|
+
"autoGenerate": "Згенерувати",
|
|
6
|
+
"bestPractices": "найкращі практики",
|
|
7
|
+
"characterCount": "{{current}}/{{minLength}}-{{maxLength}} символів, ",
|
|
8
|
+
"charactersLeftOver": "залишилось {{characters}} символів",
|
|
9
|
+
"charactersToGo": " на {{characters}} символів коротше",
|
|
10
|
+
"charactersTooMany": "на {{characters}} символів довше",
|
|
11
|
+
"checksPassing": "{{current}}/{{max}} перевірок пройдено",
|
|
12
|
+
"good": "Чудово",
|
|
13
|
+
"imageAutoGenerationTip": "Автоматична генерація використає зображення з головного блоку",
|
|
14
|
+
"lengthTipDescription": "Має бути від {{minLength}} до {{maxLength}} символів. Щоб дізнатися, як писати якісні метаописи — перегляньте ",
|
|
15
|
+
"lengthTipTitle": "Має бути від {{minLength}} до {{maxLength}} символів. Щоб дізнатися, як писати якісні метазаголовки — перегляньте ",
|
|
16
|
+
"noImage": "Немає зображення",
|
|
17
|
+
"preview": "Попередній перегляд",
|
|
18
|
+
"previewDescription": "Реальне відображення може відрізнятися в залежності від вмісту та релевантності пошуку.",
|
|
19
|
+
"tooLong": "Задовгий",
|
|
20
|
+
"tooShort": "Закороткий"
|
|
21
|
+
}
|
|
22
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export type GenerateURL = <T = any>(args: DocumentInfoContext & {
|
|
|
16
16
|
doc: T;
|
|
17
17
|
locale?: string;
|
|
18
18
|
}) => Promise<string> | string;
|
|
19
|
-
export
|
|
19
|
+
export type SEOPluginConfig = {
|
|
20
20
|
collections?: string[];
|
|
21
21
|
fieldOverrides?: {
|
|
22
22
|
description?: Partial<TextareaField>;
|
|
@@ -32,11 +32,11 @@ export interface PluginConfig {
|
|
|
32
32
|
interfaceName?: string;
|
|
33
33
|
tabbedUI?: boolean;
|
|
34
34
|
uploadsCollection?: string;
|
|
35
|
-
}
|
|
36
|
-
export
|
|
35
|
+
};
|
|
36
|
+
export type Meta = {
|
|
37
37
|
description?: string;
|
|
38
38
|
image?: any;
|
|
39
39
|
keywords?: string;
|
|
40
40
|
title?: string;
|
|
41
|
-
}
|
|
41
|
+
};
|
|
42
42
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAA;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEjF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,GAAG,EAClC,IAAI,EAAE,mBAAmB,GAAG;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KACpD,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;AAE7B,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,GAAG,GAAG,EACxC,IAAI,EAAE,mBAAmB,GAAG;IAC1B,GAAG,EAAE,CAAC,CAAA;IACN,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,KACE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;AAE7B,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,GAAG,EAClC,IAAI,EAAE,mBAAmB,GAAG;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KACpD,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;AAE7B,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,GAAG,EAChC,IAAI,EAAE,mBAAmB,GAAG;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KACpD,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;AAE7B,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAA;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEjF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,GAAG,EAClC,IAAI,EAAE,mBAAmB,GAAG;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KACpD,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;AAE7B,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,GAAG,GAAG,EACxC,IAAI,EAAE,mBAAmB,GAAG;IAC1B,GAAG,EAAE,CAAC,CAAA;IACN,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,KACE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;AAE7B,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,GAAG,EAClC,IAAI,EAAE,mBAAmB,GAAG;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KACpD,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;AAE7B,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,GAAG,EAChC,IAAI,EAAE,mBAAmB,GAAG;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KACpD,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;AAE7B,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,cAAc,CAAC,EAAE;QACf,WAAW,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;QACpC,KAAK,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;QAC5B,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;KAC3B,CAAA;IACD,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;IAChB,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;IACzC,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,IAAI,GAAG;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,GAAG,CAAA;IACX,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { DocumentInfoContext } from '@payloadcms/ui/providers/DocumentInfo'\nimport type { Field, TextField, TextareaField, UploadField } from 'payload/types'\n\nexport type GenerateTitle = <T = any>(\n args: DocumentInfoContext & { doc: T; locale?: string },\n) => Promise<string> | string\n\nexport type GenerateDescription = <T = any>(\n args: DocumentInfoContext & {\n doc: T\n locale?: string\n },\n) => Promise<string> | string\n\nexport type GenerateImage = <T = any>(\n args: DocumentInfoContext & { doc: T; locale?: string },\n) => Promise<string> | string\n\nexport type GenerateURL = <T = any>(\n args: DocumentInfoContext & { doc: T; locale?: string },\n) => Promise<string> | string\n\nexport
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { DocumentInfoContext } from '@payloadcms/ui/providers/DocumentInfo'\nimport type { Field, TextField, TextareaField, UploadField } from 'payload/types'\n\nexport type GenerateTitle = <T = any>(\n args: DocumentInfoContext & { doc: T; locale?: string },\n) => Promise<string> | string\n\nexport type GenerateDescription = <T = any>(\n args: DocumentInfoContext & {\n doc: T\n locale?: string\n },\n) => Promise<string> | string\n\nexport type GenerateImage = <T = any>(\n args: DocumentInfoContext & { doc: T; locale?: string },\n) => Promise<string> | string\n\nexport type GenerateURL = <T = any>(\n args: DocumentInfoContext & { doc: T; locale?: string },\n) => Promise<string> | string\n\nexport type SEOPluginConfig = {\n collections?: string[]\n fieldOverrides?: {\n description?: Partial<TextareaField>\n image?: Partial<UploadField>\n title?: Partial<TextField>\n }\n fields?: Field[]\n generateDescription?: GenerateDescription\n generateImage?: GenerateImage\n generateTitle?: GenerateTitle\n generateURL?: GenerateURL\n globals?: string[]\n interfaceName?: string\n tabbedUI?: boolean\n uploadsCollection?: string\n}\n\nexport type Meta = {\n description?: string\n image?: any // TODO: type this\n keywords?: string\n title?: string\n}\n"],"names":[],"rangeMappings":"","mappings":"AAwCA,WAKC"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-seo",
|
|
3
|
-
"version": "3.0.0-
|
|
4
|
-
"homepage:": "https://payloadcms.com",
|
|
5
|
-
"repository": {
|
|
6
|
-
"type": "git",
|
|
7
|
-
"url": "https://github.com/payloadcms/payload.git",
|
|
8
|
-
"directory": "packages/plugin-seo"
|
|
9
|
-
},
|
|
3
|
+
"version": "3.0.0-canary.f6e77b8",
|
|
10
4
|
"description": "SEO plugin for Payload",
|
|
11
|
-
"main": "./dist/index.js",
|
|
12
|
-
"types": "./dist/index.d.ts",
|
|
13
|
-
"type": "module",
|
|
14
5
|
"keywords": [
|
|
15
6
|
"payload",
|
|
16
7
|
"cms",
|
|
@@ -20,38 +11,56 @@
|
|
|
20
11
|
"seo",
|
|
21
12
|
"yoast"
|
|
22
13
|
],
|
|
23
|
-
"
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/payloadcms/payload.git",
|
|
17
|
+
"directory": "packages/plugin-seo"
|
|
18
|
+
},
|
|
24
19
|
"license": "MIT",
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
20
|
+
"author": "Payload <dev@payloadcms.com> (https://payloadcms.com)",
|
|
21
|
+
"type": "module",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"require": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./*": {
|
|
29
|
+
"import": "./dist/exports/*.js",
|
|
30
|
+
"require": "./dist/exports/*.js",
|
|
31
|
+
"types": "./dist/exports/*.d.ts"
|
|
32
|
+
}
|
|
30
33
|
},
|
|
34
|
+
"main": "./dist/index.js",
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"files": [
|
|
37
|
+
"dist"
|
|
38
|
+
],
|
|
31
39
|
"devDependencies": {
|
|
32
40
|
"@types/react": "18.2.74",
|
|
33
|
-
"react": "^18.0.0",
|
|
34
|
-
"payload": "3.0.0-beta.9",
|
|
35
41
|
"@payloadcms/eslint-config": "1.1.1",
|
|
36
|
-
"@payloadcms/
|
|
37
|
-
"@payloadcms/translations": "3.0.0-
|
|
42
|
+
"@payloadcms/next": "3.0.0-canary.f6e77b8",
|
|
43
|
+
"@payloadcms/translations": "3.0.0-canary.f6e77b8",
|
|
44
|
+
"payload": "3.0.0-canary.f6e77b8",
|
|
45
|
+
"@payloadcms/ui": "3.0.0-canary.f6e77b8"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
|
49
|
+
"@payloadcms/ui": "3.0.0-canary.f6e77b8",
|
|
50
|
+
"@payloadcms/translations": "3.0.0-canary.f6e77b8",
|
|
51
|
+
"payload": "3.0.0-canary.f6e77b8"
|
|
38
52
|
},
|
|
39
|
-
"exports": null,
|
|
40
53
|
"publishConfig": {
|
|
41
54
|
"registry": "https://registry.npmjs.org/"
|
|
42
55
|
},
|
|
43
|
-
"
|
|
44
|
-
"dist",
|
|
45
|
-
"types.js",
|
|
46
|
-
"types.d.ts"
|
|
47
|
-
],
|
|
56
|
+
"homepage:": "https://payloadcms.com",
|
|
48
57
|
"scripts": {
|
|
49
58
|
"build": "pnpm copyfiles && pnpm build:swc && pnpm build:types",
|
|
50
59
|
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
|
|
51
60
|
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
|
61
|
+
"clean": "rimraf {dist,*.tsbuildinfo}",
|
|
52
62
|
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
|
|
53
63
|
"lint": "eslint src",
|
|
54
|
-
"lint:fix": "eslint --fix --ext .ts,.tsx src"
|
|
55
|
-
"clean": "rimraf {dist,*.tsbuildinfo}"
|
|
64
|
+
"lint:fix": "eslint --fix --ext .ts,.tsx src"
|
|
56
65
|
}
|
|
57
66
|
}
|
package/src/index.tsx
DELETED
|
@@ -1,296 +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
|
-
...config.endpoints,
|
|
198
|
-
{
|
|
199
|
-
handler: async (req) => {
|
|
200
|
-
const args: Parameters<GenerateTitle>[0] =
|
|
201
|
-
req.data as unknown as Parameters<GenerateTitle>[0]
|
|
202
|
-
const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(args) : ''
|
|
203
|
-
return new Response(JSON.stringify({ result }), { status: 200 })
|
|
204
|
-
},
|
|
205
|
-
method: 'post',
|
|
206
|
-
path: '/plugin-seo/generate-title',
|
|
207
|
-
},
|
|
208
|
-
{
|
|
209
|
-
handler: async (req) => {
|
|
210
|
-
const args: Parameters<GenerateDescription>[0] =
|
|
211
|
-
req.data as unknown as Parameters<GenerateDescription>[0]
|
|
212
|
-
const result = pluginConfig.generateDescription
|
|
213
|
-
? await pluginConfig.generateDescription(args)
|
|
214
|
-
: ''
|
|
215
|
-
return new Response(JSON.stringify({ result }), { status: 200 })
|
|
216
|
-
},
|
|
217
|
-
method: 'post',
|
|
218
|
-
path: '/plugin-seo/generate-description',
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
handler: async (req) => {
|
|
222
|
-
const args: Parameters<GenerateURL>[0] =
|
|
223
|
-
req.data as unknown as Parameters<GenerateURL>[0]
|
|
224
|
-
const result = pluginConfig.generateURL ? await pluginConfig.generateURL(args) : ''
|
|
225
|
-
return new Response(JSON.stringify({ result }), { status: 200 })
|
|
226
|
-
},
|
|
227
|
-
method: 'post',
|
|
228
|
-
path: '/plugin-seo/generate-url',
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
handler: async (req) => {
|
|
232
|
-
const args: Parameters<GenerateImage>[0] =
|
|
233
|
-
req.data as unknown as Parameters<GenerateImage>[0]
|
|
234
|
-
const result = pluginConfig.generateImage ? await pluginConfig.generateImage(args) : ''
|
|
235
|
-
return new Response(result, { status: 200 })
|
|
236
|
-
},
|
|
237
|
-
method: 'post',
|
|
238
|
-
path: '/plugin-seo/generate-image',
|
|
239
|
-
},
|
|
240
|
-
],
|
|
241
|
-
globals:
|
|
242
|
-
config.globals?.map((global) => {
|
|
243
|
-
const { slug } = global
|
|
244
|
-
const isEnabled = pluginConfig?.globals?.includes(slug)
|
|
245
|
-
|
|
246
|
-
if (isEnabled) {
|
|
247
|
-
if (pluginConfig?.tabbedUI) {
|
|
248
|
-
const seoTabs: TabsField[] = [
|
|
249
|
-
{
|
|
250
|
-
type: 'tabs',
|
|
251
|
-
tabs: [
|
|
252
|
-
// append a new tab onto the end of the tabs array, if there is one at the first index
|
|
253
|
-
// if needed, create a new `Content` tab in the first index for this global's base fields
|
|
254
|
-
...(global?.fields?.[0].type === 'tabs' && global?.fields?.[0].tabs
|
|
255
|
-
? global.fields[0].tabs
|
|
256
|
-
: [
|
|
257
|
-
{
|
|
258
|
-
fields: [...(global?.fields || [])],
|
|
259
|
-
label: global?.label || 'Content',
|
|
260
|
-
},
|
|
261
|
-
]),
|
|
262
|
-
{
|
|
263
|
-
fields: seoFields,
|
|
264
|
-
label: 'SEO',
|
|
265
|
-
},
|
|
266
|
-
],
|
|
267
|
-
},
|
|
268
|
-
]
|
|
269
|
-
|
|
270
|
-
return {
|
|
271
|
-
...global,
|
|
272
|
-
fields: [
|
|
273
|
-
...seoTabs,
|
|
274
|
-
...(global?.fields?.[0].type === 'tabs' ? global.fields.slice(1) : []),
|
|
275
|
-
],
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return {
|
|
280
|
-
...global,
|
|
281
|
-
fields: [...(global?.fields || []), ...seoFields],
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return global
|
|
286
|
-
}) || [],
|
|
287
|
-
i18n: {
|
|
288
|
-
...config.i18n,
|
|
289
|
-
translations: {
|
|
290
|
-
...deepMerge(translations, config.i18n?.translations),
|
|
291
|
-
},
|
|
292
|
-
},
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
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')
|