import { ApiClient } from '@/client/api-client.js';
import type { ApiResponse, PaginationOptions } from '@/client/types.js';
/**
* Document Client for FeiShu
*
* API client specialized for document operations
*/
import type {
CreateBlockRequest,
CreateBlockResponse,
CreateDocumentResponse,
DocumentContent,
DocumentInfo,
} from './types/index.js';
/**
* Document API client
*
* Specialized client for interacting with FeiShu document APIs
*/
export class DocumentClient extends ApiClient {
/**
* Get document raw content
*
* @param documentId - ID of the document
* @param lang - Language setting (0 for default)
* @returns Document content response
*/
getDocumentContent = (
documentId: string,
lang = 0,
): Promise<ApiResponse<DocumentContent>> =>
this.get<DocumentContent>(
`/open-apis/docx/v1/documents/${documentId}/raw_content`,
{ lang },
);
/**
* Get document metadata
*
* @param documentId - ID of the document
* @returns Document information response
*/
getDocumentInfo = (documentId: string): Promise<ApiResponse<DocumentInfo>> =>
this.get<DocumentInfo>(`/open-apis/docx/v1/documents/${documentId}`);
/**
* Create a new document
*
* @param options - Document creation options
* @returns Created document info response
*/
createDocument = (
options: { title?: string; folderToken?: string } = {},
): Promise<ApiResponse<CreateDocumentResponse>> =>
this.post<CreateDocumentResponse>('/open-apis/docx/v1/documents', {
title: options.title,
folder_token: options.folderToken,
});
/**
* Create blocks in a document
*
* @param documentId - ID of the document
* @param blockId - ID of the parent block (use document_id for root)
* @param children - Array of blocks to create
* @param index - Index to insert blocks at (-1 for end)
* @returns Created blocks response
*/
createBlocks = (
documentId: string,
blockId: string,
children: CreateBlockRequest[],
index = -1,
): Promise<ApiResponse<CreateBlockResponse>> =>
this.post<CreateBlockResponse>(
`/open-apis/docx/v1/documents/${documentId}/blocks/${blockId}/children`,
{ children, index },
{ document_revision_id: -1 },
);
/**
* Get document blocks
*
* @param documentId - ID of the document
* @param blockId - ID of the block to get (optional, defaults to root)
* @returns Document blocks response
*/
getBlocks = (
documentId: string,
blockId?: string,
): Promise<ApiResponse<{ items: unknown[] }>> => {
const path = blockId
? `/open-apis/docx/v1/documents/${documentId}/blocks/${blockId}`
: `/open-apis/docx/v1/documents/${documentId}/blocks`;
return this.get<{ items: unknown[] }>(path);
};
/**
* Set document public sharing settings
*
* @param documentToken - Token of the document
* @param options - Sharing options
* @returns Response
*/
setPublicSharing = (
documentToken: string,
options: {
external_access_entity?: 'open' | 'closed' | 'allow_share_partner_tenant';
security_entity?: 'anyone_can_view' | 'anyone_can_edit' | 'only_full_access';
comment_entity?: 'anyone_can_view' | 'anyone_can_edit';
share_entity?: 'anyone' | 'same_tenant' | 'only_full_access';
link_share_entity?: 'tenant_readable' | 'tenant_editable' | 'partner_tenant_readable' | 'partner_tenant_editable' | 'anyone_readable' | 'anyone_editable' | 'closed';
invite_external?: boolean;
},
): Promise<ApiResponse<unknown>> =>
this.patch<unknown>(
`/open-apis/drive/v1/permissions/${documentToken}/public`,
options,
{ type: 'docx' },
);
/**
* Create password for document sharing
*
* @param documentToken - Token of the document
* @returns Response with password
*/
createSharePassword = (
documentToken: string,
): Promise<ApiResponse<{ password: string }>> =>
this.post<{ password: string }>(
`/open-apis/drive/v1/permissions/${documentToken}/public/password`,
{},
{ type: 'docx' },
);
/**
* Update password for document sharing
*
* @param documentToken - Token of the document
* @returns Response with new password
*/
updateSharePassword = (
documentToken: string,
): Promise<ApiResponse<{ password: string }>> =>
this.put<{ password: string }>(
`/open-apis/drive/v1/permissions/${documentToken}/public/password`,
{},
{ type: 'docx' },
);
/**
* Delete password for document sharing
*
* @param documentToken - Token of the document
* @returns Response
*/
deleteSharePassword = (
documentToken: string,
): Promise<ApiResponse<unknown>> =>
this.delete<unknown>(
`/open-apis/drive/v1/permissions/${documentToken}/public/password`,
{ type: 'docx' },
);
/**
* Transfer document owner
*
* @param documentToken - Token of the document
* @param newOwnerId - User ID of new owner
* @param memberType - Type of member (user, chat, department, etc.)
* @returns Response
*/
transferOwner = (
documentToken: string,
newOwnerId: string,
memberType: 'user' | 'chat' | 'department' | 'group' | 'wikispaceid' = 'user',
): Promise<ApiResponse<unknown>> =>
this.post<unknown>(
`/open-apis/drive/v1/permissions/${documentToken}/members/transfer_owner`,
{
member_type: memberType,
member_id: newOwnerId,
},
{ type: 'docx', need_notification: true },
);
/**
* Add collaborator to document
*
* @param documentToken - Token of the document
* @param memberId - ID of the member to add
* @param memberType - Type of member
* @param perm - Permission level
* @returns Response
*/
addCollaborator = (
documentToken: string,
memberId: string,
memberType: 'user' | 'chat' | 'department' | 'group' | 'wikispaceid' = 'user',
perm: 'view' | 'edit' | 'full_access' = 'edit',
): Promise<ApiResponse<unknown>> =>
this.post<unknown>(
`/open-apis/drive/v1/permissions/${documentToken}/members`,
{
member_type: memberType,
member_id: memberId,
perm,
},
{ type: 'docx', need_notification: true },
);
}