sanity-plugin-seofields 1.8.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +508 -26
  2. package/dist/SeoHealthTool-2COI27KI.cjs +8 -0
  3. package/dist/SeoHealthTool-2COI27KI.cjs.map +1 -0
  4. package/dist/SeoHealthTool-CWI3KB2V.js +8 -0
  5. package/dist/SeoHealthTool-CWI3KB2V.js.map +1 -0
  6. package/dist/{SeoPreview-3EXR6FD4.cjs → SeoPreview-LMZAWWOE.cjs} +35 -38
  7. package/dist/SeoPreview-LMZAWWOE.cjs.map +1 -0
  8. package/dist/{SeoPreview-4PPAF4NO.js → SeoPreview-UNQBKTQO.js} +14 -11
  9. package/dist/SeoPreview-UNQBKTQO.js.map +1 -0
  10. package/dist/{chunk-B5IVI5LP.cjs → chunk-5XTQRILL.cjs} +286 -236
  11. package/dist/chunk-5XTQRILL.cjs.map +1 -0
  12. package/dist/{chunk-254YHUN3.cjs → chunk-7N4MLTMR.js} +8 -6
  13. package/dist/chunk-7N4MLTMR.js.map +1 -0
  14. package/dist/{chunk-DDAAVRWG.js → chunk-A57XNQC7.cjs} +9 -4
  15. package/dist/chunk-A57XNQC7.cjs.map +1 -0
  16. package/dist/chunk-BWLJDK5J.js +624 -0
  17. package/dist/chunk-BWLJDK5J.js.map +1 -0
  18. package/dist/chunk-CRCXC45D.js +56 -0
  19. package/dist/chunk-CRCXC45D.js.map +1 -0
  20. package/dist/chunk-EUG4MNRC.cjs +713 -0
  21. package/dist/chunk-EUG4MNRC.cjs.map +1 -0
  22. package/dist/{chunk-ZBHLMQTS.cjs → chunk-HHO2AKAP.js} +44 -17
  23. package/dist/chunk-HHO2AKAP.js.map +1 -0
  24. package/dist/chunk-NLEB47UV.js +713 -0
  25. package/dist/chunk-NLEB47UV.js.map +1 -0
  26. package/dist/chunk-OULUDJPI.cjs +254 -0
  27. package/dist/chunk-OULUDJPI.cjs.map +1 -0
  28. package/dist/chunk-R2U7JF7U.cjs +624 -0
  29. package/dist/chunk-R2U7JF7U.cjs.map +1 -0
  30. package/dist/chunk-XD4HKLEA.js +254 -0
  31. package/dist/chunk-XD4HKLEA.js.map +1 -0
  32. package/dist/chunk-XYAZJ3WX.cjs +56 -0
  33. package/dist/chunk-XYAZJ3WX.cjs.map +1 -0
  34. package/dist/{chunk-VR44E62I.js → chunk-XZKQWV2H.js} +204 -33
  35. package/dist/chunk-XZKQWV2H.js.map +1 -0
  36. package/dist/{chunk-HDZZQCH7.js → chunk-Y46ACXM4.cjs} +45 -5
  37. package/dist/chunk-Y46ACXM4.cjs.map +1 -0
  38. package/dist/cli.js +27 -27
  39. package/dist/{component-DEXwtemT.d.ts → component-CjT1hvxh.d.ts} +2 -2
  40. package/dist/{component-BzI-LHPw.d.cts → component-WYh0z8as.d.cts} +2 -2
  41. package/dist/define-cli.cjs +2 -4
  42. package/dist/define-cli.cjs.map +1 -1
  43. package/dist/define-cli.js +4 -4
  44. package/dist/define-cli.js.map +1 -1
  45. package/dist/head.cjs +22 -0
  46. package/dist/head.cjs.map +1 -0
  47. package/dist/head.d.cts +314 -0
  48. package/dist/head.d.ts +314 -0
  49. package/dist/head.js +22 -0
  50. package/dist/head.js.map +1 -0
  51. package/dist/hreflang-_VbSuWYD.d.cts +29 -0
  52. package/dist/hreflang-_VbSuWYD.d.ts +29 -0
  53. package/dist/index.cjs +1072 -368
  54. package/dist/index.cjs.map +1 -1
  55. package/dist/index.d.cts +7 -374
  56. package/dist/index.d.ts +7 -374
  57. package/dist/index.js +1015 -288
  58. package/dist/index.js.map +1 -1
  59. package/dist/next.cjs +212 -455
  60. package/dist/next.cjs.map +1 -1
  61. package/dist/next.d.cts +9 -206
  62. package/dist/next.d.ts +9 -206
  63. package/dist/next.js +189 -111
  64. package/dist/next.js.map +1 -1
  65. package/dist/plugin-HFuWZsJu.d.cts +516 -0
  66. package/dist/plugin-oQUCim56.d.ts +516 -0
  67. package/dist/schema/next.cjs +173 -327
  68. package/dist/schema/next.cjs.map +1 -1
  69. package/dist/schema/next.d.cts +4 -4
  70. package/dist/schema/next.d.ts +4 -4
  71. package/dist/schema/next.js +172 -8
  72. package/dist/schema/next.js.map +1 -1
  73. package/dist/schema.cjs +376 -517
  74. package/dist/schema.cjs.map +1 -1
  75. package/dist/schema.d.cts +5 -5
  76. package/dist/schema.d.ts +5 -5
  77. package/dist/schema.js +216 -11
  78. package/dist/schema.js.map +1 -1
  79. package/dist/server.cjs +149 -0
  80. package/dist/server.cjs.map +1 -0
  81. package/dist/server.d.cts +100 -0
  82. package/dist/server.d.ts +100 -0
  83. package/dist/server.js +149 -0
  84. package/dist/server.js.map +1 -0
  85. package/dist/{types-CW8qFdAn.d.ts → types-BAdN1RMu.d.ts} +2 -2
  86. package/dist/{types-B_vjMPtM.d.cts → types-C5i3KMgs.d.cts} +2 -2
  87. package/dist/{types-BXSCbl6p.d.cts → types-DP-DiW6f.d.cts} +2 -2
  88. package/dist/{types-C19cQx5D.d.ts → types-DRLUGLtX.d.ts} +2 -2
  89. package/dist/{types-yVmQfby9.d.cts → types-DxlPXihz.d.cts} +1 -1
  90. package/dist/{types-yVmQfby9.d.ts → types-DxlPXihz.d.ts} +1 -1
  91. package/package.json +25 -4
  92. package/dist/SeoHealthDashboard-AEKVVMUR-7NWV3C3Y.js +0 -4
  93. package/dist/SeoHealthDashboard-AEKVVMUR-7NWV3C3Y.js.map +0 -1
  94. package/dist/SeoHealthDashboard-AEKVVMUR-XWKJUH24.cjs +0 -10
  95. package/dist/SeoHealthDashboard-AEKVVMUR-XWKJUH24.cjs.map +0 -1
  96. package/dist/SeoHealthTool-2KKQJLJL.cjs +0 -11
  97. package/dist/SeoHealthTool-2KKQJLJL.cjs.map +0 -1
  98. package/dist/SeoHealthTool-3CUKGADZ.js +0 -5
  99. package/dist/SeoHealthTool-3CUKGADZ.js.map +0 -1
  100. package/dist/SeoPreview-3EXR6FD4.cjs.map +0 -1
  101. package/dist/SeoPreview-4PPAF4NO.js.map +0 -1
  102. package/dist/chunk-254YHUN3.cjs.map +0 -1
  103. package/dist/chunk-27XSYENH.js +0 -2215
  104. package/dist/chunk-27XSYENH.js.map +0 -1
  105. package/dist/chunk-B5IVI5LP.cjs.map +0 -1
  106. package/dist/chunk-BNXMFD3T.cjs +0 -431
  107. package/dist/chunk-BNXMFD3T.cjs.map +0 -1
  108. package/dist/chunk-DDAAVRWG.js.map +0 -1
  109. package/dist/chunk-HDZZQCH7.js.map +0 -1
  110. package/dist/chunk-P6IOWIO2.cjs +0 -480
  111. package/dist/chunk-P6IOWIO2.cjs.map +0 -1
  112. package/dist/chunk-UOCZFYYP.js +0 -407
  113. package/dist/chunk-UOCZFYYP.js.map +0 -1
  114. package/dist/chunk-VR44E62I.js.map +0 -1
  115. package/dist/chunk-WKXHX3GO.js +0 -424
  116. package/dist/chunk-WKXHX3GO.js.map +0 -1
  117. package/dist/chunk-XZDLJ2N6.cjs +0 -2224
  118. package/dist/chunk-XZDLJ2N6.cjs.map +0 -1
  119. package/dist/chunk-ZBHLMQTS.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,25 +1,67 @@
1
- 'use strict';
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
3
+ var _chunkXYAZJ3WXcjs = require('./chunk-XYAZJ3WX.cjs');
4
4
 
5
- var chunkB5IVI5LP_cjs = require('./chunk-B5IVI5LP.cjs');
6
- var chunkZBHLMQTS_cjs = require('./chunk-ZBHLMQTS.cjs');
7
- var chunkBNXMFD3T_cjs = require('./chunk-BNXMFD3T.cjs');
8
- require('./chunk-XZDLJ2N6.cjs');
9
- var chunk254YHUN3_cjs = require('./chunk-254YHUN3.cjs');
10
- var react = require('react');
11
- var sanity = require('sanity');
12
- var jsxRuntime = require('react/jsx-runtime');
13
- var ui = require('@sanity/ui');
14
5
 
6
+
7
+
8
+ var _chunkEUG4MNRCcjs = require('./chunk-EUG4MNRC.cjs');
9
+
10
+
11
+
12
+ var _chunk5XTQRILLcjs = require('./chunk-5XTQRILL.cjs');
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+ var _chunkY46ACXM4cjs = require('./chunk-Y46ACXM4.cjs');
29
+
30
+
31
+
32
+ var _chunkA57XNQC7cjs = require('./chunk-A57XNQC7.cjs');
33
+
34
+ // src/plugin.ts
35
+ var _react = require('react');
36
+ var _sanity = require('sanity');
37
+
38
+ // src/actions/SeoPublishGateAction.tsx
39
+ var _seofieldspro = require('seofields-pro');
40
+
41
+ // src/schemas/index.ts
42
+
43
+
44
+
45
+
46
+
47
+
48
+ // src/components/geo/GEOChecklist.tsx
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+ var _jsxruntime = require('react/jsx-runtime');
15
57
  var GEOChecklist = (props) => {
16
58
  var _a;
17
59
  const { path, schemaType } = props;
18
- const [expanded, setExpanded] = react.useState(false);
60
+ const [expanded, setExpanded] = _react.useState.call(void 0, false);
19
61
  const licenseKey = (_a = schemaType.options) == null ? void 0 : _a.licenseKey;
20
- const seoFields = sanity.useFormValue([path[0]]);
21
- const rootDoc = sanity.useFormValue([]);
22
- const freeChecks = react.useMemo(() => {
62
+ const seoFields = _sanity.useFormValue.call(void 0, [path[0]]);
63
+ const rootDoc = _sanity.useFormValue.call(void 0, []);
64
+ const freeChecks = _react.useMemo.call(void 0, () => {
23
65
  var _a2, _b, _c, _d;
24
66
  const desc = (seoFields == null ? void 0 : seoFields.description) || "";
25
67
  const title = (seoFields == null ? void 0 : seoFields.title) || "";
@@ -56,8 +98,8 @@ var GEOChecklist = (props) => {
56
98
  }
57
99
  ];
58
100
  }, [seoFields]);
59
- const proChecks = react.useMemo(
60
- () => licenseKey ? chunkBNXMFD3T_cjs.buildGEOProChecks(seoFields, rootDoc) : null,
101
+ const proChecks = _react.useMemo.call(void 0,
102
+ () => licenseKey ? _seofieldspro.buildGEOProChecks.call(void 0, seoFields, rootDoc) : null,
61
103
  [licenseKey, seoFields, rootDoc]
62
104
  );
63
105
  const freePassing = freeChecks.filter((c) => c.pass).length;
@@ -77,7 +119,7 @@ var GEOChecklist = (props) => {
77
119
  scoreBg = "#fefce8";
78
120
  scoreText = "#a16207";
79
121
  }
80
- return /* @__PURE__ */ jsxRuntime.jsxs(
122
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
81
123
  "div",
82
124
  {
83
125
  style: {
@@ -87,7 +129,7 @@ var GEOChecklist = (props) => {
87
129
  fontFamily: "inherit"
88
130
  },
89
131
  children: [
90
- /* @__PURE__ */ jsxRuntime.jsxs(
132
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
91
133
  "div",
92
134
  {
93
135
  style: {
@@ -99,11 +141,11 @@ var GEOChecklist = (props) => {
99
141
  gap: 12
100
142
  },
101
143
  children: [
102
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
103
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, fontWeight: 600, color: "#111827", marginBottom: 2 }, children: "AI Overview Readiness" }),
104
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: "#9ca3af" }, children: "Signals that improve visibility in AI-generated overviews" })
144
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
145
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { fontSize: 13, fontWeight: 600, color: "#111827", marginBottom: 2 }, children: "AI Overview Readiness" }),
146
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { fontSize: 11, color: "#9ca3af" }, children: "Signals that improve visibility in AI-generated overviews" })
105
147
  ] }),
106
- /* @__PURE__ */ jsxRuntime.jsxs(
148
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
107
149
  "div",
108
150
  {
109
151
  style: {
@@ -116,8 +158,8 @@ var GEOChecklist = (props) => {
116
158
  flexShrink: 0
117
159
  },
118
160
  children: [
119
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 16, fontWeight: 700, color: scoreColor }, children: totalPassing }),
120
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: 12, color: scoreText, opacity: 0.7 }, children: [
161
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 16, fontWeight: 700, color: scoreColor }, children: totalPassing }),
162
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: { fontSize: 12, color: scoreText, opacity: 0.7 }, children: [
121
163
  "/ ",
122
164
  totalChecks
123
165
  ] })
@@ -127,7 +169,7 @@ var GEOChecklist = (props) => {
127
169
  ]
