sanity-plugin-seofields 1.8.0 → 1.9.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 (113) hide show
  1. package/README.md +437 -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-3OK3S2F7.cjs +673 -0
  11. package/dist/chunk-3OK3S2F7.cjs.map +1 -0
  12. package/dist/{chunk-B5IVI5LP.cjs → chunk-5XTQRILL.cjs} +286 -236
  13. package/dist/chunk-5XTQRILL.cjs.map +1 -0
  14. package/dist/{chunk-254YHUN3.cjs → chunk-7N4MLTMR.js} +8 -6
  15. package/dist/chunk-7N4MLTMR.js.map +1 -0
  16. package/dist/{chunk-DDAAVRWG.js → chunk-A57XNQC7.cjs} +9 -4
  17. package/dist/chunk-A57XNQC7.cjs.map +1 -0
  18. package/dist/chunk-BWLJDK5J.js +624 -0
  19. package/dist/chunk-BWLJDK5J.js.map +1 -0
  20. package/dist/chunk-FUUWBQE2.cjs +195 -0
  21. package/dist/chunk-FUUWBQE2.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-KIEO6QG3.js +195 -0
  25. package/dist/chunk-KIEO6QG3.js.map +1 -0
  26. package/dist/chunk-R2U7JF7U.cjs +624 -0
  27. package/dist/chunk-R2U7JF7U.cjs.map +1 -0
  28. package/dist/{chunk-VR44E62I.js → chunk-XZKQWV2H.js} +204 -33
  29. package/dist/chunk-XZKQWV2H.js.map +1 -0
  30. package/dist/{chunk-HDZZQCH7.js → chunk-Y46ACXM4.cjs} +45 -5
  31. package/dist/chunk-Y46ACXM4.cjs.map +1 -0
  32. package/dist/chunk-Z5AOUU4H.js +673 -0
  33. package/dist/chunk-Z5AOUU4H.js.map +1 -0
  34. package/dist/cli.js +27 -27
  35. package/dist/{component-DEXwtemT.d.ts → component-CjT1hvxh.d.ts} +2 -2
  36. package/dist/{component-BzI-LHPw.d.cts → component-WYh0z8as.d.cts} +2 -2
  37. package/dist/define-cli.cjs +2 -4
  38. package/dist/define-cli.cjs.map +1 -1
  39. package/dist/define-cli.js +4 -4
  40. package/dist/define-cli.js.map +1 -1
  41. package/dist/head.cjs +14 -0
  42. package/dist/head.cjs.map +1 -0
  43. package/dist/head.d.cts +254 -0
  44. package/dist/head.d.ts +254 -0
  45. package/dist/head.js +14 -0
  46. package/dist/head.js.map +1 -0
  47. package/dist/index.cjs +978 -367
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +6 -374
  50. package/dist/index.d.ts +6 -374
  51. package/dist/index.js +920 -286
  52. package/dist/index.js.map +1 -1
  53. package/dist/next.cjs +204 -455
  54. package/dist/next.cjs.map +1 -1
  55. package/dist/next.d.cts +8 -206
  56. package/dist/next.d.ts +8 -206
  57. package/dist/next.js +181 -111
  58. package/dist/next.js.map +1 -1
  59. package/dist/plugin-DQdThyxG.d.ts +449 -0
  60. package/dist/plugin-DoGeZP79.d.cts +449 -0
  61. package/dist/schema/next.cjs +173 -327
  62. package/dist/schema/next.cjs.map +1 -1
  63. package/dist/schema/next.d.cts +4 -4
  64. package/dist/schema/next.d.ts +4 -4
  65. package/dist/schema/next.js +172 -8
  66. package/dist/schema/next.js.map +1 -1
  67. package/dist/schema.cjs +376 -517
  68. package/dist/schema.cjs.map +1 -1
  69. package/dist/schema.d.cts +5 -5
  70. package/dist/schema.d.ts +5 -5
  71. package/dist/schema.js +216 -11
  72. package/dist/schema.js.map +1 -1
  73. package/dist/server.cjs +149 -0
  74. package/dist/server.cjs.map +1 -0
  75. package/dist/server.d.cts +102 -0
  76. package/dist/server.d.ts +102 -0
  77. package/dist/server.js +149 -0
  78. package/dist/server.js.map +1 -0
  79. package/dist/{types-CW8qFdAn.d.ts → types-BAdN1RMu.d.ts} +2 -2
  80. package/dist/{types-B_vjMPtM.d.cts → types-C5i3KMgs.d.cts} +2 -2
  81. package/dist/{types-BXSCbl6p.d.cts → types-DP-DiW6f.d.cts} +2 -2
  82. package/dist/{types-C19cQx5D.d.ts → types-DRLUGLtX.d.ts} +2 -2
  83. package/dist/{types-yVmQfby9.d.cts → types-DxlPXihz.d.cts} +1 -1
  84. package/dist/{types-yVmQfby9.d.ts → types-DxlPXihz.d.ts} +1 -1
  85. package/package.json +25 -4
  86. package/dist/SeoHealthDashboard-AEKVVMUR-7NWV3C3Y.js +0 -4
  87. package/dist/SeoHealthDashboard-AEKVVMUR-7NWV3C3Y.js.map +0 -1
  88. package/dist/SeoHealthDashboard-AEKVVMUR-XWKJUH24.cjs +0 -10
  89. package/dist/SeoHealthDashboard-AEKVVMUR-XWKJUH24.cjs.map +0 -1
  90. package/dist/SeoHealthTool-2KKQJLJL.cjs +0 -11
  91. package/dist/SeoHealthTool-2KKQJLJL.cjs.map +0 -1
  92. package/dist/SeoHealthTool-3CUKGADZ.js +0 -5
  93. package/dist/SeoHealthTool-3CUKGADZ.js.map +0 -1
  94. package/dist/SeoPreview-3EXR6FD4.cjs.map +0 -1
  95. package/dist/SeoPreview-4PPAF4NO.js.map +0 -1
  96. package/dist/chunk-254YHUN3.cjs.map +0 -1
  97. package/dist/chunk-27XSYENH.js +0 -2215
  98. package/dist/chunk-27XSYENH.js.map +0 -1
  99. package/dist/chunk-B5IVI5LP.cjs.map +0 -1
  100. package/dist/chunk-BNXMFD3T.cjs +0 -431
  101. package/dist/chunk-BNXMFD3T.cjs.map +0 -1
  102. package/dist/chunk-DDAAVRWG.js.map +0 -1
  103. package/dist/chunk-HDZZQCH7.js.map +0 -1
  104. package/dist/chunk-P6IOWIO2.cjs +0 -480
  105. package/dist/chunk-P6IOWIO2.cjs.map +0 -1
  106. package/dist/chunk-UOCZFYYP.js +0 -407
  107. package/dist/chunk-UOCZFYYP.js.map +0 -1
  108. package/dist/chunk-VR44E62I.js.map +0 -1
  109. package/dist/chunk-WKXHX3GO.js +0 -424
  110. package/dist/chunk-WKXHX3GO.js.map +0 -1
  111. package/dist/chunk-XZDLJ2N6.cjs +0 -2224
  112. package/dist/chunk-XZDLJ2N6.cjs.map +0 -1
  113. package/dist/chunk-ZBHLMQTS.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,25 +1,64 @@
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 });
4
3
 
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
4
 
5
+ var _chunk3OK3S2F7cjs = require('./chunk-3OK3S2F7.cjs');
6
+
7
+
8
+
9
+ var _chunk5XTQRILLcjs = require('./chunk-5XTQRILL.cjs');
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+ var _chunkY46ACXM4cjs = require('./chunk-Y46ACXM4.cjs');
26
+
27
+
28
+
29
+ var _chunkA57XNQC7cjs = require('./chunk-A57XNQC7.cjs');
30
+
31
+ // src/plugin.ts
32
+ var _react = require('react');
33
+ var _sanity = require('sanity');
34
+
35
+ // src/actions/SeoPublishGateAction.tsx
36
+ var _seofieldspro = require('seofields-pro');
37
+
38
+ // src/schemas/index.ts
39
+
40
+
41
+
42
+
43
+
44
+
45
+ // src/components/geo/GEOChecklist.tsx
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+ var _jsxruntime = require('react/jsx-runtime');
15
54
  var GEOChecklist = (props) => {
16
55
  var _a;
17
56
  const { path, schemaType } = props;
18
- const [expanded, setExpanded] = react.useState(false);
57
+ const [expanded, setExpanded] = _react.useState.call(void 0, false);
19
58
  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(() => {
59
+ const seoFields = _sanity.useFormValue.call(void 0, [path[0]]);
60
+ const rootDoc = _sanity.useFormValue.call(void 0, []);
61
+ const freeChecks = _react.useMemo.call(void 0, () => {
23
62
  var _a2, _b, _c, _d;
24
63
  const desc = (seoFields == null ? void 0 : seoFields.description) || "";
25
64
  const title = (seoFields == null ? void 0 : seoFields.title) || "";
@@ -56,8 +95,8 @@ var GEOChecklist = (props) => {
56
95
  }
57
96
  ];
58
97
  }, [seoFields]);
59
- const proChecks = react.useMemo(
60
- () => licenseKey ? chunkBNXMFD3T_cjs.buildGEOProChecks(seoFields, rootDoc) : null,
98
+ const proChecks = _react.useMemo.call(void 0,
99
+ () => licenseKey ? _seofieldspro.buildGEOProChecks.call(void 0, seoFields, rootDoc) : null,
61
100
  [licenseKey, seoFields, rootDoc]
62
101
  );
63
102
  const freePassing = freeChecks.filter((c) => c.pass).length;
@@ -77,7 +116,7 @@ var GEOChecklist = (props) => {
77
116
  scoreBg = "#fefce8";
78
117
  scoreText = "#a16207";
79
118
  }
80
- return /* @__PURE__ */ jsxRuntime.jsxs(
119
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
81
120
  "div",
82
121
  {
83
122
  style: {
@@ -87,7 +126,7 @@ var GEOChecklist = (props) => {
87
126
  fontFamily: "inherit"
88
127
  },
89
128
  children: [
90
- /* @__PURE__ */ jsxRuntime.jsxs(
129
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
91
130
  "div",
92
131
  {
93
132
  style: {
@@ -99,11 +138,11 @@ var GEOChecklist = (props) => {
99
138
  gap: 12
100
139
  },
101
140
  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" })
141
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
142
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { fontSize: 13, fontWeight: 600, color: "#111827", marginBottom: 2 }, children: "AI Overview Readiness" }),
143
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { fontSize: 11, color: "#9ca3af" }, children: "Signals that improve visibility in AI-generated overviews" })
105
144
  ] }),
106
- /* @__PURE__ */ jsxRuntime.jsxs(
145
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
107
146
  "div",
108
147
  {
109
148
  style: {
@@ -116,8 +155,8 @@ var GEOChecklist = (props) => {
116
155
  flexShrink: 0
117
156
  },
118
157
  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: [
158
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 16, fontWeight: 700, color: scoreColor }, children: totalPassing }),
159
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: { fontSize: 12, color: scoreText, opacity: 0.7 }, children: [
121
160
  "/ ",
122
161
  totalChecks
123
162
  ] })
@@ -127,7 +166,7 @@ var GEOChecklist = (props) => {
127
166
  ]
128
167
  }
129
168
  ),
130
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: 3, backgroundColor: "#f3f4f6" }, children: /* @__PURE__ */ jsxRuntime.jsx(
169
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { height: 3, backgroundColor: "#f3f4f6" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
131
170
  "div",
132
171
  {
133
172
  style: {
@@ -138,7 +177,7 @@ var GEOChecklist = (props) => {
138
177
  }
139
178
  }
140
179
  ) }),
