UNPKG

next-csrf

Version:

CSRF mitigation library for Next.js

288 lines (227 loc) 8.33 kB
"use strict"; exports.__esModule = true; exports["default"] = void 0; function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /* Based on Glamor's sheet https://github.com/threepointone/glamor/blob/667b480d31b3721a905021b26e1290ce92ca2879/src/sheet.js */ var isProd = typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'production'; var isString = function isString(o) { return Object.prototype.toString.call(o) === '[object String]'; }; var StyleSheet = /*#__PURE__*/ function () { function StyleSheet(_temp) { var _ref = _temp === void 0 ? {} : _temp, _ref$name = _ref.name, name = _ref$name === void 0 ? 'stylesheet' : _ref$name, _ref$optimizeForSpeed = _ref.optimizeForSpeed, optimizeForSpeed = _ref$optimizeForSpeed === void 0 ? isProd : _ref$optimizeForSpeed, _ref$isBrowser = _ref.isBrowser, isBrowser = _ref$isBrowser === void 0 ? typeof window !== 'undefined' : _ref$isBrowser; invariant(isString(name), '`name` must be a string'); this._name = name; this._deletedRulePlaceholder = "#" + name + "-deleted-rule____{}"; invariant(typeof optimizeForSpeed === 'boolean', '`optimizeForSpeed` must be a boolean'); this._optimizeForSpeed = optimizeForSpeed; this._isBrowser = isBrowser; this._serverSheet = undefined; this._tags = []; this._injected = false; this._rulesCount = 0; var node = this._isBrowser && document.querySelector('meta[property="csp-nonce"]'); this._nonce = node ? node.getAttribute('content') : null; } var _proto = StyleSheet.prototype; _proto.setOptimizeForSpeed = function setOptimizeForSpeed(bool) { invariant(typeof bool === 'boolean', '`setOptimizeForSpeed` accepts a boolean'); invariant(this._rulesCount === 0, 'optimizeForSpeed cannot be when rules have already been inserted'); this.flush(); this._optimizeForSpeed = bool; this.inject(); }; _proto.isOptimizeForSpeed = function isOptimizeForSpeed() { return this._optimizeForSpeed; }; _proto.inject = function inject() { var _this = this; invariant(!this._injected, 'sheet already injected'); this._injected = true; if (this._isBrowser && this._optimizeForSpeed) { this._tags[0] = this.makeStyleTag(this._name); this._optimizeForSpeed = 'insertRule' in this.getSheet(); if (!this._optimizeForSpeed) { if (!isProd) { console.warn('StyleSheet: optimizeForSpeed mode not supported falling back to standard mode.'); } this.flush(); this._injected = true; } return; } this._serverSheet = { cssRules: [], insertRule: function insertRule(rule, index) { if (typeof index === 'number') { _this._serverSheet.cssRules[index] = { cssText: rule }; } else { _this._serverSheet.cssRules.push({ cssText: rule }); } return index; }, deleteRule: function deleteRule(index) { _this._serverSheet.cssRules[index] = null; } }; }; _proto.getSheetForTag = function getSheetForTag(tag) { if (tag.sheet) { return tag.sheet; } // this weirdness brought to you by firefox for (var i = 0; i < document.styleSheets.length; i++) { if (document.styleSheets[i].ownerNode === tag) { return document.styleSheets[i]; } } }; _proto.getSheet = function getSheet() { return this.getSheetForTag(this._tags[this._tags.length - 1]); }; _proto.insertRule = function insertRule(rule, index) { invariant(isString(rule), '`insertRule` accepts only strings'); if (!this._isBrowser) { if (typeof index !== 'number') { index = this._serverSheet.cssRules.length; } this._serverSheet.insertRule(rule, index); return this._rulesCount++; } if (this._optimizeForSpeed) { var sheet = this.getSheet(); if (typeof index !== 'number') { index = sheet.cssRules.length; } // this weirdness for perf, and chrome's weird bug // https://stackoverflow.com/questions/20007992/chrome-suddenly-stopped-accepting-insertrule try { sheet.insertRule(rule, index); } catch (error) { if (!isProd) { console.warn("StyleSheet: illegal rule: \n\n" + rule + "\n\nSee https://stackoverflow.com/q/20007992 for more info"); } return -1; } } else { var insertionPoint = this._tags[index]; this._tags.push(this.makeStyleTag(this._name, rule, insertionPoint)); } return this._rulesCount++; }; _proto.replaceRule = function replaceRule(index, rule) { if (this._optimizeForSpeed || !this._isBrowser) { var sheet = this._isBrowser ? this.getSheet() : this._serverSheet; if (!rule.trim()) { rule = this._deletedRulePlaceholder; } if (!sheet.cssRules[index]) { // @TBD Should we throw an error? return index; } sheet.deleteRule(index); try { sheet.insertRule(rule, index); } catch (error) { if (!isProd) { console.warn("StyleSheet: illegal rule: \n\n" + rule + "\n\nSee https://stackoverflow.com/q/20007992 for more info"); } // In order to preserve the indices we insert a deleteRulePlaceholder sheet.insertRule(this._deletedRulePlaceholder, index); } } else { var tag = this._tags[index]; invariant(tag, "old rule at index `" + index + "` not found"); tag.textContent = rule; } return index; }; _proto.deleteRule = function deleteRule(index) { if (!this._isBrowser) { this._serverSheet.deleteRule(index); return; } if (this._optimizeForSpeed) { this.replaceRule(index, ''); } else { var tag = this._tags[index]; invariant(tag, "rule at index `" + index + "` not found"); tag.parentNode.removeChild(tag); this._tags[index] = null; } }; _proto.flush = function flush() { this._injected = false; this._rulesCount = 0; if (this._isBrowser) { this._tags.forEach(function (tag) { return tag && tag.parentNode.removeChild(tag); }); this._tags = []; } else { // simpler on server this._serverSheet.cssRules = []; } }; _proto.cssRules = function cssRules() { var _this2 = this; if (!this._isBrowser) { return this._serverSheet.cssRules; } return this._tags.reduce(function (rules, tag) { if (tag) { rules = rules.concat(Array.prototype.map.call(_this2.getSheetForTag(tag).cssRules, function (rule) { return rule.cssText === _this2._deletedRulePlaceholder ? null : rule; })); } else { rules.push(null); } return rules; }, []); }; _proto.makeStyleTag = function makeStyleTag(name, cssString, relativeToTag) { if (cssString) { invariant(isString(cssString), 'makeStyleTag acceps only strings as second parameter'); } var tag = document.createElement('style'); if (this._nonce) tag.setAttribute('nonce', this._nonce); tag.type = 'text/css'; tag.setAttribute("data-" + name, ''); if (cssString) { tag.appendChild(document.createTextNode(cssString)); } var head = document.head || document.getElementsByTagName('head')[0]; if (relativeToTag) { head.insertBefore(tag, relativeToTag); } else { head.appendChild(tag); } return tag; }; _createClass(StyleSheet, [{ key: "length", get: function get() { return this._rulesCount; } }]); return StyleSheet; }(); exports["default"] = StyleSheet; function invariant(condition, message) { if (!condition) { throw new Error("StyleSheet: " + message + "."); } }