745e9b691d
Memind CI / Test, build, and release guards (pull_request) Successful in 3m35s
未点公开发布但已落盘到 public/ 的页面,在无在线非 public 发布阻挡时 合成 implicit public snapshot,注入 canonical/JSON-LD 并扫描进 sitemap。 Co-authored-by: Cursor <cursoragent@cursor.com>
119 lines
3.4 KiB
JavaScript
119 lines
3.4 KiB
JavaScript
const INDEXABLE_ACCESS_MODE = 'public';
|
|
|
|
export function isWorkspacePublicHtmlRelativePath(value) {
|
|
const normalized = String(value ?? '')
|
|
.replace(/\\/g, '/')
|
|
.replace(/^\/+/, '');
|
|
if (!/^public\/[^/]+\.html$/i.test(normalized)) return false;
|
|
if (/\/_archived[^/]*\.html$/i.test(normalized)) return false;
|
|
return true;
|
|
}
|
|
|
|
export function buildImplicitWorkspacePublicPublication({
|
|
publicUrl = '',
|
|
pageId = null,
|
|
updatedAt = null,
|
|
title = null,
|
|
summary = null,
|
|
} = {}) {
|
|
const url = String(publicUrl ?? '').trim();
|
|
if (!url) return null;
|
|
return normalizePublicationSnapshot({
|
|
accessMode: INDEXABLE_ACCESS_MODE,
|
|
status: 'online',
|
|
publicUrl: url,
|
|
pageId,
|
|
userConfirmedAt: null,
|
|
expiresAt: null,
|
|
updatedAt: updatedAt ?? Date.now(),
|
|
title,
|
|
summary,
|
|
});
|
|
}
|
|
|
|
export function normalizePublicationSnapshot(input = {}) {
|
|
if (!input || typeof input !== 'object') return null;
|
|
const accessMode = String(
|
|
input.accessMode ?? input.access_mode ?? '',
|
|
).trim();
|
|
if (!accessMode) return null;
|
|
const status = String(input.status ?? 'online').trim() || 'online';
|
|
const userConfirmedRaw =
|
|
input.userConfirmedAt ?? input.user_confirmed_at;
|
|
const userConfirmedAt =
|
|
userConfirmedRaw == null || userConfirmedRaw === ''
|
|
? null
|
|
: Number(userConfirmedRaw);
|
|
const expiresRaw = input.expiresAt ?? input.expires_at;
|
|
const expiresAt =
|
|
expiresRaw == null || expiresRaw === ''
|
|
? null
|
|
: Number(expiresRaw);
|
|
return {
|
|
id: String(input.id ?? input.publicationId ?? '').trim() || null,
|
|
pageId: String(input.pageId ?? input.page_id ?? '').trim() || null,
|
|
status,
|
|
accessMode,
|
|
userConfirmedAt:
|
|
Number.isFinite(userConfirmedAt) ? userConfirmedAt : null,
|
|
expiresAt: Number.isFinite(expiresAt) ? expiresAt : null,
|
|
publicUrl: String(input.publicUrl ?? input.public_url ?? '').trim() || null,
|
|
title: String(input.title ?? '').trim() || null,
|
|
summary: String(input.summary ?? '').trim() || null,
|
|
updatedAt:
|
|
Number(input.updatedAt ?? input.updated_at ?? input.publishedAt ?? input.published_at) ||
|
|
null,
|
|
};
|
|
}
|
|
|
|
export function isPublicationIndexable(publication, { now = Date.now() } = {}) {
|
|
const snapshot = normalizePublicationSnapshot(publication);
|
|
if (!snapshot) return false;
|
|
if (snapshot.status !== 'online') return false;
|
|
if (snapshot.accessMode !== INDEXABLE_ACCESS_MODE) return false;
|
|
if (snapshot.expiresAt != null && snapshot.expiresAt <= now) return false;
|
|
return true;
|
|
}
|
|
|
|
export function resolveIndexPolicy({
|
|
seoGeoConfig = null,
|
|
publication = null,
|
|
embed = false,
|
|
} = {}) {
|
|
if (embed) {
|
|
return {
|
|
mode: 'off',
|
|
injectNoindex: false,
|
|
reason: 'embed',
|
|
};
|
|
}
|
|
if (!seoGeoConfig?.enabled) {
|
|
return {
|
|
mode: 'off',
|
|
injectNoindex: false,
|
|
reason: 'disabled',
|
|
};
|
|
}
|
|
if (!isPublicationIndexable(publication)) {
|
|
return {
|
|
mode: 'noindex',
|
|
injectNoindex: true,
|
|
reason: publication ? 'not_indexable_publication' : 'missing_publication',
|
|
};
|
|
}
|
|
return {
|
|
mode: 'indexable',
|
|
injectNoindex: false,
|
|
reason: 'public_online',
|
|
seoEnabled: Boolean(seoGeoConfig.seo?.enabled),
|
|
geoEnabled: Boolean(seoGeoConfig.geo?.enabled),
|
|
canonicalEnabled: seoGeoConfig.seo?.canonical !== false,
|
|
jsonLdEnabled: seoGeoConfig.geo?.jsonLd !== false,
|
|
};
|
|
}
|
|
|
|
export const indexPolicyInternals = {
|
|
INDEXABLE_ACCESS_MODE,
|
|
isWorkspacePublicHtmlRelativePath,
|
|
};
|