import { type Maybe } from '@dereekb/util'; import { type FirestoreModelKey, type FirestoreDocumentAccessor } from '../../common'; import { type StorageFileGroupDocument, type StorageFileGroup, type StorageFileGroupEmbeddedFile } from './storagefile'; import { type StorageFileId } from './storagefile.id'; /** * Reference to a StorageFileGroup document, either directly or by the related model key. * * Used by utility functions that need to load or update a StorageFileGroup but accept * either a pre-loaded document or a model key for lazy loading. */ export interface StorageFileGroupDocumentReferencePair { /** * StorageFileGroupDocument to update. * * If not provided, please provide the storageFileGroupRelatedModelKey. If neither value is provided, an error will be thrown. */ readonly storageFileGroupDocument?: Maybe; /** * Key of the model the storage file group is expected to be associated with. Used if StorageFileGroupDocument is not provided already. */ readonly storageFileGroupRelatedModelKey?: Maybe; } /** * Resolves a {@link StorageFileGroupDocumentReferencePair} to a concrete {@link StorageFileGroupDocument}. * * If a document is provided directly, it is returned as-is. Otherwise, the related model key * is converted to a group ID via {@link storageFileGroupIdForModel} and loaded from the accessor. * * @param input - reference pair containing either a document or a related model key * @param accessor - document accessor used to load the group document by ID * @returns the resolved StorageFileGroupDocument * @throws {Error} When neither storageFileGroupDocument nor storageFileGroupRelatedModelKey is provided * * @example * ```ts * const doc = loadStorageFileGroupDocumentForReferencePair( * { storageFileGroupRelatedModelKey: 'notification/abc123' }, * accessor * ); * ``` */ export declare function loadStorageFileGroupDocumentForReferencePair(input: StorageFileGroupDocumentReferencePair, accessor: FirestoreDocumentAccessor): StorageFileGroupDocument; /** * Input for {@link calculateStorageFileGroupEmbeddedFileUpdate}, specifying the current group state * and files to insert/remove. */ export interface CalculateStorageFileGroupEmbeddedFileUpdateInput { readonly storageFileGroup: Pick; readonly insert?: Maybe<(Pick & Partial>)[]>; readonly remove?: Maybe; /** * Whether or not to allow recalculating the regenerate flag even if the current "re" value is true. * * Regenerate will always be true if any files are removed. * * Defaults to false. */ readonly allowRecalculateRegenerateFlag?: Maybe; } /** * Calculates the updated embedded file list and regeneration flag for a StorageFileGroup * after inserting and/or removing files. * * Handles deduplication via {@link ModelRelationUtility.insertCollection}, merging new entries * with existing ones by StorageFile ID. Automatically flags regeneration when files are removed * or when new files haven't been added to the zip yet. * * @param input - current group state, files to insert/remove, and regeneration options * @returns updated `f` (embedded files) and `re` (regeneration flag) * * @example * ```ts * const update = calculateStorageFileGroupEmbeddedFileUpdate({ * storageFileGroup: group, * insert: [{ s: 'newFileId' }], * remove: ['oldFileId'] * }); * // update.f = [...updated file list] * // update.re = true (because a file was removed) * ``` */ export declare function calculateStorageFileGroupEmbeddedFileUpdate(input: CalculateStorageFileGroupEmbeddedFileUpdateInput): Pick; /** * Input for {@link calculateStorageFileGroupRegeneration}. */ export interface CalculateStorageFileGroupRegenerationInput { readonly storageFileGroup: Pick; /** * If true, will force regenerating applicable derived files, even if all content is up to date. */ readonly force?: Maybe; } export interface CalculateStorageFileGroupRegenerationResult { /** * Whether or not the zip file needs to be regenerated. */ readonly regenerateZip?: Maybe; /** * Whether or not any derived StorageFile needs to be regenerated. */ readonly flagRegenerate: boolean; } /** * Determines whether a StorageFileGroup's derived content (e.g., zip files) needs regeneration. * * The zip needs regeneration when: * - `force` is true * - The zip has never been generated (`zat` is unset) and files exist * - Any embedded file has never been included in the zip (`zat` is unset on the entry) * * @param input - group state and optional force flag * @returns the regeneration result indicating whether the zip or other derived files need to be regenerated * * @example * ```ts * const { flagRegenerate, regenerateZip } = calculateStorageFileGroupRegeneration({ * storageFileGroup: group, * force: false * }); * ``` */ export declare function calculateStorageFileGroupRegeneration(input: CalculateStorageFileGroupRegenerationInput): CalculateStorageFileGroupRegenerationResult;