import type { Dispatcher } from 'undici'; import type { AuthStrategy } from '../auth/types.js'; import { type MiddlewareRegistry } from './middleware-registry.js'; /** * Result of a PROPFIND operation. */ export interface PropfindEntry { href: string; displayName?: string; isCollection: boolean; contentLength?: number; lastModified?: Date; contentType?: string; } /** * WebDAV client for B2C Commerce instance file operations. * * Handles WebDAV requests with proper authentication and provides * typed methods for common operations. * * **Note:** This client is typically accessed via `B2CInstance.webdav` rather * than instantiated directly. The `B2CInstance` class handles authentication setup. * * @example * // Via B2CInstance (recommended) * import { resolveConfig } from '@salesforce/b2c-tooling-sdk/config'; * const config = resolveConfig(); * const instance = config.createB2CInstance(); * await instance.webdav.mkcol('Cartridges/v1'); * await instance.webdav.put('Cartridges/v1/app.zip', zipBuffer); * * @example * // Direct instantiation (advanced) * const client = new WebDavClient('sandbox.demandware.net', authStrategy); * await client.mkcol('Cartridges/v1'); * await client.put('Cartridges/v1/app_storefront/cartridge.zip', zipBuffer); */ /** * Options for creating a WebDAV client. */ export interface WebDavClientOptions { /** * Middleware registry to use for this client. * If not specified, uses the global middleware registry. */ middlewareRegistry?: MiddlewareRegistry; /** * undici dispatcher for custom TLS options (mTLS, self-signed certs). * Use createTlsDispatcher() to create one with client certificates. */ dispatcher?: Dispatcher; } export declare class WebDavClient { private auth; private baseUrl; private middlewareRegistry; private dispatcher?; /** * Creates a new WebDAV client. * * @param hostname - WebDAV hostname (may differ from API hostname) * @param auth - Authentication strategy to use for requests * @param options - Optional configuration including middleware registry and TLS dispatcher */ constructor(hostname: string, auth: AuthStrategy, options?: WebDavClientOptions); /** * Builds the full URL for a WebDAV path. * * @param path - Path relative to /webdav/Sites/ * @returns Full URL */ buildUrl(path: string): string; /** * Collects middleware from the registry for WebDAV client. */ private getMiddleware; /** * Makes a raw WebDAV request. * * @param path - Path relative to /webdav/Sites/ * @param init - Fetch init options * @returns Response from the server */ request(path: string, init?: RequestInit): Promise; /** * Converts Headers to a plain object for logging. */ private headersToObject; /** * Formats body for logging, describing binary data. */ private formatBody; /** * Creates a directory (collection). * * @param path - Path to create * @throws Error if creation fails (except 405 which means already exists) * * @example * await client.mkcol('Cartridges/v1'); */ mkcol(path: string): Promise; /** * Uploads a file. * * @param path - Destination path * @param content - File content as Buffer, Blob, or string * @param contentType - Optional content type header * * @example * await client.put('Cartridges/v1/app.zip', zipBuffer, 'application/zip'); */ put(path: string, content: Buffer | Blob | string, contentType?: string): Promise; /** * Downloads a file. * * @param path - Path to download * @returns File content as ArrayBuffer * * @example * const content = await client.get('Cartridges/v1/app.zip'); */ get(path: string): Promise; /** * Deletes a file or directory. * * @param path - Path to delete * @throws Error if the path doesn't exist (404) or deletion fails * * @example * await client.delete('Cartridges/v1/old-cartridge'); */ delete(path: string): Promise; /** * Lists directory contents. * * @param path - Directory path * @param depth - PROPFIND depth (0, 1, or 'infinity') * @returns Array of entries in the directory * * @example * const entries = await client.propfind('Cartridges'); * for (const entry of entries) { * console.log(entry.displayName, entry.isCollection); * } */ propfind(path: string, depth?: '0' | '1' | 'infinity'): Promise; /** * Copies a file or directory. * * @param source - Source path relative to /webdav/Sites/ * @param destination - Destination path relative to /webdav/Sites/ * @param overwrite - Whether to overwrite if destination exists (default: true) * * @example * await client.copy('Cartridges/v1/cartridge', 'Cartridges/v2/cartridge'); */ copy(source: string, destination: string, overwrite?: boolean): Promise; /** * Moves (renames) a file or directory. * * @param source - Source path relative to /webdav/Sites/ * @param destination - Destination path relative to /webdav/Sites/ * @param overwrite - Whether to overwrite if destination exists (default: true) * * @example * await client.move('Cartridges/v1/old-name', 'Cartridges/v1/new-name'); */ move(source: string, destination: string, overwrite?: boolean): Promise; /** * Checks if a path exists. * * @param path - Path to check * @returns true if exists, false otherwise */ exists(path: string): Promise; /** * Parses PROPFIND XML response into structured entries using xml2js. */ private parsePropfindResponse; /** * Extracts text content from an xml2js parsed value. * Handles both string values and objects with '_' text content. */ private getXmlText; }