128
170
  }
129
171
  ),
130
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: 3, backgroundColor: "#f3f4f6" }, children: /* @__PURE__ */ jsxRuntime.jsx(
172
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { height: 3, backgroundColor: "#f3f4f6" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
131
173
  "div",
132
174
  {
133
175
  style: {
@@ -138,7 +180,7 @@ var GEOChecklist = (props) => {
138
180
  }
139
181
  }
140
182
  ) }),
141
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "10px 20px" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
183
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { padding: "10px 20px" }, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
142
184
  "button",
143
185
  {
144
186
  type: "button",
@@ -156,7 +198,7 @@ var GEOChecklist = (props) => {
156
198
  gap: 4
157
199
  },
158
200
  children: [
159
- /* @__PURE__ */ jsxRuntime.jsx(
201
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
160
202
  "svg",
161
203
  {
162
204
  xmlns: "http://www.w3.org/2000/svg",
@@ -174,16 +216,16 @@ var GEOChecklist = (props) => {
174
216
  transition: "transform 0.2s ease",
175
217
  flexShrink: 0
176
218
  },
177
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 18 6-6-6-6" })
219
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "m9 18 6-6-6-6" })
178
220
  }
179
221
  ),
180
222
  expanded ? "Hide checks" : "Show all checks"
181
223
  ]
182
224
  }
183
225
  ) }),
184
- expanded && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
185
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "0 20px 16px" }, children: [
186
- /* @__PURE__ */ jsxRuntime.jsx(
226
+ expanded && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
227
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: "0 20px 16px" }, children: [
228
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
187
229
  "div",
188
230
  {
189
231
  style: {
@@ -197,9 +239,9 @@ var GEOChecklist = (props) => {
197
239
  children: "Core Checks"
198
240
  }
199
241
  ),
200
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: freeChecks.map((check) => /* @__PURE__ */ jsxRuntime.jsx(CheckRow, { check }, check.id)) })
242
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: freeChecks.map((check) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CheckRow, { check }, check.id)) })
201
243
  ] }),
202
- /* @__PURE__ */ jsxRuntime.jsxs(
244
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
203
245
  "div",
204
246
  {
205
247
  style: {
@@ -210,7 +252,7 @@ var GEOChecklist = (props) => {
210
252
  overflow: "hidden"
211
253
  },
212
254
  children: [
213
- /* @__PURE__ */ jsxRuntime.jsxs(
255
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
214
256
  "div",
215
257
  {
216
258
  style: {
@@ -221,7 +263,7 @@ var GEOChecklist = (props) => {
221
263
  gap: 8
222
264
  },
223
265
  children: [
224
- /* @__PURE__ */ jsxRuntime.jsx(
266
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
225
267
  "span",
226
268
  {
227
269
  style: {
@@ -234,7 +276,7 @@ var GEOChecklist = (props) => {
234
276
  children: "Pro Insights"
235
277
  }
236
278
  ),
237
- !licenseKey && /* @__PURE__ */ jsxRuntime.jsx(
279
+ !licenseKey && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
238
280
  "span",
239
281
  {
240
282
  style: {
@@ -248,7 +290,7 @@ var GEOChecklist = (props) => {
248
290
  children: "Unlock with licenseKey"
249
291
  }
250
292
  ),
251
- licenseKey && proChecks && /* @__PURE__ */ jsxRuntime.jsxs(
293
+ licenseKey && proChecks && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
252
294
  "span",
253
295
  {
254
296
  style: {
@@ -270,7 +312,7 @@ var GEOChecklist = (props) => {
270
312
  ]
271
313
  }
272
314
  ),
273
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "10px 16px" }, children: proChecks ? /* @__PURE__ */ jsxRuntime.jsx(chunkBNXMFD3T_cjs.GEOChecklistProChecks, { checks: proChecks }) : /* @__PURE__ */ jsxRuntime.jsx(chunkBNXMFD3T_cjs.GEOLockedTeaser, {}) })
315
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { padding: "10px 16px" }, children: proChecks ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _seofieldspro.GEOChecklistProChecks, { checks: proChecks }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _seofieldspro.GEOLockedTeaser, {}) })
274
316
  ]
275
317
  }
276
318
  )
@@ -280,7 +322,7 @@ var GEOChecklist = (props) => {
280
322
  );
281
323
  };
282
324
  function CheckRow({ check }) {
283
- return /* @__PURE__ */ jsxRuntime.jsxs(
325
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
284
326
  "div",
285
327
  {
286
328
  style: {
@@ -293,7 +335,7 @@ function CheckRow({ check }) {
293
335
  border: `1px solid ${check.pass ? "transparent" : "#fee2e2"}`
294
336
  },
295
337
  children: [
296
- /* @__PURE__ */ jsxRuntime.jsx(
338
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
297
339
  "div",
298
340
  {
299
341
  style: {
@@ -307,7 +349,7 @@ function CheckRow({ check }) {
307
349
  flexShrink: 0,
308
350
  marginTop: 1
309
351
  },
310
- children: /* @__PURE__ */ jsxRuntime.jsx(
352
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
311
353
  "span",
312
354
  {
313
355
  style: {
@@ -321,8 +363,8 @@ function CheckRow({ check }) {
321
363
  )
322
364
  }
323
365
  ),
324
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
325
- /* @__PURE__ */ jsxRuntime.jsx(
366
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { flex: 1, minWidth: 0 }, children: [
367
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
326
368
  "div",
327
369
  {
328
370
  style: {
@@ -334,30 +376,181 @@ function CheckRow({ check }) {
334
376
  children: check.label
335
377
  }
336
378
  ),
337
- !check.pass && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: "#9ca3af", marginTop: 3, lineHeight: 1.5 }, children: check.hint })
379
+ !check.pass && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { fontSize: 11, color: "#9ca3af", marginTop: 3, lineHeight: 1.5 }, children: check.hint })
338
380
  ] })
339
381
  ]
340
382
  }
341
383
  );
342
384
  }
343
385
  var GEOChecklist_default = GEOChecklist;
386
+
387
+ // src/components/meta/FocusKeywordInput.tsx
388
+ var _ui = require('@sanity/ui');
389
+
390
+
391
+
392
+ // src/components/ai/SeoGenButton.tsx
393
+ var _icons = require('@sanity/icons');
394
+
395
+
396
+
397
+
398
+ // src/utils/extractDocText.ts
399
+ function extractBlockText(block) {
400
+ if (block._type === "block" && Array.isArray(block.children)) {
401
+ return block.children.map((s) => {
402
+ var _a;
403
+ return (_a = s.text) != null ? _a : "";
404
+ }).join("");
405
+ }
406
+ const parts = [];
407
+ for (const key of Object.keys(block)) {
408
+ if (key === "_type" || key === "_key") continue;
409
+ const val = block[key];
410
+ if (typeof val === "string" && val.trim()) parts.push(val.trim());
411
+ else if (Array.isArray(val)) parts.push(extractArrayText(val));
412
+ }
413
+ return parts.filter(Boolean).join(" ");
414
+ }
415
+ function extractArrayText(arr) {
416
+ return arr.map((b) => extractBlockText(b)).filter(Boolean).join("\n");
417
+ }
418
+ function extractFieldText(value) {
419
+ if (typeof value === "string") return value;
420
+ if (!Array.isArray(value)) return "";
421
+ return extractArrayText(value).replace(/\n{3,}/g, "\n\n").trim();
422
+ }
423
+ function extractDocText(doc, bodyField) {
424
+ const fields = [bodyField].flat();
425
+ const text = fields.map((f) => extractFieldText(doc[f])).filter(Boolean).join("\n\n");
426
+ return text.slice(0, 4e3);
427
+ }
428
+ function resolveContentFields(content, docType) {
429
+ var _a;
430
+ if (!content || typeof content === "string" || Array.isArray(content)) return content != null ? content : "body";
431
+ const key = docType && docType in content ? docType : "default";
432
+ return (_a = content[key]) != null ? _a : "body";
433
+ }
434
+
435
+ // src/components/ai/SeoGenButton.tsx
436
+
437
+ function SeoGenButton({
438
+ field,
439
+ ai,
440
+ seoFieldPath,
441
+ onGenerate
442
+ }) {
443
+ var _a, _b, _c, _d, _e, _f, _g;
444
+ const [state, setState] = _react.useState.call(void 0, "idle");
445
+ const [errorMsg, setErrorMsg] = _react.useState.call(void 0, null);
446
+ const abortRef = _react.useRef.call(void 0, null);
447
+ const cooldownRef = _react.useRef.call(void 0, null);
448
+ const rootDoc = _sanity.useFormValue.call(void 0, []);
449
+ const workspace = _sanity.useWorkspace.call(void 0, );
450
+ const seoObj = _sanity.useFormValue.call(void 0, [seoFieldPath]);
451
+ const focusKeyword = (_a = seoObj == null ? void 0 : seoObj.focusKeyword) != null ? _a : "";
452
+ const keywords = (_b = seoObj == null ? void 0 : seoObj.keywords) != null ? _b : [];
453
+ const bodyField = resolveContentFields(ai == null ? void 0 : ai.content, rootDoc == null ? void 0 : rootDoc._type);
454
+ const content = rootDoc ? extractDocText(rootDoc, bodyField) : "";
455
+ const meta = field === "focusKeyword" ? {
456
+ title: (_c = seoObj == null ? void 0 : seoObj.title) != null ? _c : void 0,
457
+ description: (_d = seoObj == null ? void 0 : seoObj.description) != null ? _d : void 0,
458
+ slug: (_f = (_e = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _e.current) != null ? _f : void 0
459
+ } : void 0;
460
+ const handleGenerate = _react.useCallback.call(void 0, async () => {
461
+ var _a2;
462
+ if (!ai) return;
463
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
464
+ if (cooldownRef.current) clearTimeout(cooldownRef.current);
465
+ setState("loading");
466
+ setErrorMsg(null);
467
+ try {
468
+ let result;
469
+ if (ai.testMode) {
470
+ await new Promise((r) => setTimeout(r, 400));
471
+ result = _chunkEUG4MNRCcjs.pickTestOutput.call(void 0, field);
472
+ } else {
473
+ const controller = new AbortController();
474
+ abortRef.current = controller;
475
+ result = await _chunkEUG4MNRCcjs.generateSeoText.call(void 0, field, content, focusKeyword, keywords, {
476
+ config: _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, ai), { _projectId: workspace.projectId }),
477
+ signal: controller.signal,
478
+ meta
479
+ });
480
+ }
481
+ onGenerate(result);
482
+ setState("cooldown");
483
+ cooldownRef.current = setTimeout(() => setState("idle"), 2e3);
484
+ } catch (err) {
485
+ if (err.name === "AbortError") {
486
+ setState("idle");
487
+ return;
488
+ }
489
+ setErrorMsg(err instanceof Error ? err.message : "Generation failed.");
490
+ setState("error");
491
+ }
492
+ }, [ai, field, content, focusKeyword, keywords, meta, onGenerate, workspace.projectId]);
493
+ _react.useEffect.call(void 0, () => {
494
+ return () => {
495
+ var _a2;
496
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
497
+ if (cooldownRef.current) clearTimeout(cooldownRef.current);
498
+ };
499
+ }, []);
500
+ const isConfigured = Boolean(
501
+ (ai == null ? void 0 : ai.apiKey) || (ai == null ? void 0 : ai.endpoint) || (ai == null ? void 0 : ai.testMode) || (ai == null ? void 0 : ai.provider) === "ollama"
502
+ );
503
+ if (!isConfigured) return null;
504
+ const isLoading = state === "loading";
505
+ const isTestMode = Boolean(ai == null ? void 0 : ai.testMode);
506
+ let buttonText = "Generate with AI";
507
+ if (isLoading) buttonText = "Generating\u2026";
508
+ else if (isTestMode) buttonText = "Generate (test)";
509
+ const isFullWidth = ((_g = ai == null ? void 0 : ai.buttonWidth) != null ? _g : "full") === "full";
510
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { direction: "column", gap: 1, align: isFullWidth ? "stretch" : "flex-start", children: [
511
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
512
+ _ui.Button,
513
+ {
514
+ mode: "ghost",
515
+ tone: "primary",
516
+ paddingX: isFullWidth ? 2 : 3,
517
+ paddingY: 3,
518
+ fontSize: 1,
519
+ icon: _icons.SparklesIcon,
520
+ text: buttonText,
521
+ onClick: handleGenerate,
522
+ disabled: isLoading || state === "cooldown"
523
+ }
524
+ ),
525
+ !content && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Text, { size: 0, muted: true, children: [
526
+ "(Set ",
527
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "code", { children: "ai.content" }),
528
+ " in plugin config for better results)"
529
+ ] }),
530
+ state === "error" && errorMsg && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Card, { padding: 2, tone: "critical", radius: 2, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, children: errorMsg }) })
531
+ ] });
532
+ }
533
+
534
+ // src/components/meta/FocusKeywordInput.tsx
535
+
344
536
  var FocusKeywordInput = (props) => {
345
537
  var _a;
346
- const { value, renderDefault, path } = props;
347
- const parent = sanity.useFormValue([path[0]]);
348
- const rootDoc = sanity.useFormValue([]);
349
- const feedbackItems = react.useMemo(() => {
350
- var _a2, _b;
538
+ const { value, renderDefault, path, schemaType, onChange } = props;
539
+ const { options } = schemaType;
540
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
541
+ const rootDoc = _sanity.useFormValue.call(void 0, []);
542
+ const feedbackItems = _react.useMemo.call(void 0, () => {
543
+ var _a2;
351
544
  if (!value) return [];
352
- const kw = value.toLowerCase();
353
- const title = ((parent == null ? void 0 : parent.title) || "").toLowerCase();
354
- const description = ((parent == null ? void 0 : parent.description) || "").toLowerCase();
545
+ const title = (parent == null ? void 0 : parent.title) || "";
546
+ const description = (parent == null ? void 0 : parent.description) || "";
355
547
  const slug = ((_a2 = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _a2.current) || "";
548
+ const placement = _chunkY46ACXM4cjs.getFocusKeywordPlacement.call(void 0, value, title, description);
356
549
  const items = [];
357
550
  if (title) {
358
- if (title.startsWith(kw)) {
551
+ if (placement.atStartOfTitle) {
359
552
  items.push({ text: "Keyword at start of title \u2014 excellent", color: "green" });
360
- } else if (title.includes(kw)) {
553
+ } else if (placement.inTitle) {
361
554
  items.push({
362
555
  text: "Keyword in title \u2014 move it to the start for more prominence",
363
556
  color: "orange"
@@ -367,14 +560,14 @@ var FocusKeywordInput = (props) => {
367
560
  }
368
561
  }
369
562
  if (description) {
370
- if (description.includes(kw)) {
563
+ if (placement.inDescription) {
371
564
  items.push({ text: "Keyword in meta description", color: "green" });
372
565
  } else {
373
566
  items.push({ text: "Not in description \u2014 include it naturally", color: "orange" });
374
567
  }
375
568
  }
376
569
  if (slug) {
377
- const kwSlug = kw.replace(/\s+/g, "-");
570
+ const kwSlug = value.toLowerCase().replace(/\s+/g, "-");
378
571
  if (slug.includes(kwSlug)) {
379
572
  items.push({ text: "Keyword in URL slug", color: "green" });
380
573
  } else {
@@ -384,8 +577,7 @@ var FocusKeywordInput = (props) => {
384
577
  });
385
578
  }
386
579
  }
387
- const safeKw = kw.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
388
- if (((_b = title.match(new RegExp(safeKw, "g"))) != null ? _b : []).length > 2) {
580
+ if (placement.isStuffed) {
389
581
  items.push({
390
582
  text: "Keyword appears too many times in title \u2014 avoid stuffing",
391
583
  color: "red"
@@ -393,10 +585,19 @@ var FocusKeywordInput = (props) => {
393
585
  }
394
586
  return items;
395
587
  }, [value, parent == null ? void 0 : parent.title, parent == null ? void 0 : parent.description, (_a = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _a.current]);
396
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
588
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
397
589
  renderDefault(props),
398
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
399
- /* @__PURE__ */ jsxRuntime.jsx(
590
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
591
+ SeoGenButton,
592
+ {
593
+ field: "focusKeyword",
594
+ ai: options == null ? void 0 : options.ai,
595
+ seoFieldPath: String(path[0]),
596
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
597
+ }
598
+ ),
599
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
600
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
400
601
  "div",
401
602
  {
402
603
  style: {
@@ -407,87 +608,357 @@ var FocusKeywordInput = (props) => {
407
608
  }
408
609
  }
409
610
  ),
410
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
611
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
411
612
  ] }, item.text)) })
412
613
  ] });
413
614
  };
414
615
  var FocusKeywordInput_default = FocusKeywordInput;
415
616
 
416
- // src/utils/readability.ts
417
- function countSyllables(word) {
617
+ // src/components/meta/HreflangInput.tsx
618
+
619
+
620
+
621
+
622
+
623
+ var DEFAULT_LOCALE_FIELD = "language";
624
+ var DEFAULT_API_VERSION = "2024-01-01";
625
+ function safeField(name) {
626
+ return name && /^[A-Za-z_][A-Za-z0-9_]*$/.test(name) ? name : DEFAULT_LOCALE_FIELD;
627
+ }
628
+ var HreflangInput = (props) => {
629
+ const { schemaType, onChange, renderDefault } = props;
630
+ const { options } = schemaType;
631
+ const { hreflang, baseUrl, apiVersion } = options != null ? options : {};
632
+ const rootDoc = _sanity.useFormValue.call(void 0, []);
633
+ const client = _sanity.useClient.call(void 0, { apiVersion: apiVersion != null ? apiVersion : DEFAULT_API_VERSION });
634
+ const [state, setState] = _react.useState.call(void 0, "idle");
635
+ const [message, setMessage] = _react.useState.call(void 0, null);
636
+ const localeField = safeField(hreflang == null ? void 0 : hreflang.localeField);
637
+ const handleSync = _react.useCallback.call(void 0, async () => {
638
+ var _a;
639
+ const rawId = rootDoc == null ? void 0 : rootDoc._id;
640
+ if (!rawId) {
641
+ setState("error");
642
+ setMessage("Save the document once before syncing translations.");
643
+ return;
644
+ }
645
+ setState("loading");
646
+ setMessage(null);
647
+ try {
648
+ const publishedId = rawId.replace(/^drafts\./, "");
649
+ const query = `*[_type == "translation.metadata" && references($id)][0].translations[].value->{
650
+ "language": ${localeField},
651
+ "slug": slug.current
652
+ }`;
653
+ const translations = (_a = await client.fetch(query, { id: publishedId })) != null ? _a : [];
654
+ const entries = _chunkXYAZJ3WXcjs.buildHreflangs.call(void 0, translations, {
655
+ baseUrl,
656
+ resolvePath: hreflang == null ? void 0 : hreflang.resolvePath
657
+ });
658
+ if (entries.length === 0) {
659
+ setState("error");
660
+ setMessage("No translations with a resolvable URL were found for this document.");
661
+ return;
662
+ }
663
+ const items = entries.map((e) => ({
664
+ _type: "hreflangEntry",
665
+ _key: e.locale,
666
+ locale: e.locale,
667
+ url: e.url
668
+ }));
669
+ onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, items)));
670
+ setState("done");
671
+ setMessage(
672
+ `Synced ${items.length} alternate${items.length === 1 ? "" : "s"} from translations.`
673
+ );
674
+ } catch (err) {
675
+ setState("error");
676
+ setMessage(err instanceof Error ? err.message : "Failed to sync translations.");
677
+ }
678
+ }, [rootDoc == null ? void 0 : rootDoc._id, client, localeField, baseUrl, hreflang, onChange]);
679
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
680
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Flex, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
681
+ _ui.Button,
682
+ {
683
+ mode: "ghost",
684
+ tone: "primary",
685
+ fontSize: 1,
686
+ icon: _icons.TranslateIcon,
687
+ text: state === "loading" ? "Syncing\u2026" : "Sync from translations",
688
+ onClick: handleSync,
689
+ disabled: state === "loading"
690
+ }
691
+ ) }),
692
+ message && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Card, { padding: 2, radius: 2, tone: state === "error" ? "critical" : "positive", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, children: message }) }),
693
+ renderDefault(props)
694
+ ] });
695
+ };
696
+ var HreflangInput_default = HreflangInput;
697
+
698
+ // src/components/meta/KeywordsInput.tsx
699
+
700
+
701
+
702
+ // src/components/ai/KeywordSuggestions.tsx
703
+
704
+
705
+
706
+
707
+
708
+ function KeywordSuggestions({
709
+ ai,
710
+ seoFieldPath,
711
+ existing,
712
+ onAdd,
713
+ onAddAll
714
+ }) {
418
715
  var _a;
419
- const w = word.toLowerCase().replace(/[^a-z]/g, "");
420
- if (w.length <= 3) return 1;
421
- const groups = (_a = w.match(/[aeiouy]+/g)) != null ? _a : [];
422
- let count = groups.length;
423
- if (w.endsWith("e") && w.length > 1 && !/[aeiouy]/.test(w[w.length - 2])) {
424
- count = Math.max(1, count - 1);
716
+ const [panelState, setPanelState] = _react.useState.call(void 0, "idle");
717
+ const [suggestions, setSuggestions] = _react.useState.call(void 0, []);
718
+ const [errorMsg, setErrorMsg] = _react.useState.call(void 0, null);
719
+ const abortRef = _react.useRef.call(void 0, null);
720
+ const rootDoc = _sanity.useFormValue.call(void 0, []);
721
+ const workspace = _sanity.useWorkspace.call(void 0, );
722
+ const seoObj = _sanity.useFormValue.call(void 0, [seoFieldPath]);
723
+ const focusKeyword = (_a = seoObj == null ? void 0 : seoObj.focusKeyword) != null ? _a : "";
724
+ const bodyField = resolveContentFields(ai == null ? void 0 : ai.content, rootDoc == null ? void 0 : rootDoc._type);
725
+ const content = rootDoc ? extractDocText(rootDoc, bodyField) : "";
726
+ const handleSuggest = _react.useCallback.call(void 0, async () => {
727
+ var _a2;
728
+ if (!ai) return;
729
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
730
+ abortRef.current = new AbortController();
731
+ setPanelState("loading");
732
+ setErrorMsg(null);
733
+ setSuggestions([]);
734
+ try {
735
+ let csv;
736
+ if (ai.testMode) {
737
+ await new Promise((r) => setTimeout(r, 400));
738
+ csv = _chunkEUG4MNRCcjs.pickTestOutput.call(void 0, "keywords");
739
+ } else {
740
+ csv = await _chunkEUG4MNRCcjs.generateSeoText.call(void 0, "keywords", content, focusKeyword, existing, {
741
+ config: _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, ai), { _projectId: workspace.projectId }),
742
+ signal: abortRef.current.signal
743
+ });
744
+ }
745
+ const parsed = csv.split(",").map((k) => k.replace(/^["']|["']$/g, "").trim()).filter(Boolean);
746
+ if (parsed.length === 0) {
747
+ setErrorMsg("No keywords returned. Try again.");
748
+ setPanelState("error");
749
+ return;
750
+ }
751
+ setSuggestions(parsed);
752
+ setPanelState("suggestions");
753
+ } catch (err) {
754
+ if (err.name === "AbortError") {
755
+ setPanelState("idle");
756
+ return;
757
+ }
758
+ setErrorMsg(err instanceof Error ? err.message : "Keyword generation failed.");
759
+ setPanelState("error");
760
+ }
761
+ }, [ai, content, focusKeyword, existing, workspace.projectId]);
762
+ const handleAdd = _react.useCallback.call(void 0,
763
+ (kw) => {
764
+ onAdd(kw);
765
+ setSuggestions((prev) => prev.filter((s) => s !== kw));
766
+ if (suggestions.length <= 1) setPanelState("idle");
767
+ },
768
+ [onAdd, suggestions.length]
769
+ );
770
+ const handleAddAll = _react.useCallback.call(void 0, () => {
771
+ const toAdd = suggestions.filter((kw) => !existing.includes(kw));
772
+ if (toAdd.length > 0) onAddAll(toAdd);
773
+ setSuggestions([]);
774
+ setPanelState("idle");
775
+ }, [suggestions, existing, onAddAll]);
776
+ const handleDismiss = _react.useCallback.call(void 0, () => {
777
+ var _a2;
778
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
779
+ setSuggestions([]);
780
+ setPanelState("idle");
781
+ setErrorMsg(null);
782
+ }, []);
783
+ _react.useEffect.call(void 0, () => {
784
+ return () => {
785
+ var _a2;
786
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
787
+ };
788
+ }, []);
789
+ const isConfigured = Boolean(
790
+ (ai == null ? void 0 : ai.apiKey) || (ai == null ? void 0 : ai.endpoint) || (ai == null ? void 0 : ai.testMode) || (ai == null ? void 0 : ai.provider) === "ollama"
791
+ );
792
+ if (!isConfigured) return null;
793
+ if (panelState === "idle" || panelState === "error") {
794
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 2, children: [
795
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
796
+ _ui.Button,
797
+ {
798
+ mode: "ghost",
799
+ tone: "primary",
800
+ paddingX: 2,
801
+ paddingY: 3,
802
+ fontSize: 1,
803
+ icon: _icons.SparklesIcon,
804
+ text: (ai == null ? void 0 : ai.testMode) ? "Suggest Keywords (test)" : "Suggest Keywords with AI",
805
+ onClick: handleSuggest
806
+ }
807
+ ),
808
+ panelState === "error" && errorMsg && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Card, { padding: 2, tone: "critical", radius: 2, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, children: errorMsg }) })
809
+ ] });
425
810
  }
