aeo.js 0.0.6 → 0.0.8

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 (67) hide show
  1. package/dist/angular.d.mts +1 -1
  2. package/dist/angular.d.ts +1 -1
  3. package/dist/angular.js +65 -11
  4. package/dist/angular.js.map +1 -1
  5. package/dist/angular.mjs +65 -11
  6. package/dist/angular.mjs.map +1 -1
  7. package/dist/astro.d.mts +1 -1
  8. package/dist/astro.d.ts +1 -1
  9. package/dist/astro.js +74 -16
  10. package/dist/astro.js.map +1 -1
  11. package/dist/astro.mjs +74 -16
  12. package/dist/astro.mjs.map +1 -1
  13. package/dist/cli.js +80 -25
  14. package/dist/cli.js.map +1 -1
  15. package/dist/cli.mjs +80 -25
  16. package/dist/cli.mjs.map +1 -1
  17. package/dist/index.d.mts +2 -2
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.js +85 -27
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +85 -27
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/next.d.mts +1 -1
  24. package/dist/next.d.ts +1 -1
  25. package/dist/next.js +65 -11
  26. package/dist/next.js.map +1 -1
  27. package/dist/next.mjs +65 -11
  28. package/dist/next.mjs.map +1 -1
  29. package/dist/nuxt.d.mts +1 -1
  30. package/dist/nuxt.d.ts +1 -1
  31. package/dist/nuxt.js +65 -11
  32. package/dist/nuxt.js.map +1 -1
  33. package/dist/nuxt.mjs +65 -11
  34. package/dist/nuxt.mjs.map +1 -1
  35. package/dist/react.d.mts +1 -1
  36. package/dist/react.d.ts +1 -1
  37. package/dist/react.js +61 -9
  38. package/dist/react.js.map +1 -1
  39. package/dist/react.mjs +61 -9
  40. package/dist/react.mjs.map +1 -1
  41. package/dist/{types-Cn_Qbkmg.d.mts → types-BlLNcw-X.d.mts} +2 -0
  42. package/dist/{types-Cn_Qbkmg.d.ts → types-BlLNcw-X.d.ts} +2 -0
  43. package/dist/vite.d.mts +1 -1
  44. package/dist/vite.d.ts +1 -1
  45. package/dist/vite.js +90 -18
  46. package/dist/vite.js.map +1 -1
  47. package/dist/vite.mjs +90 -18
  48. package/dist/vite.mjs.map +1 -1
  49. package/dist/vue.d.mts +1 -1
  50. package/dist/vue.d.ts +1 -1
  51. package/dist/vue.js +61 -9
  52. package/dist/vue.js.map +1 -1
  53. package/dist/vue.mjs +61 -9
  54. package/dist/vue.mjs.map +1 -1
  55. package/dist/webpack.d.mts +1 -1
  56. package/dist/webpack.d.ts +1 -1
  57. package/dist/webpack.js +65 -11
  58. package/dist/webpack.js.map +1 -1
  59. package/dist/webpack.mjs +65 -11
  60. package/dist/webpack.mjs.map +1 -1
  61. package/dist/widget.d.mts +1 -1
  62. package/dist/widget.d.ts +1 -1
  63. package/dist/widget.js +61 -9
  64. package/dist/widget.js.map +1 -1
  65. package/dist/widget.mjs +61 -9
  66. package/dist/widget.mjs.map +1 -1
  67. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -22,7 +22,7 @@ function validateConfig(config) {
22
22
  return warnings;
23
23
  }
