Other Functions

The following functions are available globally.

Quartermaster Validation

Username Validation

  • Three differernt POST structs contain username fields; this fn exists to ensure they all validate the username the same way. This fn is designed to return a list of validation failure strings–if it returns an empty array the username is valid.

    Declaration

    Swift

    private func usernameValidations(username: String) -> [String]
  • Parses an ISO 8601 internet date-time, with or without fractional seconds. Swiftarr always emits fractional seconds but accepts timestamps that omit them.

    Declaration

    Swift

    @available(macOS 10.13, *)
    private func dateFromISO8601(_ string: String) -> Date?
  • Writes a durable log entry for a notification event that’s about to be (or was just) pushed to live sockets–see GET /api/v3/notification/log. One NotificationLogEntry row is created for the event itself, plus one NotificationRecipient row per user in recipients, so a broadcast notification sent to many users doesn’t duplicate its content once per recipient.

    The log is a convenience history, not the source of truth for notification delivery, so a failure here is logged and swallowed rather than thrown–it should never prevent the actual notification from going out.

    Declaration

    Swift

    func logNotification(type: NotificationType, info: String, recipients: [UUID], db: Database, logger: Logger) async -> UUID?

    Return Value

    The new entry’s ID (to be included in the live socket push as notificationID), or nil if there were no recipients or the write failed.

  • Returns the file system path for the given image filename. Makes sure all image directories in the path exist.

    Currently, this fn returns paths in the form: /images///.jpg where “xx” is the first 2 characters of the filename.

    Declaration

    Swift

    func getImagePath(for image: String, format: String? = nil, usage: ImageUsage, size: ImageSizeGroup) throws -> URL
  • Returns true when the image data is a format that can carry animation (GIF or WebP).

    Declaration

    Swift

    func isAnimatableFormat(_ data: Data) -> Bool
  • Detects the file extension for image data. Returns “jpg” for unrecognized formats.

    Declaration

    Swift

    func detectExtension(_ data: Data) -> String
  • Loads an image from data, auto-detecting format and applying EXIF rotation. Alpha is preserved — flattening only happens at JPEG export sites, since PNG/GIF/WebP outputs can carry transparency.

    Declaration

    Swift

    func loadImageFromData(_ data: Data) throws -> SwiftarrImage

    Parameters

    data

    The image data to load

    Return Value

    The loaded image, ready for processing

  • Resizes an image to thumbnail size and encodes it in the requested format. Returns nil if resize fails. JPEG output flattens any alpha onto a white background; PNG/GIF/WebP outputs preserve transparency.

    Declaration

    Swift

    func thumbnailData(from image: SwiftarrImage, format: String) throws -> Data?
  • Creates a thumbnail from an image and writes it to disk in the specified format. Silently skips thumbnail creation if resize fails, matching the original behavior.

    Throws

    Errors from export or file write operations

    Declaration

    Swift

    func createThumbnail(from image: SwiftarrImage, to thumbPath: URL, format: String, logger: Logger) throws

    Parameters

    image

    The source image to create a thumbnail from

    thumbPath

    The file path where the thumbnail should be saved

    format

    The output format extension (“jpg”, “png”, etc.)

    logger

    Used to report a failed resize

  • Validates, processes and stores one image: full-size and thumbnail versions, in the image store. Returns the stored filename.

    This is the single place image processing happens, shared by uploads (processImage) and anything that needs to store an image without a Request, such as migrations that seed records with images. The format is detected from the data’s contents, not any filename. PNG/GIF/WebP are kept in their own format when unmodified; everything else (JPEG, HEIC, AVIF, …) and anything we had to resize or crop is re-encoded as a JPEG, so the stored bytes always match the stored filename’s extension.

    This is synchronous and does blocking file and image work, so request handlers should call it from a thread pool.

    Declaration

    Swift

    func processImageData(_ data: Data, usage: ImageUsage, logger: Logger) throws -> String

Utilities