426
- return Math.max(1, count);
427
- }
428
- function countSentences(text) {
429
- const matches = text.match(/[.!?]+/g);
430
- return matches ? matches.length : 1;
431
- }
432
- function analyzeReadability(text) {
433
- const wordList = text.trim().split(/\s+/).filter(Boolean);
434
- const words = wordList.length;
435
- if (words < 10) return null;
436
- const sentences = countSentences(text);
437
- const syllables = wordList.reduce((acc, word) => acc + countSyllables(word), 0);
438
- const rawScore = 206.835 - 1.015 * (words / sentences) - 84.6 * (syllables / words);
439
- const score = Math.round(rawScore * 10) / 10;
440
- const rawGrade = 0.39 * (words / sentences) + 11.8 * (syllables / words) - 15.59;
441
- const gradeLevel = Math.round(rawGrade * 10) / 10;
442
- const avgWordsPerSentence = Math.round(words / sentences * 10) / 10;
443
- let label;
444
- let color;
445
- if (score >= 70) {
446
- label = "Easy to read";
447
- color = "green";
448
- } else if (score >= 50) {
449
- label = "Fairly easy";
450
- color = "green";
451
- } else if (score >= 30) {
452
- label = "Moderately difficult";
453
- color = "orange";
454
- } else {
455
- label = "Difficult to read";
456
- color = "red";
811
+ if (panelState === "loading") {
812
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { align: "center", gap: 2, paddingY: 2, children: [
813
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Spinner, { muted: true }),
814
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, muted: true, children: "Finding keywords\u2026" })
815
+ ] });
457
816
  }
