86 lines
1.7 KiB
TypeScript
86 lines
1.7 KiB
TypeScript
import { customRandom } from "nanoid";
|
|
|
|
type BaseJsonDocument = {
|
|
id: string;
|
|
title: string;
|
|
};
|
|
|
|
export type RawJsonDocument = BaseJsonDocument & {
|
|
type: "raw";
|
|
contents: string;
|
|
};
|
|
|
|
export type UrlJsonDocument = BaseJsonDocument & {
|
|
type: "url";
|
|
url: string;
|
|
};
|
|
|
|
export type JSONDocument = RawJsonDocument | UrlJsonDocument;
|
|
|
|
export async function createFromUrl(
|
|
url: URL,
|
|
title?: string
|
|
): Promise<JSONDocument> {
|
|
const docId = createId();
|
|
const doc = {
|
|
id: docId,
|
|
type: <const>"url",
|
|
url: url.href,
|
|
title: title ?? url.hostname,
|
|
};
|
|
|
|
await DOCUMENTS.put(docId, JSON.stringify(doc));
|
|
|
|
return doc;
|
|
}
|
|
|
|
export async function createFromRawJson(
|
|
filename: string,
|
|
contents: string
|
|
): Promise<JSONDocument> {
|
|
const docId = createId();
|
|
const doc = { id: docId, type: <const>"raw", contents, title: filename };
|
|
|
|
await DOCUMENTS.put(docId, JSON.stringify(doc));
|
|
|
|
return doc;
|
|
}
|
|
|
|
export async function getDocument(
|
|
slug: string
|
|
): Promise<JSONDocument | undefined> {
|
|
const doc = await DOCUMENTS.get(slug);
|
|
|
|
if (!doc) return;
|
|
|
|
return JSON.parse(doc);
|
|
}
|
|
|
|
export async function updateDocument(
|
|
slug: string,
|
|
title: string
|
|
): Promise<JSONDocument | undefined> {
|
|
const document = await getDocument(slug);
|
|
|
|
if (!document) return;
|
|
|
|
const updated = { ...document, title };
|
|
|
|
await DOCUMENTS.put(slug, JSON.stringify(updated));
|
|
|
|
return updated;
|
|
}
|
|
|
|
function createId(): string {
|
|
const nanoid = customRandom(
|
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
|
12,
|
|
(bytes: number): Uint8Array => {
|
|
const array = new Uint8Array(bytes);
|
|
crypto.getRandomValues(array);
|
|
return array;
|
|
}
|
|
);
|
|
return nanoid();
|
|
}
|