Files
bookstack/ts/bookstack.classes.chapter.ts
2026-03-28 09:16:54 +00:00

128 lines
4.0 KiB
TypeScript

import type { BookStackAccount } from './bookstack.classes.account.js';
import type {
IBookStackChapter,
IBookStackPage,
IBookStackTag,
IBookStackListParams,
IBookStackListResponse,
TBookStackExportFormat,
} from './bookstack.interfaces.js';
import { BookStackPage } from './bookstack.classes.page.js';
import { autoPaginate } from './bookstack.helpers.js';
export class BookStackChapter {
public readonly id: number;
public readonly bookId: number;
public readonly name: string;
public readonly slug: string;
public readonly description: string;
public readonly priority: number;
public readonly createdAt: string;
public readonly updatedAt: string;
public readonly createdBy: number;
public readonly updatedBy: number;
public readonly ownedBy: number;
public readonly tags: IBookStackTag[];
/** @internal */
constructor(
private accountRef: BookStackAccount,
raw: IBookStackChapter,
) {
this.id = raw.id;
this.bookId = raw.book_id;
this.name = raw.name || '';
this.slug = raw.slug || '';
this.description = raw.description || '';
this.priority = raw.priority || 0;
this.createdAt = raw.created_at || '';
this.updatedAt = raw.updated_at || '';
this.createdBy = raw.created_by;
this.updatedBy = raw.updated_by;
this.ownedBy = raw.owned_by;
this.tags = raw.tags || [];
}
// ---------------------------------------------------------------------------
// CRUD
// ---------------------------------------------------------------------------
async update(data: {
name?: string;
description?: string;
description_html?: string;
book_id?: number;
tags?: IBookStackTag[];
priority?: number;
default_template_id?: number | null;
}): Promise<BookStackChapter> {
const raw = await this.accountRef.request<IBookStackChapter>('PUT', `/chapters/${this.id}`, data);
return new BookStackChapter(this.accountRef, raw);
}
async delete(): Promise<void> {
await this.accountRef.request('DELETE', `/chapters/${this.id}`);
}
// ---------------------------------------------------------------------------
// Export
// ---------------------------------------------------------------------------
async export(format: TBookStackExportFormat): Promise<string | Uint8Array> {
if (format === 'pdf') {
return this.accountRef.requestBinary(`/chapters/${this.id}/export/${format}`);
}
return this.accountRef.requestText('GET', `/chapters/${this.id}/export/${format}`);
}
// ---------------------------------------------------------------------------
// Navigation — Pages
// ---------------------------------------------------------------------------
async getPages(opts?: IBookStackListParams): Promise<BookStackPage[]> {
return autoPaginate(
(offset, count) =>
this.accountRef.request<IBookStackListResponse<IBookStackPage>>(
'GET',
this.accountRef.buildListUrl(`/pages`, { ...opts, offset, count, filter: { ...opts?.filter, chapter_id: String(this.id) } }),
),
opts,
).then((pages) => pages.map((p) => new BookStackPage(this.accountRef, p)));
}
async createPage(data: {
name: string;
html?: string;
markdown?: string;
tags?: IBookStackTag[];
priority?: number;
}): Promise<BookStackPage> {
const raw = await this.accountRef.request<IBookStackPage>('POST', '/pages', {
chapter_id: this.id,
...data,
});
return new BookStackPage(this.accountRef, raw);
}
// ---------------------------------------------------------------------------
// Serialization
// ---------------------------------------------------------------------------
toJSON(): IBookStackChapter {
return {
id: this.id,
book_id: this.bookId,
name: this.name,
slug: this.slug,
description: this.description,
priority: this.priority,
created_at: this.createdAt,
updated_at: this.updatedAt,
created_by: this.createdBy,
updated_by: this.updatedBy,
owned_by: this.ownedBy,
tags: this.tags,
};
}
}