458
- return {
459
- score,
460
- gradeLevel,
461
- avgWordsPerSentence,
462
- words,
463
- sentences,
464
- label,
465
- color
466
- };
817
+ const pendingSuggestions = suggestions.filter((kw) => !existing.includes(kw));
818
+ const alreadyAdded = suggestions.filter((kw) => existing.includes(kw));
819
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Card, { padding: 3, radius: 2, tone: "transparent", border: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
820
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { align: "center", justify: "space-between", children: [
821
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, weight: "semibold", muted: true, children: "AI keyword suggestions" }),
822
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { gap: 2, children: [
823
+ pendingSuggestions.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
824
+ _ui.Button,
825
+ {
826
+ mode: "ghost",
827
+ tone: "primary",
828
+ paddingX: 2,
829
+ paddingY: 2,
830
+ fontSize: 1,
831
+ text: "Add all",
832
+ onClick: handleAddAll
833
+ }
834
+ ),
835
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
836
+ _ui.Button,
837
+ {
838
+ mode: "ghost",
839
+ tone: "default",
840
+ paddingX: 2,
841
+ paddingY: 2,
842
+ fontSize: 1,
843
+ text: "Dismiss",
844
+ onClick: handleDismiss
845
+ }
846
+ )
847
+ ] })
848
+ ] }),
849
+ pendingSuggestions.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Box, { children: [
850
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 0, muted: true, style: { marginBottom: 8 }, children: "Click to add:" }),
851
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Flex, { gap: 2, wrap: "wrap", style: { marginTop: 6 }, children: pendingSuggestions.map((kw) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
852
+ "button",
853
+ {
854
+ type: "button",
855
+ onClick: () => handleAdd(kw),
856
+ style: {
857
+ padding: "4px 10px",
858
+ borderRadius: 20,
859
+ border: "1px solid var(--card-border-color)",
860
+ background: "transparent",
861
+ color: "var(--card-fg-color)",
862
+ cursor: "pointer",
863
+ fontSize: 12,
864
+ lineHeight: 1.4,
865
+ transition: "background 0.15s"
866
+ },
867
+ onMouseEnter: (e) => {
868
+ ;
869
+ e.currentTarget.style.background = "var(--card-border-color)";
870
+ },
871
+ onMouseLeave: (e) => {
872
+ ;
873
+ e.currentTarget.style.background = "transparent";
874
+ },
875
+ children: [
876
+ "+ ",
877
+ kw
878
+ ]
879
+ },
880
+ kw
881
+ )) })
882
+ ] }),
883
+ alreadyAdded.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Box, { children: [
884
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 0, muted: true, style: { marginBottom: 6 }, children: "Already added:" }),
885
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Flex, { gap: 2, wrap: "wrap", style: { marginTop: 4 }, children: alreadyAdded.map((kw) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Badge, { tone: "positive", radius: 5, fontSize: 0, padding: 2, children: [
886
+ "\u2713 ",
887
+ kw
888
+ ] }, kw)) })
889
+ ] }),
890
+ pendingSuggestions.length === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, muted: true, children: "All suggested keywords added." })
891
+ ] }) });
467
892
  }
893
+
894
+ // src/components/meta/KeywordsInput.tsx
895
+
896
+ var KeywordsInput = (props) => {
897
+ const { value, renderDefault, path, schemaType, onChange } = props;
898
+ const { options } = schemaType;
899
+ const existing = value != null ? value : [];
900
+ const handleAdd = (kw) => {
901
+ if (existing.includes(kw)) return;
902
+ onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, [...existing, kw])));
903
+ };
904
+ const handleAddAll = (keywords) => {
905
+ const merged = [.../* @__PURE__ */ new Set([...existing, ...keywords])];
906
+ onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, merged)));
907
+ };
908
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
909
+ renderDefault(props),
910
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
911
+ KeywordSuggestions,
912
+ {
913
+ ai: options == null ? void 0 : options.ai,
914
+ seoFieldPath: String(path[0]),
915
+ existing,
916
+ onAdd: handleAdd,
917
+ onAddAll: handleAddAll
918
+ }
919
+ )
920
+ ] });
921
+ };
922
+ var KeywordsInput_default = KeywordsInput;
923
+
924
+ // src/components/meta/MetaDescription.tsx
925
+
926
+
927
+
928
+
468
929
  var MetaDescription = (props) => {
469
- const { value, renderDefault, path } = props;
470
- const parent = sanity.useFormValue([path[0]]);
930
+ const { value, renderDefault, path, schemaType, onChange } = props;
931
+ const { options } = schemaType;
932
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
471
933
  const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
472
- const keywords = react.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
473
- const feedbackItems = react.useMemo(
474
- () => chunkZBHLMQTS_cjs.getMetaDescriptionValidationMessages(value || "", keywords, isParentseoField),
934
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
935
+ const feedbackItems = _react.useMemo.call(void 0,
936
+ () => _chunkY46ACXM4cjs.getMetaDescriptionValidationMessages.call(void 0, value || "", keywords, isParentseoField),
475
937
  [value, keywords, isParentseoField]
476
938
  );
477
- const readability = react.useMemo(() => analyzeReadability(value || ""), [value]);
478
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
939
+ const readability = _react.useMemo.call(void 0, () => _chunkEUG4MNRCcjs.analyzeReadability.call(void 0, value || ""), [value]);
940
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
479
941
  renderDefault(props),
480
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
481
- /* @__PURE__ */ jsxRuntime.jsx(
942
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
943
+ SeoGenButton,
944
+ {
945
+ field: "description",
946
+ ai: options == null ? void 0 : options.ai,
947
+ seoFieldPath: String(path[0]),
948
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
949
+ }
950
+ ),
951
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
952
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
482
953
  "div",
483
954
  {
484
955
  style: { width: 10, height: 10, borderRadius: "50%", backgroundColor: item.color }
485
956
  }
486
957
  ),
487
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
958
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
488
959
  ] }, item.text)) }),
489
- readability && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
490
- /* @__PURE__ */ jsxRuntime.jsx(
960
+ readability && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
961
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
491
962
  "div",
492
963
  {
493
964
  style: {
@@ -498,7 +969,7 @@ var MetaDescription = (props) => {
498
969
  }
499
970
  }
500
971
  ),
501
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { weight: "bold", muted: true, size: 14, children: [
972
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: [
502
973
  "Readability: ",
503
974
  readability.label,
504
975
  " (Flesch ",
@@ -512,18 +983,24 @@ var MetaDescription = (props) => {
512
983
  ] });
513
984
  };
514
985
  var MetaDescription_default = MetaDescription;
986
+
987
+ // src/components/meta/MetaImage.tsx
988
+
989
+
990
+
991
+
515
992
  var MetaImage = (props) => {
516
993
  const { value, renderDefault, path } = props;
517
- const seoParent = sanity.useFormValue([path[0]]);
994
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
518
995
  const hasImage = !!(value == null ? void 0 : value.asset);
519
- const feedbackItems = react.useMemo(
520
- () => chunkZBHLMQTS_cjs.getMetaImageValidation(hasImage, seoParent),
996
+ const feedbackItems = _react.useMemo.call(void 0,
997
+ () => _chunkY46ACXM4cjs.getMetaImageValidation.call(void 0, hasImage, seoParent),
521
998
  [hasImage, seoParent]
522
999
  );
523
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1000
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
524
1001
  renderDefault(props),
525
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
526
- /* @__PURE__ */ jsxRuntime.jsx(
1002
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1003
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
527
1004
  "div",
528
1005
  {
529
1006
  style: {
@@ -534,11 +1011,17 @@ var MetaImage = (props) => {
534
1011
  }
535
1012
  }
536
1013
  ),
537
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1014
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
538
1015
  ] }, item.text)) })
539
1016
  ] });
540
1017
  };
541
1018
  var MetaImage_default = MetaImage;
1019
+
1020
+ // src/components/meta/MetaTagsPreview.tsx
1021
+
1022
+
1023
+
1024
+
542
1025
  function resolveImageUrl(asset, projectId, dataset) {
543
1026
  const ref = asset == null ? void 0 : asset._ref;
544
1027
  if (!ref) return null;
@@ -550,13 +1033,13 @@ function resolveImageUrl(asset, projectId, dataset) {
550
1033
  }
551
1034
  var MetaTagsPreview = (props) => {
552
1035
  const { path } = props;
553
- const [expanded, setExpanded] = react.useState(false);
554
- const [copyLabel, setCopyLabel] = react.useState("Copy");
555
- const { scheme } = sanity.useColorScheme();
556
- const seoFields = sanity.useFormValue([path[0]]);
557
- const client = sanity.useClient({ apiVersion: "2024-01-01" });
1036
+ const [expanded, setExpanded] = _react.useState.call(void 0, false);
1037
+ const [copyLabel, setCopyLabel] = _react.useState.call(void 0, "Copy");
1038
+ const { scheme } = _sanity.useColorScheme.call(void 0, );
1039
+ const seoFields = _sanity.useFormValue.call(void 0, [path[0]]);
1040
+ const client = _sanity.useClient.call(void 0, { apiVersion: "2024-01-01" });
558
1041
  const { projectId = "", dataset = "" } = client.config();
559
- const rawHtml = react.useMemo(() => {
1042
+ const rawHtml = _react.useMemo.call(void 0, () => {
560
1043
  var _a, _b, _c, _d, _e, _f, _g;
561
1044
  const lines = [];
562
1045
  lines.push('<meta charset="UTF-8" />');
@@ -612,8 +1095,8 @@ var MetaTagsPreview = (props) => {
612
1095
  }
613
1096
  return lines.join("\n");
614
1097
  }, [seoFields, projectId, dataset]);
615
- const tagCount = react.useMemo(() => rawHtml.split("\n").filter(Boolean).length, [rawHtml]);
616
- const tokens = react.useMemo(() => chunkB5IVI5LP_cjs.tokenizeHtml(rawHtml, scheme), [rawHtml, scheme]);
1098
+ const tagCount = _react.useMemo.call(void 0, () => rawHtml.split("\n").filter(Boolean).length, [rawHtml]);
1099
+ const tokens = _react.useMemo.call(void 0, () => _chunk5XTQRILLcjs.tokenizeHtml.call(void 0, rawHtml, scheme), [rawHtml, scheme]);
617
1100
  const handleCopy = () => {
618
1101
  navigator.clipboard.writeText(rawHtml).then(() => {
619
1102
  setCopyLabel("Copied!");
@@ -626,16 +1109,16 @@ var MetaTagsPreview = (props) => {
626
1109
  const headerBg = isDark ? "#21262d" : "#f0f2f4";
627
1110
  const headerBorder = isDark ? "#30363d" : "#d0d7de";
628
1111
  const headerText = isDark ? "#e6edf3" : "#24292f";
629
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 3, radius: 2, tone: "default", border: true, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
630
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", justify: "space-between", gap: 3, children: [
631
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "semibold", size: 1, children: "Meta Tags Preview" }),
632
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 2, align: "center", children: [
633
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: 0, muted: true, children: [
1112
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Card, { padding: 3, radius: 2, tone: "default", border: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1113
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { align: "center", justify: "space-between", gap: 3, children: [
1114
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "semibold", size: 1, children: "Meta Tags Preview" }),
1115
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { gap: 2, align: "center", children: [
1116
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Text, { size: 0, muted: true, children: [
634
1117
  tagCount,
635
1118
  " tags generated"
636
1119
  ] }),
637
- /* @__PURE__ */ jsxRuntime.jsx(
638
- ui.Button,
1120
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1121
+ _ui.Button,
639
1122
  {
640
1123
  text: copyLabel,
641
1124
  tone: "default",
@@ -647,7 +1130,7 @@ var MetaTagsPreview = (props) => {
647
1130
  )
648
1131
  ] })
649
1132
  ] }),
650
- /* @__PURE__ */ jsxRuntime.jsxs(
1133
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
651
1134
  "button",
652
1135
  {
653
1136
  type: "button",
@@ -668,12 +1151,12 @@ var MetaTagsPreview = (props) => {
668
1151
  color: headerText
669
1152
  },
670
1153
  children: [
671
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 10 }, children: expanded ? "\u25B2" : "\u25BC" }),
1154
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 10 }, children: expanded ? "\u25B2" : "\u25BC" }),
672
1155
  expanded ? "Hide tags" : "Show tags"
673
1156
  ]
674
1157
  }
675
1158
  ),
676
- expanded && /* @__PURE__ */ jsxRuntime.jsxs(
1159
+ expanded && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
677
1160
  "div",
678
1161
  {
679
1162
  style: {
@@ -682,7 +1165,7 @@ var MetaTagsPreview = (props) => {
682
1165
  overflow: "hidden"
683
1166
  },
684
1167
  children: [
685
- /* @__PURE__ */ jsxRuntime.jsxs(
1168
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
686
1169
  "div",
687
1170
  {
688
1171
  style: {
@@ -694,7 +1177,7 @@ var MetaTagsPreview = (props) => {
694
1177
  gap: 6
695
1178
  },
696
1179
  children: [
697
- /* @__PURE__ */ jsxRuntime.jsx(
1180
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
698
1181
  "span",
699
1182
  {
700
1183
  style: {
@@ -706,12 +1189,12 @@ var MetaTagsPreview = (props) => {
706
1189
  }
707
1190
  }
708
1191
  ),
709
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 11, color: headerText, fontFamily: "monospace" }, children: "HTML" })
1192
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 11, color: headerText, fontFamily: "monospace" }, children: "HTML" })
710
1193
  ]
711
1194
  }
712
1195
  ),
713
- /* @__PURE__ */ jsxRuntime.jsx(
714
- ui.Box,
1196
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1197
+ _ui.Box,
715
1198
  {
716
1199
  as: "pre",
717
1200
  padding: 3,
@@ -726,7 +1209,7 @@ var MetaTagsPreview = (props) => {
726
1209
  wordBreak: "break-word",
727
1210
  backgroundColor: codeBg
728
1211
  },
729
- children: tokens.map((token, idx) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: token.color }, children: token.text }, idx))
1212
+ children: tokens.map((token, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { color: token.color }, children: token.text }, idx))
730
1213
  }
731
1214
  )
732
1215
  ]
@@ -735,20 +1218,26 @@ var MetaTagsPreview = (props) => {
735
1218
  ] }) });
736
1219
  };
737
1220
  var MetaTagsPreview_default = MetaTagsPreview;
