sanity-plugin-seofields 1.4.1 → 1.5.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 (57) hide show
  1. package/README.md +1 -1
  2. package/dist/SeoHealthDashboard-3VBITMWT.cjs +10 -0
  3. package/dist/SeoHealthDashboard-3VBITMWT.cjs.map +1 -0
  4. package/dist/SeoHealthDashboard-BNJBRQVN.js +4 -0
  5. package/dist/SeoHealthDashboard-BNJBRQVN.js.map +1 -0
  6. package/dist/SeoHealthTool-4P6JST5S.cjs +14 -0
  7. package/dist/SeoHealthTool-4P6JST5S.cjs.map +1 -0
  8. package/dist/SeoHealthTool-MQBE5YGN.js +12 -0
  9. package/dist/SeoHealthTool-MQBE5YGN.js.map +1 -0
  10. package/dist/SeoPreview-G3LPA7GV.js +148 -0
  11. package/dist/SeoPreview-G3LPA7GV.js.map +1 -0
  12. package/dist/SeoPreview-Y3CFDVBR.cjs +154 -0
  13. package/dist/SeoPreview-Y3CFDVBR.cjs.map +1 -0
  14. package/dist/chunk-25JLWVEU.js +472 -0
  15. package/dist/chunk-25JLWVEU.js.map +1 -0
  16. package/dist/chunk-2NMEKWO5.js +35 -0
  17. package/dist/chunk-2NMEKWO5.js.map +1 -0
  18. package/dist/chunk-527WXITP.js +428 -0
  19. package/dist/chunk-527WXITP.js.map +1 -0
  20. package/dist/chunk-6CYMVS3O.js +1245 -0
  21. package/dist/chunk-6CYMVS3O.js.map +1 -0
  22. package/dist/chunk-D2GWRRK5.cjs +1293 -0
  23. package/dist/chunk-D2GWRRK5.cjs.map +1 -0
  24. package/dist/chunk-DYVCCQHT.cjs +1400 -0
  25. package/dist/chunk-DYVCCQHT.cjs.map +1 -0
  26. package/dist/chunk-IFDLKZET.cjs +485 -0
  27. package/dist/chunk-IFDLKZET.cjs.map +1 -0
  28. package/dist/chunk-L3L3FSPJ.cjs +478 -0
  29. package/dist/chunk-L3L3FSPJ.cjs.map +1 -0
  30. package/dist/chunk-S367Y35J.cjs +39 -0
  31. package/dist/chunk-S367Y35J.cjs.map +1 -0
  32. package/dist/chunk-WUIZN7VI.js +1394 -0
  33. package/dist/chunk-WUIZN7VI.js.map +1 -0
  34. package/dist/cli.js +67 -0
  35. package/dist/define-cli.cjs +12 -0
  36. package/dist/define-cli.cjs.map +1 -0
  37. package/dist/define-cli.d.cts +42 -0
  38. package/dist/define-cli.d.ts +42 -0
  39. package/dist/define-cli.js +10 -0
  40. package/dist/define-cli.js.map +1 -0
  41. package/dist/index.cjs +154 -2365
  42. package/dist/index.cjs.map +1 -1
  43. package/dist/index.js +109 -2303
  44. package/dist/index.js.map +1 -1
  45. package/dist/next.cjs +235 -1591
  46. package/dist/next.cjs.map +1 -1
  47. package/dist/next.js +7 -1482
  48. package/dist/next.js.map +1 -1
  49. package/dist/schema/next.cjs +200 -1542
  50. package/dist/schema/next.cjs.map +1 -1
  51. package/dist/schema/next.js +4 -1475
  52. package/dist/schema/next.js.map +1 -1
  53. package/dist/schema.cjs +252 -1514
  54. package/dist/schema.cjs.map +1 -1
  55. package/dist/schema.js +58 -1391
  56. package/dist/schema.js.map +1 -1
  57. package/package.json +21 -5
