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.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FrameworkInfo, R as ResolvedAeoConfig, A as AeoConfig, P as PageEntry } from './types-
|
|
2
|
-
export { a as AIIndexEntry, b as AeoManifest, D as DocEntry, c as FrameworkType, M as ManifestEntry, d as MarkdownFile } from './types-
|
|
1
|
+
import { F as FrameworkInfo, R as ResolvedAeoConfig, A as AeoConfig, P as PageEntry } from './types-BlLNcw-X.mjs';
|
|
2
|
+
export { a as AIIndexEntry, b as AeoManifest, D as DocEntry, c as FrameworkType, M as ManifestEntry, d as MarkdownFile } from './types-BlLNcw-X.mjs';
|
|
3
3
|
|
|
4
4
|
declare function detectFramework(projectRoot?: string): FrameworkInfo;
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FrameworkInfo, R as ResolvedAeoConfig, A as AeoConfig, P as PageEntry } from './types-
|
|
2
|
-
export { a as AIIndexEntry, b as AeoManifest, D as DocEntry, c as FrameworkType, M as ManifestEntry, d as MarkdownFile } from './types-
|
|
1
|
+
import { F as FrameworkInfo, R as ResolvedAeoConfig, A as AeoConfig, P as PageEntry } from './types-BlLNcw-X.js';
|
|
2
|
+
export { a as AIIndexEntry, b as AeoManifest, D as DocEntry, c as FrameworkType, M as ManifestEntry, d as MarkdownFile } from './types-BlLNcw-X.js';
|
|
3
3
|
|
|
4
4
|
declare function detectFramework(projectRoot?: string): FrameworkInfo;
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ function validateConfig(config) {
|
|
|
24
24
|
return warnings;
|
|
25
25
|
}
|
|
26
26
|
function resolveConfig(config = {}) {
|
|
27
|
-
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;
|
|
27
|
+
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;
|
|
28
28
|
const frameworkInfo = detectFramework();
|
|
29
29
|
return {
|
|
30
30
|
title: config.title || "My Site",
|
|
@@ -68,15 +68,16 @@ function resolveConfig(config = {}) {
|
|
|
68
68
|
widget: {
|
|
69
69
|
enabled: ((_A = config.widget) == null ? void 0 : _A.enabled) !== false,
|
|
70
70
|
position: ((_B = config.widget) == null ? void 0 : _B.position) || "bottom-right",
|
|
71
|
+
size: ((_C = config.widget) == null ? void 0 : _C.size) || "default",
|
|
71
72
|
theme: {
|
|
72
|
-
background: ((
|
|
73
|
-
text: ((
|
|
74
|
-
accent: ((
|
|
75
|
-
badge: ((
|
|
73
|
+
background: ((_E = (_D = config.widget) == null ? void 0 : _D.theme) == null ? void 0 : _E.background) || "rgba(18, 18, 24, 0.9)",
|
|
74
|
+
text: ((_G = (_F = config.widget) == null ? void 0 : _F.theme) == null ? void 0 : _G.text) || "#C0C0C5",
|
|
75
|
+
accent: ((_I = (_H = config.widget) == null ? void 0 : _H.theme) == null ? void 0 : _I.accent) || "#E8E8EA",
|
|
76
|
+
badge: ((_K = (_J = config.widget) == null ? void 0 : _J.theme) == null ? void 0 : _K.badge) || "#4ADE80"
|
|
76
77
|
},
|
|
77
|
-
humanLabel: ((
|
|
78
|
-
aiLabel: ((
|
|
79
|
-
showBadge: ((
|
|
78
|
+
humanLabel: ((_L = config.widget) == null ? void 0 : _L.humanLabel) || "Human",
|
|
79
|
+
aiLabel: ((_M = config.widget) == null ? void 0 : _M.aiLabel) || "AI",
|
|
80
|
+
showBadge: ((_N = config.widget) == null ? void 0 : _N.showBadge) !== false
|
|
80
81
|
}
|
|
81
82
|
};
|
|
82
83
|
}
|
|
@@ -269,10 +270,19 @@ function generateRobotsTxt(config) {
|
|
|
269
270
|
}
|
|
270
271
|
lines.push("# Default for all other bots");
|
|
271
272
|
lines.push("User-agent: *");
|
|
272
|
-
|
|
273
|
+
for (const path of config.robots.allow.length > 0 ? config.robots.allow : ["/"]) {
|
|
274
|
+
lines.push(`Allow: ${path}`);
|
|
275
|
+
}
|
|
276
|
+
for (const path of config.robots.disallow) {
|
|
277
|
+
lines.push(`Disallow: ${path}`);
|
|
278
|
+
}
|
|
279
|
+
if (config.robots.crawlDelay > 0) {
|
|
280
|
+
lines.push(`Crawl-delay: ${config.robots.crawlDelay}`);
|
|
281
|
+
}
|
|
273
282
|
lines.push("");
|
|
274
|
-
|
|
275
|
-
|
|
283
|
+
const sitemapUrl = config.robots.sitemap || (config.url ? `${config.url}/sitemap.xml` : "");
|
|
284
|
+
if (sitemapUrl) {
|
|
285
|
+
lines.push(`Sitemap: ${sitemapUrl}`);
|
|
276
286
|
}
|
|
277
287
|
lines.push("");
|
|
278
288
|
lines.push("# AEO (Answer Engine Optimization) files");
|
|
@@ -290,7 +300,8 @@ function collectMarkdownFiles(dir, base = dir) {
|
|
|
290
300
|
for (const entry of entries) {
|
|
291
301
|
const fullPath = path.join(dir, entry);
|
|
292
302
|
const stat = fs.statSync(fullPath);
|
|
293
|
-
|
|
303
|
+
const SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", "public", "dist", ".next", ".nuxt", ".output", ".open-next", "coverage", "__tests__", "__mocks__"]);
|
|
304
|
+
if (stat.isDirectory() && !entry.startsWith(".") && !SKIP_DIRS.has(entry)) {
|
|
294
305
|
files.push(...collectMarkdownFiles(fullPath, base));
|
|
295
306
|
} else if (stat.isFile() && (path.extname(entry) === ".md" || path.extname(entry) === ".mdx")) {
|
|
296
307
|
const content = fs.readFileSync(fullPath, "utf-8");
|
|
@@ -633,7 +644,8 @@ function collectUrls(dir, config, base = dir) {
|
|
|
633
644
|
for (const entry of entries) {
|
|
634
645
|
const fullPath = path.join(dir, entry);
|
|
635
646
|
const stat = fs.statSync(fullPath);
|
|
636
|
-
|
|
647
|
+
const SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", "public", "dist", ".next", ".nuxt", ".output", ".open-next", "coverage", "__tests__", "__mocks__"]);
|
|
648
|
+
if (stat.isDirectory() && !entry.startsWith(".") && !SKIP_DIRS.has(entry)) {
|
|
637
649
|
urls.push(...collectUrls(fullPath, config, base));
|
|
638
650
|
} else if (stat.isFile() && (path.extname(entry) === ".md" || path.extname(entry) === ".mdx" || path.extname(entry) === ".html")) {
|
|
639
651
|
const relativePath = path.relative(base, fullPath);
|
|
@@ -861,6 +873,22 @@ function generatePageSchemas(page, config) {
|
|
|
861
873
|
}))
|
|
862
874
|
});
|
|
863
875
|
}
|
|
876
|
+
if (faqItems.length === 0) {
|
|
877
|
+
const howToSteps = detectHowToSteps(page.content || "");
|
|
878
|
+
if (howToSteps.length > 0) {
|
|
879
|
+
schemas.push({
|
|
880
|
+
"@context": "https://schema.org",
|
|
881
|
+
"@type": "HowTo",
|
|
882
|
+
name: page.title || config.title,
|
|
883
|
+
step: howToSteps.map((s, i) => ({
|
|
884
|
+
"@type": "HowToStep",
|
|
885
|
+
position: i + 1,
|
|
886
|
+
name: s.name,
|
|
887
|
+
text: s.text
|
|
888
|
+
}))
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
}
|
|
864
892
|
const pageType = config.schema.defaultType;
|
|
865
893
|
const pageSchema = {
|
|
866
894
|
"@context": "https://schema.org",
|
|
@@ -937,12 +965,43 @@ function detectFaqPatterns(content) {
|
|
|
937
965
|
}
|
|
938
966
|
return items;
|
|
939
967
|
}
|
|
968
|
+
function serializeJsonForHtml(value) {
|
|
969
|
+
return JSON.stringify(value).replace(/</g, "\\u003C").replace(/>/g, "\\u003E").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
970
|
+
}
|
|
971
|
+
function detectHowToSteps(content) {
|
|
972
|
+
const steps = [];
|
|
973
|
+
const lines = content.split("\n");
|
|
974
|
+
for (let i = 0; i < lines.length; i++) {
|
|
975
|
+
const line = lines[i].trim();
|
|
976
|
+
const stepMatch = line.match(/^#{1,6}\s+(?:Step\s+\d+[\s:.-]*|(\d+)[.)]\s*)(.+)$/i);
|
|
977
|
+
if (stepMatch) {
|
|
978
|
+
const name = (stepMatch[2] || stepMatch[1] || "").trim();
|
|
979
|
+
const bodyLines = [];
|
|
980
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
981
|
+
const nextLine = lines[j].trim();
|
|
982
|
+
if (!nextLine) {
|
|
983
|
+
if (bodyLines.length > 0) break;
|
|
984
|
+
continue;
|
|
985
|
+
}
|
|
986
|
+
if (/^#{1,6}\s/.test(nextLine)) break;
|
|
987
|
+
bodyLines.push(nextLine);
|
|
988
|
+
}
|
|
989
|
+
if (name) {
|
|
990
|
+
steps.push({
|
|
991
|
+
name,
|
|
992
|
+
text: bodyLines.join(" ").slice(0, 500)
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
return steps.length >= 2 ? steps : [];
|
|
998
|
+
}
|
|
940
999
|
function generateJsonLdScript(schemas) {
|
|
941
1000
|
if (schemas.length === 0) return "";
|
|
942
1001
|
if (schemas.length === 1) {
|
|
943
|
-
return `<script type="application/ld+json">${
|
|
1002
|
+
return `<script type="application/ld+json">${serializeJsonForHtml(schemas[0])}</script>`;
|
|
944
1003
|
}
|
|
945
|
-
return schemas.map((s) => `<script type="application/ld+json">${
|
|
1004
|
+
return schemas.map((s) => `<script type="application/ld+json">${serializeJsonForHtml(s)}</script>`).join("\n");
|
|
946
1005
|
}
|
|
947
1006
|
async function generateAEOFiles(configOrRoot, maybeConfig) {
|
|
948
1007
|
var _a;
|
|
@@ -1275,15 +1334,18 @@ function auditSchemaPresence(config, issues, suggestions) {
|
|
|
1275
1334
|
if (!hasLogo) {
|
|
1276
1335
|
suggestions.push("Add schema.organization.logo for richer search results and AI knowledge");
|
|
1277
1336
|
}
|
|
1278
|
-
const
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1337
|
+
const hasFaqOrHowTo = config.pages.some((p) => {
|
|
1338
|
+
const content = p.content || "";
|
|
1339
|
+
return /^#{1,6}\s+.+\?\s*$/m.test(content) || /^#{1,6}\s+(?:Step\s+\d+[\s:.-]|How\s+to)/im.test(content);
|
|
1340
|
+
});
|
|
1341
|
+
checks.push({ label: "FAQPage or HowTo schema", passed: hasFaqOrHowTo, points: hasFaqOrHowTo ? 4 : 0 });
|
|
1342
|
+
if (!hasFaqOrHowTo) {
|
|
1343
|
+
suggestions.push("Add FAQ sections (question headings) or step-by-step content to auto-generate FAQPage/HowTo schema");
|
|
1282
1344
|
}
|
|
1283
|
-
const
|
|
1284
|
-
checks.push({ label: "
|
|
1285
|
-
if (!
|
|
1286
|
-
|
|
1345
|
+
const hasArticleOrWebPage = schemaEnabled && (config.schema.defaultType === "Article" || config.schema.defaultType === "WebPage");
|
|
1346
|
+
checks.push({ label: "Article/WebPage schema", passed: hasArticleOrWebPage, points: hasArticleOrWebPage ? 4 : 0 });
|
|
1347
|
+
if (!hasArticleOrWebPage && schemaEnabled) {
|
|
1348
|
+
suggestions.push('Set schema.defaultType to "Article" or "WebPage" for per-page structured data');
|
|
1287
1349
|
}
|
|
1288
1350
|
return {
|
|
1289
1351
|
name: "Schema Presence",
|
|
@@ -1322,12 +1384,10 @@ function auditMetaQuality(config, issues, suggestions) {
|
|
|
1322
1384
|
if (!goodTitleCoverage && config.pages.length > 0) {
|
|
1323
1385
|
issues.push({ category: "Meta Quality", severity: "warning", message: `Only ${pagesWithTitles.length}/${config.pages.length} pages have titles`, fix: "Add titles to all pages" });
|
|
1324
1386
|
}
|
|
1325
|
-
const
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
if (!goodDescCoverage && config.pages.length > 0) {
|
|
1330
|
-
suggestions.push(`Only ${pagesWithDesc.length}/${config.pages.length} pages have descriptions \u2014 add per-page descriptions`);
|
|
1387
|
+
const hasOgImage = !!config.og.image;
|
|
1388
|
+
checks.push({ label: "OG image configured", passed: hasOgImage, points: hasOgImage ? 4 : 0 });
|
|
1389
|
+
if (!hasOgImage) {
|
|
1390
|
+
suggestions.push("Set og.image for richer social sharing previews and AI citation cards");
|
|
1331
1391
|
}
|
|
1332
1392
|
return {
|
|
1333
1393
|
name: "Meta Quality",
|