Make Astro.cookies.get(key) return undefined (#7888)

This commit is contained in:
Matthew Phillips 2023-08-01 04:43:26 -04:00 committed by Emanuele Stoppa
parent 2db9df88b8
commit e4258f248a
4 changed files with 35 additions and 15 deletions

View file

@ -0,0 +1,17 @@
---
'astro': major
---
Astro.cookies.get(key) returns undefined if cookie doesn't exist
With this change, Astro.cookies.get(key) no longer always returns a `AstroCookie` object. Instead it now returns `undefined` if the cookie does not exist.
You should update your code if you assume that all calls to `get()` return a value. When using with `has()` you still need to assert the value, like so:
```astro
---
if(Astro.cookies.has(id)) {
const id = Astro.cookies.get(id)!;
}
---
```

View file

@ -15,14 +15,14 @@ interface AstroCookieSetOptions {
type AstroCookieDeleteOptions = Pick<AstroCookieSetOptions, 'domain' | 'path'>; type AstroCookieDeleteOptions = Pick<AstroCookieSetOptions, 'domain' | 'path'>;
interface AstroCookieInterface { interface AstroCookieInterface {
value: string | undefined; value: string;
json(): Record<string, any>; json(): Record<string, any>;
number(): number; number(): number;
boolean(): boolean; boolean(): boolean;
} }
interface AstroCookiesInterface { interface AstroCookiesInterface {
get(key: string): AstroCookieInterface; get(key: string): AstroCookieInterface | undefined;
has(key: string): boolean; has(key: string): boolean;
set( set(
key: string, key: string,
@ -37,7 +37,7 @@ const DELETED_VALUE = 'deleted';
const responseSentSymbol = Symbol.for('astro.responseSent'); const responseSentSymbol = Symbol.for('astro.responseSent');
class AstroCookie implements AstroCookieInterface { class AstroCookie implements AstroCookieInterface {
constructor(public value: string | undefined) {} constructor(public value: string) {}
json() { json() {
if (this.value === undefined) { if (this.value === undefined) {
throw new Error(`Cannot convert undefined to an object.`); throw new Error(`Cannot convert undefined to an object.`);
@ -97,22 +97,25 @@ class AstroCookies implements AstroCookiesInterface {
* @param key The cookie to get. * @param key The cookie to get.
* @returns An object containing the cookie value as well as convenience methods for converting its value. * @returns An object containing the cookie value as well as convenience methods for converting its value.
*/ */
get(key: string): AstroCookie { get(key: string): AstroCookie | undefined {
// Check for outgoing Set-Cookie values first // Check for outgoing Set-Cookie values first
if (this.#outgoing?.has(key)) { if (this.#outgoing?.has(key)) {
let [serializedValue, , isSetValue] = this.#outgoing.get(key)!; let [serializedValue, , isSetValue] = this.#outgoing.get(key)!;
if (isSetValue) { if (isSetValue) {
return new AstroCookie(serializedValue); return new AstroCookie(serializedValue);
} else { } else {
return new AstroCookie(undefined); return undefined;
} }
} }
const values = this.#ensureParsed(); const values = this.#ensureParsed();
if(key in values) {
const value = values[key]; const value = values[key];
return new AstroCookie(value); return new AstroCookie(value);
} }
}
/** /**
* Astro.cookies.has(key) returns a boolean indicating whether this cookie is either * Astro.cookies.has(key) returns a boolean indicating whether this cookie is either
* part of the initial request or set via Astro.cookies.set(key) * part of the initial request or set via Astro.cookies.set(key)

View file

@ -30,7 +30,7 @@ describe('astro/src/core/cookies', () => {
expect(cookies.get('foo').value).to.equal('bar'); expect(cookies.get('foo').value).to.equal('bar');
cookies.delete('foo'); cookies.delete('foo');
expect(cookies.get('foo').value).to.equal(undefined); expect(cookies.get('foo')).to.equal(undefined);
}); });
it('calling cookies.has() after returns false', () => { it('calling cookies.has() after returns false', () => {

View file

@ -16,6 +16,13 @@ describe('astro/src/core/cookies', () => {
expect(cookies.get('foo').value).to.equal('bar'); expect(cookies.get('foo').value).to.equal('bar');
}); });
it('Returns undefined is the value doesn\'t exist', () => {
const req = new Request('http://example.com/');
let cookies = new AstroCookies(req);
let cookie = cookies.get('foo');
expect(cookie).to.equal(undefined);
});
describe('.json()', () => { describe('.json()', () => {
it('returns a JavaScript object', () => { it('returns a JavaScript object', () => {
const req = new Request('http://example.com/', { const req = new Request('http://example.com/', {
@ -29,13 +36,6 @@ describe('astro/src/core/cookies', () => {
expect(json).to.be.an('object'); expect(json).to.be.an('object');
expect(json.key).to.equal('value'); expect(json.key).to.equal('value');
}); });
it('throws if the value is undefined', () => {
const req = new Request('http://example.com/');
let cookies = new AstroCookies(req);
let cookie = cookies.get('foo');
expect(() => cookie.json()).to.throw('Cannot convert undefined to an object.');
});
}); });
describe('.number()', () => { describe('.number()', () => {