141
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "10px 20px" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
180
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { padding: "10px 20px" }, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
142
181
  "button",
143
182
  {
144
183
  type: "button",
@@ -156,7 +195,7 @@ var GEOChecklist = (props) => {
156
195
  gap: 4
157
196
  },
158
197
  children: [
159
- /* @__PURE__ */ jsxRuntime.jsx(
198
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
160
199
  "svg",
161
200
  {
162
201
  xmlns: "http://www.w3.org/2000/svg",
@@ -174,16 +213,16 @@ var GEOChecklist = (props) => {
174
213
  transition: "transform 0.2s ease",
175
214
  flexShrink: 0
176
215
  },
177
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 18 6-6-6-6" })
216
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "m9 18 6-6-6-6" })
178
217
  }
179
218
  ),
180
219
  expanded ? "Hide checks" : "Show all checks"
181
220
  ]
182
221
  }
183
222
  ) }),
184
- expanded && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
185
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "0 20px 16px" }, children: [
186
- /* @__PURE__ */ jsxRuntime.jsx(
223
+ expanded && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
224
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: "0 20px 16px" }, children: [
225
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
187
226
  "div",
188
227
  {
189
228
  style: {
@@ -197,9 +236,9 @@ var GEOChecklist = (props) => {
197
236
  children: "Core Checks"
198
237
  }
199
238
  ),
200
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: freeChecks.map((check) => /* @__PURE__ */ jsxRuntime.jsx(CheckRow, { check }, check.id)) })
239
+ /* @__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
240
  ] }),
202
- /* @__PURE__ */ jsxRuntime.jsxs(
241
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
203
242
  "div",
204
243
  {
205
244
  style: {
@@ -210,7 +249,7 @@ var GEOChecklist = (props) => {
210
249
  overflow: "hidden"
211
250
  },
212
251
  children: [
213
- /* @__PURE__ */ jsxRuntime.jsxs(
252
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
214
253
  "div",
215
254
  {
216
255
  style: {
@@ -221,7 +260,7 @@ var GEOChecklist = (props) => {
221
260
  gap: 8
222
261
  },
223
262
  children: [
224
- /* @__PURE__ */ jsxRuntime.jsx(
263
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
225
264
  "span",
226
265
  {
227
266
  style: {
@@ -234,7 +273,7 @@ var GEOChecklist = (props) => {
234
273
  children: "Pro Insights"
235
274
  }
236
275
  ),
237
- !licenseKey && /* @__PURE__ */ jsxRuntime.jsx(
276
+ !licenseKey && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
238
277
  "span",
239
278
  {
240
279
  style: {
@@ -248,7 +287,7 @@ var GEOChecklist = (props) => {
248
287
  children: "Unlock with licenseKey"
249
288
  }
250
289
  ),
251
- licenseKey && proChecks && /* @__PURE__ */ jsxRuntime.jsxs(
290
+ licenseKey && proChecks && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
252
291
  "span",
253
292
  {
254
293
  style: {
@@ -270,7 +309,7 @@ var GEOChecklist = (props) => {
270
309
  ]
271
310
  }
272
311
  ),
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, {}) })
312
+ /* @__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
313
  ]
275
314
  }
276
315
  )
@@ -280,7 +319,7 @@ var GEOChecklist = (props) => {
280
319
  );
281
320
  };
282
321
  function CheckRow({ check }) {
283
- return /* @__PURE__ */ jsxRuntime.jsxs(
322
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
284
323
  "div",
285
324
  {
286
325
  style: {
@@ -293,7 +332,7 @@ function CheckRow({ check }) {
293
332
  border: `1px solid ${check.pass ? "transparent" : "#fee2e2"}`
294
333
  },
295
334
  children: [
296
- /* @__PURE__ */ jsxRuntime.jsx(
335
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
297
336
  "div",
298
337
  {
299
338
  style: {
@@ -307,7 +346,7 @@ function CheckRow({ check }) {
307
346
  flexShrink: 0,
308
347
  marginTop: 1
309
348
  },
310
- children: /* @__PURE__ */ jsxRuntime.jsx(
349
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
311
350
  "span",
312
351
  {
313
352
  style: {
@@ -321,8 +360,8 @@ function CheckRow({ check }) {
321
360
  )
322
361
  }
323
362
  ),
324
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
325
- /* @__PURE__ */ jsxRuntime.jsx(
363
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { flex: 1, minWidth: 0 }, children: [
364
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
326
365
  "div",
327
366
  {
328
367
  style: {
@@ -334,30 +373,181 @@ function CheckRow({ check }) {
334
373
  children: check.label
335
374
  }
336
375
  ),
337
- !check.pass && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: "#9ca3af", marginTop: 3, lineHeight: 1.5 }, children: check.hint })
376
+ !check.pass && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { fontSize: 11, color: "#9ca3af", marginTop: 3, lineHeight: 1.5 }, children: check.hint })
338
377
  ] })
339
378
  ]
340
379
  }
341
380
  );
342
381
  }
343
382
  var GEOChecklist_default = GEOChecklist;
383
+
384
+ // src/components/meta/FocusKeywordInput.tsx
385
+ var _ui = require('@sanity/ui');
386
+
387
+
388
+
389
+ // src/components/ai/SeoGenButton.tsx
390
+ var _icons = require('@sanity/icons');
391
+
392
+
393
+
394
+
395
+ // src/utils/extractDocText.ts
396
+ function extractBlockText(block) {
397
+ if (block._type === "block" && Array.isArray(block.children)) {
398
+ return block.children.map((s) => {
399
+ var _a;
400
+ return (_a = s.text) != null ? _a : "";
401
+ }).join("");
402
+ }
403
+ const parts = [];
404
+ for (const key of Object.keys(block)) {
405
+ if (key === "_type" || key === "_key") continue;
406
+ const val = block[key];
407
+ if (typeof val === "string" && val.trim()) parts.push(val.trim());
408
+ else if (Array.isArray(val)) parts.push(extractArrayText(val));
409
+ }
410
+ return parts.filter(Boolean).join(" ");
411
+ }
412
+ function extractArrayText(arr) {
413
+ return arr.map((b) => extractBlockText(b)).filter(Boolean).join("\n");
414
+ }
415
+ function extractFieldText(value) {
416
+ if (typeof value === "string") return value;
417
+ if (!Array.isArray(value)) return "";
418
+ return extractArrayText(value).replace(/\n{3,}/g, "\n\n").trim();
419
+ }
420
+ function extractDocText(doc, bodyField) {
421
+ const fields = [bodyField].flat();
422
+ const text = fields.map((f) => extractFieldText(doc[f])).filter(Boolean).join("\n\n");
423
+ return text.slice(0, 4e3);
424
+ }
425
+ function resolveContentFields(content, docType) {
426
+ var _a;
427
+ if (!content || typeof content === "string" || Array.isArray(content)) return content != null ? content : "body";
428
+ const key = docType && docType in content ? docType : "default";
429
+ return (_a = content[key]) != null ? _a : "body";
430
+ }
431
+
432
+ // src/components/ai/SeoGenButton.tsx
433
+
434
+ function SeoGenButton({
435
+ field,
436
+ ai,
437
+ seoFieldPath,
438
+ onGenerate
439
+ }) {
440
+ var _a, _b, _c, _d, _e, _f, _g;
441
+ const [state, setState] = _react.useState.call(void 0, "idle");
442
+ const [errorMsg, setErrorMsg] = _react.useState.call(void 0, null);
443
+ const abortRef = _react.useRef.call(void 0, null);
444
+ const cooldownRef = _react.useRef.call(void 0, null);
445
+ const rootDoc = _sanity.useFormValue.call(void 0, []);
446
+ const workspace = _sanity.useWorkspace.call(void 0, );
447
+ const seoObj = _sanity.useFormValue.call(void 0, [seoFieldPath]);
448
+ const focusKeyword = (_a = seoObj == null ? void 0 : seoObj.focusKeyword) != null ? _a : "";
449
+ const keywords = (_b = seoObj == null ? void 0 : seoObj.keywords) != null ? _b : [];
450
+ const bodyField = resolveContentFields(ai == null ? void 0 : ai.content, rootDoc == null ? void 0 : rootDoc._type);
451
+ const content = rootDoc ? extractDocText(rootDoc, bodyField) : "";
452
+ const meta = field === "focusKeyword" ? {
453
+ title: (_c = seoObj == null ? void 0 : seoObj.title) != null ? _c : void 0,
454
+ description: (_d = seoObj == null ? void 0 : seoObj.description) != null ? _d : void 0,
455
+ slug: (_f = (_e = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _e.current) != null ? _f : void 0
456
+ } : void 0;
457
+ const handleGenerate = _react.useCallback.call(void 0, async () => {
458
+ var _a2;
459
+ if (!ai) return;
460
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
461
+ if (cooldownRef.current) clearTimeout(cooldownRef.current);
462
+ setState("loading");
463
+ setErrorMsg(null);
464
+ try {
465
+ let result;
466
+ if (ai.testMode) {
467
+ await new Promise((r) => setTimeout(r, 400));
468
+ result = _chunk3OK3S2F7cjs.pickTestOutput.call(void 0, field);
469
+ } else {
470
+ const controller = new AbortController();
471
+ abortRef.current = controller;
472
+ result = await _chunk3OK3S2F7cjs.generateSeoText.call(void 0, field, content, focusKeyword, keywords, {
473
+ config: _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, ai), { _projectId: workspace.projectId }),
474
+ signal: controller.signal,
475
+ meta
476
+ });
477
+ }
478
+ onGenerate(result);
479
+ setState("cooldown");
480
+ cooldownRef.current = setTimeout(() => setState("idle"), 2e3);
481
+ } catch (err) {
482
+ if (err.name === "AbortError") {
483
+ setState("idle");
484
+ return;
485
+ }
486
+ setErrorMsg(err instanceof Error ? err.message : "Generation failed.");
487
+ setState("error");
488
+ }
489
+ }, [ai, field, content, focusKeyword, keywords, meta, onGenerate, workspace.projectId]);
490
+ _react.useEffect.call(void 0, () => {
491
+ return () => {
492
+ var _a2;
493
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
494
+ if (cooldownRef.current) clearTimeout(cooldownRef.current);
495
+ };
496
+ }, []);
497
+ const isConfigured = Boolean(
498
+ (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"
499
+ );
500
+ if (!isConfigured) return null;
501
+ const isLoading = state === "loading";
502
+ const isTestMode = Boolean(ai == null ? void 0 : ai.testMode);
503
+ let buttonText = "Generate with AI";
504
+ if (isLoading) buttonText = "Generating\u2026";
505
+ else if (isTestMode) buttonText = "Generate (test)";
506
+ const isFullWidth = ((_g = ai == null ? void 0 : ai.buttonWidth) != null ? _g : "full") === "full";
507
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { direction: "column", gap: 1, align: isFullWidth ? "stretch" : "flex-start", children: [
508
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
509
+ _ui.Button,
510
+ {
511
+ mode: "ghost",
512
+ tone: "primary",
513
+ paddingX: isFullWidth ? 2 : 3,
514
+ paddingY: 3,
515
+ fontSize: 1,
516
+ icon: _icons.SparklesIcon,
517
+ text: buttonText,
518
+ onClick: handleGenerate,
519
+ disabled: isLoading || state === "cooldown"
520
+ }
521
+ ),
522
+ !content && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Text, { size: 0, muted: true, children: [
523
+ "(Set ",
524
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "code", { children: "ai.content" }),
525
+ " in plugin config for better results)"
526
+ ] }),
527
+ 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 }) })
528
+ ] });
529
+ }
530
+
531
+ // src/components/meta/FocusKeywordInput.tsx
532
+
344
533
  var FocusKeywordInput = (props) => {
345
534
  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;
535
+ const { value, renderDefault, path, schemaType, onChange } = props;
536
+ const { options } = schemaType;
537
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
538
+ const rootDoc = _sanity.useFormValue.call(void 0, []);
539
+ const feedbackItems = _react.useMemo.call(void 0, () => {
540
+ var _a2;
351
541
  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();
542
+ const title = (parent == null ? void 0 : parent.title) || "";
543
+ const description = (parent == null ? void 0 : parent.description) || "";
355
544
  const slug = ((_a2 = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _a2.current) || "";
545
+ const placement = _chunkY46ACXM4cjs.getFocusKeywordPlacement.call(void 0, value, title, description);
356
546
  const items = [];
357
547
  if (title) {
358
- if (title.startsWith(kw)) {
548
+ if (placement.atStartOfTitle) {
359
549
  items.push({ text: "Keyword at start of title \u2014 excellent", color: "green" });
360
- } else if (title.includes(kw)) {
550
+ } else if (placement.inTitle) {
361
551
  items.push({
362
552
  text: "Keyword in title \u2014 move it to the start for more prominence",
363
553
  color: "orange"
@@ -367,14 +557,14 @@ var FocusKeywordInput = (props) => {
367
557
  }
368
558
  }
369
559
  if (description) {
370
- if (description.includes(kw)) {
560
+ if (placement.inDescription) {
371
561
  items.push({ text: "Keyword in meta description", color: "green" });
372
562
  } else {
373
563
  items.push({ text: "Not in description \u2014 include it naturally", color: "orange" });
374
564
  }
375
565
  }
376
566
  if (slug) {
377
- const kwSlug = kw.replace(/\s+/g, "-");
567
+ const kwSlug = value.toLowerCase().replace(/\s+/g, "-");
378
568
  if (slug.includes(kwSlug)) {
379
569
  items.push({ text: "Keyword in URL slug", color: "green" });
380
570
  } else {
@@ -384,8 +574,7 @@ var FocusKeywordInput = (props) => {
384
574
  });
385
575
  }
386
576
  }
387
- const safeKw = kw.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
388
- if (((_b = title.match(new RegExp(safeKw, "g"))) != null ? _b : []).length > 2) {
577
+ if (placement.isStuffed) {
389
578
  items.push({
390
579
  text: "Keyword appears too many times in title \u2014 avoid stuffing",
391
580
  color: "red"
@@ -393,10 +582,19 @@ var FocusKeywordInput = (props) => {
393
582
  }
394
583
  return items;
395
584
  }, [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: [
585
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
397
586
  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(
587
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
588
+ SeoGenButton,
589
+ {
590
+ field: "focusKeyword",
591
+ ai: options == null ? void 0 : options.ai,
592
+ seoFieldPath: String(path[0]),
593
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
594
+ }
595
+ ),
596
+ /* @__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: [
597
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
400
598
  "div",
401
599
  {
402
600
  style: {
@@ -407,87 +605,276 @@ var FocusKeywordInput = (props) => {
407
605
  }
408
606
  }
409
607
  ),
410
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
608
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
411
609
  ] }, item.text)) })
412
610
  ] });
413
611
  };
414
612
  var FocusKeywordInput_default = FocusKeywordInput;
415
613
 
416
- // src/utils/readability.ts
417
- function countSyllables(word) {
614
+ // src/components/meta/KeywordsInput.tsx
615
+
616
+
617
+
618
+ // src/components/ai/KeywordSuggestions.tsx
619
+
620
+
621
+
622
+
623
+
624
+ function KeywordSuggestions({
625
+ ai,
626
+ seoFieldPath,
627
+ existing,
628
+ onAdd,
629
+ onAddAll
630
+ }) {
418
631
  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);
632
+ const [panelState, setPanelState] = _react.useState.call(void 0, "idle");
633
+ const [suggestions, setSuggestions] = _react.useState.call(void 0, []);
634
+ const [errorMsg, setErrorMsg] = _react.useState.call(void 0, null);
635
+ const abortRef = _react.useRef.call(void 0, null);
636
+ const rootDoc = _sanity.useFormValue.call(void 0, []);
637
+ const workspace = _sanity.useWorkspace.call(void 0, );
638
+ const seoObj = _sanity.useFormValue.call(void 0, [seoFieldPath]);
639
+ const focusKeyword = (_a = seoObj == null ? void 0 : seoObj.focusKeyword) != null ? _a : "";
640
+ const bodyField = resolveContentFields(ai == null ? void 0 : ai.content, rootDoc == null ? void 0 : rootDoc._type);
641
+ const content = rootDoc ? extractDocText(rootDoc, bodyField) : "";
642
+ const handleSuggest = _react.useCallback.call(void 0, async () => {
643
+ var _a2;
644
+ if (!ai) return;
645
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
646
+ abortRef.current = new AbortController();
647
+ setPanelState("loading");
648
+ setErrorMsg(null);
649
+ setSuggestions([]);
650
+ try {
651
+ let csv;
652
+ if (ai.testMode) {
653
+ await new Promise((r) => setTimeout(r, 400));
654
+ csv = _chunk3OK3S2F7cjs.pickTestOutput.call(void 0, "keywords");
655
+ } else {
656
+ csv = await _chunk3OK3S2F7cjs.generateSeoText.call(void 0, "keywords", content, focusKeyword, existing, {
657
+ config: _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, ai), { _projectId: workspace.projectId }),
658
+ signal: abortRef.current.signal
659
+ });
660
+ }
661
+ const parsed = csv.split(",").map((k) => k.replace(/^["']|["']$/g, "").trim()).filter(Boolean);
662
+ if (parsed.length === 0) {
663
+ setErrorMsg("No keywords returned. Try again.");
664
+ setPanelState("error");
665
+ return;
666
+ }
667
+ setSuggestions(parsed);
668
+ setPanelState("suggestions");
669
+ } catch (err) {
670
+ if (err.name === "AbortError") {
671
+ setPanelState("idle");
672
+ return;
673
+ }
674
+ setErrorMsg(err instanceof Error ? err.message : "Keyword generation failed.");
675
+ setPanelState("error");
676
+ }
677
+ }, [ai, content, focusKeyword, existing, workspace.projectId]);
678
+ const handleAdd = _react.useCallback.call(void 0,
679
+ (kw) => {
680
+ onAdd(kw);
681
+ setSuggestions((prev) => prev.filter((s) => s !== kw));
682
+ if (suggestions.length <= 1) setPanelState("idle");
683
+ },
684
+ [onAdd, suggestions.length]
685
+ );
686
+ const handleAddAll = _react.useCallback.call(void 0, () => {
687
+ const toAdd = suggestions.filter((kw) => !existing.includes(kw));
688
+ if (toAdd.length > 0) onAddAll(toAdd);
689
+ setSuggestions([]);
690
+ setPanelState("idle");
691
+ }, [suggestions, existing, onAddAll]);
692
+ const handleDismiss = _react.useCallback.call(void 0, () => {
693
+ var _a2;
694
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
695
+ setSuggestions([]);
696
+ setPanelState("idle");
697
+ setErrorMsg(null);
698
+ }, []);
699
+ _react.useEffect.call(void 0, () => {
700
+ return () => {
701
+ var _a2;
702
+ (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
703
+ };
704
+ }, []);
705
+ const isConfigured = Boolean(
706
+ (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"
707
+ );
708
+ if (!isConfigured) return null;
709
+ if (panelState === "idle" || panelState === "error") {
710
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 2, children: [
711
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
712
+ _ui.Button,
713
+ {
714
+ mode: "ghost",
715
+ tone: "primary",
716
+ paddingX: 2,
717
+ paddingY: 3,
718
+ fontSize: 1,
719
+ icon: _icons.SparklesIcon,
720
+ text: (ai == null ? void 0 : ai.testMode) ? "Suggest Keywords (test)" : "Suggest Keywords with AI",
721
+ onClick: handleSuggest
722
+ }
723
+ ),
724
+ 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 }) })
725
+ ] });
425
726
  }
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";
727
+ if (panelState === "loading") {
728
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { align: "center", gap: 2, paddingY: 2, children: [
729
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Spinner, { muted: true }),
730
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, muted: true, children: "Finding keywords\u2026" })
731
+ ] });
457
732
  }
458
- return {
459
- score,
460
- gradeLevel,
461
- avgWordsPerSentence,
462
- words,
463
- sentences,
464
- label,
465
- color
466
- };
733
+ const pendingSuggestions = suggestions.filter((kw) => !existing.includes(kw));
734
+ const alreadyAdded = suggestions.filter((kw) => existing.includes(kw));
735
+ 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: [
736
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { align: "center", justify: "space-between", children: [
737
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, weight: "semibold", muted: true, children: "AI keyword suggestions" }),
738
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { gap: 2, children: [
739
+ pendingSuggestions.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
740
+ _ui.Button,
741
+ {
742
+ mode: "ghost",
743
+ tone: "primary",
744
+ paddingX: 2,
745
+ paddingY: 2,
746
+ fontSize: 1,
747
+ text: "Add all",
748
+ onClick: handleAddAll
749
+ }
750
+ ),
751
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
752
+ _ui.Button,
753
+ {
754
+ mode: "ghost",
755
+ tone: "default",
756
+ paddingX: 2,
757
+ paddingY: 2,
758
+ fontSize: 1,
759
+ text: "Dismiss",
760
+ onClick: handleDismiss
761
+ }
762
+ )
763
+ ] })
764
+ ] }),
765
+ pendingSuggestions.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Box, { children: [
766
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 0, muted: true, style: { marginBottom: 8 }, children: "Click to add:" }),
767
+ /* @__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,
768
+ "button",
769
+ {
770
+ type: "button",
771
+ onClick: () => handleAdd(kw),
772
+ style: {
773
+ padding: "4px 10px",
774
+ borderRadius: 20,
775
+ border: "1px solid var(--card-border-color)",
776
+ background: "transparent",
777
+ color: "var(--card-fg-color)",
778
+ cursor: "pointer",
779
+ fontSize: 12,
780
+ lineHeight: 1.4,
781
+ transition: "background 0.15s"
782
+ },
783
+ onMouseEnter: (e) => {
784
+ ;
785
+ e.currentTarget.style.background = "var(--card-border-color)";
786
+ },
787
+ onMouseLeave: (e) => {
788
+ ;
789
+ e.currentTarget.style.background = "transparent";
790
+ },
791
+ children: [
792
+ "+ ",
793
+ kw
794
+ ]
795
+ },
796
+ kw
797
+ )) })
798
+ ] }),
799
+ alreadyAdded.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Box, { children: [
800
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 0, muted: true, style: { marginBottom: 6 }, children: "Already added:" }),
801
+ /* @__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: [
802
+ "\u2713 ",
803
+ kw
804
+ ] }, kw)) })
805
+ ] }),
806
+ pendingSuggestions.length === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, muted: true, children: "All suggested keywords added." })
807
+ ] }) });
467
808
  }
809
+
810
+ // src/components/meta/KeywordsInput.tsx
811
+
812
+ var KeywordsInput = (props) => {
813
+ const { value, renderDefault, path, schemaType, onChange } = props;
814
+ const { options } = schemaType;
815
+ const existing = value != null ? value : [];
816
+ const handleAdd = (kw) => {
817
+ if (existing.includes(kw)) return;
818
+ onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, [...existing, kw])));
819
+ };
820
+ const handleAddAll = (keywords) => {
821
+ const merged = [.../* @__PURE__ */ new Set([...existing, ...keywords])];
822
+ onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, merged)));
823
+ };
824
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
825
+ renderDefault(props),
826
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
827
+ KeywordSuggestions,
828
+ {
829
+ ai: options == null ? void 0 : options.ai,
830
+ seoFieldPath: String(path[0]),
831
+ existing,
832
+ onAdd: handleAdd,
833
+ onAddAll: handleAddAll
834
+ }
835
+ )
836
+ ] });
837
+ };
838
+ var KeywordsInput_default = KeywordsInput;
839
+
840
+ // src/components/meta/MetaDescription.tsx
841
+
842
+
843
+
844
+
468
845
  var MetaDescription = (props) => {
469
- const { value, renderDefault, path } = props;
470
- const parent = sanity.useFormValue([path[0]]);
846
+ const { value, renderDefault, path, schemaType, onChange } = props;
847
+ const { options } = schemaType;
848
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
471
849
  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),
850
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
851
+ const feedbackItems = _react.useMemo.call(void 0,
852
+ () => _chunkY46ACXM4cjs.getMetaDescriptionValidationMessages.call(void 0, value || "", keywords, isParentseoField),
475
853
  [value, keywords, isParentseoField]
476
854
  );
477
- const readability = react.useMemo(() => analyzeReadability(value || ""), [value]);
478
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
855
+ const readability = _react.useMemo.call(void 0, () => _chunk3OK3S2F7cjs.analyzeReadability.call(void 0, value || ""), [value]);
856
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
479
857
  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(
858
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
859
+ SeoGenButton,
860
+ {
861
+ field: "description",
862
+ ai: options == null ? void 0 : options.ai,
863
+ seoFieldPath: String(path[0]),
864
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
865
+ }
866
+ ),
867
+ /* @__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: [
868
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
482
869
  "div",
483
870
  {
484
871
  style: { width: 10, height: 10, borderRadius: "50%", backgroundColor: item.color }
485
872
  }
486
873
  ),
487
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
874
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
488
875
  ] }, item.text)) }),
489
- readability && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
490
- /* @__PURE__ */ jsxRuntime.jsx(
876
+ readability && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
877
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
491
878
  "div",
492
879
  {
493
880
  style: {
@@ -498,7 +885,7 @@ var MetaDescription = (props) => {
498
885
  }
499
886
  }
500
887
  ),
501
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { weight: "bold", muted: true, size: 14, children: [
888
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: [
502
889
  "Readability: ",
503
890
  readability.label,
504
891
  " (Flesch ",
@@ -512,18 +899,24 @@ var MetaDescription = (props) => {
512
899
  ] });
513
900
  };
514
901
  var MetaDescription_default = MetaDescription;
902
+
903
+ // src/components/meta/MetaImage.tsx
904
+
905
+
906
+
907
+
515
908
  var MetaImage = (props) => {
516
909
  const { value, renderDefault, path } = props;
517
- const seoParent = sanity.useFormValue([path[0]]);
910
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
518
911
  const hasImage = !!(value == null ? void 0 : value.asset);
519
- const feedbackItems = react.useMemo(
520
- () => chunkZBHLMQTS_cjs.getMetaImageValidation(hasImage, seoParent),
912
+ const feedbackItems = _react.useMemo.call(void 0,
913
+ () => _chunkY46ACXM4cjs.getMetaImageValidation.call(void 0, hasImage, seoParent),
521
914
  [hasImage, seoParent]
522
915
  );
523
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
916
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
524
917
  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(
918
+ /* @__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: [
919
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
527
920
  "div",
528
921
  {
529
922
  style: {
@@ -534,11 +927,17 @@ var MetaImage = (props) => {
534
927
  }
535
928
  }
536
929
  ),
537
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
930
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
538
931
  ] }, item.text)) })
539
932
  ] });
540
933
  };
541
934
  var MetaImage_default = MetaImage;
935
+
936
+ // src/components/meta/MetaTagsPreview.tsx
937
+
938
+
939
+
940
+
542
941
  function resolveImageUrl(asset, projectId, dataset) {
543
942
  const ref = asset == null ? void 0 : asset._ref;
544
943
  if (!ref) return null;
@@ -550,13 +949,13 @@ function resolveImageUrl(asset, projectId, dataset) {
550
949
  }
551
950
  var MetaTagsPreview = (props) => {
552
951
  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" });
952
+ const [expanded, setExpanded] = _react.useState.call(void 0, false);
953
+ const [copyLabel, setCopyLabel] = _react.useState.call(void 0, "Copy");
954
+ const { scheme } = _sanity.useColorScheme.call(void 0, );
955
+ const seoFields = _sanity.useFormValue.call(void 0, [path[0]]);
956
+ const client = _sanity.useClient.call(void 0, { apiVersion: "2024-01-01" });
558
957
  const { projectId = "", dataset = "" } = client.config();
559
- const rawHtml = react.useMemo(() => {
958
+ const rawHtml = _react.useMemo.call(void 0, () => {
560
959
  var _a, _b, _c, _d, _e, _f, _g;
561
960
  const lines = [];
562
961
  lines.push('<meta charset="UTF-8" />');
@@ -612,8 +1011,8 @@ var MetaTagsPreview = (props) => {
612
1011
  }
613
1012
  return lines.join("\n");
614
1013
  }, [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]);
1014
+ const tagCount = _react.useMemo.call(void 0, () => rawHtml.split("\n").filter(Boolean).length, [rawHtml]);
1015
+ const tokens = _react.useMemo.call(void 0, () => _chunk5XTQRILLcjs.tokenizeHtml.call(void 0, rawHtml, scheme), [rawHtml, scheme]);
617
1016
  const handleCopy = () => {
618
1017
  navigator.clipboard.writeText(rawHtml).then(() => {
619
1018
  setCopyLabel("Copied!");
@@ -626,16 +1025,16 @@ var MetaTagsPreview = (props) => {
626
1025
  const headerBg = isDark ? "#21262d" : "#f0f2f4";
627
1026
  const headerBorder = isDark ? "#30363d" : "#d0d7de";
628
1027
  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: [
1028
+ 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: [
1029
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { align: "center", justify: "space-between", gap: 3, children: [
1030
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "semibold", size: 1, children: "Meta Tags Preview" }),
1031
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { gap: 2, align: "center", children: [
1032
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Text, { size: 0, muted: true, children: [
634
1033
  tagCount,
635
1034
  " tags generated"
636
1035
  ] }),
637
- /* @__PURE__ */ jsxRuntime.jsx(
638
- ui.Button,
1036
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1037
+ _ui.Button,
639
1038
  {
640
1039
  text: copyLabel,
641
1040
  tone: "default",
@@ -647,7 +1046,7 @@ var MetaTagsPreview = (props) => {
647
1046
  )
648
1047
  ] })
649
1048
  ] }),
650
- /* @__PURE__ */ jsxRuntime.jsxs(
1049
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
651
1050
  "button",
652
1051
  {
653
1052
  type: "button",
@@ -668,12 +1067,12 @@ var MetaTagsPreview = (props) => {
668
1067
  color: headerText
669
1068
  },
670
1069
  children: [
671
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 10 }, children: expanded ? "\u25B2" : "\u25BC" }),
1070
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 10 }, children: expanded ? "\u25B2" : "\u25BC" }),
672
1071
  expanded ? "Hide tags" : "Show tags"
673
1072
  ]
674
1073
  }
