UNPKG

3.56 kBPlain TextView Raw
1// deno-lint-ignore-file
2import {
3 CookieStore, CookieListItem, CookieInit, CookieList, CookieStoreDeleteOptions, CookieStoreGetOptions
4} from "@worker-tools/request-cookie-store";
5import { ExtendablePromise } from "@worker-tools/extendable-promise";
6import { Cookies, cookiesFrom } from "../cookies.js";
7
8const encode = encodeURIComponent;
9function decodeItem<Item extends CookieListItem | null>(item: Item) {
10 if (item) {
11 item.name = decodeURIComponent(item.name);
12 item.value = decodeURIComponent(item.value);
13 }
14 return item;
15}
16
17/**
18 * A more opinionated cookie store implementation that
19 * - URI-(en|de)codes cookie values and
20 * - provides a promise that resolves when all async operations associated with this store have settled.
21 */
22export class MiddlewareCookieStore implements CookieStore {
23 #promise: ExtendablePromise<void>;
24 #store: CookieStore;
25 constructor(store: CookieStore, requestDuration: Promise<void>) {
26 this.#store = store;
27 this.#promise = new ExtendablePromise<void>(requestDuration);
28 }
29 get(name?: string): Promise<CookieListItem | null>;
30 get(options?: CookieStoreGetOptions): Promise<CookieListItem | null>;
31 async get(options?: any): Promise<CookieListItem | null> {
32 return decodeItem(await this.#store.get(options));
33 }
34 getAll(name?: string): Promise<CookieList>;
35 getAll(options?: CookieStoreGetOptions): Promise<CookieList>;
36 async getAll(options?: any): Promise<CookieList> {
37 return (await this.#store.getAll(options)).map(decodeItem);
38 }
39 set(name: string, value: string): Promise<void>;
40 set(options: CookieInit): Promise<void>;
41 set(name: string | CookieInit, value?: string): Promise<void> {
42 let res: Promise<void>;
43 if (typeof name === 'string' && typeof value === 'string') {
44 res = this.#store.set(encode(name), encode(value));
45 } else if (name && typeof name === 'object') {
46 const options = name;
47 options.name = encode(options.name)
48 options.value = encode(options.value)
49 res = this.#store.set(options);
50 } else throw Error('Illegal invocation');
51 this.#promise.waitUntil(res);
52 return res;
53 }
54 delete(name: string): Promise<void>;
55 delete(options: CookieStoreDeleteOptions): Promise<void>;
56 delete(options: any): Promise<void> {
57 const res = this.#store.delete(options)
58 this.#promise.waitUntil(res);
59 return res;
60 }
61
62 addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void;
63 addEventListener(type: any, callback: any, options?: any): void {
64 this.#store.addEventListener(type, callback, options);
65 }
66 dispatchEvent(event: Event): boolean;
67 dispatchEvent(event: any): boolean {
68 return this.#store.dispatchEvent(event);
69 }
70 removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: boolean | EventListenerOptions): void;
71 removeEventListener(type: any, callback: any, options?: any): void {
72 this.#store.removeEventListener(type, callback, options);
73 }
74
75 /** @deprecated Name of this property might change */
76 get settled() { return this.#promise.settled }
77 /** @deprecated Name of this property might change */
78 get allSettledPromise() { return Promise.resolve(this.#promise) }
79
80 /**
81 * If you've made changes to the store and would like to access the current cookies as an object,
82 * it is provided as a promise here (TODO:)
83 * @deprecated This method might change names
84 */
85 get updatedCookies(): Promise<Cookies> {
86 return cookiesFrom(this)
87 }
88}