1221
+
1222
+ // src/components/meta/MetaTitle.tsx
1223
+
1224
+
1225
+
1226
+
738
1227
  var MetaTitle = (props) => {
739
1228
  var _a, _b, _c;
740
- const { value, renderDefault, path, schemaType } = props;
1229
+ const { value, renderDefault, path, schemaType, onChange } = props;
741
1230
  const { options } = schemaType;
742
- const parent = sanity.useFormValue([path[0]]);
1231
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
743
1232
  const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
744
- const keywords = react.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
745
- const rootDoc = (_a = sanity.useFormValue([])) != null ? _a : {};
746
- const client = sanity.useClient({ apiVersion: (_b = options == null ? void 0 : options.apiVersion) != null ? _b : "2024-01-01" });
747
- const [groqTitleSuffix, setGroqTitleSuffix] = react.useState("");
748
- const [isDuplicateTitle, setIsDuplicateTitle] = react.useState(false);
1233
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1234
+ const rootDoc = (_a = _sanity.useFormValue.call(void 0, [])) != null ? _a : {};
1235
+ const client = _sanity.useClient.call(void 0, { apiVersion: (_b = options == null ? void 0 : options.apiVersion) != null ? _b : "2024-01-01" });
1236
+ const [groqTitleSuffix, setGroqTitleSuffix] = _react.useState.call(void 0, "");
1237
+ const [isDuplicateTitle, setIsDuplicateTitle] = _react.useState.call(void 0, false);
749
1238
  const titleSuffixQuery = options == null ? void 0 : options.titleSuffixQuery;
750
1239
  const titleSuffixOption = options == null ? void 0 : options.titleSuffix;
751
- react.useEffect(() => {
1240
+ _react.useEffect.call(void 0, () => {
752
1241
  if (!titleSuffixQuery) return;
753
1242
  client.fetch(titleSuffixQuery).then((result) => {
754
1243
  setGroqTitleSuffix(result === null || result === void 0 ? "" : String(result));
@@ -757,7 +1246,7 @@ var MetaTitle = (props) => {
757
1246
  });
758
1247
  }, [titleSuffixQuery, client]);
759
1248
  const currentDocId = (_c = rootDoc._id) != null ? _c : "";
760
- react.useEffect(() => {
1249
+ _react.useEffect.call(void 0, () => {
761
1250
  if (!(value == null ? void 0 : value.trim()) || !currentDocId) {
762
1251
  setIsDuplicateTitle(false);
763
1252
  return () => {
@@ -771,7 +1260,7 @@ var MetaTitle = (props) => {
771
1260
  }, 600);
772
1261
  return () => clearTimeout(timer);
773
1262
  }, [value, client, currentDocId]);
774
- const resolvedSuffix = react.useMemo(() => {
1263
+ const resolvedSuffix = _react.useMemo.call(void 0, () => {
775
1264
  if (titleSuffixQuery) return groqTitleSuffix;
776
1265
  if (!titleSuffixOption) return "";
777
1266
  if (typeof titleSuffixOption === "function") {
@@ -780,15 +1269,24 @@ var MetaTitle = (props) => {
780
1269
  return titleSuffixOption;
781
1270
  }, [titleSuffixQuery, groqTitleSuffix, titleSuffixOption, rootDoc]);
782
1271
  const suffixLength = resolvedSuffix ? resolvedSuffix.length + 3 : 0;
783
- const feedbackItems = react.useMemo(
784
- () => chunkZBHLMQTS_cjs.getMetaTitleValidationMessages(value || "", keywords, isParentseoField, suffixLength),
1272
+ const feedbackItems = _react.useMemo.call(void 0,
1273
+ () => _chunkY46ACXM4cjs.getMetaTitleValidationMessages.call(void 0, value || "", keywords, isParentseoField, suffixLength),
785
1274
  [value, keywords, isParentseoField, suffixLength]
786
1275
  );
787
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1276
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
788
1277
  renderDefault(props),
789
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
790
- feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
791
- /* @__PURE__ */ jsxRuntime.jsx(
1278
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1279
+ SeoGenButton,
1280
+ {
1281
+ field: "title",
1282
+ ai: options == null ? void 0 : options.ai,
1283
+ seoFieldPath: String(path[0]),
1284
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1285
+ }
1286
+ ),
1287
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 2, children: [
1288
+ feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1289
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
792
1290
  "div",
793
1291
  {
794
1292
  style: {
@@ -799,10 +1297,10 @@ var MetaTitle = (props) => {
799
1297
  }
800
1298
  }
801
1299
  ),
802
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1300
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
803
1301
  ] }, item.text)),
804
- isDuplicateTitle && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
805
- /* @__PURE__ */ jsxRuntime.jsx(
1302
+ isDuplicateTitle && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1303
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
806
1304
  "div",
807
1305
  {
808
1306
  style: {
@@ -813,7 +1311,7 @@ var MetaTitle = (props) => {
813
1311
  }
814
1312
  }
815
1313
  ),
816
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: "Duplicate meta title \u2014 another published document uses this exact title." })
1314
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: "Duplicate meta title \u2014 another published document uses this exact title." })
817
1315
  ] })
818
1316
  ] })
819
1317
  ] });
@@ -821,6 +1319,10 @@ var MetaTitle = (props) => {
821
1319
  var MetaTitle_default = MetaTitle;
822
1320
 
823
1321
  // src/utils/fieldsUtils.ts
1322
+ function withLicense(ai, licenseKey) {
1323
+ if (!ai) return void 0;
1324
+ return licenseKey ? _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, ai), { _licenseKey: licenseKey }) : ai;
1325
+ }
824
1326
  var DEFAULT_FIELD_INFO = {
825
1327
  title: {
826
1328
  title: "Meta Title",
@@ -958,19 +1460,38 @@ var getFieldHiddenFunction = (fieldName, config) => {
958
1460
  var isEmpty = (value) => {
959
1461
  return value === null || value === void 0 || typeof value === "string" && value.trim() === "" || Array.isArray(value) && value.length === 0 || typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
960
1462
  };
1463
+
1464
+ // src/schemas/types/openGraph/index.ts
1465
+
1466
+
1467
+ // src/components/openGraph/OgDescription.tsx
1468
+
1469
+
1470
+
1471
+
961
1472
  var OgDescription = (props) => {
962
- const { value, renderDefault, path } = props;
963
- const parent = sanity.useFormValue([path[0]]);
1473
+ const { value, renderDefault, path, schemaType, onChange } = props;
1474
+ const { options } = schemaType;
1475
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
964
1476
  const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
965
- const keywords = react.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
966
- const feedbackItems = react.useMemo(
967
- () => chunkZBHLMQTS_cjs.getOgDescriptionValidation(value || "", keywords, isParentseoField),
1477
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1478
+ const feedbackItems = _react.useMemo.call(void 0,
1479
+ () => _chunkY46ACXM4cjs.getOgDescriptionValidation.call(void 0, value || "", keywords, isParentseoField),
968
1480
  [value, keywords, isParentseoField]
969
1481
  );
970
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1482
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
971
1483
  renderDefault(props),
972
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
973
- /* @__PURE__ */ jsxRuntime.jsx(
1484
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1485
+ SeoGenButton,
1486
+ {
1487
+ field: "ogDescription",
1488
+ ai: options == null ? void 0 : options.ai,
1489
+ seoFieldPath: String(path[0]),
1490
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1491
+ }
1492
+ ),
1493
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1494
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
974
1495
  "div",
975
1496
  {
976
1497
  style: {
@@ -981,25 +1502,31 @@ var OgDescription = (props) => {
981
1502
  }
982
1503
  }
983
1504
  ),
984
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1505
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
985
1506
  ] }, item.text)) })
986
1507
  ] });
987
1508
  };
988
1509
  var OgDescription_default = OgDescription;
1510
+
1511
+ // src/components/openGraph/OgImage.tsx
1512
+
1513
+
1514
+
1515
+
989
1516
  var OgImage = (props) => {
990
1517
  const { value, renderDefault, path } = props;
991
- const seoParent = sanity.useFormValue([path[0]]);
1518
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
992
1519
  const imgValue = value;
993
1520
  const hasImage = !!(imgValue == null ? void 0 : imgValue.asset);
994
1521
  const altText = imgValue == null ? void 0 : imgValue.alt;
995
- const feedbackItems = react.useMemo(
996
- () => chunkZBHLMQTS_cjs.getOgImageValidation(hasImage, altText, seoParent),
1522
+ const feedbackItems = _react.useMemo.call(void 0,
1523
+ () => _chunkY46ACXM4cjs.getOgImageValidation.call(void 0, hasImage, altText, seoParent),
997
1524
  [hasImage, altText, seoParent]
998
1525
  );
999
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1526
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1000
1527
  renderDefault(props),
1001
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1002
- /* @__PURE__ */ jsxRuntime.jsx(
1528
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1529
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1003
1530
  "div",
1004
1531
  {
1005
1532
  style: {
@@ -1010,19 +1537,25 @@ var OgImage = (props) => {
1010
1537
  }
1011
1538
  }
1012
1539
  ),
1013
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1540
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1014
1541
  ] }, item.text)) })
1015
1542
  ] });
1016
1543
  };
1017
1544
  var OgImage_default = OgImage;
1545
+
1546
+ // src/components/openGraph/OgImageUrl.tsx
1547
+
1548
+
1549
+
1550
+
1018
1551
  var OgImageUrl = (props) => {
1019
1552
  const { value, renderDefault, path } = props;
1020
- const seoParent = sanity.useFormValue([path[0]]);
1021
- const feedbackItems = react.useMemo(() => chunkZBHLMQTS_cjs.getOgImageUrlValidation(value, seoParent), [value, seoParent]);
1022
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1553
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
1554
+ const feedbackItems = _react.useMemo.call(void 0, () => _chunkY46ACXM4cjs.getOgImageUrlValidation.call(void 0, value, seoParent), [value, seoParent]);
1555
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1023
1556
  renderDefault(props),
1024
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1025
- /* @__PURE__ */ jsxRuntime.jsx(
1557
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1558
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1026
1559
  "div",
1027
1560
  {
1028
1561
  style: {
@@ -1033,24 +1566,40 @@ var OgImageUrl = (props) => {
1033
1566
  }
1034
1567
  }
1035
1568
  ),
1036
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1569
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1037
1570
  ] }, item.text)) })
1038
1571
  ] });
1039
1572
  };
1040
1573
  var OgImageUrl_default = OgImageUrl;
1574
+
1575
+ // src/components/openGraph/OgTitle.tsx
1576
+
1577
+
1578
+
1579
+
1041
1580
  var OgTitle = (props) => {
1042
- const { value, renderDefault, path } = props;
1043
- const parent = sanity.useFormValue([path[0]]);
1581
+ const { value, renderDefault, path, schemaType, onChange } = props;
1582
+ const { options } = schemaType;
1583
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
1044
1584
  const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
1045
- const keywords = react.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1046
- const feedbackItems = react.useMemo(
1047
- () => chunkZBHLMQTS_cjs.getOgTitleValidation(value || "", keywords, isParentseoField),
1585
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1586
+ const feedbackItems = _react.useMemo.call(void 0,
1587
+ () => _chunkY46ACXM4cjs.getOgTitleValidation.call(void 0, value || "", keywords, isParentseoField),
1048
1588
  [value, keywords, isParentseoField]
1049
1589
  );
1050
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1590
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1051
1591
  renderDefault(props),
1052
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1053
- /* @__PURE__ */ jsxRuntime.jsx(
1592
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1593
+ SeoGenButton,
1594
+ {
1595
+ field: "ogTitle",
1596
+ ai: options == null ? void 0 : options.ai,
1597
+ seoFieldPath: String(path[0]),
1598
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1599
+ }
1600
+ ),
1601
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1602
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1054
1603
  "div",
1055
1604
  {
1056
1605
  style: {
@@ -1061,7 +1610,7 @@ var OgTitle = (props) => {
1061
1610
  }
1062
1611
  }
1063
1612
  ),
1064
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1613
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1065
1614
  ] }, item.text)) })
1066
1615
  ] });
1067
1616
  };
@@ -1069,29 +1618,29 @@ var OgTitle_default = OgTitle;
1069
1618
 
1070
1619
  // src/schemas/types/openGraph/index.ts
1071
1620
  function openGraph(config = {}) {
1072
- return sanity.defineType({
1621
+ return _sanity.defineType.call(void 0, {
1073
1622
  name: "openGraph",
1074
1623
  title: "Open Graph Settings",
1075
1624
  type: "object",
1076
1625
  fields: [
1077
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1626
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1078
1627
  name: "url",
1079
1628
  type: "url"
1080
1629
  }, getFieldInfo("openGraphUrl", config.fieldOverrides)), {
1081
1630
  hidden: getFieldHiddenFunction("openGraphUrl", config),
1082
1631
  description: "The canonical URL of the page. This should be the full URL including protocol (https://)."
1083
1632
  })),
1084
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1633
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1085
1634
  name: "title"
1086
1635
  }, getFieldInfo("openGraphTitle", config.fieldOverrides)), {
1087
1636
  type: "string",
1088
1637
  hidden: getFieldHiddenFunction("openGraphTitle", config),
1089
1638
  components: {
1090
1639
  input: OgTitle_default
1091
- // Can also wrap with a string input + preview
1092
- }
1640
+ },
1641
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
1093
1642
  })),
1094
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1643
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1095
1644
  name: "description"
1096
1645
  }, getFieldInfo("openGraphDescription", config.fieldOverrides)), {
1097
1646
  type: "text",
@@ -1099,16 +1648,16 @@ function openGraph(config = {}) {
1099
1648
  hidden: getFieldHiddenFunction("openGraphDescription", config),
1100
1649
  components: {
1101
1650
  input: OgDescription_default
1102
- // Can also wrap with a text area + preview
1103
- }
1651
+ },
1652
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
1104
1653
  })),
1105
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1654
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1106
1655
  name: "siteName"
1107
1656
  }, getFieldInfo("openGraphSiteName", config.fieldOverrides)), {
1108
1657
  type: "string",
1109
1658
  hidden: getFieldHiddenFunction("openGraphSiteName", config)
1110
1659
  })),
1111
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1660
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1112
1661
  name: "type"
1113
1662
  }, getFieldInfo("openGraphType", config.fieldOverrides)), {
1114
1663
  type: "string",
@@ -1127,7 +1676,7 @@ function openGraph(config = {}) {
1127
1676
  hidden: getFieldHiddenFunction("openGraphType", config),
1128
1677
  initialValue: "website"
1129
1678
  })),
1130
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1679
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1131
1680
  name: "imageType"
