From e24f757f013127ef8281f3c11845ce4e5e053b69 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 20 Dec 2024 00:31:20 -0800 Subject: [PATCH] Add ETag support --- packages/headers/CHANGELOG.md | 1 + .../headers/src/lib/super-headers.test.ts | 29 +++++++++++++++++++ packages/headers/src/lib/super-headers.ts | 22 ++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index fb35713..c0ba583 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -134,6 +134,7 @@ header.getPreferred(['gzip', 'deflate']); // 'gzip' - `connection` - `contentEncoding` - `contentLanguage` + - `etag` - `host` - `location` - `referer` diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index a32ef33..19da6db 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -232,6 +232,11 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Date'), 'Fri, 01 Jan 2021 00:00:00 GMT'); }); + it('handles the etag property', () => { + let headers = new SuperHeaders({ etag: 'abc' }); + assert.equal(headers.get('ETag'), '"abc"'); + }); + it('handles the expires property', () => { let headers = new SuperHeaders({ expires: new Date('2021-01-01T00:00:00Z') }); assert.equal(headers.get('Expires'), 'Fri, 01 Jan 2021 00:00:00 GMT'); @@ -526,6 +531,30 @@ describe('SuperHeaders', () => { assert.equal(headers.date, null); }); + it('supports the etag property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.etag, null); + + headers.etag = 'abc'; + assert.equal(headers.etag, '"abc"'); + + headers.etag = '"def"'; + assert.equal(headers.etag, '"def"'); + + headers.etag = 'W/"def"'; + assert.equal(headers.etag, 'W/"def"'); + + headers.etag = ''; + assert.equal(headers.etag, '""'); + + headers.etag = '""'; + assert.equal(headers.etag, '""'); + + headers.etag = null; + assert.equal(headers.etag, null); + }); + it('supports the expires property', () => { let headers = new SuperHeaders(); diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 2de8db4..771761b 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -72,6 +72,10 @@ interface SuperHeadersPropertyInit { * The [`Date`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date) header value. */ date?: string | DateInit; + /** + * The [`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) header value. + */ + etag?: string; /** * The [`Expires`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires) header value. */ @@ -543,6 +547,24 @@ export class SuperHeaders extends Headers { this.#setDateValue('date', value); } + /** + * The `ETag` header provides a unique identifier for the current version of the resource. + * + * [MDN `ETag` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-2.3) + */ + get etag(): string | null { + return this.get('etag'); + } + + set etag(value: string | undefined | null) { + this.#setValue( + 'etag', + typeof value === 'string' && !/^(W\/)?".*"$/.test(value) ? `"${value}"` : value, + ); + } + /** * The `Expires` header contains the date/time after which the response is considered stale. *