All files / lib/attachment-archive package-activity.ts

100% Statements 25/25
92.3% Branches 12/13
100% Functions 16/16
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129                                                            21x 32x 32x 32x       30x           30x                   28x 1x     27x 1x     26x                   21x 30x           30x   10x         6x     4x     28x 28x 28x   28x                                                 1x 2x         2x    
import { opensearch } from "shared-types";
import { getPackageActivityLabelSlug } from "shared-utils";
 
import { buildSectionArchiveFolderName, getSectionArchiveRootFolderName } from "./archive-manifest";
import { AttachmentArchiveSectionInfo, AttachmentArchiveSourceAttachment } from "./types";
 
export type AttachmentArchiveChangelogDocument = {
  id: string;
  packageId?: string;
  event: opensearch.changelog.Document["event"];
  timestamp?: string | number;
  submitterName?: string;
  attachments?: opensearch.changelog.Document["attachments"];
  additionalInformation?: string | null;
  detailMessage?: string;
  isAdminChange?: boolean;
};
 
export type AttachmentArchiveChangelogItem = Omit<opensearch.changelog.ItemResult, "_source"> & {
  _source: AttachmentArchiveChangelogDocument;
};
 
export interface AttachmentArchiveSectionDescriptor extends AttachmentArchiveSectionInfo {
  packageId: string;
  attachments: AttachmentArchiveSourceAttachment[];
}
 
export function getArchiveEligibleChangelogEntries(
  changelog: AttachmentArchiveChangelogItem[],
): AttachmentArchiveChangelogDocument[] {
  return changelog
    .map((item) => item._source)
    .filter((document): document is AttachmentArchiveChangelogDocument => Boolean(document))
    .filter((document) => !document.isAdminChange);
}
 
function getArchiveEntryTimestamp(entry: AttachmentArchiveChangelogDocument) {
  return typeof entry.timestamp === "number" ? entry.timestamp : undefined;
}
 
function getSectionAttachments(
  entry: AttachmentArchiveChangelogDocument,
): AttachmentArchiveSourceAttachment[] {
  return (entry.attachments || []).map((attachment) => ({
    bucket: attachment.bucket,
    filename: attachment.filename,
    key: attachment.key,
    title: attachment.title,
    uploadDate: attachment.uploadDate,
  }));
}
 
function getArchiveSectionLabel(entry: AttachmentArchiveChangelogDocument): string {
  if (entry.id.endsWith("-draft-updated-activity")) {
    return "draft-updated";
  }
 
  if (entry.id.endsWith("-draft-activity")) {
    return "draft-created";
  }
 
  return getPackageActivityLabelSlug(entry.event);
}
 
export function buildAttachmentArchiveSections({
  packageId,
  changelog,
}: {
  packageId: string;
  changelog: AttachmentArchiveChangelogItem[];
}): AttachmentArchiveSectionDescriptor[] {
  return getArchiveEligibleChangelogEntries(changelog)
    .map((entry, originalIndex) => ({
      attachments: getSectionAttachments(entry),
      entry,
      originalIndex,
      timestamp: getArchiveEntryTimestamp(entry),
    }))
    .filter(({ attachments }) => attachments.length > 0)
    .sort((left, right) => {
      if (
        left.timestamp !== undefined &&
        right.timestamp !== undefined &&
        left.timestamp !== right.timestamp
      ) {
        return left.timestamp - right.timestamp;
      }
 
      return left.originalIndex - right.originalIndex;
    })
    .map(({ attachments, entry }, index) => {
      const sectionNumber = index + 1;
      const sectionLabel = getArchiveSectionLabel(entry);
      const sectionFolderName = buildSectionArchiveFolderName({ sectionNumber, sectionLabel });
 
      return {
        packageId,
        attachments,
        sectionId: entry.id,
        sectionNumber,
        sectionLabel,
        sectionFolderName,
        rootFolderName: getSectionArchiveRootFolderName({
          packageId,
          sectionNumber,
          sectionLabel,
        }),
      };
    });
}
 
export function getAttachmentArchiveSectionById({
  packageId,
  changelog,
  sectionId,
}: {
  packageId: string;
  changelog: AttachmentArchiveChangelogItem[];
  sectionId: string;
}): AttachmentArchiveSectionDescriptor | undefined {
  return buildAttachmentArchiveSections({ packageId, changelog }).find(
    (section) => section.sectionId === sectionId,
  );
}
 
export function hasArchiveableAttachments(changelog: AttachmentArchiveChangelogItem[]): boolean {
  return buildAttachmentArchiveSections({ packageId: "_", changelog }).length > 0;
}