diff --git a/api/.gitignore b/api/.gitignore index 43172356..9928fedf 100644 --- a/api/.gitignore +++ b/api/.gitignore @@ -3,6 +3,12 @@ docs/*.md # subsequent PRs will un-ignore areas that are under review until # all docs are complete and we can drop this ignore file entirely +!docs/tough-cookie.cookie.md +!docs/tough-cookie.cookie.*.md +!docs/tough-cookie.createcookieoptions.md +!docs/tough-cookie.parsecookieoptions.md +!docs/tough-cookie.parsecookieoptions.loose.md +!docs/tough-cookie.serializedcookie.md !docs/tough-cookie.prefixsecurity.md !docs/tough-cookie.md !docs/tough-cookie.store.md diff --git a/api/docs/tough-cookie.cookie._constructor_.md b/api/docs/tough-cookie.cookie._constructor_.md new file mode 100644 index 00000000..80022b88 --- /dev/null +++ b/api/docs/tough-cookie.cookie._constructor_.md @@ -0,0 +1,49 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [(constructor)](./tough-cookie.cookie._constructor_.md) + +## Cookie.(constructor) + +Create a new Cookie instance. + +**Signature:** + +```typescript +constructor(options?: CreateCookieOptions); +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +options + + + + +CreateCookieOptions + + + + +_(Optional)_ The attributes to set on the cookie + + +
diff --git a/api/docs/tough-cookie.cookie.canonicalizeddomain.md b/api/docs/tough-cookie.cookie.canonicalizeddomain.md new file mode 100644 index 00000000..eceaf1f7 --- /dev/null +++ b/api/docs/tough-cookie.cookie.canonicalizeddomain.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [canonicalizedDomain](./tough-cookie.cookie.canonicalizeddomain.md) + +## Cookie.canonicalizedDomain() method + +Calls [canonicalDomain()](./tough-cookie.canonicaldomain.md) with the [Cookie.domain](./tough-cookie.cookie.domain.md) property. + +**Signature:** + +```typescript +canonicalizedDomain(): string | undefined; +``` +**Returns:** + +string \| undefined + diff --git a/api/docs/tough-cookie.cookie.cdomain.md b/api/docs/tough-cookie.cookie.cdomain.md new file mode 100644 index 00000000..62628f26 --- /dev/null +++ b/api/docs/tough-cookie.cookie.cdomain.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [cdomain](./tough-cookie.cookie.cdomain.md) + +## Cookie.cdomain() method + +Alias for [Cookie.canonicalizedDomain()](./tough-cookie.cookie.canonicalizeddomain.md) + +**Signature:** + +```typescript +cdomain(): string | undefined; +``` +**Returns:** + +string \| undefined + diff --git a/api/docs/tough-cookie.cookie.clone.md b/api/docs/tough-cookie.cookie.clone.md new file mode 100644 index 00000000..c05435cb --- /dev/null +++ b/api/docs/tough-cookie.cookie.clone.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [clone](./tough-cookie.cookie.clone.md) + +## Cookie.clone() method + +Does a deep clone of this cookie, implemented exactly as `Cookie.fromJSON(cookie.toJSON())`. + +**Signature:** + +```typescript +clone(): Cookie | undefined; +``` +**Returns:** + +[Cookie](./tough-cookie.cookie.md) \| undefined + diff --git a/api/docs/tough-cookie.cookie.cookiestring.md b/api/docs/tough-cookie.cookie.cookiestring.md new file mode 100644 index 00000000..00314053 --- /dev/null +++ b/api/docs/tough-cookie.cookie.cookiestring.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [cookieString](./tough-cookie.cookie.cookiestring.md) + +## Cookie.cookieString() method + +Encodes to a `Cookie` header value (specifically, the [Cookie.key](./tough-cookie.cookie.key.md) and [Cookie.value](./tough-cookie.cookie.value.md) properties joined with "="). + +**Signature:** + +```typescript +cookieString(): string; +``` +**Returns:** + +string + diff --git a/api/docs/tough-cookie.cookie.creation.md b/api/docs/tough-cookie.cookie.creation.md new file mode 100644 index 00000000..7a7bc395 --- /dev/null +++ b/api/docs/tough-cookie.cookie.creation.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [creation](./tough-cookie.cookie.creation.md) + +## Cookie.creation property + +Set to the date and time when a Cookie is initially stored or a matching cookie is received that replaces an existing cookie (See [RFC6265 Section 5.3](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.3)). + +Also used to maintain ordering among cookies. Among cookies that have equal-length path fields, cookies with earlier creation-times are listed before cookies with later creation-times (See [RFC6265 Section 5.4](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4)). + +**Signature:** + +```typescript +creation: Date | 'Infinity' | null; +``` diff --git a/api/docs/tough-cookie.cookie.creationindex.md b/api/docs/tough-cookie.cookie.creationindex.md new file mode 100644 index 00000000..65cb7ef4 --- /dev/null +++ b/api/docs/tough-cookie.cookie.creationindex.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [creationIndex](./tough-cookie.cookie.creationindex.md) + +## Cookie.creationIndex property + +A global counter used to break ordering ties between two cookies that have equal-length path fields and the same creation-time. + +**Signature:** + +```typescript +creationIndex: number; +``` diff --git a/api/docs/tough-cookie.cookie.domain.md b/api/docs/tough-cookie.cookie.domain.md new file mode 100644 index 00000000..f23863d5 --- /dev/null +++ b/api/docs/tough-cookie.cookie.domain.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [domain](./tough-cookie.cookie.domain.md) + +## Cookie.domain property + +The 'Domain' attribute of the cookie represents the domain the cookie belongs to (See [RFC6265 Section 5.2.3](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.3)). + +**Signature:** + +```typescript +domain: string | null; +``` diff --git a/api/docs/tough-cookie.cookie.expires.md b/api/docs/tough-cookie.cookie.expires.md new file mode 100644 index 00000000..fbd0d426 --- /dev/null +++ b/api/docs/tough-cookie.cookie.expires.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [expires](./tough-cookie.cookie.expires.md) + +## Cookie.expires property + +The 'Expires' attribute of the cookie (See [RFC6265 Section 5.2.1](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.1)). + +**Signature:** + +```typescript +expires: Date | 'Infinity' | null; +``` diff --git a/api/docs/tough-cookie.cookie.expirytime.md b/api/docs/tough-cookie.cookie.expirytime.md new file mode 100644 index 00000000..39188c81 --- /dev/null +++ b/api/docs/tough-cookie.cookie.expirytime.md @@ -0,0 +1,57 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [expiryTime](./tough-cookie.cookie.expirytime.md) + +## Cookie.expiryTime() method + +Computes the absolute unix-epoch milliseconds that this cookie expires. + +The "Max-Age" attribute takes precedence over "Expires" (as per the RFC). The [Cookie.lastAccessed](./tough-cookie.cookie.lastaccessed.md) attribute (or the `now` parameter if given) is used to offset the [Cookie.maxAge](./tough-cookie.cookie.maxage.md) attribute. + +If Expires ([Cookie.expires](./tough-cookie.cookie.expires.md)) is set, that's returned. + +**Signature:** + +```typescript +expiryTime(now?: Date): number | undefined; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +now + + + + +Date + + + + +_(Optional)_ can be used to provide a time offset (instead of [Cookie.lastAccessed](./tough-cookie.cookie.lastaccessed.md)) to use when calculating the "Max-Age" value + + +
+**Returns:** + +number \| undefined + diff --git a/api/docs/tough-cookie.cookie.extensions.md b/api/docs/tough-cookie.cookie.extensions.md new file mode 100644 index 00000000..5a64caf3 --- /dev/null +++ b/api/docs/tough-cookie.cookie.extensions.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [extensions](./tough-cookie.cookie.extensions.md) + +## Cookie.extensions property + +Contains attributes which are not part of the defined spec but match the `extension-av` syntax defined in Section 4.1.1 of RFC6265 (See [RFC6265 Section 4.1.1](https://www.rfc-editor.org/rfc/rfc6265.html#section-4.1.1)). + +**Signature:** + +```typescript +extensions: string[] | null; +``` diff --git a/api/docs/tough-cookie.cookie.fromjson.md b/api/docs/tough-cookie.cookie.fromjson.md new file mode 100644 index 00000000..4f104fed --- /dev/null +++ b/api/docs/tough-cookie.cookie.fromjson.md @@ -0,0 +1,76 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [fromJSON](./tough-cookie.cookie.fromjson.md) + +## Cookie.fromJSON() method + +Does the reverse of [Cookie.toJSON()](./tough-cookie.cookie.tojson.md). + +**Signature:** + +```typescript +static fromJSON(str: unknown): Cookie | undefined; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +str + + + + +unknown + + + + +An unparsed JSON string or a value that has already been parsed as JSON + + +
+**Returns:** + +[Cookie](./tough-cookie.cookie.md) \| undefined + +## Remarks + +Any Date properties (such as .expires, .creation, and .lastAccessed) are parsed via Date.parse, not tough-cookie's parseDate, since ISO timestamps are being handled at this layer. + +## Example + + +``` +const json = JSON.stringify({ + key: 'alpha', + value: 'beta', + domain: 'example.com', + path: '/foo', + expires: '2038-01-19T03:14:07.000Z', +}) +const cookie = Cookie.fromJSON(json) +cookie.key === 'alpha' +cookie.value === 'beta' +cookie.domain === 'example.com' +cookie.path === '/foo' +cookie.expires === new Date(Date.parse('2038-01-19T03:14:07.000Z')) +``` + diff --git a/api/docs/tough-cookie.cookie.hostonly.md b/api/docs/tough-cookie.cookie.hostonly.md new file mode 100644 index 00000000..74977480 --- /dev/null +++ b/api/docs/tough-cookie.cookie.hostonly.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [hostOnly](./tough-cookie.cookie.hostonly.md) + +## Cookie.hostOnly property + +A boolean flag indicating if a cookie is a host-only cookie (i.e.; when the request's host exactly matches the domain of the cookie) or not (See [RFC6265 Section 5.3](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.3)). + +**Signature:** + +```typescript +hostOnly: boolean | null; +``` diff --git a/api/docs/tough-cookie.cookie.httponly.md b/api/docs/tough-cookie.cookie.httponly.md new file mode 100644 index 00000000..552e0d8d --- /dev/null +++ b/api/docs/tough-cookie.cookie.httponly.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [httpOnly](./tough-cookie.cookie.httponly.md) + +## Cookie.httpOnly property + +The 'HttpOnly' flag of the cookie indicates if the cookie is inaccessible to client scripts or not (See [RFC6265 Section 5.2.6](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.6)). + +**Signature:** + +```typescript +httpOnly: boolean; +``` diff --git a/api/docs/tough-cookie.cookie.ispersistent.md b/api/docs/tough-cookie.cookie.ispersistent.md new file mode 100644 index 00000000..20a5e2f8 --- /dev/null +++ b/api/docs/tough-cookie.cookie.ispersistent.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [isPersistent](./tough-cookie.cookie.ispersistent.md) + +## Cookie.isPersistent() method + +Indicates if the cookie has been persisted to a store or not. + +**Signature:** + +```typescript +isPersistent(): boolean; +``` +**Returns:** + +boolean + diff --git a/api/docs/tough-cookie.cookie.key.md b/api/docs/tough-cookie.cookie.key.md new file mode 100644 index 00000000..46d44d6f --- /dev/null +++ b/api/docs/tough-cookie.cookie.key.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [key](./tough-cookie.cookie.key.md) + +## Cookie.key property + +The name or key of the cookie + +**Signature:** + +```typescript +key: string; +``` diff --git a/api/docs/tough-cookie.cookie.lastaccessed.md b/api/docs/tough-cookie.cookie.lastaccessed.md new file mode 100644 index 00000000..4093fc94 --- /dev/null +++ b/api/docs/tough-cookie.cookie.lastaccessed.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [lastAccessed](./tough-cookie.cookie.lastaccessed.md) + +## Cookie.lastAccessed property + +Set to the date and time when a cookie was initially stored ([RFC6265 Section 5.3](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.3)) and updated whenever the cookie is retrieved from the [CookieJar](./tough-cookie.cookiejar.md) ([RFC6265 Section 5.4](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4)). + +**Signature:** + +```typescript +lastAccessed: Date | 'Infinity' | null; +``` diff --git a/api/docs/tough-cookie.cookie.maxage.md b/api/docs/tough-cookie.cookie.maxage.md new file mode 100644 index 00000000..4932c1cb --- /dev/null +++ b/api/docs/tough-cookie.cookie.maxage.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [maxAge](./tough-cookie.cookie.maxage.md) + +## Cookie.maxAge property + +The 'Max-Age' attribute of the cookie (See [RFC6265 Section 5.2.2](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.2)). + +**Signature:** + +```typescript +maxAge: number | 'Infinity' | '-Infinity' | null; +``` diff --git a/api/docs/tough-cookie.cookie.md b/api/docs/tough-cookie.cookie.md new file mode 100644 index 00000000..fe5547fd --- /dev/null +++ b/api/docs/tough-cookie.cookie.md @@ -0,0 +1,604 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) + +## Cookie class + +An HTTP cookie (web cookie, browser cookie) is a small piece of data that a server sends to a user's web browser. It is defined in [RFC6265](https://www.rfc-editor.org/rfc/rfc6265.html). + +**Signature:** + +```typescript +export declare class Cookie +``` + +## Constructors + + + +
+ +Constructor + + + + +Modifiers + + + + +Description + + +
+ +[(constructor)(options)](./tough-cookie.cookie._constructor_.md) + + + + + + + +Create a new Cookie instance. + + +
+ +## Properties + + + + + + + + + + + + + + + + + + +
+ +Property + + + + +Modifiers + + + + +Type + + + + +Description + + +
+ +[creation](./tough-cookie.cookie.creation.md) + + + + + + + +Date \| 'Infinity' \| null + + + + +Set to the date and time when a Cookie is initially stored or a matching cookie is received that replaces an existing cookie (See [RFC6265 Section 5.3](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.3)). + +Also used to maintain ordering among cookies. Among cookies that have equal-length path fields, cookies with earlier creation-times are listed before cookies with later creation-times (See [RFC6265 Section 5.4](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4)). + + +
+ +[creationIndex](./tough-cookie.cookie.creationindex.md) + + + + + + + +number + + + + +A global counter used to break ordering ties between two cookies that have equal-length path fields and the same creation-time. + + +
+ +[domain](./tough-cookie.cookie.domain.md) + + + + + + + +string \| null + + + + +The 'Domain' attribute of the cookie represents the domain the cookie belongs to (See [RFC6265 Section 5.2.3](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.3)). + + +
+ +[expires](./tough-cookie.cookie.expires.md) + + + + + + + +Date \| 'Infinity' \| null + + + + +The 'Expires' attribute of the cookie (See [RFC6265 Section 5.2.1](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.1)). + + +
+ +[extensions](./tough-cookie.cookie.extensions.md) + + + + + + + +string\[\] \| null + + + + +Contains attributes which are not part of the defined spec but match the `extension-av` syntax defined in Section 4.1.1 of RFC6265 (See [RFC6265 Section 4.1.1](https://www.rfc-editor.org/rfc/rfc6265.html#section-4.1.1)). + + +
+ +[hostOnly](./tough-cookie.cookie.hostonly.md) + + + + + + + +boolean \| null + + + + +A boolean flag indicating if a cookie is a host-only cookie (i.e.; when the request's host exactly matches the domain of the cookie) or not (See [RFC6265 Section 5.3](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.3)). + + +
+ +[httpOnly](./tough-cookie.cookie.httponly.md) + + + + + + + +boolean + + + + +The 'HttpOnly' flag of the cookie indicates if the cookie is inaccessible to client scripts or not (See [RFC6265 Section 5.2.6](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.6)). + + +
+ +[key](./tough-cookie.cookie.key.md) + + + + + + + +string + + + + +The name or key of the cookie + + +
+ +[lastAccessed](./tough-cookie.cookie.lastaccessed.md) + + + + + + + +Date \| 'Infinity' \| null + + + + +Set to the date and time when a cookie was initially stored ([RFC6265 Section 5.3](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.3)) and updated whenever the cookie is retrieved from the [CookieJar](./tough-cookie.cookiejar.md) ([RFC6265 Section 5.4](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4)). + + +
+ +[maxAge](./tough-cookie.cookie.maxage.md) + + + + + + + +number \| 'Infinity' \| '-Infinity' \| null + + + + +The 'Max-Age' attribute of the cookie (See [RFC6265 Section 5.2.2](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.2)). + + +
+ +[path](./tough-cookie.cookie.path.md) + + + + + + + +string \| null + + + + +The 'Path' attribute of the cookie represents the path of the cookie (See [RFC6265 Section 5.2.4](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.4)). + + +
+ +[pathIsDefault](./tough-cookie.cookie.pathisdefault.md) + + + + + + + +boolean \| null + + + + +A boolean flag indicating if a cookie had no 'Path' attribute and the default path was used (See [RFC6265 Section 5.2.4](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.4)). + + +
+ +[sameSite](./tough-cookie.cookie.samesite.md) + + + + + + + +string \| undefined + + + + +The 'SameSite' attribute of a cookie as defined in RFC6265bis (See [RFC6265bis (v13) Section 5.2](https://www.ietf.org/archive/id/draft-ietf-httpbis-rfc6265bis-13.html#section-5.2)). + + +
+ +[secure](./tough-cookie.cookie.secure.md) + + + + + + + +boolean + + + + +The 'Secure' flag of the cookie indicates if the scope of the cookie is limited to secure channels (e.g.; HTTPS) or not (See [RFC6265 Section 5.2.5](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.5)). + + +
+ +[serializableProperties](./tough-cookie.cookie.serializableproperties.md) + + + + +`static` + + + + +readonly \["key", "value", "expires", "maxAge", "domain", "path", "secure", "httpOnly", "extensions", "hostOnly", "pathIsDefault", "creation", "lastAccessed", "sameSite"\] + + + + +Cookie properties that will be serialized when using [Cookie.fromJSON()](./tough-cookie.cookie.fromjson.md) and [Cookie.toJSON()](./tough-cookie.cookie.tojson.md). + + +
+ +[value](./tough-cookie.cookie.value.md) + + + + + + + +string + + + + +The value of the cookie + + +
+ +## Methods + + + + + + + + + + + + + + + + +
+ +Method + + + + +Modifiers + + + + +Description + + +
+ +[canonicalizedDomain()](./tough-cookie.cookie.canonicalizeddomain.md) + + + + + + + +Calls [canonicalDomain()](./tough-cookie.canonicaldomain.md) with the [Cookie.domain](./tough-cookie.cookie.domain.md) property. + + +
+ +[cdomain()](./tough-cookie.cookie.cdomain.md) + + + + + + + +Alias for [Cookie.canonicalizedDomain()](./tough-cookie.cookie.canonicalizeddomain.md) + + +
+ +[clone()](./tough-cookie.cookie.clone.md) + + + + + + + +Does a deep clone of this cookie, implemented exactly as `Cookie.fromJSON(cookie.toJSON())`. + + +
+ +[cookieString()](./tough-cookie.cookie.cookiestring.md) + + + + + + + +Encodes to a `Cookie` header value (specifically, the [Cookie.key](./tough-cookie.cookie.key.md) and [Cookie.value](./tough-cookie.cookie.value.md) properties joined with "="). + + +
+ +[expiryTime(now)](./tough-cookie.cookie.expirytime.md) + + + + + + + +Computes the absolute unix-epoch milliseconds that this cookie expires. + +The "Max-Age" attribute takes precedence over "Expires" (as per the RFC). The [Cookie.lastAccessed](./tough-cookie.cookie.lastaccessed.md) attribute (or the `now` parameter if given) is used to offset the [Cookie.maxAge](./tough-cookie.cookie.maxage.md) attribute. + +If Expires ([Cookie.expires](./tough-cookie.cookie.expires.md)) is set, that's returned. + + +
+ +[fromJSON(str)](./tough-cookie.cookie.fromjson.md) + + + + +`static` + + + + +Does the reverse of [Cookie.toJSON()](./tough-cookie.cookie.tojson.md). + + +
+ +[isPersistent()](./tough-cookie.cookie.ispersistent.md) + + + + + + + +Indicates if the cookie has been persisted to a store or not. + + +
+ +[parse(str, options)](./tough-cookie.cookie.parse.md) + + + + +`static` + + + + +Parses a string into a Cookie object. + + +
+ +[setExpires(exp)](./tough-cookie.cookie.setexpires.md) + + + + + + + +Sets the 'Expires' attribute on a cookie. + + +
+ +[setMaxAge(age)](./tough-cookie.cookie.setmaxage.md) + + + + + + + +Sets the 'Max-Age' attribute (in seconds) on a cookie. + + +
+ +[toJSON()](./tough-cookie.cookie.tojson.md) + + + + + + + +For convenience in using `JSON.stringify(cookie)`. Returns a plain-old Object that can be JSON-serialized. + + +
+ +[toString()](./tough-cookie.cookie.tostring.md) + + + + + + + +Encodes to a `Set-Cookie header` value. + + +
+ +[TTL(now)](./tough-cookie.cookie.ttl.md) + + + + + + + +Computes the TTL relative to now (milliseconds). + + +
+ +[validate()](./tough-cookie.cookie.validate.md) + + + + + + + +**_(BETA)_** Validates cookie attributes for semantic correctness. Useful for "lint" checking any `Set-Cookie` headers you generate. For now, it returns a boolean, but eventually could return a reason string. + + +
diff --git a/api/docs/tough-cookie.cookie.parse.md b/api/docs/tough-cookie.cookie.parse.md new file mode 100644 index 00000000..0ffb1e3d --- /dev/null +++ b/api/docs/tough-cookie.cookie.parse.md @@ -0,0 +1,100 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [parse](./tough-cookie.cookie.parse.md) + +## Cookie.parse() method + +Parses a string into a Cookie object. + +**Signature:** + +```typescript +static parse(str: string, options?: ParseCookieOptions): Cookie | undefined; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +str + + + + +string + + + + +The `Set-Cookie` header or a Cookie string to parse. + + +
+ +options + + + + +ParseCookieOptions + + + + +_(Optional)_ Configures `strict` or `loose` mode for cookie parsing + + +
+**Returns:** + +[Cookie](./tough-cookie.cookie.md) \| undefined + +## Remarks + +Note: when parsing a `Cookie` header it must be split by ';' before each Cookie string can be parsed. + +## Example 1 + + +``` +// parse a `Set-Cookie` header +const setCookieHeader = 'a=bcd; Expires=Tue, 18 Oct 2011 07:05:03 GMT' +const cookie = Cookie.parse(setCookieHeader) +cookie.key === 'a' +cookie.value === 'bcd' +cookie.expires === new Date(Date.parse('Tue, 18 Oct 2011 07:05:03 GMT')) +``` + +## Example 2 + + +``` +// parse a `Cookie` header +const cookieHeader = 'name=value; name2=value2; name3=value3' +const cookies = cookieHeader.split(';').map(Cookie.parse) +cookies[0].name === 'name' +cookies[0].value === 'value' +cookies[1].name === 'name2' +cookies[1].value === 'value2' +cookies[2].name === 'name3' +cookies[2].value === 'value3' +``` + diff --git a/api/docs/tough-cookie.cookie.path.md b/api/docs/tough-cookie.cookie.path.md new file mode 100644 index 00000000..a1ce5eb5 --- /dev/null +++ b/api/docs/tough-cookie.cookie.path.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [path](./tough-cookie.cookie.path.md) + +## Cookie.path property + +The 'Path' attribute of the cookie represents the path of the cookie (See [RFC6265 Section 5.2.4](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.4)). + +**Signature:** + +```typescript +path: string | null; +``` diff --git a/api/docs/tough-cookie.cookie.pathisdefault.md b/api/docs/tough-cookie.cookie.pathisdefault.md new file mode 100644 index 00000000..325b6b91 --- /dev/null +++ b/api/docs/tough-cookie.cookie.pathisdefault.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [pathIsDefault](./tough-cookie.cookie.pathisdefault.md) + +## Cookie.pathIsDefault property + +A boolean flag indicating if a cookie had no 'Path' attribute and the default path was used (See [RFC6265 Section 5.2.4](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.4)). + +**Signature:** + +```typescript +pathIsDefault: boolean | null; +``` diff --git a/api/docs/tough-cookie.cookie.samesite.md b/api/docs/tough-cookie.cookie.samesite.md new file mode 100644 index 00000000..7be64cce --- /dev/null +++ b/api/docs/tough-cookie.cookie.samesite.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [sameSite](./tough-cookie.cookie.samesite.md) + +## Cookie.sameSite property + +The 'SameSite' attribute of a cookie as defined in RFC6265bis (See [RFC6265bis (v13) Section 5.2](https://www.ietf.org/archive/id/draft-ietf-httpbis-rfc6265bis-13.html#section-5.2)). + +**Signature:** + +```typescript +sameSite: string | undefined; +``` diff --git a/api/docs/tough-cookie.cookie.secure.md b/api/docs/tough-cookie.cookie.secure.md new file mode 100644 index 00000000..b7607aa5 --- /dev/null +++ b/api/docs/tough-cookie.cookie.secure.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [secure](./tough-cookie.cookie.secure.md) + +## Cookie.secure property + +The 'Secure' flag of the cookie indicates if the scope of the cookie is limited to secure channels (e.g.; HTTPS) or not (See [RFC6265 Section 5.2.5](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.5)). + +**Signature:** + +```typescript +secure: boolean; +``` diff --git a/api/docs/tough-cookie.cookie.serializableproperties.md b/api/docs/tough-cookie.cookie.serializableproperties.md new file mode 100644 index 00000000..74bc648c --- /dev/null +++ b/api/docs/tough-cookie.cookie.serializableproperties.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [serializableProperties](./tough-cookie.cookie.serializableproperties.md) + +## Cookie.serializableProperties property + +Cookie properties that will be serialized when using [Cookie.fromJSON()](./tough-cookie.cookie.fromjson.md) and [Cookie.toJSON()](./tough-cookie.cookie.tojson.md). + +**Signature:** + +```typescript +static serializableProperties: readonly ["key", "value", "expires", "maxAge", "domain", "path", "secure", "httpOnly", "extensions", "hostOnly", "pathIsDefault", "creation", "lastAccessed", "sameSite"]; +``` diff --git a/api/docs/tough-cookie.cookie.setexpires.md b/api/docs/tough-cookie.cookie.setexpires.md new file mode 100644 index 00000000..ca00af7d --- /dev/null +++ b/api/docs/tough-cookie.cookie.setexpires.md @@ -0,0 +1,57 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [setExpires](./tough-cookie.cookie.setexpires.md) + +## Cookie.setExpires() method + +Sets the 'Expires' attribute on a cookie. + +**Signature:** + +```typescript +setExpires(exp: string | Date): void; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +exp + + + + +string \| Date + + + + +the new value for the 'Expires' attribute of the cookie. + + +
+**Returns:** + +void + +## Remarks + +When given a `string` value it will be parsed with [parseDate()](./tough-cookie.parsedate.md). If the value can't be parsed as a cookie date then the 'Expires' attribute will be set to `"Infinity"`. + diff --git a/api/docs/tough-cookie.cookie.setmaxage.md b/api/docs/tough-cookie.cookie.setmaxage.md new file mode 100644 index 00000000..a7c99ecc --- /dev/null +++ b/api/docs/tough-cookie.cookie.setmaxage.md @@ -0,0 +1,57 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [setMaxAge](./tough-cookie.cookie.setmaxage.md) + +## Cookie.setMaxAge() method + +Sets the 'Max-Age' attribute (in seconds) on a cookie. + +**Signature:** + +```typescript +setMaxAge(age: number): void; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +age + + + + +number + + + + +the new value for the 'Max-Age' attribute (in seconds). + + +
+**Returns:** + +void + +## Remarks + +Coerces `-Infinity` to `"-Infinity"` and `Infinity` to `"Infinity"` so it can be serialized to JSON. + diff --git a/api/docs/tough-cookie.cookie.tojson.md b/api/docs/tough-cookie.cookie.tojson.md new file mode 100644 index 00000000..840aa6d4 --- /dev/null +++ b/api/docs/tough-cookie.cookie.tojson.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [toJSON](./tough-cookie.cookie.tojson.md) + +## Cookie.toJSON() method + +For convenience in using `JSON.stringify(cookie)`. Returns a plain-old Object that can be JSON-serialized. + +**Signature:** + +```typescript +toJSON(): SerializedCookie; +``` +**Returns:** + +SerializedCookie + +## Remarks + +- Any `Date` properties (such as [Cookie.expires](./tough-cookie.cookie.expires.md), [Cookie.creation](./tough-cookie.cookie.creation.md), and [Cookie.lastAccessed](./tough-cookie.cookie.lastaccessed.md)) are exported in ISO format (`Date.toISOString()`). + +- Custom Cookie properties are discarded. In tough-cookie 1.x, since there was no [Cookie.toJSON()](./tough-cookie.cookie.tojson.md) method explicitly defined, all enumerable properties were captured. If you want a property to be serialized, add the property name to [Cookie.serializableProperties](./tough-cookie.cookie.serializableproperties.md). + diff --git a/api/docs/tough-cookie.cookie.tostring.md b/api/docs/tough-cookie.cookie.tostring.md new file mode 100644 index 00000000..ff1a0181 --- /dev/null +++ b/api/docs/tough-cookie.cookie.tostring.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [toString](./tough-cookie.cookie.tostring.md) + +## Cookie.toString() method + +Encodes to a `Set-Cookie header` value. + +**Signature:** + +```typescript +toString(): string; +``` +**Returns:** + +string + diff --git a/api/docs/tough-cookie.cookie.ttl.md b/api/docs/tough-cookie.cookie.ttl.md new file mode 100644 index 00000000..06fd587a --- /dev/null +++ b/api/docs/tough-cookie.cookie.ttl.md @@ -0,0 +1,61 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [TTL](./tough-cookie.cookie.ttl.md) + +## Cookie.TTL() method + +Computes the TTL relative to now (milliseconds). + +**Signature:** + +```typescript +TTL(now?: number): number; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +now + + + + +number + + + + +_(Optional)_ passing an explicit value is mostly used for testing purposes since this defaults to the `Date.now()` + + +
+**Returns:** + +number + +## Remarks + +- `Infinity` is returned for cookies without an explicit expiry + +- `0` is returned if the cookie is expired. + +- Otherwise a time-to-live in milliseconds is returned. + diff --git a/api/docs/tough-cookie.cookie.validate.md b/api/docs/tough-cookie.cookie.validate.md new file mode 100644 index 00000000..ed9c2ec3 --- /dev/null +++ b/api/docs/tough-cookie.cookie.validate.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [validate](./tough-cookie.cookie.validate.md) + +## Cookie.validate() method + +> This API is provided as a beta preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +> + +Validates cookie attributes for semantic correctness. Useful for "lint" checking any `Set-Cookie` headers you generate. For now, it returns a boolean, but eventually could return a reason string. + +**Signature:** + +```typescript +validate(): boolean; +``` +**Returns:** + +boolean + +## Remarks + +Works for a few things, but is by no means comprehensive. + diff --git a/api/docs/tough-cookie.cookie.value.md b/api/docs/tough-cookie.cookie.value.md new file mode 100644 index 00000000..60b95892 --- /dev/null +++ b/api/docs/tough-cookie.cookie.value.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [tough-cookie](./tough-cookie.md) > [Cookie](./tough-cookie.cookie.md) > [value](./tough-cookie.cookie.value.md) + +## Cookie.value property + +The value of the cookie + +**Signature:** + +```typescript +value: string; +``` diff --git a/api/docs/tough-cookie.cookiejar.setcookie.md b/api/docs/tough-cookie.cookiejar.setcookie.md index db1d6d8f..b4cd4e6b 100644 --- a/api/docs/tough-cookie.cookiejar.setcookie.md +++ b/api/docs/tough-cookie.cookiejar.setcookie.md @@ -42,7 +42,7 @@ string \| [Cookie](./tough-cookie.cookie.md) -The cookie object or cookie string to store. A string value will be parsed into a cookie using [Cookie.parse](./tough-cookie.cookie.parse.md). +The cookie object or cookie string to store. A string value will be parsed into a cookie using [Cookie.parse()](./tough-cookie.cookie.parse.md). diff --git a/api/docs/tough-cookie.cookiejar.setcookie_1.md b/api/docs/tough-cookie.cookiejar.setcookie_1.md index 3c12d1cb..92eb8c27 100644 --- a/api/docs/tough-cookie.cookiejar.setcookie_1.md +++ b/api/docs/tough-cookie.cookiejar.setcookie_1.md @@ -42,7 +42,7 @@ string \| [Cookie](./tough-cookie.cookie.md) -The cookie object or cookie string to store. A string value will be parsed into a cookie using [Cookie.parse](./tough-cookie.cookie.parse.md). +The cookie object or cookie string to store. A string value will be parsed into a cookie using [Cookie.parse()](./tough-cookie.cookie.parse.md). diff --git a/api/docs/tough-cookie.cookiejar.setcookie_2.md b/api/docs/tough-cookie.cookiejar.setcookie_2.md index 7a6f574f..5867e372 100644 --- a/api/docs/tough-cookie.cookiejar.setcookie_2.md +++ b/api/docs/tough-cookie.cookiejar.setcookie_2.md @@ -42,7 +42,7 @@ string \| [Cookie](./tough-cookie.cookie.md) -The cookie object or cookie string to store. A string value will be parsed into a cookie using [Cookie.parse](./tough-cookie.cookie.parse.md). +The cookie object or cookie string to store. A string value will be parsed into a cookie using [Cookie.parse()](./tough-cookie.cookie.parse.md). diff --git a/api/docs/tough-cookie.cookiejar.setcookiesync.md b/api/docs/tough-cookie.cookiejar.setcookiesync.md index fd6626a3..d09bae88 100644 --- a/api/docs/tough-cookie.cookiejar.setcookiesync.md +++ b/api/docs/tough-cookie.cookiejar.setcookiesync.md @@ -44,7 +44,7 @@ string \| [Cookie](./tough-cookie.cookie.md) -The cookie object or cookie string to store. A string value will be parsed into a cookie using [Cookie.parse](./tough-cookie.cookie.parse.md). +The cookie object or cookie string to store. A string value will be parsed into a cookie using [Cookie.parse()](./tough-cookie.cookie.parse.md). diff --git a/api/docs/tough-cookie.md b/api/docs/tough-cookie.md index 9ff567de..ffd2ab47 100644 --- a/api/docs/tough-cookie.md +++ b/api/docs/tough-cookie.md @@ -24,6 +24,8 @@ Description +An HTTP cookie (web cookie, browser cookie) is a small piece of data that a server sends to a user's web browser. It is defined in [RFC6265](https://www.rfc-editor.org/rfc/rfc6265.html). + @@ -151,15 +153,6 @@ Answers "does this real domain match the domain in a cookie?". The `domain` is t Format a [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) into the [preferred Internet standard format](https://www.rfc-editor.org/rfc/rfc2616#section-3.3.1) defined in [RFC822](https://www.rfc-editor.org/rfc/rfc822#section-5) and updated in [RFC1123](https://www.rfc-editor.org/rfc/rfc1123#page-55). - - - -[fromJSON(str)](./tough-cookie.fromjson.md) - - - - - @@ -171,15 +164,6 @@ Format a [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referenc Returns the public suffix of this hostname. The public suffix is the shortest domain name upon which a cookie can be set. - - - -[parse(str, options)](./tough-cookie.parse.md) - - - - - @@ -334,6 +318,24 @@ Description +[fromJSON](./tough-cookie.fromjson.md) + + + + + + + + +[parse](./tough-cookie.parse.md) + + + + + + + + [PrefixSecurityEnum](./tough-cookie.prefixsecurityenum.md) diff --git a/api/tough-cookie.api.md b/api/tough-cookie.api.md index 424a50c4..da19bc77 100644 --- a/api/tough-cookie.api.md +++ b/api/tough-cookie.api.md @@ -19,88 +19,53 @@ export interface Callback { // @public export function canonicalDomain(domainName: Nullable): string | undefined; -// @public (undocumented) +// @public export class Cookie { // Warning: (ae-forgotten-export) The symbol "CreateCookieOptions" needs to be exported by the entry point index.d.ts constructor(options?: CreateCookieOptions); - // (undocumented) canonicalizedDomain(): string | undefined; - // (undocumented) cdomain(): string | undefined; - // (undocumented) clone(): Cookie | undefined; - // (undocumented) - static cookiesCreated: number; - // (undocumented) cookieString(): string; - // (undocumented) creation: Date | 'Infinity' | null; - // (undocumented) creationIndex: number; - // (undocumented) domain: string | null; - // (undocumented) expires: Date | 'Infinity' | null; - // (undocumented) expiryTime(now?: Date): number | undefined; - // (undocumented) extensions: string[] | null; - // Warning: (ae-forgotten-export) The symbol "fromJSON_2" needs to be exported by the entry point index.d.ts - // - // (undocumented) - static fromJSON: typeof fromJSON_2; - // (undocumented) + static fromJSON(str: unknown): Cookie | undefined; hostOnly: boolean | null; - // (undocumented) httpOnly: boolean; - // (undocumented) isPersistent(): boolean; - // (undocumented) key: string; - // (undocumented) lastAccessed: Date | 'Infinity' | null; - // (undocumented) maxAge: number | 'Infinity' | '-Infinity' | null; - // Warning: (ae-forgotten-export) The symbol "parse_2" needs to be exported by the entry point index.d.ts - // - // (undocumented) - static parse: typeof parse_2; - // (undocumented) + // Warning: (ae-forgotten-export) The symbol "ParseCookieOptions" needs to be exported by the entry point index.d.ts + static parse(str: string, options?: ParseCookieOptions): Cookie | undefined; path: string | null; - // (undocumented) pathIsDefault: boolean | null; - // (undocumented) sameSite: string | undefined; - // (undocumented) + // @internal (undocumented) static sameSiteCanonical: { readonly strict: "Strict"; readonly lax: "Lax"; }; - // (undocumented) + // @internal (undocumented) static sameSiteLevel: { readonly strict: 3; readonly lax: 2; readonly none: 1; }; - // (undocumented) secure: boolean; - // (undocumented) static serializableProperties: readonly ["key", "value", "expires", "maxAge", "domain", "path", "secure", "httpOnly", "extensions", "hostOnly", "pathIsDefault", "creation", "lastAccessed", "sameSite"]; - // (undocumented) setExpires(exp: string | Date): void; - // (undocumented) setMaxAge(age: number): void; // Warning: (ae-forgotten-export) The symbol "SerializedCookie" needs to be exported by the entry point index.d.ts - // - // (undocumented) toJSON(): SerializedCookie; - // (undocumented) toString(): string; - // (undocumented) TTL(now?: number): number; - // (undocumented) + // @beta validate(): boolean; - // (undocumented) value: string; } @@ -186,7 +151,7 @@ export interface ErrorCallback { export function formatDate(date: Date): string; // @public (undocumented) -export const fromJSON: (str: unknown) => Cookie | undefined; +export const fromJSON: typeof Cookie.fromJSON; // @public export interface GetCookiesOptions { @@ -237,9 +202,7 @@ export class ParameterError extends Error { } // @public (undocumented) -export const parse: (str: string, options?: { - loose?: boolean | undefined; -} | undefined) => Cookie | undefined; +export const parse: typeof Cookie.parse; // @public export function parseDate(cookieDate: Nullable): Date | undefined; diff --git a/lib/cookie/constants.ts b/lib/cookie/constants.ts index 0af44db5..ed08ac80 100644 --- a/lib/cookie/constants.ts +++ b/lib/cookie/constants.ts @@ -61,7 +61,11 @@ export interface SerializedCookieJar { cookies: SerializedCookie[] } -export interface SerializedCookie { +/** + * A JSON object that is created when {@link Cookie.toJSON} is called. This object will contain the properties defined in {@link Cookie.serializableProperties}. + * @public + */ +export type SerializedCookie = { key?: string value?: string [key: string]: unknown diff --git a/lib/cookie/cookie.ts b/lib/cookie/cookie.ts index 782234ff..2747502d 100644 --- a/lib/cookie/cookie.ts +++ b/lib/cookie/cookie.ts @@ -111,16 +111,17 @@ function parseCookiePair( return c } -type ParseCookieOptions = { +/** + * Optional configuration to be used when parsing cookies. + * @public + */ +export interface ParseCookieOptions { + /** + * If `true` then keyless cookies like `=abc` and `=` which are not RFC-compliant will be parsed. + */ loose?: boolean | undefined } -/** - * Parses a string into a Cookie object. - * @param str the Set-Cookie header or a Cookie string to parse. Note: when parsing a Cookie header it must be split by ';' before each Cookie string can be parsed. - * @param options configures strict or loose mode for cookie parsing - * @returns `Cookie` object when parsing succeeds, `undefined` when parsing fails. - */ function parse(str: string, options?: ParseCookieOptions): Cookie | undefined { if (validators.isEmptyString(str) || !validators.isString(str)) { return undefined @@ -371,7 +372,11 @@ function fromJSON(str: unknown): Cookie | undefined { return c } -type CreateCookieOptions = Omit< +/** + * Type alias for all the cookie properties defined by {@link Cookie} (except for {@link Cookie.creationIndex}). + * @public + */ +export 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 @@ -401,23 +406,101 @@ const cookieDefaults = { sameSite: undefined, } as const satisfies Required +/** + * An HTTP cookie (web cookie, browser cookie) is a small piece of data that a server sends to a user's web browser. + * It is defined in {@link https://www.rfc-editor.org/rfc/rfc6265.html | RFC6265}. + * @public + */ export class Cookie { + /** + * The name or key of the cookie + */ key: string + /** + * The value of the cookie + */ value: string + /** + * The 'Expires' attribute of the cookie + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.1 | RFC6265 Section 5.2.1}). + */ expires: Date | 'Infinity' | null + /** + * The 'Max-Age' attribute of the cookie + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.2 | RFC6265 Section 5.2.2}). + */ maxAge: number | 'Infinity' | '-Infinity' | null + /** + * The 'Domain' attribute of the cookie represents the domain the cookie belongs to + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.3 | RFC6265 Section 5.2.3}). + */ domain: string | null + /** + * The 'Path' attribute of the cookie represents the path of the cookie + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.4 | RFC6265 Section 5.2.4}). + */ path: string | null + /** + * The 'Secure' flag of the cookie indicates if the scope of the cookie is + * limited to secure channels (e.g.; HTTPS) or not + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.5 | RFC6265 Section 5.2.5}). + */ secure: boolean + /** + * The 'HttpOnly' flag of the cookie indicates if the cookie is inaccessible to + * client scripts or not + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.6 | RFC6265 Section 5.2.6}). + */ httpOnly: boolean + /** + * Contains attributes which are not part of the defined spec but match the `extension-av` syntax + * defined in Section 4.1.1 of RFC6265 + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-4.1.1 | RFC6265 Section 4.1.1}). + */ extensions: string[] | null + /** + * Set to the date and time when a Cookie is initially stored or a matching cookie is + * received that replaces an existing cookie + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.3 | RFC6265 Section 5.3}). + * + * Also used to maintain ordering among cookies. Among cookies that have equal-length path fields, + * cookies with earlier creation-times are listed before cookies with later creation-times + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4 | RFC6265 Section 5.4}). + */ creation: Date | 'Infinity' | null + /** + * A global counter used to break ordering ties between two cookies that have equal-length path fields + * and the same creation-time. + */ creationIndex: number + /** + * A boolean flag indicating if a cookie is a host-only cookie (i.e.; when the request's host exactly + * matches the domain of the cookie) or not + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.3 | RFC6265 Section 5.3}). + */ hostOnly: boolean | null + /** + * A boolean flag indicating if a cookie had no 'Path' attribute and the default path + * was used + * (See {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.4 | RFC6265 Section 5.2.4}). + */ pathIsDefault: boolean | null + /** + * Set to the date and time when a cookie was initially stored ({@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.3 | RFC6265 Section 5.3}) and updated whenever + * the cookie is retrieved from the {@link CookieJar} ({@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4 | RFC6265 Section 5.4}). + */ lastAccessed: Date | 'Infinity' | null + /** + * The 'SameSite' attribute of a cookie as defined in RFC6265bis + * (See {@link https://www.ietf.org/archive/id/draft-ietf-httpbis-rfc6265bis-13.html#section-5.2 | RFC6265bis (v13) Section 5.2 }). + */ sameSite: string | undefined + /** + * Create a new Cookie instance. + * @public + * @param options - The attributes to set on the cookie + */ constructor(options: CreateCookieOptions = {}) { this.key = options.key ?? cookieDefaults.key this.value = options.value ?? cookieDefaults.value @@ -461,6 +544,15 @@ export class Cookie { return `Cookie="${this.toString()}; hostOnly=${hostOnly}; aAge=${accessAge}; cAge=${createAge}"` } + /** + * For convenience in using `JSON.stringify(cookie)`. Returns a plain-old Object that can be JSON-serialized. + * + * @remarks + * - Any `Date` properties (such as {@link Cookie.expires}, {@link Cookie.creation}, and {@link Cookie.lastAccessed}) are exported in ISO format (`Date.toISOString()`). + * + * - Custom Cookie properties are discarded. In tough-cookie 1.x, since there was no {@link Cookie.toJSON} method explicitly defined, all enumerable properties were captured. + * If you want a property to be serialized, add the property name to {@link Cookie.serializableProperties}. + */ toJSON(): SerializedCookie { const obj: SerializedCookie = {} @@ -531,10 +623,23 @@ export class Cookie { return obj } + /** + * Does a deep clone of this cookie, implemented exactly as `Cookie.fromJSON(cookie.toJSON())`. + * @public + */ clone(): Cookie | undefined { return fromJSON(this.toJSON()) } + /** + * Validates cookie attributes for semantic correctness. Useful for "lint" checking any `Set-Cookie` headers you generate. + * For now, it returns a boolean, but eventually could return a reason string. + * + * @remarks + * Works for a few things, but is by no means comprehensive. + * + * @beta + */ validate(): boolean { if (this.value == null || !COOKIE_OCTETS.test(this.value)) { return false @@ -571,6 +676,15 @@ export class Cookie { return true } + /** + * Sets the 'Expires' attribute on a cookie. + * + * @remarks + * When given a `string` value it will be parsed with {@link parseDate}. If the value can't be parsed as a cookie date + * then the 'Expires' attribute will be set to `"Infinity"`. + * + * @param exp - the new value for the 'Expires' attribute of the cookie. + */ setExpires(exp: string | Date): void { if (exp instanceof Date) { this.expires = exp @@ -579,6 +693,14 @@ export class Cookie { } } + /** + * Sets the 'Max-Age' attribute (in seconds) on a cookie. + * + * @remarks + * Coerces `-Infinity` to `"-Infinity"` and `Infinity` to `"Infinity"` so it can be serialized to JSON. + * + * @param age - the new value for the 'Max-Age' attribute (in seconds). + */ setMaxAge(age: number): void { if (age === Infinity) { this.maxAge = 'Infinity' @@ -589,6 +711,10 @@ export class Cookie { } } + /** + * Encodes to a `Cookie` header value (specifically, the {@link Cookie.key} and {@link Cookie.value} properties joined with "="). + * @public + */ cookieString(): string { const val = this.value ?? '' if (this.key) { @@ -597,7 +723,10 @@ export class Cookie { return val } - // gives Set-Cookie header format + /** + * Encodes to a `Set-Cookie header` value. + * @public + */ toString(): string { let str = this.cookieString() @@ -648,16 +777,29 @@ export class Cookie { return str } - // TTL() partially replaces the "expiry-time" parts of S5.3 step 3 (setCookie() - // elsewhere) - // S5.3 says to give the "latest representable date" for which we use Infinity - // For "expired" we use 0 + /** + * Computes the TTL relative to now (milliseconds). + * + * @remarks + * - `Infinity` is returned for cookies without an explicit expiry + * + * - `0` is returned if the cookie is expired. + * + * - Otherwise a time-to-live in milliseconds is returned. + * + * @param now - passing an explicit value is mostly used for testing purposes since this defaults to the `Date.now()` + * @public + */ TTL(now: number = Date.now()): number { - /* RFC6265 S4.1.2.2 If a cookie has both the Max-Age and the Expires - * attribute, the Max-Age attribute has precedence and controls the - * expiration date of the cookie. - * (Concurs with S5.3 step 3) - */ + // TTL() partially replaces the "expiry-time" parts of S5.3 step 3 (setCookie() + // elsewhere) + // S5.3 says to give the "latest representable date" for which we use Infinity + // For "expired" we use 0 + // ----- + // RFC6265 S4.1.2.2 If a cookie has both the Max-Age and the Expires + // attribute, the Max-Age attribute has precedence and controls the + // expiration date of the cookie. + // (Concurs with S5.3 step 3) if (this.maxAge != null && typeof this.maxAge === 'number') { return this.maxAge <= 0 ? 0 : this.maxAge * 1000 } @@ -670,9 +812,18 @@ export class Cookie { return (expires?.getTime() ?? now) - (now || Date.now()) } - // expiryTime() replaces the "expiry-time" parts of S5.3 step 3 (setCookie() - // elsewhere) + /** + * Computes the absolute unix-epoch milliseconds that this cookie expires. + * + * The "Max-Age" attribute takes precedence over "Expires" (as per the RFC). The {@link Cookie.lastAccessed} attribute + * (or the `now` parameter if given) is used to offset the {@link Cookie.maxAge} attribute. + * + * If Expires ({@link Cookie.expires}) is set, that's returned. + * + * @param now - can be used to provide a time offset (instead of {@link Cookie.lastAccessed}) to use when calculating the "Max-Age" value + */ expiryTime(now?: Date): number | undefined { + // expiryTime() replaces the "expiry-time" parts of S5.3 step 3 (setCookie() elsewhere) if (this.maxAge != null) { const relativeTo = now || this.lastAccessed || new Date() const maxAge = typeof this.maxAge === 'number' ? this.maxAge : -Infinity @@ -690,37 +841,120 @@ export class Cookie { return this.expires ? this.expires.getTime() : undefined } - // This replaces the "persistent-flag" parts of S5.3 step 3 + /** + * Indicates if the cookie has been persisted to a store or not. + * @public + */ isPersistent(): boolean { + // This replaces the "persistent-flag" parts of S5.3 step 3 return this.maxAge != null || this.expires != 'Infinity' } - // Mostly S5.1.2 and S5.2.3: + /** + * Calls {@link canonicalDomain} with the {@link Cookie.domain} property. + * @public + */ canonicalizedDomain(): string | undefined { + // Mostly S5.1.2 and S5.2.3: return canonicalDomain(this.domain) } + /** + * Alias for {@link Cookie.canonicalizedDomain} + * @public + */ cdomain(): string | undefined { return canonicalDomain(this.domain) } - static parse = parse + /** + * Parses a string into a Cookie object. + * + * @remarks + * Note: when parsing a `Cookie` header it must be split by ';' before each Cookie string can be parsed. + * + * @example + * ``` + * // parse a `Set-Cookie` header + * const setCookieHeader = 'a=bcd; Expires=Tue, 18 Oct 2011 07:05:03 GMT' + * const cookie = Cookie.parse(setCookieHeader) + * cookie.key === 'a' + * cookie.value === 'bcd' + * cookie.expires === new Date(Date.parse('Tue, 18 Oct 2011 07:05:03 GMT')) + * ``` + * + * @example + * ``` + * // parse a `Cookie` header + * const cookieHeader = 'name=value; name2=value2; name3=value3' + * const cookies = cookieHeader.split(';').map(Cookie.parse) + * cookies[0].name === 'name' + * cookies[0].value === 'value' + * cookies[1].name === 'name2' + * cookies[1].value === 'value2' + * cookies[2].name === 'name3' + * cookies[2].value === 'value3' + * ``` + * + * @param str - The `Set-Cookie` header or a Cookie string to parse. + * @param options - Configures `strict` or `loose` mode for cookie parsing + */ + static parse(str: string, options?: ParseCookieOptions): Cookie | undefined { + return parse(str, options) + } - static fromJSON = fromJSON + /** + * Does the reverse of {@link Cookie.toJSON}. + * + * @remarks + * Any Date properties (such as .expires, .creation, and .lastAccessed) are parsed via Date.parse, not tough-cookie's parseDate, since ISO timestamps are being handled at this layer. + * + * @example + * ``` + * const json = JSON.stringify({ + * key: 'alpha', + * value: 'beta', + * domain: 'example.com', + * path: '/foo', + * expires: '2038-01-19T03:14:07.000Z', + * }) + * const cookie = Cookie.fromJSON(json) + * cookie.key === 'alpha' + * cookie.value === 'beta' + * cookie.domain === 'example.com' + * cookie.path === '/foo' + * cookie.expires === new Date(Date.parse('2038-01-19T03:14:07.000Z')) + * ``` + * + * @param str - An unparsed JSON string or a value that has already been parsed as JSON + */ + static fromJSON(str: unknown): Cookie | undefined { + return fromJSON(str) + } - static cookiesCreated = 0 + private static cookiesCreated = 0 + /** + * @internal + */ static sameSiteLevel = { strict: 3, lax: 2, none: 1, } as const + /** + * @internal + */ static sameSiteCanonical = { strict: 'Strict', lax: 'Lax', } as const + /** + * Cookie properties that will be serialized when using {@link Cookie.fromJSON} and {@link Cookie.toJSON}. + * @public + */ static serializableProperties = [ 'key', 'value',