import type { RepresentationMetadata } from '../http/representation/RepresentationMetadata'; import { DC } from '../util/Vocabularies'; import { getETag } from './Conditions'; import type { Conditions } from './Conditions'; export interface BasicConditionsOptions { matchesETag?: string[]; notMatchesETag?: string[]; modifiedSince?: Date; unmodifiedSince?: Date; } /** * Stores all the relevant Conditions values and matches them based on RFC7232. */ export class BasicConditions implements Conditions { public readonly matchesETag?: string[]; public readonly notMatchesETag?: string[]; public readonly modifiedSince?: Date; public readonly unmodifiedSince?: Date; public constructor(options: BasicConditionsOptions) { this.matchesETag = options.matchesETag; this.notMatchesETag = options.notMatchesETag; this.modifiedSince = options.modifiedSince; this.unmodifiedSince = options.unmodifiedSince; } public matchesMetadata(metadata?: RepresentationMetadata): boolean { if (!metadata) { // RFC7232: ...If-Match... If the field-value is "*", the condition is false if the origin server // does not have a current representation for the target resource. return !this.matchesETag?.includes('*'); } const modified = metadata.get(DC.terms.modified); const modifiedDate = modified ? new Date(modified.value) : undefined; const etag = getETag(metadata); return this.matches(etag, modifiedDate); } public matches(eTag?: string, lastModified?: Date): boolean { // RFC7232: ...If-None-Match... If the field-value is "*", the condition is false if the origin server // has a current representation for the target resource. if (this.notMatchesETag?.includes('*')) { return false; } if (eTag) { if (this.matchesETag && !this.matchesETag.includes(eTag) && !this.matchesETag.includes('*')) { return false; } if (this.notMatchesETag?.includes(eTag)) { return false; } } if (lastModified) { if (this.modifiedSince && lastModified < this.modifiedSince) { return false; } if (this.unmodifiedSince && lastModified > this.unmodifiedSince) { return false; } } return true; } }