55 lines
1.3 KiB
TypeScript
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];
|
|
}
|