675
1074
  ),
676
- expanded && /* @__PURE__ */ jsxRuntime.jsxs(
1075
+ expanded && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
677
1076
  "div",
678
1077
  {
679
1078
  style: {
@@ -682,7 +1081,7 @@ var MetaTagsPreview = (props) => {
682
1081
  overflow: "hidden"
683
1082
  },
684
1083
  children: [
685
- /* @__PURE__ */ jsxRuntime.jsxs(
1084
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
686
1085
  "div",
687
1086
  {
688
1087
  style: {
@@ -694,7 +1093,7 @@ var MetaTagsPreview = (props) => {
694
1093
  gap: 6
695
1094
  },
696
1095
  children: [
697
- /* @__PURE__ */ jsxRuntime.jsx(
1096
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
698
1097
  "span",
699
1098
  {
700
1099
  style: {
@@ -706,12 +1105,12 @@ var MetaTagsPreview = (props) => {
706
1105
  }
707
1106
  }
708
1107
  ),
709
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 11, color: headerText, fontFamily: "monospace" }, children: "HTML" })
1108
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 11, color: headerText, fontFamily: "monospace" }, children: "HTML" })
710
1109
  ]
711
1110
  }
712
1111
  ),
713
- /* @__PURE__ */ jsxRuntime.jsx(
714
- ui.Box,
1112
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1113
+ _ui.Box,
715
1114
  {
716
1115
  as: "pre",
717
1116
  padding: 3,
@@ -726,7 +1125,7 @@ var MetaTagsPreview = (props) => {
726
1125
  wordBreak: "break-word",
727
1126
  backgroundColor: codeBg
728
1127
  },
729
- children: tokens.map((token, idx) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: token.color }, children: token.text }, idx))
1128
+ children: tokens.map((token, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { color: token.color }, children: token.text }, idx))
730
1129
  }
