ministry-platform-provider
Version:
TypeScript client library for Ministry Platform API integration
336 lines (308 loc) • 13 kB
text/typescript
import { MinistryPlatformClient } from "./core/ministryPlatformClient.js";
import { TableService } from "./services/tableService.js";
import { ProcedureService } from "./services/procedureService.js";
import { CommunicationService } from "./services/communicationService.js";
import { MetadataService } from "./services/metadataService.js";
import { DomainService } from "./services/domainService.js";
import { FileService } from "./services/fileService.js";
import {
TableQueryParams,
ProcedureInfo,
CommunicationInfo,
Communication,
MessageInfo,
DomainInfo,
GlobalFilterItem,
GlobalFilterParams,
TableRecord,
FileDescription,
FileUploadParams,
FileUpdateParams,
TableMetadata,
QueryParams
} from "./Interfaces/mpProviderInterfaces.js";
/**
* ministryPlatformProvider - Core Provider Singleton
*
* Central orchestrator for all Ministry Platform operations using the Singleton pattern.
* Manages service instances and provides a unified interface for:
* - Table operations (CRUD)
* - Stored procedure execution
* - Communication/messaging
* - File management
* - Metadata operations
* - Domain configuration
*
* All services share a single MinistryPlatformClient instance for consistent
* authentication and configuration management.
*/
export class ministryPlatformProvider {
// Singleton instance storage
private static instance: ministryPlatformProvider;
// Core client for HTTP operations and authentication
private client: MinistryPlatformClient;
// Specialized service instances for different domains of functionality
private tableService: TableService; // CRUD operations for all tables
private procedureService: ProcedureService; // Stored procedure execution
private communicationService: CommunicationService; // Email/SMS communications
private metadataService: MetadataService; // Schema and metadata operations
private domainService: DomainService; // Domain configuration and filters
private fileService: FileService; // File upload/download operations
/**
* Private constructor for Singleton pattern
* Initializes the core client and all specialized service instances
*/
private constructor() {
// Create the core HTTP client with authentication management
this.client = new MinistryPlatformClient();
// Initialize all service instances with shared client
this.tableService = new TableService(this.client);
this.procedureService = new ProcedureService(this.client);
this.communicationService = new CommunicationService(this.client);
this.metadataService = new MetadataService(this.client);
this.domainService = new DomainService(this.client);
this.fileService = new FileService(this.client);
}
/**
* Returns the singleton instance of the Ministry Platform provider
* Creates the instance on first call, returns existing instance on subsequent calls
* @returns The singleton ministryPlatformProvider instance
*/
public static getInstance(): ministryPlatformProvider {
// Create instance if it doesn't exist (lazy initialization)
if (!this.instance) {
this.instance = new ministryPlatformProvider();
}
return this.instance;
}
// Domain Service Methods
/**
* Returns the basic information about the current domain.
* @returns Promise with the domain information
*/
public async getDomainInfo(): Promise<DomainInfo> {
return this.domainService.getDomainInfo();
}
/**
* Returns the lookup values to be used as global filters.
* @param params Optional parameters for the global filters request
* @returns Promise with an array of global filter items
*/
public async getGlobalFilters(params?: GlobalFilterParams): Promise<GlobalFilterItem[]> {
return this.domainService.getGlobalFilters(params);
}
// Metadata Service Methods
/**
* Triggers an update of the metadata cache on all servers and in all applications.
* @returns Promise with the response from the API
*/
public async refreshMetadata(): Promise<void> {
return this.metadataService.refreshMetadata();
}
/**
* Returns the list of tables available to the current user with basic metadata.
* @param search Optional search term to filter tables
* @returns Promise with an array of TableInfo objects
*/
public async getTables(search?: string): Promise<TableMetadata[]> {
return this.metadataService.getTables(search);
}
// Table Service Methods
/**
* Returns the list of records from the specified table satisfying the provided search criteria.
* @param table Table to retrieve records from
* @param params Query parameters for filtering, sorting, etc.
* @returns Promise with an array of records
*/
public async getTableRecords<T>(table: string, params?: TableQueryParams): Promise<T[]> {
return this.tableService.getTableRecords<T>(table, params);
}
/**
* Creates new records in the specified table.
* @param table Table where records need to be created
* @param records Array of records to be added to the table
* @param params Additional query parameters
* @returns Promise with the created records
*/
public async createTableRecords<T extends TableRecord = TableRecord>(
table: string,
records: T[],
params?: Pick<TableQueryParams, '$select' | '$userId'>
): Promise<T[]> {
return this.tableService.createTableRecords<T>(table, records, params);
}
/**
* Updates provided records in the specified table.
* @param table Table where records need to be updated
* @param records Array of records to be updated in the table
* @param params Additional query parameters
* @returns Promise with the updated records
*/
public async updateTableRecords<T extends TableRecord = TableRecord>(
table: string,
records: T[],
params?: Pick<TableQueryParams, '$select' | '$userId' | '$allowCreate'>
): Promise<T[]> {
return this.tableService.updateTableRecords<T>(table, records, params);
}
/**
* Deletes multiple records from the specified table.
* @param table Table where records need to be deleted
* @param ids Array of identifiers corresponding to records to be deleted
* @param params Additional query parameters
* @returns Promise with the deleted records
*/
public async deleteTableRecords<T extends TableRecord = TableRecord>(
table: string,
ids: number[],
params?: Pick<TableQueryParams, '$select' | '$userId'>
): Promise<T[]> {
return this.tableService.deleteTableRecords<T>(table, ids, params);
}
// Procedure Service Methods
/**
* Returns the list of procedures available to the current user with basic metadata.
* @param search Optional search term to filter procedures
* @returns Promise with an array of ProcedureInfo objects
*/
public async getProcedures(search?: string): Promise<ProcedureInfo[]> {
return this.procedureService.getProcedures(search);
}
/**
* Executes the requested stored procedure retrieving parameters from the query string.
* @param procedure Stored procedure name
* @param params Query parameters to pass to the procedure
* @returns Promise with the procedure results
*/
public async executeProcedure(
procedure: string,
params?: QueryParams
): Promise<unknown[][]> {
return this.procedureService.executeProcedure(procedure, params);
}
/**
* Executes the requested stored procedure with provided parameters in the request body.
* @param procedure Stored procedure name
* @param parameters Parameters to be used for calling stored procedure
* @returns Promise with the procedure results
*/
public async executeProcedureWithBody(
procedure: string,
parameters: Record<string, unknown>
): Promise<unknown[][]> {
return this.procedureService.executeProcedureWithBody(procedure, parameters);
}
// Communication Service Methods
/**
* Creates a new communication, immediately renders it and schedules for delivery.
* Supports both simple JSON communication and multipart form data with file attachments.
* @param communication Communication information object
* @param attachments Optional array of file attachments
* @returns Promise with the created communication
*/
public async createCommunication(
communication: CommunicationInfo,
attachments?: File[]
): Promise<Communication> {
return this.communicationService.createCommunication(communication, attachments);
}
/**
* Creates email messages from the provided information and immediately schedules them for delivery.
* Supports both simple JSON message and multipart form data with file attachments.
* @param message Message information object
* @param attachments Optional array of file attachments
* @returns Promise with the created communication
*/
public async sendMessage(
message: MessageInfo,
attachments?: File[]
): Promise<Communication> {
return this.communicationService.sendMessage(message, attachments);
}
// File Service Methods
/**
* Returns the metadata (descriptions) of the files attached to the specified record.
* @param table Table name where the record exists
* @param recordId ID of the record to get files for
* @param defaultOnly Optional flag to return only default files
* @returns Promise with an array of file descriptions
*/
public async getFilesByRecord(
table: string,
recordId: number,
defaultOnly?: boolean
): Promise<FileDescription[]> {
return this.fileService.getFilesByRecord(table, recordId, defaultOnly);
}
/**
* Uploads and attaches multiple files to the specified record.
* @param table Table name where the record exists
* @param recordId ID of the record to attach files to
* @param files Array of files to upload
* @param params Optional upload parameters
* @returns Promise with an array of uploaded file descriptions
*/
public async uploadFiles(
table: string,
recordId: number,
files: File[],
params?: FileUploadParams
): Promise<FileDescription[]> {
return this.fileService.uploadFiles(table, recordId, files, params);
}
/**
* Updates the content and/or metadata of the file corresponding to provided identifier.
* @param fileId ID of the file to update
* @param file Optional new file content
* @param params Optional update parameters
* @returns Promise with the updated file description
*/
public async updateFile(
fileId: number,
file?: File,
params?: FileUpdateParams
): Promise<FileDescription> {
return this.fileService.updateFile(fileId, file, params);
}
/**
* Deletes the file corresponding to provided identifier.
* @param fileId ID of the file to delete
* @param userId Optional user ID for auditing
* @returns Promise that resolves when file is deleted
*/
public async deleteFile(
fileId: number,
userId?: number
): Promise<void> {
return this.fileService.deleteFile(fileId, userId);
}
/**
* Returns the content of the file corresponding to provided globally unique identifier.
* This method does NOT require authentication.
* @param uniqueFileId Globally unique file identifier
* @param thumbnail Optional flag to get thumbnail version
* @returns Promise with the file content as a Blob
*/
public async getFileContentByUniqueId(
uniqueFileId: string,
thumbnail?: boolean
): Promise<Blob> {
return this.fileService.getFileContentByUniqueId(uniqueFileId, thumbnail);
}
/**
* Returns the file metadata (description) corresponding to provided database identifier.
* @param fileId Database ID of the file
* @returns Promise with the file description
*/
public async getFileMetadata(fileId: number): Promise<FileDescription> {
return this.fileService.getFileMetadata(fileId);
}
/**
* Returns the file metadata (description) corresponding to provided globally unique identifier.
* @param uniqueFileId Globally unique file identifier
* @returns Promise with the file description
*/
public async getFileMetadataByUniqueId(uniqueFileId: string): Promise<FileDescription> {
return this.fileService.getFileMetadataByUniqueId(uniqueFileId);
}
}