@seolful/nextjs-connector 1.0.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.
- package/bin/seolful-next.mjs +4 -0
- package/dist/api.d.ts +4 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +43 -0
- package/dist/api.js.map +1 -0
- package/dist/cli/handshake.d.ts +17 -0
- package/dist/cli/handshake.d.ts.map +1 -0
- package/dist/cli/handshake.js +30 -0
- package/dist/cli/handshake.js.map +1 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +173 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/scaffold.d.ts +6 -0
- package/dist/cli/scaffold.d.ts.map +1 -0
- package/dist/cli/scaffold.js +101 -0
- package/dist/cli/scaffold.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +44 -0
- package/dist/config.js.map +1 -0
- package/dist/crawler/analyze.d.ts +18 -0
- package/dist/crawler/analyze.d.ts.map +1 -0
- package/dist/crawler/analyze.js +114 -0
- package/dist/crawler/analyze.js.map +1 -0
- package/dist/crawler/crawl-service.d.ts +10 -0
- package/dist/crawler/crawl-service.d.ts.map +1 -0
- package/dist/crawler/crawl-service.js +79 -0
- package/dist/crawler/crawl-service.js.map +1 -0
- package/dist/crawler/discover.d.ts +5 -0
- package/dist/crawler/discover.d.ts.map +1 -0
- package/dist/crawler/discover.js +49 -0
- package/dist/crawler/discover.js.map +1 -0
- package/dist/handlers/audit-data.d.ts +3 -0
- package/dist/handlers/audit-data.d.ts.map +1 -0
- package/dist/handlers/audit-data.js +46 -0
- package/dist/handlers/audit-data.js.map +1 -0
- package/dist/handlers/crawl.d.ts +2 -0
- package/dist/handlers/crawl.d.ts.map +1 -0
- package/dist/handlers/crawl.js +11 -0
- package/dist/handlers/crawl.js.map +1 -0
- package/dist/handlers/demote-h1.d.ts +3 -0
- package/dist/handlers/demote-h1.d.ts.map +1 -0
- package/dist/handlers/demote-h1.js +28 -0
- package/dist/handlers/demote-h1.js.map +1 -0
- package/dist/handlers/update-ai-visibility.d.ts +3 -0
- package/dist/handlers/update-ai-visibility.d.ts.map +1 -0
- package/dist/handlers/update-ai-visibility.js +38 -0
- package/dist/handlers/update-ai-visibility.js.map +1 -0
- package/dist/handlers/update-seo.d.ts +3 -0
- package/dist/handlers/update-seo.d.ts.map +1 -0
- package/dist/handlers/update-seo.js +65 -0
- package/dist/handlers/update-seo.js.map +1 -0
- package/dist/helpers/generate-metadata.d.ts +3 -0
- package/dist/helpers/generate-metadata.d.ts.map +1 -0
- package/dist/helpers/generate-metadata.js +15 -0
- package/dist/helpers/generate-metadata.js.map +1 -0
- package/dist/helpers/get-page-seo.d.ts +3 -0
- package/dist/helpers/get-page-seo.d.ts.map +1 -0
- package/dist/helpers/get-page-seo.js +10 -0
- package/dist/helpers/get-page-seo.js.map +1 -0
- package/dist/helpers/seolful-h1.d.ts +10 -0
- package/dist/helpers/seolful-h1.d.ts.map +1 -0
- package/dist/helpers/seolful-h1.js +11 -0
- package/dist/helpers/seolful-h1.js.map +1 -0
- package/dist/helpers/seolful-image.d.ts +8 -0
- package/dist/helpers/seolful-image.d.ts.map +1 -0
- package/dist/helpers/seolful-image.js +8 -0
- package/dist/helpers/seolful-image.js.map +1 -0
- package/dist/helpers/seolful-schema.d.ts +6 -0
- package/dist/helpers/seolful-schema.d.ts.map +1 -0
- package/dist/helpers/seolful-schema.js +10 -0
- package/dist/helpers/seolful-schema.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/validate-token.d.ts +8 -0
- package/dist/middleware/validate-token.d.ts.map +1 -0
- package/dist/middleware/validate-token.js +29 -0
- package/dist/middleware/validate-token.js.map +1 -0
- package/dist/storage/file-adapter.d.ts +24 -0
- package/dist/storage/file-adapter.d.ts.map +1 -0
- package/dist/storage/file-adapter.js +118 -0
- package/dist/storage/file-adapter.js.map +1 -0
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +13 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/types.d.ts +2 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/types.d.ts +60 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawl-service.d.ts","sourceRoot":"","sources":["../../src/crawler/crawl-service.ts"],"names":[],"mappings":"AASA,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,eAAe,EAAE,MAAM,CAAA;CACxB;AAMD,wBAAsB,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,CAmBtD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { getConfig } from '../config.js';
|
|
2
|
+
import { getStorage } from '../storage/index.js';
|
|
3
|
+
import { discoverUrls } from './discover.js';
|
|
4
|
+
import { analyzePage } from './analyze.js';
|
|
5
|
+
const LOCK_TTL_MS = 300_000; // 5 minutes
|
|
6
|
+
const BATCH_SIZE = 20;
|
|
7
|
+
function sleep(ms) {
|
|
8
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
9
|
+
}
|
|
10
|
+
export async function crawlSite() {
|
|
11
|
+
const storage = getStorage();
|
|
12
|
+
const locked = await storage.acquireLock('crawling', LOCK_TTL_MS);
|
|
13
|
+
if (!locked) {
|
|
14
|
+
return {
|
|
15
|
+
crawled: 0,
|
|
16
|
+
failed: 0,
|
|
17
|
+
total: 0,
|
|
18
|
+
firstError: 'A crawl is already in progress.',
|
|
19
|
+
discoveryMethod: 'skipped',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
return await doCrawl();
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
await storage.releaseLock('crawling');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function doCrawl() {
|
|
30
|
+
const config = getConfig();
|
|
31
|
+
const storage = getStorage();
|
|
32
|
+
const delayMs = config.crawl?.delayMs ?? 300;
|
|
33
|
+
const timeout = (config.crawl?.timeout ?? 10) * 1000;
|
|
34
|
+
const { urls, method } = await discoverUrls();
|
|
35
|
+
const total = urls.length;
|
|
36
|
+
let crawled = 0;
|
|
37
|
+
let failed = 0;
|
|
38
|
+
let firstError = null;
|
|
39
|
+
const batch = [];
|
|
40
|
+
for (const url of urls) {
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(timeout) });
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(`HTTP ${response.status}`);
|
|
45
|
+
}
|
|
46
|
+
const html = await response.text();
|
|
47
|
+
const analysis = analyzePage(url, html);
|
|
48
|
+
batch.push({
|
|
49
|
+
...analysis,
|
|
50
|
+
demoteH1: false,
|
|
51
|
+
crawledAt: new Date().toISOString(),
|
|
52
|
+
});
|
|
53
|
+
crawled++;
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
57
|
+
firstError ??= message;
|
|
58
|
+
failed++;
|
|
59
|
+
}
|
|
60
|
+
if (batch.length >= BATCH_SIZE) {
|
|
61
|
+
await storage.upsertPages(batch);
|
|
62
|
+
batch.length = 0;
|
|
63
|
+
}
|
|
64
|
+
if (delayMs > 0) {
|
|
65
|
+
await sleep(delayMs);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (batch.length > 0) {
|
|
69
|
+
await storage.upsertPages(batch);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
crawled,
|
|
73
|
+
failed,
|
|
74
|
+
total,
|
|
75
|
+
firstError,
|
|
76
|
+
discoveryMethod: method,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=crawl-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawl-service.js","sourceRoot":"","sources":["../../src/crawler/crawl-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/crawler/discover.ts"],"names":[],"mappings":"AAEA,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBhF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { getConfig } from '../config.js';
|
|
2
|
+
export async function discoverUrls() {
|
|
3
|
+
const config = getConfig();
|
|
4
|
+
const siteUrl = config.siteUrl.replace(/\/$/, '');
|
|
5
|
+
const explicit = config.crawl?.urls ?? [];
|
|
6
|
+
if (explicit.length > 0) {
|
|
7
|
+
return { urls: explicit, method: 'config list' };
|
|
8
|
+
}
|
|
9
|
+
if (config.crawl?.useSitemap !== false) {
|
|
10
|
+
const sitemapUrl = config.crawl?.sitemapUrl ?? `${siteUrl}/sitemap.xml`;
|
|
11
|
+
const urls = await parseSitemap(sitemapUrl);
|
|
12
|
+
if (urls.length > 0) {
|
|
13
|
+
return { urls, method: 'sitemap.xml' };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return { urls: [siteUrl + '/'], method: 'root only' };
|
|
17
|
+
}
|
|
18
|
+
async function parseSitemap(url, depth = 0) {
|
|
19
|
+
if (depth > 3)
|
|
20
|
+
return [];
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(10_000) });
|
|
23
|
+
if (!response.ok)
|
|
24
|
+
return [];
|
|
25
|
+
const body = await response.text();
|
|
26
|
+
const urls = [];
|
|
27
|
+
// Extract <loc> from <url> entries
|
|
28
|
+
const locMatches = body.matchAll(/<url>\s*<loc>([^<]+)<\/loc>/gs);
|
|
29
|
+
for (const match of locMatches) {
|
|
30
|
+
const loc = match[1].trim();
|
|
31
|
+
if (loc)
|
|
32
|
+
urls.push(loc);
|
|
33
|
+
}
|
|
34
|
+
// Handle sitemap index — <sitemap><loc>...</loc></sitemap>
|
|
35
|
+
const sitemapMatches = body.matchAll(/<sitemap>\s*<loc>([^<]+)<\/loc>/gs);
|
|
36
|
+
for (const match of sitemapMatches) {
|
|
37
|
+
const loc = match[1].trim();
|
|
38
|
+
if (loc) {
|
|
39
|
+
const childUrls = await parseSitemap(loc, depth + 1);
|
|
40
|
+
urls.push(...childUrls);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return [...new Set(urls)];
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=discover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/crawler/discover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAExC,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAEjD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,CAAA;IACzC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;IAClD,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,UAAU,KAAK,KAAK,EAAE,CAAC;QACvC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,UAAU,IAAI,GAAG,OAAO,cAAc,CAAA;QACvE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAA;QAC3C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;QACxC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,CAAC,OAAO,GAAG,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;AACvD,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,KAAK,GAAG,CAAC;IAChD,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAExB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC1E,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,EAAE,CAAA;QAE3B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,MAAM,IAAI,GAAa,EAAE,CAAA;QAEzB,mCAAmC;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAA;QACjE,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;YAC3B,IAAI,GAAG;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC;QAED,2DAA2D;QAC3D,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,mCAAmC,CAAC,CAAA;QACzE,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;YAC3B,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;gBACpD,IAAI,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAA;YACzB,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-data.d.ts","sourceRoot":"","sources":["../../src/handlers/audit-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAMzC,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6C9E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getStorage } from '../storage/index.js';
|
|
2
|
+
import { getPageRole } from '../types.js';
|
|
3
|
+
const PER_PAGE = 75;
|
|
4
|
+
export async function auditDataHandler(request) {
|
|
5
|
+
const url = new URL(request.url);
|
|
6
|
+
const page = Math.max(1, Number(url.searchParams.get('page') ?? 1));
|
|
7
|
+
const storage = getStorage();
|
|
8
|
+
const { data, total } = await storage.getAllPages(page, PER_PAGE);
|
|
9
|
+
const lastPage = Math.max(1, Math.ceil(total / PER_PAGE));
|
|
10
|
+
const items = data.map((p) => {
|
|
11
|
+
const missingAltImages = (p.imageAlts ?? []).filter((img) => img.missing);
|
|
12
|
+
return {
|
|
13
|
+
url: p.url,
|
|
14
|
+
post_id: p.id,
|
|
15
|
+
title: p.title,
|
|
16
|
+
meta_description: p.metaDescription,
|
|
17
|
+
page_role: getPageRole(p),
|
|
18
|
+
h1_in_content: p.h1Count > 1,
|
|
19
|
+
h1_text: p.h1Count > 1 ? p.h1Secondary : null,
|
|
20
|
+
word_count: p.wordCount,
|
|
21
|
+
images_missing_alt: missingAltImages.map((img) => ({ src: img.src })),
|
|
22
|
+
internal_links: p.internalLinkCount,
|
|
23
|
+
structured_data: p.structuredData ?? [],
|
|
24
|
+
is_noindexed: p.noindex,
|
|
25
|
+
canonical_url: p.canonicalUrl,
|
|
26
|
+
page_builder: null,
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
let connectorVersion = null;
|
|
30
|
+
try {
|
|
31
|
+
const pkg = await import('../../package.json', { with: { type: 'json' } });
|
|
32
|
+
connectorVersion = pkg.default.version;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// ignore
|
|
36
|
+
}
|
|
37
|
+
return Response.json({
|
|
38
|
+
data: items,
|
|
39
|
+
current_page: page,
|
|
40
|
+
last_page: lastPage,
|
|
41
|
+
per_page: PER_PAGE,
|
|
42
|
+
total,
|
|
43
|
+
connector_version: connectorVersion,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=audit-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-data.js","sourceRoot":"","sources":["../../src/handlers/audit-data.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,QAAQ,GAAG,EAAE,CAAA;AAEnB,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAoB;IACzD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAEnE,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAA;IAEzD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,MAAM,gBAAgB,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAEzE,OAAO;YACL,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,OAAO,EAAE,CAAC,CAAC,EAAE;YACb,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,gBAAgB,EAAE,CAAC,CAAC,eAAe;YACnC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;YACzB,aAAa,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;YAC5B,OAAO,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;YAC7C,UAAU,EAAE,CAAC,CAAC,SAAS;YACvB,kBAAkB,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;YACrE,cAAc,EAAE,CAAC,CAAC,iBAAiB;YACnC,eAAe,EAAE,CAAC,CAAC,cAAc,IAAI,EAAE;YACvC,YAAY,EAAE,CAAC,CAAC,OAAO;YACvB,aAAa,EAAE,CAAC,CAAC,YAAY;YAC7B,YAAY,EAAE,IAAI;SACnB,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,gBAAgB,GAAkB,IAAI,CAAA;IAC1C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;QAC1E,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAA;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC;QACnB,IAAI,EAAE,KAAK;QACX,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,QAAQ;QACnB,QAAQ,EAAE,QAAQ;QAClB,KAAK;QACL,iBAAiB,EAAE,gBAAgB;KACpC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawl.d.ts","sourceRoot":"","sources":["../../src/handlers/crawl.ts"],"names":[],"mappings":"AAEA,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAStD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { crawlSite } from '../crawler/crawl-service.js';
|
|
2
|
+
export async function crawlHandler() {
|
|
3
|
+
const result = await crawlSite();
|
|
4
|
+
return Response.json({
|
|
5
|
+
status: 'success',
|
|
6
|
+
crawled: result.crawled,
|
|
7
|
+
failed: result.failed,
|
|
8
|
+
total: result.total,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=crawl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawl.js","sourceRoot":"","sources":["../../src/handlers/crawl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAEvD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;IAEhC,OAAO,QAAQ,CAAC,IAAI,CAAC;QACnB,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demote-h1.d.ts","sourceRoot":"","sources":["../../src/handlers/demote-h1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAGzC,wBAAsB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8B7E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getStorage } from '../storage/index.js';
|
|
2
|
+
export async function demoteH1Handler(request) {
|
|
3
|
+
const data = (await request.json());
|
|
4
|
+
if (!data.post_id || typeof data.post_id !== 'number') {
|
|
5
|
+
return Response.json({ error: 'post_id is required' }, { status: 422 });
|
|
6
|
+
}
|
|
7
|
+
const storage = getStorage();
|
|
8
|
+
const page = await storage.getPageById(data.post_id);
|
|
9
|
+
if (!page) {
|
|
10
|
+
return Response.json({ error: 'Page not found' }, { status: 404 });
|
|
11
|
+
}
|
|
12
|
+
page.demoteH1 = true;
|
|
13
|
+
const { id: _, ...pageWithoutId } = page;
|
|
14
|
+
await storage.upsertPage(pageWithoutId);
|
|
15
|
+
try {
|
|
16
|
+
const { revalidatePath } = await import('next/cache');
|
|
17
|
+
const pathname = new URL(page.url).pathname;
|
|
18
|
+
revalidatePath(pathname);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// revalidatePath may not be available outside Next.js runtime
|
|
22
|
+
}
|
|
23
|
+
return Response.json({
|
|
24
|
+
status: 'success',
|
|
25
|
+
fields_updated: ['h1'],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=demote-h1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demote-h1.js","sourceRoot":"","sources":["../../src/handlers/demote-h1.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAoB;IACxD,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAA4B,CAAA;IAE9D,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACtD,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAEpD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACpE,CAAC;IAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,aAAa,EAAE,GAAG,IAAI,CAAA;IACxC,MAAM,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;IAEvC,IAAI,CAAC;QACH,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAA;QACrD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAA;QAC3C,cAAc,CAAC,QAAQ,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC;QACnB,MAAM,EAAE,SAAS;QACjB,cAAc,EAAE,CAAC,IAAI,CAAC;KACvB,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-ai-visibility.d.ts","sourceRoot":"","sources":["../../src/handlers/update-ai-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAKzC,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqCjF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { getStorage } from '../storage/index.js';
|
|
4
|
+
export async function aiVisibilityHandler(request) {
|
|
5
|
+
const data = (await request.json());
|
|
6
|
+
const updated = [];
|
|
7
|
+
if (data.llms_txt_content !== undefined) {
|
|
8
|
+
const publicDir = join(process.cwd(), 'public');
|
|
9
|
+
if (!existsSync(publicDir))
|
|
10
|
+
mkdirSync(publicDir, { recursive: true });
|
|
11
|
+
writeFileSync(join(publicDir, 'llms.txt'), String(data.llms_txt_content));
|
|
12
|
+
updated.push('llms_txt_content');
|
|
13
|
+
}
|
|
14
|
+
if (data.schema_jsonld !== undefined && data.post_id !== undefined) {
|
|
15
|
+
const storage = getStorage();
|
|
16
|
+
const page = await storage.getPageById(Number(data.post_id));
|
|
17
|
+
if (!page) {
|
|
18
|
+
return Response.json({ error: 'Page not found' }, { status: 404 });
|
|
19
|
+
}
|
|
20
|
+
page.structuredData = Array.isArray(data.schema_jsonld) ? data.schema_jsonld : [data.schema_jsonld];
|
|
21
|
+
const { id: _, ...pageWithoutId } = page;
|
|
22
|
+
await storage.upsertPage(pageWithoutId);
|
|
23
|
+
updated.push('schema_jsonld');
|
|
24
|
+
try {
|
|
25
|
+
const { revalidatePath } = await import('next/cache');
|
|
26
|
+
const pathname = new URL(page.url).pathname;
|
|
27
|
+
revalidatePath(pathname);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// revalidatePath may not be available outside Next.js runtime
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return Response.json({
|
|
34
|
+
status: 'success',
|
|
35
|
+
fields_updated: updated,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=update-ai-visibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-ai-visibility.js","sourceRoot":"","sources":["../../src/handlers/update-ai-visibility.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAoB;IAC5D,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAA4B,CAAA;IAC9D,MAAM,OAAO,GAAa,EAAE,CAAA;IAE5B,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAA;QAC/C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACrE,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAA;QACzE,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACnE,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;QAC5B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;QAE5D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QACpE,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAyB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAuB,CAAC,CAAA;QACzH,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,aAAa,EAAE,GAAG,IAAI,CAAA;QACxC,MAAM,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;QACvC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QAE7B,IAAI,CAAC;YACH,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAA;YACrD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAA;YAC3C,cAAc,CAAC,QAAQ,CAAC,CAAA;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,8DAA8D;QAChE,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC;QACnB,MAAM,EAAE,SAAS;QACjB,cAAc,EAAE,OAAO;KACxB,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-seo.d.ts","sourceRoot":"","sources":["../../src/handlers/update-seo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAqBzC,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAuD9E"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { getStorage } from '../storage/index.js';
|
|
2
|
+
const LABEL_PREFIXES = [
|
|
3
|
+
'Meta Description:', 'Meta description:',
|
|
4
|
+
'Title Tag:', 'Title tag:', 'Title:',
|
|
5
|
+
'New Title:', 'New Meta Description:',
|
|
6
|
+
'Revised Title:', 'Revised Meta Description:',
|
|
7
|
+
'Updated Title:', 'Updated Meta Description:',
|
|
8
|
+
'H1:', 'H1 Heading:', 'Alt Text:', 'Alt text:',
|
|
9
|
+
];
|
|
10
|
+
function stripLabelPrefix(value) {
|
|
11
|
+
for (const prefix of LABEL_PREFIXES) {
|
|
12
|
+
if (value.startsWith(prefix)) {
|
|
13
|
+
return value.slice(prefix.length).trim();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
export async function updateSeoHandler(request) {
|
|
19
|
+
const data = (await request.json());
|
|
20
|
+
if (!data.post_id || typeof data.post_id !== 'number') {
|
|
21
|
+
return Response.json({ error: 'post_id is required' }, { status: 422 });
|
|
22
|
+
}
|
|
23
|
+
const storage = getStorage();
|
|
24
|
+
const page = await storage.getPageById(data.post_id);
|
|
25
|
+
if (!page) {
|
|
26
|
+
return Response.json({ error: 'Page not found' }, { status: 404 });
|
|
27
|
+
}
|
|
28
|
+
const updated = [];
|
|
29
|
+
if (data.meta_title !== undefined) {
|
|
30
|
+
page.title = stripLabelPrefix(String(data.meta_title));
|
|
31
|
+
updated.push('meta_title');
|
|
32
|
+
}
|
|
33
|
+
if (data.meta_description !== undefined) {
|
|
34
|
+
page.metaDescription = stripLabelPrefix(String(data.meta_description));
|
|
35
|
+
updated.push('meta_description');
|
|
36
|
+
}
|
|
37
|
+
if (data.image_src !== undefined && data.image_alt !== undefined) {
|
|
38
|
+
const alts = page.imageAlts ?? [];
|
|
39
|
+
for (const img of alts) {
|
|
40
|
+
if (img.src === data.image_src) {
|
|
41
|
+
img.alt = String(data.image_alt);
|
|
42
|
+
img.missing = false;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
page.imageAlts = alts;
|
|
47
|
+
updated.push('image_alt');
|
|
48
|
+
}
|
|
49
|
+
const { id: _, ...pageWithoutId } = page;
|
|
50
|
+
await storage.upsertPage(pageWithoutId);
|
|
51
|
+
// Trigger ISR revalidation
|
|
52
|
+
try {
|
|
53
|
+
const { revalidatePath } = await import('next/cache');
|
|
54
|
+
const pathname = new URL(page.url).pathname;
|
|
55
|
+
revalidatePath(pathname);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// revalidatePath may not be available outside Next.js runtime
|
|
59
|
+
}
|
|
60
|
+
return Response.json({
|
|
61
|
+
status: 'success',
|
|
62
|
+
fields_updated: updated,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=update-seo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-seo.js","sourceRoot":"","sources":["../../src/handlers/update-seo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-metadata.d.ts","sourceRoot":"","sources":["../../src/helpers/generate-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAGpC,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,QAAQ,CAAC,CAenB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getPageSeo } from './get-page-seo.js';
|
|
2
|
+
export async function withSeolfulMetadata(pathname, base) {
|
|
3
|
+
const seo = await getPageSeo(pathname);
|
|
4
|
+
if (!seo)
|
|
5
|
+
return base;
|
|
6
|
+
const merged = { ...base };
|
|
7
|
+
if (seo.title) {
|
|
8
|
+
merged.title = seo.title;
|
|
9
|
+
}
|
|
10
|
+
if (seo.metaDescription) {
|
|
11
|
+
merged.description = seo.metaDescription;
|
|
12
|
+
}
|
|
13
|
+
return merged;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=generate-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-metadata.js","sourceRoot":"","sources":["../../src/helpers/generate-metadata.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB,EAChB,IAAc;IAEd,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAA;IACtC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IAErB,MAAM,MAAM,GAAa,EAAE,GAAG,IAAI,EAAE,CAAA;IAEpC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAA;IAC1B,CAAC;IAED,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;QACxB,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,eAAe,CAAA;IAC1C,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-page-seo.d.ts","sourceRoot":"","sources":["../../src/helpers/get-page-seo.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAO1E"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getStorage } from '../storage/index.js';
|
|
2
|
+
import { getConfig } from '../config.js';
|
|
3
|
+
export async function getPageSeo(pathname) {
|
|
4
|
+
const config = getConfig();
|
|
5
|
+
const siteUrl = config.siteUrl.replace(/\/$/, '');
|
|
6
|
+
const fullUrl = siteUrl + pathname;
|
|
7
|
+
const storage = getStorage();
|
|
8
|
+
return storage.getPageByUrl(fullUrl);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=get-page-seo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-page-seo.js","sourceRoot":"","sources":["../../src/helpers/get-page-seo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAGxC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACjD,MAAM,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAA;IAElC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,OAAO,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;AACtC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
interface SeolfulH1Props {
|
|
3
|
+
pathname: string;
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
isSecondary?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function SeolfulH1({ pathname, children, className, isSecondary, }: SeolfulH1Props): Promise<import("react").JSX.Element>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=seolful-h1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seolful-h1.d.ts","sourceRoot":"","sources":["../../src/helpers/seolful-h1.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,wBAAsB,SAAS,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,WAAmB,GACpB,EAAE,cAAc,wCAShB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getPageSeo } from './get-page-seo.js';
|
|
3
|
+
export async function SeolfulH1({ pathname, children, className, isSecondary = false, }) {
|
|
4
|
+
const seo = await getPageSeo(pathname);
|
|
5
|
+
const shouldDemote = isSecondary && seo?.demoteH1;
|
|
6
|
+
if (shouldDemote) {
|
|
7
|
+
return _jsx("h2", { className: className, children: children });
|
|
8
|
+
}
|
|
9
|
+
return _jsx("h1", { className: className, children: children });
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=seolful-h1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seolful-h1.js","sourceRoot":"","sources":["../../src/helpers/seolful-h1.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAU9C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,WAAW,GAAG,KAAK,GACJ;IACf,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAA;IACtC,MAAM,YAAY,GAAG,WAAW,IAAI,GAAG,EAAE,QAAQ,CAAA;IAEjD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,aAAI,SAAS,EAAE,SAAS,YAAG,QAAQ,GAAM,CAAA;IAClD,CAAC;IAED,OAAO,aAAI,SAAS,EAAE,SAAS,YAAG,QAAQ,GAAM,CAAA;AAClD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ImageProps } from 'next/image';
|
|
2
|
+
import type { ImageAlt } from '../types.js';
|
|
3
|
+
type SeolfulImageProps = ImageProps & {
|
|
4
|
+
seolfulAlts?: ImageAlt[];
|
|
5
|
+
};
|
|
6
|
+
export declare function SeolfulImage({ src, seolfulAlts, alt, ...props }: SeolfulImageProps): import("react").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=seolful-image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seolful-image.d.ts","sourceRoot":"","sources":["../../src/helpers/seolful-image.tsx"],"names":[],"mappings":"AAEA,OAAc,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,KAAK,iBAAiB,GAAG,UAAU,GAAG;IACpC,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAA;CACzB,CAAA;AAED,wBAAgB,YAAY,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,+BAGlF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import Image from 'next/image';
|
|
4
|
+
export function SeolfulImage({ src, seolfulAlts, alt, ...props }) {
|
|
5
|
+
const resolved = seolfulAlts?.find((a) => a.src === String(src))?.alt ?? alt;
|
|
6
|
+
return _jsx(Image, { src: src, alt: resolved ?? '', ...props });
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=seolful-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seolful-image.js","sourceRoot":"","sources":["../../src/helpers/seolful-image.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAA0B,MAAM,YAAY,CAAA;AAOnD,MAAM,UAAU,YAAY,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,KAAK,EAAqB;IACjF,MAAM,QAAQ,GAAG,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,GAAG,CAAA;IAC5E,OAAO,KAAC,KAAK,IAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,IAAI,EAAE,KAAM,KAAK,GAAI,CAAA;AAC5D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seolful-schema.d.ts","sourceRoot":"","sources":["../../src/helpers/seolful-schema.tsx"],"names":[],"mappings":"AAEA,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAsB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,kBAAkB,+CAiBnE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { getPageSeo } from './get-page-seo.js';
|
|
3
|
+
export async function SeolfulSchema({ pathname }) {
|
|
4
|
+
const seo = await getPageSeo(pathname);
|
|
5
|
+
const schemas = seo?.structuredData ?? [];
|
|
6
|
+
if (schemas.length === 0)
|
|
7
|
+
return null;
|
|
8
|
+
return (_jsx(_Fragment, { children: schemas.map((schema, i) => (_jsx("script", { type: "application/ld+json", dangerouslySetInnerHTML: { __html: JSON.stringify(schema) } }, i))) }));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=seolful-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seolful-schema.js","sourceRoot":"","sources":["../../src/helpers/seolful-schema.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAM9C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAE,QAAQ,EAAsB;IAClE,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAA;IACtC,MAAM,OAAO,GAAG,GAAG,EAAE,cAAc,IAAI,EAAE,CAAA;IAEzC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAErC,OAAO,CACL,4BACG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAC1B,iBAEE,IAAI,EAAC,qBAAqB,EAC1B,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAFtD,CAAC,CAGN,CACH,CAAC,GACD,CACJ,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { SeolfulConfig, SeolfulConnection, SeoPage, ImageAlt, StorageAdapter, } from './types.js';
|
|
2
|
+
export { getPageRole } from './types.js';
|
|
3
|
+
export { getConfig, getStorageDir, clearConfigCache } from './config.js';
|
|
4
|
+
export { getStorage, setStorage } from './storage/index.js';
|
|
5
|
+
export { FileAdapter } from './storage/file-adapter.js';
|
|
6
|
+
export { getPageSeo } from './helpers/get-page-seo.js';
|
|
7
|
+
export { withSeolfulMetadata } from './helpers/generate-metadata.js';
|
|
8
|
+
export { SeolfulImage } from './helpers/seolful-image.js';
|
|
9
|
+
export { SeolfulSchema } from './helpers/seolful-schema.js';
|
|
10
|
+
export { SeolfulH1 } from './helpers/seolful-h1.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,OAAO,EACP,QAAQ,EACR,cAAc,GACf,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAGxC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGxE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAGvD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { getPageRole } from './types.js';
|
|
2
|
+
// Config
|
|
3
|
+
export { getConfig, getStorageDir, clearConfigCache } from './config.js';
|
|
4
|
+
// Storage
|
|
5
|
+
export { getStorage, setStorage } from './storage/index.js';
|
|
6
|
+
export { FileAdapter } from './storage/file-adapter.js';
|
|
7
|
+
// Helpers — user-facing
|
|
8
|
+
export { getPageSeo } from './helpers/get-page-seo.js';
|
|
9
|
+
export { withSeolfulMetadata } from './helpers/generate-metadata.js';
|
|
10
|
+
export { SeolfulImage } from './helpers/seolful-image.js';
|
|
11
|
+
export { SeolfulSchema } from './helpers/seolful-schema.js';
|
|
12
|
+
export { SeolfulH1 } from './helpers/seolful-h1.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAExC,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAExE,UAAU;AACV,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAEvD,wBAAwB;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA"}
|