731
1130
  )
732
1131
  ]
@@ -735,20 +1134,26 @@ var MetaTagsPreview = (props) => {
735
1134
  ] }) });
736
1135
  };
737
1136
  var MetaTagsPreview_default = MetaTagsPreview;
1137
+
1138
+ // src/components/meta/MetaTitle.tsx
1139
+
1140
+
1141
+
1142
+
738
1143
  var MetaTitle = (props) => {
739
1144
  var _a, _b, _c;
740
- const { value, renderDefault, path, schemaType } = props;
1145
+ const { value, renderDefault, path, schemaType, onChange } = props;
741
1146
  const { options } = schemaType;
742
- const parent = sanity.useFormValue([path[0]]);
1147
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
743
1148
  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);
1149
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1150
+ const rootDoc = (_a = _sanity.useFormValue.call(void 0, [])) != null ? _a : {};
1151
+ const client = _sanity.useClient.call(void 0, { apiVersion: (_b = options == null ? void 0 : options.apiVersion) != null ? _b : "2024-01-01" });
1152
+ const [groqTitleSuffix, setGroqTitleSuffix] = _react.useState.call(void 0, "");
1153
+ const [isDuplicateTitle, setIsDuplicateTitle] = _react.useState.call(void 0, false);
749
1154
  const titleSuffixQuery = options == null ? void 0 : options.titleSuffixQuery;
750
1155
  const titleSuffixOption = options == null ? void 0 : options.titleSuffix;
