From f5c4b997b802ba926a4832a1072796e8d6530fe3 Mon Sep 17 00:00:00 2001 From: Will Harney Date: Fri, 1 Mar 2024 15:17:24 -0500 Subject: [PATCH 1/4] Use only null for unset cookie props --- lib/cookie/cookie.ts | 46 +++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/lib/cookie/cookie.ts b/lib/cookie/cookie.ts index 75aac272..ad7e6813 100644 --- a/lib/cookie/cookie.ts +++ b/lib/cookie/cookie.ts @@ -403,25 +403,39 @@ type CreateCookieOptions = { } export class Cookie { - key: string | undefined - value: string | undefined - expires: Date | 'Infinity' | null | undefined - maxAge: number | 'Infinity' | '-Infinity' | undefined - domain: string | null | undefined - path: string | null | undefined - secure: boolean | undefined - httpOnly: boolean | undefined - extensions: string[] | null | undefined + key: string + value: string + expires: Date | 'Infinity' | null + maxAge: number | 'Infinity' | '-Infinity' | null + domain: string | null + path: string | null + secure: boolean + httpOnly: boolean + extensions: string[] | null creation: Date | 'Infinity' | null - creationIndex: number | undefined - hostOnly: boolean | null | undefined - pathIsDefault: boolean | null | undefined - lastAccessed: Date | 'Infinity' | null | undefined + creationIndex: number + hostOnly: boolean | null + pathIsDefault: boolean | null + lastAccessed: Date | 'Infinity' | null sameSite: string | undefined constructor(options: CreateCookieOptions = {}) { - Object.assign(this, cookieDefaults, options) - this.creation = options.creation ?? cookieDefaults.creation ?? new Date() + this.key = options.key ?? cookieDefaults.key + this.value = options.value ?? cookieDefaults.value + this.expires = options.expires ?? cookieDefaults.expires + this.maxAge = options.maxAge ?? cookieDefaults.maxAge + this.domain = options.domain ?? cookieDefaults.domain + this.path = options.path ?? cookieDefaults.path + this.secure = options.secure ?? cookieDefaults.secure + this.httpOnly = options.httpOnly ?? cookieDefaults.httpOnly + this.extensions = options.extensions ?? cookieDefaults.extensions + this.creation = options.creation ?? cookieDefaults.creation + this.hostOnly = options.hostOnly ?? cookieDefaults.hostOnly + this.pathIsDefault = options.pathIsDefault ?? cookieDefaults.pathIsDefault + this.lastAccessed = options.lastAccessed ?? cookieDefaults.lastAccessed + this.sameSite = options.sameSite ?? cookieDefaults.sameSite + + this.creation = options.creation ?? new Date() // used to break creation ties in cookieCompare(): Object.defineProperty(this, 'creationIndex', { @@ -430,6 +444,8 @@ export class Cookie { writable: true, value: ++Cookie.cookiesCreated, }) + // Duplicate operation, but it makes TypeScript happy... + this.creationIndex = Cookie.cookiesCreated } [Symbol.for('nodejs.util.inspect.custom')]() { From 60b0e3ffe084d395fdba15e7dbf87dcef8c194c5 Mon Sep 17 00:00:00 2001 From: Will Harney Date: Fri, 1 Mar 2024 15:29:01 -0500 Subject: [PATCH 2/4] Clean up cookie creation options. --- lib/cookie/cookie.ts | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/lib/cookie/cookie.ts b/lib/cookie/cookie.ts index ad7e6813..b261192d 100644 --- a/lib/cookie/cookie.ts +++ b/lib/cookie/cookie.ts @@ -365,6 +365,17 @@ function fromJSON(str: unknown) { return c } +type CreateCookieOptions = Omit< + { + // Assume that all non-method attributes on the class can be configured, except creationIndex. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [K in keyof Cookie as Cookie[K] extends (...args: any[]) => any + ? never + : K]?: Cookie[K] + }, + 'creationIndex' +> + const cookieDefaults = { // the order in which the RFC has them: key: '', @@ -382,25 +393,7 @@ const cookieDefaults = { creation: null, lastAccessed: null, sameSite: undefined, -} - -type CreateCookieOptions = { - key?: string - value?: string - expires?: Date | 'Infinity' | null - maxAge?: number | 'Infinity' | '-Infinity' - domain?: string | null - path?: string | null - secure?: boolean - httpOnly?: boolean - extensions?: string[] | null - creation?: Date | 'Infinity' | null - creationIndex?: number - hostOnly?: boolean | null - pathIsDefault?: boolean | null - lastAccessed?: Date | 'Infinity' | null - sameSite?: string | undefined -} +} as const satisfies Required export class Cookie { key: string From b11e6a547a1e03631b4a0ef8089de3fd531c0f2e Mon Sep 17 00:00:00 2001 From: Will Harney Date: Wed, 13 Mar 2024 14:03:37 -0400 Subject: [PATCH 3/4] remove unnecessary type assertions --- lib/__tests__/cookieJar.spec.ts | 6 +++--- lib/__tests__/cookieSorting.spec.ts | 8 ++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/__tests__/cookieJar.spec.ts b/lib/__tests__/cookieJar.spec.ts index 474448b8..03b1648a 100644 --- a/lib/__tests__/cookieJar.spec.ts +++ b/lib/__tests__/cookieJar.spec.ts @@ -420,7 +420,7 @@ describe('CookieJar', () => { expect(allHaveRootPath).toBe(true) const noCookiesWithAnOtherKeyRetrieved = cookies.every( - (cookie) => !/^other/.test(cookie.key as string), + (cookie) => !/^other/.test(cookie.key), ) expect(noCookiesWithAnOtherKeyRetrieved).toBe(true) }) @@ -430,7 +430,7 @@ describe('CookieJar', () => { expect(cookies).toHaveLength(4) const noCookiesWithAnOtherKeyRetrieved = cookies.every( - (cookie) => !/^other/.test(cookie.key as string), + (cookie) => !/^other/.test(cookie.key), ) expect(noCookiesWithAnOtherKeyRetrieved).toBe(true) }) @@ -442,7 +442,7 @@ describe('CookieJar', () => { expect(cookies).toHaveLength(4) const noCookiesWithAnOtherKeyRetrieved = cookies.every( - (cookie) => !/^other/.test(cookie.key as string), + (cookie) => !/^other/.test(cookie.key), ) expect(noCookiesWithAnOtherKeyRetrieved).toBe(true) }) diff --git a/lib/__tests__/cookieSorting.spec.ts b/lib/__tests__/cookieSorting.spec.ts index 784457c1..b1997896 100644 --- a/lib/__tests__/cookieSorting.spec.ts +++ b/lib/__tests__/cookieSorting.spec.ts @@ -9,9 +9,7 @@ describe('Cookie sorting', () => { const cookie2 = new Cookie() expect(typeof cookie1.creationIndex).toBe('number') expect(typeof cookie2.creationIndex).toBe('number') - expect(cookie1.creationIndex).toBeLessThan( - cookie2.creationIndex as number, - ) + expect(cookie1.creationIndex).toBeLessThan(cookie2.creationIndex) }) it('should set the creation index during construction when creation time is provided', () => { @@ -21,9 +19,7 @@ describe('Cookie sorting', () => { expect(cookie1.creation).toEqual(cookie2.creation) expect(typeof cookie1.creationIndex).toBe('number') expect(typeof cookie2.creationIndex).toBe('number') - expect(cookie1.creationIndex).toBeLessThan( - cookie2.creationIndex as number, - ) + expect(cookie1.creationIndex).toBeLessThan(cookie2.creationIndex) }) it('should leave the creation index alone during setCookie', async () => { From 0c5d587dce24b47129569a7675e9b790326d0c7c Mon Sep 17 00:00:00 2001 From: Will Harney Date: Wed, 13 Mar 2024 14:20:38 -0400 Subject: [PATCH 4/4] sort package dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f9faa46e..caf37ae8 100644 --- a/package.json +++ b/package.json @@ -120,8 +120,8 @@ "vows": "^0.8.3" }, "dependencies": { - "tldts": "^6.1.0", "punycode": "^2.3.1", + "tldts": "^6.1.0", "url-parse": "^1.5.10" } }