124 lines
2.9 KiB
TypeScript
124 lines
2.9 KiB
TypeScript
import { getApiClient } from './client';
|
|
import { listWorkspaces, type MobileWorkspace } from './workspaces';
|
|
|
|
export type MobileNote = {
|
|
id: string;
|
|
workspaceId: string;
|
|
title: string;
|
|
body: string;
|
|
workspaceName: string;
|
|
status: 'draft' | 'active' | 'archived';
|
|
updatedAt: string;
|
|
};
|
|
|
|
type NoteDoc = {
|
|
id: string;
|
|
workspaceId: string;
|
|
title: string;
|
|
body: string;
|
|
status: 'draft' | 'active' | 'archived';
|
|
updatedAt: string;
|
|
};
|
|
|
|
type NoteListResponse = {
|
|
items: NoteDoc[];
|
|
};
|
|
|
|
type CreateNoteInput = {
|
|
id: string;
|
|
workspaceId: string;
|
|
title: string;
|
|
body: string;
|
|
tags?: string[];
|
|
links?: string[];
|
|
};
|
|
|
|
function generateNoteId(): string {
|
|
if (typeof globalThis.crypto?.randomUUID === 'function') {
|
|
return globalThis.crypto.randomUUID();
|
|
}
|
|
|
|
return `note-${Date.now()}`;
|
|
}
|
|
|
|
function mapWorkspaceNames(workspaces: MobileWorkspace[]) {
|
|
return new Map(workspaces.map((workspace) => [workspace.id, workspace.name]));
|
|
}
|
|
|
|
function toMobileNote(note: NoteDoc, workspaceNames: Map<string, string>): MobileNote {
|
|
return {
|
|
id: note.id,
|
|
workspaceId: note.workspaceId,
|
|
title: note.title,
|
|
body: note.body,
|
|
workspaceName: workspaceNames.get(note.workspaceId) ?? note.workspaceId,
|
|
status: note.status,
|
|
updatedAt: note.updatedAt,
|
|
};
|
|
}
|
|
|
|
export async function listNotes(): Promise<MobileNote[]> {
|
|
const [response, workspaces] = await Promise.all([
|
|
getApiClient().fetch<NoteListResponse>('/notes'),
|
|
listWorkspaces(),
|
|
]);
|
|
|
|
const workspaceNames = mapWorkspaceNames(workspaces);
|
|
return response.items.map((note) => toMobileNote(note, workspaceNames));
|
|
}
|
|
|
|
export async function getNote(id: string, workspaceId: string): Promise<MobileNote | null> {
|
|
const [note, workspaces] = await Promise.all([
|
|
getApiClient().fetch<NoteDoc>(`/notes/${id}?workspaceId=${encodeURIComponent(workspaceId)}`),
|
|
listWorkspaces(),
|
|
]);
|
|
|
|
return toMobileNote(note, mapWorkspaceNames(workspaces));
|
|
}
|
|
|
|
export async function createNote(
|
|
workspaceId: string,
|
|
title: string,
|
|
body: string,
|
|
): Promise<MobileNote> {
|
|
const trimmedTitle = title.trim() || 'Untitled draft';
|
|
const payload: CreateNoteInput = {
|
|
id: generateNoteId(),
|
|
workspaceId,
|
|
title: trimmedTitle,
|
|
body,
|
|
tags: [],
|
|
links: [],
|
|
};
|
|
|
|
const [created, workspaces] = await Promise.all([
|
|
getApiClient().fetch<NoteDoc>('/notes', {
|
|
method: 'POST',
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
listWorkspaces(),
|
|
]);
|
|
|
|
return toMobileNote(created, mapWorkspaceNames(workspaces));
|
|
}
|
|
|
|
export async function updateNote(
|
|
id: string,
|
|
workspaceId: string,
|
|
title: string,
|
|
body: string,
|
|
): Promise<MobileNote> {
|
|
const [updated, workspaces] = await Promise.all([
|
|
getApiClient().fetch<NoteDoc>(`/notes/${id}?workspaceId=${encodeURIComponent(workspaceId)}`, {
|
|
method: 'PATCH',
|
|
body: JSON.stringify({
|
|
title,
|
|
body,
|
|
}),
|
|
}),
|
|
listWorkspaces(),
|
|
]);
|
|
|
|
return toMobileNote(updated, mapWorkspaceNames(workspaces));
|
|
}
|