feat: add record building with threshold and input validation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
d88c06d086
commit
386b88bab5
@@ -0,0 +1,53 @@
|
||||
import { isVideoId } from './video-id.js';
|
||||
|
||||
const PAGES = new Set(['home', 'watch', 'search', 'channel']);
|
||||
const MAX_TEXT = 300;
|
||||
|
||||
export function shouldSave({ views, outlierScore }, { threshold, minViews }) {
|
||||
return typeof outlierScore === 'number' && outlierScore >= threshold && views >= minViews;
|
||||
}
|
||||
|
||||
const finiteOrNull = (value) => (typeof value === 'number' && Number.isFinite(value) ? value : null);
|
||||
const textOrNull = (value) => (typeof value === 'string' && value.trim() ? value.trim().slice(0, MAX_TEXT) : null);
|
||||
const urlOrNull = (value, prefix) => (typeof value === 'string' && value.startsWith(prefix) ? value : null);
|
||||
|
||||
// Validates a message coming from the content script before anything is stored.
|
||||
export function sanitizeItem(raw) {
|
||||
if (!raw || !isVideoId(raw.videoId)) return null;
|
||||
const outlierScore = finiteOrNull(raw.outlierScore);
|
||||
const views = finiteOrNull(raw.views);
|
||||
if (outlierScore === null || outlierScore < 0 || views === null || views < 0) return null;
|
||||
const subscribers = finiteOrNull(raw.subscribers);
|
||||
return {
|
||||
videoId: raw.videoId,
|
||||
title: textOrNull(raw.title),
|
||||
thumbnailUrl: urlOrNull(raw.thumbnailUrl, 'https://i.ytimg.com/'),
|
||||
channelTitle: textOrNull(raw.channelTitle),
|
||||
channelUrl: urlOrNull(raw.channelUrl, 'https://www.youtube.com/'),
|
||||
subscribers: subscribers !== null && subscribers >= 0 ? subscribers : null,
|
||||
views,
|
||||
outlierScore: Math.round(outlierScore * 100) / 100,
|
||||
isShort: raw.isShort === true,
|
||||
page: PAGES.has(raw.page) ? raw.page : 'home',
|
||||
};
|
||||
}
|
||||
|
||||
export function buildRecord(item, previous, settings, now = new Date()) {
|
||||
if (!previous && !shouldSave(item, settings)) return null;
|
||||
const nowIso = now.toISOString();
|
||||
return {
|
||||
videoId: item.videoId,
|
||||
title: item.title ?? previous?.title ?? item.videoId,
|
||||
url: `https://www.youtube.com/watch?v=${item.videoId}`,
|
||||
thumbnailUrl: item.thumbnailUrl ?? previous?.thumbnailUrl ?? null,
|
||||
channelTitle: item.channelTitle ?? previous?.channelTitle ?? null,
|
||||
channelUrl: item.channelUrl ?? previous?.channelUrl ?? null,
|
||||
subscribers: item.subscribers ?? previous?.subscribers ?? null,
|
||||
views: item.views,
|
||||
outlierScore: item.outlierScore,
|
||||
isShort: item.isShort || previous?.isShort || false,
|
||||
foundOn: previous?.foundOn ?? item.page,
|
||||
firstSeenAt: previous?.firstSeenAt ?? nowIso,
|
||||
updatedAt: nowIso,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user