751
- react.useEffect(() => {
1156
+ _react.useEffect.call(void 0, () => {
752
1157
  if (!titleSuffixQuery) return;
753
1158
  client.fetch(titleSuffixQuery).then((result) => {
754
1159
  setGroqTitleSuffix(result === null || result === void 0 ? "" : String(result));
@@ -757,7 +1162,7 @@ var MetaTitle = (props) => {
757
1162
  });
758
1163
  }, [titleSuffixQuery, client]);
759
1164
  const currentDocId = (_c = rootDoc._id) != null ? _c : "";
760
- react.useEffect(() => {
1165
+ _react.useEffect.call(void 0, () => {
761
1166
  if (!(value == null ? void 0 : value.trim()) || !currentDocId) {
762
1167
  setIsDuplicateTitle(false);
763
1168
  return () => {
@@ -771,7 +1176,7 @@ var MetaTitle = (props) => {
771
1176
  }, 600);
772
1177
  return () => clearTimeout(timer);
773
1178
  }, [value, client, currentDocId]);
774
- const resolvedSuffix = react.useMemo(() => {
1179
+ const resolvedSuffix = _react.useMemo.call(void 0, () => {
775
1180
  if (titleSuffixQuery) return groqTitleSuffix;
776
1181
  if (!titleSuffixOption) return "";
777
1182
  if (typeof titleSuffixOption === "function") {
@@ -780,15 +1185,24 @@ var MetaTitle = (props) => {
780
1185
  return titleSuffixOption;
781
1186
  }, [titleSuffixQuery, groqTitleSuffix, titleSuffixOption, rootDoc]);
782
1187
  const suffixLength = resolvedSuffix ? resolvedSuffix.length + 3 : 0;
783
- const feedbackItems = react.useMemo(
784
- () => chunkZBHLMQTS_cjs.getMetaTitleValidationMessages(value || "", keywords, isParentseoField, suffixLength),
1188
+ const feedbackItems = _react.useMemo.call(void 0,
1189
+ () => _chunkY46ACXM4cjs.getMetaTitleValidationMessages.call(void 0, value || "", keywords, isParentseoField, suffixLength),
785
1190
  [value, keywords, isParentseoField, suffixLength]
786
1191
  );
787
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1192
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
788
1193
  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(
1194
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1195
+ SeoGenButton,
1196
+ {
1197
+ field: "title",
1198
+ ai: options == null ? void 0 : options.ai,
1199
+ seoFieldPath: String(path[0]),
1200
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1201
+ }
1202
+ ),
1203
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 2, children: [
1204
+ feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1205
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
792
1206
  "div",
793
1207
  {
794
1208
  style: {
@@ -799,10 +1213,10 @@ var MetaTitle = (props) => {
799
1213
  }
800
1214
  }
801
1215
  ),
802
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1216
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
803
1217
  ] }, item.text)),
804
- isDuplicateTitle && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
805
- /* @__PURE__ */ jsxRuntime.jsx(
1218
+ isDuplicateTitle && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
1219
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
806
1220
  "div",
807
1221
  {
808
1222
  style: {
@@ -813,7 +1227,7 @@ var MetaTitle = (props) => {
813
1227
  }
814
1228
  }
815
1229
  ),
816
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: "Duplicate meta title \u2014 another published document uses this exact title." })
1230
+ /* @__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
1231
  ] })
818
1232
  ] })
819
1233
  ] });
@@ -821,6 +1235,10 @@ var MetaTitle = (props) => {
821
1235
  var MetaTitle_default = MetaTitle;
822
1236
 
823
1237
  // src/utils/fieldsUtils.ts
1238
+ function withLicense(ai, licenseKey) {
1239
+ if (!ai) return void 0;
1240
+ return licenseKey ? _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, ai), { _licenseKey: licenseKey }) : ai;
1241
+ }
824
1242
  var DEFAULT_FIELD_INFO = {
825
1243
  title: {
826
1244
  title: "Meta Title",
@@ -958,19 +1376,38 @@ var getFieldHiddenFunction = (fieldName, config) => {
958
1376
  var isEmpty = (value) => {
959
1377
  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
1378
  };
1379
+
1380
+ // src/schemas/types/openGraph/index.ts
1381
+
1382
+
1383
+ // src/components/openGraph/OgDescription.tsx
1384
+
1385
+
1386
+
1387
+
961
1388
  var OgDescription = (props) => {
962
- const { value, renderDefault, path } = props;
963
- const parent = sanity.useFormValue([path[0]]);
1389
+ const { value, renderDefault, path, schemaType, onChange } = props;
1390
+ const { options } = schemaType;
1391
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
964
1392
  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),
1393
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1394
+ const feedbackItems = _react.useMemo.call(void 0,
1395
+ () => _chunkY46ACXM4cjs.getOgDescriptionValidation.call(void 0, value || "", keywords, isParentseoField),
968
1396
  [value, keywords, isParentseoField]
969
1397
  );
970
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1398
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
971
1399
  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(
1400
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1401
+ SeoGenButton,
1402
+ {
1403
+ field: "ogDescription",
1404
+ ai: options == null ? void 0 : options.ai,
1405
+ seoFieldPath: String(path[0]),
1406
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1407
+ }
1408
+ ),
1409
+ /* @__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: [
1410
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
974
1411
  "div",
975
1412
  {
976
1413
  style: {
@@ -981,25 +1418,31 @@ var OgDescription = (props) => {
981
1418
  }
982
1419
  }
983
1420
  ),
984
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1421
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
985
1422
  ] }, item.text)) })
986
1423
  ] });
987
1424
  };
988
1425
  var OgDescription_default = OgDescription;
1426
+
1427
+ // src/components/openGraph/OgImage.tsx
1428
+
1429
+
1430
+
1431
+
989
1432
  var OgImage = (props) => {
990
1433
  const { value, renderDefault, path } = props;
991
- const seoParent = sanity.useFormValue([path[0]]);
1434
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
992
1435
  const imgValue = value;
993
1436
  const hasImage = !!(imgValue == null ? void 0 : imgValue.asset);
994
1437
  const altText = imgValue == null ? void 0 : imgValue.alt;
995
- const feedbackItems = react.useMemo(
996
- () => chunkZBHLMQTS_cjs.getOgImageValidation(hasImage, altText, seoParent),
1438
+ const feedbackItems = _react.useMemo.call(void 0,
1439
+ () => _chunkY46ACXM4cjs.getOgImageValidation.call(void 0, hasImage, altText, seoParent),
997
1440
  [hasImage, altText, seoParent]
998
1441
  );
999
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1442
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1000
1443
  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(
1444
+ /* @__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: [
1445
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1003
1446
  "div",
1004
1447
  {
1005
1448
  style: {
@@ -1010,19 +1453,25 @@ var OgImage = (props) => {
1010
1453
  }
1011
1454
  }
1012
1455
  ),
1013
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1456
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1014
1457
  ] }, item.text)) })
1015
1458
  ] });
1016
1459
  };
1017
1460
  var OgImage_default = OgImage;
1461
+
1462
+ // src/components/openGraph/OgImageUrl.tsx
1463
+
1464
+
1465
+
1466
+
1018
1467
  var OgImageUrl = (props) => {
1019
1468
  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: [
1469
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
1470
+ const feedbackItems = _react.useMemo.call(void 0, () => _chunkY46ACXM4cjs.getOgImageUrlValidation.call(void 0, value, seoParent), [value, seoParent]);
1471
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1023
1472
  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(
1473
+ /* @__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: [
1474
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1026
1475
  "div",
1027
1476
  {
1028
1477
  style: {
@@ -1033,24 +1482,40 @@ var OgImageUrl = (props) => {
1033
1482
  }
1034
1483
  }
1035
1484
  ),
1036
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1485
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1037
1486
  ] }, item.text)) })
1038
1487
  ] });
1039
1488
  };
1040
1489
  var OgImageUrl_default = OgImageUrl;
1490
+
1491
+ // src/components/openGraph/OgTitle.tsx
1492
+
1493
+
1494
+
1495
+
1041
1496
  var OgTitle = (props) => {
1042
- const { value, renderDefault, path } = props;
1043
- const parent = sanity.useFormValue([path[0]]);
1497
+ const { value, renderDefault, path, schemaType, onChange } = props;
1498
+ const { options } = schemaType;
1499
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
1044
1500
  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),
1501
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1502
+ const feedbackItems = _react.useMemo.call(void 0,
1503
+ () => _chunkY46ACXM4cjs.getOgTitleValidation.call(void 0, value || "", keywords, isParentseoField),
1048
1504
  [value, keywords, isParentseoField]
1049
1505
  );
1050
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1506
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1051
1507
  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(
1508
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1509
+ SeoGenButton,
1510
+ {
1511
+ field: "ogTitle",
1512
+ ai: options == null ? void 0 : options.ai,
1513
+ seoFieldPath: String(path[0]),
1514
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1515
+ }
1516
+ ),
1517
+ /* @__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: [
1518
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1054
1519
  "div",
1055
1520
  {
1056
1521
  style: {
@@ -1061,7 +1526,7 @@ var OgTitle = (props) => {
1061
1526
  }
1062
1527
  }
1063
1528
  ),
1064
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1529
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1065
1530
  ] }, item.text)) })
1066
1531
  ] });
1067
1532
  };
@@ -1069,29 +1534,29 @@ var OgTitle_default = OgTitle;
1069
1534
 
1070
1535
  // src/schemas/types/openGraph/index.ts
1071
1536
  function openGraph(config = {}) {
1072
- return sanity.defineType({
1537
+ return _sanity.defineType.call(void 0, {
1073
1538
  name: "openGraph",
1074
1539
  title: "Open Graph Settings",
1075
1540
  type: "object",
1076
1541
  fields: [
1077
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1542
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1078
1543
  name: "url",
1079
1544
  type: "url"
1080
1545
  }, getFieldInfo("openGraphUrl", config.fieldOverrides)), {
1081
1546
  hidden: getFieldHiddenFunction("openGraphUrl", config),
1082
1547
  description: "The canonical URL of the page. This should be the full URL including protocol (https://)."
1083
1548
  })),
1084
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1549
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1085
1550
  name: "title"
1086
1551
  }, getFieldInfo("openGraphTitle", config.fieldOverrides)), {
1087
1552
  type: "string",
1088
1553
  hidden: getFieldHiddenFunction("openGraphTitle", config),
1089
1554
  components: {
1090
1555
  input: OgTitle_default
1091
- // Can also wrap with a string input + preview
1092
- }
1556
+ },
1557
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
1093
1558
  })),
1094
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1559
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1095
1560
  name: "description"
1096
1561
  }, getFieldInfo("openGraphDescription", config.fieldOverrides)), {
1097
1562
  type: "text",
@@ -1099,16 +1564,16 @@ function openGraph(config = {}) {
1099
1564
  hidden: getFieldHiddenFunction("openGraphDescription", config),
1100
1565
  components: {
1101
1566
  input: OgDescription_default
1102
- // Can also wrap with a text area + preview
1103
- }
1567
+ },
1568
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
1104
1569
  })),
1105
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1570
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1106
1571
  name: "siteName"
1107
1572
  }, getFieldInfo("openGraphSiteName", config.fieldOverrides)), {
1108
1573
  type: "string",
1109
1574
  hidden: getFieldHiddenFunction("openGraphSiteName", config)
1110
1575
  })),
1111
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1576
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1112
1577
  name: "type"
1113
1578
  }, getFieldInfo("openGraphType", config.fieldOverrides)), {
1114
1579
  type: "string",
@@ -1127,7 +1592,7 @@ function openGraph(config = {}) {
1127
1592
  hidden: getFieldHiddenFunction("openGraphType", config),
1128
1593
  initialValue: "website"
1129
1594
  })),
1130
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1595
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1131
1596
  name: "imageType"
1132
1597
  }, getFieldInfo("openGraphImageType", config.fieldOverrides)), {
1133
1598
  type: "string",
@@ -1140,7 +1605,7 @@ function openGraph(config = {}) {
1140
1605
  hidden: getFieldHiddenFunction("openGraphImage", config),
1141
1606
  initialValue: "upload"
1142
1607
  })),
1143
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1608
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1144
1609
  name: "image"
1145
1610
  }, getFieldInfo("openGraphImage", config.fieldOverrides)), {
1146
1611
  type: "image",
@@ -1151,7 +1616,7 @@ function openGraph(config = {}) {
1151
1616
  input: OgImage_default
1152
1617
  },
1153
1618
  fields: [
1154
- sanity.defineField({
1619
+ _sanity.defineField.call(void 0, {
1155
1620
  name: "alt",
1156
1621
  title: "Image Alt Text",
1157
1622
  type: "string",
@@ -1165,7 +1630,7 @@ function openGraph(config = {}) {
1165
1630
  return typeof hiddenFn === "function" ? hiddenFn(context) : hiddenFn;
1166
1631
  }
1167
1632
  })),
1168
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1633
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1169
1634
  name: "imageUrl"
1170
1635
  }, getFieldInfo("openGraphImageUrl", config.fieldOverrides)), {
1171
1636
  type: "url",
@@ -1182,19 +1647,38 @@ function openGraph(config = {}) {
1182
1647
  ]
1183
1648
  });
1184
1649
  }
1650
+
1651
+ // src/schemas/types/twitter/index.ts
1652
+
1653
+
1654
+ // src/components/twitter/twitterDescription.tsx
1655
+
1656
+
1657
+
1658
+
1185
1659
  var TwitterDescription = (props) => {
1186
- const { value, renderDefault, path } = props;
1187
- const parent = sanity.useFormValue([path[0]]);
1660
+ const { value, renderDefault, path, schemaType, onChange } = props;
1661
+ const { options } = schemaType;
1662
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
1188
1663
  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),
1664
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1665
+ const feedbackItems = _react.useMemo.call(void 0,
1666
+ () => _chunkY46ACXM4cjs.getTwitterDescriptionValidation.call(void 0, value || "", keywords, isParentseoField),
1192
1667
  [value, keywords, isParentseoField]
1193
1668
  );
1194
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1669
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1195
1670
  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(
1671
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1672
+ SeoGenButton,
1673
+ {
1674
+ field: "twitterDescription",
1675
+ ai: options == null ? void 0 : options.ai,
1676
+ seoFieldPath: String(path[0]),
1677
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1678
+ }
1679
+ ),
1680
+ /* @__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: [
1681
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1198
1682
  "div",
1199
1683
  {
1200
1684
  style: {
@@ -1205,25 +1689,31 @@ var TwitterDescription = (props) => {
1205
1689
  }
1206
1690
  }
1207
1691
  ),
1208
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1692
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1209
1693
  ] }, item.text)) })
1210
1694
  ] });
1211
1695
  };
1212
1696
  var twitterDescription_default = TwitterDescription;
1697
+
1698
+ // src/components/twitter/TwitterImage.tsx
1699
+
1700
+
1701
+
1702
+
1213
1703
  var TwitterImage = (props) => {
1214
1704
  const { value, renderDefault, path } = props;
1215
- const seoParent = sanity.useFormValue([path[0]]);
1705
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
1216
1706
  const imgValue = value;
1217
1707
  const hasImage = !!(imgValue == null ? void 0 : imgValue.asset);
1218
1708
  const altText = imgValue == null ? void 0 : imgValue.alt;
1219
- const feedbackItems = react.useMemo(
1220
- () => chunkZBHLMQTS_cjs.getTwitterImageValidation(hasImage, altText, seoParent),
1709
+ const feedbackItems = _react.useMemo.call(void 0,
1710
+ () => _chunkY46ACXM4cjs.getTwitterImageValidation.call(void 0, hasImage, altText, seoParent),
1221
1711
  [hasImage, altText, seoParent]
1222
1712
  );
1223
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1713
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1224
1714
  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(
1715
+ /* @__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: [
1716
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1227
1717
  "div",
1228
1718
  {
1229
1719
  style: {
@@ -1234,22 +1724,28 @@ var TwitterImage = (props) => {
1234
1724
  }
1235
1725
  }
1236
1726
  ),
1237
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1727
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1238
1728
  ] }, item.text)) })
1239
1729
  ] });
1240
1730
  };
1241
1731
  var TwitterImage_default = TwitterImage;
1732
+
1733
+ // src/components/twitter/TwitterImageUrl.tsx
1734
+
1735
+
1736
+
1737
+
1242
1738
  var TwitterImageUrl = (props) => {
1243
1739
  const { value, renderDefault, path } = props;
1244
- const seoParent = sanity.useFormValue([path[0]]);
1245
- const feedbackItems = react.useMemo(
1246
- () => chunkZBHLMQTS_cjs.getTwitterImageUrlValidation(value, seoParent),
1740
+ const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
1741
+ const feedbackItems = _react.useMemo.call(void 0,
1742
+ () => _chunkY46ACXM4cjs.getTwitterImageUrlValidation.call(void 0, value, seoParent),
1247
1743
  [value, seoParent]
1248
1744
  );
1249
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1745
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1250
1746
  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(
1747
+ /* @__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: [
1748
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1253
1749
  "div",
1254
1750
  {
1255
1751
  style: {
@@ -1260,24 +1756,40 @@ var TwitterImageUrl = (props) => {
1260
1756
  }
1261
1757
  }
1262
1758
  ),
1263
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1759
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1264
1760
  ] }, item.text)) })
1265
1761
  ] });
1266
1762
  };
1267
1763
  var TwitterImageUrl_default = TwitterImageUrl;
1764
+
1765
+ // src/components/twitter/twitterTitle.tsx
1766
+
1767
+
1768
+
1769
+
1268
1770
  var TwitterTitle = (props) => {
1269
- const { value, renderDefault, path } = props;
1270
- const parent = sanity.useFormValue([path[0]]);
1771
+ const { value, renderDefault, path, schemaType, onChange } = props;
1772
+ const { options } = schemaType;
1773
+ const parent = _sanity.useFormValue.call(void 0, [path[0]]);
1271
1774
  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),
1775
+ const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
1776
+ const feedbackItems = _react.useMemo.call(void 0,
1777
+ () => _chunkY46ACXM4cjs.getTwitterTitleValidation.call(void 0, value || "", keywords, isParentseoField),
1275
1778
  [value, keywords, isParentseoField]
1276
1779
  );
1277
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
1780
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
1278
1781
  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(
1782
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1783
+ SeoGenButton,
1784
+ {
1785
+ field: "twitterTitle",
1786
+ ai: options == null ? void 0 : options.ai,
1787
+ seoFieldPath: String(path[0]),
1788
+ onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
1789
+ }
1790
+ ),
1791
+ /* @__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: [
1792
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1281
1793
  "div",
1282
1794
  {
1283
1795
  style: {
@@ -1288,7 +1800,7 @@ var TwitterTitle = (props) => {
1288
1800
  }
1289
1801
  }
1290
1802
  ),
1291
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1803
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
1292
1804
  ] }, item.text)) })
1293
1805
  ] });
1294
1806
  };
@@ -1296,12 +1808,12 @@ var twitterTitle_default = TwitterTitle;
1296
1808
 
1297
1809
  // src/schemas/types/twitter/index.ts
1298
1810
  function twitter(config = {}) {
1299
- return sanity.defineType({
1811
+ return _sanity.defineType.call(void 0, {
1300
1812
  name: "twitter",
1301
1813
  title: "X (Formerly Twitter)",
1302
1814
  type: "object",
1303
1815
  fields: [
1304
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1816
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1305
1817
  name: "card"
1306
1818
  }, getFieldInfo("twitterCard", config.fieldOverrides)), {
1307
1819
  type: "string",
@@ -1317,28 +1829,29 @@ function twitter(config = {}) {
1317
1829
  initialValue: "summary_large_image"
1318
1830
  // good default
1319
1831
  })),
1320
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1832
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1321
1833
  name: "site"
1322
1834
  }, getFieldInfo("twitterSite", config.fieldOverrides)), {
1323
1835
  type: "string",
1324
1836
  hidden: getFieldHiddenFunction("twitterSite", config)
1325
1837
  })),
1326
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1838
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1327
1839
  name: "creator",
1328
1840
  type: "string"
1329
1841
  }, getFieldInfo("twitterCreator", config.fieldOverrides)), {
1330
1842
  hidden: getFieldHiddenFunction("twitterCreator", config)
1331
1843
  })),
1332
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1844
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1333
1845
  name: "title",
1334
1846
  type: "string"
1335
1847
  }, getFieldInfo("twitterTitle", config.fieldOverrides)), {
1336
1848
  hidden: getFieldHiddenFunction("twitterTitle", config),
1337
1849
  components: {
1338
1850
  input: twitterTitle_default
1339
- }
1851
+ },
1852
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
1340
1853
  })),
1341
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1854
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1342
1855
  name: "description",
1343
1856
  type: "text",
1344
1857
  rows: 3
@@ -1346,9 +1859,10 @@ function twitter(config = {}) {
1346
1859
  hidden: getFieldHiddenFunction("twitterDescription", config),
1347
1860
  components: {
1348
1861
  input: twitterDescription_default
1349
- }
1862
+ },
1863
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
1350
1864
  })),
1351
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1865
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1352
1866
  name: "imageType"
1353
1867
  }, getFieldInfo("twitterImageType", config.fieldOverrides)), {
1354
1868
  type: "string",
@@ -1361,7 +1875,7 @@ function twitter(config = {}) {
1361
1875
  hidden: getFieldHiddenFunction("twitterImage", config),
1362
1876
  initialValue: "upload"
1363
1877
  })),
1364
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1878
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1365
1879
  name: "image"
1366
1880
  }, getFieldInfo("twitterImage", config.fieldOverrides)), {
1367
1881
  type: "image",
@@ -1372,7 +1886,7 @@ function twitter(config = {}) {
1372
1886
  input: TwitterImage_default
1373
1887
  },
1374
1888
  fields: [
1375
- sanity.defineField({
1889
+ _sanity.defineField.call(void 0, {
1376
1890
  name: "alt",
1377
1891
  title: "Image Alt Text",
1378
1892
  type: "string",
@@ -1386,7 +1900,7 @@ function twitter(config = {}) {
1386
1900
  return typeof hiddenFn === "function" ? hiddenFn(context) : hiddenFn;
1387
1901
  }
1388
1902
  })),
1389
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
1903
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1390
1904
  name: "imageUrl"
1391
1905
  }, getFieldInfo("twitterImageUrl", config.fieldOverrides)), {
1392
1906
  type: "url",
@@ -1405,8 +1919,8 @@ function twitter(config = {}) {
1405
1919
  }
1406
1920
 
1407
1921
  // 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));
1922
+ var LazySeoPreview = _react.lazy.call(void 0, () => Promise.resolve().then(() => _interopRequireWildcard(require("./SeoPreview-LMZAWWOE.cjs"))));
1923
+ var SeoPreviewWrapper = (props) => _react.createElement.call(void 0, _react.Suspense, { fallback: null }, _react.createElement.call(void 0, LazySeoPreview, props));
1410
1924
  function buildFieldGroupMap(groups) {
1411
1925
  const map = /* @__PURE__ */ new Map();
1412
1926
  for (const g of groups) {
@@ -1438,20 +1952,88 @@ function withGroup(field, fieldGroupMap) {
1438
1952
  if (!fieldGroupMap) return field;
1439
1953
  const groups = fieldGroupMap.get(field.name);
1440
1954
  if (!groups || groups.length === 0) return field;
1441
- return chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({}, field), { group: groups.length === 1 ? groups[0] : groups });
1955
+ return _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, field), { group: groups.length === 1 ? groups[0] : groups });
1956
+ }
1957
+ function shouldShowPreviewField(seoPreview) {
1958
+ if (typeof seoPreview === "boolean") return seoPreview;
1959
+ if (typeof seoPreview === "object") return !isEmpty(seoPreview);
1960
+ return false;
1961
+ }
1962
+ function getSeoPreviewSuffixOptions(seoPreview) {
1963
+ if (typeof seoPreview !== "object" || !seoPreview) return {};
1964
+ const extra = {};
1965
+ if (seoPreview.titleSuffix) extra.titleSuffix = seoPreview.titleSuffix;
1966
+ if (seoPreview.titleSuffixQuery) extra.titleSuffixQuery = seoPreview.titleSuffixQuery;
1967
+ return extra;
1968
+ }
1969
+ function getPreviewFieldOptions(config) {
1970
+ const seoPreview = config.seoPreview;
1971
+ const extra = {};
1972
+ if (typeof seoPreview === "object" && seoPreview) {
1973
+ if (seoPreview.prefix) extra.prefix = seoPreview.prefix;
1974
+ if (seoPreview.titleSuffixInheritColor) {
1975
+ extra.titleSuffixInheritColor = seoPreview.titleSuffixInheritColor;
1976
+ }
1977
+ }
1978
+ return _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1979
+ baseUrl: config.baseUrl || "https://www.example.com"
1980
+ }, config.apiVersion ? { apiVersion: config.apiVersion } : {}), getSeoPreviewSuffixOptions(seoPreview)), extra);
1981
+ }
1982
+ function getAiOption(config) {
1983
+ return config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {};
1984
+ }
1985
+ function getTitleFieldOptions(config) {
1986
+ 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));
1987
+ }
1988
+ function buildGeoChecklistField(config, fieldGroupMap) {
1989
+ if (config.geo === false) return [];
1990
+ return [
1991
+ withGroup(
1992
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1993
+ name: "geoChecklist"
1994
+ }, getFieldInfo("geoChecklist", config.fieldOverrides)), {
1995
+ type: "string",
1996
+ readOnly: true,
1997
+ components: {
1998
+ input: GEOChecklist_default
1999
+ },
2000
+ options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.licenseKey ? { licenseKey: config.licenseKey } : {}),
2001
+ hidden: getFieldHiddenFunction("geoChecklist", config)
2002
+ })),
2003
+ fieldGroupMap
2004
+ )
2005
+ ];
2006
+ }
2007
+ function buildMetaTagsPreviewField(config, fieldGroupMap) {
2008
+ if (config.metaTagsPreview === false) return [];
2009
+ return [
2010
+ withGroup(
2011
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
2012
+ name: "metaTagsPreview"
2013
+ }, getFieldInfo("metaTagsPreview", config.fieldOverrides)), {
2014
+ type: "string",
2015
+ readOnly: true,
2016
+ components: {
2017
+ input: MetaTagsPreview_default
2018
+ },
2019
+ hidden: getFieldHiddenFunction("metaTagsPreview", config)
2020
+ })),
2021
+ fieldGroupMap
2022
+ )
2023
+ ];
1442
2024
  }