1132
1681
  }, getFieldInfo("openGraphImageType", config.fieldOverrides)), {
1133
1682
  type: "string",
@@ -1140,7 +1689,7 @@ function openGraph(config = {}) {
1140
1689
  hidden: getFieldHiddenFunction("openGraphImage", config),
1141
1690
  initialValue: "upload"
1142
1691
  })),
1143
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1692
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1144
1693
  name: "image"
1145
1694
  }, getFieldInfo("openGraphImage", config.fieldOverrides)), {
1146
1695
  type: "image",
@@ -1151,7 +1700,7 @@ function openGraph(config = {}) {
1151
1700
  input: OgImage_default
1152
1701
  },
1153
1702
  fields: [
1154
- sanity.defineField({
1703
+ _sanity.defineField.call(void 0, {
1155
1704
  name: "alt",
1156
1705
  title: "Image Alt Text",
1157
1706
  type: "string",
@@ -1165,7 +1714,7 @@ function openGraph(config = {}) {
1165
1714
  return typeof hiddenFn === "function" ? hiddenFn(context) : hiddenFn;
1166
1715
  }
1167
1716
  })),
1168
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1717
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1169
1718
  name: "imageUrl"
1170
1719
  }, getFieldInfo("openGraphImageUrl", config.fieldOverrides)), {
1171
1720
  type: "url",
@@ -1182,19 +1731,38 @@ function openGraph(config = {}) {
1182
1731
  ]
1183
1732
  });
1184
1733
  }
1734
+
1735
+ // src/schemas/types/twitter/index.ts
1736
+
1737
+
1738
+ // src/components/twitter/twitterDescription.tsx
1739
+
1740
+
1741
+
1742
+
1185
1743
  var TwitterDescription = (props) => {
1186
- const { value, renderDefault, path } = props;
1187
- const parent = sanity.useFormValue([path[0]]);
1744
+ const { value, renderDefault, path, schemaType, onChange } = props;
1745
+ const { options } = schemaType;
1746
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
1188
1747
  const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
1189
- const keywords = react.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1190
- const feedbackItems = react.useMemo(
1191
- () => chunkZBHLMQTS_cjs.getTwitterDescriptionValidation(value || "", keywords, isParentseoField),
1748
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1749
+ const feedbackItems = _react.useMemo.call(void 0,
1750
+ () => _chunkY46ACXM4cjs.getTwitterDescriptionValidation.call(void 0, value || "", keywords, isParentseoField),
1192
1751
  [value, keywords, isParentseoField]
1193
1752
  );
1194
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1753
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1195
1754
  renderDefault(props),
1196
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1197
- /* @__PURE__ */ jsxRuntime.jsx(
1755
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1756
+ SeoGenButton,
1757
+ {
1758
+ field: "twitterDescription",
1759
+ ai: options == null ? void 0 : options.ai,
1760
+ seoFieldPath: String(path[0]),
1761
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1762
+ }
1763
+ ),
1764
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1765
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1198
1766
  "div",
1199
1767
  {
1200
1768
  style: {
@@ -1205,25 +1773,31 @@ var TwitterDescription = (props) => {
1205
1773
  }
1206
1774
  }
1207
1775
  ),
1208
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1776
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1209
1777
  ] }, item.text)) })
1210
1778
  ] });
1211
1779
  };
1212
1780
  var twitterDescription_default = TwitterDescription;
1781
+
1782
+ // src/components/twitter/TwitterImage.tsx
1783
+
1784
+
1785
+
1786
+
1213
1787
  var TwitterImage = (props) => {
1214
1788
  const { value, renderDefault, path } = props;
1215
- const seoParent = sanity.useFormValue([path[0]]);
1789
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
1216
1790
  const imgValue = value;
1217
1791
  const hasImage = !!(imgValue == null ? void 0 : imgValue.asset);
1218
1792
  const altText = imgValue == null ? void 0 : imgValue.alt;
1219
- const feedbackItems = react.useMemo(
1220
- () => chunkZBHLMQTS_cjs.getTwitterImageValidation(hasImage, altText, seoParent),
1793
+ const feedbackItems = _react.useMemo.call(void 0,
1794
+ () => _chunkY46ACXM4cjs.getTwitterImageValidation.call(void 0, hasImage, altText, seoParent),
1221
1795
  [hasImage, altText, seoParent]
1222
1796
  );
1223
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1797
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1224
1798
  renderDefault(props),
1225
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1226
- /* @__PURE__ */ jsxRuntime.jsx(
1799
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1800
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1227
1801
  "div",
1228
1802
  {
1229
1803
  style: {
@@ -1234,22 +1808,28 @@ var TwitterImage = (props) => {
1234
1808
  }
1235
1809
  }
1236
1810
  ),
1237
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1811
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1238
1812
  ] }, item.text)) })
1239
1813
  ] });
1240
1814
  };
1241
1815
  var TwitterImage_default = TwitterImage;
1816
+
1817
+ // src/components/twitter/TwitterImageUrl.tsx
1818
+
1819
+
1820
+
1821
+
1242
1822
  var TwitterImageUrl = (props) => {
1243
1823
  const { value, renderDefault, path } = props;
1244
- const seoParent = sanity.useFormValue([path[0]]);
1245
- const feedbackItems = react.useMemo(
1246
- () => chunkZBHLMQTS_cjs.getTwitterImageUrlValidation(value, seoParent),
1824
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
1825
+ const feedbackItems = _react.useMemo.call(void 0,
1826
+ () => _chunkY46ACXM4cjs.getTwitterImageUrlValidation.call(void 0, value, seoParent),
1247
1827
  [value, seoParent]
1248
1828
  );
1249
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1829
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1250
1830
  renderDefault(props),
1251
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1252
- /* @__PURE__ */ jsxRuntime.jsx(
1831
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1832
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1253
1833
  "div",
1254
1834
  {
1255
1835
  style: {
@@ -1260,24 +1840,40 @@ var TwitterImageUrl = (props) => {
1260
1840
  }
1261
1841
  }
1262
1842
  ),
1263
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1843
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1264
1844
  ] }, item.text)) })
1265
1845
  ] });
1266
1846
  };
1267
1847
  var TwitterImageUrl_default = TwitterImageUrl;
1848
+
1849
+ // src/components/twitter/twitterTitle.tsx
1850
+
1851
+
1852
+
1853
+
1268
1854
  var TwitterTitle = (props) => {
1269
- const { value, renderDefault, path } = props;
1270
- const parent = sanity.useFormValue([path[0]]);
1855
+ const { value, renderDefault, path, schemaType, onChange } = props;
1856
+ const { options } = schemaType;
1857
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
1271
1858
  const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
1272
- const keywords = react.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1273
- const feedbackItems = react.useMemo(
1274
- () => chunkZBHLMQTS_cjs.getTwitterTitleValidation(value || "", keywords, isParentseoField),
1859
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1860
+ const feedbackItems = _react.useMemo.call(void 0,
1861
+ () => _chunkY46ACXM4cjs.getTwitterTitleValidation.call(void 0, value || "", keywords, isParentseoField),
1275
1862
  [value, keywords, isParentseoField]
1276
1863
  );
1277
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1864
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1278
1865
  renderDefault(props),
1279
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1280
- /* @__PURE__ */ jsxRuntime.jsx(
1866
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1867
+ SeoGenButton,
1868
+ {
1869
+ field: "twitterTitle",
1870
+ ai: options == null ? void 0 : options.ai,
1871
+ seoFieldPath: String(path[0]),
1872
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1873
+ }
1874
+ ),
1875
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1876
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1281
1877
  "div",
1282
1878
  {
1283
1879
  style: {
@@ -1288,7 +1884,7 @@ var TwitterTitle = (props) => {
1288
1884
  }
1289
1885
  }
1290
1886
  ),
1291
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1887
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1292
1888
  ] }, item.text)) })
1293
1889
  ] });
1294
1890
  };
@@ -1296,12 +1892,12 @@ var twitterTitle_default = TwitterTitle;
1296
1892
 
1297
1893
  // src/schemas/types/twitter/index.ts
1298
1894
  function twitter(config = {}) {
1299
- return sanity.defineType({
1895
+ return _sanity.defineType.call(void 0, {
1300
1896
  name: "twitter",
1301
1897
  title: "X (Formerly Twitter)",
1302
1898
  type: "object",
1303
1899
  fields: [
1304
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1900
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1305
1901
  name: "card"
1306
1902
  }, getFieldInfo("twitterCard", config.fieldOverrides)), {
1307
1903
  type: "string",
@@ -1317,28 +1913,29 @@ function twitter(config = {}) {
1317
1913
  initialValue: "summary_large_image"
1318
1914
  // good default
1319
1915
  })),
1320
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1916
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1321
1917
  name: "site"
1322
1918
  }, getFieldInfo("twitterSite", config.fieldOverrides)), {
1323
1919
  type: "string",
1324
1920
  hidden: getFieldHiddenFunction("twitterSite", config)
1325
1921
  })),
1326
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1922
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1327
1923
  name: "creator",
1328
1924
  type: "string"
1329
1925
  }, getFieldInfo("twitterCreator", config.fieldOverrides)), {
1330
1926
  hidden: getFieldHiddenFunction("twitterCreator", config)
1331
1927
  })),
1332
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1928
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1333
1929
  name: "title",
1334
1930
  type: "string"
1335
1931
  }, getFieldInfo("twitterTitle", config.fieldOverrides)), {
1336
1932
  hidden: getFieldHiddenFunction("twitterTitle", config),
1337
1933
  components: {
1338
1934
  input: twitterTitle_default
1339
- }
1935
+ },
1936
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
1340
1937
  })),
1341
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1938
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1342
1939
  name: "description",
1343
1940
  type: "text",
1344
1941
  rows: 3
@@ -1346,9 +1943,10 @@ function twitter(config = {}) {
1346
1943
  hidden: getFieldHiddenFunction("twitterDescription", config),
1347
1944
  components: {
1348
1945
  input: twitterDescription_default
1349
- }
1946
+ },
1947
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
1350
1948
  })),
1351
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1949
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1352
1950
  name: "imageType"
1353
1951
  }, getFieldInfo("twitterImageType", config.fieldOverrides)), {
1354
1952
  type: "string",
@@ -1361,7 +1959,7 @@ function twitter(config = {}) {
1361
1959
  hidden: getFieldHiddenFunction("twitterImage", config),
1362
1960
  initialValue: "upload"
1363
1961
  })),
1364
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1962
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1365
1963
  name: "image"
1366
1964
  }, getFieldInfo("twitterImage", config.fieldOverrides)), {
1367
1965
  type: "image",
@@ -1372,7 +1970,7 @@ function twitter(config = {}) {
1372
1970
  input: TwitterImage_default
1373
1971
  },
1374
1972
  fields: [
1375
- sanity.defineField({
1973
+ _sanity.defineField.call(void 0, {
1376
1974
  name: "alt",
1377
1975
  title: "Image Alt Text",
1378
1976
  type: "string",
@@ -1386,7 +1984,7 @@ function twitter(config = {}) {
1386
1984
  return typeof hiddenFn === "function" ? hiddenFn(context) : hiddenFn;
1387
1985
  }
1388
1986
  })),
1389
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1987
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1390
1988
  name: "imageUrl"
1391
1989
  }, getFieldInfo("twitterImageUrl", config.fieldOverrides)), {
1392
1990
  type: "url",
@@ -1405,8 +2003,8 @@ function twitter(config = {}) {
1405
2003
  }
1406
2004
 
1407
2005
  // src/schemas/index.ts
1408
- var LazySeoPreview = react.lazy(() => import('./SeoPreview-3EXR6FD4.cjs'));
1409
- var SeoPreviewWrapper = (props) => react.createElement(react.Suspense, { fallback: null }, react.createElement(LazySeoPreview, props));
2006
+ var LazySeoPreview = _react.lazy.call(void 0, () => Promise.resolve().then(() => _interopRequireWildcard(require("./SeoPreview-LMZAWWOE.cjs"))));
2007
+ var SeoPreviewWrapper = (props) => _react.createElement.call(void 0, _react.Suspense, { fallback: null }, _react.createElement.call(void 0, LazySeoPreview, props));
1410
2008
  function buildFieldGroupMap(groups) {
1411
2009
  const map = /* @__PURE__ */ new Map();
1412
2010
  for (const g of groups) {
@@ -1438,20 +2036,89 @@ function withGroup(field, fieldGroupMap) {
1438
2036
  if (!fieldGroupMap) return field;
1439
2037
  const groups = fieldGroupMap.get(field.name);
1440
2038
  if (!groups || groups.length === 0) return field;
1441
- return chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({}, field), { group: groups.length === 1 ? groups[0] : groups });
2039
+ return _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, field), { group: groups.length === 1 ? groups[0] : groups });
2040
+ }
2041
+ function shouldShowPreviewField(seoPreview) {
2042
+ if (typeof seoPreview === "boolean") return seoPreview;
2043
+ if (typeof seoPreview === "object") return !isEmpty(seoPreview);
2044
+ return false;
2045
+ }
2046
+ function getSeoPreviewSuffixOptions(seoPreview) {
2047
+ if (typeof seoPreview !== "object" || !seoPreview) return {};
2048
+ const extra = {};
2049
+ if (seoPreview.titleSuffix) extra.titleSuffix = seoPreview.titleSuffix;
2050
+ if (seoPreview.titleSuffixQuery) extra.titleSuffixQuery = seoPreview.titleSuffixQuery;
2051
+ return extra;
2052
+ }
2053
+ function getPreviewFieldOptions(config) {
2054
+ const seoPreview = config.seoPreview;
2055
+ const extra = {};
2056
+ if (typeof seoPreview === "object" && seoPreview) {
2057
+ if (seoPreview.prefix) extra.prefix = seoPreview.prefix;
2058
+ if (seoPreview.titleSuffixInheritColor) {
2059
+ extra.titleSuffixInheritColor = seoPreview.titleSuffixInheritColor;
2060
+ }
2061
+ }
2062
+ return _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
2063
+ baseUrl: config.baseUrl || "https://www.example.com"
2064
+ }, config.apiVersion ? { apiVersion: config.apiVersion } : {}), getSeoPreviewSuffixOptions(seoPreview)), extra);
2065
+ }
2066
+ function getAiOption(config) {
2067
+ return config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {};
2068
+ }
2069
+ function getTitleFieldOptions(config) {
2070
+ return _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.apiVersion ? { apiVersion: config.apiVersion } : {}), getSeoPreviewSuffixOptions(config.seoPreview)), getAiOption(config));
2071
+ }
2072
+ function buildGeoChecklistField(config, fieldGroupMap) {
2073
+ if (config.geo === false) return [];
2074
+ return [
2075
+ withGroup(
2076
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
2077
+ name: "geoChecklist"
2078
+ }, getFieldInfo("geoChecklist", config.fieldOverrides)), {
2079
+ type: "string",
2080
+ readOnly: true,
2081
+ components: {
2082
+ input: GEOChecklist_default
2083
+ },
2084
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.licenseKey ? { licenseKey: config.licenseKey } : {}),
2085
+ hidden: getFieldHiddenFunction("geoChecklist", config)
2086
+ })),
2087
+ fieldGroupMap
2088
+ )
2089
+ ];
2090
+ }
2091
+ function buildMetaTagsPreviewField(config, fieldGroupMap) {
2092
+ if (config.metaTagsPreview === false) return [];
2093
+ return [
2094
+ withGroup(
2095
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
2096
+ name: "metaTagsPreview"
2097
+ }, getFieldInfo("metaTagsPreview", config.fieldOverrides)), {
2098
+ type: "string",
2099
+ readOnly: true,
2100
+ components: {
2101
+ input: MetaTagsPreview_default
2102
+ },
2103
+ hidden: getFieldHiddenFunction("metaTagsPreview", config)
2104
+ })),
2105
+ fieldGroupMap
2106
+ )
2107
+ ];
1442
2108
  }
