aeo.js 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -164
- package/dist/angular.d.mts +1 -1
- package/dist/angular.d.ts +1 -1
- package/dist/angular.js +69 -13
- package/dist/angular.js.map +1 -1
- package/dist/angular.mjs +69 -13
- package/dist/angular.mjs.map +1 -1
- package/dist/astro.d.mts +1 -1
- package/dist/astro.d.ts +1 -1
- package/dist/astro.js +78 -18
- package/dist/astro.js.map +1 -1
- package/dist/astro.mjs +78 -18
- package/dist/astro.mjs.map +1 -1
- package/dist/cli.js +84 -27
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +84 -27
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +89 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +89 -29
- package/dist/index.mjs.map +1 -1
- package/dist/next.d.mts +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/next.js +71 -15
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +71 -15
- package/dist/next.mjs.map +1 -1
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/nuxt.js +69 -13
- package/dist/nuxt.js.map +1 -1
- package/dist/nuxt.mjs +69 -13
- package/dist/nuxt.mjs.map +1 -1
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +52 -7
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +52 -7
- package/dist/react.mjs.map +1 -1
- package/dist/{types-Cn_Qbkmg.d.mts → types-BlLNcw-X.d.mts} +2 -0
- package/dist/{types-Cn_Qbkmg.d.ts → types-BlLNcw-X.d.ts} +2 -0
- package/dist/vite.d.mts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +94 -20
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +94 -20
- package/dist/vite.mjs.map +1 -1
- package/dist/vue.d.mts +1 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +52 -7
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +52 -7
- package/dist/vue.mjs.map +1 -1
- package/dist/webpack.d.mts +1 -1
- package/dist/webpack.d.ts +1 -1
- package/dist/webpack.js +69 -13
- package/dist/webpack.js.map +1 -1
- package/dist/webpack.mjs +69 -13
- package/dist/webpack.mjs.map +1 -1
- package/dist/widget.d.mts +1 -1
- package/dist/widget.d.ts +1 -1
- package/dist/widget.js +52 -7
- package/dist/widget.js.map +1 -1
- package/dist/widget.mjs +52 -7
- package/dist/widget.mjs.map +1 -1
- 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: ((
|
|
71
|
-
text: ((
|
|
72
|
-
accent: ((
|
|
73
|
-
badge: ((
|
|
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: ((
|
|
76
|
-
aiLabel: ((
|
|
77
|
-
showBadge: ((
|
|
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
|
-
|
|
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
|
-
|
|
273
|
-
|
|
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");
|
|
@@ -288,7 +298,8 @@ function collectMarkdownFiles(dir, base = dir) {
|
|
|
288
298
|
for (const entry of entries) {
|
|
289
299
|
const fullPath = join(dir, entry);
|
|
290
300
|
const stat = statSync(fullPath);
|
|
291
|
-
|
|
301
|
+
const SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", "public", "dist", ".next", ".nuxt", ".output", ".open-next", "coverage", "__tests__", "__mocks__"]);
|
|
302
|
+
if (stat.isDirectory() && !entry.startsWith(".") && !SKIP_DIRS.has(entry)) {
|
|
292
303
|
files.push(...collectMarkdownFiles(fullPath, base));
|
|
293
304
|
} else if (stat.isFile() && (extname(entry) === ".md" || extname(entry) === ".mdx")) {
|
|
294
305
|
const content = readFileSync(fullPath, "utf-8");
|
|
@@ -631,7 +642,8 @@ function collectUrls(dir, config, base = dir) {
|
|
|
631
642
|
for (const entry of entries) {
|
|
632
643
|
const fullPath = join(dir, entry);
|
|
633
644
|
const stat = statSync(fullPath);
|
|
634
|
-
|
|
645
|
+
const SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", "public", "dist", ".next", ".nuxt", ".output", ".open-next", "coverage", "__tests__", "__mocks__"]);
|
|
646
|
+
if (stat.isDirectory() && !entry.startsWith(".") && !SKIP_DIRS.has(entry)) {
|
|
635
647
|
urls.push(...collectUrls(fullPath, config, base));
|
|
636
648
|
} else if (stat.isFile() && (extname(entry) === ".md" || extname(entry) === ".mdx" || extname(entry) === ".html")) {
|
|
637
649
|
const relativePath = relative(base, fullPath);
|
|
@@ -859,6 +871,22 @@ function generatePageSchemas(page, config) {
|
|
|
859
871
|
}))
|
|
860
872
|
});
|
|
861
873
|
}
|
|
874
|
+
if (faqItems.length === 0) {
|
|
875
|
+
const howToSteps = detectHowToSteps(page.content || "");
|
|
876
|
+
if (howToSteps.length > 0) {
|
|
877
|
+
schemas.push({
|
|
878
|
+
"@context": "https://schema.org",
|
|
879
|
+
"@type": "HowTo",
|
|
880
|
+
name: page.title || config.title,
|
|
881
|
+
step: howToSteps.map((s, i) => ({
|
|
882
|
+
"@type": "HowToStep",
|
|
883
|
+
position: i + 1,
|
|
884
|
+
name: s.name,
|
|
885
|
+
text: s.text
|
|
886
|
+
}))
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
}
|
|
862
890
|
const pageType = config.schema.defaultType;
|
|
863
891
|
const pageSchema = {
|
|
864
892
|
"@context": "https://schema.org",
|
|
@@ -935,12 +963,43 @@ function detectFaqPatterns(content) {
|
|
|
935
963
|
}
|
|
936
964
|
return items;
|
|
937
965
|
}
|
|
966
|
+
function serializeJsonForHtml(value) {
|
|
967
|
+
return JSON.stringify(value).replace(/</g, "\\u003C").replace(/>/g, "\\u003E").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
968
|
+
}
|
|
969
|
+
function detectHowToSteps(content) {
|
|
970
|
+
const steps = [];
|
|
971
|
+
const lines = content.split("\n");
|
|
972
|
+
for (let i = 0; i < lines.length; i++) {
|
|
973
|
+
const line = lines[i].trim();
|
|
974
|
+
const stepMatch = line.match(/^#{1,6}\s+(?:Step\s+\d+[\s:.-]*|(\d+)[.)]\s*)(.+)$/i);
|
|
975
|
+
if (stepMatch) {
|
|
976
|
+
const name = (stepMatch[2] || stepMatch[1] || "").trim();
|
|
977
|
+
const bodyLines = [];
|
|
978
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
979
|
+
const nextLine = lines[j].trim();
|
|
980
|
+
if (!nextLine) {
|
|
981
|
+
if (bodyLines.length > 0) break;
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
if (/^#{1,6}\s/.test(nextLine)) break;
|
|
985
|
+
bodyLines.push(nextLine);
|
|
986
|
+
}
|
|
987
|
+
if (name) {
|
|
988
|
+
steps.push({
|
|
989
|
+
name,
|
|
990
|
+
text: bodyLines.join(" ").slice(0, 500)
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
return steps.length >= 2 ? steps : [];
|
|
996
|
+
}
|
|
938
997
|
function generateJsonLdScript(schemas) {
|
|
939
998
|
if (schemas.length === 0) return "";
|
|
940
999
|
if (schemas.length === 1) {
|
|
941
|
-
return `<script type="application/ld+json">${
|
|
1000
|
+
return `<script type="application/ld+json">${serializeJsonForHtml(schemas[0])}</script>`;
|
|
942
1001
|
}
|
|
943
|
-
return schemas.map((s) => `<script type="application/ld+json">${
|
|
1002
|
+
return schemas.map((s) => `<script type="application/ld+json">${serializeJsonForHtml(s)}</script>`).join("\n");
|
|
944
1003
|
}
|
|
945
1004
|
async function generateAEOFiles(configOrRoot, maybeConfig) {
|
|
946
1005
|
var _a;
|
|
@@ -1273,15 +1332,18 @@ function auditSchemaPresence(config, issues, suggestions) {
|
|
|
1273
1332
|
if (!hasLogo) {
|
|
1274
1333
|
suggestions.push("Add schema.organization.logo for richer search results and AI knowledge");
|
|
1275
1334
|
}
|
|
1276
|
-
const
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1335
|
+
const hasFaqOrHowTo = config.pages.some((p) => {
|
|
1336
|
+
const content = p.content || "";
|
|
1337
|
+
return /^#{1,6}\s+.+\?\s*$/m.test(content) || /^#{1,6}\s+(?:Step\s+\d+[\s:.-]|How\s+to)/im.test(content);
|
|
1338
|
+
});
|
|
1339
|
+
checks.push({ label: "FAQPage or HowTo schema", passed: hasFaqOrHowTo, points: hasFaqOrHowTo ? 4 : 0 });
|
|
1340
|
+
if (!hasFaqOrHowTo) {
|
|
1341
|
+
suggestions.push("Add FAQ sections (question headings) or step-by-step content to auto-generate FAQPage/HowTo schema");
|
|
1280
1342
|
}
|
|
1281
|
-
const
|
|
1282
|
-
checks.push({ label: "
|
|
1283
|
-
if (!
|
|
1284
|
-
|
|
1343
|
+
const hasArticleOrWebPage = schemaEnabled && (config.schema.defaultType === "Article" || config.schema.defaultType === "WebPage");
|
|
1344
|
+
checks.push({ label: "Article/WebPage schema", passed: hasArticleOrWebPage, points: hasArticleOrWebPage ? 4 : 0 });
|
|
1345
|
+
if (!hasArticleOrWebPage && schemaEnabled) {
|
|
1346
|
+
suggestions.push('Set schema.defaultType to "Article" or "WebPage" for per-page structured data');
|
|
1285
1347
|
}
|
|
1286
1348
|
return {
|
|
1287
1349
|
name: "Schema Presence",
|
|
@@ -1320,12 +1382,10 @@ function auditMetaQuality(config, issues, suggestions) {
|
|
|
1320
1382
|
if (!goodTitleCoverage && config.pages.length > 0) {
|
|
1321
1383
|
issues.push({ category: "Meta Quality", severity: "warning", message: `Only ${pagesWithTitles.length}/${config.pages.length} pages have titles`, fix: "Add titles to all pages" });
|
|
1322
1384
|
}
|
|
1323
|
-
const
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
if (!goodDescCoverage && config.pages.length > 0) {
|
|
1328
|
-
suggestions.push(`Only ${pagesWithDesc.length}/${config.pages.length} pages have descriptions \u2014 add per-page descriptions`);
|
|
1385
|
+
const hasOgImage = !!config.og.image;
|
|
1386
|
+
checks.push({ label: "OG image configured", passed: hasOgImage, points: hasOgImage ? 4 : 0 });
|
|
1387
|
+
if (!hasOgImage) {
|
|
1388
|
+
suggestions.push("Set og.image for richer social sharing previews and AI citation cards");
|
|
1329
1389
|
}
|
|
1330
1390
|
return {
|
|
1331
1391
|
name: "Meta Quality",
|