@prenta/core 7.7.0 → 7.7.1
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/CHANGELOG.md +6 -0
- package/dist/api/routes/seo/handlers/analysis.d.ts +4 -0
- package/dist/api/routes/seo/handlers/analysis.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/analysis.js +131 -0
- package/dist/api/routes/seo/handlers/analysis.js.map +1 -0
- package/dist/api/routes/seo/handlers/audits.d.ts +5 -0
- package/dist/api/routes/seo/handlers/audits.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/audits.js +121 -0
- package/dist/api/routes/seo/handlers/audits.js.map +1 -0
- package/dist/api/routes/seo/handlers/content.d.ts +4 -0
- package/dist/api/routes/seo/handlers/content.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/content.js +330 -0
- package/dist/api/routes/seo/handlers/content.js.map +1 -0
- package/dist/api/routes/seo/handlers/issue-helpers.d.ts +37 -0
- package/dist/api/routes/seo/handlers/issue-helpers.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/issue-helpers.js +72 -0
- package/dist/api/routes/seo/handlers/issue-helpers.js.map +1 -0
- package/dist/api/routes/seo/handlers/issues-briefs.d.ts +7 -0
- package/dist/api/routes/seo/handlers/issues-briefs.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/issues-briefs.js +341 -0
- package/dist/api/routes/seo/handlers/issues-briefs.js.map +1 -0
- package/dist/api/routes/seo/handlers/issues-fixes.d.ts +4 -0
- package/dist/api/routes/seo/handlers/issues-fixes.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/issues-fixes.js +233 -0
- package/dist/api/routes/seo/handlers/issues-fixes.js.map +1 -0
- package/dist/api/routes/seo/handlers/issues-list.d.ts +7 -0
- package/dist/api/routes/seo/handlers/issues-list.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/issues-list.js +191 -0
- package/dist/api/routes/seo/handlers/issues-list.js.map +1 -0
- package/dist/api/routes/seo/handlers/links.d.ts +6 -0
- package/dist/api/routes/seo/handlers/links.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/links.js +383 -0
- package/dist/api/routes/seo/handlers/links.js.map +1 -0
- package/dist/api/routes/seo/handlers/overview.d.ts +4 -0
- package/dist/api/routes/seo/handlers/overview.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/overview.js +348 -0
- package/dist/api/routes/seo/handlers/overview.js.map +1 -0
- package/dist/api/routes/seo/handlers/pages.d.ts +2 -0
- package/dist/api/routes/seo/handlers/pages.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/pages.js +38 -0
- package/dist/api/routes/seo/handlers/pages.js.map +1 -0
- package/dist/api/routes/seo/handlers/proposals.d.ts +4 -0
- package/dist/api/routes/seo/handlers/proposals.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/proposals.js +93 -0
- package/dist/api/routes/seo/handlers/proposals.js.map +1 -0
- package/dist/api/routes/seo/handlers/public-files.d.ts +6 -0
- package/dist/api/routes/seo/handlers/public-files.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/public-files.js +328 -0
- package/dist/api/routes/seo/handlers/public-files.js.map +1 -0
- package/dist/api/routes/seo/handlers/shared.d.ts +24 -0
- package/dist/api/routes/seo/handlers/shared.d.ts.map +1 -0
- package/dist/api/routes/seo/handlers/shared.js +67 -0
- package/dist/api/routes/seo/handlers/shared.js.map +1 -0
- package/dist/api/routes/seo.d.ts +5 -5
- package/dist/api/routes/seo.d.ts.map +1 -1
- package/dist/api/routes/seo.js +56 -2610
- package/dist/api/routes/seo.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { getPrentaConfig } from '../../../../config/runtime.js';
|
|
2
|
+
import { json, errorResponse, internalError, hasModel, formatCompactNumber, requireAuth, } from '../../../route-helpers.js';
|
|
3
|
+
import { db, sortIssuesBySeverity } from './shared.js';
|
|
4
|
+
import { seoIssueToApi } from './issue-helpers.js';
|
|
5
|
+
/** Synced GSC data (trailing 28 days). Returns null when there is none yet. */
|
|
6
|
+
async function loadRealSearchPerformance(limit) {
|
|
7
|
+
if (!hasModel(db(), 'searchPageInsight'))
|
|
8
|
+
return null;
|
|
9
|
+
try {
|
|
10
|
+
const rows = await db().searchPageInsight.findMany({
|
|
11
|
+
where: { impressions28d: { gt: 0 } },
|
|
12
|
+
orderBy: { impressions28d: 'desc' },
|
|
13
|
+
take: limit,
|
|
14
|
+
});
|
|
15
|
+
if (rows.length === 0)
|
|
16
|
+
return null;
|
|
17
|
+
const ids = rows.map((r) => r.entityId).filter(Boolean);
|
|
18
|
+
const titles = new Map();
|
|
19
|
+
if (ids.length > 0) {
|
|
20
|
+
const docs = await db().document.findMany({
|
|
21
|
+
where: { id: { in: ids } },
|
|
22
|
+
select: { id: true, title: true },
|
|
23
|
+
});
|
|
24
|
+
for (const d of docs) {
|
|
25
|
+
if (d.title)
|
|
26
|
+
titles.set(d.id, d.title);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return rows.map((r) => ({
|
|
30
|
+
url: r.path,
|
|
31
|
+
title: (r.entityId && titles.get(r.entityId)) || r.path,
|
|
32
|
+
impressions: r.impressions28d,
|
|
33
|
+
clicks: r.clicks28d,
|
|
34
|
+
ctr: r.impressions28d > 0 ? r.clicks28d / r.impressions28d : 0,
|
|
35
|
+
averagePosition: r.avgPosition28d ?? 0,
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Synced GSC rows when Search Console is connected; otherwise (or before the
|
|
44
|
+
* first sync) an empty list. The admin renders its own "not connected" empty
|
|
45
|
+
* state, and MCP / REST consumers must never see fabricated rows.
|
|
46
|
+
*/
|
|
47
|
+
async function loadSearchPerformance(limit = 10, connected = false) {
|
|
48
|
+
if (!connected)
|
|
49
|
+
return [];
|
|
50
|
+
return (await loadRealSearchPerformance(limit)) ?? [];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Site-level 28d totals + prior-window deltas from the insight table for the
|
|
54
|
+
* overview metric cards. Position is impressions-weighted. Null when no
|
|
55
|
+
* synced data exists (metrics then fall back to the perf-row estimate,
|
|
56
|
+
* which is empty until Search Console is connected).
|
|
57
|
+
*/
|
|
58
|
+
async function loadSearchInsightStats() {
|
|
59
|
+
if (!hasModel(db(), 'searchPageInsight'))
|
|
60
|
+
return null;
|
|
61
|
+
try {
|
|
62
|
+
const rows = (await db().searchPageInsight.findMany({
|
|
63
|
+
where: { OR: [{ impressions28d: { gt: 0 } }, { impressionsPrev28d: { gt: 0 } }] },
|
|
64
|
+
select: {
|
|
65
|
+
impressions28d: true,
|
|
66
|
+
impressionsPrev28d: true,
|
|
67
|
+
avgPosition28d: true,
|
|
68
|
+
avgPositionPrev28d: true,
|
|
69
|
+
},
|
|
70
|
+
take: 2000,
|
|
71
|
+
}));
|
|
72
|
+
if (rows.length === 0)
|
|
73
|
+
return null;
|
|
74
|
+
let impressions28d = 0;
|
|
75
|
+
let impressionsPrev28d = 0;
|
|
76
|
+
let posWeight = 0;
|
|
77
|
+
let posWeightBase = 0;
|
|
78
|
+
let prevPosWeight = 0;
|
|
79
|
+
let prevPosWeightBase = 0;
|
|
80
|
+
for (const r of rows) {
|
|
81
|
+
impressions28d += r.impressions28d;
|
|
82
|
+
impressionsPrev28d += r.impressionsPrev28d;
|
|
83
|
+
if (r.avgPosition28d !== null && r.impressions28d > 0) {
|
|
84
|
+
posWeight += r.avgPosition28d * r.impressions28d;
|
|
85
|
+
posWeightBase += r.impressions28d;
|
|
86
|
+
}
|
|
87
|
+
if (r.avgPositionPrev28d !== null && r.impressionsPrev28d > 0) {
|
|
88
|
+
prevPosWeight += r.avgPositionPrev28d * r.impressionsPrev28d;
|
|
89
|
+
prevPosWeightBase += r.impressionsPrev28d;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
impressions28d,
|
|
94
|
+
impressionsPrev28d,
|
|
95
|
+
avgPosition: posWeightBase > 0 ? posWeight / posWeightBase : null,
|
|
96
|
+
avgPositionPrev: prevPosWeightBase > 0 ? prevPosWeight / prevPosWeightBase : null,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export async function getSeoOverview(request) {
|
|
104
|
+
try {
|
|
105
|
+
const auth = await requireAuth(request);
|
|
106
|
+
if (auth.error)
|
|
107
|
+
return auth.error;
|
|
108
|
+
const { resolveSeoModuleSettings, getSeoOverrides } = await import('../../../../seo/config-store.js');
|
|
109
|
+
const { buildQuickWins } = await import('../../../../seo/audit-engine.js');
|
|
110
|
+
const { gradeForSeoScore } = await import('../../../../seo/score.js');
|
|
111
|
+
const overrides = await getSeoOverrides(db()).catch(() => null);
|
|
112
|
+
const moduleSettings = resolveSeoModuleSettings(overrides);
|
|
113
|
+
let lastRun = null;
|
|
114
|
+
let openIssues = [];
|
|
115
|
+
if (hasModel(db(), 'seoAuditRun')) {
|
|
116
|
+
lastRun = await db().seoAuditRun.findFirst({
|
|
117
|
+
where: { status: 'COMPLETED' },
|
|
118
|
+
orderBy: { startedAt: 'desc' },
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (hasModel(db(), 'seoIssue')) {
|
|
122
|
+
const rawIssues = await db().seoIssue.findMany({
|
|
123
|
+
where: { status: { in: ['open', 'recurring'] } },
|
|
124
|
+
orderBy: { lastDetectedAt: 'desc' },
|
|
125
|
+
take: 200,
|
|
126
|
+
});
|
|
127
|
+
openIssues = sortIssuesBySeverity(rawIssues);
|
|
128
|
+
}
|
|
129
|
+
const { frontEndContentCollectionTypes, countAuditEntities } = await import('../../../../seo/audit-runner.js');
|
|
130
|
+
const collectionTypes = frontEndContentCollectionTypes(getPrentaConfig());
|
|
131
|
+
const total = await countAuditEntities(db(), { collectionTypes }).catch(() => 0);
|
|
132
|
+
const meta = (lastRun?.metadata ?? {});
|
|
133
|
+
const indexable = typeof meta.indexableCount === 'number' && Number.isFinite(meta.indexableCount)
|
|
134
|
+
? meta.indexableCount
|
|
135
|
+
: total;
|
|
136
|
+
const auditTruncated = meta.truncated === true;
|
|
137
|
+
const perf = await loadSearchPerformance(10, moduleSettings.searchConsoleConnected);
|
|
138
|
+
const searchStats = moduleSettings.searchConsoleConnected
|
|
139
|
+
? await loadSearchInsightStats()
|
|
140
|
+
: null;
|
|
141
|
+
const summary = {
|
|
142
|
+
total: openIssues.length,
|
|
143
|
+
critical: openIssues.filter((i) => i.severity === 'critical').length,
|
|
144
|
+
warning: openIssues.filter((i) => i.severity === 'warning').length,
|
|
145
|
+
info: openIssues.filter((i) => i.severity === 'info').length,
|
|
146
|
+
};
|
|
147
|
+
const { countPendingProposals } = await import('../../../../seo/proposals.js');
|
|
148
|
+
const pendingProposals = await countPendingProposals(db(), openIssues).catch(() => ({
|
|
149
|
+
issueFixes: 0,
|
|
150
|
+
redirects: 0,
|
|
151
|
+
}));
|
|
152
|
+
const scoreAfter = lastRun?.siteScoreAfter ?? null;
|
|
153
|
+
const scoreBefore = lastRun?.siteScoreBefore ?? null;
|
|
154
|
+
const breakdown = lastRun?.metadata?.breakdown ?? [];
|
|
155
|
+
// Real site-level stats (weighted by impressions, with prior-window
|
|
156
|
+
// trends) when synced data exists; the perf-row estimate otherwise.
|
|
157
|
+
const avgPosition = searchStats?.avgPosition ??
|
|
158
|
+
(perf.length > 0
|
|
159
|
+
? perf.reduce((s, r) => s + r.averagePosition, 0) / perf.length
|
|
160
|
+
: null);
|
|
161
|
+
const impressions28d = searchStats?.impressions28d ?? perf.reduce((s, r) => s + r.impressions, 0);
|
|
162
|
+
// Position: lower is better, so an "up" trend means the number dropped.
|
|
163
|
+
let positionTrend = 'flat';
|
|
164
|
+
if (searchStats?.avgPosition != null && searchStats.avgPositionPrev != null) {
|
|
165
|
+
const delta = searchStats.avgPosition - searchStats.avgPositionPrev;
|
|
166
|
+
if (delta <= -0.5)
|
|
167
|
+
positionTrend = 'up';
|
|
168
|
+
else if (delta >= 0.5)
|
|
169
|
+
positionTrend = 'down';
|
|
170
|
+
}
|
|
171
|
+
let impressionsTrend = 'flat';
|
|
172
|
+
if (searchStats && searchStats.impressionsPrev28d > 0) {
|
|
173
|
+
const ratio = searchStats.impressions28d / searchStats.impressionsPrev28d;
|
|
174
|
+
if (ratio >= 1.05)
|
|
175
|
+
impressionsTrend = 'up';
|
|
176
|
+
else if (ratio <= 0.95)
|
|
177
|
+
impressionsTrend = 'down';
|
|
178
|
+
}
|
|
179
|
+
const metrics = [
|
|
180
|
+
{
|
|
181
|
+
label: 'Pages Indexed',
|
|
182
|
+
value: String(indexable),
|
|
183
|
+
helper: auditTruncated ? `${total} published (audit capped)` : `${total} published pages`,
|
|
184
|
+
trend: 'flat',
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
label: 'Open Issues',
|
|
188
|
+
value: String(summary.total),
|
|
189
|
+
helper: `${summary.critical} critical`,
|
|
190
|
+
trend: summary.critical > 0 ? 'down' : 'flat',
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
label: 'Avg. Position',
|
|
194
|
+
value: avgPosition !== null ? avgPosition.toFixed(1) : '—',
|
|
195
|
+
helper: moduleSettings.searchConsoleConnected
|
|
196
|
+
? searchStats?.avgPositionPrev != null
|
|
197
|
+
? `was ${searchStats.avgPositionPrev.toFixed(1)} the prior 28 days`
|
|
198
|
+
: 'last 28 days'
|
|
199
|
+
: 'Connect Search Console',
|
|
200
|
+
trend: positionTrend,
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
label: 'Impressions',
|
|
204
|
+
value: impressions28d > 0 ? formatCompactNumber(impressions28d) : '—',
|
|
205
|
+
helper: moduleSettings.searchConsoleConnected
|
|
206
|
+
? searchStats && searchStats.impressionsPrev28d > 0
|
|
207
|
+
? `was ${formatCompactNumber(searchStats.impressionsPrev28d)} the prior 28 days`
|
|
208
|
+
: 'last 28 days'
|
|
209
|
+
: 'Connect Search Console',
|
|
210
|
+
trend: impressionsTrend,
|
|
211
|
+
},
|
|
212
|
+
];
|
|
213
|
+
// Weight quick wins by real traffic when synced search data exists.
|
|
214
|
+
const impressionsByEntityId = {};
|
|
215
|
+
if (moduleSettings.searchConsoleConnected && hasModel(db(), 'searchPageInsight')) {
|
|
216
|
+
try {
|
|
217
|
+
const impressionRows = (await db().searchPageInsight.findMany({
|
|
218
|
+
where: { entityId: { not: null }, impressions28d: { gt: 0 } },
|
|
219
|
+
select: { entityId: true, impressions28d: true },
|
|
220
|
+
take: 2000,
|
|
221
|
+
}));
|
|
222
|
+
for (const r of impressionRows) {
|
|
223
|
+
if (r.entityId)
|
|
224
|
+
impressionsByEntityId[r.entityId] = r.impressions28d;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
/* weighting is optional */
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const quickWins = buildQuickWins(openIssues.map((i) => ({
|
|
232
|
+
issueKey: i.issueKey,
|
|
233
|
+
entityType: i.entityType,
|
|
234
|
+
entityId: i.entityId,
|
|
235
|
+
entityTitle: i.entityTitle,
|
|
236
|
+
url: i.url,
|
|
237
|
+
severity: i.severity,
|
|
238
|
+
category: i.category,
|
|
239
|
+
type: i.type,
|
|
240
|
+
title: i.title,
|
|
241
|
+
description: i.description ?? '',
|
|
242
|
+
impact: i.impact ?? 'Low',
|
|
243
|
+
recommendation: i.recommendation ?? '',
|
|
244
|
+
fixable: i.fixable ?? false,
|
|
245
|
+
fixActionType: i.fixActionType ?? null,
|
|
246
|
+
relatedEntityIds: Array.isArray(i.relatedEntityIds) ? i.relatedEntityIds : [],
|
|
247
|
+
})), { impressionsByEntityId }).map((w) => ({
|
|
248
|
+
id: w.id,
|
|
249
|
+
title: w.title,
|
|
250
|
+
explanation: w.explanation,
|
|
251
|
+
impact: w.impact,
|
|
252
|
+
issueId: openIssues.find((i) => i.type === w.issueType)?.id ?? null,
|
|
253
|
+
fixActionType: w.fixActionType,
|
|
254
|
+
}));
|
|
255
|
+
return json({
|
|
256
|
+
data: {
|
|
257
|
+
siteScore: {
|
|
258
|
+
score: scoreAfter ?? 0,
|
|
259
|
+
grade: gradeForSeoScore(scoreAfter ?? 0),
|
|
260
|
+
delta: scoreAfter !== null && scoreBefore !== null ? scoreAfter - scoreBefore : null,
|
|
261
|
+
breakdown,
|
|
262
|
+
},
|
|
263
|
+
metrics,
|
|
264
|
+
issues: openIssues.slice(0, 7).map(seoIssueToApi),
|
|
265
|
+
issuesSummary: summary,
|
|
266
|
+
quickWins,
|
|
267
|
+
searchPerformance: perf,
|
|
268
|
+
searchConsoleConnected: moduleSettings.searchConsoleConnected,
|
|
269
|
+
lastAuditRunId: lastRun?.id ?? null,
|
|
270
|
+
auditTruncated,
|
|
271
|
+
pendingProposals,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
catch (err) {
|
|
276
|
+
return internalError(err, 'seo/overview');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
export async function getSeoSearchPerformance(request) {
|
|
280
|
+
try {
|
|
281
|
+
const auth = await requireAuth(request);
|
|
282
|
+
if (auth.error)
|
|
283
|
+
return auth.error;
|
|
284
|
+
const url = new URL(request.url);
|
|
285
|
+
const limit = Math.min(50, Math.max(1, Number(url.searchParams.get('limit') ?? 10)));
|
|
286
|
+
const { getSeoOverrides, resolveSeoModuleSettings } = await import('../../../../seo/config-store.js');
|
|
287
|
+
const settings = resolveSeoModuleSettings(await getSeoOverrides(db()));
|
|
288
|
+
const rows = await loadSearchPerformance(limit, settings.searchConsoleConnected);
|
|
289
|
+
return json({ data: { rows } });
|
|
290
|
+
}
|
|
291
|
+
catch (err) {
|
|
292
|
+
return internalError(err, 'seo/search-performance');
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
// Per-document search insight (synced GSC + CrUX) for the editor pane's
|
|
296
|
+
// read-only stats block. `insight: null` when not synced or no data.
|
|
297
|
+
export async function getSeoSearchInsights(request, params) {
|
|
298
|
+
try {
|
|
299
|
+
const auth = await requireAuth(request);
|
|
300
|
+
if (auth.error)
|
|
301
|
+
return auth.error;
|
|
302
|
+
const entityId = params.entityId;
|
|
303
|
+
if (!entityId)
|
|
304
|
+
return errorResponse('entityId is required', 400);
|
|
305
|
+
const { getSeoOverrides, resolveSeoModuleSettings } = await import('../../../../seo/config-store.js');
|
|
306
|
+
const settings = resolveSeoModuleSettings(await getSeoOverrides(db()));
|
|
307
|
+
const connected = settings.searchConsoleConnected;
|
|
308
|
+
if (!connected || !hasModel(db(), 'searchPageInsight')) {
|
|
309
|
+
return json({ data: { connected, insight: null } });
|
|
310
|
+
}
|
|
311
|
+
const row = await db().searchPageInsight.findFirst({
|
|
312
|
+
where: { entityId },
|
|
313
|
+
select: {
|
|
314
|
+
path: true,
|
|
315
|
+
clicks28d: true,
|
|
316
|
+
impressions28d: true,
|
|
317
|
+
avgPosition28d: true,
|
|
318
|
+
clicksPrev28d: true,
|
|
319
|
+
impressionsPrev28d: true,
|
|
320
|
+
avgPositionPrev28d: true,
|
|
321
|
+
topQueries: true,
|
|
322
|
+
lcpMs: true,
|
|
323
|
+
inpMs: true,
|
|
324
|
+
cls: true,
|
|
325
|
+
cwvStatus: true,
|
|
326
|
+
lastSyncedAt: true,
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
return json({
|
|
330
|
+
data: {
|
|
331
|
+
connected,
|
|
332
|
+
insight: row
|
|
333
|
+
? {
|
|
334
|
+
...row,
|
|
335
|
+
topQueries: Array.isArray(row.topQueries) ? row.topQueries : [],
|
|
336
|
+
lastSyncedAt: row.lastSyncedAt instanceof Date
|
|
337
|
+
? row.lastSyncedAt.toISOString()
|
|
338
|
+
: row.lastSyncedAt,
|
|
339
|
+
}
|
|
340
|
+
: null,
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
catch (err) {
|
|
345
|
+
return internalError(err, 'seo/search-insights');
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
//# sourceMappingURL=overview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overview.js","sourceRoot":"","sources":["../../../../../src/api/routes/seo/handlers/overview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EACL,IAAI,EACJ,aAAa,EACb,aAAa,EACb,QAAQ,EACR,mBAAmB,EACnB,WAAW,GACZ,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,EAAE,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAYlD,+EAA+E;AAC/E,KAAK,UAAU,yBAAyB,CAAC,KAAa;IACpD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,mBAAmB,CAAC;QAAE,OAAO,IAAI,CAAA;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC;YACjD,KAAK,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;YACpC,OAAO,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE;YACnC,IAAI,EAAE,KAAK;SACZ,CAAC,CAAA;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAa,CAAA;QACxE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;QACxC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACxC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;gBAC1B,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;aAClC,CAAC,CAAA;YACF,KAAK,MAAM,CAAC,IAAI,IAAmD,EAAE,CAAC;gBACpE,IAAI,CAAC,CAAC,KAAK;oBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;YACxC,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;YAC3B,GAAG,EAAE,CAAC,CAAC,IAAI;YACX,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI;YACvD,WAAW,EAAE,CAAC,CAAC,cAAc;YAC7B,MAAM,EAAE,CAAC,CAAC,SAAS;YACnB,GAAG,EAAE,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;YAC9D,eAAe,EAAE,CAAC,CAAC,cAAc,IAAI,CAAC;SACvC,CAAC,CAAC,CAAA;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,qBAAqB,CAAC,KAAK,GAAG,EAAE,EAAE,SAAS,GAAG,KAAK;IAChE,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAA;IACzB,OAAO,CAAC,MAAM,yBAAyB,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;AACvD,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,sBAAsB;IAMnC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,mBAAmB,CAAC;QAAE,OAAO,IAAI,CAAA;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC;YAClD,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE;YACjF,MAAM,EAAE;gBACN,cAAc,EAAE,IAAI;gBACpB,kBAAkB,EAAE,IAAI;gBACxB,cAAc,EAAE,IAAI;gBACpB,kBAAkB,EAAE,IAAI;aACzB;YACD,IAAI,EAAE,IAAI;SACX,CAAC,CAKA,CAAA;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QAClC,IAAI,cAAc,GAAG,CAAC,CAAA;QACtB,IAAI,kBAAkB,GAAG,CAAC,CAAA;QAC1B,IAAI,SAAS,GAAG,CAAC,CAAA;QACjB,IAAI,aAAa,GAAG,CAAC,CAAA;QACrB,IAAI,aAAa,GAAG,CAAC,CAAA;QACrB,IAAI,iBAAiB,GAAG,CAAC,CAAA;QACzB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,cAAc,IAAI,CAAC,CAAC,cAAc,CAAA;YAClC,kBAAkB,IAAI,CAAC,CAAC,kBAAkB,CAAA;YAC1C,IAAI,CAAC,CAAC,cAAc,KAAK,IAAI,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;gBACtD,SAAS,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAA;gBAChD,aAAa,IAAI,CAAC,CAAC,cAAc,CAAA;YACnC,CAAC;YACD,IAAI,CAAC,CAAC,kBAAkB,KAAK,IAAI,IAAI,CAAC,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC;gBAC9D,aAAa,IAAI,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,kBAAkB,CAAA;gBAC5D,iBAAiB,IAAI,CAAC,CAAC,kBAAkB,CAAA;YAC3C,CAAC;QACH,CAAC;QACD,OAAO;YACL,cAAc;YACd,kBAAkB;YAClB,WAAW,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI;YACjE,eAAe,EAAE,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI;SAClF,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAgB;IACnD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAA;QACvC,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAA;QAEjC,MAAM,EAAE,wBAAwB,EAAE,eAAe,EAAE,GACjD,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAA;QACjD,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAA;QAC1E,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAA;QACrE,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QAC/D,MAAM,cAAc,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAA;QAE1D,IAAI,OAAO,GAAQ,IAAI,CAAA;QACvB,IAAI,UAAU,GAAU,EAAE,CAAA;QAC1B,IAAI,QAAQ,CAAC,EAAE,EAAE,EAAE,aAAa,CAAC,EAAE,CAAC;YAClC,OAAO,GAAG,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC;gBACzC,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE;gBAC9B,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;aAC/B,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,QAAQ,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAC7C,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,EAAE;gBAChD,OAAO,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE;gBACnC,IAAI,EAAE,GAAG;aACV,CAAC,CAAA;YACF,UAAU,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAA;QAC9C,CAAC;QAED,MAAM,EAAE,8BAA8B,EAAE,kBAAkB,EAAE,GAC1D,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAA;QACjD,MAAM,eAAe,GAAG,8BAA8B,CAAC,eAAe,EAAE,CAAC,CAAA;QACzE,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;QAChF,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,IAAI,EAAE,CAGpC,CAAA;QACD,MAAM,SAAS,GACb,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC;YAC7E,CAAC,CAAC,IAAI,CAAC,cAAc;YACrB,CAAC,CAAC,KAAK,CAAA;QACX,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,CAAA;QAC9C,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,EAAE,EAAE,cAAc,CAAC,sBAAsB,CAAC,CAAA;QACnF,MAAM,WAAW,GAAG,cAAc,CAAC,sBAAsB;YACvD,CAAC,CAAC,MAAM,sBAAsB,EAAE;YAChC,CAAC,CAAC,IAAI,CAAA;QAER,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,UAAU,CAAC,MAAM;YACxB,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,MAAM;YACzE,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM;YACvE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM;SAClE,CAAA;QAED,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAA;QAC9E,MAAM,gBAAgB,GAAG,MAAM,qBAAqB,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;YAClF,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,CAAC;SACb,CAAC,CAAC,CAAA;QAEH,MAAM,UAAU,GAAG,OAAO,EAAE,cAAc,IAAI,IAAI,CAAA;QAClD,MAAM,WAAW,GAAG,OAAO,EAAE,eAAe,IAAI,IAAI,CAAA;QACpD,MAAM,SAAS,GAAI,OAAO,EAAE,QAAgB,EAAE,SAAS,IAAI,EAAE,CAAA;QAE7D,oEAAoE;QACpE,oEAAoE;QACpE,MAAM,WAAW,GACf,WAAW,EAAE,WAAW;YACxB,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;gBACd,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,CAAM,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM;gBAC5E,CAAC,CAAC,IAAI,CAAC,CAAA;QACX,MAAM,cAAc,GAClB,WAAW,EAAE,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,CAAM,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;QAEzF,wEAAwE;QACxE,IAAI,aAAa,GAAG,MAAM,CAAA;QAC1B,IAAI,WAAW,EAAE,WAAW,IAAI,IAAI,IAAI,WAAW,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC;YAC5E,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,GAAG,WAAW,CAAC,eAAe,CAAA;YACnE,IAAI,KAAK,IAAI,CAAC,GAAG;gBAAE,aAAa,GAAG,IAAI,CAAA;iBAClC,IAAI,KAAK,IAAI,GAAG;gBAAE,aAAa,GAAG,MAAM,CAAA;QAC/C,CAAC;QACD,IAAI,gBAAgB,GAAG,MAAM,CAAA;QAC7B,IAAI,WAAW,IAAI,WAAW,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC;YACtD,MAAM,KAAK,GAAG,WAAW,CAAC,cAAc,GAAG,WAAW,CAAC,kBAAkB,CAAA;YACzE,IAAI,KAAK,IAAI,IAAI;gBAAE,gBAAgB,GAAG,IAAI,CAAA;iBACrC,IAAI,KAAK,IAAI,IAAI;gBAAE,gBAAgB,GAAG,MAAM,CAAA;QACnD,CAAC;QAED,MAAM,OAAO,GAAG;YACd;gBACE,KAAK,EAAE,eAAe;gBACtB,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC;gBACxB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,KAAK,2BAA2B,CAAC,CAAC,CAAC,GAAG,KAAK,kBAAkB;gBACzF,KAAK,EAAE,MAAM;aACd;YACD;gBACE,KAAK,EAAE,aAAa;gBACpB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;gBAC5B,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,WAAW;gBACtC,KAAK,EAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;aAC9C;YACD;gBACE,KAAK,EAAE,eAAe;gBACtB,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;gBAC1D,MAAM,EAAE,cAAc,CAAC,sBAAsB;oBAC3C,CAAC,CAAC,WAAW,EAAE,eAAe,IAAI,IAAI;wBACpC,CAAC,CAAC,OAAO,WAAW,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB;wBACnE,CAAC,CAAC,cAAc;oBAClB,CAAC,CAAC,wBAAwB;gBAC5B,KAAK,EAAE,aAAa;aACrB;YACD;gBACE,KAAK,EAAE,aAAa;gBACpB,KAAK,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG;gBACrE,MAAM,EAAE,cAAc,CAAC,sBAAsB;oBAC3C,CAAC,CAAC,WAAW,IAAI,WAAW,CAAC,kBAAkB,GAAG,CAAC;wBACjD,CAAC,CAAC,OAAO,mBAAmB,CAAC,WAAW,CAAC,kBAAkB,CAAC,oBAAoB;wBAChF,CAAC,CAAC,cAAc;oBAClB,CAAC,CAAC,wBAAwB;gBAC5B,KAAK,EAAE,gBAAgB;aACxB;SACF,CAAA;QAED,oEAAoE;QACpE,MAAM,qBAAqB,GAA2B,EAAE,CAAA;QACxD,IAAI,cAAc,CAAC,sBAAsB,IAAI,QAAQ,CAAC,EAAE,EAAE,EAAE,mBAAmB,CAAC,EAAE,CAAC;YACjF,IAAI,CAAC;gBACH,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC;oBAC5D,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;oBAC7D,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE;oBAChD,IAAI,EAAE,IAAI;iBACX,CAAC,CAA+D,CAAA;gBACjE,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;oBAC/B,IAAI,CAAC,CAAC,QAAQ;wBAAE,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,cAAc,CAAA;gBACtE,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,2BAA2B;YAC7B,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,cAAc,CAC9B,UAAU,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;YAC1B,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;YAChC,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,KAAK;YACzB,cAAc,EAAE,CAAC,CAAC,cAAc,IAAI,EAAE;YACtC,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK;YAC3B,aAAa,EAAE,CAAC,CAAC,aAAa,IAAI,IAAI;YACtC,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE;SAC9E,CAAC,CAAC,EACH,EAAE,qBAAqB,EAAE,CAC1B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACZ,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,IAAI;YACxE,aAAa,EAAE,CAAC,CAAC,aAAa;SAC/B,CAAC,CAAC,CAAA;QAEH,OAAO,IAAI,CAAC;YACV,IAAI,EAAE;gBACJ,SAAS,EAAE;oBACT,KAAK,EAAE,UAAU,IAAI,CAAC;oBACtB,KAAK,EAAE,gBAAgB,CAAC,UAAU,IAAI,CAAC,CAAC;oBACxC,KAAK,EAAE,UAAU,KAAK,IAAI,IAAI,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI;oBACpF,SAAS;iBACV;gBACD,OAAO;gBACP,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC;gBACjD,aAAa,EAAE,OAAO;gBACtB,SAAS;gBACT,iBAAiB,EAAE,IAAI;gBACvB,sBAAsB,EAAE,cAAc,CAAC,sBAAsB;gBAC7D,cAAc,EAAE,OAAO,EAAE,EAAE,IAAI,IAAI;gBACnC,cAAc;gBACd,gBAAgB;aACjB;SACF,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,aAAa,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAAgB;IAC5D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAA;QACvC,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAA;QACjC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QACpF,MAAM,EAAE,eAAe,EAAE,wBAAwB,EAAE,GACjD,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAA;QACjD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,MAAM,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;QACtE,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAA;QAChF,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,aAAa,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAA;IACrD,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB,EAChB,MAA8B;IAE9B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAA;QACvC,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAA;QACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;QAChC,IAAI,CAAC,QAAQ;YAAE,OAAO,aAAa,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAA;QAEhE,MAAM,EAAE,eAAe,EAAE,wBAAwB,EAAE,GACjD,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAA;QACjD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,MAAM,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;QACtE,MAAM,SAAS,GAAG,QAAQ,CAAC,sBAAsB,CAAA;QAEjD,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,mBAAmB,CAAC,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;QACrD,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;YACjD,KAAK,EAAE,EAAE,QAAQ,EAAE;YACnB,MAAM,EAAE;gBACN,IAAI,EAAE,IAAI;gBACV,SAAS,EAAE,IAAI;gBACf,cAAc,EAAE,IAAI;gBACpB,cAAc,EAAE,IAAI;gBACpB,aAAa,EAAE,IAAI;gBACnB,kBAAkB,EAAE,IAAI;gBACxB,kBAAkB,EAAE,IAAI;gBACxB,UAAU,EAAE,IAAI;gBAChB,KAAK,EAAE,IAAI;gBACX,KAAK,EAAE,IAAI;gBACX,GAAG,EAAE,IAAI;gBACT,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,IAAI;aACnB;SACF,CAAC,CAAA;QACF,OAAO,IAAI,CAAC;YACV,IAAI,EAAE;gBACJ,SAAS;gBACT,OAAO,EAAE,GAAG;oBACV,CAAC,CAAC;wBACE,GAAG,GAAG;wBACN,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;wBAC/D,YAAY,EACV,GAAG,CAAC,YAAY,YAAY,IAAI;4BAC9B,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,WAAW,EAAE;4BAChC,CAAC,CAAC,GAAG,CAAC,YAAY;qBACvB;oBACH,CAAC,CAAC,IAAI;aACT;SACF,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,aAAa,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAA;IAClD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../../../../src/api/routes/seo/handlers/pages.ts"],"names":[],"mappings":"AAMA,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgCrE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { json, internalError, normalizeSeoPage, requireAuth } from '../../../route-helpers.js';
|
|
2
|
+
import { db } from './shared.js';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// SEO routes
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
export async function getSeoPages(request) {
|
|
7
|
+
try {
|
|
8
|
+
const auth = await requireAuth(request);
|
|
9
|
+
if (auth.error)
|
|
10
|
+
return auth.error;
|
|
11
|
+
// Bound the scan: a large site can have tens of thousands of published
|
|
12
|
+
// docs, and each carries a full `data` JSONB. Default to a high cap so
|
|
13
|
+
// typical sites are unaffected; expose `?limit`/`?offset` so clients can
|
|
14
|
+
// page rather than pull everything into memory at once. A full page
|
|
15
|
+
// (data.length === limit) signals there may be more.
|
|
16
|
+
const params = new URL(request.url).searchParams;
|
|
17
|
+
const limit = Math.min(Math.max(Number(params.get('limit')) || 1000, 1), 5000);
|
|
18
|
+
const offset = Math.max(Number(params.get('offset')) || 0, 0);
|
|
19
|
+
const pages = await db().document.findMany({
|
|
20
|
+
where: { deletedAt: null, status: 'PUBLISHED' },
|
|
21
|
+
select: {
|
|
22
|
+
id: true,
|
|
23
|
+
collection: true,
|
|
24
|
+
data: true,
|
|
25
|
+
updatedAt: true,
|
|
26
|
+
structuredData: true,
|
|
27
|
+
},
|
|
28
|
+
orderBy: { updatedAt: 'desc' },
|
|
29
|
+
take: limit,
|
|
30
|
+
skip: offset,
|
|
31
|
+
});
|
|
32
|
+
return json({ data: pages.map(normalizeSeoPage), limit, offset });
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
return internalError(err);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=pages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages.js","sourceRoot":"","sources":["../../../../../src/api/routes/seo/handlers/pages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAC9F,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAEhC,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAgB;IAChD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAA;QACvC,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAA;QAEjC,uEAAuE;QACvE,uEAAuE;QACvE,yEAAyE;QACzE,oEAAoE;QACpE,qDAAqD;QACrD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,CAAA;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;QAE7D,MAAM,KAAK,GAAG,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACzC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE;YAC/C,MAAM,EAAE;gBACN,EAAE,EAAE,IAAI;gBACR,UAAU,EAAE,IAAI;gBAChB,IAAI,EAAE,IAAI;gBACV,SAAS,EAAE,IAAI;gBACf,cAAc,EAAE,IAAI;aACrB;YACD,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;YAC9B,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,MAAM;SACb,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACnE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,aAAa,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function getSeoProposals(request: Request): Promise<Response>;
|
|
2
|
+
export declare function postSeoProposalsGenerate(request: Request): Promise<Response>;
|
|
3
|
+
export declare function postSeoProposalsBulkApply(request: Request): Promise<Response>;
|
|
4
|
+
//# sourceMappingURL=proposals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposals.d.ts","sourceRoot":"","sources":["../../../../../src/api/routes/seo/handlers/proposals.ts"],"names":[],"mappings":"AAoBA,wBAAsB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAUzE;AAED,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6BlF;AAID,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyCnF"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { assertPlanFeature } from '../../../../plan/features.js';
|
|
2
|
+
import { json, errorResponse, internalError, hasModel, modelNotAvailable, requireAuth, WRITE_ROLES, ADMIN_ROLES, requireRole, aiGenerateLimiter, checkRateLimitAsync, } from '../../../route-helpers.js';
|
|
3
|
+
import { seoBulkApplyBodySchema, validateBody } from '../../../validate-body.js';
|
|
4
|
+
import { db, planRequiredResponse, contentWriteGate } from './shared.js';
|
|
5
|
+
// Any authenticated user, like GET /seo/issues and GET /seo/overview: editors
|
|
6
|
+
// read the inbox and act through the WRITE_ROLES mutation routes.
|
|
7
|
+
export async function getSeoProposals(request) {
|
|
8
|
+
try {
|
|
9
|
+
const auth = await requireAuth(request);
|
|
10
|
+
if (auth.error)
|
|
11
|
+
return auth.error;
|
|
12
|
+
const { listSeoProposals } = await import('../../../../seo/proposals.js');
|
|
13
|
+
return json({ data: await listSeoProposals(db()) });
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
return internalError(err, 'seo/proposals');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export async function postSeoProposalsGenerate(request) {
|
|
20
|
+
try {
|
|
21
|
+
const auth = await requireAuth(request);
|
|
22
|
+
if (auth.error)
|
|
23
|
+
return auth.error;
|
|
24
|
+
const roleErr = requireRole(auth.session.role, ADMIN_ROLES);
|
|
25
|
+
if (roleErr)
|
|
26
|
+
return roleErr;
|
|
27
|
+
const planErr = assertPlanFeature('seo.inlineApply');
|
|
28
|
+
if (planErr)
|
|
29
|
+
return planRequiredResponse(planErr);
|
|
30
|
+
if (!hasModel(db(), 'seoIssue'))
|
|
31
|
+
return modelNotAvailable('SeoIssue');
|
|
32
|
+
const body = (await request.json().catch(() => ({})));
|
|
33
|
+
if (body?.confirm !== true) {
|
|
34
|
+
return errorResponse('Pass { "confirm": true } to generate proposals.', 400);
|
|
35
|
+
}
|
|
36
|
+
if (!(await checkRateLimitAsync(aiGenerateLimiter, `ai-seo-proposals-generate:${auth.session.userId}`))) {
|
|
37
|
+
return errorResponse('AI rate limit reached. Try again in an hour.', 429);
|
|
38
|
+
}
|
|
39
|
+
const { generateSeoProposals } = await import('../../../../seo/proposals-generate.js');
|
|
40
|
+
const result = await generateSeoProposals(db(), { userId: auth.session.userId });
|
|
41
|
+
return json({ data: result });
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
return internalError(err, 'seo/proposals/generate');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// WRITE_ROLES like the per-item apply-fix route; redirect items are
|
|
48
|
+
// additionally admin-gated per item inside the service (spec §4).
|
|
49
|
+
export async function postSeoProposalsBulkApply(request) {
|
|
50
|
+
try {
|
|
51
|
+
const auth = await requireAuth(request);
|
|
52
|
+
if (auth.error)
|
|
53
|
+
return auth.error;
|
|
54
|
+
const roleErr = requireRole(auth.session.role, WRITE_ROLES);
|
|
55
|
+
if (roleErr)
|
|
56
|
+
return roleErr;
|
|
57
|
+
if (!hasModel(db(), 'seoIssue'))
|
|
58
|
+
return modelNotAvailable('SeoIssue');
|
|
59
|
+
const parsed = await validateBody(request, seoBulkApplyBodySchema);
|
|
60
|
+
if (!parsed.ok)
|
|
61
|
+
return parsed.error;
|
|
62
|
+
const rawItems = parsed.data.items;
|
|
63
|
+
const { PROPOSAL_BULK_APPLY_MAX, bulkApplySeoProposals } = await import('../../../../seo/proposals-bulk-apply.js');
|
|
64
|
+
if (rawItems.length > PROPOSAL_BULK_APPLY_MAX) {
|
|
65
|
+
return errorResponse(`At most ${PROPOSAL_BULK_APPLY_MAX} items per bulk apply.`, 400);
|
|
66
|
+
}
|
|
67
|
+
const items = rawItems.map((item) => ({
|
|
68
|
+
kind: item.kind,
|
|
69
|
+
id: item.id,
|
|
70
|
+
fingerprint: item.fingerprint,
|
|
71
|
+
}));
|
|
72
|
+
const result = await bulkApplySeoProposals(db(), {
|
|
73
|
+
items,
|
|
74
|
+
actor: { userId: auth.session.userId, role: auth.session.role },
|
|
75
|
+
authorizeContentWrite: contentWriteGate(auth.session),
|
|
76
|
+
});
|
|
77
|
+
if (result.blocked) {
|
|
78
|
+
return json({ error: result.reason, code: 'governance_blocked' }, 403);
|
|
79
|
+
}
|
|
80
|
+
return json({
|
|
81
|
+
data: {
|
|
82
|
+
results: result.results,
|
|
83
|
+
applied: result.applied,
|
|
84
|
+
failed: result.failed,
|
|
85
|
+
pending: result.pending,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
return internalError(err, 'seo/proposals/bulk-apply');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=proposals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposals.js","sourceRoot":"","sources":["../../../../../src/api/routes/seo/handlers/proposals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function getLlmsTxt(request: Request): Promise<Response>;
|
|
2
|
+
export declare function getLlmsFullTxt(request: Request): Promise<Response>;
|
|
3
|
+
export declare function getMarkdownForPath(request: Request): Promise<Response>;
|
|
4
|
+
export declare function getAiCrawlerTrap(request: Request): Promise<Response>;
|
|
5
|
+
export declare function getAiCrawlers(request: Request): Promise<Response>;
|
|
6
|
+
//# sourceMappingURL=public-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-files.d.ts","sourceRoot":"","sources":["../../../../../src/api/routes/seo/handlers/public-files.ts"],"names":[],"mappings":"AAYA,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyFpE;AAMD,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkGxE;AAOD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0E5E;AAOD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkB1E;AAID,wBAAsB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgEvE"}
|