1443
2025
  function seoFieldsSchema(config = {}) {
1444
2026
  const groupsCfg = config.fieldGroups;
1445
2027
  const fieldGroupMap = (groupsCfg == null ? void 0 : groupsCfg.length) ? buildFieldGroupMap(groupsCfg) : void 0;
1446
2028
  const sanityGroups = (groupsCfg == null ? void 0 : groupsCfg.length) ? toSanityGroups(groupsCfg) : void 0;
1447
- return sanity.defineType(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2029
+ return _sanity.defineType.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1448
2030
  name: "seoFields",
1449
2031
  title: "SEO Fields",
1450
2032
  type: "object"
1451
2033
  }, sanityGroups ? { groups: sanityGroups } : {}), {
1452
2034
  fields: [
1453
2035
  withGroup(
1454
- sanity.defineField({
2036
+ _sanity.defineField.call(void 0, {
1455
2037
  name: "robots",
1456
2038
  title: "Robots Settings",
1457
2039
  type: "robots",
@@ -1460,16 +2042,14 @@ function seoFieldsSchema(config = {}) {
1460
2042
  fieldGroupMap
1461
2043
  ),
1462
2044
  // 👇 conditionally spread preview field
1463
- ...typeof config.seoPreview === "boolean" && config.seoPreview || typeof config.seoPreview === "object" && !isEmpty(config.seoPreview) ? [
2045
+ ...shouldShowPreviewField(config.seoPreview) ? [
1464
2046
  withGroup(
1465
- sanity.defineField({
2047
+ _sanity.defineField.call(void 0, {
1466
2048
  name: "preview",
1467
2049
  title: "SEO Preview",
1468
2050
  type: "string",
1469
2051
  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 } : {}),
2052
+ options: getPreviewFieldOptions(config),
1473
2053
  initialValue: "",
1474
2054
  readOnly: true
1475
2055
  }),
@@ -1477,20 +2057,20 @@ function seoFieldsSchema(config = {}) {
1477
2057
  )
1478
2058
  ] : [],
1479
2059
  withGroup(
1480
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2060
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1481
2061
  name: "title"
1482
2062
  }, getFieldInfo("title", config.fieldOverrides)), {
1483
2063
  type: "string",
1484
2064
  components: {
1485
2065
  input: MetaTitle_default
1486
2066
  },
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 } : {}),
2067
+ options: getTitleFieldOptions(config),
1488
2068
  hidden: getFieldHiddenFunction("title", config)
1489
2069
  })),
1490
2070
  fieldGroupMap
1491
2071
  ),
1492
2072
  withGroup(
1493
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2073
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1494
2074
  name: "description"
1495
2075
  }, getFieldInfo("description", config.fieldOverrides)), {
1496
2076
  type: "text",
@@ -1498,12 +2078,13 @@ function seoFieldsSchema(config = {}) {
1498
2078
  components: {
1499
2079
  input: MetaDescription_default
1500
2080
  },
2081
+ options: getAiOption(config),
1501
2082
  hidden: getFieldHiddenFunction("description", config)
1502
2083
  })),
1503
2084
  fieldGroupMap
1504
2085
  ),