24
24
  function resolveConfig(config = {}) {
25
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M;
25
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N;
26
26
  const frameworkInfo = detectFramework();
27
27
  return {
28
28
  title: config.title || "My Site",
@@ -66,15 +66,16 @@ function resolveConfig(config = {}) {
66
66
  widget: {
67
67
  enabled: ((_A = config.widget) == null ? void 0 : _A.enabled) !== false,
68
68
  position: ((_B = config.widget) == null ? void 0 : _B.position) || "bottom-right",
69
+ size: ((_C = config.widget) == null ? void 0 : _C.size) || "default",
69
70
  theme: {
70
- background: ((_D = (_C = config.widget) == null ? void 0 : _C.theme) == null ? void 0 : _D.background) || "rgba(18, 18, 24, 0.9)",
71
- text: ((_F = (_E = config.widget) == null ? void 0 : _E.theme) == null ? void 0 : _F.text) || "#C0C0C5",
72
- accent: ((_H = (_G = config.widget) == null ? void 0 : _G.theme) == null ? void 0 : _H.accent) || "#E8E8EA",
73
- badge: ((_J = (_I = config.widget) == null ? void 0 : _I.theme) == null ? void 0 : _J.badge) || "#4ADE80"
71
+ background: ((_E = (_D = config.widget) == null ? void 0 : _D.theme) == null ? void 0 : _E.background) || "rgba(18, 18, 24, 0.9)",
72
+ text: ((_G = (_F = config.widget) == null ? void 0 : _F.theme) == null ? void 0 : _G.text) || "#C0C0C5",
73
+ accent: ((_I = (_H = config.widget) == null ? void 0 : _H.theme) == null ? void 0 : _I.accent) || "#E8E8EA",
74
+ badge: ((_K = (_J = config.widget) == null ? void 0 : _J.theme) == null ? void 0 : _K.badge) || "#4ADE80"
74
75
  },
75
- humanLabel: ((_K = config.widget) == null ? void 0 : _K.humanLabel) || "Human",
76
- aiLabel: ((_L = config.widget) == null ? void 0 : _L.aiLabel) || "AI",
77
- showBadge: ((_M = config.widget) == null ? void 0 : _M.showBadge) !== false
76
+ humanLabel: ((_L = config.widget) == null ? void 0 : _L.humanLabel) || "Human",
77
+ aiLabel: ((_M = config.widget) == null ? void 0 : _M.aiLabel) || "AI",
78
+ showBadge: ((_N = config.widget) == null ? void 0 : _N.showBadge) !== false
78
79
  }
79
80
  };
80
81
  }
@@ -267,10 +268,19 @@ function generateRobotsTxt(config) {
267
268
  }
268
269
  lines.push("# Default for all other bots");
269
270
  lines.push("User-agent: *");
270
- lines.push("Allow: /");
271
+ for (const path of config.robots.allow.length > 0 ? config.robots.allow : ["/"]) {
272
+ lines.push(`Allow: ${path}`);
273
+ }
274
+ for (const path of config.robots.disallow) {
275
+ lines.push(`Disallow: ${path}`);
276
+ }
277
+ if (config.robots.crawlDelay > 0) {
278
+ lines.push(`Crawl-delay: ${config.robots.crawlDelay}`);
279
+ }
271
280
  lines.push("");
272
- if (config.url) {
273
- lines.push(`Sitemap: ${config.url}/sitemap.xml`);
281
+ const sitemapUrl = config.robots.sitemap || (config.url ? `${config.url}/sitemap.xml` : "");
282
+ if (sitemapUrl) {
283
+ lines.push(`Sitemap: ${sitemapUrl}`);
274
284
  }
275
285
  lines.push("");
276
286
  lines.push("# AEO (Answer Engine Optimization) files");
@@ -859,6 +869,22 @@ function generatePageSchemas(page, config) {
859
869
  }))
860
870
  });
861
871
  }
872
+ if (faqItems.length === 0) {
873
+ const howToSteps = detectHowToSteps(page.content || "");
874
+ if (howToSteps.length > 0) {
875
+ schemas.push({
876
+ "@context": "https://schema.org",
877
+ "@type": "HowTo",
878
+ name: page.title || config.title,
879
+ step: howToSteps.map((s, i) => ({
880
+ "@type": "HowToStep",
881
+ position: i + 1,
882
+ name: s.name,
883
+ text: s.text
884
+ }))
885
+ });
886
+ }
887
+ }
862
888
  const pageType = config.schema.defaultType;
863
889
  const pageSchema = {
864
890
  "@context": "https://schema.org",
@@ -935,12 +961,43 @@ function detectFaqPatterns(content) {
935
961
  }
936
962
  return items;
937
963
  }
