diff --git a/libs/pinner/src/adapters/pinata/v2/adapter-interface.ts b/libs/pinner/src/adapters/pinata/v2/adapter-interface.ts index 65f048f56..cfa6e716b 100644 --- a/libs/pinner/src/adapters/pinata/v2/adapter-interface.ts +++ b/libs/pinner/src/adapters/pinata/v2/adapter-interface.ts @@ -234,6 +234,9 @@ export interface PinataAdapter { * Configuration */ config: PinataConfig; + /** + * Update the adapter configuration + */ updateConfig(newConfig: PinataConfig): void; /** diff --git a/libs/pinner/src/api/ipns.ts b/libs/pinner/src/api/ipns.ts index 56e8a4c68..a11c7d2f7 100644 --- a/libs/pinner/src/api/ipns.ts +++ b/libs/pinner/src/api/ipns.ts @@ -21,9 +21,16 @@ export interface IpnsClientOptions { signal?: AbortSignal; } +/** + * Client for managing IPNS keys and publishing content to IPNS names. + */ export class IpnsClient { private config: PinnerConfig; + /** + * Create a new IpnsClient. + * @param config SDK configuration + */ constructor(config: PinnerConfig) { if (!config.jwt) { throw new ConfigurationError("JWT token is required"); @@ -99,18 +106,32 @@ export class IpnsClient { } } + /** + * List all IPNS keys. + * @param options Request options + */ async listKeys(options?: IpnsClientOptions): Promise { return this.request("api/ipns/keys", { signal: options?.signal, }); } + /** + * Get a specific IPNS key by ID. + * @param id Key ID + * @param options Request options + */ async getKey(id: number, options?: IpnsClientOptions): Promise { return this.request(`api/ipns/keys/${id}`, { signal: options?.signal, }); } + /** + * Create a new IPNS key. + * @param request Key creation parameters + * @param options Request options + */ async createKey( request: IPNSKeyRequest, options?: IpnsClientOptions, @@ -122,6 +143,11 @@ export class IpnsClient { }); } + /** + * Delete an IPNS key by ID. + * @param id Key ID to delete + * @param options Request options + */ async deleteKey(id: number, options?: IpnsClientOptions): Promise { await this.request(`api/ipns/keys/${id}`, { method: "DELETE", @@ -129,6 +155,11 @@ export class IpnsClient { }); } + /** + * Publish content to an IPNS name. + * @param request Publishing parameters + * @param options Request options + */ async publish( request: IPNSPublishRequest, options?: IpnsClientOptions, @@ -140,6 +171,11 @@ export class IpnsClient { }); } + /** + * Republish (refresh) an existing IPNS record. + * @param id Key ID to republish + * @param options Request options + */ async republish( id: number, options?: IpnsClientOptions, @@ -150,6 +186,11 @@ export class IpnsClient { }); } + /** + * Resolve an IPNS name to its content. + * @param name IPNS name to resolve + * @param options Request options + */ async resolve( name: string, options?: IpnsClientOptions, diff --git a/libs/pinner/src/api/websites.ts b/libs/pinner/src/api/websites.ts index aba3dcf2c..b05276593 100644 --- a/libs/pinner/src/api/websites.ts +++ b/libs/pinner/src/api/websites.ts @@ -65,9 +65,16 @@ export interface WebsitesClientOptions { signal?: AbortSignal; } +/** + * Client for managing websites hosted on IPFS with custom domains and SSL. + */ export class WebsitesClient { private config: PinnerConfig; + /** + * Create a new WebsitesClient. + * @param config SDK configuration + */ constructor(config: PinnerConfig) { if (!config.jwt) { throw new ConfigurationError("JWT token is required"); @@ -145,12 +152,21 @@ export class WebsitesClient { } } + /** + * List all websites. + * @param options Request options + */ async listWebsites(options?: WebsitesClientOptions): Promise { return this.request("api/websites", { signal: options?.signal, }); } + /** + * Create a new website. + * @param request Website creation parameters + * @param options Request options + */ async createWebsite( request: WebsiteRequest, options?: WebsitesClientOptions, @@ -162,6 +178,11 @@ export class WebsitesClient { }); } + /** + * Get website details by ID. + * @param id Website ID + * @param options Request options + */ async getWebsite( id: number, options?: WebsitesClientOptions, @@ -171,6 +192,12 @@ export class WebsitesClient { }); } + /** + * Update a website's configuration. + * @param id Website ID + * @param request Update parameters + * @param options Request options + */ async updateWebsite( id: number, request: WebsiteUpdateRequest, @@ -183,6 +210,11 @@ export class WebsitesClient { }); } + /** + * Delete a website by ID. + * @param id Website ID + * @param options Request options + */ async deleteWebsite( id: number, options?: WebsitesClientOptions, @@ -193,6 +225,11 @@ export class WebsitesClient { }); } + /** + * Validate a website's DNS and SSL configuration. + * @param id Website ID + * @param options Request options + */ async validateWebsite( id: number, options?: WebsitesClientOptions, @@ -206,6 +243,11 @@ export class WebsitesClient { ); } + /** + * Check the SSL certificate status for a domain. + * @param domain Domain name + * @param options Request options + */ async getSSLStatus( domain: string, options?: WebsitesClientOptions, @@ -218,6 +260,10 @@ export class WebsitesClient { ); } + /** + * Get the global website configuration. + * @param options Request options + */ async getWebsiteConfig( options?: WebsitesClientOptions, ): Promise { @@ -226,6 +272,11 @@ export class WebsitesClient { }); } + /** + * Watch SSL status until provisioned, failed, or timed out. + * @param domain Domain name + * @param options Watch interval and timeout + */ watchSSL( domain: string, options?: WatchOptions, diff --git a/libs/pinner/src/blockstore/unstorage-base.ts b/libs/pinner/src/blockstore/unstorage-base.ts index 0cd6cb59b..a7c7434d4 100644 --- a/libs/pinner/src/blockstore/unstorage-base.ts +++ b/libs/pinner/src/blockstore/unstorage-base.ts @@ -16,10 +16,15 @@ import { collectAsyncIterable } from "@/utils/stream"; export interface UnstorageBlockstoreOptions { + /** Unstorage instance to use (bypasses driver creation) */ storage?: Storage; + /** Key prefix for blockstore keys */ prefix?: string; + /** Unstorage driver name or instance */ driver?: Driver; + /** Base path for storage driver */ base?: string; + /** Prefix for datastore keys (defaults to prefix) */ datastorePrefix?: string; } diff --git a/libs/pinner/src/pinner.ts b/libs/pinner/src/pinner.ts index d8cd568ce..38b037f07 100644 --- a/libs/pinner/src/pinner.ts +++ b/libs/pinner/src/pinner.ts @@ -27,6 +27,10 @@ export class Pinner { private _websites: WebsitesClient; private _upload?: UploadMethodAndBuilder; + /** + * Create a new Pinner SDK instance. + * @param config SDK configuration object + */ constructor(config: PinnerConfig) { this.uploadManager = new UploadManager(config); this._pins = new PinClient(config); @@ -86,6 +90,8 @@ export class Pinner { /** * Upload a file and wait for completion. * Convenience method for simple use cases where controls aren't needed. + * @param file The file to upload + * @param options Upload configuration */ async uploadAndWait( file: File, @@ -110,6 +116,8 @@ export class Pinner { /** * Upload a directory to IPFS. + * @param files Array of files to upload as a directory + * @param options Upload configuration */ async uploadDirectory( files: File[], @@ -121,6 +129,8 @@ export class Pinner { /** * Upload a CAR file without preprocessing. * This is useful for passthrough of pre-generated CAR files. + * @param file CAR file or stream to upload + * @param options Upload configuration */ async uploadCar( file: File | ReadableStream, @@ -131,6 +141,8 @@ export class Pinner { /** * Pin existing content by CID. + * @param cid CID of content to pin (string or CID object) + * @param options Remote add options */ async pinByHash( cid: string | CID, @@ -142,6 +154,7 @@ export class Pinner { /** * List pinned content. + * @param options List filtering options */ async listPins(options?: RemoteLsOptions): Promise { const pins: RemotePin[] = []; @@ -153,6 +166,7 @@ export class Pinner { /** * Get pin status. + * @param cid CID of the pinned content to check */ async getPinStatus(cid: string | CID): Promise { const cidObj = typeof cid === "string" ? CID.parse(cid) : cid; @@ -161,6 +175,7 @@ export class Pinner { /** * Check if content is pinned. + * @param cid CID to check */ async isPinned(cid: string | CID): Promise { const cidObj = typeof cid === "string" ? CID.parse(cid) : cid; @@ -169,6 +184,8 @@ export class Pinner { /** * Update pin metadata. + * @param cid CID of the pin + * @param metadata Key-value metadata to set */ async setPinMetadata( cid: string | CID, @@ -180,6 +197,8 @@ export class Pinner { /** * Remove a pin. The block may be deleted when garbage collection is run. + * @param cid CID to unpin + * @param options Abort options */ async unpin(cid: string | CID, options?: AbortOptions): Promise { const cidObj = typeof cid === "string" ? CID.parse(cid) : cid; @@ -191,6 +210,8 @@ export class Pinner { /** * Remove a pin by request ID. The block may be deleted when garbage collection is run. + * @param requestId The request ID to remove + * @param options Abort options */ async unpinByRequestId(requestId: string, options?: AbortOptions): Promise { return this.pins.rmByRequestId(requestId, options); diff --git a/libs/pinner/src/types/pin.ts b/libs/pinner/src/types/pin.ts index db7a45730..7dbc8d641 100644 --- a/libs/pinner/src/types/pin.ts +++ b/libs/pinner/src/types/pin.ts @@ -5,6 +5,9 @@ import type { Status } from "@ipfs-shipyard/pinning-service-client"; * Options that can be passed to abort async operations */ export interface AbortOptions { + /** + * AbortSignal to cancel the operation + */ signal?: AbortSignal; } @@ -12,8 +15,17 @@ export interface AbortOptions { * Allows passing extra options accepted by the remote pinning service */ export interface RemoteAddOptions extends AbortOptions { + /** + * Name for the pin or filter + */ name?: string; + /** + * Key-value metadata to attach to the pin + */ metadata?: Record; + /** + * Origin addresses for the pinned content + */ origins?: string[]; } @@ -21,9 +33,21 @@ export interface RemoteAddOptions extends AbortOptions { * Allows passing extra options accepted by the remote pinning service */ export interface RemoteLsOptions extends AbortOptions { + /** + * Name for the pin or filter + */ name?: string; + /** + * Current status (queued, pinning, pinned, failed) + */ status?: Status[]; + /** + * Maximum number of results per page + */ limit?: number; + /** + * Pagination cursor for listing results + */ cursor?: string; } @@ -31,11 +55,29 @@ export interface RemoteLsOptions extends AbortOptions { * Includes extra metadata supported by the remote pinning service */ export interface RemotePin { + /** + * IPFS Content Identifier + */ cid: CID; + /** + * Name for the pin or filter + */ name?: string; + /** + * Current status (queued, pinning, pinned, failed) + */ status: Status; + /** + * ISO timestamp of creation + */ created: Date; + /** + * Size in bytes + */ size?: number; + /** + * Key-value metadata to attach to the pin + */ metadata?: Record; } diff --git a/libs/pinner/src/upload/base-upload.ts b/libs/pinner/src/upload/base-upload.ts index 980169cf5..7994e7c82 100644 --- a/libs/pinner/src/upload/base-upload.ts +++ b/libs/pinner/src/upload/base-upload.ts @@ -199,8 +199,17 @@ export abstract class BaseUploadHandler { async #addFileToUppy( uppy: Uppy, normalized: { + /** + * List of file manager items + */ data: File | ReadableStream; + /** + * Name for the pin or filter + */ name: string; + /** + * MIME type or content type + */ type: string; }, size?: number, diff --git a/libs/pinner/src/upload/car.ts b/libs/pinner/src/upload/car.ts index d465f815e..8c8c8ebc5 100644 --- a/libs/pinner/src/upload/car.ts +++ b/libs/pinner/src/upload/car.ts @@ -18,14 +18,32 @@ import { import { FILE_EXTENSION_CAR, MIME_TYPE_CAR } from "@/types/mime-types"; export interface CarPreprocessOptions { + /** + * Name for the pin or filter + */ name?: string; + /** + * Progress callback for preprocessing + */ onProgress?: (percentage: number) => void; + /** + * AbortSignal to cancel the operation + */ signal?: AbortSignal; } export interface CarPreprocessResult { + /** + * Preprocessed CAR data as a readable stream + */ carStream: ReadableStream; + /** + * Root CID of the CAR file + */ rootCid: string; + /** + * Size in bytes + */ size: bigint; } @@ -95,6 +113,9 @@ async function* fileSource( signal?: AbortSignal, ): AsyncGenerator<{ content: AsyncIterable | undefined; + /** + * File path within the pin + */ path: string; }> { const seenDirs = new Set(); diff --git a/libs/pinner/src/upload/manager.ts b/libs/pinner/src/upload/manager.ts index ddb635cc3..74474d80e 100644 --- a/libs/pinner/src/upload/manager.ts +++ b/libs/pinner/src/upload/manager.ts @@ -36,6 +36,9 @@ import { calculateStreamSize, streamToBlob } from "../utils/stream"; import { EmptyFileError } from "../errors"; import { type UploadInputObject } from "./normalize"; +/** + * Handles file uploads via XHR or TUS protocol based on file size. + */ export class UploadManager { private config: PinnerConfig; private xhrHandler: XHRUploadHandler; @@ -44,6 +47,10 @@ export class UploadManager { private uploadLimit: number = TUS_SIZE_THRESHOLD; // Default to 100 MB private limitFetched: boolean = false; + /** + * Create a new UploadManager. + * @param config SDK configuration + */ constructor(config: PinnerConfig) { this.config = config; this.xhrHandler = new XHRUploadHandler(config); @@ -55,6 +62,9 @@ export class UploadManager { }); } + /** + * Fetch the upload size limit from the API. Falls back to 100 MB on failure. + */ async fetchUploadLimit(): Promise { if (this.limitFetched) { return this.uploadLimit; @@ -74,10 +84,18 @@ export class UploadManager { return this.uploadLimit; } + /** + * Get the cached upload size limit (in bytes). Call fetchUploadLimit() first. + */ getUploadLimit(): number { return this.uploadLimit; } + /** + * Upload a file or stream to IPFS. + * @param input File, stream, or upload object + * @param options Upload configuration + */ async upload( input: UploadInput, options?: UploadOptions, @@ -86,6 +104,11 @@ export class UploadManager { return this.#uploadInput(input, options); } + /** + * Upload a CAR file or stream directly without preprocessing. + * @param input CAR file or stream + * @param options Upload configuration + */ async uploadCar( input: File | ReadableStream, options?: UploadOptions, @@ -342,6 +365,11 @@ export class UploadManager { } } + /** + * Upload an array of files as an IPFS directory. + * @param files Files to upload + * @param options Upload configuration + */ async uploadDirectory( files: File[], options?: UploadOptions, diff --git a/libs/pinner/src/upload/normalize.ts b/libs/pinner/src/upload/normalize.ts index d63b41006..56ae7cb3b 100644 --- a/libs/pinner/src/upload/normalize.ts +++ b/libs/pinner/src/upload/normalize.ts @@ -6,6 +6,9 @@ import { } from "@/types/mime-types"; export interface NormalizedUploadInput { + /** + * List of file manager items + */ data: File | ReadableStream; name: string; type: string; @@ -13,6 +16,9 @@ export interface NormalizedUploadInput { } export interface UploadInputObject { + /** + * List of file manager items + */ data: ReadableStream; name: string; type: string;