Skip to content

Commit

Permalink
Some cookie changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mjackson committed Dec 20, 2024
1 parent 16b8946 commit 79f0990
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 33 deletions.
5 changes: 5 additions & 0 deletions packages/headers/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

This is the changelog for [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers). It follows [semantic versioning](https://semver.org/).

## HEAD

- BREAKING CHANGE: `cookie.delete(name)` returns `void` instead of `boolean`
- BREAKING CHANGE: `cookie.forEach()` calls its callback with `(name, value, cookie)` instead of `(value, name, map)`

## v0.9.0 (2024-12-20)

This release tightens up the type safety and brings `SuperHeaders` more in line with the built-in `Headers` interface.
Expand Down
34 changes: 20 additions & 14 deletions packages/headers/src/lib/cookie.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,21 @@ describe('Cookie', () => {
});

it('sets and gets values', () => {
let header = new Cookie('');
let header = new Cookie();
header.set('name', 'value');
assert.equal(header.get('name'), 'value');
});

it('returns `null` for nonexistent values', () => {
let header = new Cookie();
assert.equal(header.get('name'), null);
});

it('deletes values', () => {
let header = new Cookie('name=value');
assert.equal(header.delete('name'), true);
assert.equal(header.delete('nonexistent'), false);
assert.equal(header.get('name'), undefined);
assert.equal(header.has('name'), true);
header.delete('name');
assert.equal(header.has('name'), false);
});

it('checks if value exists', () => {
Expand All @@ -63,19 +68,11 @@ describe('Cookie', () => {

it('clears all values', () => {
let header = new Cookie('name1=value1; name2=value2');
assert.equal(header.size, 2);
header.clear();
assert.equal(header.size, 0);
});

it('iterates over entries', () => {
let header = new Cookie('name1=value1; name2=value2');
let entries = Array.from(header.entries());
assert.deepEqual(entries, [
['name1', 'value1'],
['name2', 'value2'],
]);
});

it('iterates over names', () => {
let header = new Cookie('name1=value1; name2=value2');
let names = Array.from(header.names());
Expand All @@ -88,10 +85,19 @@ describe('Cookie', () => {
assert.deepEqual(values, ['value1', 'value2']);
});

it('iterates over entries', () => {
let header = new Cookie('name1=value1; name2=value2');
let entries = Array.from(header.entries());
assert.deepEqual(entries, [
['name1', 'value1'],
['name2', 'value2'],
]);
});

it('uses forEach correctly', () => {
let header = new Cookie('name1=value1; name2=value2');
let result: [string, string][] = [];
header.forEach((value, name) => {
header.forEach((name, value) => {
result.push([name, value]);
});
assert.deepEqual(result, [
Expand Down
44 changes: 25 additions & 19 deletions packages/headers/src/lib/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,44 +37,47 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> {
}

/**
* Gets the value of a cookie with the given name from the `Cookie` header.
* Gets the value of a cookie with the given name from the header.
* @param name The name of the cookie.
* @returns The value of the cookie, or `null` if the cookie does not exist.
*/
get(name: string): string | undefined {
return this.#map.get(name);
get(name: string): string | null {
return this.#map.get(name) ?? null;
}

/**
* Sets a cookie with the given name and value in the `Cookie` header.
* Sets a cookie with the given name and value in the header.
* @param name The name of the cookie.
* @param value The value of the cookie.
*/
set(name: string, value: string): void {
this.#map.set(name, value);
}

/**
* Removes a cookie with the given name from the `Cookie` header.
* Removes a cookie with the given name from the header.
* @param name The name of the cookie.
*/
delete(name: string): boolean {
return this.#map.delete(name);
delete(name: string): void {
this.#map.delete(name);
}

/**
* True if a cookie with the given name exists in the `Cookie` header.
* True if a cookie with the given name exists in the header.
* @param name The name of the cookie.
* @returns True if a cookie with the given name exists in the header.
*/
has(name: string): boolean {
return this.#map.has(name);
}

/**
* Removes all cookies from the `Cookie` header.
* Removes all cookies from the header.
*/
clear(): void {
this.#map.clear();
}

entries(): IterableIterator<[string, string]> {
return this.#map.entries();
}

names(): IterableIterator<string> {
return this.#map.keys();
}
Expand All @@ -83,19 +86,22 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> {
return this.#map.values();
}

entries(): IterableIterator<[string, string]> {
return this.#map.entries();
}

[Symbol.iterator](): IterableIterator<[string, string]> {
return this.entries();
}

forEach(
callback: (value: string, key: string, map: Map<string, string>) => void,
thisArg?: any,
): void {
this.#map.forEach(callback, thisArg);
forEach(callback: (name: string, value: string, header: Cookie) => void, thisArg?: any): void {
for (let [name, value] of this) {
callback.call(thisArg, name, value, this);
}
}

/**
* The number of cookies in the `Cookie` header.
* The number of cookies in the header.
*/
get size(): number {
return this.#map.size;
Expand Down

0 comments on commit 79f0990

Please sign in to comment.