/** * Core metadata about a single document version. */ export interface ObjSnapshot { lastModified: string; snapshotId: string; } /** * Extended Grist metadata about a single document version. Names of fields are kept * short since there is a tight limit on total metadata size in S3. */ export interface ObjMetadata { t?: string; // timestamp tz?: string; // timezone h?: string; // actionHash n?: number; // actionNum label?: string; } export interface ObjSnapshotWithMetadata extends ObjSnapshot { metadata?: ObjMetadata; } /** * Information about a single document snapshot in S3, including a Grist docId. */ export interface DocSnapshot extends ObjSnapshotWithMetadata { docId: string; } /** * A collection of document snapshots. Most recent snapshots first. */ export interface DocSnapshots { snapshots: DocSnapshot[]; } /** * Metadata format for external storage like S3 and Azure. * The only difference is that external metadata values must be strings. * * For S3, there are restrictions on total length of metadata (2 KB). * See: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#UserMetadata */ type ExternalMetadata = Record; /** * Convert metadata from internal Grist format to external storage format (string values). */ export function toExternalMetadata(metadata: ObjMetadata): ExternalMetadata { const result: ExternalMetadata = {}; for (const [key, val] of Object.entries(metadata)) { if (val !== undefined) { result[key] = String(val); } } return result; } /** * Select metadata controlled by Grist, and convert to expected formats. */ export function toGristMetadata(metadata: ExternalMetadata): ObjMetadata { const result: ObjMetadata = {}; for (const key of ['t', 'tz', 'h', 'label'] as const) { if (metadata[key]) { result[key] = metadata[key]; } } if (metadata.n) { result.n = parseInt(metadata.n, 10); } return result; }