UNPKG

fhir-package-installer

Version:

A utility module for downloading, indexing, caching, and managing FHIR packages from the FHIR Package Registry and Simplifier

340 lines (330 loc) 13.9 kB
import { Logger, FhirPackageIdentifier, PackageIndex, PackageManifest } from '@outburn/types'; export { FileInPackageIndex, PackageIndex, PackageManifest } from '@outburn/types'; /** * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved * Project name: FHIR-Package-Installer */ /** * A basic interface for a resource file in a package */ interface PackageResource { id: string; resourceType: string; [key: string]: any | any[]; } /** * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved * Project name: FHIR-Package-Installer */ /** * The structure of the FPI constructor config object. */ interface FpiConfig { logger?: Logger; registryUrl?: string; registryToken?: string; cachePath?: string; skipExamples?: boolean; allowHttp?: boolean; requestTimeoutMs?: number; extractTimeoutMs?: number; /** * TTL (ms) for cached registry lookups (unversioned package documents, dist-tags, etc). * Default: 30 minutes. */ registryTtlMs?: number; } /** * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved * Project name: FHIR-Package-Installer */ /** * Options for the downloadPackage function. * @param destination The directory path where the package should be saved or extracted. * Defaults to the current working directory. * @param overwrite Whether to overwrite the existing package if it already exists. * Defaults to false. * @param extract Whether to extract the package after downloading. * If true, the tarball will be extracted into a subdirectory of `destination`. */ interface DownloadPackageOptions { destination?: string; overwrite?: boolean; extract?: boolean; } /** * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved * Project name: FHIR-Package-Installer */ /** * Options for installing a package. * @param packageId Specifies a custom package ID to be installed. Defaults to the package identifier from the `package.json` file. * @param override Whether to override the existing package if it already exists. Defaults to false. * @param installDependencies Whether to install dependencies of the package. Defaults to false. */ interface InstallPackageOptions { packageId?: string | FhirPackageIdentifier; override?: boolean; installDependencies?: boolean; } /** * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved * Project name: FHIR-Package-Installer */ type GetDependenciesOptions = { rootPackage?: string | FhirPackageIdentifier; explicitImplicitVersions?: ReadonlyMap<string, string>; includePlanningFallbacks?: boolean; }; declare class FhirPackageInstaller { private logger; private registryUrl; private registryDisabled; private registryToken?; private requestTimeoutMs; private extractTimeoutMs; private registryTtlMs; /** * Path to the FHIR package cache directory. * This directory is used to store downloaded and extracted FHIR packages. * If the directory does not exist, it will be created. * Default location follows FHIR spec: * - User apps: ~/.fhir/packages (Windows: C:\Users\<user>\.fhir\packages) * - System services: /var/lib/.fhir/packages (Windows: %ProgramData%\.fhir\packages) */ private cachePath; private skipExamples; private allowHttp; private resolvingImplicitDeps; private installingPackages; private formatPackageForDebug; private formatMaterializationStatusForDebug; private describePackageInstallWaitState; private formatElapsedMs; private withDebugTiming; private getPackageKey; private normalizeDependencies; constructor(config?: FpiConfig); /** * Determines the default FHIR package cache path based on FHIR specifications: * https://confluence.hl7.org/display/FHIR/FHIR+Package+Cache * * For user applications: * - Windows: C:\Users\<username>\.fhir\packages * - Unix/Linux: ~/.fhir/packages * * For system services (daemons): * - Windows: %ProgramData%\.fhir\packages (typically C:\ProgramData\.fhir\packages) * - Unix/Linux: /var/lib/.fhir/packages * * Behavior can be overridden via the FHIR_PACKAGE_CACHE_MODE environment variable: * - FHIR_PACKAGE_CACHE_MODE=system -> always use system service paths * - FHIR_PACKAGE_CACHE_MODE=user -> always use user paths */ private getDefaultCachePath; private withDiskLock; private tryWithDiskLock; private ensureDiskCacheSubdir; private createWorkingTempDir; private getPackageInstallLockKey; private getInstallParticipantDir; private withInstallParticipant; private countActiveInstallParticipants; private isPackageInstallLockHeld; private waitForPeerDependencyHandoff; private withPackageInstallLock; private tryWithPackageInstallLock; private getStagingPath; private cleanupStaleStagingDirectories; private createStagingDirectory; private buildPackageIndexFromPackageDir; private normalizeIndexEntry; private normalizePackageIndex; private persistMaterializedPackageIndex; private tryMaterializeLegacyPackageIndex; private materializePackageIndex; private getPackageMaterializationStatus; private stagePackageForPublish; private isAlreadyExistsError; private isRetryableStagePublishError; private getDiskCacheKeyPrefix; private readDiskCacheJson; private writeDiskCacheJson; private writeDiskCacheJsonNoTtl; private getDiskRegistryMetadataCachePath; private getDiskIndexCachePath; private getDiskTarballCacheKey; private getDiskTarballCachePaths; private readDiskTarballCache; private writeDiskTarballDoneMarker; private getIndexMemKey; private getIndexDiskLockKey; private getMaterializationMarkerPath; private writeMaterializationMarker; private hasFreshMaterializationMarker; private isRegistryDisabled; private formatRegistryDisabledMessage; private hasShallowInstalledPackage; private isStrictlyMaterialized; private hasReadableManifest; private collectMissingPackages; private collectPlannedDependencyClosure; private withRetries; /** * Takes a FhirPackageIdentifier Object and returns the corresponding directory name of the package * @param packageObject A PackageObject with both name and version keys * @returns (string) Directory name in the standard format `name#version` */ private toDirName; /** * Takes a FhirPackageIdentifier Object and returns the path to the package folder in the cache * @param packageObject A FhirPackageIdentifier Object with both name and version keys * @returns The full path to the package directory */ getPackageDirPath(packageId: FhirPackageIdentifier | string): Promise<string>; /** * Get the full path to the .fpi.index.json file in the package folder * @param packageObject A FhirPackageIdentifier Object with both name and version keys * @returns (string) The path to the package index file */ private getPackageIndexPath; /** * Scans a package folder and generates a new `.fpi.index.json` file * @param packageObject The package identifier object * @returns PackageIndex */ private generatePackageIndex; /** * Generates HTTP options including authorization header for registry requests * @param url The URL being requested * @returns HTTP options object with headers if needed */ private getHttpOptions; private fetchJson; private fetchStream; private getPackageDataFromRegistry; private getTarballUrl; private downloadFile; private downloadTarball; private getOrDownloadDiskCachedTarball; /** * Extracts a tarball to a temporary directory and generates a new `.fpi.index.json` file. * The tarball can be a file path or a stream. * @param src The source tarball, either a file path or a Readable stream. * @returns The path to the temporary directory where the package was extracted. */ private extractTarball; private downloadAndExtractTarball; /** * Caches the package in the FHIR package cache directory. * If the package is already installed, it will not be reinstalled. * @param packageObject The package identifier object * @param src The source path of the package to be cached * @param move Whether to move the package to the cache or copy it. Defaults to **true**. * @returns The path to the cached package directory */ private cachePackage; /** * Extracts the version of the package from a raw package identifier string. * Supported formats: `name@version`, `name#version`, or just `name` * @param packageId Raw package identifier string * @returns The version part or 'latest' if not supplied */ private getVersionFromPackageString; isInstalled(packageId: FhirPackageIdentifier | string, options?: { deep?: boolean; }): Promise<boolean>; getPackageIndexFile(packageId: FhirPackageIdentifier | string): Promise<PackageIndex>; checkLatestPackageDist(packageName: string): Promise<string>; toPackageObject(packageId: string | FhirPackageIdentifier): Promise<FhirPackageIdentifier>; private getImplicitEffectiveCacheKey; private getImplicitPlanningCacheKeys; private readManifestFile; private waitForManifestDuringActiveInstall; getManifest(packageId: string | FhirPackageIdentifier): Promise<PackageManifest>; /** * Get the path to the FHIR package cache directory. * This directory is used to store downloaded and extracted FHIR packages. * If the directory does not exist, it will be created. * @returns {string} The path to the FHIR package cache directory */ getCachePath(): string; /** * Get the logger instance used by this FhirPackageInstaller. */ getLogger(): Logger; /** * Scan cache directory for installed versions of a package * @param packageName Package name to search for * @returns Array of installed versions sorted in descending order (latest first) */ private getInstalledVersions; /** * Resolve an implicit package dependency to an effective version that is installed and manifest-valid. * * This is the materializing resolver used by code paths that need a real readable package entry, * not just a plannable version candidate. */ protected resolveImplicitPackageVersionWithFallbacks(packageName: string): Promise<string>; private resolveImplicitPackageVersionForPlanning; /** * Get implicit dependencies for a given package * @param packageObject The package to check for implicit dependencies * @returns Promise resolving to record of implicit dependencies */ private getImplicitDependencies; /** * Get explicit dependencies from package.json only (internal use) * @param packageObject The package to get explicit dependencies for * @returns Promise resolving to record of explicit dependencies only */ private getExplicitDependencies; private getExplicitDependenciesFromTarballManifest; private getExplicitDependenciesFromRegistryMetadata; private getExplicitDependenciesForPlanning; private getDependenciesForPlanning; private collectExplicitDependencyClosure; /** * Get all dependencies for a package, including both explicit dependencies from package.json * and automatic implicit dependencies for core FHIR packages. * * For core FHIR packages (hl7.fhir.r3.core, hl7.fhir.r4.core, hl7.fhir.r5.core), * this automatically includes essential terminology and extension packages. * * @param packageObject The package to get dependencies for * @param options Optional root/context information for graph-aware implicit package version selection * @returns Promise resolving to record of all dependencies (explicit + implicit) */ getDependencies(packageObject: FhirPackageIdentifier, options?: GetDependenciesOptions): Promise<Record<string, string>>; install(packageId: string | FhirPackageIdentifier): Promise<boolean>; private materializePackageWithoutDependencies; private installPackageDependencies; /** * Installs a package from a local file or directory. * The package can be a tarball file or a directory containing the package files. * @param src The path to the local package file or directory. * @param options Options for installing the package. * @returns A promise that resolves to true if the package was installed successfully, * or false if it was already installed. */ installLocalPackage(src: string, options?: InstallPackageOptions): Promise<boolean>; /** * Downloads a package tarball and optionally extracts it to a destination directory. * * Behavior: * - If `extract` is false or omitted: downloads the tarball as a .tgz file to the destination directory. * - If `extract` is true: downloads and extracts the package into a subdirectory of the destination path. * * @param packageId A package identifier string or a FhirPackageIdentifier object. * @param options Options controlling the download and extraction behavior. * @returns * - If `extract` is false: the full path to the downloaded tarball file. * - If `extract` is true: the full path to the extracted package directory. */ downloadPackage(packageId: string | FhirPackageIdentifier, options?: DownloadPackageOptions): Promise<string>; } /** * Default instance export for convenience */ declare const fpi: FhirPackageInstaller; export { type DownloadPackageOptions, FhirPackageInstaller, type FpiConfig, type InstallPackageOptions, type PackageResource, fpi as default };