1443
2109
  function seoFieldsSchema(config = {}) {
2110
+ var _a;
1444
2111
  const groupsCfg = config.fieldGroups;
1445
2112
  const fieldGroupMap = (groupsCfg == null ? void 0 : groupsCfg.length) ? buildFieldGroupMap(groupsCfg) : void 0;
1446
2113
  const sanityGroups = (groupsCfg == null ? void 0 : groupsCfg.length) ? toSanityGroups(groupsCfg) : void 0;
1447
- return sanity.defineType(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2114
+ return _sanity.defineType.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1448
2115
  name: "seoFields",
1449
2116
  title: "SEO Fields",
1450
2117
  type: "object"
1451
2118
  }, sanityGroups ? { groups: sanityGroups } : {}), {
1452
2119
  fields: [
1453
2120
  withGroup(
1454
- sanity.defineField({
2121
+ _sanity.defineField.call(void 0, {
1455
2122
  name: "robots",
1456
2123
  title: "Robots Settings",
1457
2124
  type: "robots",
@@ -1460,16 +2127,14 @@ function seoFieldsSchema(config = {}) {
1460
2127
  fieldGroupMap
1461
2128
  ),
1462
2129
  // 👇 conditionally spread preview field
1463
- ...typeof config.seoPreview === "boolean" && config.seoPreview || typeof config.seoPreview === "object" && !isEmpty(config.seoPreview) ? [
2130
+ ...shouldShowPreviewField(config.seoPreview) ? [
1464
2131
  withGroup(
1465
- sanity.defineField({
2132
+ _sanity.defineField.call(void 0, {
1466
2133
  name: "preview",
1467
2134
  title: "SEO Preview",
1468
2135
  type: "string",
1469
2136
  components: { input: SeoPreviewWrapper },
1470
- options: chunk254YHUN3_cjs.__spreadValues(chunk254YHUN3_cjs.__spreadValues(chunk254YHUN3_cjs.__spreadValues(chunk254YHUN3_cjs.__spreadValues(chunk254YHUN3_cjs.__spreadValues({
1471
- baseUrl: config.baseUrl || "https://www.example.com"
1472
- }, config.apiVersion ? { apiVersion: config.apiVersion } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.prefix ? { prefix: config.seoPreview.prefix } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.titleSuffix ? { titleSuffix: config.seoPreview.titleSuffix } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.titleSuffixInheritColor ? { titleSuffixInheritColor: config.seoPreview.titleSuffixInheritColor } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.titleSuffixQuery ? { titleSuffixQuery: config.seoPreview.titleSuffixQuery } : {}),
2137
+ options: getPreviewFieldOptions(config),
1473
2138
  initialValue: "",
1474
2139
  readOnly: true
1475
2140
  }),
@@ -1477,20 +2142,20 @@ function seoFieldsSchema(config = {}) {
1477
2142
  )
1478
2143
  ] : [],
1479
2144
  withGroup(
1480
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2145
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1481
2146
  name: "title"
1482
2147
  }, getFieldInfo("title", config.fieldOverrides)), {
1483
2148
  type: "string",
1484
2149
  components: {
1485
2150
  input: MetaTitle_default
1486
2151
  },
1487
- options: chunk254YHUN3_cjs.__spreadValues(chunk254YHUN3_cjs.__spreadValues(chunk254YHUN3_cjs.__spreadValues({}, config.apiVersion ? { apiVersion: config.apiVersion } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.titleSuffix ? { titleSuffix: config.seoPreview.titleSuffix } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.titleSuffixQuery ? { titleSuffixQuery: config.seoPreview.titleSuffixQuery } : {}),
2152
+ options: getTitleFieldOptions(config),
1488
2153
  hidden: getFieldHiddenFunction("title", config)
1489
2154
  })),
1490
2155
  fieldGroupMap
1491
2156
  ),
1492
2157
  withGroup(
1493
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2158
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1494
2159
  name: "description"
1495
2160
  }, getFieldInfo("description", config.fieldOverrides)), {
1496
2161
  type: "text",
@@ -1498,12 +2163,13 @@ function seoFieldsSchema(config = {}) {
1498
2163
  components: {
1499
2164
  input: MetaDescription_default
1500
2165
  },
2166
+ options: getAiOption(config),
1501
2167
  hidden: getFieldHiddenFunction("description", config)
1502
2168
  })),
1503
2169
  fieldGroupMap
1504
2170
  ),
1505
2171
  withGroup(
1506
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2172
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1507
2173
  name: "metaImage"
1508
2174
  }, getFieldInfo("metaImage", config.fieldOverrides)), {
1509
2175
  type: "image",
@@ -1518,7 +2184,7 @@ function seoFieldsSchema(config = {}) {
1518
2184
  fieldGroupMap
1519
2185
  ),
1520
2186
  withGroup(
1521
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2187
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1522
2188
  name: "metaAttributes"
1523
2189
  }, getFieldInfo("metaAttributes", config.fieldOverrides)), {
1524
2190
  type: "array",
@@ -1528,19 +2194,21 @@ function seoFieldsSchema(config = {}) {
1528
2194
  fieldGroupMap
1529
2195
  ),
1530
2196
  withGroup(
1531
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2197
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1532
2198
  name: "keywords"
1533
2199
  }, getFieldInfo("keywords", config.fieldOverrides)), {
1534
2200
  title: "Keywords",
1535
2201
  type: "array",
1536
2202
  of: [{ type: "string" }],
1537
2203
  description: "Add relevant keywords for this page. These keywords will be used for SEO purposes.",
2204
+ components: config.ai ? { input: KeywordsInput_default } : void 0,
2205
+ options: getAiOption(config),
1538
2206
  hidden: getFieldHiddenFunction("keywords", config)
1539
2207
  })),
1540
2208
  fieldGroupMap
1541
2209
  ),
1542
2210
  withGroup(
1543
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2211
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1544
2212
  name: "canonicalUrl"
1545
2213
  }, getFieldInfo("canonicalUrl", config.fieldOverrides)), {
1546
2214
  title: "Canonical URL",
@@ -1551,71 +2219,54 @@ function seoFieldsSchema(config = {}) {
1551
2219
  fieldGroupMap
1552
2220
  ),
1553
2221
  withGroup(
1554
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2222
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1555
2223
  name: "focusKeyword"
1556
2224
  }, getFieldInfo("focusKeyword", config.fieldOverrides)), {
1557
2225
  type: "string",
1558
2226
  components: {
1559
2227
  input: FocusKeywordInput_default
1560
2228
  },
2229
+ options: getAiOption(config),
1561
2230
  hidden: getFieldHiddenFunction("focusKeyword", config)
1562
2231
  })),
1563
2232
  fieldGroupMap
1564
2233
  ),
1565
2234
  withGroup(
1566
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2235
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1567
2236
  name: "hreflangs"
1568
2237
  }, getFieldInfo("hreflangs", config.fieldOverrides)), {
1569
2238
  type: "array",
1570
2239
  of: [{ type: "hreflangEntry" }],
1571
- description: "Add alternate language/region versions. Include x-default for the fallback URL.",
2240
+ description: "Add alternate language/region versions. Include x-default for the fallback URL."
2241
+ }), ((_a = config.hreflang) == null ? void 0 : _a.autoFill) ? {
2242
+ components: { input: HreflangInput_default },
2243
+ options: {
2244
+ hreflang: config.hreflang,
2245
+ baseUrl: config.baseUrl,
2246
+ apiVersion: config.apiVersion
2247
+ }
2248
+ } : {}), {
1572
2249
  hidden: getFieldHiddenFunction("hreflangs", config)
1573
2250
  })),
1574
2251
  fieldGroupMap
1575
2252
  ),
1576
- ...config.geo === false ? [] : [
1577
- withGroup(
1578
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1579
- name: "geoChecklist"
1580
- }, getFieldInfo("geoChecklist", config.fieldOverrides)), {
1581
- type: "string",
1582
- readOnly: true,
1583
- components: {
1584
- input: GEOChecklist_default
1585
- },
1586
- options: chunk254YHUN3_cjs.__spreadValues({}, config.licenseKey ? { licenseKey: config.licenseKey } : {}),
1587
- hidden: getFieldHiddenFunction("geoChecklist", config)
1588
- })),
1589
- fieldGroupMap
1590
- )
1591
- ],
1592
- ...config.metaTagsPreview === false ? [] : [
1593
- withGroup(
1594
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1595
- name: "metaTagsPreview"
1596
- }, getFieldInfo("metaTagsPreview", config.fieldOverrides)), {
1597
- type: "string",
1598
- readOnly: true,
1599
- components: {
1600
- input: MetaTagsPreview_default
1601
- },
1602
- hidden: getFieldHiddenFunction("metaTagsPreview", config)
1603
- })),
1604
- fieldGroupMap
1605
- )
1606
- ],
2253
+ ...buildGeoChecklistField(config, fieldGroupMap),
2254
+ ...buildMetaTagsPreviewField(config, fieldGroupMap),
1607
2255
  withGroup(openGraph(config), fieldGroupMap),
1608
2256
  withGroup(twitter(config), fieldGroupMap)
1609
2257
  ]
1610
2258
  }));
1611
2259
  }
2260
+
2261
+ // src/schemas/types/baseMeta/index.ts
2262
+
1612
2263
  function baseMeta(config = {}) {
1613
- return sanity.defineType({
2264
+ return _sanity.defineType.call(void 0, {
1614
2265
  name: "baseMeta",
1615
2266
  title: "Basic Meta Settings",
1616
2267
  type: "object",
1617
2268
  fields: [
1618
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2269
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1619
2270
  name: "title"
1620
2271
  }, getFieldInfo("title", config.fieldOverrides)), {
1621
2272
  type: "string",
@@ -1624,7 +2275,7 @@ function baseMeta(config = {}) {
1624
2275
  },
1625
2276
  hidden: getFieldHiddenFunction("title", config)
1626
2277
  })),
1627
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2278
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1628
2279
  name: "description"
1629
2280
  }, getFieldInfo("description", config.fieldOverrides)), {
1630
2281
  type: "text",
@@ -1634,7 +2285,7 @@ function baseMeta(config = {}) {
1634
2285
  },
1635
2286
  hidden: getFieldHiddenFunction("description", config)
1636
2287
  })),
1637
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2288
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1638
2289
  name: "metaImage"
1639
2290
  }, getFieldInfo("metaImage", config.fieldOverrides)), {
1640
2291
  type: "image",
@@ -1646,7 +2297,7 @@ function baseMeta(config = {}) {
1646
2297
  },
1647
2298
  hidden: getFieldHiddenFunction("metaImage", config)
1648
2299
  })),
1649
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2300
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1650
2301
  name: "keywords"
1651
2302
  }, getFieldInfo("keywords", config.fieldOverrides)), {
1652
2303
  title: "Keywords",
@@ -1655,7 +2306,7 @@ function baseMeta(config = {}) {
1655
2306
  description: "Add relevant keywords for this page. These keywords will be used for SEO purposes.",
1656
2307
  hidden: getFieldHiddenFunction("keywords", config)
1657
2308
  })),
1658
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2309
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1659
2310
  name: "canonicalUrl"
1660
2311
  }, getFieldInfo("canonicalUrl", config.fieldOverrides)), {
1661
2312
  title: "Canonical URL",
@@ -1663,7 +2314,7 @@ function baseMeta(config = {}) {
1663
2314
  description: "Specify the canonical URL for this page. This helps prevent duplicate content issues by indicating the preferred version of a page.",
1664
2315
  hidden: getFieldHiddenFunction("canonicalUrl", config)
1665
2316
  })),
1666
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2317
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1667
2318
  name: "metaAttributes"
1668
2319
  }, getFieldInfo("metaAttributes", config.fieldOverrides)), {
1669
2320
  type: "array",
@@ -1673,12 +2324,15 @@ function baseMeta(config = {}) {
1673
2324
  ]
1674
2325
  });
1675
2326
  }
