Skip to content

Commit

Permalink
Implement getAll method (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Kennedy committed Aug 8, 2020
1 parent fe99d16 commit 11c5d06
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 26 deletions.
11 changes: 2 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,8 @@ console.log(foo); // { name: 'forgive', value: 'me' }
await cookieStore.set('forget', 'it');

// get multiple cookies
const cookies = await cookieStore.getAll({
name: 'for',
matchType: 'starts-with',
});
const obj = {};
for (const cookie of cookies) {
obj[cookie.name] = cookie.value;
}
console.log(obj); // { forgive: 'me', forget: 'it' }
const cookies = await cookieStore.getAll();
console.log(obj); // [{ name: 'forgive', value: 'me' }, { name: 'forget', value: 'it' }]

// delete a cookie
await cookieStore.delete('forget');
Expand Down
24 changes: 23 additions & 1 deletion index.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,28 @@ describe('Cookie Store', () => {
expect(result).to.deep.equal({ name: foo, value: bar });
});
});
describe('getAll', () => {
it('returns an array with all cookies if no name is provided', async () => {
const foo = 'foo';
const bar = 'bar';
const baz = 'baz';
document.cookie = `${foo}=${bar}; ${bar}=${baz}`;
const result = await window.cookieStore.getAll();
expect(result).to.deep.equal([
{ name: foo, value: bar },
{ name: bar, value: baz },
]);
});

it('returns an array with cookies that match name', async () => {
const foo = 'foo';
const bar = 'bar';
const baz = 'baz';
document.cookie = `${foo}=${bar}; ${bar}=${baz}`;
const result = await window.cookieStore.getAll(bar);
expect(result).to.deep.equal([{ name: bar, value: baz }]);
});
});
describe('set', () => {
it('updates document.cookie with supplied value', async () => {
await window.cookieStore.set('foo', 'bar');
Expand All @@ -33,7 +55,7 @@ describe('Cookie Store', () => {
it('sets max age to 0 on cookie that matches supplied name', async () => {
document.cookie = 'foo=bar';
await window.cookieStore.delete('foo');
expect(document.cookie).to.equal('foo=bar; Max-Age=0; Path=/');
expect(document.cookie).to.equal('foo=bar; Max-Age=0');
});
});
});
61 changes: 45 additions & 16 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function tryDecode(
}

type CookieSameSite = 'no_restriction' | 'lax' | 'strict';
type CookieMatchType = 'equals';

interface Cookie {
domain?: string;
Expand All @@ -50,11 +51,15 @@ interface Cookie {

interface CookieStoreDeleteOptions {
name: string;
domain: null;
path: '/';
domain?: string;
path?: string;
}

type ParsedCookies = Record<string, Cookie>;
interface CookieStoreGetOptions {
name?: string;
url?: string;
matchType?: CookieMatchType;
}

interface ParseOptions {
decode?: boolean;
Expand Down Expand Up @@ -83,12 +88,12 @@ interface SerializeOptions {
* @private
*/

function parse(str, options: ParseOptions = {}): ParsedCookies {
function parse(str, options: ParseOptions = {}): Cookie[] {
if (typeof str !== 'string') {
throw new TypeError('argument str must be a string');
}

const obj: ParsedCookies = {};
const obj = [];
const opt = options || {};
const pairs = str.split(pairSplitRegExp);
const dec = opt.decode || decode;
Expand All @@ -112,10 +117,10 @@ function parse(str, options: ParseOptions = {}): ParsedCookies {

// only assign once
if (undefined == obj[key]) {
obj[key] = {
obj.push({
name: key,
value: tryDecode(val, dec),
};
});
}
}

Expand Down Expand Up @@ -223,15 +228,30 @@ function serialize(name, val, options: SerializeOptions = {}): string {
return str;
}

function sanitizeOptions(
arg: unknown
): CookieStoreGetOptions | CookieStoreDeleteOptions {
if (!arg) {
return {};
}
if (typeof arg === 'string') {
return { name: arg };
}
return arg;
}

const CookieStore = {
/**
* Get a cookie.
*
* @param {string} name
* @return {Promise}
*/
get(name): Promise<Cookie> {
return Promise.resolve(parse(document.cookie)[name]);
async get(
options?: CookieStoreGetOptions['name'] | CookieStoreGetOptions
): Promise<Cookie> {
const { name } = sanitizeOptions(options);
return parse(document.cookie).find((cookie) => cookie.name === name);
},

/**
Expand All @@ -255,11 +275,16 @@ const CookieStore = {

/**
* Get multiple cookies.
*
* @return {Promise}
*/
getAll(): Promise<void> {
throw Error('getAll not implemented, coming soon though.');
async getAll(
options?: CookieStoreGetOptions['name'] | CookieStoreGetOptions
): Promise<Cookie[]> {
const { name } = sanitizeOptions(options);
if (name) {
const cookie = await this.get(name);
return [cookie];
}
return parse(document.cookie);
},

/**
Expand All @@ -268,12 +293,16 @@ const CookieStore = {
* @param {String} name
* @return {Promise}
*/
async delete(name: CookieStoreDeleteOptions['name']): Promise<void> {
async delete(
options: CookieStoreDeleteOptions['name'] | CookieStoreDeleteOptions
): Promise<void> {
const { name, domain } = sanitizeOptions(
options
) as CookieStoreDeleteOptions;
const { value } = await this.get(name);
const serializedValue = serialize(name, value, {
maxAge: 0,
domain: null,
path: '/',
domain,
});
document.cookie = serializedValue;
return Promise.resolve();
Expand Down

0 comments on commit 11c5d06

Please sign in to comment.