@orion-studios/payload-seo-audit 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/README.md +127 -0
- package/bin/init.js +267 -0
- package/dist/api/backlinks-import.d.ts +4 -0
- package/dist/api/backlinks-import.d.ts.map +1 -0
- package/dist/api/backlinks-import.js +182 -0
- package/dist/api/cron.d.ts +4 -0
- package/dist/api/cron.d.ts.map +1 -0
- package/dist/api/cron.js +89 -0
- package/dist/api/index.d.ts +10 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +21 -0
- package/dist/api/page-result.d.ts +4 -0
- package/dist/api/page-result.d.ts.map +1 -0
- package/dist/api/page-result.js +93 -0
- package/dist/api/page-results.d.ts +4 -0
- package/dist/api/page-results.d.ts.map +1 -0
- package/dist/api/page-results.js +83 -0
- package/dist/api/run-stream.d.ts +4 -0
- package/dist/api/run-stream.d.ts.map +1 -0
- package/dist/api/run-stream.js +273 -0
- package/dist/api/run.d.ts +4 -0
- package/dist/api/run.d.ts.map +1 -0
- package/dist/api/run.js +102 -0
- package/dist/api/snapshot-report.d.ts +4 -0
- package/dist/api/snapshot-report.d.ts.map +1 -0
- package/dist/api/snapshot-report.js +130 -0
- package/dist/api/snapshots.d.ts +4 -0
- package/dist/api/snapshots.d.ts.map +1 -0
- package/dist/api/snapshots.js +138 -0
- package/dist/api/trend.d.ts +4 -0
- package/dist/api/trend.d.ts.map +1 -0
- package/dist/api/trend.js +71 -0
- package/dist/collections/SeoAuthoritySnapshots.d.ts +3 -0
- package/dist/collections/SeoAuthoritySnapshots.d.ts.map +1 -0
- package/dist/collections/SeoAuthoritySnapshots.js +83 -0
- package/dist/collections/SeoKeywordVisibility.d.ts +3 -0
- package/dist/collections/SeoKeywordVisibility.d.ts.map +1 -0
- package/dist/collections/SeoKeywordVisibility.js +65 -0
- package/dist/collections/SeoPageResults.d.ts +3 -0
- package/dist/collections/SeoPageResults.d.ts.map +1 -0
- package/dist/collections/SeoPageResults.js +170 -0
- package/dist/collections/SeoSnapshots.d.ts +3 -0
- package/dist/collections/SeoSnapshots.d.ts.map +1 -0
- package/dist/collections/SeoSnapshots.js +131 -0
- package/dist/components/hooks/useSeoApi.d.ts +7 -0
- package/dist/components/hooks/useSeoApi.d.ts.map +1 -0
- package/dist/components/hooks/useSeoApi.js +31 -0
- package/dist/components/hooks/useSeoPageResults.d.ts +19 -0
- package/dist/components/hooks/useSeoPageResults.d.ts.map +1 -0
- package/dist/components/hooks/useSeoPageResults.js +62 -0
- package/dist/components/hooks/useSeoSnapshot.d.ts +8 -0
- package/dist/components/hooks/useSeoSnapshot.d.ts.map +1 -0
- package/dist/components/hooks/useSeoSnapshot.js +39 -0
- package/dist/components/hooks/useSeoTrend.d.ts +8 -0
- package/dist/components/hooks/useSeoTrend.d.ts.map +1 -0
- package/dist/components/hooks/useSeoTrend.js +38 -0
- package/dist/components/layout/SeoReportHeader.d.ts +10 -0
- package/dist/components/layout/SeoReportHeader.d.ts.map +1 -0
- package/dist/components/layout/SeoReportHeader.js +18 -0
- package/dist/components/layout/SeoReportShell.d.ts +9 -0
- package/dist/components/layout/SeoReportShell.d.ts.map +1 -0
- package/dist/components/layout/SeoReportShell.js +17 -0
- package/dist/components/pdf/PdfDownloadButton.d.ts +9 -0
- package/dist/components/pdf/PdfDownloadButton.d.ts.map +1 -0
- package/dist/components/pdf/PdfDownloadButton.js +80 -0
- package/dist/components/tables/IssueTable.d.ts +11 -0
- package/dist/components/tables/IssueTable.d.ts.map +1 -0
- package/dist/components/tables/IssueTable.js +121 -0
- package/dist/components/tables/PageResultsTable.d.ts +18 -0
- package/dist/components/tables/PageResultsTable.d.ts.map +1 -0
- package/dist/components/tables/PageResultsTable.js +96 -0
- package/dist/components/types.d.ts +107 -0
- package/dist/components/types.d.ts.map +1 -0
- package/dist/components/types.js +22 -0
- package/dist/components/utils/formatters.d.ts +15 -0
- package/dist/components/utils/formatters.d.ts.map +1 -0
- package/dist/components/utils/formatters.js +98 -0
- package/dist/components/utils/scoreHelpers.d.ts +17 -0
- package/dist/components/utils/scoreHelpers.d.ts.map +1 -0
- package/dist/components/utils/scoreHelpers.js +139 -0
- package/dist/components/views/SeoDashboard.d.ts +3 -0
- package/dist/components/views/SeoDashboard.d.ts.map +1 -0
- package/dist/components/views/SeoDashboard.js +239 -0
- package/dist/components/views/SeoPageReport.d.ts +3 -0
- package/dist/components/views/SeoPageReport.d.ts.map +1 -0
- package/dist/components/views/SeoPageReport.js +234 -0
- package/dist/components/views/SeoSnapshotReport.d.ts +3 -0
- package/dist/components/views/SeoSnapshotReport.d.ts.map +1 -0
- package/dist/components/views/SeoSnapshotReport.js +224 -0
- package/dist/components/visualization/CategoryScoreCard.d.ts +11 -0
- package/dist/components/visualization/CategoryScoreCard.d.ts.map +1 -0
- package/dist/components/visualization/CategoryScoreCard.js +17 -0
- package/dist/components/visualization/CategoryScoreGrid.d.ts +9 -0
- package/dist/components/visualization/CategoryScoreGrid.d.ts.map +1 -0
- package/dist/components/visualization/CategoryScoreGrid.js +32 -0
- package/dist/components/visualization/IssueCategoryChart.d.ts +8 -0
- package/dist/components/visualization/IssueCategoryChart.d.ts.map +1 -0
- package/dist/components/visualization/IssueCategoryChart.js +47 -0
- package/dist/components/visualization/MetricCard.d.ts +11 -0
- package/dist/components/visualization/MetricCard.d.ts.map +1 -0
- package/dist/components/visualization/MetricCard.js +17 -0
- package/dist/components/visualization/MetricCardRow.d.ts +7 -0
- package/dist/components/visualization/MetricCardRow.d.ts.map +1 -0
- package/dist/components/visualization/MetricCardRow.js +12 -0
- package/dist/components/visualization/ScoreBar.d.ts +11 -0
- package/dist/components/visualization/ScoreBar.d.ts.map +1 -0
- package/dist/components/visualization/ScoreBar.js +34 -0
- package/dist/components/visualization/ScoreGauge.d.ts +11 -0
- package/dist/components/visualization/ScoreGauge.d.ts.map +1 -0
- package/dist/components/visualization/ScoreGauge.js +28 -0
- package/dist/components/visualization/ScoreTrendChart.d.ts +9 -0
- package/dist/components/visualization/ScoreTrendChart.d.ts.map +1 -0
- package/dist/components/visualization/ScoreTrendChart.js +43 -0
- package/dist/components/visualization/SeverityBadge.d.ts +8 -0
- package/dist/components/visualization/SeverityBadge.d.ts.map +1 -0
- package/dist/components/visualization/SeverityBadge.js +14 -0
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +36 -0
- package/dist/exports/components.d.ts +4 -0
- package/dist/exports/components.d.ts.map +1 -0
- package/dist/exports/components.js +9 -0
- package/dist/globals/SeoDashboard.d.ts +3 -0
- package/dist/globals/SeoDashboard.d.ts.map +1 -0
- package/dist/globals/SeoDashboard.js +25 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/utilities/access.d.ts +8 -0
- package/dist/utilities/access.d.ts.map +1 -0
- package/dist/utilities/access.js +11 -0
- package/dist/utilities/auth.d.ts +7 -0
- package/dist/utilities/auth.d.ts.map +1 -0
- package/dist/utilities/auth.js +28 -0
- package/dist/utilities/checks.d.ts +3 -0
- package/dist/utilities/checks.d.ts.map +1 -0
- package/dist/utilities/checks.js +255 -0
- package/dist/utilities/crawler.d.ts +14 -0
- package/dist/utilities/crawler.d.ts.map +1 -0
- package/dist/utilities/crawler.js +152 -0
- package/dist/utilities/gsc.d.ts +15 -0
- package/dist/utilities/gsc.d.ts.map +1 -0
- package/dist/utilities/gsc.js +69 -0
- package/dist/utilities/helpers.d.ts +7 -0
- package/dist/utilities/helpers.d.ts.map +1 -0
- package/dist/utilities/helpers.js +44 -0
- package/dist/utilities/pagespeed.d.ts +3 -0
- package/dist/utilities/pagespeed.d.ts.map +1 -0
- package/dist/utilities/pagespeed.js +49 -0
- package/dist/utilities/providers.d.ts +3 -0
- package/dist/utilities/providers.d.ts.map +1 -0
- package/dist/utilities/providers.js +18 -0
- package/dist/utilities/runAudit.d.ts +14 -0
- package/dist/utilities/runAudit.d.ts.map +1 -0
- package/dist/utilities/runAudit.js +224 -0
- package/dist/utilities/scoring.d.ts +3 -0
- package/dist/utilities/scoring.d.ts.map +1 -0
- package/dist/utilities/scoring.js +45 -0
- package/dist/utilities/triggers.d.ts +3 -0
- package/dist/utilities/triggers.d.ts.map +1 -0
- package/dist/utilities/triggers.js +39 -0
- package/dist/utilities/types.d.ts +87 -0
- package/dist/utilities/types.d.ts.map +1 -0
- package/dist/utilities/types.js +2 -0
- package/package.json +63 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handleSeoSnapshotReport = handleSeoSnapshotReport;
|
|
37
|
+
const auth_1 = require("../utilities/auth");
|
|
38
|
+
async function handleSeoSnapshotReport(payload, request) {
|
|
39
|
+
const { NextResponse } = await Promise.resolve().then(() => __importStar(require('next/server')));
|
|
40
|
+
try {
|
|
41
|
+
const user = await (0, auth_1.authenticateSEOAdmin)(payload, request);
|
|
42
|
+
if (!user) {
|
|
43
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
44
|
+
}
|
|
45
|
+
const { searchParams } = new URL(request.url);
|
|
46
|
+
const snapshotParam = searchParams.get('snapshot');
|
|
47
|
+
const snapshotID = snapshotParam && Number.isFinite(Number(snapshotParam)) ? Number(snapshotParam) : null;
|
|
48
|
+
if (!snapshotID) {
|
|
49
|
+
return NextResponse.json({ error: 'snapshot query param is required.' }, { status: 400 });
|
|
50
|
+
}
|
|
51
|
+
const snapshot = await payload.findByID({
|
|
52
|
+
collection: 'seo-snapshots',
|
|
53
|
+
id: snapshotID,
|
|
54
|
+
depth: 1,
|
|
55
|
+
overrideAccess: true,
|
|
56
|
+
});
|
|
57
|
+
if (!snapshot) {
|
|
58
|
+
return NextResponse.json({ error: 'Snapshot not found.' }, { status: 404 });
|
|
59
|
+
}
|
|
60
|
+
const pageResults = await payload.find({
|
|
61
|
+
collection: 'seo-page-results',
|
|
62
|
+
where: { snapshot: { equals: snapshotID } },
|
|
63
|
+
limit: 1000,
|
|
64
|
+
sort: 'overallScore',
|
|
65
|
+
depth: 0,
|
|
66
|
+
overrideAccess: true,
|
|
67
|
+
});
|
|
68
|
+
const docs = pageResults.docs;
|
|
69
|
+
const categoryDistribution = {};
|
|
70
|
+
const severityDistribution = {};
|
|
71
|
+
let totalIssues = 0;
|
|
72
|
+
for (const doc of docs) {
|
|
73
|
+
const issues = doc.issues || [];
|
|
74
|
+
totalIssues += issues.length;
|
|
75
|
+
for (const issue of issues) {
|
|
76
|
+
if (issue.category) {
|
|
77
|
+
categoryDistribution[issue.category] = (categoryDistribution[issue.category] || 0) + 1;
|
|
78
|
+
}
|
|
79
|
+
if (issue.severity) {
|
|
80
|
+
severityDistribution[issue.severity] = (severityDistribution[issue.severity] || 0) + 1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
console.log(`[SEO Report] Processed ${docs.length} pages with ${totalIssues} total issues`);
|
|
85
|
+
const worstPages = docs
|
|
86
|
+
.filter((d) => typeof d.overallScore === 'number')
|
|
87
|
+
.sort((a, b) => (a.overallScore ?? 100) - (b.overallScore ?? 100))
|
|
88
|
+
.slice(0, 10)
|
|
89
|
+
.map((d) => ({
|
|
90
|
+
url: d.url,
|
|
91
|
+
score: d.overallScore ?? 0,
|
|
92
|
+
issueCount: (d.issues || []).length,
|
|
93
|
+
}));
|
|
94
|
+
const bestPages = docs
|
|
95
|
+
.filter((d) => typeof d.overallScore === 'number')
|
|
96
|
+
.sort((a, b) => (b.overallScore ?? 0) - (a.overallScore ?? 0))
|
|
97
|
+
.slice(0, 5)
|
|
98
|
+
.map((d) => ({
|
|
99
|
+
url: d.url,
|
|
100
|
+
score: d.overallScore ?? 0,
|
|
101
|
+
}));
|
|
102
|
+
const buckets = Array.from({ length: 10 }, (_, i) => ({
|
|
103
|
+
range: `${i * 10}-${i * 10 + 9}`,
|
|
104
|
+
count: 0,
|
|
105
|
+
}));
|
|
106
|
+
buckets[9].range = '90-100';
|
|
107
|
+
for (const doc of docs) {
|
|
108
|
+
const score = doc.overallScore;
|
|
109
|
+
if (typeof score === 'number') {
|
|
110
|
+
const bucketIndex = score >= 100 ? 9 : Math.floor(score / 10);
|
|
111
|
+
buckets[Math.min(bucketIndex, 9)].count++;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return NextResponse.json({
|
|
115
|
+
snapshot,
|
|
116
|
+
pageResults: docs,
|
|
117
|
+
aggregated: {
|
|
118
|
+
worstPages,
|
|
119
|
+
bestPages,
|
|
120
|
+
categoryDistribution,
|
|
121
|
+
severityDistribution,
|
|
122
|
+
scoreHistogram: buckets,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
console.error('SEO snapshot-report error:', error);
|
|
128
|
+
return NextResponse.json({ error: error instanceof Error ? error.message : 'Failed to load snapshot report.' }, { status: 500 });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshots.d.ts","sourceRoot":"","sources":["../../src/api/snapshots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAQ5D,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAkItG"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handleSeoSnapshots = handleSeoSnapshots;
|
|
37
|
+
const auth_1 = require("../utilities/auth");
|
|
38
|
+
const first = (value) => (Array.isArray(value) ? value[0] : value);
|
|
39
|
+
async function handleSeoSnapshots(payload, request) {
|
|
40
|
+
const { NextResponse } = await Promise.resolve().then(() => __importStar(require('next/server')));
|
|
41
|
+
try {
|
|
42
|
+
const user = await (0, auth_1.authenticateSEOAdmin)(payload, request);
|
|
43
|
+
if (!user) {
|
|
44
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
45
|
+
}
|
|
46
|
+
const url = new URL(request.url);
|
|
47
|
+
const limit = Math.max(1, Math.min(52, Number(url.searchParams.get('limit') || 12)));
|
|
48
|
+
const format = url.searchParams.get('format') || 'json';
|
|
49
|
+
const snapshots = await payload.find({
|
|
50
|
+
collection: 'seo-snapshots',
|
|
51
|
+
limit,
|
|
52
|
+
sort: '-startedAt',
|
|
53
|
+
depth: 0,
|
|
54
|
+
overrideAccess: true,
|
|
55
|
+
});
|
|
56
|
+
const latestSnapshot = snapshots.docs[0];
|
|
57
|
+
let latestIssues = [];
|
|
58
|
+
if (latestSnapshot) {
|
|
59
|
+
const pageResults = await payload.find({
|
|
60
|
+
collection: 'seo-page-results',
|
|
61
|
+
where: {
|
|
62
|
+
snapshot: { equals: latestSnapshot.id },
|
|
63
|
+
},
|
|
64
|
+
limit: 15,
|
|
65
|
+
sort: 'overallScore',
|
|
66
|
+
depth: 0,
|
|
67
|
+
overrideAccess: true,
|
|
68
|
+
});
|
|
69
|
+
const priority = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
|
|
70
|
+
const collectedIssues = [];
|
|
71
|
+
for (const doc of pageResults.docs) {
|
|
72
|
+
const issues = doc.issues || [];
|
|
73
|
+
for (const issue of issues) {
|
|
74
|
+
if (issue?.severity && issue?.message) {
|
|
75
|
+
collectedIssues.push({
|
|
76
|
+
url: doc.url,
|
|
77
|
+
severity: issue.severity,
|
|
78
|
+
message: issue.message,
|
|
79
|
+
recommendation: issue.recommendation,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (collectedIssues.length >= 50)
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
latestIssues = collectedIssues
|
|
87
|
+
.sort((a, b) => {
|
|
88
|
+
return (priority[a.severity || 'info'] ?? 5) - (priority[b.severity || 'info'] ?? 5);
|
|
89
|
+
})
|
|
90
|
+
.slice(0, 20);
|
|
91
|
+
}
|
|
92
|
+
if (format === 'csv') {
|
|
93
|
+
const header = [
|
|
94
|
+
'snapshot_id',
|
|
95
|
+
'run_label',
|
|
96
|
+
'status',
|
|
97
|
+
'started_at',
|
|
98
|
+
'completed_at',
|
|
99
|
+
'overall_score',
|
|
100
|
+
'critical',
|
|
101
|
+
'high',
|
|
102
|
+
'medium',
|
|
103
|
+
'low',
|
|
104
|
+
'info',
|
|
105
|
+
];
|
|
106
|
+
const rows = snapshots.docs.map((snapshot) => [
|
|
107
|
+
snapshot.id,
|
|
108
|
+
snapshot.runLabel || '',
|
|
109
|
+
snapshot.status || '',
|
|
110
|
+
snapshot.startedAt || '',
|
|
111
|
+
snapshot.completedAt || '',
|
|
112
|
+
snapshot.scores?.overall ?? '',
|
|
113
|
+
snapshot.issueCounts?.critical ?? 0,
|
|
114
|
+
snapshot.issueCounts?.high ?? 0,
|
|
115
|
+
snapshot.issueCounts?.medium ?? 0,
|
|
116
|
+
snapshot.issueCounts?.low ?? 0,
|
|
117
|
+
snapshot.issueCounts?.info ?? 0,
|
|
118
|
+
]
|
|
119
|
+
.map((value) => `"${String(value).replace(/"/g, '""')}"`)
|
|
120
|
+
.join(','));
|
|
121
|
+
return new NextResponse([header.join(','), ...rows].join('\n'), {
|
|
122
|
+
status: 200,
|
|
123
|
+
headers: {
|
|
124
|
+
'content-type': 'text/csv; charset=utf-8',
|
|
125
|
+
'content-disposition': 'attachment; filename="seo-snapshots.csv"',
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return NextResponse.json({
|
|
130
|
+
snapshots: snapshots.docs,
|
|
131
|
+
latestIssues,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error('SEO snapshots error:', error);
|
|
136
|
+
return NextResponse.json({ error: error instanceof Error ? error.message : 'Failed to load SEO snapshots.' }, { status: 500 });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trend.d.ts","sourceRoot":"","sources":["../../src/api/trend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAM5D,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAwClG"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handleSeoTrend = handleSeoTrend;
|
|
37
|
+
const auth_1 = require("../utilities/auth");
|
|
38
|
+
async function handleSeoTrend(payload, request) {
|
|
39
|
+
const { NextResponse } = await Promise.resolve().then(() => __importStar(require('next/server')));
|
|
40
|
+
try {
|
|
41
|
+
const user = await (0, auth_1.authenticateSEOAdmin)(payload, request);
|
|
42
|
+
if (!user) {
|
|
43
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
44
|
+
}
|
|
45
|
+
const { searchParams } = new URL(request.url);
|
|
46
|
+
const limit = Math.max(1, Math.min(52, Number(searchParams.get('limit') || 12)));
|
|
47
|
+
const snapshots = await payload.find({
|
|
48
|
+
collection: 'seo-snapshots',
|
|
49
|
+
where: {
|
|
50
|
+
status: { equals: 'completed' },
|
|
51
|
+
},
|
|
52
|
+
limit,
|
|
53
|
+
sort: '-startedAt',
|
|
54
|
+
depth: 0,
|
|
55
|
+
overrideAccess: true,
|
|
56
|
+
});
|
|
57
|
+
const points = snapshots.docs.map((doc) => ({
|
|
58
|
+
snapshotId: doc.id,
|
|
59
|
+
startedAt: doc.startedAt,
|
|
60
|
+
runLabel: doc.runLabel || '',
|
|
61
|
+
scores: doc.scores || {},
|
|
62
|
+
issueCounts: doc.issueCounts || {},
|
|
63
|
+
metrics: doc.metrics || {},
|
|
64
|
+
}));
|
|
65
|
+
return NextResponse.json({ points });
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error('SEO trend error:', error);
|
|
69
|
+
return NextResponse.json({ error: error instanceof Error ? error.message : 'Failed to load trend data.' }, { status: 500 });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeoAuthoritySnapshots.d.ts","sourceRoot":"","sources":["../../src/collections/SeoAuthoritySnapshots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAG/C,eAAO,MAAM,qBAAqB,EAAE,gBA8EnC,CAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SeoAuthoritySnapshots = void 0;
|
|
4
|
+
const access_1 = require("../utilities/access");
|
|
5
|
+
exports.SeoAuthoritySnapshots = {
|
|
6
|
+
slug: 'seo-authority-snapshots',
|
|
7
|
+
admin: {
|
|
8
|
+
useAsTitle: 'label',
|
|
9
|
+
defaultColumns: ['label', 'capturedAt', 'referringDomains', 'totalBacklinks'],
|
|
10
|
+
group: 'SEO',
|
|
11
|
+
},
|
|
12
|
+
access: {
|
|
13
|
+
read: access_1.seoAdminAccess,
|
|
14
|
+
create: access_1.seoAdminAccess,
|
|
15
|
+
update: access_1.seoAdminAccess,
|
|
16
|
+
delete: access_1.seoAdminAccess,
|
|
17
|
+
},
|
|
18
|
+
fields: [
|
|
19
|
+
{
|
|
20
|
+
name: 'label',
|
|
21
|
+
type: 'text',
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'capturedAt',
|
|
26
|
+
type: 'date',
|
|
27
|
+
required: true,
|
|
28
|
+
admin: {
|
|
29
|
+
date: { pickerAppearance: 'dayAndTime' },
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'source',
|
|
34
|
+
type: 'select',
|
|
35
|
+
required: true,
|
|
36
|
+
options: [
|
|
37
|
+
{ label: 'Manual CSV', value: 'manual-csv' },
|
|
38
|
+
{ label: 'Google Search Console', value: 'gsc' },
|
|
39
|
+
{ label: 'Provider API', value: 'provider' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'totalBacklinks',
|
|
44
|
+
type: 'number',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'referringDomains',
|
|
48
|
+
type: 'number',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'domainAuthorityProxy',
|
|
52
|
+
type: 'number',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'backlinks',
|
|
56
|
+
type: 'array',
|
|
57
|
+
fields: [
|
|
58
|
+
{ name: 'sourceURL', type: 'text' },
|
|
59
|
+
{ name: 'targetURL', type: 'text' },
|
|
60
|
+
{ name: 'anchorText', type: 'text' },
|
|
61
|
+
{ name: 'firstSeen', type: 'date' },
|
|
62
|
+
{ name: 'lastSeen', type: 'date' },
|
|
63
|
+
{
|
|
64
|
+
name: 'linkType',
|
|
65
|
+
type: 'select',
|
|
66
|
+
options: [
|
|
67
|
+
{ label: 'Follow', value: 'follow' },
|
|
68
|
+
{ label: 'Nofollow', value: 'nofollow' },
|
|
69
|
+
{ label: 'Unknown', value: 'unknown' },
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'providerMetadata',
|
|
76
|
+
type: 'json',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'notes',
|
|
80
|
+
type: 'textarea',
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeoKeywordVisibility.d.ts","sourceRoot":"","sources":["../../src/collections/SeoKeywordVisibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAG/C,eAAO,MAAM,oBAAoB,EAAE,gBA4DlC,CAAA"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SeoKeywordVisibility = void 0;
|
|
4
|
+
const access_1 = require("../utilities/access");
|
|
5
|
+
exports.SeoKeywordVisibility = {
|
|
6
|
+
slug: 'seo-keyword-visibility',
|
|
7
|
+
admin: {
|
|
8
|
+
useAsTitle: 'query',
|
|
9
|
+
defaultColumns: ['query', 'page', 'impressions', 'clicks', 'ctr', 'position', 'capturedAt'],
|
|
10
|
+
group: 'SEO',
|
|
11
|
+
},
|
|
12
|
+
access: {
|
|
13
|
+
read: access_1.seoAdminAccess,
|
|
14
|
+
create: access_1.seoAdminAccess,
|
|
15
|
+
update: access_1.seoAdminAccess,
|
|
16
|
+
delete: access_1.seoAdminAccess,
|
|
17
|
+
},
|
|
18
|
+
fields: [
|
|
19
|
+
{
|
|
20
|
+
name: 'capturedAt',
|
|
21
|
+
type: 'date',
|
|
22
|
+
required: true,
|
|
23
|
+
index: true,
|
|
24
|
+
admin: {
|
|
25
|
+
date: { pickerAppearance: 'dayAndTime' },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'query',
|
|
30
|
+
type: 'text',
|
|
31
|
+
required: true,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'page',
|
|
35
|
+
type: 'text',
|
|
36
|
+
required: true,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'impressions',
|
|
40
|
+
type: 'number',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'clicks',
|
|
44
|
+
type: 'number',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'ctr',
|
|
48
|
+
type: 'number',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'position',
|
|
52
|
+
type: 'number',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'source',
|
|
56
|
+
type: 'select',
|
|
57
|
+
required: true,
|
|
58
|
+
defaultValue: 'gsc',
|
|
59
|
+
options: [
|
|
60
|
+
{ label: 'Google Search Console', value: 'gsc' },
|
|
61
|
+
{ label: 'Manual Import', value: 'manual' },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeoPageResults.d.ts","sourceRoot":"","sources":["../../src/collections/SeoPageResults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAG/C,eAAO,MAAM,cAAc,EAAE,gBAqK5B,CAAA"}
|