@@ -0,0 +1,472 @@
1
+ // src/utils/seoUtils.ts
2
+ var stopWords = ["the", "a", "an", "and", "or", "but"];
3
+ var hasMatchingKeyword = (title, keywordList) => {
4
+ if (!title || keywordList.length === 0) return false;
5
+ const lowerTitle = title.toLowerCase();
6
+ return keywordList.some((keyword) => keyword && lowerTitle.includes(keyword.toLowerCase()));
7
+ };
8
+ var hasKeywordOveruse = (title, keywordList, maxOccurrences = 3) => {
9
+ if (!title || keywordList.length === 0) return false;
10
+ const lowerTitle = title.toLowerCase();
11
+ return keywordList.some((keyword) => {
12
+ if (!keyword) return false;
13
+ const matches = lowerTitle.match(new RegExp(keyword.toLowerCase(), "g"));
14
+ return matches ? matches.length > maxOccurrences : false;
15
+ });
16
+ };
17
+ var startsWithStopWord = (title) => {
18
+ if (!title) return false;
19
+ const firstWord = title.trim().split(" ")[0].toLowerCase();
20
+ return stopWords.includes(firstWord);
21
+ };
22
+ var truncate = (text, maxLength) => text.length > maxLength ? `${text.slice(0, maxLength)}\u2026` : text;
23
+ var hasExcessivePunctuation = (title) => /[!@#$%^&*]{2,}/.test(title);
24
+ var getMetaTitleValidationMessages = (title, keywords, isParentseoField) => {
25
+ const feedback = [];
26
+ const minChar = 50;
27
+ const maxChar = 60;
28
+ const charCount = (title == null ? void 0 : title.length) || 0;
29
+ if (!(title == null ? void 0 : title.trim())) {
30
+ feedback.push({ text: "Meta Title is empty. Add content to improve SEO.", color: "red" });
31
+ return feedback;
32
+ }
33
+ if (charCount < minChar)
34
+ feedback.push({
35
+ text: `Title is ${charCount} characters \u2014 below recommended ${minChar}.`,
36
+ color: "orange"
37
+ });
38
+ else if (charCount > maxChar)
39
+ feedback.push({
40
+ text: `Title is ${charCount} characters \u2014 exceeds recommended ${maxChar}.`,
41
+ color: "red"
42
+ });
43
+ else feedback.push({ text: `Title length (${charCount}) looks good for SEO.`, color: "green" });
44
+ if (isParentseoField) {
45
+ if (keywords.length > 0) {
46
+ const hasKeyword = hasMatchingKeyword(title, keywords);
47
+ feedback.push({
48
+ text: hasKeyword ? "Keyword found in title \u2014 good job!" : "Keywords defined but missing in title.",
49
+ color: hasKeyword ? "green" : "red"
50
+ });
51
+ if (hasKeywordOveruse(title, keywords)) {
52
+ feedback.push({
53
+ text: "Keyword appears too many times \u2014 avoid keyword stuffing.",
54
+ color: "orange"
55
+ });
56
+ }
57
+ } else {
58
+ feedback.push({
59
+ text: "No keywords defined. Consider adding relevant keywords.",
60
+ color: "orange"
61
+ });
62
+ }
63
+ }
64
+ if (startsWithStopWord(title))
65
+ feedback.push({ text: "Title starts with a stop word \u2014 consider rephrasing.", color: "orange" });
66
+ if (hasExcessivePunctuation(title))
67
+ feedback.push({ text: "Title contains excessive punctuation \u2014 simplify it.", color: "orange" });
68
+ return feedback;
69
+ };
70
+ var getMetaDescriptionValidationMessages = (description, keywords, isParentseoField) => {
71
+ const feedback = [];
72
+ const minChar = 120;
73
+ const maxChar = 160;
74
+ const charCount = (description == null ? void 0 : description.length) || 0;
75
+ if (!(description == null ? void 0 : description.trim())) {
76
+ feedback.push({ text: "Meta description is empty. Add content to improve SEO.", color: "red" });
77
+ return feedback;
78
+ }
79
+ if (charCount < minChar)
80
+ feedback.push({
81
+ text: `Description is ${charCount} chars \u2014 below recommended ${minChar}.`,
82
+ color: "orange"
83
+ });
84
+ else if (charCount > maxChar)
85
+ feedback.push({
86
+ text: `Description is ${charCount} chars \u2014 exceeds recommended ${maxChar}.`,
87
+ color: "red"
88
+ });
89
+ else
90
+ feedback.push({ text: `Description length (${charCount}) looks good for SEO.`, color: "green" });
91
+ if (isParentseoField) {
92
+ if (keywords.length > 0) {
93
+ const hasKeyword = hasMatchingKeyword(description, keywords);
94
+ feedback.push({
95
+ text: hasKeyword ? "Keyword found in description \u2014 good job!" : "Keywords defined but missing in description.",
96
+ color: hasKeyword ? "green" : "red"
97
+ });
98
+ if (hasKeywordOveruse(description, keywords)) {
99
+ feedback.push({
100
+ text: "Keyword appears too many times \u2014 avoid keyword stuffing.",
101
+ color: "orange"
102
+ });
103
+ }
104
+ } else {
105
+ feedback.push({
106
+ text: "No keywords defined. Consider adding relevant keywords.",
107
+ color: "orange"
108
+ });
109
+ }
110
+ }
111
+ if (startsWithStopWord(description))
112
+ feedback.push({
113
+ text: "Description starts with a stop word \u2014 consider rephrasing.",
114
+ color: "orange"
115
+ });
116
+ if (hasExcessivePunctuation(description))
117
+ feedback.push({
118
+ text: "Description contains excessive punctuation \u2014 simplify it.",
119
+ color: "orange"
120
+ });
121
+ return feedback;
122
+ };
123
+ var getOgTitleValidation = (title, keywords = [], isParentseoField) => {
124
+ const feedback = [];
125
+ const min = 40;
126
+ const max = 60;
127
+ const count = (title == null ? void 0 : title.length) || 0;
128
+ if (!(title == null ? void 0 : title.trim())) {
129
+ feedback.push({ text: "OG Title is empty. Add content for better social preview.", color: "red" });
130
+ return feedback;
131
+ }
132
+ if (count < min)
133
+ feedback.push({
134
+ text: `OG Title is ${count} chars \u2014 shorter than recommended ${min}.`,
135
+ color: "orange"
136
+ });
137
+ else if (count > max)
138
+ feedback.push({ text: `OG Title is ${count} chars \u2014 exceeds recommended ${max}.`, color: "red" });
139
+ else feedback.push({ text: `OG Title length (${count}) looks good.`, color: "green" });
140
+ if (isParentseoField) {
141
+ if (keywords.length > 0) {
142
+ const hasKeyword = hasMatchingKeyword(title, keywords);
143
+ feedback.push({
144
+ text: hasKeyword ? "Keyword found in OG title \u2014 good job!" : "Keywords defined but missing in OG title.",
145
+ color: hasKeyword ? "green" : "red"
146
+ });
147
+ if (hasKeywordOveruse(title, keywords)) {
148
+ feedback.push({
149
+ text: "Keyword appears too many times in OG title \u2014 avoid keyword stuffing.",
150
+ color: "orange"
151
+ });
152
+ }
153
+ } else {
154
+ feedback.push({
155
+ text: "No keywords defined. Consider adding relevant keywords.",
156
+ color: "orange"
157
+ });
158
+ }
159
+ }
160
+ if (startsWithStopWord(title))
161
+ feedback.push({
162
+ text: "OG Title starts with a stop word \u2014 consider rephrasing.",
163
+ color: "orange"
164
+ });
165
+ if (hasExcessivePunctuation(title))
166
+ feedback.push({ text: "OG Title contains excessive punctuation \u2014 simplify it.", color: "orange" });
167
+ return feedback;
168
+ };
169
+ var getOgDescriptionValidation = (desc, keywords = [], isParentseoField) => {
170
+ const feedback = [];
171
+ const min = 90;
172
+ const max = 120;
173
+ const count = (desc == null ? void 0 : desc.length) || 0;
174
+ if (!(desc == null ? void 0 : desc.trim())) {
175
+ feedback.push({
176
+ text: "OG Description is empty. Add content for better social preview.",
177
+ color: "red"
178
+ });
179
+ return feedback;
180
+ }
181
+ if (count < min)
182
+ feedback.push({
183
+ text: `OG Description is ${count} chars \u2014 shorter than recommended ${min}.`,
184
+ color: "orange"
185
+ });
186
+ else if (count > max)
187
+ feedback.push({
188
+ text: `OG Description is ${count} chars \u2014 exceeds recommended ${max}.`,
189
+ color: "red"
190
+ });
191
+ else feedback.push({ text: `OG Description length (${count}) looks good.`, color: "green" });
192
+ if (isParentseoField) {
193
+ if (keywords.length > 0) {
194
+ const hasKeyword = hasMatchingKeyword(desc, keywords);
195
+ feedback.push({
196
+ text: hasKeyword ? "Keyword found in OG description \u2014 good job!" : "Keywords defined but missing in OG description.",
197
+ color: hasKeyword ? "green" : "red"
198
+ });
199
+ if (hasKeywordOveruse(desc, keywords)) {
200
+ feedback.push({
201
+ text: "Keyword appears too many times in OG description \u2014 avoid keyword stuffing.",
202
+ color: "orange"
203
+ });
204
+ }
205
+ } else {
206
+ feedback.push({
207
+ text: "No keywords defined. Consider adding relevant keywords.",
208
+ color: "orange"
209
+ });
210
+ }
211
+ }
212
+ if (startsWithStopWord(desc))
213
+ feedback.push({
214
+ text: "OG Description starts with a stop word \u2014 consider rephrasing.",
215
+ color: "orange"
216
+ });
217
+ if (hasExcessivePunctuation(desc))
218
+ feedback.push({
219
+ text: "OG Description contains excessive punctuation \u2014 simplify it.",
220
+ color: "orange"
221
+ });
222
+ return feedback;
223
+ };
224
+ var getTwitterTitleValidation = (title, keywords = [], isParentseoField) => {
225
+ const feedback = [];
226
+ const min = 30;
227
+ const max = 70;
228
+ const count = (title == null ? void 0 : title.length) || 0;
229
+ if (!(title == null ? void 0 : title.trim())) {
230
+ feedback.push({ text: "X Title is empty. Add content for better SEO.", color: "red" });
231
+ return feedback;
232
+ }
233
+ if (count < min)
234
+ feedback.push({
235
+ text: `X Title is ${count} chars \u2014 shorter than recommended ${min}.`,
236
+ color: "orange"
237
+ });
238
+ else if (count > max)
239
+ feedback.push({
240
+ text: `X Title is ${count} chars \u2014 exceeds recommended ${max}.`,
241
+ color: "red"
242
+ });
243
+ else feedback.push({ text: `X Title length (${count}) looks good.`, color: "green" });
244
+ if (isParentseoField) {
245
+ if (keywords.length > 0) {
246
+ const hasKeyword = hasMatchingKeyword(title, keywords);
247
+ feedback.push({
248
+ text: hasKeyword ? "Keyword found in X title \u2014 good job!" : "Keywords defined but missing in X title.",
249
+ color: hasKeyword ? "green" : "red"
250
+ });
251
+ } else {
252
+ feedback.push({
253
+ text: "No keywords defined. Consider adding relevant keywords.",
254
+ color: "orange"
255
+ });
256
+ }
257
+ }
258
+ if (/[!@#$%^&*]{2,}/.test(title))
259
+ feedback.push({ text: "X Title has excessive punctuation \u2014 simplify it.", color: "orange" });
260
+ return feedback;
261
+ };
262
+ var getTwitterDescriptionValidation = (desc, keywords = [], isParentseoField) => {
263
+ const feedback = [];
264
+ const min = 50;
265
+ const max = 200;
266
+ const count = (desc == null ? void 0 : desc.length) || 0;
267
+ if (!(desc == null ? void 0 : desc.trim())) {
268
+ feedback.push({ text: "X Description is empty. Add content for better SEO.", color: "red" });
269
+ return feedback;
270
+ }
271
+ if (count < min)
272
+ feedback.push({
273
+ text: `X Description is ${count} chars \u2014 shorter than recommended ${min}.`,
274
+ color: "orange"
275
+ });
276
+ else if (count > max)
277
+ feedback.push({
278
+ text: `X Description is ${count} chars \u2014 exceeds recommended ${max}.`,
279
+ color: "red"
280
+ });
281
+ else feedback.push({ text: `X Description length (${count}) looks good.`, color: "green" });
282
+ if (isParentseoField) {
283
+ if (keywords.length > 0) {
284
+ const hasKeyword = hasMatchingKeyword(desc, keywords);
285
+ feedback.push({
286
+ text: hasKeyword ? "Keyword found in X description \u2014 good job!" : "Keywords defined but missing in X description.",
287
+ color: hasKeyword ? "green" : "red"
288
+ });
289
+ } else {
290
+ feedback.push({
291
+ text: "No keywords defined. Consider adding relevant keywords.",
292
+ color: "orange"
293
+ });
294
+ }
295
+ }
296
+ if (/[!@#$%^&*]{2,}/.test(desc))
297
+ feedback.push({
298
+ text: "X Description has excessive punctuation \u2014 simplify it.",
299
+ color: "orange"
300
+ });
301
+ return feedback;
302
+ };
303
+ var isSubImageSet = (subObj) => {
304
+ var _a;
305
+ if (!subObj) return false;
306
+ if (subObj.imageType === "url") return !!((_a = subObj.imageUrl) == null ? void 0 : _a.trim());
307
+ const img = subObj.image;
308
+ return !!(img == null ? void 0 : img.asset);
309
+ };
310
+ var isMetaImageSet = (seoParent) => {
311
+ if (!seoParent) return false;
312
+ const metaImage = seoParent.metaImage;
313
+ return !!(metaImage == null ? void 0 : metaImage.asset);
314
+ };
315
+ var getMetaImageValidation = (hasImage, seoParent) => {
316
+ const feedback = [];
317
+ if (!hasImage) {
318
+ feedback.push({
319
+ text: "No meta image provided. Adding an image improves click-through rates.",
320
+ color: "red"
321
+ });
322
+ return feedback;
323
+ }
324
+ feedback.push({ text: "Meta image is set \u2014 great for SEO and social sharing.", color: "green" });
325
+ const ogSet = isSubImageSet(seoParent == null ? void 0 : seoParent.openGraph);
326
+ const twSet = isSubImageSet(seoParent == null ? void 0 : seoParent.twitter);
327
+ if (!ogSet && !twSet) {
328
+ feedback.push({
329
+ text: "OG and Twitter images are missing \u2014 add them for full social coverage.",
330
+ color: "orange"
331
+ });
332
+ } else if (!ogSet) {
333
+ feedback.push({
334
+ text: "OG image is missing \u2014 add it for better Facebook/LinkedIn previews.",
335
+ color: "orange"
336
+ });
337
+ } else if (twSet) {
338
+ feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
339
+ } else {
340
+ feedback.push({
341
+ text: "Twitter image is missing \u2014 add it for better X (Twitter) cards.",
342
+ color: "orange"
343
+ });
344
+ }
345
+ return feedback;
346
+ };
347
+ var getOgImageValidation = (hasImage, altText, seoParent) => {
348
+ const feedback = [];
349
+ if (!hasImage) {
350
+ feedback.push({
351
+ text: "No OG image provided. Social shares will lack a visual preview.",
352
+ color: "red"
353
+ });
354
+ return feedback;
355
+ }
356
+ feedback.push({ text: "OG image is set \u2014 good for social sharing.", color: "green" });
357
+ if (altText == null ? void 0 : altText.trim()) {
358
+ feedback.push({ text: "Alt text is set \u2014 good for accessibility.", color: "green" });
359
+ } else {
360
+ feedback.push({ text: "Consider adding alt text for better accessibility.", color: "orange" });
361
+ }
362
+ const metaSet = isMetaImageSet(seoParent);
363
+ const twSet = isSubImageSet(seoParent == null ? void 0 : seoParent.twitter);
364
+ if (metaSet && twSet) {
365
+ feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
366
+ } else {
367
+ if (!metaSet)
368
+ feedback.push({
369
+ text: "Meta image is missing \u2014 add it for search engine results.",
370
+ color: "orange"
371
+ });
372
+ if (!twSet)
373
+ feedback.push({
374
+ text: "Twitter image is missing \u2014 add it for X (Twitter) cards.",
375
+ color: "orange"
376
+ });
377
+ }
378
+ return feedback;
379
+ };
380
+ var getOgImageUrlValidation = (imageUrl, seoParent) => {
381
+ const feedback = [];
382
+ if (!(imageUrl == null ? void 0 : imageUrl.trim())) {
383
+ feedback.push({
384
+ text: "No OG image URL provided. Social shares will lack a visual preview.",
385
+ color: "red"
386
+ });
387
+ return feedback;
388
+ }
389
+ feedback.push({ text: "OG image URL is set \u2014 good for social sharing.", color: "green" });
390
+ const metaSet = isMetaImageSet(seoParent);
391
+ const twSet = isSubImageSet(seoParent == null ? void 0 : seoParent.twitter);
392
+ if (metaSet && twSet) {
393
+ feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
394
+ } else {
395
+ if (!metaSet)
396
+ feedback.push({
397
+ text: "Meta image is missing \u2014 add it for search engine results.",
398
+ color: "orange"
399
+ });
400
+ if (!twSet)
401
+ feedback.push({
402
+ text: "Twitter image is missing \u2014 add it for X (Twitter) cards.",
403
+ color: "orange"
404
+ });
405
+ }
406
+ return feedback;
407
+ };
408
+ var getTwitterImageValidation = (hasImage, altText, seoParent) => {
409
+ const feedback = [];
410
+ if (!hasImage) {
411
+ feedback.push({
412
+ text: "No Twitter image provided. Posts on X will lack a visual.",
413
+ color: "red"
414
+ });
415
+ return feedback;
416
+ }
417
+ feedback.push({ text: "Twitter image is set \u2014 good for X sharing.", color: "green" });
418
+ if (altText == null ? void 0 : altText.trim()) {
419
+ feedback.push({ text: "Alt text is set \u2014 good for accessibility.", color: "green" });
420
+ } else {
421
+ feedback.push({ text: "Consider adding alt text for better accessibility.", color: "orange" });
422
+ }
423
+ const metaSet = isMetaImageSet(seoParent);
424
+ const ogSet = isSubImageSet(seoParent == null ? void 0 : seoParent.openGraph);
425
+ if (metaSet && ogSet) {
426
+ feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
427
+ } else {
428
+ if (!metaSet)
429
+ feedback.push({
430
+ text: "Meta image is missing \u2014 add it for search engine results.",
431
+ color: "orange"
432
+ });
433
+ if (!ogSet)
434
+ feedback.push({
435
+ text: "OG image is missing \u2014 add it for Facebook/LinkedIn sharing.",
436
+ color: "orange"
437
+ });
438
+ }
439
+ return feedback;
440
+ };
441
+ var getTwitterImageUrlValidation = (imageUrl, seoParent) => {
442
+ const feedback = [];
443
+ if (!(imageUrl == null ? void 0 : imageUrl.trim())) {
444
+ feedback.push({
445
+ text: "No Twitter image URL provided. Posts on X will lack a visual.",
446
+ color: "red"
447
+ });
448
+ return feedback;
449
+ }
450
+ feedback.push({ text: "Twitter image URL is set \u2014 good for X sharing.", color: "green" });
451
+ const metaSet = isMetaImageSet(seoParent);
452
+ const ogSet = isSubImageSet(seoParent == null ? void 0 : seoParent.openGraph);
453
+ if (metaSet && ogSet) {
454
+ feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
455
+ } else {
456
+ if (!metaSet)
457
+ feedback.push({
458
+ text: "Meta image is missing \u2014 add it for search engine results.",
459
+ color: "orange"
460
+ });
461
+ if (!ogSet)
462
+ feedback.push({
463
+ text: "OG image is missing \u2014 add it for Facebook/LinkedIn sharing.",
464
+ color: "orange"
465
+ });
466
+ }
467
+ return feedback;
468
+ };
469
+
470
+ export { getMetaDescriptionValidationMessages, getMetaImageValidation, getMetaTitleValidationMessages, getOgDescriptionValidation, getOgImageUrlValidation, getOgImageValidation, getOgTitleValidation, getTwitterDescriptionValidation, getTwitterImageUrlValidation, getTwitterImageValidation, getTwitterTitleValidation, truncate };
471
+ //# sourceMappingURL=chunk-25JLWVEU.js.map
472
+ //# sourceMappingURL=chunk-25JLWVEU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/seoUtils.ts"],"names":[],"mappings":"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","file":"chunk-25JLWVEU.js","sourcesContent":["import {FeedbackType} from '../types'\n\nexport const stopWords = ['the', 'a', 'an', 'and', 'or', 'but']\n\nexport const hasMatchingKeyword = (title: string, keywordList: string[]): boolean => {\n if (!title || keywordList.length === 0) return false\n const lowerTitle = title.toLowerCase()\n return keywordList.some((keyword) => keyword && lowerTitle.includes(keyword.toLowerCase()))\n}\n\nexport const hasKeywordOveruse = (\n title: string,\n keywordList: string[],\n maxOccurrences = 3,\n): boolean => {\n if (!title || keywordList.length === 0) return false\n const lowerTitle = title.toLowerCase()\n return keywordList.some((keyword) => {\n if (!keyword) return false\n const matches = lowerTitle.match(new RegExp(keyword.toLowerCase(), 'g'))\n return matches ? matches.length > maxOccurrences : false\n })\n}\n\nexport const startsWithStopWord = (title: string): boolean => {\n if (!title) return false\n const firstWord = title.trim().split(' ')[0].toLowerCase()\n return stopWords.includes(firstWord)\n}\n\nexport const primaryKeywordAtStart = (title: string, keywords: string[]): boolean => {\n if (!title || keywords.length === 0) return true\n return title.toLowerCase().startsWith(keywords[0].toLowerCase())\n}\n\nexport const truncate = (text: string, maxLength: number): string =>\n text.length > maxLength ? `${text.slice(0, maxLength)}…` : text\n\nexport const hasExcessivePunctuation = (title: string): boolean => /[!@#$%^&*]{2,}/.test(title)\n\nexport const getMetaTitleValidationMessages = (\n title: string,\n keywords: string[],\n isParentseoField: boolean,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n\n const minChar = 50\n const maxChar = 60\n const charCount = title?.length || 0\n\n // Empty check\n if (!title?.trim()) {\n feedback.push({text: 'Meta Title is empty. Add content to improve SEO.', color: 'red'})\n return feedback\n }\n\n // Length check\n if (charCount < minChar)\n feedback.push({\n text: `Title is ${charCount} characters — below recommended ${minChar}.`,\n color: 'orange',\n })\n else if (charCount > maxChar)\n feedback.push({\n text: `Title is ${charCount} characters — exceeds recommended ${maxChar}.`,\n color: 'red',\n })\n else feedback.push({text: `Title length (${charCount}) looks good for SEO.`, color: 'green'})\n\n // Keyword checks\n if (isParentseoField) {\n if (keywords.length > 0) {\n const hasKeyword = hasMatchingKeyword(title, keywords)\n feedback.push({\n text: hasKeyword\n ? 'Keyword found in title — good job!'\n : 'Keywords defined but missing in title.',\n color: hasKeyword ? 'green' : 'red',\n })\n\n if (hasKeywordOveruse(title, keywords)) {\n feedback.push({\n text: 'Keyword appears too many times — avoid keyword stuffing.',\n color: 'orange',\n })\n }\n } else {\n feedback.push({\n text: 'No keywords defined. Consider adding relevant keywords.',\n color: 'orange',\n })\n }\n }\n\n // Stop word check\n if (startsWithStopWord(title))\n feedback.push({text: 'Title starts with a stop word — consider rephrasing.', color: 'orange'})\n\n // Punctuation check\n if (hasExcessivePunctuation(title))\n feedback.push({text: 'Title contains excessive punctuation — simplify it.', color: 'orange'})\n\n return feedback\n}\n\nexport const getMetaDescriptionValidationMessages = (\n description: string,\n keywords: string[],\n isParentseoField: boolean,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n\n const minChar = 120\n const maxChar = 160\n const charCount = description?.length || 0\n\n if (!description?.trim()) {\n feedback.push({text: 'Meta description is empty. Add content to improve SEO.', color: 'red'})\n return feedback\n }\n\n // Length check\n if (charCount < minChar)\n feedback.push({\n text: `Description is ${charCount} chars — below recommended ${minChar}.`,\n color: 'orange',\n })\n else if (charCount > maxChar)\n feedback.push({\n text: `Description is ${charCount} chars — exceeds recommended ${maxChar}.`,\n color: 'red',\n })\n else\n feedback.push({text: `Description length (${charCount}) looks good for SEO.`, color: 'green'})\n\n // Keyword checks\n if (isParentseoField) {\n if (keywords.length > 0) {\n const hasKeyword = hasMatchingKeyword(description, keywords)\n feedback.push({\n text: hasKeyword\n ? 'Keyword found in description — good job!'\n : 'Keywords defined but missing in description.',\n color: hasKeyword ? 'green' : 'red',\n })\n\n if (hasKeywordOveruse(description, keywords)) {\n feedback.push({\n text: 'Keyword appears too many times — avoid keyword stuffing.',\n color: 'orange',\n })\n }\n } else {\n feedback.push({\n text: 'No keywords defined. Consider adding relevant keywords.',\n color: 'orange',\n })\n }\n }\n\n // Stop word / filler check\n if (startsWithStopWord(description))\n feedback.push({\n text: 'Description starts with a stop word — consider rephrasing.',\n color: 'orange',\n })\n\n // Punctuation / special characters\n if (hasExcessivePunctuation(description))\n feedback.push({\n text: 'Description contains excessive punctuation — simplify it.',\n color: 'orange',\n })\n\n return feedback\n}\n\nexport const getOgTitleValidation = (\n title: string,\n keywords: string[] = [],\n isParentseoField: boolean,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n const min = 40\n const max = 60\n const count = title?.length || 0\n\n // Empty check\n if (!title?.trim()) {\n feedback.push({text: 'OG Title is empty. Add content for better social preview.', color: 'red'})\n return feedback\n }\n\n // Length check\n if (count < min)\n feedback.push({\n text: `OG Title is ${count} chars — shorter than recommended ${min}.`,\n color: 'orange',\n })\n else if (count > max)\n feedback.push({text: `OG Title is ${count} chars — exceeds recommended ${max}.`, color: 'red'})\n else feedback.push({text: `OG Title length (${count}) looks good.`, color: 'green'})\n\n if (isParentseoField) {\n // Keyword checks\n if (keywords.length > 0) {\n const hasKeyword = hasMatchingKeyword(title, keywords)\n feedback.push({\n text: hasKeyword\n ? 'Keyword found in OG title — good job!'\n : 'Keywords defined but missing in OG title.',\n color: hasKeyword ? 'green' : 'red',\n })\n\n if (hasKeywordOveruse(title, keywords)) {\n feedback.push({\n text: 'Keyword appears too many times in OG title — avoid keyword stuffing.',\n color: 'orange',\n })\n }\n } else {\n feedback.push({\n text: 'No keywords defined. Consider adding relevant keywords.',\n color: 'orange',\n })\n }\n }\n\n // Additional OG-specific checks\n if (startsWithStopWord(title))\n feedback.push({\n text: 'OG Title starts with a stop word — consider rephrasing.',\n color: 'orange',\n })\n\n if (hasExcessivePunctuation(title))\n feedback.push({text: 'OG Title contains excessive punctuation — simplify it.', color: 'orange'})\n\n return feedback\n}\n\nexport const getOgDescriptionValidation = (\n desc: string,\n keywords: string[] = [],\n isParentseoField: boolean,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n const min = 90\n const max = 120\n const count = desc?.length || 0\n\n // Empty check\n if (!desc?.trim()) {\n feedback.push({\n text: 'OG Description is empty. Add content for better social preview.',\n color: 'red',\n })\n return feedback\n }\n\n // Length check\n if (count < min)\n feedback.push({\n text: `OG Description is ${count} chars — shorter than recommended ${min}.`,\n color: 'orange',\n })\n else if (count > max)\n feedback.push({\n text: `OG Description is ${count} chars — exceeds recommended ${max}.`,\n color: 'red',\n })\n else feedback.push({text: `OG Description length (${count}) looks good.`, color: 'green'})\n\n // Keyword checks\n if (isParentseoField) {\n if (keywords.length > 0) {\n const hasKeyword = hasMatchingKeyword(desc, keywords)\n feedback.push({\n text: hasKeyword\n ? 'Keyword found in OG description — good job!'\n : 'Keywords defined but missing in OG description.',\n color: hasKeyword ? 'green' : 'red',\n })\n\n if (hasKeywordOveruse(desc, keywords)) {\n feedback.push({\n text: 'Keyword appears too many times in OG description — avoid keyword stuffing.',\n color: 'orange',\n })\n }\n } else {\n feedback.push({\n text: 'No keywords defined. Consider adding relevant keywords.',\n color: 'orange',\n })\n }\n }\n\n // Additional OG-specific checks\n if (startsWithStopWord(desc))\n feedback.push({\n text: 'OG Description starts with a stop word — consider rephrasing.',\n color: 'orange',\n })\n\n if (hasExcessivePunctuation(desc))\n feedback.push({\n text: 'OG Description contains excessive punctuation — simplify it.',\n color: 'orange',\n })\n\n return feedback\n}\n\nexport const getTwitterTitleValidation = (\n title: string,\n keywords: string[] = [],\n isParentseoField: boolean,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n const min = 30\n const max = 70\n const count = title?.length || 0\n\n if (!title?.trim()) {\n feedback.push({text: 'X Title is empty. Add content for better SEO.', color: 'red'})\n return feedback\n }\n\n // Length check\n if (count < min)\n feedback.push({\n text: `X Title is ${count} chars — shorter than recommended ${min}.`,\n color: 'orange',\n })\n else if (count > max)\n feedback.push({\n text: `X Title is ${count} chars — exceeds recommended ${max}.`,\n color: 'red',\n })\n else feedback.push({text: `X Title length (${count}) looks good.`, color: 'green'})\n\n if (isParentseoField) {\n // Keyword checks\n if (keywords.length > 0) {\n const hasKeyword = hasMatchingKeyword(title, keywords)\n feedback.push({\n text: hasKeyword\n ? 'Keyword found in X title — good job!'\n : 'Keywords defined but missing in X title.',\n color: hasKeyword ? 'green' : 'red',\n })\n } else {\n feedback.push({\n text: 'No keywords defined. Consider adding relevant keywords.',\n color: 'orange',\n })\n }\n }\n\n // Punctuation check\n if (/[!@#$%^&*]{2,}/.test(title))\n feedback.push({text: 'X Title has excessive punctuation — simplify it.', color: 'orange'})\n\n return feedback\n}\n\nexport const getTwitterDescriptionValidation = (\n desc: string,\n keywords: string[] = [],\n isParentseoField: boolean,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n const min = 50\n const max = 200\n const count = desc?.length || 0\n\n if (!desc?.trim()) {\n feedback.push({text: 'X Description is empty. Add content for better SEO.', color: 'red'})\n return feedback\n }\n\n // Length check\n if (count < min)\n feedback.push({\n text: `X Description is ${count} chars — shorter than recommended ${min}.`,\n color: 'orange',\n })\n else if (count > max)\n feedback.push({\n text: `X Description is ${count} chars — exceeds recommended ${max}.`,\n color: 'red',\n })\n else feedback.push({text: `X Description length (${count}) looks good.`, color: 'green'})\n\n if (isParentseoField) {\n // Keyword checks\n if (keywords.length > 0) {\n const hasKeyword = hasMatchingKeyword(desc, keywords)\n feedback.push({\n text: hasKeyword\n ? 'Keyword found in X description — good job!'\n : 'Keywords defined but missing in X description.',\n color: hasKeyword ? 'green' : 'red',\n })\n } else {\n feedback.push({\n text: 'No keywords defined. Consider adding relevant keywords.',\n color: 'orange',\n })\n }\n }\n\n // Punctuation check\n if (/[!@#$%^&*]{2,}/.test(desc))\n feedback.push({\n text: 'X Description has excessive punctuation — simplify it.',\n color: 'orange',\n })\n\n return feedback\n}\n\n// ── Image Validation Helpers ──\n\n/** Check if an image is set in an OG/Twitter sub-object (handles upload vs URL) */\nexport const isSubImageSet = (subObj: Record<string, unknown> | null | undefined): boolean => {\n if (!subObj) return false\n if (subObj.imageType === 'url') return !!(subObj.imageUrl as string)?.trim()\n const img = subObj.image as Record<string, unknown> | undefined\n return !!img?.asset\n}\n\n/** Check if metaImage asset is set */\nconst isMetaImageSet = (seoParent: Record<string, unknown> | null | undefined): boolean => {\n if (!seoParent) return false\n const metaImage = seoParent.metaImage as Record<string, unknown> | undefined\n return !!metaImage?.asset\n}\n\nexport const getMetaImageValidation = (\n hasImage: boolean,\n seoParent: Record<string, unknown> | null | undefined,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n\n if (!hasImage) {\n feedback.push({\n text: 'No meta image provided. Adding an image improves click-through rates.',\n color: 'red',\n })\n return feedback\n }\n\n feedback.push({text: 'Meta image is set — great for SEO and social sharing.', color: 'green'})\n\n const ogSet = isSubImageSet(seoParent?.openGraph as Record<string, unknown> | undefined)\n const twSet = isSubImageSet(seoParent?.twitter as Record<string, unknown> | undefined)\n\n if (!ogSet && !twSet) {\n feedback.push({\n text: 'OG and Twitter images are missing — add them for full social coverage.',\n color: 'orange',\n })\n } else if (!ogSet) {\n feedback.push({\n text: 'OG image is missing — add it for better Facebook/LinkedIn previews.',\n color: 'orange',\n })\n } else if (twSet) {\n feedback.push({text: 'All images set (Meta, OG, Twitter) — full coverage!', color: 'green'})\n } else {\n feedback.push({\n text: 'Twitter image is missing — add it for better X (Twitter) cards.',\n color: 'orange',\n })\n }\n\n return feedback\n}\n\nexport const getOgImageValidation = (\n hasImage: boolean,\n altText: string | undefined,\n seoParent: Record<string, unknown> | null | undefined,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n\n if (!hasImage) {\n feedback.push({\n text: 'No OG image provided. Social shares will lack a visual preview.',\n color: 'red',\n })\n return feedback\n }\n\n feedback.push({text: 'OG image is set — good for social sharing.', color: 'green'})\n\n if (altText?.trim()) {\n feedback.push({text: 'Alt text is set — good for accessibility.', color: 'green'})\n } else {\n feedback.push({text: 'Consider adding alt text for better accessibility.', color: 'orange'})\n }\n\n const metaSet = isMetaImageSet(seoParent)\n const twSet = isSubImageSet(seoParent?.twitter as Record<string, unknown> | undefined)\n\n if (metaSet && twSet) {\n feedback.push({text: 'All images set (Meta, OG, Twitter) — full coverage!', color: 'green'})\n } else {\n if (!metaSet)\n feedback.push({\n text: 'Meta image is missing — add it for search engine results.',\n color: 'orange',\n })\n if (!twSet)\n feedback.push({\n text: 'Twitter image is missing — add it for X (Twitter) cards.',\n color: 'orange',\n })\n }\n\n return feedback\n}\n\nexport const getOgImageUrlValidation = (\n imageUrl: string | undefined,\n seoParent: Record<string, unknown> | null | undefined,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n\n if (!imageUrl?.trim()) {\n feedback.push({\n text: 'No OG image URL provided. Social shares will lack a visual preview.',\n color: 'red',\n })\n return feedback\n }\n\n feedback.push({text: 'OG image URL is set — good for social sharing.', color: 'green'})\n\n const metaSet = isMetaImageSet(seoParent)\n const twSet = isSubImageSet(seoParent?.twitter as Record<string, unknown> | undefined)\n\n if (metaSet && twSet) {\n feedback.push({text: 'All images set (Meta, OG, Twitter) — full coverage!', color: 'green'})\n } else {\n if (!metaSet)\n feedback.push({\n text: 'Meta image is missing — add it for search engine results.',\n color: 'orange',\n })\n if (!twSet)\n feedback.push({\n text: 'Twitter image is missing — add it for X (Twitter) cards.',\n color: 'orange',\n })\n }\n\n return feedback\n}\n\nexport const getTwitterImageValidation = (\n hasImage: boolean,\n altText: string | undefined,\n seoParent: Record<string, unknown> | null | undefined,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n\n if (!hasImage) {\n feedback.push({\n text: 'No Twitter image provided. Posts on X will lack a visual.',\n color: 'red',\n })\n return feedback\n }\n\n feedback.push({text: 'Twitter image is set — good for X sharing.', color: 'green'})\n\n if (altText?.trim()) {\n feedback.push({text: 'Alt text is set — good for accessibility.', color: 'green'})\n } else {\n feedback.push({text: 'Consider adding alt text for better accessibility.', color: 'orange'})\n }\n\n const metaSet = isMetaImageSet(seoParent)\n const ogSet = isSubImageSet(seoParent?.openGraph as Record<string, unknown> | undefined)\n\n if (metaSet && ogSet) {\n feedback.push({text: 'All images set (Meta, OG, Twitter) — full coverage!', color: 'green'})\n } else {\n if (!metaSet)\n feedback.push({\n text: 'Meta image is missing — add it for search engine results.',\n color: 'orange',\n })\n if (!ogSet)\n feedback.push({\n text: 'OG image is missing — add it for Facebook/LinkedIn sharing.',\n color: 'orange',\n })\n }\n\n return feedback\n}\n\nexport const getTwitterImageUrlValidation = (\n imageUrl: string | undefined,\n seoParent: Record<string, unknown> | null | undefined,\n): FeedbackType[] => {\n const feedback: FeedbackType[] = []\n\n if (!imageUrl?.trim()) {\n feedback.push({\n text: 'No Twitter image URL provided. Posts on X will lack a visual.',\n color: 'red',\n })\n return feedback\n }\n\n feedback.push({text: 'Twitter image URL is set — good for X sharing.', color: 'green'})\n\n const metaSet = isMetaImageSet(seoParent)\n const ogSet = isSubImageSet(seoParent?.openGraph as Record<string, unknown> | undefined)\n\n if (metaSet && ogSet) {\n feedback.push({text: 'All images set (Meta, OG, Twitter) — full coverage!', color: 'green'})\n } else {\n if (!metaSet)\n feedback.push({\n text: 'Meta image is missing — add it for search engine results.',\n color: 'orange',\n })\n if (!ogSet)\n feedback.push({\n text: 'OG image is missing — add it for Facebook/LinkedIn sharing.',\n color: 'orange',\n })\n }\n\n return feedback\n}\n"]}
@@ -0,0 +1,35 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+
33
+ export { __objRest, __spreadProps, __spreadValues };
34
+ //# sourceMappingURL=chunk-2NMEKWO5.js.map
35
+ //# sourceMappingURL=chunk-2NMEKWO5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-2NMEKWO5.js"}