1676
- var hreflang_default = sanity.defineType({
2327
+
2328
+ // src/schemas/types/hreflang/index.ts
2329
+
2330
+ var hreflang_default = _sanity.defineType.call(void 0, {
1677
2331
  name: "hreflangEntry",
1678
2332
  title: "Hreflang Entry",
1679
2333
  type: "object",
1680
2334
  fields: [
1681
- sanity.defineField({
2335
+ _sanity.defineField.call(void 0, {
1682
2336
  name: "locale",
1683
2337
  title: "Language / Region",
1684
2338
  type: "string",
@@ -1691,7 +2345,7 @@ var hreflang_default = sanity.defineType({
1691
2345
  return true;
1692
2346
  })
1693
2347
  }),
1694
- sanity.defineField({
2348
+ _sanity.defineField.call(void 0, {
1695
2349
  name: "url",
1696
2350
  title: "URL",
1697
2351
  type: "url",
@@ -1705,17 +2359,20 @@ var hreflang_default = sanity.defineType({
1705
2359
  }
1706
2360
  }
1707
2361
  });
1708
- var metaAttribute_default = sanity.defineType({
2362
+
2363
+ // src/schemas/types/metaAttribute/index.ts
2364
+
2365
+ var metaAttribute_default = _sanity.defineType.call(void 0, {
1709
2366
  name: "metaAttribute",
1710
2367
  title: "Meta Attribute",
1711
2368
  type: "object",
1712
2369
  fields: [
1713
- sanity.defineField({
2370
+ _sanity.defineField.call(void 0, {
1714
2371
  name: "key",
1715
2372
  title: "Attribute Name",
1716
2373
  type: "string"
1717
2374
  }),
1718
- sanity.defineField({
2375
+ _sanity.defineField.call(void 0, {
1719
2376
  name: "type",
1720
2377
  title: "Attribute Value Type",
1721
2378
  type: "string",
@@ -1727,13 +2384,13 @@ var metaAttribute_default = sanity.defineType({
1727
2384
  },
1728
2385
  initialValue: "string"
1729
2386
  }),
1730
- sanity.defineField({
2387
+ _sanity.defineField.call(void 0, {
1731
2388
  name: "value",
1732
2389
  title: "Attribute Value",
1733
2390
  type: "string",
1734
2391
  hidden: ({ parent }) => (parent == null ? void 0 : parent.type) === "image"
1735
2392
  }),
1736
- sanity.defineField({
2393
+ _sanity.defineField.call(void 0, {
1737
2394
  name: "image",
1738
2395
  title: "Attribute Image Value",
1739
2396
  type: "image",
@@ -1763,7 +2420,10 @@ var metaAttribute_default = sanity.defineType({
1763
2420
  }
1764
2421
  }
1765
2422
  });
1766
- var metaTag_default = sanity.defineType({
2423
+
2424
+ // src/schemas/types/metaTag/index.ts
2425
+
2426
+ var metaTag_default = _sanity.defineType.call(void 0, {
1767
2427
  name: "metaTag",
1768
2428
  title: "Meta Tag",
1769
2429
  type: "object",
@@ -1777,33 +2437,36 @@ var metaTag_default = sanity.defineType({
1777
2437
  }
1778
2438
  ]
1779
2439
  });
1780
- var robots_default = sanity.defineType({
2440
+
2441
+ // src/schemas/types/robots/index.ts
2442
+
2443
+ var robots_default = _sanity.defineType.call(void 0, {
1781
2444
  name: "robots",
1782
2445
  title: "Robots Settings",
1783
2446
  type: "object",
1784
2447
  fields: [
1785
- sanity.defineField({
2448
+ _sanity.defineField.call(void 0, {
1786
2449
  name: "noIndex",
1787
2450
  title: "No Index",
1788
2451
  type: "boolean",
1789
2452
  initialValue: false,
1790
2453
  description: "Enable this to prevent search engines from indexing this page. The page will not appear in search results."
1791
2454
  }),
1792
- sanity.defineField({
2455
+ _sanity.defineField.call(void 0, {
1793
2456
  name: "noFollow",
1794
2457
  title: "No Follow",
1795
2458
  type: "boolean",
1796
2459
  initialValue: false,
1797
2460
  description: "Enable this to prevent search engines from following links on this page. Links will not pass SEO value."
1798
2461
  }),
1799
- sanity.defineField({
2462
+ _sanity.defineField.call(void 0, {
1800
2463
  name: "noTranslate",
1801
2464
  title: "No Translate",
1802
2465
  type: "boolean",
1803
2466
  initialValue: false,
1804
2467
  description: "Enable this to prevent search engines from offering a translated version of this page in search results."
1805
2468
  }),
1806
- sanity.defineField({
2469
+ _sanity.defineField.call(void 0, {
1807
2470
  name: "noImageIndex",
1808
2471
  title: "No Image Index",
1809
2472
  type: "boolean",
@@ -1896,15 +2559,15 @@ var resolveDashboardConfig = (healthDashboard, rootApiVersion, rootLicenseKey) =
1896
2559
  deprecationWarnings
1897
2560
  };
1898
2561
  };
1899
- var seofields = sanity.definePlugin((config = {}) => {
2562
+ var seofields = _sanity.definePlugin.call(void 0, (config = {}) => {
1900
2563
  const cfg = config;
1901
2564
  const { healthDashboard = true, licenseKey, publishGate } = cfg;
1902
2565
  const dash = resolveDashboardConfig(healthDashboard, cfg.apiVersion, licenseKey);
1903
- const LazySeoHealthTool = react.lazy(() => import('./SeoHealthTool-2KKQJLJL.cjs'));
1904
- const BoundSeoHealthTool = () => react.createElement(
1905
- react.Suspense,
2566
+ const LazySeoHealthTool = _react.lazy.call(void 0, () => Promise.resolve().then(() => _interopRequireWildcard(require("./SeoHealthTool-2COI27KI.cjs"))));
2567
+ const BoundSeoHealthTool = () => _react.createElement.call(void 0,
2568
+ _react.Suspense,
1906
2569
  { fallback: null },
1907
- react.createElement(LazySeoHealthTool, {
2570
+ _react.createElement.call(void 0, LazySeoHealthTool, {
1908
2571
  icon: dash.icon,
1909
2572
  title: dash.title,
1910
2573
  description: dash.description,
@@ -1930,7 +2593,7 @@ var seofields = sanity.definePlugin((config = {}) => {
1930
2593
  _deprecationWarnings: dash.deprecationWarnings
1931
2594
  })
1932
2595
  );
1933
- return chunk254YHUN3_cjs.__spreadValues(chunk254YHUN3_cjs.__spreadValues({
2596
+ return _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1934
2597
  name: "sanity-plugin-seofields",
1935
2598
  schema: {
1936
2599
  types: types(cfg)
@@ -1942,7 +2605,7 @@ var seofields = sanity.definePlugin((config = {}) => {
1942
2605
  if (((_a = publishGate.types) == null ? void 0 : _a.length) && !publishGate.types.includes(context.schemaType))
1943
2606
  return prev;
1944
2607
  return prev.map(
1945
- (Action) => Action.action === "publish" ? chunkBNXMFD3T_cjs.createSeoPublishGateAction(Action, chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({}, publishGate), { licenseKey })) : Action
2608
+ (Action) => Action.action === "publish" ? _seofieldspro.createSeoPublishGateAction.call(void 0, Action, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, publishGate), { licenseKey })) : Action
1946
2609
  );
1947
2610
  }
1948
2611
  }
@@ -1959,6 +2622,10 @@ var seofields = sanity.definePlugin((config = {}) => {
1959
2622
  });
1960
2623
  var plugin_default = seofields;
1961
2624
 
2625
+ // src/components/SeoHealthPane.tsx
2626
+
2627
+
2628
+
1962
2629
  // src/utils/scoring.ts
1963
2630
  var getStatusCategory = (score) => {
1964
2631
  if (score >= 80) return "excellent";
@@ -2027,6 +2694,50 @@ var scoreTwitterCard = (twitter2) => {
2027
2694
  }
2028
2695
  return { score, issues };
2029
2696
  };
2697
+ var scoreKeywordArray = (keywords, title, description) => {
2698
+ if (!keywords || keywords.length === 0) {
2699
+ return { score: 0, issues: ["No keywords defined"], stuffed: false };
2700
+ }
2701
+ const issues = [];
2702
+ let score = 2;
2703
+ if (_chunkY46ACXM4cjs.hasMatchingKeyword.call(void 0, title || "", keywords) || _chunkY46ACXM4cjs.hasMatchingKeyword.call(void 0, description || "", keywords)) {
2704
+ score += 3;
2705
+ } else {
2706
+ issues.push("Keywords defined but not used in title or description");
2707
+ }
2708
+ const stuffed = _chunkY46ACXM4cjs.hasKeywordOveruse.call(void 0, title || "", keywords) || _chunkY46ACXM4cjs.hasKeywordOveruse.call(void 0, description || "", keywords);
2709
+ if (stuffed) issues.push("Keyword stuffing detected \u2014 reduce repeated keyword usage");
2710
+ return { score, issues, stuffed };
2711
+ };
2712
+ var scoreFocusKeyword = (focusKeyword, title, description) => {
2713
+ const placement = _chunkY46ACXM4cjs.getFocusKeywordPlacement.call(void 0, focusKeyword, title, description);
2714
+ if (!placement.hasFocusKeyword) {
2715
+ return { score: 0, issues: ["No focus keyword defined"], stuffed: false };
2716
+ }
2717
+ const issues = [];
2718
+ let score = 1;
2719
+ if (placement.atStartOfTitle) {
2720
+ score += 4;
2721
+ } else if (placement.inTitle) {
2722
+ score += 2;
2723
+ issues.push("Focus keyword is in the title but not at the start");
2724
+ } else if (placement.inDescription) {
2725
+ score += 1;
2726
+ issues.push("Focus keyword missing from meta title");
2727
+ } else {
2728
+ issues.push("Focus keyword missing from meta title and description");
2729
+ }
2730
+ if (placement.isStuffed)
2731
+ issues.push("Focus keyword appears too many times in title \u2014 avoid stuffing");
2732
+ return { score, issues, stuffed: placement.isStuffed };
2733
+ };
2734
+ var scoreKeywordOptimization = (keywords, focusKeyword, title, description) => {
2735
+ const arrayResult = scoreKeywordArray(keywords, title, description);
2736
+ const focusResult = scoreFocusKeyword(focusKeyword, title, description);
2737
+ let score = arrayResult.score + focusResult.score;
2738
+ if (arrayResult.stuffed || focusResult.stuffed) score = Math.max(0, score - 2);
2739
+ return { score: Math.min(score, 10), issues: [...arrayResult.issues, ...focusResult.issues] };
2740
+ };
2030
2741
  var calculateHealthScore = (doc) => {
2031
2742
  if (!doc.seo) {
2032
2743
  return { score: 0, status: "missing", issues: ["SEO fields not configured"] };
@@ -2035,6 +2746,7 @@ var calculateHealthScore = (doc) => {
2035
2746
  const title = seo.title;
2036
2747
  const description = seo.description;
2037
2748
  const keywords = seo.keywords;
2749
+ const focusKeyword = seo.focusKeyword;
2038
2750
  const robots = seo.robots;
2039
2751
  const openGraph2 = seo.openGraph;
2040
2752
  const twitter2 = seo.twitter;
@@ -2048,8 +2760,9 @@ var calculateHealthScore = (doc) => {
2048
2760
  issues.push(...descResult.issues);
2049
2761
  if (seo.metaImage) score += 10;
2050
2762
  else issues.push("Missing meta image");
2051
- if (keywords && keywords.length > 0) score += 10;
2052
- else issues.push("No keywords defined");
2763
+ const keywordResult = scoreKeywordOptimization(keywords, focusKeyword, title, description);
2764
+ score += keywordResult.score;
2765
+ issues.push(...keywordResult.issues);
2053
2766
  if (robots && !robots.noIndex) score += 5;
2054
2767
  else if (!robots) score += 5;
2055
2768
  const ogResult = scoreOpenGraph(openGraph2);
@@ -2077,27 +2790,18 @@ var calculateHealthScore = (doc) => {
2077
2790
  // src/index.ts
2078
2791
  var src_default = plugin_default;
2079
2792
 
2080
- Object.defineProperty(exports, "SchemaOrgDocumentJsonLdPreview", {
2081
- enumerable: true,
2082
- get: function () { return chunkB5IVI5LP_cjs.SchemaOrgJsonLdPreview; }
2083
- });
2084
- Object.defineProperty(exports, "SchemaOrgJsonLdPreview", {
2085
- enumerable: true,
2086
- get: function () { return chunkB5IVI5LP_cjs.SchemaOrgJsonLdPreview; }
2087
- });
2088
- Object.defineProperty(exports, "createSeoHealthPane", {
2089
- enumerable: true,
2090
- get: function () { return chunkBNXMFD3T_cjs.createSeoHealthPane; }
2091
- });
2092
- exports.allSchemas = types;
2093
- exports.baseMetaSchema = baseMeta;
2094
- exports.calculateHealthScore = calculateHealthScore;
2095
- exports.default = src_default;
2096
- exports.metaAttributeSchema = metaAttribute_default;
2097
- exports.metaTagSchema = metaTag_default;
2098
- exports.openGraphSchema = openGraph;
2099
- exports.robotsSchema = robots_default;
2100
- exports.seoFieldsSchema = seoFieldsSchema;
2101
- exports.twitterSchema = twitter;
2102
- //# sourceMappingURL=index.cjs.map
2793
+
2794
+
2795
+
2796
+
2797
+
2798
+
2799
+
2800
+
2801
+
2802
+
2803
+
2804
+
2805
+
2806
+ exports.SchemaOrgDocumentJsonLdPreview = _chunk5XTQRILLcjs.SchemaOrgJsonLdPreview; exports.SchemaOrgJsonLdPreview = _chunk5XTQRILLcjs.SchemaOrgJsonLdPreview; exports.allSchemas = types; exports.baseMetaSchema = baseMeta; exports.calculateHealthScore = calculateHealthScore; exports.createSeoHealthPane = _seofieldspro.createSeoHealthPane; exports.default = src_default; exports.metaAttributeSchema = metaAttribute_default; exports.metaTagSchema = metaTag_default; exports.openGraphSchema = openGraph; exports.robotsSchema = robots_default; exports.seoFieldsSchema = seoFieldsSchema; exports.twitterSchema = twitter;
2103
2807
  //# sourceMappingURL=index.cjs.map