Files

55 lines
1.3 KiB
TypeScript

import type { QueryCtx, MutationCtx } from './_generated/server.js';
export async function requireOwner(ctx: QueryCtx | MutationCtx) {
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new Error('Not authenticated');
}
return identity.tokenIdentifier;
}
export function slugifyTag(value: string) {
return value
.trim()
.toLowerCase()
.replace(/['"]/g, '')
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '')
.slice(0, 48);
}
export function cleanTagName(value: string) {
return value.trim().replace(/\s+/g, ' ').slice(0, 40);
}
export function markdownToPlainText(markdown: string) {
return markdown
.replace(/```[\s\S]*?```/g, ' ')
.replace(/`([^`]+)`/g, '$1')
.replace(/!\[[^\]]*]\([^)]*\)/g, ' ')
.replace(/\[([^\]]+)]\([^)]*\)/g, '$1')
.replace(/[#>*_~`|[\](){}-]/g, ' ')
.replace(/\s+/g, ' ')
.trim();
}
export function buildSearchText(args: {
title: string;
body: string;
mood: string;
tagNames: string[];
}) {
return [args.title, markdownToPlainText(args.body), args.mood, ...args.tagNames]
.filter(Boolean)
.join(' ');
}
export function tagColor(slug: string) {
const colors = ['amber', 'orange', 'rose', 'sky', 'teal', 'violet', 'lime', 'stone'];
const total = [...slug].reduce((sum, char) => sum + char.charCodeAt(0), 0);
return colors[total % colors.length];
}