1505
2086
  withGroup(
1506
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2087
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1507
2088
  name: "metaImage"
1508
2089
  }, getFieldInfo("metaImage", config.fieldOverrides)), {
1509
2090
  type: "image",
@@ -1518,7 +2099,7 @@ function seoFieldsSchema(config = {}) {
1518
2099
  fieldGroupMap
1519
2100
  ),
1520
2101
  withGroup(
1521
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2102
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1522
2103
  name: "metaAttributes"
1523
2104
  }, getFieldInfo("metaAttributes", config.fieldOverrides)), {
1524
2105
  type: "array",
@@ -1528,19 +2109,21 @@ function seoFieldsSchema(config = {}) {
1528
2109
  fieldGroupMap
1529
2110
  ),
1530
2111
  withGroup(
1531
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2112
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1532
2113
  name: "keywords"
1533
2114
  }, getFieldInfo("keywords", config.fieldOverrides)), {
1534
2115
  title: "Keywords",
1535
2116
  type: "array",
1536
2117
  of: [{ type: "string" }],
1537
2118
  description: "Add relevant keywords for this page. These keywords will be used for SEO purposes.",
2119
+ components: config.ai ? { input: KeywordsInput_default } : void 0,
2120
+ options: getAiOption(config),
1538
2121
  hidden: getFieldHiddenFunction("keywords", config)
1539
2122
  })),
1540
2123
  fieldGroupMap
1541
2124
  ),
1542
2125
  withGroup(
1543
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2126
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1544
2127
  name: "canonicalUrl"
1545
2128
  }, getFieldInfo("canonicalUrl", config.fieldOverrides)), {
1546
2129
  title: "Canonical URL",
@@ -1551,19 +2134,20 @@ function seoFieldsSchema(config = {}) {
1551
2134
  fieldGroupMap
1552
2135
  ),
1553
2136
  withGroup(
1554
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2137
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1555
2138
  name: "focusKeyword"
1556
2139
  }, getFieldInfo("focusKeyword", config.fieldOverrides)), {
1557
2140
  type: "string",
1558
2141
  components: {
1559
2142
  input: FocusKeywordInput_default
1560
2143
  },
2144
+ options: getAiOption(config),
1561
2145
  hidden: getFieldHiddenFunction("focusKeyword", config)
1562
2146
  })),
1563
2147
  fieldGroupMap
1564
2148
  ),
1565
2149
  withGroup(
1566
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2150
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1567
2151
  name: "hreflangs"
1568
2152
  }, getFieldInfo("hreflangs", config.fieldOverrides)), {
1569
2153
  type: "array",
@@ -1573,49 +2157,23 @@ function seoFieldsSchema(config = {}) {
1573
2157
  })),
1574
2158
  fieldGroupMap
1575
2159
  ),
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
- ],
2160
+ ...buildGeoChecklistField(config, fieldGroupMap),
2161
+ ...buildMetaTagsPreviewField(config, fieldGroupMap),
1607
2162
  withGroup(openGraph(config), fieldGroupMap),
1608
2163
  withGroup(twitter(config), fieldGroupMap)
1609
2164
  ]
1610
2165
  }));
1611
2166
  }
2167
+
2168
+ // src/schemas/types/baseMeta/index.ts
2169
+
1612
2170
  function baseMeta(config = {}) {
1613
- return sanity.defineType({
2171
+ return _sanity.defineType.call(void 0, {
1614
2172
  name: "baseMeta",
1615
2173
  title: "Basic Meta Settings",
1616
2174
  type: "object",
1617
2175
  fields: [
1618
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2176
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1619
2177
  name: "title"
1620
2178
  }, getFieldInfo("title", config.fieldOverrides)), {
1621
2179
  type: "string",
@@ -1624,7 +2182,7 @@ function baseMeta(config = {}) {
1624
2182
  },
1625
2183
  hidden: getFieldHiddenFunction("title", config)
1626
2184
  })),
1627
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2185
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1628
2186
  name: "description"
1629
2187
  }, getFieldInfo("description", config.fieldOverrides)), {
1630
2188
  type: "text",
@@ -1634,7 +2192,7 @@ function baseMeta(config = {}) {
1634
2192
  },
1635
2193
  hidden: getFieldHiddenFunction("description", config)
1636
2194
  })),
1637
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2195
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1638
2196
  name: "metaImage"
1639
2197
  }, getFieldInfo("metaImage", config.fieldOverrides)), {
1640
2198
  type: "image",
@@ -1646,7 +2204,7 @@ function baseMeta(config = {}) {
1646
2204
  },
1647
2205
  hidden: getFieldHiddenFunction("metaImage", config)
1648
2206
  })),
1649
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2207
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1650
2208
  name: "keywords"
1651
2209
  }, getFieldInfo("keywords", config.fieldOverrides)), {
1652
2210
  title: "Keywords",
@@ -1655,7 +2213,7 @@ function baseMeta(config = {}) {
1655
2213
  description: "Add relevant keywords for this page. These keywords will be used for SEO purposes.",
1656
2214
  hidden: getFieldHiddenFunction("keywords", config)
1657
2215
  })),
1658
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2216
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1659
2217
  name: "canonicalUrl"
1660
2218
  }, getFieldInfo("canonicalUrl", config.fieldOverrides)), {
1661
2219
  title: "Canonical URL",
@@ -1663,7 +2221,7 @@ function baseMeta(config = {}) {
1663
2221
  description: "Specify the canonical URL for this page. This helps prevent duplicate content issues by indicating the preferred version of a page.",
1664
2222
  hidden: getFieldHiddenFunction("canonicalUrl", config)
1665
2223
  })),
1666
- sanity.defineField(chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({
2224
+ _sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1667
2225
  name: "metaAttributes"
1668
2226
  }, getFieldInfo("metaAttributes", config.fieldOverrides)), {
1669
2227
  type: "array",
@@ -1673,12 +2231,15 @@ function baseMeta(config = {}) {
1673
2231
  ]
1674
2232
  });
1675
2233
  }