964
+ function serializeJsonForHtml(value) {
965
+ return JSON.stringify(value).replace(/</g, "\\u003C").replace(/>/g, "\\u003E").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
966
+ }
967
+ function detectHowToSteps(content) {
968
+ const steps = [];
969
+ const lines = content.split("\n");
970
+ for (let i = 0; i < lines.length; i++) {
971
+ const line = lines[i].trim();
972
+ const stepMatch = line.match(/^#{1,6}\s+(?:Step\s+\d+[\s:.-]*|(\d+)[.)]\s*)(.+)$/i);
973
+ if (stepMatch) {
974
+ const name = (stepMatch[2] || stepMatch[1] || "").trim();
975
+ const bodyLines = [];
976
+ for (let j = i + 1; j < lines.length; j++) {
977
+ const nextLine = lines[j].trim();
978
+ if (!nextLine) {
979
+ if (bodyLines.length > 0) break;
980
+ continue;
981
+ }
982
+ if (/^#{1,6}\s/.test(nextLine)) break;
983
+ bodyLines.push(nextLine);
984
+ }
985
+ if (name) {
986
+ steps.push({
987
+ name,
988
+ text: bodyLines.join(" ").slice(0, 500)
989
+ });
990
+ }
991
+ }
992
+ }
993
+ return steps.length >= 2 ? steps : [];
994
+ }
938
995
  function generateJsonLdScript(schemas) {
939
996
  if (schemas.length === 0) return "";
940
997
  if (schemas.length === 1) {
941
- return `<script type="application/ld+json">${JSON.stringify(schemas[0])}</script>`;
998
+ return `<script type="application/ld+json">${serializeJsonForHtml(schemas[0])}</script>`;
942
999
  }
943
- return schemas.map((s) => `<script type="application/ld+json">${JSON.stringify(s)}</script>`).join("\n");
1000
+ return schemas.map((s) => `<script type="application/ld+json">${serializeJsonForHtml(s)}</script>`).join("\n");
944
1001
  }
945
1002
  async function generateAEOFiles(configOrRoot, maybeConfig) {
946
1003
  var _a;
@@ -1273,15 +1330,18 @@ function auditSchemaPresence(config, issues, suggestions) {
1273
1330
  if (!hasLogo) {
1274
1331
  suggestions.push("Add schema.organization.logo for richer search results and AI knowledge");
1275
1332
  }
1276
- const hasSameAs = config.schema.organization.sameAs.length > 0;
1277
- checks.push({ label: "Social profiles linked (sameAs)", passed: hasSameAs, points: hasSameAs ? 4 : 0 });
1278
- if (!hasSameAs) {
1279
- issues.push({ category: "Schema Presence", severity: "warning", message: "No social profiles (sameAs) \u2014 critical for GEO/E-E-A-T signals", fix: "Add schema.organization.sameAs with social profile URLs" });
1333
+ const hasFaqOrHowTo = config.pages.some((p) => {
1334
+ const content = p.content || "";
1335
+ return /^#{1,6}\s+.+\?\s*$/m.test(content) || /^#{1,6}\s+(?:Step\s+\d+[\s:.-]|How\s+to)/im.test(content);
1336
+ });
1337
+ checks.push({ label: "FAQPage or HowTo schema", passed: hasFaqOrHowTo, points: hasFaqOrHowTo ? 4 : 0 });
1338
+ if (!hasFaqOrHowTo) {
1339
+ suggestions.push("Add FAQ sections (question headings) or step-by-step content to auto-generate FAQPage/HowTo schema");
1280
1340
  }
1281
- const hasRealUrl = config.url !== "https://example.com" && config.url !== "";
1282
- checks.push({ label: "Site URL is configured (not default)", passed: hasRealUrl, points: hasRealUrl ? 4 : 0 });
1283
- if (!hasRealUrl) {
1284
- issues.push({ category: "Schema Presence", severity: "error", message: "Site URL is still the default (https://example.com)", fix: "Set url to your actual site URL" });
1341
+ const hasArticleOrWebPage = schemaEnabled && (config.schema.defaultType === "Article" || config.schema.defaultType === "WebPage");
1342
+ checks.push({ label: "Article/WebPage schema", passed: hasArticleOrWebPage, points: hasArticleOrWebPage ? 4 : 0 });
1343
+ if (!hasArticleOrWebPage && schemaEnabled) {
1344
+ suggestions.push('Set schema.defaultType to "Article" or "WebPage" for per-page structured data');
1285
1345
  }
1286
1346
  return {
1287
1347
  name: "Schema Presence",
@@ -1320,12 +1380,10 @@ function auditMetaQuality(config, issues, suggestions) {
1320
1380
  if (!goodTitleCoverage && config.pages.length > 0) {
1321
1381
  issues.push({ category: "Meta Quality", severity: "warning", message: `Only ${pagesWithTitles.length}/${config.pages.length} pages have titles`, fix: "Add titles to all pages" });
1322
1382
  }
1323
- const pagesWithDesc = config.pages.filter((p) => p.description && p.description.length > 0);
1324
- const descCoverage = config.pages.length > 0 ? pagesWithDesc.length / config.pages.length : 0;
1325
- const goodDescCoverage = descCoverage >= 0.5;
1326
- checks.push({ label: "50%+ of pages have descriptions", passed: goodDescCoverage, points: goodDescCoverage ? 4 : 0 });
1327
- if (!goodDescCoverage && config.pages.length > 0) {
1328
- suggestions.push(`Only ${pagesWithDesc.length}/${config.pages.length} pages have descriptions \u2014 add per-page descriptions`);
1383
+ const hasOgImage = !!config.og.image;
1384
+ checks.push({ label: "OG image configured", passed: hasOgImage, points: hasOgImage ? 4 : 0 });
1385
+ if (!hasOgImage) {
1386
+ suggestions.push("Set og.image for richer social sharing previews and AI citation cards");
1329
1387
  }
1330
1388
  return {
1331
1389
  name: "Meta Quality",