Greasy Fork is available in English.

cookie-umd

UMD build of cookie

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greasyfork.org/scripts/501949/1418023/cookie-umd.js

// ==UserScript==
// @name          cookie-umd
// @namespace     flomk.userscripts
// @version       1.0
// @description   UMD build of cookie
// @author        flomk
// ==/UserScript==
(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
	typeof define === 'function' && define.amd ? define(['exports'], factory) :
	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.cookie = {}));
})(this, (function (exports) { 'use strict';
    const __toString = Object.prototype.toString
    
    /**
     * RegExp to match field-content in RFC 7230 sec 3.2
     *
     * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
     * field-vchar   = VCHAR / obs-text
     * obs-text      = %x80-FF
     */
    
    const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
    
    /**
     * Parse a cookie header.
     *
     * Parse the given cookie header string into an object
     * The object has the various cookies as keys(names) => values
     *
     * @param {string} str
     * @param {object} [options]
     * @return {object}
     * @public
     */
    
    const parse = (str, options) => {
        if (typeof str !== 'string') {
            throw new TypeError('argument str must be a string');
        }
    
        var obj = {}
        var opt = options || {};
        var dec = opt.decode || decode;
    
        var index = 0
        while (index < str.length) {
            var eqIdx = str.indexOf('=', index)
    
            // no more cookie pairs
            if (eqIdx === -1) {
                break
            }
    
            var endIdx = str.indexOf(';', index)
    
            if (endIdx === -1) {
                endIdx = str.length
            } else if (endIdx < eqIdx) {
                // backtrack on prior semicolon
                index = str.lastIndexOf(';', eqIdx - 1) + 1
                continue
            }
    
            var key = str.slice(index, eqIdx).trim()
    
            // only assign once
            if (undefined === obj[key]) {
                var val = str.slice(eqIdx + 1, endIdx).trim()
    
                // quoted values
                if (val.charCodeAt(0) === 0x22) {
                    val = val.slice(1, -1)
                }
    
                obj[key] = tryDecode(val, dec);
            }
    
            index = endIdx + 1
        }
    
        return obj;
    };
    
    /**
     * Serialize data into a cookie header.
     *
     * Serialize the a name value pair into a cookie string suitable for
     * http headers. An optional options object specified cookie parameters.
     *
     * serialize('foo', 'bar', { httpOnly: true })
     *   => "foo=bar; httpOnly"
     *
     * @param {string} name
     * @param {string} val
     * @param {object} [options]
     * @return {string}
     * @public
     */
    
    const serialize = (name, val, options) => {
        var opt = options || {};
        var enc = opt.encode || encode;
    
        if (typeof enc !== 'function') {
            throw new TypeError('option encode is invalid');
        }
    
        if (!fieldContentRegExp.test(name)) {
            throw new TypeError('argument name is invalid');
        }
    
        var value = enc(val);
    
        if (value && !fieldContentRegExp.test(value)) {
            throw new TypeError('argument val is invalid');
        }
    
        var str = name + '=' + value;
    
        if (null != opt.maxAge) {
            var maxAge = opt.maxAge - 0;
    
            if (isNaN(maxAge) || !isFinite(maxAge)) {
                throw new TypeError('option maxAge is invalid')
            }
    
            str += '; Max-Age=' + Math.floor(maxAge);
        }
    
        if (opt.domain) {
            if (!fieldContentRegExp.test(opt.domain)) {
                throw new TypeError('option domain is invalid');
            }
    
            str += '; Domain=' + opt.domain;
        }
    
        if (opt.path) {
            if (!fieldContentRegExp.test(opt.path)) {
                throw new TypeError('option path is invalid');
            }
    
            str += '; Path=' + opt.path;
        }
    
        if (opt.expires) {
            var expires = opt.expires
    
            if (!isDate(expires) || isNaN(expires.valueOf())) {
                throw new TypeError('option expires is invalid');
            }
    
            str += '; Expires=' + expires.toUTCString()
        }
    
        if (opt.httpOnly) {
            str += '; HttpOnly';
        }
    
        if (opt.secure) {
            str += '; Secure';
        }
    
        if (opt.partitioned) {
            str += '; Partitioned'
        }
    
        if (opt.priority) {
            var priority = typeof opt.priority === 'string'
                ? opt.priority.toLowerCase()
                : opt.priority
    
            switch (priority) {
                case 'low':
                    str += '; Priority=Low'
                    break
                case 'medium':
                    str += '; Priority=Medium'
                    break
                case 'high':
                    str += '; Priority=High'
                    break
                default:
                    throw new TypeError('option priority is invalid')
            }
        }
    
        if (opt.sameSite) {
            var sameSite = typeof opt.sameSite === 'string'
                ? opt.sameSite.toLowerCase() : opt.sameSite;
    
            switch (sameSite) {
                case true:
                    str += '; SameSite=Strict';
                    break;
                case 'lax':
                    str += '; SameSite=Lax';
                    break;
                case 'strict':
                    str += '; SameSite=Strict';
                    break;
                case 'none':
                    str += '; SameSite=None';
                    break;
                default:
                    throw new TypeError('option sameSite is invalid');
            }
        }
    
        return str;
    };
    
    /**
     * URL-decode string value. Optimized to skip native call when no %.
     *
     * @param {string} str
     * @returns {string}
     */
    
    const decode = str => str.indexOf('%') !== -1 ? decodeURIComponent(str) : str;
    
    /**
     * URL-encode value.
     *
     * @param {string} val
     * @returns {string}
     */
    
    const encode = val => encodeURIComponent(val);
    
    /**
     * Determine if value is a Date.
     *
     * @param {*} val
     * @private
     */
    
    const isDate = val => __toString.call(val) === '[object Date]' || val instanceof Date;
    
    /**
     * Try decoding a string using a decoding function.
     *
     * @param {string} str
     * @param {function} decode
     * @private
     */
    
    const tryDecode = (str, decode) => {
        try {
            return decode(str);
        } catch (e) {
            return str;
        }
    };
    
    
    
    exports.parse = parse;
    exports.serialize = serialize;
}));