143 lines
4.0 KiB
TypeScript
143 lines
4.0 KiB
TypeScript
import { resources } from "@lib/resources.ts";
|
|
|
|
export function formatDate(date: Date): string {
|
|
const options = { year: "numeric", month: "long", day: "numeric" } as const;
|
|
return new Intl.DateTimeFormat("en-US", options).format(date);
|
|
}
|
|
|
|
export function safeFileName(inputString: string): string {
|
|
// Convert the string to lowercase
|
|
let fileName = inputString.toLowerCase();
|
|
|
|
// Replace spaces with underscores
|
|
fileName = fileName.replace(/ /g, "_");
|
|
|
|
// Remove characters that are not safe for file names
|
|
fileName = fileName.replace(/[^\w.-]/g, "");
|
|
|
|
fileName = fileName.replaceAll(":", "");
|
|
|
|
return fileName;
|
|
}
|
|
|
|
export function extractHashTags(inputString: string) {
|
|
const hashtags = [];
|
|
|
|
for (
|
|
const [hashtag] of inputString.matchAll(/(?:^|\s)#\S*(?<!\))/g)
|
|
) {
|
|
const cleaned = hashtag.replace(/\#/g, "").trim();
|
|
if (cleaned.length > 2) {
|
|
hashtags.push(cleaned);
|
|
}
|
|
}
|
|
|
|
return hashtags;
|
|
}
|
|
|
|
export const isYoutubeLink = (link: string) => {
|
|
try {
|
|
const url = new URL(link);
|
|
return ["youtu.be", "youtube.com", "www.youtube.com"].includes(
|
|
url.hostname,
|
|
);
|
|
} catch (_err) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
export function extractYoutubeId(link: string) {
|
|
const url = new URL(link);
|
|
if (url.searchParams.has("v")) {
|
|
const id = url.searchParams.get("v");
|
|
|
|
if (id?.length && id.length > 4) {
|
|
return id;
|
|
}
|
|
}
|
|
|
|
return url.pathname.replace(/^\//, "");
|
|
}
|
|
|
|
export async function hash(message: string) {
|
|
const data = new TextEncoder().encode(message);
|
|
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join(
|
|
"",
|
|
);
|
|
return hashHex;
|
|
}
|
|
// Helper function to calculate SHA-256 hash
|
|
export async function sha256(input: string) {
|
|
const encoder = new TextEncoder();
|
|
const data = encoder.encode(input);
|
|
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
return base64urlencode(new Uint8Array(hashBuffer));
|
|
}
|
|
|
|
// Helper function to encode a byte array as a URL-safe base64 string
|
|
function base64urlencode(data: Uint8Array) {
|
|
const base64 = btoa(String.fromCharCode(...data));
|
|
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
}
|
|
export function getCookie(name: string): string | null {
|
|
if (typeof document === "undefined") return null;
|
|
const nameLenPlus = name.length + 1;
|
|
return document.cookie
|
|
.split(";")
|
|
.map((c) => c.trim())
|
|
.filter((cookie) => {
|
|
return cookie.substring(0, nameLenPlus) === `${name}=`;
|
|
})
|
|
.map((cookie) => {
|
|
return decodeURIComponent(cookie.substring(nameLenPlus));
|
|
})[0] || null;
|
|
}
|
|
|
|
const resourcePrefixes = Object.values(resources).map((v) => v.prefix).filter(
|
|
(s) => s.length > 2,
|
|
);
|
|
export const isLocalImage = (src: string) =>
|
|
resourcePrefixes.some((p) => src.startsWith(p));
|
|
|
|
export const isString = (input: string | undefined): input is string => {
|
|
return typeof input === "string";
|
|
};
|
|
|
|
function componentToHex(c: number) {
|
|
if (c <= 1) {
|
|
c = Math.round(c * 255);
|
|
}
|
|
const hex = c.toString(16);
|
|
return hex.length == 1 ? "0" + hex : hex;
|
|
}
|
|
|
|
export function getTimeCacheKey() {
|
|
const d = new Date();
|
|
const year = d.getFullYear();
|
|
const month = d.getMonth().toString();
|
|
const day = d.getDate().toString();
|
|
const hour = d.getHours().toString();
|
|
const minute = d.getMinutes().toString();
|
|
const seconds = d.getSeconds().toString();
|
|
return `${year}:${month}:${day}:${hour}:${minute}:${seconds}`;
|
|
}
|
|
|
|
export function parseTimeCacheKey(key: string) {
|
|
const [_year, _month, _day, _hour, _minute, _second] = key.split(":")
|
|
.slice(1).map((s) => parseInt(s));
|
|
const d = new Date();
|
|
d.setFullYear(_year);
|
|
d.setMonth(_month);
|
|
d.setDate(_day);
|
|
d.setHours(_hour);
|
|
d.setMinutes(_minute);
|
|
d.setSeconds(_second);
|
|
return d;
|
|
}
|
|
|
|
export function rgbToHex(r: number, g: number, b: number) {
|
|
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
|
|
}
|