1676
- var hreflang_default = sanity.defineType({
2234
+
2235
+ // src/schemas/types/hreflang/index.ts
2236
+
2237
+ var hreflang_default = _sanity.defineType.call(void 0, {
1677
2238
  name: "hreflangEntry",
1678
2239
  title: "Hreflang Entry",
1679
2240
  type: "object",
1680
2241
  fields: [
1681
- sanity.defineField({
2242
+ _sanity.defineField.call(void 0, {
1682
2243
  name: "locale",
1683
2244
  title: "Language / Region",
1684
2245
  type: "string",
@@ -1691,7 +2252,7 @@ var hreflang_default = sanity.defineType({
1691
2252
  return true;
1692
2253
  })
1693
2254
  }),
1694
- sanity.defineField({
2255
+ _sanity.defineField.call(void 0, {
1695
2256
  name: "url",
1696
2257
  title: "URL",
1697
2258
  type: "url",
@@ -1705,17 +2266,20 @@ var hreflang_default = sanity.defineType({
1705
2266
  }
1706
2267
  }
1707
2268
  });
1708
- var metaAttribute_default = sanity.defineType({
2269
+
2270
+ // src/schemas/types/metaAttribute/index.ts
2271
+
2272
+ var metaAttribute_default = _sanity.defineType.call(void 0, {
1709
2273
  name: "metaAttribute",
1710
2274
  title: "Meta Attribute",
1711
2275
  type: "object",
1712
2276
  fields: [
1713
- sanity.defineField({
2277
+ _sanity.defineField.call(void 0, {
1714
2278
  name: "key",
1715
2279
  title: "Attribute Name",
1716
2280
  type: "string"
1717
2281
  }),
1718
- sanity.defineField({
2282
+ _sanity.defineField.call(void 0, {
1719
2283
  name: "type",
1720
2284
  title: "Attribute Value Type",
1721
2285
  type: "string",
@@ -1727,13 +2291,13 @@ var metaAttribute_default = sanity.defineType({
1727
2291
  },
1728
2292
  initialValue: "string"
1729
2293
  }),
1730
- sanity.defineField({
2294
+ _sanity.defineField.call(void 0, {
1731
2295
  name: "value",
1732
2296
  title: "Attribute Value",
1733
2297
  type: "string",
1734
2298
  hidden: ({ parent }) => (parent == null ? void 0 : parent.type) === "image"
1735
2299
  }),
1736
- sanity.defineField({
2300
+ _sanity.defineField.call(void 0, {
1737
2301
  name: "image",
1738
2302
  title: "Attribute Image Value",
1739
2303
  type: "image",
@@ -1763,7 +2327,10 @@ var metaAttribute_default = sanity.defineType({
1763
2327
  }
1764
2328
  }
1765
2329
  });
1766
- var metaTag_default = sanity.defineType({
2330
+
2331
+ // src/schemas/types/metaTag/index.ts
2332
+
2333
+ var metaTag_default = _sanity.defineType.call(void 0, {
1767
2334
  name: "metaTag",
1768
2335
  title: "Meta Tag",
1769
2336
  type: "object",
@@ -1777,33 +2344,36 @@ var metaTag_default = sanity.defineType({
1777
2344
  }
1778
2345
  ]
1779
2346
  });
1780
- var robots_default = sanity.defineType({
2347
+
2348
+ // src/schemas/types/robots/index.ts
2349
+
2350
+ var robots_default = _sanity.defineType.call(void 0, {
1781
2351
  name: "robots",
1782
2352
  title: "Robots Settings",
1783
2353
  type: "object",
1784
2354
  fields: [
1785
- sanity.defineField({
2355
+ _sanity.defineField.call(void 0, {
1786
2356
  name: "noIndex",
1787
2357
  title: "No Index",
1788
2358
  type: "boolean",
1789
2359
  initialValue: false,
1790
2360
  description: "Enable this to prevent search engines from indexing this page. The page will not appear in search results."
1791
2361
  }),
1792
- sanity.defineField({
2362
+ _sanity.defineField.call(void 0, {
1793
2363
  name: "noFollow",
1794
2364
  title: "No Follow",
1795
2365
  type: "boolean",
1796
2366
  initialValue: false,
1797
2367
  description: "Enable this to prevent search engines from following links on this page. Links will not pass SEO value."
1798
2368
  }),
1799
- sanity.defineField({
2369
+ _sanity.defineField.call(void 0, {
1800
2370
  name: "noTranslate",
1801
2371
  title: "No Translate",
1802
2372
  type: "boolean",
1803
2373
  initialValue: false,
1804
2374
  description: "Enable this to prevent search engines from offering a translated version of this page in search results."
1805
2375
  }),
1806
- sanity.defineField({
2376
+ _sanity.defineField.call(void 0, {
1807
2377
  name: "noImageIndex",
1808
2378
  title: "No Image Index",
1809
2379
  type: "boolean",
@@ -1896,15 +2466,15 @@ var resolveDashboardConfig = (healthDashboard, rootApiVersion, rootLicenseKey) =
1896
2466
  deprecationWarnings
1897
2467
  };
1898
2468
  };
1899
- var seofields = sanity.definePlugin((config = {}) => {
2469
+ var seofields = _sanity.definePlugin.call(void 0, (config = {}) => {
1900
2470
  const cfg = config;
1901
2471
  const { healthDashboard = true, licenseKey, publishGate } = cfg;
1902
2472
  const dash = resolveDashboardConfig(healthDashboard, cfg.apiVersion, licenseKey);
1903
- const LazySeoHealthTool = react.lazy(() => import('./SeoHealthTool-2KKQJLJL.cjs'));
1904
- const BoundSeoHealthTool = () => react.createElement(
1905
- react.Suspense,
2473
+ const LazySeoHealthTool = _react.lazy.call(void 0, () => Promise.resolve().then(() => _interopRequireWildcard(require("./SeoHealthTool-2COI27KI.cjs"))));
2474
+ const BoundSeoHealthTool = () => _react.createElement.call(void 0,
2475
+ _react.Suspense,
1906
2476
  { fallback: null },
1907
- react.createElement(LazySeoHealthTool, {
2477
+ _react.createElement.call(void 0, LazySeoHealthTool, {
1908
2478
  icon: dash.icon,
1909
2479
  title: dash.title,
1910
2480
  description: dash.description,
@@ -1930,7 +2500,7 @@ var seofields = sanity.definePlugin((config = {}) => {
1930
2500
  _deprecationWarnings: dash.deprecationWarnings
1931
2501
  })
1932
2502
  );
1933
- return chunk254YHUN3_cjs.__spreadValues(chunk254YHUN3_cjs.__spreadValues({
2503
+ return _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
1934
2504
  name: "sanity-plugin-seofields",
1935
2505
  schema: {
1936
2506
  types: types(cfg)
@@ -1942,7 +2512,7 @@ var seofields = sanity.definePlugin((config = {}) => {
1942
2512
  if (((_a = publishGate.types) == null ? void 0 : _a.length) && !publishGate.types.includes(context.schemaType))
1943
2513
  return prev;
1944
2514
  return prev.map(
1945
- (Action) => Action.action === "publish" ? chunkBNXMFD3T_cjs.createSeoPublishGateAction(Action, chunk254YHUN3_cjs.__spreadProps(chunk254YHUN3_cjs.__spreadValues({}, publishGate), { licenseKey })) : Action
2515
+ (Action) => Action.action === "publish" ? _seofieldspro.createSeoPublishGateAction.call(void 0, Action, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, publishGate), { licenseKey })) : Action
1946
2516
  );
1947
2517
  }
1948
2518
  }
@@ -1959,6 +2529,10 @@ var seofields = sanity.definePlugin((config = {}) => {
1959
2529
  });
1960
2530
  var plugin_default = seofields;
1961
2531
 
2532
+ // src/components/SeoHealthPane.tsx
2533
+
2534
+
2535
+
1962
2536
  // src/utils/scoring.ts
1963
2537
  var getStatusCategory = (score) => {
1964
2538
  if (score >= 80) return "excellent";
@@ -2027,6 +2601,50 @@ var scoreTwitterCard = (twitter2) => {
2027
2601
  }
2028
2602
  return { score, issues };
2029
2603
  };
2604
+ var scoreKeywordArray = (keywords, title, description) => {
2605
+ if (!keywords || keywords.length === 0) {
2606
+ return { score: 0, issues: ["No keywords defined"], stuffed: false };
2607
+ }
2608
+ const issues = [];
2609
+ let score = 2;
2610
+ if (_chunkY46ACXM4cjs.hasMatchingKeyword.call(void 0, title || "", keywords) || _chunkY46ACXM4cjs.hasMatchingKeyword.call(void 0, description || "", keywords)) {
2611
+ score += 3;
2612
+ } else {
2613
+ issues.push("Keywords defined but not used in title or description");
2614
+ }
2615
+ const stuffed = _chunkY46ACXM4cjs.hasKeywordOveruse.call(void 0, title || "", keywords) || _chunkY46ACXM4cjs.hasKeywordOveruse.call(void 0, description || "", keywords);
2616
+ if (stuffed) issues.push("Keyword stuffing detected \u2014 reduce repeated keyword usage");
2617
+ return { score, issues, stuffed };
2618
+ };
2619
+ var scoreFocusKeyword = (focusKeyword, title, description) => {
2620
+ const placement = _chunkY46ACXM4cjs.getFocusKeywordPlacement.call(void 0, focusKeyword, title, description);
2621
+ if (!placement.hasFocusKeyword) {
2622
+ return { score: 0, issues: ["No focus keyword defined"], stuffed: false };
2623
+ }
2624
+ const issues = [];
2625
+ let score = 1;
2626
+ if (placement.atStartOfTitle) {
2627
+ score += 4;
2628
+ } else if (placement.inTitle) {
2629
+ score += 2;
2630
+ issues.push("Focus keyword is in the title but not at the start");
2631
+ } else if (placement.inDescription) {
2632
+ score += 1;
2633
+ issues.push("Focus keyword missing from meta title");
2634
+ } else {
2635
+ issues.push("Focus keyword missing from meta title and description");
2636
+ }
2637
+ if (placement.isStuffed)
2638
+ issues.push("Focus keyword appears too many times in title \u2014 avoid stuffing");
2639
+ return { score, issues, stuffed: placement.isStuffed };
2640
+ };
2641
+ var scoreKeywordOptimization = (keywords, focusKeyword, title, description) => {
2642
+ const arrayResult = scoreKeywordArray(keywords, title, description);
2643
+ const focusResult = scoreFocusKeyword(focusKeyword, title, description);
2644
+ let score = arrayResult.score + focusResult.score;
2645
+ if (arrayResult.stuffed || focusResult.stuffed) score = Math.max(0, score - 2);
2646
+ return { score: Math.min(score, 10), issues: [...arrayResult.issues, ...focusResult.issues] };
2647
+ };
2030
2648
  var calculateHealthScore = (doc) => {
2031
2649
  if (!doc.seo) {
2032
2650
  return { score: 0, status: "missing", issues: ["SEO fields not configured"] };
@@ -2035,6 +2653,7 @@ var calculateHealthScore = (doc) => {
2035
2653
  const title = seo.title;
2036
2654
  const description = seo.description;
2037
2655
  const keywords = seo.keywords;
2656
+ const focusKeyword = seo.focusKeyword;
2038
2657
  const robots = seo.robots;
2039
2658
  const openGraph2 = seo.openGraph;
2040
2659
  const twitter2 = seo.twitter;
@@ -2048,8 +2667,9 @@ var calculateHealthScore = (doc) => {
2048
2667
  issues.push(...descResult.issues);
2049
2668
  if (seo.metaImage) score += 10;
2050
2669
  else issues.push("Missing meta image");
2051
- if (keywords && keywords.length > 0) score += 10;
2052
- else issues.push("No keywords defined");
2670
+ const keywordResult = scoreKeywordOptimization(keywords, focusKeyword, title, description);
2671
+ score += keywordResult.score;
2672
+ issues.push(...keywordResult.issues);
2053
2673
  if (robots && !robots.noIndex) score += 5;
2054
2674
  else if (!robots) score += 5;
2055
2675
  const ogResult = scoreOpenGraph(openGraph2);
@@ -2077,27 +2697,18 @@ var calculateHealthScore = (doc) => {
2077
2697
  // src/index.ts
2078
2698
  var src_default = plugin_default;
2079
2699
 
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
2700
+
2701
+
2702
+
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+
2713
+ 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
2714
  //# sourceMappingURL=index.cjs.map