feat(core/utils/puppeteer-utils): Cookie utils (#11471)

Signed-off-by: Rongrong <i@rong.moe>

Signed-off-by: Rongrong <i@rong.moe>
This commit is contained in:
Rongrong
2022-12-20 19:51:33 +08:00
committed by GitHub
parent 7838a1e6d8
commit 9264d7afbe
3 changed files with 168 additions and 2 deletions

View File

@@ -0,0 +1,63 @@
/**
* Get Cookie-header-style cookie string from a puppeteer-style cookie array
*
* @param {import('puppeteer').Protocol.Network.CookieParam[]} cookies Puppeteer-style cookie array
* @param {RegExp | string} domainFilter Filter cookies by domain or RegExp
* @return {string} Cookie-header-style cookie string (e.g. "foobar; foo=bar; baz=qux")
*/
const parseCookieArray = (cookies, domainFilter = null) => {
if (typeof domainFilter === 'string') {
const dotDomain = '.' + domainFilter;
cookies = cookies.filter(({ domain }) => domain === domainFilter || domain.endsWith(dotDomain));
} else if (domainFilter && domainFilter.test !== undefined) {
cookies = cookies.filter(({ domain }) => domainFilter.test(domain));
}
// {name: '', value: 'foobar'} => 'foobar' // https://stackoverflow.com/questions/42531198/cookie-without-a-name
// {name: 'foo', value: 'bar'} => 'foo=bar'
return cookies.map(({ name, value }) => (name ? `${name}=${value}` : value)).join('; ');
};
/**
* Construct a puppeteer-style cookie array from a Cookie-header-style cookie string
*
* @param {string} cookieStr Cookie-header-style cookie string (e.g. "foobar; foo=bar; baz=qux")
* @param {string} domain Domain to set for each cookie
* @return {import('puppeteer').Protocol.Network.CookieParam[]} Puppeteer-style cookie array
*/
const constructCookieArray = (cookieStr, domain) =>
cookieStr.split('; ').map((item) => {
const [name, value] = item.split('=');
return value === undefined ? { name: '', value: name, domain } : { name, value, domain };
});
/**
* Set cookies for a page
*
* @param {import('puppeteer').Page} page Puppeteer Page object
* @param {string} cookieStr Cookie-header-style cookie string (e.g. "foobar; foo=bar; baz=qux")
* @param {string} domain Domain to set for each cookie
* @return {Promise<void>}
*/
const setCookies = async (page, cookieStr, domain) => {
const cookies = constructCookieArray(cookieStr, domain);
await page.setCookie(...cookies);
};
/**
* Get Cookie-header-style cookie string from a page
*
* @param {import('puppeteer').Page} page Puppeteer Page object
* @param {RegExp | string} domainFilter Filter cookies by domain or RegExp
* @return {Promise<string>} Cookie-header-style cookie string
*/
const getCookies = async (page, domainFilter = null) => {
const cookies = await page.cookies();
return parseCookieArray(cookies, domainFilter);
};
module.exports = {
parseCookieArray,
constructCookieArray,
setCookies,
getCookies,
};