From f99106743c32d616080f69ba85647039470d58a9 Mon Sep 17 00:00:00 2001 From: build-token <build-token> Date: Tue, 2 Aug 2022 10:10:11 +0000 Subject: [PATCH] publish: Merge remote-tracking branch 'origin/main' into feat/insee-code generated from commit 58baa01c358a466a6f88b241971df5b3faae30b2 --- index.js | 112321 ++++++++++++++++++++++++------------------------ package.json | 6 +- 2 files changed, 56302 insertions(+), 56025 deletions(-) diff --git a/index.js b/index.js index 6ed7fba..9043f7c 100644 --- a/index.js +++ b/index.js @@ -527,7 +527,7 @@ async function findUserPdl( const requestFactory = __webpack_require__(2); -const hydrateAndFilter = __webpack_require__(341); +const hydrateAndFilter = __webpack_require__(353); const categorization = __webpack_require__(1226); @@ -536,7 +536,7 @@ const log = __webpack_require__(1243); module.exports = { BaseKonnector: __webpack_require__(1244), CookieKonnector: __webpack_require__(1324), - cozyClient: __webpack_require__(473), + cozyClient: __webpack_require__(485), errors: __webpack_require__(1250), log, saveFiles: __webpack_require__(1246), @@ -559,7 +559,7 @@ module.exports = { scrape: __webpack_require__(1328), mkdirp: __webpack_require__(1249), normalizeFilename: __webpack_require__(1329), - utils: __webpack_require__(472), + utils: __webpack_require__(484), solveCaptcha: __webpack_require__(1330), createCategorizer: categorization.createCategorizer, categorize: categorization.categorize, @@ -658,7 +658,7 @@ module.exports = __webpack_require__(3)["default"]; */ let request = __webpack_require__(4); -const requestdebug = __webpack_require__(253); // Quickly found more UserAgent here +const requestdebug = __webpack_require__(254); // Quickly found more UserAgent here // https://www.whatismybrowser.com/guides/the-latest-user-agent/ @@ -756,7 +756,7 @@ function mergeDefaultOptions(options = {}) { } function transformWithCheerio(body, response, resolveWithFullResponse) { - const result = (__webpack_require__(255).load)(body); + const result = (__webpack_require__(256).load)(body); if (resolveWithFullResponse) { return { ...response, @@ -809,7 +809,7 @@ try { } catch (err) { /* istanbul ignore next */ - var EOL = (__webpack_require__(252).EOL); + var EOL = (__webpack_require__(253).EOL); /* istanbul ignore next */ console.error(EOL + '###' + EOL + '### The "request" library is not installed automatically anymore.' + EOL + '### But is a dependency of "request-promise".' + EOL + '### Please install it with:' + EOL + '### npm install request --save' + EOL + '###' + EOL); /* istanbul ignore next */ @@ -10363,7 +10363,7 @@ var hawk = __webpack_require__(245) var Multipart = (__webpack_require__(246).Multipart) var Redirect = (__webpack_require__(247).Redirect) var Tunnel = (__webpack_require__(248).Tunnel) -var now = __webpack_require__(251) +var now = __webpack_require__(252) var Buffer = (__webpack_require__(77).Buffer) var safeStringify = helpers.safeStringify @@ -40070,7 +40070,7 @@ var net = __webpack_require__(62) , events = __webpack_require__(250) , assert = __webpack_require__(91) , util = __webpack_require__(64) - , Buffer = (__webpack_require__(77).Buffer) + , Buffer = (__webpack_require__(251).Buffer) ; exports.httpOverHttp = httpOverHttp @@ -40316,6 +40316,77 @@ module.exports = require("events"); /***/ }), /* 251 */ +/***/ ((module, exports, __webpack_require__) => { + +/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ +/* eslint-disable node/no-deprecated-api */ +var buffer = __webpack_require__(78) +var Buffer = buffer.Buffer + +// alternative to using Object.keys for old browsers +function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] + } +} +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer +} else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer +} + +function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) +} + +SafeBuffer.prototype = Object.create(Buffer.prototype) + +// Copy static methods from Buffer +copyProps(Buffer, SafeBuffer) + +SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) +} + +SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf +} + +SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) +} + +SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) +} + + +/***/ }), +/* 252 */ /***/ (function(module) { // Generated by CoffeeScript 1.12.2 @@ -40357,17 +40428,17 @@ module.exports = require("events"); /***/ }), -/* 252 */ +/* 253 */ /***/ ((module) => { "use strict"; module.exports = require("os"); /***/ }), -/* 253 */ +/* 254 */ /***/ ((module, exports, __webpack_require__) => { -var clone = __webpack_require__(254); +var clone = __webpack_require__(255); var debugId = 0 @@ -40462,7 +40533,7 @@ exports.log = function(type, data, r) { /***/ }), -/* 254 */ +/* 255 */ /***/ ((module) => { "use strict"; @@ -40474,29 +40545,29 @@ module.exports = function (obj) { /***/ }), -/* 255 */ +/* 256 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.root = exports.parseHTML = exports.merge = exports.contains = void 0; -var tslib_1 = __webpack_require__(256); +var tslib_1 = __webpack_require__(257); /** * Types used in signatures of Cheerio methods. * * @category Cheerio */ -tslib_1.__exportStar(__webpack_require__(257), exports); tslib_1.__exportStar(__webpack_require__(258), exports); -var load_1 = __webpack_require__(258); +tslib_1.__exportStar(__webpack_require__(259), exports); +var load_1 = __webpack_require__(259); /** * The default cheerio instance. * * @deprecated Use the function returned by `load` instead. */ exports["default"] = load_1.load([]); -var staticMethods = tslib_1.__importStar(__webpack_require__(260)); +var staticMethods = tslib_1.__importStar(__webpack_require__(261)); /** * In order to promote consistency with the jQuery library, users are encouraged * to instead use the static method of the same name. @@ -40562,7 +40633,7 @@ exports.root = staticMethods.root; /***/ }), -/* 256 */ +/* 257 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; @@ -40835,7 +40906,7 @@ function __classPrivateFieldSet(receiver, state, value, kind, f) { /***/ }), -/* 257 */ +/* 258 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -40844,18 +40915,18 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); /***/ }), -/* 258 */ +/* 259 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.load = void 0; -var tslib_1 = __webpack_require__(256); -var options_1 = tslib_1.__importStar(__webpack_require__(259)); -var staticMethods = tslib_1.__importStar(__webpack_require__(260)); -var cheerio_1 = __webpack_require__(333); -var parse_1 = tslib_1.__importDefault(__webpack_require__(334)); +var tslib_1 = __webpack_require__(257); +var options_1 = tslib_1.__importStar(__webpack_require__(260)); +var staticMethods = tslib_1.__importStar(__webpack_require__(261)); +var cheerio_1 = __webpack_require__(345); +var parse_1 = tslib_1.__importDefault(__webpack_require__(346)); /** * Create a querying function, bound to a document created from the provided * markup. Note that similar to web browser contexts, this operation may @@ -40904,14 +40975,14 @@ exports.load = load; /***/ }), -/* 259 */ +/* 260 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.flatten = void 0; -var tslib_1 = __webpack_require__(256); +var tslib_1 = __webpack_require__(257); var defaultOpts = { xml: false, decodeEntities: true, @@ -40933,19 +41004,19 @@ exports.flatten = flatten; /***/ }), -/* 260 */ +/* 261 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.merge = exports.contains = exports.root = exports.parseHTML = exports.text = exports.xml = exports.html = void 0; -var tslib_1 = __webpack_require__(256); -var options_1 = tslib_1.__importStar(__webpack_require__(259)); -var cheerio_select_1 = __webpack_require__(261); -var htmlparser2_1 = __webpack_require__(302); -var parse5_adapter_1 = __webpack_require__(306); -var htmlparser2_adapter_1 = __webpack_require__(332); +var tslib_1 = __webpack_require__(257); +var options_1 = tslib_1.__importStar(__webpack_require__(260)); +var cheerio_select_1 = __webpack_require__(262); +var htmlparser2_1 = __webpack_require__(303); +var parse5_adapter_1 = __webpack_require__(316); +var htmlparser2_adapter_1 = __webpack_require__(344); /** * Helper function to render a DOM. * @@ -41147,7 +41218,7 @@ function isArrayLike(item) { /***/ }), -/* 261 */ +/* 262 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -41189,13 +41260,13 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.select = exports.filter = exports.some = exports.is = exports.aliases = exports.pseudos = exports.filters = void 0; -var css_what_1 = __webpack_require__(262); -var css_select_1 = __webpack_require__(265); -var DomUtils = __importStar(__webpack_require__(266)); -var helpers_1 = __webpack_require__(300); -var positionals_1 = __webpack_require__(301); +var css_what_1 = __webpack_require__(263); +var css_select_1 = __webpack_require__(266); +var DomUtils = __importStar(__webpack_require__(267)); +var helpers_1 = __webpack_require__(301); +var positionals_1 = __webpack_require__(302); // Re-export pseudo extension points -var css_select_2 = __webpack_require__(265); +var css_select_2 = __webpack_require__(266); Object.defineProperty(exports, "filters", ({ enumerable: true, get: function () { return css_select_2.filters; } })); Object.defineProperty(exports, "pseudos", ({ enumerable: true, get: function () { return css_select_2.pseudos; } })); Object.defineProperty(exports, "aliases", ({ enumerable: true, get: function () { return css_select_2.aliases; } })); @@ -41450,7 +41521,7 @@ function filterElements(elements, sel, options) { /***/ }), -/* 262 */ +/* 263 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -41470,15 +41541,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.stringify = exports.parse = void 0; -__exportStar(__webpack_require__(263), exports); -var parse_1 = __webpack_require__(263); +__exportStar(__webpack_require__(264), exports); +var parse_1 = __webpack_require__(264); Object.defineProperty(exports, "parse", ({ enumerable: true, get: function () { return __importDefault(parse_1).default; } })); -var stringify_1 = __webpack_require__(264); +var stringify_1 = __webpack_require__(265); Object.defineProperty(exports, "stringify", ({ enumerable: true, get: function () { return __importDefault(stringify_1).default; } })); /***/ }), -/* 263 */ +/* 264 */ /***/ (function(__unused_webpack_module, exports) { "use strict"; @@ -41913,7 +41984,7 @@ function addToken(subselects, tokens) { /***/ }), -/* 264 */ +/* 265 */ /***/ (function(__unused_webpack_module, exports) { "use strict"; @@ -42021,7 +42092,7 @@ function escapeName(str) { /***/ }), -/* 265 */ +/* 266 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -42047,10 +42118,10 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.aliases = exports.pseudos = exports.filters = exports.is = exports.selectOne = exports.selectAll = exports.prepareContext = exports._compileToken = exports._compileUnsafe = exports.compile = void 0; -var DomUtils = __importStar(__webpack_require__(266)); -var boolbase_1 = __webpack_require__(286); -var compile_1 = __webpack_require__(287); -var subselects_1 = __webpack_require__(299); +var DomUtils = __importStar(__webpack_require__(267)); +var boolbase_1 = __webpack_require__(287); +var compile_1 = __webpack_require__(288); +var subselects_1 = __webpack_require__(300); var defaultEquals = function (a, b) { return a === b; }; var defaultOptions = { adapter: DomUtils, @@ -42165,14 +42236,14 @@ exports.is = is; */ exports["default"] = exports.selectAll; // Export filters, pseudos and aliases to allow users to supply their own. -var pseudo_selectors_1 = __webpack_require__(292); +var pseudo_selectors_1 = __webpack_require__(293); Object.defineProperty(exports, "filters", ({ enumerable: true, get: function () { return pseudo_selectors_1.filters; } })); Object.defineProperty(exports, "pseudos", ({ enumerable: true, get: function () { return pseudo_selectors_1.pseudos; } })); Object.defineProperty(exports, "aliases", ({ enumerable: true, get: function () { return pseudo_selectors_1.aliases; } })); /***/ }), -/* 266 */ +/* 267 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -42189,13 +42260,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.hasChildren = exports.isDocument = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = void 0; -__exportStar(__webpack_require__(267), exports); -__exportStar(__webpack_require__(281), exports); +__exportStar(__webpack_require__(268), exports); __exportStar(__webpack_require__(282), exports); __exportStar(__webpack_require__(283), exports); __exportStar(__webpack_require__(284), exports); __exportStar(__webpack_require__(285), exports); -var domhandler_1 = __webpack_require__(268); +__exportStar(__webpack_require__(286), exports); +var domhandler_1 = __webpack_require__(269); Object.defineProperty(exports, "isTag", ({ enumerable: true, get: function () { return domhandler_1.isTag; } })); Object.defineProperty(exports, "isCDATA", ({ enumerable: true, get: function () { return domhandler_1.isCDATA; } })); Object.defineProperty(exports, "isText", ({ enumerable: true, get: function () { return domhandler_1.isText; } })); @@ -42205,7 +42276,7 @@ Object.defineProperty(exports, "hasChildren", ({ enumerable: true, get: function /***/ }), -/* 267 */ +/* 268 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -42215,9 +42286,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.innerText = exports.textContent = exports.getText = exports.getInnerHTML = exports.getOuterHTML = void 0; -var domhandler_1 = __webpack_require__(268); -var dom_serializer_1 = __importDefault(__webpack_require__(271)); -var domelementtype_1 = __webpack_require__(269); +var domhandler_1 = __webpack_require__(269); +var dom_serializer_1 = __importDefault(__webpack_require__(272)); +var domelementtype_1 = __webpack_require__(270); /** * @param node Node to get the outer HTML of. * @param options Options for serialization. @@ -42301,7 +42372,7 @@ exports.innerText = innerText; /***/ }), -/* 268 */ +/* 269 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -42318,9 +42389,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.DomHandler = void 0; -var domelementtype_1 = __webpack_require__(269); -var node_1 = __webpack_require__(270); -__exportStar(__webpack_require__(270), exports); +var domelementtype_1 = __webpack_require__(270); +var node_1 = __webpack_require__(271); +__exportStar(__webpack_require__(271), exports); var reWhitespace = /\s+/g; // Default options var defaultOpts = { @@ -42477,7 +42548,7 @@ exports["default"] = DomHandler; /***/ }), -/* 269 */ +/* 270 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -42539,7 +42610,7 @@ exports.Doctype = ElementType.Doctype; /***/ }), -/* 270 */ +/* 271 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -42572,7 +42643,7 @@ var __assign = (this && this.__assign) || function () { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.cloneNode = exports.hasChildren = exports.isDocument = exports.isDirective = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = exports.Element = exports.Document = exports.NodeWithChildren = exports.ProcessingInstruction = exports.Comment = exports.Text = exports.DataNode = exports.Node = void 0; -var domelementtype_1 = __webpack_require__(269); +var domelementtype_1 = __webpack_require__(270); var nodeTypes = new Map([ [domelementtype_1.ElementType.Tag, 1], [domelementtype_1.ElementType.Script, 1], @@ -42936,7 +43007,7 @@ function cloneChildren(childs) { /***/ }), -/* 271 */ +/* 272 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -42975,15 +43046,15 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); /* * Module dependencies */ -var ElementType = __importStar(__webpack_require__(269)); -var entities_1 = __webpack_require__(272); +var ElementType = __importStar(__webpack_require__(270)); +var entities_1 = __webpack_require__(273); /** * Mixed-case SVG and MathML tags & attributes * recognized by the HTML parser. * * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign */ -var foreignNames_1 = __webpack_require__(280); +var foreignNames_1 = __webpack_require__(281); var unencodedElements = new Set([ "style", "script", @@ -43154,15 +43225,15 @@ function renderComment(elem) { /***/ }), -/* 272 */ +/* 273 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.decodeXMLStrict = exports.decodeHTML5Strict = exports.decodeHTML4Strict = exports.decodeHTML5 = exports.decodeHTML4 = exports.decodeHTMLStrict = exports.decodeHTML = exports.decodeXML = exports.encodeHTML5 = exports.encodeHTML4 = exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = exports.encode = exports.decodeStrict = exports.decode = void 0; -var decode_1 = __webpack_require__(273); -var encode_1 = __webpack_require__(279); +var decode_1 = __webpack_require__(274); +var encode_1 = __webpack_require__(280); /** * Decodes a string with entities. * @@ -43196,7 +43267,7 @@ function encode(data, level) { return (!level || level <= 0 ? encode_1.encodeXML : encode_1.encodeHTML)(data); } exports.encode = encode; -var encode_2 = __webpack_require__(279); +var encode_2 = __webpack_require__(280); Object.defineProperty(exports, "encodeXML", ({ enumerable: true, get: function () { return encode_2.encodeXML; } })); Object.defineProperty(exports, "encodeHTML", ({ enumerable: true, get: function () { return encode_2.encodeHTML; } })); Object.defineProperty(exports, "encodeNonAsciiHTML", ({ enumerable: true, get: function () { return encode_2.encodeNonAsciiHTML; } })); @@ -43205,7 +43276,7 @@ Object.defineProperty(exports, "escapeUTF8", ({ enumerable: true, get: function // Legacy aliases (deprecated) Object.defineProperty(exports, "encodeHTML4", ({ enumerable: true, get: function () { return encode_2.encodeHTML; } })); Object.defineProperty(exports, "encodeHTML5", ({ enumerable: true, get: function () { return encode_2.encodeHTML; } })); -var decode_2 = __webpack_require__(273); +var decode_2 = __webpack_require__(274); Object.defineProperty(exports, "decodeXML", ({ enumerable: true, get: function () { return decode_2.decodeXML; } })); Object.defineProperty(exports, "decodeHTML", ({ enumerable: true, get: function () { return decode_2.decodeHTML; } })); Object.defineProperty(exports, "decodeHTMLStrict", ({ enumerable: true, get: function () { return decode_2.decodeHTMLStrict; } })); @@ -43218,7 +43289,7 @@ Object.defineProperty(exports, "decodeXMLStrict", ({ enumerable: true, get: func /***/ }), -/* 273 */ +/* 274 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -43228,10 +43299,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.decodeHTML = exports.decodeHTMLStrict = exports.decodeXML = void 0; -var entities_json_1 = __importDefault(__webpack_require__(274)); -var legacy_json_1 = __importDefault(__webpack_require__(275)); -var xml_json_1 = __importDefault(__webpack_require__(276)); -var decode_codepoint_1 = __importDefault(__webpack_require__(277)); +var entities_json_1 = __importDefault(__webpack_require__(275)); +var legacy_json_1 = __importDefault(__webpack_require__(276)); +var xml_json_1 = __importDefault(__webpack_require__(277)); +var decode_codepoint_1 = __importDefault(__webpack_require__(278)); var strictEntityRe = /&(?:[a-zA-Z0-9]+|#[xX][\da-fA-F]+|#\d+);/g; exports.decodeXML = getStrictDecoder(xml_json_1.default); exports.decodeHTMLStrict = getStrictDecoder(entities_json_1.default); @@ -43278,28 +43349,28 @@ function getReplacer(map) { /***/ }), -/* 274 */ +/* 275 */ /***/ ((module) => { "use strict"; module.exports = JSON.parse('{"Aacute":"Ã","aacute":"á","Abreve":"Ä‚","abreve":"ă","ac":"∾","acd":"∿","acE":"∾̳","Acirc":"Â","acirc":"â","acute":"´","Acy":"Ð","acy":"а","AElig":"Æ","aelig":"æ","af":"â¡","Afr":"ð”„","afr":"ð”ž","Agrave":"À","agrave":"à ","alefsym":"ℵ","aleph":"ℵ","Alpha":"Α","alpha":"α","Amacr":"Ä€","amacr":"Ä","amalg":"⨿","amp":"&","AMP":"&","andand":"â©•","And":"â©“","and":"∧","andd":"â©œ","andslope":"⩘","andv":"â©š","ang":"∠","ange":"⦤","angle":"∠","angmsdaa":"⦨","angmsdab":"⦩","angmsdac":"⦪","angmsdad":"⦫","angmsdae":"⦬","angmsdaf":"â¦","angmsdag":"⦮","angmsdah":"⦯","angmsd":"∡","angrt":"∟","angrtvb":"⊾","angrtvbd":"â¦","angsph":"∢","angst":"Ã…","angzarr":"â¼","Aogon":"Ä„","aogon":"Ä…","Aopf":"ð”¸","aopf":"ð•’","apacir":"⩯","ap":"≈","apE":"â©°","ape":"≊","apid":"≋","apos":"\'","ApplyFunction":"â¡","approx":"≈","approxeq":"≊","Aring":"Ã…","aring":"Ã¥","Ascr":"ð’œ","ascr":"ð’¶","Assign":"≔","ast":"*","asymp":"≈","asympeq":"â‰","Atilde":"Ã","atilde":"ã","Auml":"Ä","auml":"ä","awconint":"∳","awint":"⨑","backcong":"≌","backepsilon":"϶","backprime":"‵","backsim":"∽","backsimeq":"â‹","Backslash":"∖","Barv":"⫧","barvee":"⊽","barwed":"⌅","Barwed":"⌆","barwedge":"⌅","bbrk":"⎵","bbrktbrk":"⎶","bcong":"≌","Bcy":"Б","bcy":"б","bdquo":"„","becaus":"∵","because":"∵","Because":"∵","bemptyv":"⦰","bepsi":"϶","bernou":"ℬ","Bernoullis":"ℬ","Beta":"Î’","beta":"β","beth":"ℶ","between":"≬","Bfr":"ð”…","bfr":"ð”Ÿ","bigcap":"â‹‚","bigcirc":"â—¯","bigcup":"⋃","bigodot":"⨀","bigoplus":"â¨","bigotimes":"⨂","bigsqcup":"⨆","bigstar":"★","bigtriangledown":"â–½","bigtriangleup":"â–³","biguplus":"⨄","bigvee":"â‹","bigwedge":"â‹€","bkarow":"â¤","blacklozenge":"⧫","blacksquare":"â–ª","blacktriangle":"â–´","blacktriangledown":"â–¾","blacktriangleleft":"â—‚","blacktriangleright":"â–¸","blank":"â£","blk12":"â–’","blk14":"â–‘","blk34":"â–“","block":"â–ˆ","bne":"=⃥","bnequiv":"≡⃥","bNot":"â«","bnot":"âŒ","Bopf":"ð”¹","bopf":"ð•“","bot":"⊥","bottom":"⊥","bowtie":"⋈","boxbox":"⧉","boxdl":"â”","boxdL":"â••","boxDl":"â•–","boxDL":"â•—","boxdr":"┌","boxdR":"â•’","boxDr":"â•“","boxDR":"â•”","boxh":"─","boxH":"â•","boxhd":"┬","boxHd":"╤","boxhD":"â•¥","boxHD":"╦","boxhu":"â”´","boxHu":"╧","boxhU":"╨","boxHU":"â•©","boxminus":"⊟","boxplus":"⊞","boxtimes":"⊠","boxul":"┘","boxuL":"â•›","boxUl":"â•œ","boxUL":"â•","boxur":"â””","boxuR":"╘","boxUr":"â•™","boxUR":"â•š","boxv":"│","boxV":"â•‘","boxvh":"┼","boxvH":"╪","boxVh":"â•«","boxVH":"╬","boxvl":"┤","boxvL":"â•¡","boxVl":"â•¢","boxVL":"â•£","boxvr":"├","boxvR":"â•ž","boxVr":"â•Ÿ","boxVR":"â• ","bprime":"‵","breve":"˘","Breve":"˘","brvbar":"¦","bscr":"ð’·","Bscr":"ℬ","bsemi":"â","bsim":"∽","bsime":"â‹","bsolb":"⧅","bsol":"\\\\","bsolhsub":"⟈","bull":"•","bullet":"•","bump":"≎","bumpE":"⪮","bumpe":"â‰","Bumpeq":"≎","bumpeq":"â‰","Cacute":"Ć","cacute":"ć","capand":"â©„","capbrcup":"⩉","capcap":"â©‹","cap":"∩","Cap":"â‹’","capcup":"⩇","capdot":"â©€","CapitalDifferentialD":"â……","caps":"∩︀","caret":"â","caron":"ˇ","Cayleys":"â„","ccaps":"â©","Ccaron":"ÄŒ","ccaron":"Ä","Ccedil":"Ç","ccedil":"ç","Ccirc":"Ĉ","ccirc":"ĉ","Cconint":"∰","ccups":"â©Œ","ccupssm":"â©","Cdot":"ÄŠ","cdot":"Ä‹","cedil":"¸","Cedilla":"¸","cemptyv":"⦲","cent":"¢","centerdot":"·","CenterDot":"·","cfr":"ð” ","Cfr":"â„","CHcy":"Ч","chcy":"ч","check":"✓","checkmark":"✓","Chi":"Χ","chi":"χ","circ":"ˆ","circeq":"≗","circlearrowleft":"↺","circlearrowright":"↻","circledast":"⊛","circledcirc":"⊚","circleddash":"âŠ","CircleDot":"⊙","circledR":"®","circledS":"Ⓢ","CircleMinus":"⊖","CirclePlus":"⊕","CircleTimes":"⊗","cir":"â—‹","cirE":"⧃","cire":"≗","cirfnint":"â¨","cirmid":"⫯","cirscir":"⧂","ClockwiseContourIntegral":"∲","CloseCurlyDoubleQuote":"â€","CloseCurlyQuote":"’","clubs":"♣","clubsuit":"♣","colon":":","Colon":"∷","Colone":"â©´","colone":"≔","coloneq":"≔","comma":",","commat":"@","comp":"âˆ","compfn":"∘","complement":"âˆ","complexes":"â„‚","cong":"≅","congdot":"â©","Congruent":"≡","conint":"∮","Conint":"∯","ContourIntegral":"∮","copf":"ð•”","Copf":"â„‚","coprod":"âˆ","Coproduct":"âˆ","copy":"©","COPY":"©","copysr":"â„—","CounterClockwiseContourIntegral":"∳","crarr":"↵","cross":"✗","Cross":"⨯","Cscr":"ð’ž","cscr":"ð’¸","csub":"â«","csube":"â«‘","csup":"â«","csupe":"â«’","ctdot":"⋯","cudarrl":"⤸","cudarrr":"⤵","cuepr":"â‹ž","cuesc":"â‹Ÿ","cularr":"↶","cularrp":"⤽","cupbrcap":"⩈","cupcap":"⩆","CupCap":"â‰","cup":"∪","Cup":"â‹“","cupcup":"â©Š","cupdot":"âŠ","cupor":"â©…","cups":"∪︀","curarr":"↷","curarrm":"⤼","curlyeqprec":"â‹ž","curlyeqsucc":"â‹Ÿ","curlyvee":"â‹Ž","curlywedge":"â‹","curren":"¤","curvearrowleft":"↶","curvearrowright":"↷","cuvee":"â‹Ž","cuwed":"â‹","cwconint":"∲","cwint":"∱","cylcty":"âŒ","dagger":"†","Dagger":"‡","daleth":"ℸ","darr":"↓","Darr":"↡","dArr":"⇓","dash":"â€","Dashv":"⫤","dashv":"⊣","dbkarow":"â¤","dblac":"Ë","Dcaron":"ÄŽ","dcaron":"Ä","Dcy":"Д","dcy":"д","ddagger":"‡","ddarr":"⇊","DD":"â……","dd":"â…†","DDotrahd":"⤑","ddotseq":"â©·","deg":"°","Del":"∇","Delta":"Δ","delta":"δ","demptyv":"⦱","dfisht":"⥿","Dfr":"ð”‡","dfr":"ð”¡","dHar":"⥥","dharl":"⇃","dharr":"⇂","DiacriticalAcute":"´","DiacriticalDot":"Ë™","DiacriticalDoubleAcute":"Ë","DiacriticalGrave":"`","DiacriticalTilde":"Ëœ","diam":"â‹„","diamond":"â‹„","Diamond":"â‹„","diamondsuit":"♦","diams":"♦","die":"¨","DifferentialD":"â…†","digamma":"Ï","disin":"⋲","div":"÷","divide":"÷","divideontimes":"⋇","divonx":"⋇","DJcy":"Ђ","djcy":"Ñ’","dlcorn":"⌞","dlcrop":"âŒ","dollar":"$","Dopf":"ð”»","dopf":"ð••","Dot":"¨","dot":"Ë™","DotDot":"⃜","doteq":"â‰","doteqdot":"≑","DotEqual":"â‰","dotminus":"∸","dotplus":"∔","dotsquare":"⊡","doublebarwedge":"⌆","DoubleContourIntegral":"∯","DoubleDot":"¨","DoubleDownArrow":"⇓","DoubleLeftArrow":"â‡","DoubleLeftRightArrow":"⇔","DoubleLeftTee":"⫤","DoubleLongLeftArrow":"⟸","DoubleLongLeftRightArrow":"⟺","DoubleLongRightArrow":"⟹","DoubleRightArrow":"⇒","DoubleRightTee":"⊨","DoubleUpArrow":"⇑","DoubleUpDownArrow":"⇕","DoubleVerticalBar":"∥","DownArrowBar":"⤓","downarrow":"↓","DownArrow":"↓","Downarrow":"⇓","DownArrowUpArrow":"⇵","DownBreve":"Ì‘","downdownarrows":"⇊","downharpoonleft":"⇃","downharpoonright":"⇂","DownLeftRightVector":"â¥","DownLeftTeeVector":"⥞","DownLeftVectorBar":"⥖","DownLeftVector":"↽","DownRightTeeVector":"⥟","DownRightVectorBar":"⥗","DownRightVector":"â‡","DownTeeArrow":"↧","DownTee":"⊤","drbkarow":"â¤","drcorn":"⌟","drcrop":"⌌","Dscr":"ð’Ÿ","dscr":"ð’¹","DScy":"Ð…","dscy":"Ñ•","dsol":"⧶","Dstrok":"Ä","dstrok":"Ä‘","dtdot":"⋱","dtri":"â–¿","dtrif":"â–¾","duarr":"⇵","duhar":"⥯","dwangle":"⦦","DZcy":"Ð","dzcy":"ÑŸ","dzigrarr":"⟿","Eacute":"É","eacute":"é","easter":"â©®","Ecaron":"Äš","ecaron":"Ä›","Ecirc":"Ê","ecirc":"ê","ecir":"≖","ecolon":"≕","Ecy":"Ð","ecy":"Ñ","eDDot":"â©·","Edot":"Ä–","edot":"Ä—","eDot":"≑","ee":"â…‡","efDot":"≒","Efr":"ð”ˆ","efr":"ð”¢","eg":"⪚","Egrave":"È","egrave":"è","egs":"⪖","egsdot":"⪘","el":"⪙","Element":"∈","elinters":"â§","ell":"â„“","els":"⪕","elsdot":"⪗","Emacr":"Ä’","emacr":"Ä“","empty":"∅","emptyset":"∅","EmptySmallSquare":"â—»","emptyv":"∅","EmptyVerySmallSquare":"â–«","emsp13":" ","emsp14":" ","emsp":" ","ENG":"ÅŠ","eng":"Å‹","ensp":" ","Eogon":"Ę","eogon":"Ä™","Eopf":"ð”¼","eopf":"ð•–","epar":"â‹•","eparsl":"⧣","eplus":"⩱","epsi":"ε","Epsilon":"Ε","epsilon":"ε","epsiv":"ϵ","eqcirc":"≖","eqcolon":"≕","eqsim":"≂","eqslantgtr":"⪖","eqslantless":"⪕","Equal":"⩵","equals":"=","EqualTilde":"≂","equest":"≟","Equilibrium":"⇌","equiv":"≡","equivDD":"⩸","eqvparsl":"⧥","erarr":"⥱","erDot":"≓","escr":"ℯ","Escr":"â„°","esdot":"â‰","Esim":"⩳","esim":"≂","Eta":"Η","eta":"η","ETH":"Ã","eth":"ð","Euml":"Ë","euml":"ë","euro":"€","excl":"!","exist":"∃","Exists":"∃","expectation":"â„°","exponentiale":"â…‡","ExponentialE":"â…‡","fallingdotseq":"≒","Fcy":"Ф","fcy":"Ñ„","female":"♀","ffilig":"ffi","fflig":"ff","ffllig":"ffl","Ffr":"ð”‰","ffr":"ð”£","filig":"ï¬","FilledSmallSquare":"â—¼","FilledVerySmallSquare":"â–ª","fjlig":"fj","flat":"â™","fllig":"fl","fltns":"â–±","fnof":"Æ’","Fopf":"ð”½","fopf":"ð•—","forall":"∀","ForAll":"∀","fork":"â‹”","forkv":"â«™","Fouriertrf":"ℱ","fpartint":"â¨","frac12":"½","frac13":"â…“","frac14":"¼","frac15":"â…•","frac16":"â…™","frac18":"â…›","frac23":"â…”","frac25":"â…–","frac34":"¾","frac35":"â…—","frac38":"â…œ","frac45":"â…˜","frac56":"â…š","frac58":"â…","frac78":"â…ž","frasl":"â„","frown":"⌢","fscr":"ð’»","Fscr":"ℱ","gacute":"ǵ","Gamma":"Γ","gamma":"γ","Gammad":"Ïœ","gammad":"Ï","gap":"⪆","Gbreve":"Äž","gbreve":"ÄŸ","Gcedil":"Ä¢","Gcirc":"Äœ","gcirc":"Ä","Gcy":"Г","gcy":"г","Gdot":"Ä ","gdot":"Ä¡","ge":"≥","gE":"≧","gEl":"⪌","gel":"â‹›","geq":"≥","geqq":"≧","geqslant":"⩾","gescc":"⪩","ges":"⩾","gesdot":"⪀","gesdoto":"⪂","gesdotol":"⪄","gesl":"⋛︀","gesles":"⪔","Gfr":"ð”Š","gfr":"ð”¤","gg":"≫","Gg":"â‹™","ggg":"â‹™","gimel":"â„·","GJcy":"Ѓ","gjcy":"Ñ“","gla":"⪥","gl":"≷","glE":"⪒","glj":"⪤","gnap":"⪊","gnapprox":"⪊","gne":"⪈","gnE":"≩","gneq":"⪈","gneqq":"≩","gnsim":"⋧","Gopf":"ð”¾","gopf":"ð•˜","grave":"`","GreaterEqual":"≥","GreaterEqualLess":"â‹›","GreaterFullEqual":"≧","GreaterGreater":"⪢","GreaterLess":"≷","GreaterSlantEqual":"⩾","GreaterTilde":"≳","Gscr":"ð’¢","gscr":"â„Š","gsim":"≳","gsime":"⪎","gsiml":"âª","gtcc":"⪧","gtcir":"⩺","gt":">","GT":">","Gt":"≫","gtdot":"â‹—","gtlPar":"⦕","gtquest":"⩼","gtrapprox":"⪆","gtrarr":"⥸","gtrdot":"â‹—","gtreqless":"â‹›","gtreqqless":"⪌","gtrless":"≷","gtrsim":"≳","gvertneqq":"≩︀","gvnE":"≩︀","Hacek":"ˇ","hairsp":" ","half":"½","hamilt":"â„‹","HARDcy":"Ъ","hardcy":"ÑŠ","harrcir":"⥈","harr":"↔","hArr":"⇔","harrw":"â†","Hat":"^","hbar":"â„","Hcirc":"Ĥ","hcirc":"Ä¥","hearts":"♥","heartsuit":"♥","hellip":"…","hercon":"⊹","hfr":"ð”¥","Hfr":"â„Œ","HilbertSpace":"â„‹","hksearow":"⤥","hkswarow":"⤦","hoarr":"⇿","homtht":"∻","hookleftarrow":"↩","hookrightarrow":"↪","hopf":"ð•™","Hopf":"â„","horbar":"―","HorizontalLine":"─","hscr":"ð’½","Hscr":"â„‹","hslash":"â„","Hstrok":"Ħ","hstrok":"ħ","HumpDownHump":"≎","HumpEqual":"â‰","hybull":"âƒ","hyphen":"â€","Iacute":"Ã","iacute":"Ã","ic":"â£","Icirc":"ÃŽ","icirc":"î","Icy":"И","icy":"и","Idot":"Ä°","IEcy":"Е","iecy":"е","iexcl":"¡","iff":"⇔","ifr":"ð”¦","Ifr":"â„‘","Igrave":"ÃŒ","igrave":"ì","ii":"â…ˆ","iiiint":"⨌","iiint":"âˆ","iinfin":"⧜","iiota":"â„©","IJlig":"IJ","ijlig":"ij","Imacr":"Ī","imacr":"Ä«","image":"â„‘","ImaginaryI":"â…ˆ","imagline":"â„","imagpart":"â„‘","imath":"ı","Im":"â„‘","imof":"⊷","imped":"Ƶ","Implies":"⇒","incare":"â„…","in":"∈","infin":"∞","infintie":"â§","inodot":"ı","intcal":"⊺","int":"∫","Int":"∬","integers":"ℤ","Integral":"∫","intercal":"⊺","Intersection":"â‹‚","intlarhk":"⨗","intprod":"⨼","InvisibleComma":"â£","InvisibleTimes":"â¢","IOcy":"Ð","iocy":"Ñ‘","Iogon":"Ä®","iogon":"į","Iopf":"ð•€","iopf":"ð•š","Iota":"Ι","iota":"ι","iprod":"⨼","iquest":"¿","iscr":"ð’¾","Iscr":"â„","isin":"∈","isindot":"⋵","isinE":"⋹","isins":"â‹´","isinsv":"⋳","isinv":"∈","it":"â¢","Itilde":"Ĩ","itilde":"Ä©","Iukcy":"І","iukcy":"Ñ–","Iuml":"Ã","iuml":"ï","Jcirc":"Ä´","jcirc":"ĵ","Jcy":"Й","jcy":"й","Jfr":"ð”","jfr":"ð”§","jmath":"È·","Jopf":"ð•","jopf":"ð•›","Jscr":"ð’¥","jscr":"ð’¿","Jsercy":"Ј","jsercy":"ј","Jukcy":"Є","jukcy":"Ñ”","Kappa":"Κ","kappa":"κ","kappav":"Ï°","Kcedil":"Ķ","kcedil":"Ä·","Kcy":"К","kcy":"к","Kfr":"ð”Ž","kfr":"ð”¨","kgreen":"ĸ","KHcy":"Ð¥","khcy":"Ñ…","KJcy":"ÐŒ","kjcy":"Ñœ","Kopf":"ð•‚","kopf":"ð•œ","Kscr":"ð’¦","kscr":"ð“€","lAarr":"⇚","Lacute":"Ĺ","lacute":"ĺ","laemptyv":"⦴","lagran":"â„’","Lambda":"Λ","lambda":"λ","lang":"⟨","Lang":"⟪","langd":"⦑","langle":"⟨","lap":"⪅","Laplacetrf":"â„’","laquo":"«","larrb":"⇤","larrbfs":"⤟","larr":"â†","Larr":"↞","lArr":"â‡","larrfs":"â¤","larrhk":"↩","larrlp":"↫","larrpl":"⤹","larrsim":"⥳","larrtl":"↢","latail":"⤙","lAtail":"⤛","lat":"⪫","late":"âª","lates":"âªï¸€","lbarr":"⤌","lBarr":"⤎","lbbrk":"â²","lbrace":"{","lbrack":"[","lbrke":"⦋","lbrksld":"â¦","lbrkslu":"â¦","Lcaron":"Ľ","lcaron":"ľ","Lcedil":"Ä»","lcedil":"ļ","lceil":"⌈","lcub":"{","Lcy":"Л","lcy":"л","ldca":"⤶","ldquo":"“","ldquor":"„","ldrdhar":"⥧","ldrushar":"⥋","ldsh":"↲","le":"≤","lE":"≦","LeftAngleBracket":"⟨","LeftArrowBar":"⇤","leftarrow":"â†","LeftArrow":"â†","Leftarrow":"â‡","LeftArrowRightArrow":"⇆","leftarrowtail":"↢","LeftCeiling":"⌈","LeftDoubleBracket":"⟦","LeftDownTeeVector":"⥡","LeftDownVectorBar":"⥙","LeftDownVector":"⇃","LeftFloor":"⌊","leftharpoondown":"↽","leftharpoonup":"↼","leftleftarrows":"⇇","leftrightarrow":"↔","LeftRightArrow":"↔","Leftrightarrow":"⇔","leftrightarrows":"⇆","leftrightharpoons":"⇋","leftrightsquigarrow":"â†","LeftRightVector":"⥎","LeftTeeArrow":"↤","LeftTee":"⊣","LeftTeeVector":"⥚","leftthreetimes":"â‹‹","LeftTriangleBar":"â§","LeftTriangle":"⊲","LeftTriangleEqual":"⊴","LeftUpDownVector":"⥑","LeftUpTeeVector":"⥠","LeftUpVectorBar":"⥘","LeftUpVector":"↿","LeftVectorBar":"⥒","LeftVector":"↼","lEg":"⪋","leg":"â‹š","leq":"≤","leqq":"≦","leqslant":"⩽","lescc":"⪨","les":"⩽","lesdot":"â©¿","lesdoto":"âª","lesdotor":"⪃","lesg":"⋚︀","lesges":"⪓","lessapprox":"⪅","lessdot":"â‹–","lesseqgtr":"â‹š","lesseqqgtr":"⪋","LessEqualGreater":"â‹š","LessFullEqual":"≦","LessGreater":"≶","lessgtr":"≶","LessLess":"⪡","lesssim":"≲","LessSlantEqual":"⩽","LessTilde":"≲","lfisht":"⥼","lfloor":"⌊","Lfr":"ð”","lfr":"ð”©","lg":"≶","lgE":"⪑","lHar":"⥢","lhard":"↽","lharu":"↼","lharul":"⥪","lhblk":"â–„","LJcy":"Љ","ljcy":"Ñ™","llarr":"⇇","ll":"≪","Ll":"⋘","llcorner":"⌞","Lleftarrow":"⇚","llhard":"⥫","lltri":"â—º","Lmidot":"Ä¿","lmidot":"Å€","lmoustache":"⎰","lmoust":"⎰","lnap":"⪉","lnapprox":"⪉","lne":"⪇","lnE":"≨","lneq":"⪇","lneqq":"≨","lnsim":"⋦","loang":"⟬","loarr":"⇽","lobrk":"⟦","longleftarrow":"⟵","LongLeftArrow":"⟵","Longleftarrow":"⟸","longleftrightarrow":"⟷","LongLeftRightArrow":"⟷","Longleftrightarrow":"⟺","longmapsto":"⟼","longrightarrow":"⟶","LongRightArrow":"⟶","Longrightarrow":"⟹","looparrowleft":"↫","looparrowright":"↬","lopar":"⦅","Lopf":"ð•ƒ","lopf":"ð•","loplus":"â¨","lotimes":"⨴","lowast":"∗","lowbar":"_","LowerLeftArrow":"↙","LowerRightArrow":"↘","loz":"â—Š","lozenge":"â—Š","lozf":"⧫","lpar":"(","lparlt":"⦓","lrarr":"⇆","lrcorner":"⌟","lrhar":"⇋","lrhard":"â¥","lrm":"‎","lrtri":"⊿","lsaquo":"‹","lscr":"ð“","Lscr":"â„’","lsh":"↰","Lsh":"↰","lsim":"≲","lsime":"âª","lsimg":"âª","lsqb":"[","lsquo":"‘","lsquor":"‚","Lstrok":"Å","lstrok":"Å‚","ltcc":"⪦","ltcir":"⩹","lt":"<","LT":"<","Lt":"≪","ltdot":"â‹–","lthree":"â‹‹","ltimes":"⋉","ltlarr":"⥶","ltquest":"â©»","ltri":"â—ƒ","ltrie":"⊴","ltrif":"â—‚","ltrPar":"⦖","lurdshar":"⥊","luruhar":"⥦","lvertneqq":"≨︀","lvnE":"≨︀","macr":"¯","male":"♂","malt":"✠","maltese":"✠","Map":"⤅","map":"↦","mapsto":"↦","mapstodown":"↧","mapstoleft":"↤","mapstoup":"↥","marker":"â–®","mcomma":"⨩","Mcy":"Ðœ","mcy":"м","mdash":"—","mDDot":"∺","measuredangle":"∡","MediumSpace":"âŸ","Mellintrf":"ℳ","Mfr":"ð”","mfr":"ð”ª","mho":"℧","micro":"µ","midast":"*","midcir":"â«°","mid":"∣","middot":"·","minusb":"⊟","minus":"−","minusd":"∸","minusdu":"⨪","MinusPlus":"∓","mlcp":"â«›","mldr":"…","mnplus":"∓","models":"⊧","Mopf":"ð•„","mopf":"ð•ž","mp":"∓","mscr":"ð“‚","Mscr":"ℳ","mstpos":"∾","Mu":"Îœ","mu":"μ","multimap":"⊸","mumap":"⊸","nabla":"∇","Nacute":"Ń","nacute":"Å„","nang":"∠⃒","nap":"≉","napE":"⩰̸","napid":"≋̸","napos":"ʼn","napprox":"≉","natural":"â™®","naturals":"â„•","natur":"â™®","nbsp":" ","nbump":"≎̸","nbumpe":"â‰Ì¸","ncap":"⩃","Ncaron":"Ň","ncaron":"ň","Ncedil":"Å…","ncedil":"ņ","ncong":"≇","ncongdot":"â©Ì¸","ncup":"â©‚","Ncy":"Ð","ncy":"н","ndash":"–","nearhk":"⤤","nearr":"↗","neArr":"⇗","nearrow":"↗","ne":"≠","nedot":"â‰Ì¸","NegativeMediumSpace":"​","NegativeThickSpace":"​","NegativeThinSpace":"​","NegativeVeryThinSpace":"​","nequiv":"≢","nesear":"⤨","nesim":"≂̸","NestedGreaterGreater":"≫","NestedLessLess":"≪","NewLine":"\\n","nexist":"∄","nexists":"∄","Nfr":"ð”‘","nfr":"ð”«","ngE":"≧̸","nge":"≱","ngeq":"≱","ngeqq":"≧̸","ngeqslant":"⩾̸","nges":"⩾̸","nGg":"⋙̸","ngsim":"≵","nGt":"≫⃒","ngt":"≯","ngtr":"≯","nGtv":"≫̸","nharr":"↮","nhArr":"⇎","nhpar":"⫲","ni":"∋","nis":"⋼","nisd":"⋺","niv":"∋","NJcy":"Њ","njcy":"Ñš","nlarr":"↚","nlArr":"â‡","nldr":"‥","nlE":"≦̸","nle":"≰","nleftarrow":"↚","nLeftarrow":"â‡","nleftrightarrow":"↮","nLeftrightarrow":"⇎","nleq":"≰","nleqq":"≦̸","nleqslant":"⩽̸","nles":"⩽̸","nless":"≮","nLl":"⋘̸","nlsim":"≴","nLt":"≪⃒","nlt":"≮","nltri":"⋪","nltrie":"⋬","nLtv":"≪̸","nmid":"∤","NoBreak":"â ","NonBreakingSpace":" ","nopf":"ð•Ÿ","Nopf":"â„•","Not":"⫬","not":"¬","NotCongruent":"≢","NotCupCap":"â‰","NotDoubleVerticalBar":"∦","NotElement":"∉","NotEqual":"≠","NotEqualTilde":"≂̸","NotExists":"∄","NotGreater":"≯","NotGreaterEqual":"≱","NotGreaterFullEqual":"≧̸","NotGreaterGreater":"≫̸","NotGreaterLess":"≹","NotGreaterSlantEqual":"⩾̸","NotGreaterTilde":"≵","NotHumpDownHump":"≎̸","NotHumpEqual":"â‰Ì¸","notin":"∉","notindot":"⋵̸","notinE":"⋹̸","notinva":"∉","notinvb":"â‹·","notinvc":"⋶","NotLeftTriangleBar":"â§Ì¸","NotLeftTriangle":"⋪","NotLeftTriangleEqual":"⋬","NotLess":"≮","NotLessEqual":"≰","NotLessGreater":"≸","NotLessLess":"≪̸","NotLessSlantEqual":"⩽̸","NotLessTilde":"≴","NotNestedGreaterGreater":"⪢̸","NotNestedLessLess":"⪡̸","notni":"∌","notniva":"∌","notnivb":"⋾","notnivc":"⋽","NotPrecedes":"⊀","NotPrecedesEqual":"⪯̸","NotPrecedesSlantEqual":"â‹ ","NotReverseElement":"∌","NotRightTriangleBar":"â§Ì¸","NotRightTriangle":"â‹«","NotRightTriangleEqual":"â‹","NotSquareSubset":"âŠÌ¸","NotSquareSubsetEqual":"â‹¢","NotSquareSuperset":"âŠÌ¸","NotSquareSupersetEqual":"â‹£","NotSubset":"⊂⃒","NotSubsetEqual":"⊈","NotSucceeds":"âŠ","NotSucceedsEqual":"⪰̸","NotSucceedsSlantEqual":"â‹¡","NotSucceedsTilde":"≿̸","NotSuperset":"⊃⃒","NotSupersetEqual":"⊉","NotTilde":"â‰","NotTildeEqual":"≄","NotTildeFullEqual":"≇","NotTildeTilde":"≉","NotVerticalBar":"∤","nparallel":"∦","npar":"∦","nparsl":"⫽⃥","npart":"∂̸","npolint":"⨔","npr":"⊀","nprcue":"â‹ ","nprec":"⊀","npreceq":"⪯̸","npre":"⪯̸","nrarrc":"⤳̸","nrarr":"↛","nrArr":"â‡","nrarrw":"â†Ì¸","nrightarrow":"↛","nRightarrow":"â‡","nrtri":"â‹«","nrtrie":"â‹","nsc":"âŠ","nsccue":"â‹¡","nsce":"⪰̸","Nscr":"ð’©","nscr":"ð“ƒ","nshortmid":"∤","nshortparallel":"∦","nsim":"â‰","nsime":"≄","nsimeq":"≄","nsmid":"∤","nspar":"∦","nsqsube":"â‹¢","nsqsupe":"â‹£","nsub":"⊄","nsubE":"⫅̸","nsube":"⊈","nsubset":"⊂⃒","nsubseteq":"⊈","nsubseteqq":"⫅̸","nsucc":"âŠ","nsucceq":"⪰̸","nsup":"⊅","nsupE":"⫆̸","nsupe":"⊉","nsupset":"⊃⃒","nsupseteq":"⊉","nsupseteqq":"⫆̸","ntgl":"≹","Ntilde":"Ñ","ntilde":"ñ","ntlg":"≸","ntriangleleft":"⋪","ntrianglelefteq":"⋬","ntriangleright":"â‹«","ntrianglerighteq":"â‹","Nu":"Î","nu":"ν","num":"#","numero":"â„–","numsp":" ","nvap":"â‰âƒ’","nvdash":"⊬","nvDash":"âŠ","nVdash":"⊮","nVDash":"⊯","nvge":"≥⃒","nvgt":">⃒","nvHarr":"⤄","nvinfin":"⧞","nvlArr":"⤂","nvle":"≤⃒","nvlt":"<⃒","nvltrie":"⊴⃒","nvrArr":"⤃","nvrtrie":"⊵⃒","nvsim":"∼⃒","nwarhk":"⤣","nwarr":"↖","nwArr":"⇖","nwarrow":"↖","nwnear":"⤧","Oacute":"Ó","oacute":"ó","oast":"⊛","Ocirc":"Ô","ocirc":"ô","ocir":"⊚","Ocy":"О","ocy":"о","odash":"âŠ","Odblac":"Å","odblac":"Å‘","odiv":"⨸","odot":"⊙","odsold":"⦼","OElig":"Å’","oelig":"Å“","ofcir":"⦿","Ofr":"ð”’","ofr":"ð”¬","ogon":"Ë›","Ograve":"Ã’","ograve":"ò","ogt":"â§","ohbar":"⦵","ohm":"Ω","oint":"∮","olarr":"↺","olcir":"⦾","olcross":"⦻","oline":"‾","olt":"⧀","Omacr":"ÅŒ","omacr":"Å","Omega":"Ω","omega":"ω","Omicron":"Ο","omicron":"ο","omid":"⦶","ominus":"⊖","Oopf":"ð•†","oopf":"ð• ","opar":"⦷","OpenCurlyDoubleQuote":"“","OpenCurlyQuote":"‘","operp":"⦹","oplus":"⊕","orarr":"↻","Or":"â©”","or":"∨","ord":"â©","order":"â„´","orderof":"â„´","ordf":"ª","ordm":"º","origof":"⊶","oror":"â©–","orslope":"â©—","orv":"â©›","oS":"Ⓢ","Oscr":"ð’ª","oscr":"â„´","Oslash":"Ø","oslash":"ø","osol":"⊘","Otilde":"Õ","otilde":"õ","otimesas":"⨶","Otimes":"⨷","otimes":"⊗","Ouml":"Ö","ouml":"ö","ovbar":"⌽","OverBar":"‾","OverBrace":"âž","OverBracket":"⎴","OverParenthesis":"âœ","para":"¶","parallel":"∥","par":"∥","parsim":"⫳","parsl":"⫽","part":"∂","PartialD":"∂","Pcy":"П","pcy":"п","percnt":"%","period":".","permil":"‰","perp":"⊥","pertenk":"‱","Pfr":"ð”“","pfr":"ð”","Phi":"Φ","phi":"φ","phiv":"Ï•","phmmat":"ℳ","phone":"☎","Pi":"Î ","pi":"Ï€","pitchfork":"â‹”","piv":"Ï–","planck":"â„","planckh":"â„Ž","plankv":"â„","plusacir":"⨣","plusb":"⊞","pluscir":"⨢","plus":"+","plusdo":"∔","plusdu":"⨥","pluse":"⩲","PlusMinus":"±","plusmn":"±","plussim":"⨦","plustwo":"⨧","pm":"±","Poincareplane":"â„Œ","pointint":"⨕","popf":"ð•¡","Popf":"â„™","pound":"£","prap":"⪷","Pr":"⪻","pr":"≺","prcue":"≼","precapprox":"⪷","prec":"≺","preccurlyeq":"≼","Precedes":"≺","PrecedesEqual":"⪯","PrecedesSlantEqual":"≼","PrecedesTilde":"≾","preceq":"⪯","precnapprox":"⪹","precneqq":"⪵","precnsim":"⋨","pre":"⪯","prE":"⪳","precsim":"≾","prime":"′","Prime":"″","primes":"â„™","prnap":"⪹","prnE":"⪵","prnsim":"⋨","prod":"âˆ","Product":"âˆ","profalar":"⌮","profline":"⌒","profsurf":"⌓","prop":"âˆ","Proportional":"âˆ","Proportion":"∷","propto":"âˆ","prsim":"≾","prurel":"⊰","Pscr":"ð’«","pscr":"ð“…","Psi":"Ψ","psi":"ψ","puncsp":" ","Qfr":"ð””","qfr":"ð”®","qint":"⨌","qopf":"ð•¢","Qopf":"â„š","qprime":"â—","Qscr":"ð’¬","qscr":"ð“†","quaternions":"â„","quatint":"⨖","quest":"?","questeq":"≟","quot":"\\"","QUOT":"\\"","rAarr":"⇛","race":"∽̱","Racute":"Å”","racute":"Å•","radic":"√","raemptyv":"⦳","rang":"⟩","Rang":"⟫","rangd":"⦒","range":"⦥","rangle":"⟩","raquo":"»","rarrap":"⥵","rarrb":"⇥","rarrbfs":"⤠","rarrc":"⤳","rarr":"→","Rarr":"↠","rArr":"⇒","rarrfs":"⤞","rarrhk":"↪","rarrlp":"↬","rarrpl":"⥅","rarrsim":"⥴","Rarrtl":"⤖","rarrtl":"↣","rarrw":"â†","ratail":"⤚","rAtail":"⤜","ratio":"∶","rationals":"â„š","rbarr":"â¤","rBarr":"â¤","RBarr":"â¤","rbbrk":"â³","rbrace":"}","rbrack":"]","rbrke":"⦌","rbrksld":"⦎","rbrkslu":"â¦","Rcaron":"Ř","rcaron":"Å™","Rcedil":"Å–","rcedil":"Å—","rceil":"⌉","rcub":"}","Rcy":"Ð ","rcy":"Ñ€","rdca":"⤷","rdldhar":"⥩","rdquo":"â€","rdquor":"â€","rdsh":"↳","real":"â„œ","realine":"â„›","realpart":"â„œ","reals":"â„","Re":"â„œ","rect":"â–","reg":"®","REG":"®","ReverseElement":"∋","ReverseEquilibrium":"⇋","ReverseUpEquilibrium":"⥯","rfisht":"⥽","rfloor":"⌋","rfr":"ð”¯","Rfr":"â„œ","rHar":"⥤","rhard":"â‡","rharu":"⇀","rharul":"⥬","Rho":"Ρ","rho":"Ï","rhov":"ϱ","RightAngleBracket":"⟩","RightArrowBar":"⇥","rightarrow":"→","RightArrow":"→","Rightarrow":"⇒","RightArrowLeftArrow":"⇄","rightarrowtail":"↣","RightCeiling":"⌉","RightDoubleBracket":"⟧","RightDownTeeVector":"â¥","RightDownVectorBar":"⥕","RightDownVector":"⇂","RightFloor":"⌋","rightharpoondown":"â‡","rightharpoonup":"⇀","rightleftarrows":"⇄","rightleftharpoons":"⇌","rightrightarrows":"⇉","rightsquigarrow":"â†","RightTeeArrow":"↦","RightTee":"⊢","RightTeeVector":"⥛","rightthreetimes":"â‹Œ","RightTriangleBar":"â§","RightTriangle":"⊳","RightTriangleEqual":"⊵","RightUpDownVector":"â¥","RightUpTeeVector":"⥜","RightUpVectorBar":"⥔","RightUpVector":"↾","RightVectorBar":"⥓","RightVector":"⇀","ring":"Ëš","risingdotseq":"≓","rlarr":"⇄","rlhar":"⇌","rlm":"â€","rmoustache":"⎱","rmoust":"⎱","rnmid":"â«®","roang":"âŸ","roarr":"⇾","robrk":"⟧","ropar":"⦆","ropf":"ð•£","Ropf":"â„","roplus":"⨮","rotimes":"⨵","RoundImplies":"⥰","rpar":")","rpargt":"⦔","rppolint":"⨒","rrarr":"⇉","Rrightarrow":"⇛","rsaquo":"›","rscr":"ð“‡","Rscr":"â„›","rsh":"↱","Rsh":"↱","rsqb":"]","rsquo":"’","rsquor":"’","rthree":"â‹Œ","rtimes":"â‹Š","rtri":"â–¹","rtrie":"⊵","rtrif":"â–¸","rtriltri":"⧎","RuleDelayed":"⧴","ruluhar":"⥨","rx":"â„ž","Sacute":"Åš","sacute":"Å›","sbquo":"‚","scap":"⪸","Scaron":"Å ","scaron":"Å¡","Sc":"⪼","sc":"≻","sccue":"≽","sce":"⪰","scE":"⪴","Scedil":"Åž","scedil":"ÅŸ","Scirc":"Åœ","scirc":"Å","scnap":"⪺","scnE":"⪶","scnsim":"â‹©","scpolint":"⨓","scsim":"≿","Scy":"С","scy":"Ñ","sdotb":"⊡","sdot":"â‹…","sdote":"⩦","searhk":"⤥","searr":"↘","seArr":"⇘","searrow":"↘","sect":"§","semi":";","seswar":"⤩","setminus":"∖","setmn":"∖","sext":"✶","Sfr":"ð”–","sfr":"ð”°","sfrown":"⌢","sharp":"♯","SHCHcy":"Щ","shchcy":"щ","SHcy":"Ш","shcy":"ш","ShortDownArrow":"↓","ShortLeftArrow":"â†","shortmid":"∣","shortparallel":"∥","ShortRightArrow":"→","ShortUpArrow":"↑","shy":"Â","Sigma":"Σ","sigma":"σ","sigmaf":"Ï‚","sigmav":"Ï‚","sim":"∼","simdot":"⩪","sime":"≃","simeq":"≃","simg":"⪞","simgE":"⪠","siml":"âª","simlE":"⪟","simne":"≆","simplus":"⨤","simrarr":"⥲","slarr":"â†","SmallCircle":"∘","smallsetminus":"∖","smashp":"⨳","smeparsl":"⧤","smid":"∣","smile":"⌣","smt":"⪪","smte":"⪬","smtes":"⪬︀","SOFTcy":"Ь","softcy":"ÑŒ","solbar":"⌿","solb":"⧄","sol":"/","Sopf":"ð•Š","sopf":"ð•¤","spades":"â™ ","spadesuit":"â™ ","spar":"∥","sqcap":"⊓","sqcaps":"⊓︀","sqcup":"⊔","sqcups":"⊔︀","Sqrt":"√","sqsub":"âŠ","sqsube":"⊑","sqsubset":"âŠ","sqsubseteq":"⊑","sqsup":"âŠ","sqsupe":"⊒","sqsupset":"âŠ","sqsupseteq":"⊒","square":"â–¡","Square":"â–¡","SquareIntersection":"⊓","SquareSubset":"âŠ","SquareSubsetEqual":"⊑","SquareSuperset":"âŠ","SquareSupersetEqual":"⊒","SquareUnion":"⊔","squarf":"â–ª","squ":"â–¡","squf":"â–ª","srarr":"→","Sscr":"ð’®","sscr":"ð“ˆ","ssetmn":"∖","ssmile":"⌣","sstarf":"⋆","Star":"⋆","star":"☆","starf":"★","straightepsilon":"ϵ","straightphi":"Ï•","strns":"¯","sub":"⊂","Sub":"â‹","subdot":"⪽","subE":"â«…","sube":"⊆","subedot":"⫃","submult":"â«","subnE":"â«‹","subne":"⊊","subplus":"⪿","subrarr":"⥹","subset":"⊂","Subset":"â‹","subseteq":"⊆","subseteqq":"â«…","SubsetEqual":"⊆","subsetneq":"⊊","subsetneqq":"â«‹","subsim":"⫇","subsub":"â«•","subsup":"â«“","succapprox":"⪸","succ":"≻","succcurlyeq":"≽","Succeeds":"≻","SucceedsEqual":"⪰","SucceedsSlantEqual":"≽","SucceedsTilde":"≿","succeq":"⪰","succnapprox":"⪺","succneqq":"⪶","succnsim":"â‹©","succsim":"≿","SuchThat":"∋","sum":"∑","Sum":"∑","sung":"♪","sup1":"¹","sup2":"²","sup3":"³","sup":"⊃","Sup":"â‹‘","supdot":"⪾","supdsub":"⫘","supE":"⫆","supe":"⊇","supedot":"â«„","Superset":"⊃","SupersetEqual":"⊇","suphsol":"⟉","suphsub":"â«—","suplarr":"⥻","supmult":"â«‚","supnE":"â«Œ","supne":"⊋","supplus":"â«€","supset":"⊃","Supset":"â‹‘","supseteq":"⊇","supseteqq":"⫆","supsetneq":"⊋","supsetneqq":"â«Œ","supsim":"⫈","supsub":"â«”","supsup":"â«–","swarhk":"⤦","swarr":"↙","swArr":"⇙","swarrow":"↙","swnwar":"⤪","szlig":"ß","Tab":"\\t","target":"⌖","Tau":"Τ","tau":"Ï„","tbrk":"⎴","Tcaron":"Ť","tcaron":"Å¥","Tcedil":"Å¢","tcedil":"Å£","Tcy":"Т","tcy":"Ñ‚","tdot":"⃛","telrec":"⌕","Tfr":"ð”—","tfr":"ð”±","there4":"∴","therefore":"∴","Therefore":"∴","Theta":"Θ","theta":"θ","thetasym":"Ï‘","thetav":"Ï‘","thickapprox":"≈","thicksim":"∼","ThickSpace":"âŸâ€Š","ThinSpace":" ","thinsp":" ","thkap":"≈","thksim":"∼","THORN":"Þ","thorn":"þ","tilde":"Ëœ","Tilde":"∼","TildeEqual":"≃","TildeFullEqual":"≅","TildeTilde":"≈","timesbar":"⨱","timesb":"⊠","times":"×","timesd":"⨰","tint":"âˆ","toea":"⤨","topbot":"⌶","topcir":"⫱","top":"⊤","Topf":"ð•‹","topf":"ð•¥","topfork":"â«š","tosa":"⤩","tprime":"‴","trade":"â„¢","TRADE":"â„¢","triangle":"â–µ","triangledown":"â–¿","triangleleft":"â—ƒ","trianglelefteq":"⊴","triangleq":"≜","triangleright":"â–¹","trianglerighteq":"⊵","tridot":"â—¬","trie":"≜","triminus":"⨺","TripleDot":"⃛","triplus":"⨹","trisb":"â§","tritime":"⨻","trpezium":"â¢","Tscr":"ð’¯","tscr":"ð“‰","TScy":"Ц","tscy":"ц","TSHcy":"Ћ","tshcy":"Ñ›","Tstrok":"Ŧ","tstrok":"ŧ","twixt":"≬","twoheadleftarrow":"↞","twoheadrightarrow":"↠","Uacute":"Ú","uacute":"ú","uarr":"↑","Uarr":"↟","uArr":"⇑","Uarrocir":"⥉","Ubrcy":"ÐŽ","ubrcy":"Ñž","Ubreve":"Ŭ","ubreve":"Å","Ucirc":"Û","ucirc":"û","Ucy":"У","ucy":"у","udarr":"⇅","Udblac":"Å°","udblac":"ű","udhar":"⥮","ufisht":"⥾","Ufr":"ð”˜","ufr":"ð”²","Ugrave":"Ù","ugrave":"ù","uHar":"⥣","uharl":"↿","uharr":"↾","uhblk":"â–€","ulcorn":"⌜","ulcorner":"⌜","ulcrop":"âŒ","ultri":"â—¸","Umacr":"Ū","umacr":"Å«","uml":"¨","UnderBar":"_","UnderBrace":"âŸ","UnderBracket":"⎵","UnderParenthesis":"â","Union":"⋃","UnionPlus":"⊎","Uogon":"Ų","uogon":"ų","Uopf":"ð•Œ","uopf":"ð•¦","UpArrowBar":"⤒","uparrow":"↑","UpArrow":"↑","Uparrow":"⇑","UpArrowDownArrow":"⇅","updownarrow":"↕","UpDownArrow":"↕","Updownarrow":"⇕","UpEquilibrium":"⥮","upharpoonleft":"↿","upharpoonright":"↾","uplus":"⊎","UpperLeftArrow":"↖","UpperRightArrow":"↗","upsi":"Ï…","Upsi":"Ï’","upsih":"Ï’","Upsilon":"Î¥","upsilon":"Ï…","UpTeeArrow":"↥","UpTee":"⊥","upuparrows":"⇈","urcorn":"âŒ","urcorner":"âŒ","urcrop":"⌎","Uring":"Å®","uring":"ů","urtri":"â—¹","Uscr":"ð’°","uscr":"ð“Š","utdot":"â‹°","Utilde":"Ũ","utilde":"Å©","utri":"â–µ","utrif":"â–´","uuarr":"⇈","Uuml":"Ãœ","uuml":"ü","uwangle":"⦧","vangrt":"⦜","varepsilon":"ϵ","varkappa":"Ï°","varnothing":"∅","varphi":"Ï•","varpi":"Ï–","varpropto":"âˆ","varr":"↕","vArr":"⇕","varrho":"ϱ","varsigma":"Ï‚","varsubsetneq":"⊊︀","varsubsetneqq":"⫋︀","varsupsetneq":"⊋︀","varsupsetneqq":"⫌︀","vartheta":"Ï‘","vartriangleleft":"⊲","vartriangleright":"⊳","vBar":"⫨","Vbar":"â««","vBarv":"â«©","Vcy":"Ð’","vcy":"в","vdash":"⊢","vDash":"⊨","Vdash":"⊩","VDash":"⊫","Vdashl":"⫦","veebar":"⊻","vee":"∨","Vee":"â‹","veeeq":"≚","vellip":"â‹®","verbar":"|","Verbar":"‖","vert":"|","Vert":"‖","VerticalBar":"∣","VerticalLine":"|","VerticalSeparator":"â˜","VerticalTilde":"≀","VeryThinSpace":" ","Vfr":"ð”™","vfr":"ð”³","vltri":"⊲","vnsub":"⊂⃒","vnsup":"⊃⃒","Vopf":"ð•","vopf":"ð•§","vprop":"âˆ","vrtri":"⊳","Vscr":"ð’±","vscr":"ð“‹","vsubnE":"⫋︀","vsubne":"⊊︀","vsupnE":"⫌︀","vsupne":"⊋︀","Vvdash":"⊪","vzigzag":"⦚","Wcirc":"Å´","wcirc":"ŵ","wedbar":"â©Ÿ","wedge":"∧","Wedge":"â‹€","wedgeq":"≙","weierp":"℘","Wfr":"ð”š","wfr":"ð”´","Wopf":"ð•Ž","wopf":"ð•¨","wp":"℘","wr":"≀","wreath":"≀","Wscr":"ð’²","wscr":"ð“Œ","xcap":"â‹‚","xcirc":"â—¯","xcup":"⋃","xdtri":"â–½","Xfr":"ð”›","xfr":"ð”µ","xharr":"⟷","xhArr":"⟺","Xi":"Ξ","xi":"ξ","xlarr":"⟵","xlArr":"⟸","xmap":"⟼","xnis":"â‹»","xodot":"⨀","Xopf":"ð•","xopf":"ð•©","xoplus":"â¨","xotime":"⨂","xrarr":"⟶","xrArr":"⟹","Xscr":"ð’³","xscr":"ð“","xsqcup":"⨆","xuplus":"⨄","xutri":"â–³","xvee":"â‹","xwedge":"â‹€","Yacute":"Ã","yacute":"ý","YAcy":"Я","yacy":"Ñ","Ycirc":"Ŷ","ycirc":"Å·","Ycy":"Ы","ycy":"Ñ‹","yen":"Â¥","Yfr":"ð”œ","yfr":"ð”¶","YIcy":"Ї","yicy":"Ñ—","Yopf":"ð•","yopf":"ð•ª","Yscr":"ð’´","yscr":"ð“Ž","YUcy":"Ю","yucy":"ÑŽ","yuml":"ÿ","Yuml":"Ÿ","Zacute":"Ź","zacute":"ź","Zcaron":"Ž","zcaron":"ž","Zcy":"З","zcy":"з","Zdot":"Å»","zdot":"ż","zeetrf":"ℨ","ZeroWidthSpace":"​","Zeta":"Ζ","zeta":"ζ","zfr":"ð”·","Zfr":"ℨ","ZHcy":"Ж","zhcy":"ж","zigrarr":"â‡","zopf":"ð•«","Zopf":"ℤ","Zscr":"ð’µ","zscr":"ð“","zwj":"â€","zwnj":"‌"}'); /***/ }), -/* 275 */ +/* 276 */ /***/ ((module) => { "use strict"; module.exports = JSON.parse('{"Aacute":"Ã","aacute":"á","Acirc":"Â","acirc":"â","acute":"´","AElig":"Æ","aelig":"æ","Agrave":"À","agrave":"à ","amp":"&","AMP":"&","Aring":"Ã…","aring":"Ã¥","Atilde":"Ã","atilde":"ã","Auml":"Ä","auml":"ä","brvbar":"¦","Ccedil":"Ç","ccedil":"ç","cedil":"¸","cent":"¢","copy":"©","COPY":"©","curren":"¤","deg":"°","divide":"÷","Eacute":"É","eacute":"é","Ecirc":"Ê","ecirc":"ê","Egrave":"È","egrave":"è","ETH":"Ã","eth":"ð","Euml":"Ë","euml":"ë","frac12":"½","frac14":"¼","frac34":"¾","gt":">","GT":">","Iacute":"Ã","iacute":"Ã","Icirc":"ÃŽ","icirc":"î","iexcl":"¡","Igrave":"ÃŒ","igrave":"ì","iquest":"¿","Iuml":"Ã","iuml":"ï","laquo":"«","lt":"<","LT":"<","macr":"¯","micro":"µ","middot":"·","nbsp":" ","not":"¬","Ntilde":"Ñ","ntilde":"ñ","Oacute":"Ó","oacute":"ó","Ocirc":"Ô","ocirc":"ô","Ograve":"Ã’","ograve":"ò","ordf":"ª","ordm":"º","Oslash":"Ø","oslash":"ø","Otilde":"Õ","otilde":"õ","Ouml":"Ö","ouml":"ö","para":"¶","plusmn":"±","pound":"£","quot":"\\"","QUOT":"\\"","raquo":"»","reg":"®","REG":"®","sect":"§","shy":"Â","sup1":"¹","sup2":"²","sup3":"³","szlig":"ß","THORN":"Þ","thorn":"þ","times":"×","Uacute":"Ú","uacute":"ú","Ucirc":"Û","ucirc":"û","Ugrave":"Ù","ugrave":"ù","uml":"¨","Uuml":"Ãœ","uuml":"ü","Yacute":"Ã","yacute":"ý","yen":"Â¥","yuml":"ÿ"}'); /***/ }), -/* 276 */ +/* 277 */ /***/ ((module) => { "use strict"; module.exports = JSON.parse('{"amp":"&","apos":"\'","gt":">","lt":"<","quot":"\\""}'); /***/ }), -/* 277 */ +/* 278 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -43308,7 +43379,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -var decode_json_1 = __importDefault(__webpack_require__(278)); +var decode_json_1 = __importDefault(__webpack_require__(279)); // Adapted from https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119 var fromCodePoint = // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition @@ -43336,14 +43407,14 @@ exports["default"] = decodeCodePoint; /***/ }), -/* 278 */ +/* 279 */ /***/ ((module) => { "use strict"; module.exports = JSON.parse('{"0":65533,"128":8364,"130":8218,"131":402,"132":8222,"133":8230,"134":8224,"135":8225,"136":710,"137":8240,"138":352,"139":8249,"140":338,"142":381,"145":8216,"146":8217,"147":8220,"148":8221,"149":8226,"150":8211,"151":8212,"152":732,"153":8482,"154":353,"155":8250,"156":339,"158":382,"159":376}'); /***/ }), -/* 279 */ +/* 280 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -43353,7 +43424,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = void 0; -var xml_json_1 = __importDefault(__webpack_require__(276)); +var xml_json_1 = __importDefault(__webpack_require__(277)); var inverseXML = getInverseObj(xml_json_1.default); var xmlReplacer = getInverseReplacer(inverseXML); /** @@ -43364,7 +43435,7 @@ var xmlReplacer = getInverseReplacer(inverseXML); * numeric hexadecimal reference (eg. `ü`) will be used. */ exports.encodeXML = getASCIIEncoder(inverseXML); -var entities_json_1 = __importDefault(__webpack_require__(274)); +var entities_json_1 = __importDefault(__webpack_require__(275)); var inverseHTML = getInverseObj(entities_json_1.default); var htmlReplacer = getInverseReplacer(inverseHTML); /** @@ -43486,7 +43557,7 @@ function getASCIIEncoder(obj) { /***/ }), -/* 280 */ +/* 281 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -43596,14 +43667,14 @@ exports.attributeNames = new Map([ /***/ }), -/* 281 */ +/* 282 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.prevElementSibling = exports.nextElementSibling = exports.getName = exports.hasAttrib = exports.getAttributeValue = exports.getSiblings = exports.getParent = exports.getChildren = void 0; -var domhandler_1 = __webpack_require__(268); +var domhandler_1 = __webpack_require__(269); var emptyArray = []; /** * Get a node's children. @@ -43720,7 +43791,7 @@ exports.prevElementSibling = prevElementSibling; /***/ }), -/* 282 */ +/* 283 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -43856,14 +43927,14 @@ exports.prepend = prepend; /***/ }), -/* 283 */ +/* 284 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.findAll = exports.existsOne = exports.findOne = exports.findOneChild = exports.find = exports.filter = void 0; -var domhandler_1 = __webpack_require__(268); +var domhandler_1 = __webpack_require__(269); /** * Search a node and its children for nodes passing a test function. * @@ -43989,15 +44060,15 @@ exports.findAll = findAll; /***/ }), -/* 284 */ +/* 285 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getElementsByTagType = exports.getElementsByTagName = exports.getElementById = exports.getElements = exports.testElement = void 0; -var domhandler_1 = __webpack_require__(268); -var querying_1 = __webpack_require__(283); +var domhandler_1 = __webpack_require__(269); +var querying_1 = __webpack_require__(284); var Checks = { tag_name: function (name) { if (typeof name === "function") { @@ -44120,14 +44191,14 @@ exports.getElementsByTagType = getElementsByTagType; /***/ }), -/* 285 */ +/* 286 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.uniqueSort = exports.compareDocumentPosition = exports.removeSubsets = void 0; -var domhandler_1 = __webpack_require__(268); +var domhandler_1 = __webpack_require__(269); /** * Given an array of nodes, remove any member that is contained by another. * @@ -44252,7 +44323,7 @@ exports.uniqueSort = uniqueSort; /***/ }), -/* 286 */ +/* 287 */ /***/ ((module) => { module.exports = { @@ -44265,7 +44336,7 @@ module.exports = { }; /***/ }), -/* 287 */ +/* 288 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -44275,12 +44346,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.compileToken = exports.compileUnsafe = exports.compile = void 0; -var css_what_1 = __webpack_require__(262); -var boolbase_1 = __webpack_require__(286); -var sort_1 = __importDefault(__webpack_require__(288)); -var procedure_1 = __webpack_require__(289); -var general_1 = __webpack_require__(290); -var subselects_1 = __webpack_require__(299); +var css_what_1 = __webpack_require__(263); +var boolbase_1 = __webpack_require__(287); +var sort_1 = __importDefault(__webpack_require__(289)); +var procedure_1 = __webpack_require__(290); +var general_1 = __webpack_require__(291); +var subselects_1 = __webpack_require__(300); /** * Compiles a selector to an executable function. * @@ -44387,13 +44458,13 @@ function reduceRules(a, b) { /***/ }), -/* 288 */ +/* 289 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -var procedure_1 = __webpack_require__(289); +var procedure_1 = __webpack_require__(290); var attributes = { exists: 10, equals: 8, @@ -44478,7 +44549,7 @@ function getProcedure(token) { /***/ }), -/* 289 */ +/* 290 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -44505,15 +44576,15 @@ exports.isTraversal = isTraversal; /***/ }), -/* 290 */ +/* 291 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.compileGeneralSelector = void 0; -var attributes_1 = __webpack_require__(291); -var pseudo_selectors_1 = __webpack_require__(292); +var attributes_1 = __webpack_require__(292); +var pseudo_selectors_1 = __webpack_require__(293); /* * All available rules */ @@ -44616,14 +44687,14 @@ exports.compileGeneralSelector = compileGeneralSelector; /***/ }), -/* 291 */ +/* 292 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.attributeRules = void 0; -var boolbase_1 = __webpack_require__(286); +var boolbase_1 = __webpack_require__(287); /** * All reserved characters in a regex, used for escaping. * @@ -44794,7 +44865,7 @@ exports.attributeRules = { /***/ }), -/* 292 */ +/* 293 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; @@ -44815,15 +44886,15 @@ exports.compilePseudoSelector = exports.aliases = exports.pseudos = exports.filt * of `next()` and your code. * Pseudos should be used to implement simple checks. */ -var boolbase_1 = __webpack_require__(286); -var css_what_1 = __webpack_require__(262); -var filters_1 = __webpack_require__(293); +var boolbase_1 = __webpack_require__(287); +var css_what_1 = __webpack_require__(263); +var filters_1 = __webpack_require__(294); Object.defineProperty(exports, "filters", ({ enumerable: true, get: function () { return filters_1.filters; } })); -var pseudos_1 = __webpack_require__(297); +var pseudos_1 = __webpack_require__(298); Object.defineProperty(exports, "pseudos", ({ enumerable: true, get: function () { return pseudos_1.pseudos; } })); -var aliases_1 = __webpack_require__(298); +var aliases_1 = __webpack_require__(299); Object.defineProperty(exports, "aliases", ({ enumerable: true, get: function () { return aliases_1.aliases; } })); -var subselects_1 = __webpack_require__(299); +var subselects_1 = __webpack_require__(300); function compilePseudoSelector(next, selector, options, context, compileToken) { var name = selector.name, data = selector.data; if (Array.isArray(data)) { @@ -44855,7 +44926,7 @@ exports.compilePseudoSelector = compilePseudoSelector; /***/ }), -/* 293 */ +/* 294 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -44865,8 +44936,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.filters = void 0; -var nth_check_1 = __importDefault(__webpack_require__(294)); -var boolbase_1 = __webpack_require__(286); +var nth_check_1 = __importDefault(__webpack_require__(295)); +var boolbase_1 = __webpack_require__(287); function getChildFunc(next, adapter) { return function (elem) { var parent = adapter.getParent(elem); @@ -45018,16 +45089,16 @@ function dynamicStatePseudo(name) { /***/ }), -/* 294 */ +/* 295 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.compile = exports.parse = void 0; -var parse_1 = __webpack_require__(295); +var parse_1 = __webpack_require__(296); Object.defineProperty(exports, "parse", ({ enumerable: true, get: function () { return parse_1.parse; } })); -var compile_1 = __webpack_require__(296); +var compile_1 = __webpack_require__(297); Object.defineProperty(exports, "compile", ({ enumerable: true, get: function () { return compile_1.compile; } })); /** * Parses and compiles a formula to a highly optimized function. @@ -45059,7 +45130,7 @@ exports["default"] = nthCheck; /***/ }), -/* 295 */ +/* 296 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -45105,14 +45176,14 @@ exports.parse = parse; /***/ }), -/* 296 */ +/* 297 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.compile = void 0; -var boolbase_1 = __webpack_require__(286); +var boolbase_1 = __webpack_require__(287); /** * Returns a function that checks if an elements index matches the given rule * highly optimized to return the fastest solution. @@ -45167,7 +45238,7 @@ exports.compile = compile; /***/ }), -/* 297 */ +/* 298 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -45263,7 +45334,7 @@ exports.verifyPseudoArgs = verifyPseudoArgs; /***/ }), -/* 298 */ +/* 299 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -45303,7 +45374,7 @@ exports.aliases = { /***/ }), -/* 299 */ +/* 300 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -45315,8 +45386,8 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.subselects = exports.getNextSiblings = exports.ensureIsTag = exports.PLACEHOLDER_ELEMENT = void 0; -var boolbase_1 = __webpack_require__(286); -var procedure_1 = __webpack_require__(289); +var boolbase_1 = __webpack_require__(287); +var procedure_1 = __webpack_require__(290); /** Used as a placeholder for :has. Will be replaced with the actual element. */ exports.PLACEHOLDER_ELEMENT = {}; function ensureIsTag(next, adapter) { @@ -45415,14 +45486,14 @@ exports.subselects = { /***/ }), -/* 300 */ +/* 301 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.groupSelectors = exports.getDocumentRoot = void 0; -var positionals_1 = __webpack_require__(301); +var positionals_1 = __webpack_require__(302); function getDocumentRoot(node) { while (node.parent) node = node.parent; @@ -45447,7 +45518,7 @@ exports.groupSelectors = groupSelectors; /***/ }), -/* 301 */ +/* 302 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -45496,7 +45567,7 @@ exports.getLimit = getLimit; /***/ }), -/* 302 */ +/* 303 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -45528,9 +45599,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.RssHandler = exports.DefaultHandler = exports.DomUtils = exports.ElementType = exports.Tokenizer = exports.createDomStream = exports.parseDOM = exports.parseDocument = exports.DomHandler = exports.Parser = void 0; -var Parser_1 = __webpack_require__(303); +var Parser_1 = __webpack_require__(304); Object.defineProperty(exports, "Parser", ({ enumerable: true, get: function () { return Parser_1.Parser; } })); -var domhandler_1 = __webpack_require__(268); +var domhandler_1 = __webpack_require__(306); Object.defineProperty(exports, "DomHandler", ({ enumerable: true, get: function () { return domhandler_1.DomHandler; } })); Object.defineProperty(exports, "DefaultHandler", ({ enumerable: true, get: function () { return domhandler_1.DomHandler; } })); // Helper methods @@ -45572,22 +45643,22 @@ function createDomStream(cb, options, elementCb) { return new Parser_1.Parser(handler, options); } exports.createDomStream = createDomStream; -var Tokenizer_1 = __webpack_require__(304); +var Tokenizer_1 = __webpack_require__(305); Object.defineProperty(exports, "Tokenizer", ({ enumerable: true, get: function () { return __importDefault(Tokenizer_1).default; } })); -var ElementType = __importStar(__webpack_require__(269)); +var ElementType = __importStar(__webpack_require__(270)); exports.ElementType = ElementType; /* * All of the following exports exist for backwards-compatibility. * They should probably be removed eventually. */ -__exportStar(__webpack_require__(305), exports); -exports.DomUtils = __importStar(__webpack_require__(266)); -var FeedHandler_1 = __webpack_require__(305); +__exportStar(__webpack_require__(308), exports); +exports.DomUtils = __importStar(__webpack_require__(309)); +var FeedHandler_1 = __webpack_require__(308); Object.defineProperty(exports, "RssHandler", ({ enumerable: true, get: function () { return FeedHandler_1.FeedHandler; } })); /***/ }), -/* 303 */ +/* 304 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -45597,7 +45668,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.Parser = void 0; -var Tokenizer_1 = __importDefault(__webpack_require__(304)); +var Tokenizer_1 = __importDefault(__webpack_require__(305)); var formTags = new Set([ "input", "option", @@ -45975,7 +46046,7 @@ exports.Parser = Parser; /***/ }), -/* 304 */ +/* 305 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -45984,10 +46055,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -var decode_codepoint_1 = __importDefault(__webpack_require__(277)); -var entities_json_1 = __importDefault(__webpack_require__(274)); -var legacy_json_1 = __importDefault(__webpack_require__(275)); -var xml_json_1 = __importDefault(__webpack_require__(276)); +var decode_codepoint_1 = __importDefault(__webpack_require__(278)); +var entities_json_1 = __importDefault(__webpack_require__(275)); +var legacy_json_1 = __importDefault(__webpack_require__(276)); +var xml_json_1 = __importDefault(__webpack_require__(277)); function whitespace(c) { return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r"; } @@ -46891,7 +46962,580 @@ exports["default"] = Tokenizer; /***/ }), -/* 305 */ +/* 306 */ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.DomHandler = void 0; +var domelementtype_1 = __webpack_require__(270); +var node_1 = __webpack_require__(307); +__exportStar(__webpack_require__(307), exports); +var reWhitespace = /\s+/g; +// Default options +var defaultOpts = { + normalizeWhitespace: false, + withStartIndices: false, + withEndIndices: false, +}; +var DomHandler = /** @class */ (function () { + /** + * @param callback Called once parsing has completed. + * @param options Settings for the handler. + * @param elementCB Callback whenever a tag is closed. + */ + function DomHandler(callback, options, elementCB) { + /** The elements of the DOM */ + this.dom = []; + /** The root element for the DOM */ + this.root = new node_1.Document(this.dom); + /** Indicated whether parsing has been completed. */ + this.done = false; + /** Stack of open tags. */ + this.tagStack = [this.root]; + /** A data node that is still being written to. */ + this.lastNode = null; + /** Reference to the parser instance. Used for location information. */ + this.parser = null; + // Make it possible to skip arguments, for backwards-compatibility + if (typeof options === "function") { + elementCB = options; + options = defaultOpts; + } + if (typeof callback === "object") { + options = callback; + callback = undefined; + } + this.callback = callback !== null && callback !== void 0 ? callback : null; + this.options = options !== null && options !== void 0 ? options : defaultOpts; + this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null; + } + DomHandler.prototype.onparserinit = function (parser) { + this.parser = parser; + }; + // Resets the handler back to starting state + DomHandler.prototype.onreset = function () { + var _a; + this.dom = []; + this.root = new node_1.Document(this.dom); + this.done = false; + this.tagStack = [this.root]; + this.lastNode = null; + this.parser = (_a = this.parser) !== null && _a !== void 0 ? _a : null; + }; + // Signals the handler that parsing is done + DomHandler.prototype.onend = function () { + if (this.done) + return; + this.done = true; + this.parser = null; + this.handleCallback(null); + }; + DomHandler.prototype.onerror = function (error) { + this.handleCallback(error); + }; + DomHandler.prototype.onclosetag = function () { + this.lastNode = null; + var elem = this.tagStack.pop(); + if (this.options.withEndIndices) { + elem.endIndex = this.parser.endIndex; + } + if (this.elementCB) + this.elementCB(elem); + }; + DomHandler.prototype.onopentag = function (name, attribs) { + var type = this.options.xmlMode ? domelementtype_1.ElementType.Tag : undefined; + var element = new node_1.Element(name, attribs, undefined, type); + this.addNode(element); + this.tagStack.push(element); + }; + DomHandler.prototype.ontext = function (data) { + var normalizeWhitespace = this.options.normalizeWhitespace; + var lastNode = this.lastNode; + if (lastNode && lastNode.type === domelementtype_1.ElementType.Text) { + if (normalizeWhitespace) { + lastNode.data = (lastNode.data + data).replace(reWhitespace, " "); + } + else { + lastNode.data += data; + } + } + else { + if (normalizeWhitespace) { + data = data.replace(reWhitespace, " "); + } + var node = new node_1.Text(data); + this.addNode(node); + this.lastNode = node; + } + }; + DomHandler.prototype.oncomment = function (data) { + if (this.lastNode && this.lastNode.type === domelementtype_1.ElementType.Comment) { + this.lastNode.data += data; + return; + } + var node = new node_1.Comment(data); + this.addNode(node); + this.lastNode = node; + }; + DomHandler.prototype.oncommentend = function () { + this.lastNode = null; + }; + DomHandler.prototype.oncdatastart = function () { + var text = new node_1.Text(""); + var node = new node_1.NodeWithChildren(domelementtype_1.ElementType.CDATA, [text]); + this.addNode(node); + text.parent = node; + this.lastNode = text; + }; + DomHandler.prototype.oncdataend = function () { + this.lastNode = null; + }; + DomHandler.prototype.onprocessinginstruction = function (name, data) { + var node = new node_1.ProcessingInstruction(name, data); + this.addNode(node); + }; + DomHandler.prototype.handleCallback = function (error) { + if (typeof this.callback === "function") { + this.callback(error, this.dom); + } + else if (error) { + throw error; + } + }; + DomHandler.prototype.addNode = function (node) { + var parent = this.tagStack[this.tagStack.length - 1]; + var previousSibling = parent.children[parent.children.length - 1]; + if (this.options.withStartIndices) { + node.startIndex = this.parser.startIndex; + } + if (this.options.withEndIndices) { + node.endIndex = this.parser.endIndex; + } + parent.children.push(node); + if (previousSibling) { + node.prev = previousSibling; + previousSibling.next = node; + } + node.parent = parent; + this.lastNode = null; + }; + return DomHandler; +}()); +exports.DomHandler = DomHandler; +exports["default"] = DomHandler; + + +/***/ }), +/* 307 */ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +"use strict"; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.cloneNode = exports.hasChildren = exports.isDocument = exports.isDirective = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = exports.Element = exports.Document = exports.NodeWithChildren = exports.ProcessingInstruction = exports.Comment = exports.Text = exports.DataNode = exports.Node = void 0; +var domelementtype_1 = __webpack_require__(270); +var nodeTypes = new Map([ + [domelementtype_1.ElementType.Tag, 1], + [domelementtype_1.ElementType.Script, 1], + [domelementtype_1.ElementType.Style, 1], + [domelementtype_1.ElementType.Directive, 1], + [domelementtype_1.ElementType.Text, 3], + [domelementtype_1.ElementType.CDATA, 4], + [domelementtype_1.ElementType.Comment, 8], + [domelementtype_1.ElementType.Root, 9], +]); +/** + * This object will be used as the prototype for Nodes when creating a + * DOM-Level-1-compliant structure. + */ +var Node = /** @class */ (function () { + /** + * + * @param type The type of the node. + */ + function Node(type) { + this.type = type; + /** Parent of the node */ + this.parent = null; + /** Previous sibling */ + this.prev = null; + /** Next sibling */ + this.next = null; + /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */ + this.startIndex = null; + /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */ + this.endIndex = null; + } + Object.defineProperty(Node.prototype, "nodeType", { + // Read-only aliases + get: function () { + var _a; + return (_a = nodeTypes.get(this.type)) !== null && _a !== void 0 ? _a : 1; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "parentNode", { + // Read-write aliases for properties + get: function () { + return this.parent; + }, + set: function (parent) { + this.parent = parent; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "previousSibling", { + get: function () { + return this.prev; + }, + set: function (prev) { + this.prev = prev; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "nextSibling", { + get: function () { + return this.next; + }, + set: function (next) { + this.next = next; + }, + enumerable: false, + configurable: true + }); + /** + * Clone this node, and optionally its children. + * + * @param recursive Clone child nodes as well. + * @returns A clone of the node. + */ + Node.prototype.cloneNode = function (recursive) { + if (recursive === void 0) { recursive = false; } + return cloneNode(this, recursive); + }; + return Node; +}()); +exports.Node = Node; +var DataNode = /** @class */ (function (_super) { + __extends(DataNode, _super); + /** + * @param type The type of the node + * @param data The content of the data node + */ + function DataNode(type, data) { + var _this = _super.call(this, type) || this; + _this.data = data; + return _this; + } + Object.defineProperty(DataNode.prototype, "nodeValue", { + get: function () { + return this.data; + }, + set: function (data) { + this.data = data; + }, + enumerable: false, + configurable: true + }); + return DataNode; +}(Node)); +exports.DataNode = DataNode; +var Text = /** @class */ (function (_super) { + __extends(Text, _super); + function Text(data) { + return _super.call(this, domelementtype_1.ElementType.Text, data) || this; + } + return Text; +}(DataNode)); +exports.Text = Text; +var Comment = /** @class */ (function (_super) { + __extends(Comment, _super); + function Comment(data) { + return _super.call(this, domelementtype_1.ElementType.Comment, data) || this; + } + return Comment; +}(DataNode)); +exports.Comment = Comment; +var ProcessingInstruction = /** @class */ (function (_super) { + __extends(ProcessingInstruction, _super); + function ProcessingInstruction(name, data) { + var _this = _super.call(this, domelementtype_1.ElementType.Directive, data) || this; + _this.name = name; + return _this; + } + return ProcessingInstruction; +}(DataNode)); +exports.ProcessingInstruction = ProcessingInstruction; +/** + * A `Node` that can have children. + */ +var NodeWithChildren = /** @class */ (function (_super) { + __extends(NodeWithChildren, _super); + /** + * @param type Type of the node. + * @param children Children of the node. Only certain node types can have children. + */ + function NodeWithChildren(type, children) { + var _this = _super.call(this, type) || this; + _this.children = children; + return _this; + } + Object.defineProperty(NodeWithChildren.prototype, "firstChild", { + // Aliases + get: function () { + var _a; + return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(NodeWithChildren.prototype, "lastChild", { + get: function () { + return this.children.length > 0 + ? this.children[this.children.length - 1] + : null; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(NodeWithChildren.prototype, "childNodes", { + get: function () { + return this.children; + }, + set: function (children) { + this.children = children; + }, + enumerable: false, + configurable: true + }); + return NodeWithChildren; +}(Node)); +exports.NodeWithChildren = NodeWithChildren; +var Document = /** @class */ (function (_super) { + __extends(Document, _super); + function Document(children) { + return _super.call(this, domelementtype_1.ElementType.Root, children) || this; + } + return Document; +}(NodeWithChildren)); +exports.Document = Document; +var Element = /** @class */ (function (_super) { + __extends(Element, _super); + /** + * @param name Name of the tag, eg. `div`, `span`. + * @param attribs Object mapping attribute names to attribute values. + * @param children Children of the node. + */ + function Element(name, attribs, children, type) { + if (children === void 0) { children = []; } + if (type === void 0) { type = name === "script" + ? domelementtype_1.ElementType.Script + : name === "style" + ? domelementtype_1.ElementType.Style + : domelementtype_1.ElementType.Tag; } + var _this = _super.call(this, type, children) || this; + _this.name = name; + _this.attribs = attribs; + return _this; + } + Object.defineProperty(Element.prototype, "tagName", { + // DOM Level 1 aliases + get: function () { + return this.name; + }, + set: function (name) { + this.name = name; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Element.prototype, "attributes", { + get: function () { + var _this = this; + return Object.keys(this.attribs).map(function (name) { + var _a, _b; + return ({ + name: name, + value: _this.attribs[name], + namespace: (_a = _this["x-attribsNamespace"]) === null || _a === void 0 ? void 0 : _a[name], + prefix: (_b = _this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name], + }); + }); + }, + enumerable: false, + configurable: true + }); + return Element; +}(NodeWithChildren)); +exports.Element = Element; +/** + * @param node Node to check. + * @returns `true` if the node is a `Element`, `false` otherwise. + */ +function isTag(node) { + return domelementtype_1.isTag(node); +} +exports.isTag = isTag; +/** + * @param node Node to check. + * @returns `true` if the node has the type `CDATA`, `false` otherwise. + */ +function isCDATA(node) { + return node.type === domelementtype_1.ElementType.CDATA; +} +exports.isCDATA = isCDATA; +/** + * @param node Node to check. + * @returns `true` if the node has the type `Text`, `false` otherwise. + */ +function isText(node) { + return node.type === domelementtype_1.ElementType.Text; +} +exports.isText = isText; +/** + * @param node Node to check. + * @returns `true` if the node has the type `Comment`, `false` otherwise. + */ +function isComment(node) { + return node.type === domelementtype_1.ElementType.Comment; +} +exports.isComment = isComment; +/** + * @param node Node to check. + * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise. + */ +function isDirective(node) { + return node.type === domelementtype_1.ElementType.Directive; +} +exports.isDirective = isDirective; +/** + * @param node Node to check. + * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise. + */ +function isDocument(node) { + return node.type === domelementtype_1.ElementType.Root; +} +exports.isDocument = isDocument; +/** + * @param node Node to check. + * @returns `true` if the node is a `NodeWithChildren` (has children), `false` otherwise. + */ +function hasChildren(node) { + return Object.prototype.hasOwnProperty.call(node, "children"); +} +exports.hasChildren = hasChildren; +/** + * Clone a node, and optionally its children. + * + * @param recursive Clone child nodes as well. + * @returns A clone of the node. + */ +function cloneNode(node, recursive) { + if (recursive === void 0) { recursive = false; } + var result; + if (isText(node)) { + result = new Text(node.data); + } + else if (isComment(node)) { + result = new Comment(node.data); + } + else if (isTag(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_1 = new Element(node.name, __assign({}, node.attribs), children); + children.forEach(function (child) { return (child.parent = clone_1); }); + if (node["x-attribsNamespace"]) { + clone_1["x-attribsNamespace"] = __assign({}, node["x-attribsNamespace"]); + } + if (node["x-attribsPrefix"]) { + clone_1["x-attribsPrefix"] = __assign({}, node["x-attribsPrefix"]); + } + result = clone_1; + } + else if (isCDATA(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_2 = new NodeWithChildren(domelementtype_1.ElementType.CDATA, children); + children.forEach(function (child) { return (child.parent = clone_2); }); + result = clone_2; + } + else if (isDocument(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_3 = new Document(children); + children.forEach(function (child) { return (child.parent = clone_3); }); + if (node["x-mode"]) { + clone_3["x-mode"] = node["x-mode"]; + } + result = clone_3; + } + else if (isDirective(node)) { + var instruction = new ProcessingInstruction(node.name, node.data); + if (node["x-name"] != null) { + instruction["x-name"] = node["x-name"]; + instruction["x-publicId"] = node["x-publicId"]; + instruction["x-systemId"] = node["x-systemId"]; + } + result = instruction; + } + else { + throw new Error("Not implemented yet: " + node.type); + } + result.startIndex = node.startIndex; + result.endIndex = node.endIndex; + return result; +} +exports.cloneNode = cloneNode; +function cloneChildren(childs) { + var children = childs.map(function (child) { return cloneNode(child, true); }); + for (var i = 1; i < children.length; i++) { + children[i].prev = children[i - 1]; + children[i - 1].next = children[i]; + } + return children; +} + + +/***/ }), +/* 308 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -46935,9 +47579,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.parseFeed = exports.FeedHandler = void 0; -var domhandler_1 = __importDefault(__webpack_require__(268)); -var DomUtils = __importStar(__webpack_require__(266)); -var Parser_1 = __webpack_require__(303); +var domhandler_1 = __importDefault(__webpack_require__(306)); +var DomUtils = __importStar(__webpack_require__(309)); +var Parser_1 = __webpack_require__(304); var FeedItemMediaMedium; (function (FeedItemMediaMedium) { FeedItemMediaMedium[FeedItemMediaMedium["image"] = 0] = "image"; @@ -47133,17 +47777,802 @@ exports.parseFeed = parseFeed; /***/ }), -/* 306 */ +/* 309 */ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.hasChildren = exports.isDocument = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = void 0; +__exportStar(__webpack_require__(310), exports); +__exportStar(__webpack_require__(311), exports); +__exportStar(__webpack_require__(312), exports); +__exportStar(__webpack_require__(313), exports); +__exportStar(__webpack_require__(314), exports); +__exportStar(__webpack_require__(315), exports); +var domhandler_1 = __webpack_require__(306); +Object.defineProperty(exports, "isTag", ({ enumerable: true, get: function () { return domhandler_1.isTag; } })); +Object.defineProperty(exports, "isCDATA", ({ enumerable: true, get: function () { return domhandler_1.isCDATA; } })); +Object.defineProperty(exports, "isText", ({ enumerable: true, get: function () { return domhandler_1.isText; } })); +Object.defineProperty(exports, "isComment", ({ enumerable: true, get: function () { return domhandler_1.isComment; } })); +Object.defineProperty(exports, "isDocument", ({ enumerable: true, get: function () { return domhandler_1.isDocument; } })); +Object.defineProperty(exports, "hasChildren", ({ enumerable: true, get: function () { return domhandler_1.hasChildren; } })); + + +/***/ }), +/* 310 */ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +"use strict"; + +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.innerText = exports.textContent = exports.getText = exports.getInnerHTML = exports.getOuterHTML = void 0; +var domhandler_1 = __webpack_require__(306); +var dom_serializer_1 = __importDefault(__webpack_require__(272)); +var domelementtype_1 = __webpack_require__(270); +/** + * @param node Node to get the outer HTML of. + * @param options Options for serialization. + * @deprecated Use the `dom-serializer` module directly. + * @returns `node`'s outer HTML. + */ +function getOuterHTML(node, options) { + return dom_serializer_1.default(node, options); +} +exports.getOuterHTML = getOuterHTML; +/** + * @param node Node to get the inner HTML of. + * @param options Options for serialization. + * @deprecated Use the `dom-serializer` module directly. + * @returns `node`'s inner HTML. + */ +function getInnerHTML(node, options) { + return domhandler_1.hasChildren(node) + ? node.children.map(function (node) { return getOuterHTML(node, options); }).join("") + : ""; +} +exports.getInnerHTML = getInnerHTML; +/** + * Get a node's inner text. Same as `textContent`, but inserts newlines for `<br>` tags. + * + * @deprecated Use `textContent` instead. + * @param node Node to get the inner text of. + * @returns `node`'s inner text. + */ +function getText(node) { + if (Array.isArray(node)) + return node.map(getText).join(""); + if (domhandler_1.isTag(node)) + return node.name === "br" ? "\n" : getText(node.children); + if (domhandler_1.isCDATA(node)) + return getText(node.children); + if (domhandler_1.isText(node)) + return node.data; + return ""; +} +exports.getText = getText; +/** + * Get a node's text content. + * + * @param node Node to get the text content of. + * @returns `node`'s text content. + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent} + */ +function textContent(node) { + if (Array.isArray(node)) + return node.map(textContent).join(""); + if (domhandler_1.isTag(node)) + return textContent(node.children); + if (domhandler_1.isCDATA(node)) + return textContent(node.children); + if (domhandler_1.isText(node)) + return node.data; + return ""; +} +exports.textContent = textContent; +/** + * Get a node's inner text. + * + * @param node Node to get the inner text of. + * @returns `node`'s inner text. + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/innerText} + */ +function innerText(node) { + if (Array.isArray(node)) + return node.map(innerText).join(""); + if (domhandler_1.hasChildren(node) && node.type === domelementtype_1.ElementType.Tag) { + return innerText(node.children); + } + if (domhandler_1.isCDATA(node)) + return innerText(node.children); + if (domhandler_1.isText(node)) + return node.data; + return ""; +} +exports.innerText = innerText; + + +/***/ }), +/* 311 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.prevElementSibling = exports.nextElementSibling = exports.getName = exports.hasAttrib = exports.getAttributeValue = exports.getSiblings = exports.getParent = exports.getChildren = void 0; +var domhandler_1 = __webpack_require__(306); +var emptyArray = []; +/** + * Get a node's children. + * + * @param elem Node to get the children of. + * @returns `elem`'s children, or an empty array. + */ +function getChildren(elem) { + var _a; + return (_a = elem.children) !== null && _a !== void 0 ? _a : emptyArray; +} +exports.getChildren = getChildren; +/** + * Get a node's parent. + * + * @param elem Node to get the parent of. + * @returns `elem`'s parent node. + */ +function getParent(elem) { + return elem.parent || null; +} +exports.getParent = getParent; +/** + * Gets an elements siblings, including the element itself. + * + * Attempts to get the children through the element's parent first. + * If we don't have a parent (the element is a root node), + * we walk the element's `prev` & `next` to get all remaining nodes. + * + * @param elem Element to get the siblings of. + * @returns `elem`'s siblings. + */ +function getSiblings(elem) { + var _a, _b; + var parent = getParent(elem); + if (parent != null) + return getChildren(parent); + var siblings = [elem]; + var prev = elem.prev, next = elem.next; + while (prev != null) { + siblings.unshift(prev); + (_a = prev, prev = _a.prev); + } + while (next != null) { + siblings.push(next); + (_b = next, next = _b.next); + } + return siblings; +} +exports.getSiblings = getSiblings; +/** + * Gets an attribute from an element. + * + * @param elem Element to check. + * @param name Attribute name to retrieve. + * @returns The element's attribute value, or `undefined`. + */ +function getAttributeValue(elem, name) { + var _a; + return (_a = elem.attribs) === null || _a === void 0 ? void 0 : _a[name]; +} +exports.getAttributeValue = getAttributeValue; +/** + * Checks whether an element has an attribute. + * + * @param elem Element to check. + * @param name Attribute name to look for. + * @returns Returns whether `elem` has the attribute `name`. + */ +function hasAttrib(elem, name) { + return (elem.attribs != null && + Object.prototype.hasOwnProperty.call(elem.attribs, name) && + elem.attribs[name] != null); +} +exports.hasAttrib = hasAttrib; +/** + * Get the tag name of an element. + * + * @param elem The element to get the name for. + * @returns The tag name of `elem`. + */ +function getName(elem) { + return elem.name; +} +exports.getName = getName; +/** + * Returns the next element sibling of a node. + * + * @param elem The element to get the next sibling of. + * @returns `elem`'s next sibling that is a tag. + */ +function nextElementSibling(elem) { + var _a; + var next = elem.next; + while (next !== null && !domhandler_1.isTag(next)) + (_a = next, next = _a.next); + return next; +} +exports.nextElementSibling = nextElementSibling; +/** + * Returns the previous element sibling of a node. + * + * @param elem The element to get the previous sibling of. + * @returns `elem`'s previous sibling that is a tag. + */ +function prevElementSibling(elem) { + var _a; + var prev = elem.prev; + while (prev !== null && !domhandler_1.isTag(prev)) + (_a = prev, prev = _a.prev); + return prev; +} +exports.prevElementSibling = prevElementSibling; + + +/***/ }), +/* 312 */ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.prepend = exports.prependChild = exports.append = exports.appendChild = exports.replaceElement = exports.removeElement = void 0; +/** + * Remove an element from the dom + * + * @param elem The element to be removed + */ +function removeElement(elem) { + if (elem.prev) + elem.prev.next = elem.next; + if (elem.next) + elem.next.prev = elem.prev; + if (elem.parent) { + var childs = elem.parent.children; + childs.splice(childs.lastIndexOf(elem), 1); + } +} +exports.removeElement = removeElement; +/** + * Replace an element in the dom + * + * @param elem The element to be replaced + * @param replacement The element to be added + */ +function replaceElement(elem, replacement) { + var prev = (replacement.prev = elem.prev); + if (prev) { + prev.next = replacement; + } + var next = (replacement.next = elem.next); + if (next) { + next.prev = replacement; + } + var parent = (replacement.parent = elem.parent); + if (parent) { + var childs = parent.children; + childs[childs.lastIndexOf(elem)] = replacement; + } +} +exports.replaceElement = replaceElement; +/** + * Append a child to an element. + * + * @param elem The element to append to. + * @param child The element to be added as a child. + */ +function appendChild(elem, child) { + removeElement(child); + child.next = null; + child.parent = elem; + if (elem.children.push(child) > 1) { + var sibling = elem.children[elem.children.length - 2]; + sibling.next = child; + child.prev = sibling; + } + else { + child.prev = null; + } +} +exports.appendChild = appendChild; +/** + * Append an element after another. + * + * @param elem The element to append after. + * @param next The element be added. + */ +function append(elem, next) { + removeElement(next); + var parent = elem.parent; + var currNext = elem.next; + next.next = currNext; + next.prev = elem; + elem.next = next; + next.parent = parent; + if (currNext) { + currNext.prev = next; + if (parent) { + var childs = parent.children; + childs.splice(childs.lastIndexOf(currNext), 0, next); + } + } + else if (parent) { + parent.children.push(next); + } +} +exports.append = append; +/** + * Prepend a child to an element. + * + * @param elem The element to prepend before. + * @param child The element to be added as a child. + */ +function prependChild(elem, child) { + removeElement(child); + child.parent = elem; + child.prev = null; + if (elem.children.unshift(child) !== 1) { + var sibling = elem.children[1]; + sibling.prev = child; + child.next = sibling; + } + else { + child.next = null; + } +} +exports.prependChild = prependChild; +/** + * Prepend an element before another. + * + * @param elem The element to prepend before. + * @param prev The element be added. + */ +function prepend(elem, prev) { + removeElement(prev); + var parent = elem.parent; + if (parent) { + var childs = parent.children; + childs.splice(childs.indexOf(elem), 0, prev); + } + if (elem.prev) { + elem.prev.next = prev; + } + prev.parent = parent; + prev.prev = elem.prev; + prev.next = elem; + elem.prev = prev; +} +exports.prepend = prepend; + + +/***/ }), +/* 313 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.findAll = exports.existsOne = exports.findOne = exports.findOneChild = exports.find = exports.filter = void 0; +var domhandler_1 = __webpack_require__(306); +/** + * Search a node and its children for nodes passing a test function. + * + * @param test Function to test nodes on. + * @param node Node to search. Will be included in the result set if it matches. + * @param recurse Also consider child nodes. + * @param limit Maximum number of nodes to return. + * @returns All nodes passing `test`. + */ +function filter(test, node, recurse, limit) { + if (recurse === void 0) { recurse = true; } + if (limit === void 0) { limit = Infinity; } + if (!Array.isArray(node)) + node = [node]; + return find(test, node, recurse, limit); +} +exports.filter = filter; +/** + * Search an array of node and its children for nodes passing a test function. + * + * @param test Function to test nodes on. + * @param nodes Array of nodes to search. + * @param recurse Also consider child nodes. + * @param limit Maximum number of nodes to return. + * @returns All nodes passing `test`. + */ +function find(test, nodes, recurse, limit) { + var result = []; + for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { + var elem = nodes_1[_i]; + if (test(elem)) { + result.push(elem); + if (--limit <= 0) + break; + } + if (recurse && domhandler_1.hasChildren(elem) && elem.children.length > 0) { + var children = find(test, elem.children, recurse, limit); + result.push.apply(result, children); + limit -= children.length; + if (limit <= 0) + break; + } + } + return result; +} +exports.find = find; +/** + * Finds the first element inside of an array that matches a test function. + * + * @param test Function to test nodes on. + * @param nodes Array of nodes to search. + * @returns The first node in the array that passes `test`. + */ +function findOneChild(test, nodes) { + return nodes.find(test); +} +exports.findOneChild = findOneChild; +/** + * Finds one element in a tree that passes a test. + * + * @param test Function to test nodes on. + * @param nodes Array of nodes to search. + * @param recurse Also consider child nodes. + * @returns The first child node that passes `test`. + */ +function findOne(test, nodes, recurse) { + if (recurse === void 0) { recurse = true; } + var elem = null; + for (var i = 0; i < nodes.length && !elem; i++) { + var checked = nodes[i]; + if (!domhandler_1.isTag(checked)) { + continue; + } + else if (test(checked)) { + elem = checked; + } + else if (recurse && checked.children.length > 0) { + elem = findOne(test, checked.children); + } + } + return elem; +} +exports.findOne = findOne; +/** + * @param test Function to test nodes on. + * @param nodes Array of nodes to search. + * @returns Whether a tree of nodes contains at least one node passing a test. + */ +function existsOne(test, nodes) { + return nodes.some(function (checked) { + return domhandler_1.isTag(checked) && + (test(checked) || + (checked.children.length > 0 && + existsOne(test, checked.children))); + }); +} +exports.existsOne = existsOne; +/** + * Search and array of nodes and its children for nodes passing a test function. + * + * Same as `find`, only with less options, leading to reduced complexity. + * + * @param test Function to test nodes on. + * @param nodes Array of nodes to search. + * @returns All nodes passing `test`. + */ +function findAll(test, nodes) { + var _a; + var result = []; + var stack = nodes.filter(domhandler_1.isTag); + var elem; + while ((elem = stack.shift())) { + var children = (_a = elem.children) === null || _a === void 0 ? void 0 : _a.filter(domhandler_1.isTag); + if (children && children.length > 0) { + stack.unshift.apply(stack, children); + } + if (test(elem)) + result.push(elem); + } + return result; +} +exports.findAll = findAll; + + +/***/ }), +/* 314 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getElementsByTagType = exports.getElementsByTagName = exports.getElementById = exports.getElements = exports.testElement = void 0; +var domhandler_1 = __webpack_require__(306); +var querying_1 = __webpack_require__(313); +var Checks = { + tag_name: function (name) { + if (typeof name === "function") { + return function (elem) { return domhandler_1.isTag(elem) && name(elem.name); }; + } + else if (name === "*") { + return domhandler_1.isTag; + } + return function (elem) { return domhandler_1.isTag(elem) && elem.name === name; }; + }, + tag_type: function (type) { + if (typeof type === "function") { + return function (elem) { return type(elem.type); }; + } + return function (elem) { return elem.type === type; }; + }, + tag_contains: function (data) { + if (typeof data === "function") { + return function (elem) { return domhandler_1.isText(elem) && data(elem.data); }; + } + return function (elem) { return domhandler_1.isText(elem) && elem.data === data; }; + }, +}; +/** + * @param attrib Attribute to check. + * @param value Attribute value to look for. + * @returns A function to check whether the a node has an attribute with a particular value. + */ +function getAttribCheck(attrib, value) { + if (typeof value === "function") { + return function (elem) { return domhandler_1.isTag(elem) && value(elem.attribs[attrib]); }; + } + return function (elem) { return domhandler_1.isTag(elem) && elem.attribs[attrib] === value; }; +} +/** + * @param a First function to combine. + * @param b Second function to combine. + * @returns A function taking a node and returning `true` if either + * of the input functions returns `true` for the node. + */ +function combineFuncs(a, b) { + return function (elem) { return a(elem) || b(elem); }; +} +/** + * @param options An object describing nodes to look for. + * @returns A function executing all checks in `options` and returning `true` + * if any of them match a node. + */ +function compileTest(options) { + var funcs = Object.keys(options).map(function (key) { + var value = options[key]; + return key in Checks + ? Checks[key](value) + : getAttribCheck(key, value); + }); + return funcs.length === 0 ? null : funcs.reduce(combineFuncs); +} +/** + * @param options An object describing nodes to look for. + * @param node The element to test. + * @returns Whether the element matches the description in `options`. + */ +function testElement(options, node) { + var test = compileTest(options); + return test ? test(node) : true; +} +exports.testElement = testElement; +/** + * @param options An object describing nodes to look for. + * @param nodes Nodes to search through. + * @param recurse Also consider child nodes. + * @param limit Maximum number of nodes to return. + * @returns All nodes that match `options`. + */ +function getElements(options, nodes, recurse, limit) { + if (limit === void 0) { limit = Infinity; } + var test = compileTest(options); + return test ? querying_1.filter(test, nodes, recurse, limit) : []; +} +exports.getElements = getElements; +/** + * @param id The unique ID attribute value to look for. + * @param nodes Nodes to search through. + * @param recurse Also consider child nodes. + * @returns The node with the supplied ID. + */ +function getElementById(id, nodes, recurse) { + if (recurse === void 0) { recurse = true; } + if (!Array.isArray(nodes)) + nodes = [nodes]; + return querying_1.findOne(getAttribCheck("id", id), nodes, recurse); +} +exports.getElementById = getElementById; +/** + * @param tagName Tag name to search for. + * @param nodes Nodes to search through. + * @param recurse Also consider child nodes. + * @param limit Maximum number of nodes to return. + * @returns All nodes with the supplied `tagName`. + */ +function getElementsByTagName(tagName, nodes, recurse, limit) { + if (recurse === void 0) { recurse = true; } + if (limit === void 0) { limit = Infinity; } + return querying_1.filter(Checks.tag_name(tagName), nodes, recurse, limit); +} +exports.getElementsByTagName = getElementsByTagName; +/** + * @param type Element type to look for. + * @param nodes Nodes to search through. + * @param recurse Also consider child nodes. + * @param limit Maximum number of nodes to return. + * @returns All nodes with the supplied `type`. + */ +function getElementsByTagType(type, nodes, recurse, limit) { + if (recurse === void 0) { recurse = true; } + if (limit === void 0) { limit = Infinity; } + return querying_1.filter(Checks.tag_type(type), nodes, recurse, limit); +} +exports.getElementsByTagType = getElementsByTagType; + + +/***/ }), +/* 315 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.uniqueSort = exports.compareDocumentPosition = exports.removeSubsets = void 0; +var domhandler_1 = __webpack_require__(306); +/** + * Given an array of nodes, remove any member that is contained by another. + * + * @param nodes Nodes to filter. + * @returns Remaining nodes that aren't subtrees of each other. + */ +function removeSubsets(nodes) { + var idx = nodes.length; + /* + * Check if each node (or one of its ancestors) is already contained in the + * array. + */ + while (--idx >= 0) { + var node = nodes[idx]; + /* + * Remove the node if it is not unique. + * We are going through the array from the end, so we only + * have to check nodes that preceed the node under consideration in the array. + */ + if (idx > 0 && nodes.lastIndexOf(node, idx - 1) >= 0) { + nodes.splice(idx, 1); + continue; + } + for (var ancestor = node.parent; ancestor; ancestor = ancestor.parent) { + if (nodes.includes(ancestor)) { + nodes.splice(idx, 1); + break; + } + } + } + return nodes; +} +exports.removeSubsets = removeSubsets; +/** + * Compare the position of one node against another node in any other document. + * The return value is a bitmask with the following values: + * + * Document order: + * > There is an ordering, document order, defined on all the nodes in the + * > document corresponding to the order in which the first character of the + * > XML representation of each node occurs in the XML representation of the + * > document after expansion of general entities. Thus, the document element + * > node will be the first node. Element nodes occur before their children. + * > Thus, document order orders element nodes in order of the occurrence of + * > their start-tag in the XML (after expansion of entities). The attribute + * > nodes of an element occur after the element and before its children. The + * > relative order of attribute nodes is implementation-dependent./ + * + * Source: + * http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order + * + * @param nodeA The first node to use in the comparison + * @param nodeB The second node to use in the comparison + * @returns A bitmask describing the input nodes' relative position. + * + * See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for + * a description of these values. + */ +function compareDocumentPosition(nodeA, nodeB) { + var aParents = []; + var bParents = []; + if (nodeA === nodeB) { + return 0; + } + var current = domhandler_1.hasChildren(nodeA) ? nodeA : nodeA.parent; + while (current) { + aParents.unshift(current); + current = current.parent; + } + current = domhandler_1.hasChildren(nodeB) ? nodeB : nodeB.parent; + while (current) { + bParents.unshift(current); + current = current.parent; + } + var maxIdx = Math.min(aParents.length, bParents.length); + var idx = 0; + while (idx < maxIdx && aParents[idx] === bParents[idx]) { + idx++; + } + if (idx === 0) { + return 1 /* DISCONNECTED */; + } + var sharedParent = aParents[idx - 1]; + var siblings = sharedParent.children; + var aSibling = aParents[idx]; + var bSibling = bParents[idx]; + if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) { + if (sharedParent === nodeB) { + return 4 /* FOLLOWING */ | 16 /* CONTAINED_BY */; + } + return 4 /* FOLLOWING */; + } + if (sharedParent === nodeA) { + return 2 /* PRECEDING */ | 8 /* CONTAINS */; + } + return 2 /* PRECEDING */; +} +exports.compareDocumentPosition = compareDocumentPosition; +/** + * Sort an array of nodes based on their relative position in the document and + * remove any duplicate nodes. If the array contains nodes that do not belong + * to the same document, sort order is unspecified. + * + * @param nodes Array of DOM nodes. + * @returns Collection of unique nodes, sorted in document order. + */ +function uniqueSort(nodes) { + nodes = nodes.filter(function (node, i, arr) { return !arr.includes(node, i + 1); }); + nodes.sort(function (a, b) { + var relative = compareDocumentPosition(a, b); + if (relative & 2 /* PRECEDING */) { + return -1; + } + else if (relative & 4 /* FOLLOWING */) { + return 1; + } + return 0; + }); + return nodes; +} +exports.uniqueSort = uniqueSort; + + +/***/ }), +/* 316 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.render = exports.parse = void 0; -var tslib_1 = __webpack_require__(256); -var domhandler_1 = __webpack_require__(268); -var parse5_1 = __webpack_require__(307); -var parse5_htmlparser2_tree_adapter_1 = tslib_1.__importDefault(__webpack_require__(331)); +var tslib_1 = __webpack_require__(257); +var domhandler_1 = __webpack_require__(317); +var parse5_1 = __webpack_require__(319); +var parse5_htmlparser2_tree_adapter_1 = tslib_1.__importDefault(__webpack_require__(343)); function parse(content, options, isDocument) { var opts = { scriptingEnabled: typeof options.scriptingEnabled === 'boolean' @@ -47181,93 +48610,666 @@ exports.render = render; /***/ }), -/* 307 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/* 317 */ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; - -const Parser = __webpack_require__(308); -const Serializer = __webpack_require__(330); - -// Shorthands -exports.parse = function parse(html, options) { - const parser = new Parser(options); - - return parser.parse(html); -}; - -exports.parseFragment = function parseFragment(fragmentContext, html, options) { - if (typeof fragmentContext === 'string') { - options = html; - html = fragmentContext; - fragmentContext = null; - } - - const parser = new Parser(options); - - return parser.parseFragment(html, fragmentContext); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; - -exports.serialize = function(node, options) { - const serializer = new Serializer(node, options); - - return serializer.serialize(); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.DomHandler = void 0; +var domelementtype_1 = __webpack_require__(270); +var node_1 = __webpack_require__(318); +__exportStar(__webpack_require__(318), exports); +var reWhitespace = /\s+/g; +// Default options +var defaultOpts = { + normalizeWhitespace: false, + withStartIndices: false, + withEndIndices: false, }; +var DomHandler = /** @class */ (function () { + /** + * @param callback Called once parsing has completed. + * @param options Settings for the handler. + * @param elementCB Callback whenever a tag is closed. + */ + function DomHandler(callback, options, elementCB) { + /** The elements of the DOM */ + this.dom = []; + /** The root element for the DOM */ + this.root = new node_1.Document(this.dom); + /** Indicated whether parsing has been completed. */ + this.done = false; + /** Stack of open tags. */ + this.tagStack = [this.root]; + /** A data node that is still being written to. */ + this.lastNode = null; + /** Reference to the parser instance. Used for location information. */ + this.parser = null; + // Make it possible to skip arguments, for backwards-compatibility + if (typeof options === "function") { + elementCB = options; + options = defaultOpts; + } + if (typeof callback === "object") { + options = callback; + callback = undefined; + } + this.callback = callback !== null && callback !== void 0 ? callback : null; + this.options = options !== null && options !== void 0 ? options : defaultOpts; + this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null; + } + DomHandler.prototype.onparserinit = function (parser) { + this.parser = parser; + }; + // Resets the handler back to starting state + DomHandler.prototype.onreset = function () { + var _a; + this.dom = []; + this.root = new node_1.Document(this.dom); + this.done = false; + this.tagStack = [this.root]; + this.lastNode = null; + this.parser = (_a = this.parser) !== null && _a !== void 0 ? _a : null; + }; + // Signals the handler that parsing is done + DomHandler.prototype.onend = function () { + if (this.done) + return; + this.done = true; + this.parser = null; + this.handleCallback(null); + }; + DomHandler.prototype.onerror = function (error) { + this.handleCallback(error); + }; + DomHandler.prototype.onclosetag = function () { + this.lastNode = null; + var elem = this.tagStack.pop(); + if (this.options.withEndIndices) { + elem.endIndex = this.parser.endIndex; + } + if (this.elementCB) + this.elementCB(elem); + }; + DomHandler.prototype.onopentag = function (name, attribs) { + var type = this.options.xmlMode ? domelementtype_1.ElementType.Tag : undefined; + var element = new node_1.Element(name, attribs, undefined, type); + this.addNode(element); + this.tagStack.push(element); + }; + DomHandler.prototype.ontext = function (data) { + var normalizeWhitespace = this.options.normalizeWhitespace; + var lastNode = this.lastNode; + if (lastNode && lastNode.type === domelementtype_1.ElementType.Text) { + if (normalizeWhitespace) { + lastNode.data = (lastNode.data + data).replace(reWhitespace, " "); + } + else { + lastNode.data += data; + } + } + else { + if (normalizeWhitespace) { + data = data.replace(reWhitespace, " "); + } + var node = new node_1.Text(data); + this.addNode(node); + this.lastNode = node; + } + }; + DomHandler.prototype.oncomment = function (data) { + if (this.lastNode && this.lastNode.type === domelementtype_1.ElementType.Comment) { + this.lastNode.data += data; + return; + } + var node = new node_1.Comment(data); + this.addNode(node); + this.lastNode = node; + }; + DomHandler.prototype.oncommentend = function () { + this.lastNode = null; + }; + DomHandler.prototype.oncdatastart = function () { + var text = new node_1.Text(""); + var node = new node_1.NodeWithChildren(domelementtype_1.ElementType.CDATA, [text]); + this.addNode(node); + text.parent = node; + this.lastNode = text; + }; + DomHandler.prototype.oncdataend = function () { + this.lastNode = null; + }; + DomHandler.prototype.onprocessinginstruction = function (name, data) { + var node = new node_1.ProcessingInstruction(name, data); + this.addNode(node); + }; + DomHandler.prototype.handleCallback = function (error) { + if (typeof this.callback === "function") { + this.callback(error, this.dom); + } + else if (error) { + throw error; + } + }; + DomHandler.prototype.addNode = function (node) { + var parent = this.tagStack[this.tagStack.length - 1]; + var previousSibling = parent.children[parent.children.length - 1]; + if (this.options.withStartIndices) { + node.startIndex = this.parser.startIndex; + } + if (this.options.withEndIndices) { + node.endIndex = this.parser.endIndex; + } + parent.children.push(node); + if (previousSibling) { + node.prev = previousSibling; + previousSibling.next = node; + } + node.parent = parent; + this.lastNode = null; + }; + return DomHandler; +}()); +exports.DomHandler = DomHandler; +exports["default"] = DomHandler; /***/ }), -/* 308 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 318 */ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; - -const Tokenizer = __webpack_require__(309); -const OpenElementStack = __webpack_require__(314); -const FormattingElementList = __webpack_require__(316); -const LocationInfoParserMixin = __webpack_require__(317); -const ErrorReportingParserMixin = __webpack_require__(322); -const Mixin = __webpack_require__(318); -const defaultTreeAdapter = __webpack_require__(326); -const mergeOptions = __webpack_require__(327); -const doctype = __webpack_require__(328); -const foreignContent = __webpack_require__(329); -const ERR = __webpack_require__(312); -const unicode = __webpack_require__(311); -const HTML = __webpack_require__(315); - -//Aliases -const $ = HTML.TAG_NAMES; -const NS = HTML.NAMESPACES; -const ATTRS = HTML.ATTRS; - -const DEFAULT_OPTIONS = { - scriptingEnabled: true, - sourceCodeLocationInfo: false, - onParseError: null, - treeAdapter: defaultTreeAdapter +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); }; - -//Misc constants -const HIDDEN_INPUT_TYPE = 'hidden'; - -//Adoption agency loops iteration count -const AA_OUTER_LOOP_ITER = 8; -const AA_INNER_LOOP_ITER = 3; - -//Insertion modes -const INITIAL_MODE = 'INITIAL_MODE'; -const BEFORE_HTML_MODE = 'BEFORE_HTML_MODE'; -const BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE'; -const IN_HEAD_MODE = 'IN_HEAD_MODE'; -const IN_HEAD_NO_SCRIPT_MODE = 'IN_HEAD_NO_SCRIPT_MODE'; -const AFTER_HEAD_MODE = 'AFTER_HEAD_MODE'; -const IN_BODY_MODE = 'IN_BODY_MODE'; -const TEXT_MODE = 'TEXT_MODE'; -const IN_TABLE_MODE = 'IN_TABLE_MODE'; -const IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE'; -const IN_CAPTION_MODE = 'IN_CAPTION_MODE'; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.cloneNode = exports.hasChildren = exports.isDocument = exports.isDirective = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = exports.Element = exports.Document = exports.NodeWithChildren = exports.ProcessingInstruction = exports.Comment = exports.Text = exports.DataNode = exports.Node = void 0; +var domelementtype_1 = __webpack_require__(270); +var nodeTypes = new Map([ + [domelementtype_1.ElementType.Tag, 1], + [domelementtype_1.ElementType.Script, 1], + [domelementtype_1.ElementType.Style, 1], + [domelementtype_1.ElementType.Directive, 1], + [domelementtype_1.ElementType.Text, 3], + [domelementtype_1.ElementType.CDATA, 4], + [domelementtype_1.ElementType.Comment, 8], + [domelementtype_1.ElementType.Root, 9], +]); +/** + * This object will be used as the prototype for Nodes when creating a + * DOM-Level-1-compliant structure. + */ +var Node = /** @class */ (function () { + /** + * + * @param type The type of the node. + */ + function Node(type) { + this.type = type; + /** Parent of the node */ + this.parent = null; + /** Previous sibling */ + this.prev = null; + /** Next sibling */ + this.next = null; + /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */ + this.startIndex = null; + /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */ + this.endIndex = null; + } + Object.defineProperty(Node.prototype, "nodeType", { + // Read-only aliases + get: function () { + var _a; + return (_a = nodeTypes.get(this.type)) !== null && _a !== void 0 ? _a : 1; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "parentNode", { + // Read-write aliases for properties + get: function () { + return this.parent; + }, + set: function (parent) { + this.parent = parent; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "previousSibling", { + get: function () { + return this.prev; + }, + set: function (prev) { + this.prev = prev; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "nextSibling", { + get: function () { + return this.next; + }, + set: function (next) { + this.next = next; + }, + enumerable: false, + configurable: true + }); + /** + * Clone this node, and optionally its children. + * + * @param recursive Clone child nodes as well. + * @returns A clone of the node. + */ + Node.prototype.cloneNode = function (recursive) { + if (recursive === void 0) { recursive = false; } + return cloneNode(this, recursive); + }; + return Node; +}()); +exports.Node = Node; +var DataNode = /** @class */ (function (_super) { + __extends(DataNode, _super); + /** + * @param type The type of the node + * @param data The content of the data node + */ + function DataNode(type, data) { + var _this = _super.call(this, type) || this; + _this.data = data; + return _this; + } + Object.defineProperty(DataNode.prototype, "nodeValue", { + get: function () { + return this.data; + }, + set: function (data) { + this.data = data; + }, + enumerable: false, + configurable: true + }); + return DataNode; +}(Node)); +exports.DataNode = DataNode; +var Text = /** @class */ (function (_super) { + __extends(Text, _super); + function Text(data) { + return _super.call(this, domelementtype_1.ElementType.Text, data) || this; + } + return Text; +}(DataNode)); +exports.Text = Text; +var Comment = /** @class */ (function (_super) { + __extends(Comment, _super); + function Comment(data) { + return _super.call(this, domelementtype_1.ElementType.Comment, data) || this; + } + return Comment; +}(DataNode)); +exports.Comment = Comment; +var ProcessingInstruction = /** @class */ (function (_super) { + __extends(ProcessingInstruction, _super); + function ProcessingInstruction(name, data) { + var _this = _super.call(this, domelementtype_1.ElementType.Directive, data) || this; + _this.name = name; + return _this; + } + return ProcessingInstruction; +}(DataNode)); +exports.ProcessingInstruction = ProcessingInstruction; +/** + * A `Node` that can have children. + */ +var NodeWithChildren = /** @class */ (function (_super) { + __extends(NodeWithChildren, _super); + /** + * @param type Type of the node. + * @param children Children of the node. Only certain node types can have children. + */ + function NodeWithChildren(type, children) { + var _this = _super.call(this, type) || this; + _this.children = children; + return _this; + } + Object.defineProperty(NodeWithChildren.prototype, "firstChild", { + // Aliases + get: function () { + var _a; + return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(NodeWithChildren.prototype, "lastChild", { + get: function () { + return this.children.length > 0 + ? this.children[this.children.length - 1] + : null; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(NodeWithChildren.prototype, "childNodes", { + get: function () { + return this.children; + }, + set: function (children) { + this.children = children; + }, + enumerable: false, + configurable: true + }); + return NodeWithChildren; +}(Node)); +exports.NodeWithChildren = NodeWithChildren; +var Document = /** @class */ (function (_super) { + __extends(Document, _super); + function Document(children) { + return _super.call(this, domelementtype_1.ElementType.Root, children) || this; + } + return Document; +}(NodeWithChildren)); +exports.Document = Document; +var Element = /** @class */ (function (_super) { + __extends(Element, _super); + /** + * @param name Name of the tag, eg. `div`, `span`. + * @param attribs Object mapping attribute names to attribute values. + * @param children Children of the node. + */ + function Element(name, attribs, children, type) { + if (children === void 0) { children = []; } + if (type === void 0) { type = name === "script" + ? domelementtype_1.ElementType.Script + : name === "style" + ? domelementtype_1.ElementType.Style + : domelementtype_1.ElementType.Tag; } + var _this = _super.call(this, type, children) || this; + _this.name = name; + _this.attribs = attribs; + return _this; + } + Object.defineProperty(Element.prototype, "tagName", { + // DOM Level 1 aliases + get: function () { + return this.name; + }, + set: function (name) { + this.name = name; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Element.prototype, "attributes", { + get: function () { + var _this = this; + return Object.keys(this.attribs).map(function (name) { + var _a, _b; + return ({ + name: name, + value: _this.attribs[name], + namespace: (_a = _this["x-attribsNamespace"]) === null || _a === void 0 ? void 0 : _a[name], + prefix: (_b = _this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name], + }); + }); + }, + enumerable: false, + configurable: true + }); + return Element; +}(NodeWithChildren)); +exports.Element = Element; +/** + * @param node Node to check. + * @returns `true` if the node is a `Element`, `false` otherwise. + */ +function isTag(node) { + return domelementtype_1.isTag(node); +} +exports.isTag = isTag; +/** + * @param node Node to check. + * @returns `true` if the node has the type `CDATA`, `false` otherwise. + */ +function isCDATA(node) { + return node.type === domelementtype_1.ElementType.CDATA; +} +exports.isCDATA = isCDATA; +/** + * @param node Node to check. + * @returns `true` if the node has the type `Text`, `false` otherwise. + */ +function isText(node) { + return node.type === domelementtype_1.ElementType.Text; +} +exports.isText = isText; +/** + * @param node Node to check. + * @returns `true` if the node has the type `Comment`, `false` otherwise. + */ +function isComment(node) { + return node.type === domelementtype_1.ElementType.Comment; +} +exports.isComment = isComment; +/** + * @param node Node to check. + * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise. + */ +function isDirective(node) { + return node.type === domelementtype_1.ElementType.Directive; +} +exports.isDirective = isDirective; +/** + * @param node Node to check. + * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise. + */ +function isDocument(node) { + return node.type === domelementtype_1.ElementType.Root; +} +exports.isDocument = isDocument; +/** + * @param node Node to check. + * @returns `true` if the node is a `NodeWithChildren` (has children), `false` otherwise. + */ +function hasChildren(node) { + return Object.prototype.hasOwnProperty.call(node, "children"); +} +exports.hasChildren = hasChildren; +/** + * Clone a node, and optionally its children. + * + * @param recursive Clone child nodes as well. + * @returns A clone of the node. + */ +function cloneNode(node, recursive) { + if (recursive === void 0) { recursive = false; } + var result; + if (isText(node)) { + result = new Text(node.data); + } + else if (isComment(node)) { + result = new Comment(node.data); + } + else if (isTag(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_1 = new Element(node.name, __assign({}, node.attribs), children); + children.forEach(function (child) { return (child.parent = clone_1); }); + if (node["x-attribsNamespace"]) { + clone_1["x-attribsNamespace"] = __assign({}, node["x-attribsNamespace"]); + } + if (node["x-attribsPrefix"]) { + clone_1["x-attribsPrefix"] = __assign({}, node["x-attribsPrefix"]); + } + result = clone_1; + } + else if (isCDATA(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_2 = new NodeWithChildren(domelementtype_1.ElementType.CDATA, children); + children.forEach(function (child) { return (child.parent = clone_2); }); + result = clone_2; + } + else if (isDocument(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_3 = new Document(children); + children.forEach(function (child) { return (child.parent = clone_3); }); + if (node["x-mode"]) { + clone_3["x-mode"] = node["x-mode"]; + } + result = clone_3; + } + else if (isDirective(node)) { + var instruction = new ProcessingInstruction(node.name, node.data); + if (node["x-name"] != null) { + instruction["x-name"] = node["x-name"]; + instruction["x-publicId"] = node["x-publicId"]; + instruction["x-systemId"] = node["x-systemId"]; + } + result = instruction; + } + else { + throw new Error("Not implemented yet: " + node.type); + } + result.startIndex = node.startIndex; + result.endIndex = node.endIndex; + return result; +} +exports.cloneNode = cloneNode; +function cloneChildren(childs) { + var children = childs.map(function (child) { return cloneNode(child, true); }); + for (var i = 1; i < children.length; i++) { + children[i].prev = children[i - 1]; + children[i - 1].next = children[i]; + } + return children; +} + + +/***/ }), +/* 319 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +const Parser = __webpack_require__(320); +const Serializer = __webpack_require__(342); + +// Shorthands +exports.parse = function parse(html, options) { + const parser = new Parser(options); + + return parser.parse(html); +}; + +exports.parseFragment = function parseFragment(fragmentContext, html, options) { + if (typeof fragmentContext === 'string') { + options = html; + html = fragmentContext; + fragmentContext = null; + } + + const parser = new Parser(options); + + return parser.parseFragment(html, fragmentContext); +}; + +exports.serialize = function(node, options) { + const serializer = new Serializer(node, options); + + return serializer.serialize(); +}; + + +/***/ }), +/* 320 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +const Tokenizer = __webpack_require__(321); +const OpenElementStack = __webpack_require__(326); +const FormattingElementList = __webpack_require__(328); +const LocationInfoParserMixin = __webpack_require__(329); +const ErrorReportingParserMixin = __webpack_require__(334); +const Mixin = __webpack_require__(330); +const defaultTreeAdapter = __webpack_require__(338); +const mergeOptions = __webpack_require__(339); +const doctype = __webpack_require__(340); +const foreignContent = __webpack_require__(341); +const ERR = __webpack_require__(324); +const unicode = __webpack_require__(323); +const HTML = __webpack_require__(327); + +//Aliases +const $ = HTML.TAG_NAMES; +const NS = HTML.NAMESPACES; +const ATTRS = HTML.ATTRS; + +const DEFAULT_OPTIONS = { + scriptingEnabled: true, + sourceCodeLocationInfo: false, + onParseError: null, + treeAdapter: defaultTreeAdapter +}; + +//Misc constants +const HIDDEN_INPUT_TYPE = 'hidden'; + +//Adoption agency loops iteration count +const AA_OUTER_LOOP_ITER = 8; +const AA_INNER_LOOP_ITER = 3; + +//Insertion modes +const INITIAL_MODE = 'INITIAL_MODE'; +const BEFORE_HTML_MODE = 'BEFORE_HTML_MODE'; +const BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE'; +const IN_HEAD_MODE = 'IN_HEAD_MODE'; +const IN_HEAD_NO_SCRIPT_MODE = 'IN_HEAD_NO_SCRIPT_MODE'; +const AFTER_HEAD_MODE = 'AFTER_HEAD_MODE'; +const IN_BODY_MODE = 'IN_BODY_MODE'; +const TEXT_MODE = 'TEXT_MODE'; +const IN_TABLE_MODE = 'IN_TABLE_MODE'; +const IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE'; +const IN_CAPTION_MODE = 'IN_CAPTION_MODE'; const IN_COLUMN_GROUP_MODE = 'IN_COLUMN_GROUP_MODE'; const IN_TABLE_BODY_MODE = 'IN_TABLE_BODY_MODE'; const IN_ROW_MODE = 'IN_ROW_MODE'; @@ -50180,16 +52182,16 @@ function endTagInForeignContent(p, token) { /***/ }), -/* 309 */ +/* 321 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const Preprocessor = __webpack_require__(310); -const unicode = __webpack_require__(311); -const neTree = __webpack_require__(313); -const ERR = __webpack_require__(312); +const Preprocessor = __webpack_require__(322); +const unicode = __webpack_require__(323); +const neTree = __webpack_require__(325); +const ERR = __webpack_require__(324); //Aliases const $ = unicode.CODE_POINTS; @@ -52383,14 +54385,14 @@ module.exports = Tokenizer; /***/ }), -/* 310 */ +/* 322 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const unicode = __webpack_require__(311); -const ERR = __webpack_require__(312); +const unicode = __webpack_require__(323); +const ERR = __webpack_require__(324); //Aliases const $ = unicode.CODE_POINTS; @@ -52549,7 +54551,7 @@ module.exports = Preprocessor; /***/ }), -/* 311 */ +/* 323 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -52665,7 +54667,7 @@ exports.isUndefinedCodePoint = function(cp) { /***/ }), -/* 312 */ +/* 324 */ /***/ ((module) => { "use strict"; @@ -52737,7 +54739,7 @@ module.exports = { /***/ }), -/* 313 */ +/* 325 */ /***/ ((module) => { "use strict"; @@ -52748,13 +54750,13 @@ module.exports = { module.exports = new Uint16Array([4,52,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,106,303,412,810,1432,1701,1796,1987,2114,2360,2420,2484,3170,3251,4140,4393,4575,4610,5106,5512,5728,6117,6274,6315,6345,6427,6516,7002,7910,8733,9323,9870,10170,10631,10893,11318,11386,11467,12773,13092,14474,14922,15448,15542,16419,17666,18166,18611,19004,19095,19298,19397,4,16,69,77,97,98,99,102,103,108,109,110,111,112,114,115,116,117,140,150,158,169,176,194,199,210,216,222,226,242,256,266,283,294,108,105,103,5,198,1,59,148,1,198,80,5,38,1,59,156,1,38,99,117,116,101,5,193,1,59,167,1,193,114,101,118,101,59,1,258,4,2,105,121,182,191,114,99,5,194,1,59,189,1,194,59,1,1040,114,59,3,55349,56580,114,97,118,101,5,192,1,59,208,1,192,112,104,97,59,1,913,97,99,114,59,1,256,100,59,1,10835,4,2,103,112,232,237,111,110,59,1,260,102,59,3,55349,56632,112,108,121,70,117,110,99,116,105,111,110,59,1,8289,105,110,103,5,197,1,59,264,1,197,4,2,99,115,272,277,114,59,3,55349,56476,105,103,110,59,1,8788,105,108,100,101,5,195,1,59,292,1,195,109,108,5,196,1,59,301,1,196,4,8,97,99,101,102,111,114,115,117,321,350,354,383,388,394,400,405,4,2,99,114,327,336,107,115,108,97,115,104,59,1,8726,4,2,118,119,342,345,59,1,10983,101,100,59,1,8966,121,59,1,1041,4,3,99,114,116,362,369,379,97,117,115,101,59,1,8757,110,111,117,108,108,105,115,59,1,8492,97,59,1,914,114,59,3,55349,56581,112,102,59,3,55349,56633,101,118,101,59,1,728,99,114,59,1,8492,109,112,101,113,59,1,8782,4,14,72,79,97,99,100,101,102,104,105,108,111,114,115,117,442,447,456,504,542,547,569,573,577,616,678,784,790,796,99,121,59,1,1063,80,89,5,169,1,59,454,1,169,4,3,99,112,121,464,470,497,117,116,101,59,1,262,4,2,59,105,476,478,1,8914,116,97,108,68,105,102,102,101,114,101,110,116,105,97,108,68,59,1,8517,108,101,121,115,59,1,8493,4,4,97,101,105,111,514,520,530,535,114,111,110,59,1,268,100,105,108,5,199,1,59,528,1,199,114,99,59,1,264,110,105,110,116,59,1,8752,111,116,59,1,266,4,2,100,110,553,560,105,108,108,97,59,1,184,116,101,114,68,111,116,59,1,183,114,59,1,8493,105,59,1,935,114,99,108,101,4,4,68,77,80,84,591,596,603,609,111,116,59,1,8857,105,110,117,115,59,1,8854,108,117,115,59,1,8853,105,109,101,115,59,1,8855,111,4,2,99,115,623,646,107,119,105,115,101,67,111,110,116,111,117,114,73,110,116,101,103,114,97,108,59,1,8754,101,67,117,114,108,121,4,2,68,81,658,671,111,117,98,108,101,81,117,111,116,101,59,1,8221,117,111,116,101,59,1,8217,4,4,108,110,112,117,688,701,736,753,111,110,4,2,59,101,696,698,1,8759,59,1,10868,4,3,103,105,116,709,717,722,114,117,101,110,116,59,1,8801,110,116,59,1,8751,111,117,114,73,110,116,101,103,114,97,108,59,1,8750,4,2,102,114,742,745,59,1,8450,111,100,117,99,116,59,1,8720,110,116,101,114,67,108,111,99,107,119,105,115,101,67,111,110,116,111,117,114,73,110,116,101,103,114,97,108,59,1,8755,111,115,115,59,1,10799,99,114,59,3,55349,56478,112,4,2,59,67,803,805,1,8915,97,112,59,1,8781,4,11,68,74,83,90,97,99,101,102,105,111,115,834,850,855,860,865,888,903,916,921,1011,1415,4,2,59,111,840,842,1,8517,116,114,97,104,100,59,1,10513,99,121,59,1,1026,99,121,59,1,1029,99,121,59,1,1039,4,3,103,114,115,873,879,883,103,101,114,59,1,8225,114,59,1,8609,104,118,59,1,10980,4,2,97,121,894,900,114,111,110,59,1,270,59,1,1044,108,4,2,59,116,910,912,1,8711,97,59,1,916,114,59,3,55349,56583,4,2,97,102,927,998,4,2,99,109,933,992,114,105,116,105,99,97,108,4,4,65,68,71,84,950,957,978,985,99,117,116,101,59,1,180,111,4,2,116,117,964,967,59,1,729,98,108,101,65,99,117,116,101,59,1,733,114,97,118,101,59,1,96,105,108,100,101,59,1,732,111,110,100,59,1,8900,102,101,114,101,110,116,105,97,108,68,59,1,8518,4,4,112,116,117,119,1021,1026,1048,1249,102,59,3,55349,56635,4,3,59,68,69,1034,1036,1041,1,168,111,116,59,1,8412,113,117,97,108,59,1,8784,98,108,101,4,6,67,68,76,82,85,86,1065,1082,1101,1189,1211,1236,111,110,116,111,117,114,73,110,116,101,103,114,97,108,59,1,8751,111,4,2,116,119,1089,1092,59,1,168,110,65,114,114,111,119,59,1,8659,4,2,101,111,1107,1141,102,116,4,3,65,82,84,1117,1124,1136,114,114,111,119,59,1,8656,105,103,104,116,65,114,114,111,119,59,1,8660,101,101,59,1,10980,110,103,4,2,76,82,1149,1177,101,102,116,4,2,65,82,1158,1165,114,114,111,119,59,1,10232,105,103,104,116,65,114,114,111,119,59,1,10234,105,103,104,116,65,114,114,111,119,59,1,10233,105,103,104,116,4,2,65,84,1199,1206,114,114,111,119,59,1,8658,101,101,59,1,8872,112,4,2,65,68,1218,1225,114,114,111,119,59,1,8657,111,119,110,65,114,114,111,119,59,1,8661,101,114,116,105,99,97,108,66,97,114,59,1,8741,110,4,6,65,66,76,82,84,97,1264,1292,1299,1352,1391,1408,114,114,111,119,4,3,59,66,85,1276,1278,1283,1,8595,97,114,59,1,10515,112,65,114,114,111,119,59,1,8693,114,101,118,101,59,1,785,101,102,116,4,3,82,84,86,1310,1323,1334,105,103,104,116,86,101,99,116,111,114,59,1,10576,101,101,86,101,99,116,111,114,59,1,10590,101,99,116,111,114,4,2,59,66,1345,1347,1,8637,97,114,59,1,10582,105,103,104,116,4,2,84,86,1362,1373,101,101,86,101,99,116,111,114,59,1,10591,101,99,116,111,114,4,2,59,66,1384,1386,1,8641,97,114,59,1,10583,101,101,4,2,59,65,1399,1401,1,8868,114,114,111,119,59,1,8615,114,114,111,119,59,1,8659,4,2,99,116,1421,1426,114,59,3,55349,56479,114,111,107,59,1,272,4,16,78,84,97,99,100,102,103,108,109,111,112,113,115,116,117,120,1466,1470,1478,1489,1515,1520,1525,1536,1544,1593,1609,1617,1650,1664,1668,1677,71,59,1,330,72,5,208,1,59,1476,1,208,99,117,116,101,5,201,1,59,1487,1,201,4,3,97,105,121,1497,1503,1512,114,111,110,59,1,282,114,99,5,202,1,59,1510,1,202,59,1,1069,111,116,59,1,278,114,59,3,55349,56584,114,97,118,101,5,200,1,59,1534,1,200,101,109,101,110,116,59,1,8712,4,2,97,112,1550,1555,99,114,59,1,274,116,121,4,2,83,86,1563,1576,109,97,108,108,83,113,117,97,114,101,59,1,9723,101,114,121,83,109,97,108,108,83,113,117,97,114,101,59,1,9643,4,2,103,112,1599,1604,111,110,59,1,280,102,59,3,55349,56636,115,105,108,111,110,59,1,917,117,4,2,97,105,1624,1640,108,4,2,59,84,1631,1633,1,10869,105,108,100,101,59,1,8770,108,105,98,114,105,117,109,59,1,8652,4,2,99,105,1656,1660,114,59,1,8496,109,59,1,10867,97,59,1,919,109,108,5,203,1,59,1675,1,203,4,2,105,112,1683,1689,115,116,115,59,1,8707,111,110,101,110,116,105,97,108,69,59,1,8519,4,5,99,102,105,111,115,1713,1717,1722,1762,1791,121,59,1,1060,114,59,3,55349,56585,108,108,101,100,4,2,83,86,1732,1745,109,97,108,108,83,113,117,97,114,101,59,1,9724,101,114,121,83,109,97,108,108,83,113,117,97,114,101,59,1,9642,4,3,112,114,117,1770,1775,1781,102,59,3,55349,56637,65,108,108,59,1,8704,114,105,101,114,116,114,102,59,1,8497,99,114,59,1,8497,4,12,74,84,97,98,99,100,102,103,111,114,115,116,1822,1827,1834,1848,1855,1877,1882,1887,1890,1896,1978,1984,99,121,59,1,1027,5,62,1,59,1832,1,62,109,109,97,4,2,59,100,1843,1845,1,915,59,1,988,114,101,118,101,59,1,286,4,3,101,105,121,1863,1869,1874,100,105,108,59,1,290,114,99,59,1,284,59,1,1043,111,116,59,1,288,114,59,3,55349,56586,59,1,8921,112,102,59,3,55349,56638,101,97,116,101,114,4,6,69,70,71,76,83,84,1915,1933,1944,1953,1959,1971,113,117,97,108,4,2,59,76,1925,1927,1,8805,101,115,115,59,1,8923,117,108,108,69,113,117,97,108,59,1,8807,114,101,97,116,101,114,59,1,10914,101,115,115,59,1,8823,108,97,110,116,69,113,117,97,108,59,1,10878,105,108,100,101,59,1,8819,99,114,59,3,55349,56482,59,1,8811,4,8,65,97,99,102,105,111,115,117,2005,2012,2026,2032,2036,2049,2073,2089,82,68,99,121,59,1,1066,4,2,99,116,2018,2023,101,107,59,1,711,59,1,94,105,114,99,59,1,292,114,59,1,8460,108,98,101,114,116,83,112,97,99,101,59,1,8459,4,2,112,114,2055,2059,102,59,1,8461,105,122,111,110,116,97,108,76,105,110,101,59,1,9472,4,2,99,116,2079,2083,114,59,1,8459,114,111,107,59,1,294,109,112,4,2,68,69,2097,2107,111,119,110,72,117,109,112,59,1,8782,113,117,97,108,59,1,8783,4,14,69,74,79,97,99,100,102,103,109,110,111,115,116,117,2144,2149,2155,2160,2171,2189,2194,2198,2209,2245,2307,2329,2334,2341,99,121,59,1,1045,108,105,103,59,1,306,99,121,59,1,1025,99,117,116,101,5,205,1,59,2169,1,205,4,2,105,121,2177,2186,114,99,5,206,1,59,2184,1,206,59,1,1048,111,116,59,1,304,114,59,1,8465,114,97,118,101,5,204,1,59,2207,1,204,4,3,59,97,112,2217,2219,2238,1,8465,4,2,99,103,2225,2229,114,59,1,298,105,110,97,114,121,73,59,1,8520,108,105,101,115,59,1,8658,4,2,116,118,2251,2281,4,2,59,101,2257,2259,1,8748,4,2,103,114,2265,2271,114,97,108,59,1,8747,115,101,99,116,105,111,110,59,1,8898,105,115,105,98,108,101,4,2,67,84,2293,2300,111,109,109,97,59,1,8291,105,109,101,115,59,1,8290,4,3,103,112,116,2315,2320,2325,111,110,59,1,302,102,59,3,55349,56640,97,59,1,921,99,114,59,1,8464,105,108,100,101,59,1,296,4,2,107,109,2347,2352,99,121,59,1,1030,108,5,207,1,59,2358,1,207,4,5,99,102,111,115,117,2372,2386,2391,2397,2414,4,2,105,121,2378,2383,114,99,59,1,308,59,1,1049,114,59,3,55349,56589,112,102,59,3,55349,56641,4,2,99,101,2403,2408,114,59,3,55349,56485,114,99,121,59,1,1032,107,99,121,59,1,1028,4,7,72,74,97,99,102,111,115,2436,2441,2446,2452,2467,2472,2478,99,121,59,1,1061,99,121,59,1,1036,112,112,97,59,1,922,4,2,101,121,2458,2464,100,105,108,59,1,310,59,1,1050,114,59,3,55349,56590,112,102,59,3,55349,56642,99,114,59,3,55349,56486,4,11,74,84,97,99,101,102,108,109,111,115,116,2508,2513,2520,2562,2585,2981,2986,3004,3011,3146,3167,99,121,59,1,1033,5,60,1,59,2518,1,60,4,5,99,109,110,112,114,2532,2538,2544,2548,2558,117,116,101,59,1,313,98,100,97,59,1,923,103,59,1,10218,108,97,99,101,116,114,102,59,1,8466,114,59,1,8606,4,3,97,101,121,2570,2576,2582,114,111,110,59,1,317,100,105,108,59,1,315,59,1,1051,4,2,102,115,2591,2907,116,4,10,65,67,68,70,82,84,85,86,97,114,2614,2663,2672,2728,2735,2760,2820,2870,2888,2895,4,2,110,114,2620,2633,103,108,101,66,114,97,99,107,101,116,59,1,10216,114,111,119,4,3,59,66,82,2644,2646,2651,1,8592,97,114,59,1,8676,105,103,104,116,65,114,114,111,119,59,1,8646,101,105,108,105,110,103,59,1,8968,111,4,2,117,119,2679,2692,98,108,101,66,114,97,99,107,101,116,59,1,10214,110,4,2,84,86,2699,2710,101,101,86,101,99,116,111,114,59,1,10593,101,99,116,111,114,4,2,59,66,2721,2723,1,8643,97,114,59,1,10585,108,111,111,114,59,1,8970,105,103,104,116,4,2,65,86,2745,2752,114,114,111,119,59,1,8596,101,99,116,111,114,59,1,10574,4,2,101,114,2766,2792,101,4,3,59,65,86,2775,2777,2784,1,8867,114,114,111,119,59,1,8612,101,99,116,111,114,59,1,10586,105,97,110,103,108,101,4,3,59,66,69,2806,2808,2813,1,8882,97,114,59,1,10703,113,117,97,108,59,1,8884,112,4,3,68,84,86,2829,2841,2852,111,119,110,86,101,99,116,111,114,59,1,10577,101,101,86,101,99,116,111,114,59,1,10592,101,99,116,111,114,4,2,59,66,2863,2865,1,8639,97,114,59,1,10584,101,99,116,111,114,4,2,59,66,2881,2883,1,8636,97,114,59,1,10578,114,114,111,119,59,1,8656,105,103,104,116,97,114,114,111,119,59,1,8660,115,4,6,69,70,71,76,83,84,2922,2936,2947,2956,2962,2974,113,117,97,108,71,114,101,97,116,101,114,59,1,8922,117,108,108,69,113,117,97,108,59,1,8806,114,101,97,116,101,114,59,1,8822,101,115,115,59,1,10913,108,97,110,116,69,113,117,97,108,59,1,10877,105,108,100,101,59,1,8818,114,59,3,55349,56591,4,2,59,101,2992,2994,1,8920,102,116,97,114,114,111,119,59,1,8666,105,100,111,116,59,1,319,4,3,110,112,119,3019,3110,3115,103,4,4,76,82,108,114,3030,3058,3070,3098,101,102,116,4,2,65,82,3039,3046,114,114,111,119,59,1,10229,105,103,104,116,65,114,114,111,119,59,1,10231,105,103,104,116,65,114,114,111,119,59,1,10230,101,102,116,4,2,97,114,3079,3086,114,114,111,119,59,1,10232,105,103,104,116,97,114,114,111,119,59,1,10234,105,103,104,116,97,114,114,111,119,59,1,10233,102,59,3,55349,56643,101,114,4,2,76,82,3123,3134,101,102,116,65,114,114,111,119,59,1,8601,105,103,104,116,65,114,114,111,119,59,1,8600,4,3,99,104,116,3154,3158,3161,114,59,1,8466,59,1,8624,114,111,107,59,1,321,59,1,8810,4,8,97,99,101,102,105,111,115,117,3188,3192,3196,3222,3227,3237,3243,3248,112,59,1,10501,121,59,1,1052,4,2,100,108,3202,3213,105,117,109,83,112,97,99,101,59,1,8287,108,105,110,116,114,102,59,1,8499,114,59,3,55349,56592,110,117,115,80,108,117,115,59,1,8723,112,102,59,3,55349,56644,99,114,59,1,8499,59,1,924,4,9,74,97,99,101,102,111,115,116,117,3271,3276,3283,3306,3422,3427,4120,4126,4137,99,121,59,1,1034,99,117,116,101,59,1,323,4,3,97,101,121,3291,3297,3303,114,111,110,59,1,327,100,105,108,59,1,325,59,1,1053,4,3,103,115,119,3314,3380,3415,97,116,105,118,101,4,3,77,84,86,3327,3340,3365,101,100,105,117,109,83,112,97,99,101,59,1,8203,104,105,4,2,99,110,3348,3357,107,83,112,97,99,101,59,1,8203,83,112,97,99,101,59,1,8203,101,114,121,84,104,105,110,83,112,97,99,101,59,1,8203,116,101,100,4,2,71,76,3389,3405,114,101,97,116,101,114,71,114,101,97,116,101,114,59,1,8811,101,115,115,76,101,115,115,59,1,8810,76,105,110,101,59,1,10,114,59,3,55349,56593,4,4,66,110,112,116,3437,3444,3460,3464,114,101,97,107,59,1,8288,66,114,101,97,107,105,110,103,83,112,97,99,101,59,1,160,102,59,1,8469,4,13,59,67,68,69,71,72,76,78,80,82,83,84,86,3492,3494,3517,3536,3578,3657,3685,3784,3823,3860,3915,4066,4107,1,10988,4,2,111,117,3500,3510,110,103,114,117,101,110,116,59,1,8802,112,67,97,112,59,1,8813,111,117,98,108,101,86,101,114,116,105,99,97,108,66,97,114,59,1,8742,4,3,108,113,120,3544,3552,3571,101,109,101,110,116,59,1,8713,117,97,108,4,2,59,84,3561,3563,1,8800,105,108,100,101,59,3,8770,824,105,115,116,115,59,1,8708,114,101,97,116,101,114,4,7,59,69,70,71,76,83,84,3600,3602,3609,3621,3631,3637,3650,1,8815,113,117,97,108,59,1,8817,117,108,108,69,113,117,97,108,59,3,8807,824,114,101,97,116,101,114,59,3,8811,824,101,115,115,59,1,8825,108,97,110,116,69,113,117,97,108,59,3,10878,824,105,108,100,101,59,1,8821,117,109,112,4,2,68,69,3666,3677,111,119,110,72,117,109,112,59,3,8782,824,113,117,97,108,59,3,8783,824,101,4,2,102,115,3692,3724,116,84,114,105,97,110,103,108,101,4,3,59,66,69,3709,3711,3717,1,8938,97,114,59,3,10703,824,113,117,97,108,59,1,8940,115,4,6,59,69,71,76,83,84,3739,3741,3748,3757,3764,3777,1,8814,113,117,97,108,59,1,8816,114,101,97,116,101,114,59,1,8824,101,115,115,59,3,8810,824,108,97,110,116,69,113,117,97,108,59,3,10877,824,105,108,100,101,59,1,8820,101,115,116,101,100,4,2,71,76,3795,3812,114,101,97,116,101,114,71,114,101,97,116,101,114,59,3,10914,824,101,115,115,76,101,115,115,59,3,10913,824,114,101,99,101,100,101,115,4,3,59,69,83,3838,3840,3848,1,8832,113,117,97,108,59,3,10927,824,108,97,110,116,69,113,117,97,108,59,1,8928,4,2,101,105,3866,3881,118,101,114,115,101,69,108,101,109,101,110,116,59,1,8716,103,104,116,84,114,105,97,110,103,108,101,4,3,59,66,69,3900,3902,3908,1,8939,97,114,59,3,10704,824,113,117,97,108,59,1,8941,4,2,113,117,3921,3973,117,97,114,101,83,117,4,2,98,112,3933,3952,115,101,116,4,2,59,69,3942,3945,3,8847,824,113,117,97,108,59,1,8930,101,114,115,101,116,4,2,59,69,3963,3966,3,8848,824,113,117,97,108,59,1,8931,4,3,98,99,112,3981,4000,4045,115,101,116,4,2,59,69,3990,3993,3,8834,8402,113,117,97,108,59,1,8840,99,101,101,100,115,4,4,59,69,83,84,4015,4017,4025,4037,1,8833,113,117,97,108,59,3,10928,824,108,97,110,116,69,113,117,97,108,59,1,8929,105,108,100,101,59,3,8831,824,101,114,115,101,116,4,2,59,69,4056,4059,3,8835,8402,113,117,97,108,59,1,8841,105,108,100,101,4,4,59,69,70,84,4080,4082,4089,4100,1,8769,113,117,97,108,59,1,8772,117,108,108,69,113,117,97,108,59,1,8775,105,108,100,101,59,1,8777,101,114,116,105,99,97,108,66,97,114,59,1,8740,99,114,59,3,55349,56489,105,108,100,101,5,209,1,59,4135,1,209,59,1,925,4,14,69,97,99,100,102,103,109,111,112,114,115,116,117,118,4170,4176,4187,4205,4212,4217,4228,4253,4259,4292,4295,4316,4337,4346,108,105,103,59,1,338,99,117,116,101,5,211,1,59,4185,1,211,4,2,105,121,4193,4202,114,99,5,212,1,59,4200,1,212,59,1,1054,98,108,97,99,59,1,336,114,59,3,55349,56594,114,97,118,101,5,210,1,59,4226,1,210,4,3,97,101,105,4236,4241,4246,99,114,59,1,332,103,97,59,1,937,99,114,111,110,59,1,927,112,102,59,3,55349,56646,101,110,67,117,114,108,121,4,2,68,81,4272,4285,111,117,98,108,101,81,117,111,116,101,59,1,8220,117,111,116,101,59,1,8216,59,1,10836,4,2,99,108,4301,4306,114,59,3,55349,56490,97,115,104,5,216,1,59,4314,1,216,105,4,2,108,109,4323,4332,100,101,5,213,1,59,4330,1,213,101,115,59,1,10807,109,108,5,214,1,59,4344,1,214,101,114,4,2,66,80,4354,4380,4,2,97,114,4360,4364,114,59,1,8254,97,99,4,2,101,107,4372,4375,59,1,9182,101,116,59,1,9140,97,114,101,110,116,104,101,115,105,115,59,1,9180,4,9,97,99,102,104,105,108,111,114,115,4413,4422,4426,4431,4435,4438,4448,4471,4561,114,116,105,97,108,68,59,1,8706,121,59,1,1055,114,59,3,55349,56595,105,59,1,934,59,1,928,117,115,77,105,110,117,115,59,1,177,4,2,105,112,4454,4467,110,99,97,114,101,112,108,97,110,101,59,1,8460,102,59,1,8473,4,4,59,101,105,111,4481,4483,4526,4531,1,10939,99,101,100,101,115,4,4,59,69,83,84,4498,4500,4507,4519,1,8826,113,117,97,108,59,1,10927,108,97,110,116,69,113,117,97,108,59,1,8828,105,108,100,101,59,1,8830,109,101,59,1,8243,4,2,100,112,4537,4543,117,99,116,59,1,8719,111,114,116,105,111,110,4,2,59,97,4555,4557,1,8759,108,59,1,8733,4,2,99,105,4567,4572,114,59,3,55349,56491,59,1,936,4,4,85,102,111,115,4585,4594,4599,4604,79,84,5,34,1,59,4592,1,34,114,59,3,55349,56596,112,102,59,1,8474,99,114,59,3,55349,56492,4,12,66,69,97,99,101,102,104,105,111,114,115,117,4636,4642,4650,4681,4704,4763,4767,4771,5047,5069,5081,5094,97,114,114,59,1,10512,71,5,174,1,59,4648,1,174,4,3,99,110,114,4658,4664,4668,117,116,101,59,1,340,103,59,1,10219,114,4,2,59,116,4675,4677,1,8608,108,59,1,10518,4,3,97,101,121,4689,4695,4701,114,111,110,59,1,344,100,105,108,59,1,342,59,1,1056,4,2,59,118,4710,4712,1,8476,101,114,115,101,4,2,69,85,4722,4748,4,2,108,113,4728,4736,101,109,101,110,116,59,1,8715,117,105,108,105,98,114,105,117,109,59,1,8651,112,69,113,117,105,108,105,98,114,105,117,109,59,1,10607,114,59,1,8476,111,59,1,929,103,104,116,4,8,65,67,68,70,84,85,86,97,4792,4840,4849,4905,4912,4972,5022,5040,4,2,110,114,4798,4811,103,108,101,66,114,97,99,107,101,116,59,1,10217,114,111,119,4,3,59,66,76,4822,4824,4829,1,8594,97,114,59,1,8677,101,102,116,65,114,114,111,119,59,1,8644,101,105,108,105,110,103,59,1,8969,111,4,2,117,119,4856,4869,98,108,101,66,114,97,99,107,101,116,59,1,10215,110,4,2,84,86,4876,4887,101,101,86,101,99,116,111,114,59,1,10589,101,99,116,111,114,4,2,59,66,4898,4900,1,8642,97,114,59,1,10581,108,111,111,114,59,1,8971,4,2,101,114,4918,4944,101,4,3,59,65,86,4927,4929,4936,1,8866,114,114,111,119,59,1,8614,101,99,116,111,114,59,1,10587,105,97,110,103,108,101,4,3,59,66,69,4958,4960,4965,1,8883,97,114,59,1,10704,113,117,97,108,59,1,8885,112,4,3,68,84,86,4981,4993,5004,111,119,110,86,101,99,116,111,114,59,1,10575,101,101,86,101,99,116,111,114,59,1,10588,101,99,116,111,114,4,2,59,66,5015,5017,1,8638,97,114,59,1,10580,101,99,116,111,114,4,2,59,66,5033,5035,1,8640,97,114,59,1,10579,114,114,111,119,59,1,8658,4,2,112,117,5053,5057,102,59,1,8477,110,100,73,109,112,108,105,101,115,59,1,10608,105,103,104,116,97,114,114,111,119,59,1,8667,4,2,99,104,5087,5091,114,59,1,8475,59,1,8625,108,101,68,101,108,97,121,101,100,59,1,10740,4,13,72,79,97,99,102,104,105,109,111,113,115,116,117,5134,5150,5157,5164,5198,5203,5259,5265,5277,5283,5374,5380,5385,4,2,67,99,5140,5146,72,99,121,59,1,1065,121,59,1,1064,70,84,99,121,59,1,1068,99,117,116,101,59,1,346,4,5,59,97,101,105,121,5176,5178,5184,5190,5195,1,10940,114,111,110,59,1,352,100,105,108,59,1,350,114,99,59,1,348,59,1,1057,114,59,3,55349,56598,111,114,116,4,4,68,76,82,85,5216,5227,5238,5250,111,119,110,65,114,114,111,119,59,1,8595,101,102,116,65,114,114,111,119,59,1,8592,105,103,104,116,65,114,114,111,119,59,1,8594,112,65,114,114,111,119,59,1,8593,103,109,97,59,1,931,97,108,108,67,105,114,99,108,101,59,1,8728,112,102,59,3,55349,56650,4,2,114,117,5289,5293,116,59,1,8730,97,114,101,4,4,59,73,83,85,5306,5308,5322,5367,1,9633,110,116,101,114,115,101,99,116,105,111,110,59,1,8851,117,4,2,98,112,5329,5347,115,101,116,4,2,59,69,5338,5340,1,8847,113,117,97,108,59,1,8849,101,114,115,101,116,4,2,59,69,5358,5360,1,8848,113,117,97,108,59,1,8850,110,105,111,110,59,1,8852,99,114,59,3,55349,56494,97,114,59,1,8902,4,4,98,99,109,112,5395,5420,5475,5478,4,2,59,115,5401,5403,1,8912,101,116,4,2,59,69,5411,5413,1,8912,113,117,97,108,59,1,8838,4,2,99,104,5426,5468,101,101,100,115,4,4,59,69,83,84,5440,5442,5449,5461,1,8827,113,117,97,108,59,1,10928,108,97,110,116,69,113,117,97,108,59,1,8829,105,108,100,101,59,1,8831,84,104,97,116,59,1,8715,59,1,8721,4,3,59,101,115,5486,5488,5507,1,8913,114,115,101,116,4,2,59,69,5498,5500,1,8835,113,117,97,108,59,1,8839,101,116,59,1,8913,4,11,72,82,83,97,99,102,104,105,111,114,115,5536,5546,5552,5567,5579,5602,5607,5655,5695,5701,5711,79,82,78,5,222,1,59,5544,1,222,65,68,69,59,1,8482,4,2,72,99,5558,5563,99,121,59,1,1035,121,59,1,1062,4,2,98,117,5573,5576,59,1,9,59,1,932,4,3,97,101,121,5587,5593,5599,114,111,110,59,1,356,100,105,108,59,1,354,59,1,1058,114,59,3,55349,56599,4,2,101,105,5613,5631,4,2,114,116,5619,5627,101,102,111,114,101,59,1,8756,97,59,1,920,4,2,99,110,5637,5647,107,83,112,97,99,101,59,3,8287,8202,83,112,97,99,101,59,1,8201,108,100,101,4,4,59,69,70,84,5668,5670,5677,5688,1,8764,113,117,97,108,59,1,8771,117,108,108,69,113,117,97,108,59,1,8773,105,108,100,101,59,1,8776,112,102,59,3,55349,56651,105,112,108,101,68,111,116,59,1,8411,4,2,99,116,5717,5722,114,59,3,55349,56495,114,111,107,59,1,358,4,14,97,98,99,100,102,103,109,110,111,112,114,115,116,117,5758,5789,5805,5823,5830,5835,5846,5852,5921,5937,6089,6095,6101,6108,4,2,99,114,5764,5774,117,116,101,5,218,1,59,5772,1,218,114,4,2,59,111,5781,5783,1,8607,99,105,114,59,1,10569,114,4,2,99,101,5796,5800,121,59,1,1038,118,101,59,1,364,4,2,105,121,5811,5820,114,99,5,219,1,59,5818,1,219,59,1,1059,98,108,97,99,59,1,368,114,59,3,55349,56600,114,97,118,101,5,217,1,59,5844,1,217,97,99,114,59,1,362,4,2,100,105,5858,5905,101,114,4,2,66,80,5866,5892,4,2,97,114,5872,5876,114,59,1,95,97,99,4,2,101,107,5884,5887,59,1,9183,101,116,59,1,9141,97,114,101,110,116,104,101,115,105,115,59,1,9181,111,110,4,2,59,80,5913,5915,1,8899,108,117,115,59,1,8846,4,2,103,112,5927,5932,111,110,59,1,370,102,59,3,55349,56652,4,8,65,68,69,84,97,100,112,115,5955,5985,5996,6009,6026,6033,6044,6075,114,114,111,119,4,3,59,66,68,5967,5969,5974,1,8593,97,114,59,1,10514,111,119,110,65,114,114,111,119,59,1,8645,111,119,110,65,114,114,111,119,59,1,8597,113,117,105,108,105,98,114,105,117,109,59,1,10606,101,101,4,2,59,65,6017,6019,1,8869,114,114,111,119,59,1,8613,114,114,111,119,59,1,8657,111,119,110,97,114,114,111,119,59,1,8661,101,114,4,2,76,82,6052,6063,101,102,116,65,114,114,111,119,59,1,8598,105,103,104,116,65,114,114,111,119,59,1,8599,105,4,2,59,108,6082,6084,1,978,111,110,59,1,933,105,110,103,59,1,366,99,114,59,3,55349,56496,105,108,100,101,59,1,360,109,108,5,220,1,59,6115,1,220,4,9,68,98,99,100,101,102,111,115,118,6137,6143,6148,6152,6166,6250,6255,6261,6267,97,115,104,59,1,8875,97,114,59,1,10987,121,59,1,1042,97,115,104,4,2,59,108,6161,6163,1,8873,59,1,10982,4,2,101,114,6172,6175,59,1,8897,4,3,98,116,121,6183,6188,6238,97,114,59,1,8214,4,2,59,105,6194,6196,1,8214,99,97,108,4,4,66,76,83,84,6209,6214,6220,6231,97,114,59,1,8739,105,110,101,59,1,124,101,112,97,114,97,116,111,114,59,1,10072,105,108,100,101,59,1,8768,84,104,105,110,83,112,97,99,101,59,1,8202,114,59,3,55349,56601,112,102,59,3,55349,56653,99,114,59,3,55349,56497,100,97,115,104,59,1,8874,4,5,99,101,102,111,115,6286,6292,6298,6303,6309,105,114,99,59,1,372,100,103,101,59,1,8896,114,59,3,55349,56602,112,102,59,3,55349,56654,99,114,59,3,55349,56498,4,4,102,105,111,115,6325,6330,6333,6339,114,59,3,55349,56603,59,1,926,112,102,59,3,55349,56655,99,114,59,3,55349,56499,4,9,65,73,85,97,99,102,111,115,117,6365,6370,6375,6380,6391,6405,6410,6416,6422,99,121,59,1,1071,99,121,59,1,1031,99,121,59,1,1070,99,117,116,101,5,221,1,59,6389,1,221,4,2,105,121,6397,6402,114,99,59,1,374,59,1,1067,114,59,3,55349,56604,112,102,59,3,55349,56656,99,114,59,3,55349,56500,109,108,59,1,376,4,8,72,97,99,100,101,102,111,115,6445,6450,6457,6472,6477,6501,6505,6510,99,121,59,1,1046,99,117,116,101,59,1,377,4,2,97,121,6463,6469,114,111,110,59,1,381,59,1,1047,111,116,59,1,379,4,2,114,116,6483,6497,111,87,105,100,116,104,83,112,97,99,101,59,1,8203,97,59,1,918,114,59,1,8488,112,102,59,1,8484,99,114,59,3,55349,56501,4,16,97,98,99,101,102,103,108,109,110,111,112,114,115,116,117,119,6550,6561,6568,6612,6622,6634,6645,6672,6699,6854,6870,6923,6933,6963,6974,6983,99,117,116,101,5,225,1,59,6559,1,225,114,101,118,101,59,1,259,4,6,59,69,100,105,117,121,6582,6584,6588,6591,6600,6609,1,8766,59,3,8766,819,59,1,8767,114,99,5,226,1,59,6598,1,226,116,101,5,180,1,59,6607,1,180,59,1,1072,108,105,103,5,230,1,59,6620,1,230,4,2,59,114,6628,6630,1,8289,59,3,55349,56606,114,97,118,101,5,224,1,59,6643,1,224,4,2,101,112,6651,6667,4,2,102,112,6657,6663,115,121,109,59,1,8501,104,59,1,8501,104,97,59,1,945,4,2,97,112,6678,6692,4,2,99,108,6684,6688,114,59,1,257,103,59,1,10815,5,38,1,59,6697,1,38,4,2,100,103,6705,6737,4,5,59,97,100,115,118,6717,6719,6724,6727,6734,1,8743,110,100,59,1,10837,59,1,10844,108,111,112,101,59,1,10840,59,1,10842,4,7,59,101,108,109,114,115,122,6753,6755,6758,6762,6814,6835,6848,1,8736,59,1,10660,101,59,1,8736,115,100,4,2,59,97,6770,6772,1,8737,4,8,97,98,99,100,101,102,103,104,6790,6793,6796,6799,6802,6805,6808,6811,59,1,10664,59,1,10665,59,1,10666,59,1,10667,59,1,10668,59,1,10669,59,1,10670,59,1,10671,116,4,2,59,118,6821,6823,1,8735,98,4,2,59,100,6830,6832,1,8894,59,1,10653,4,2,112,116,6841,6845,104,59,1,8738,59,1,197,97,114,114,59,1,9084,4,2,103,112,6860,6865,111,110,59,1,261,102,59,3,55349,56658,4,7,59,69,97,101,105,111,112,6886,6888,6891,6897,6900,6904,6908,1,8776,59,1,10864,99,105,114,59,1,10863,59,1,8778,100,59,1,8779,115,59,1,39,114,111,120,4,2,59,101,6917,6919,1,8776,113,59,1,8778,105,110,103,5,229,1,59,6931,1,229,4,3,99,116,121,6941,6946,6949,114,59,3,55349,56502,59,1,42,109,112,4,2,59,101,6957,6959,1,8776,113,59,1,8781,105,108,100,101,5,227,1,59,6972,1,227,109,108,5,228,1,59,6981,1,228,4,2,99,105,6989,6997,111,110,105,110,116,59,1,8755,110,116,59,1,10769,4,16,78,97,98,99,100,101,102,105,107,108,110,111,112,114,115,117,7036,7041,7119,7135,7149,7155,7219,7224,7347,7354,7463,7489,7786,7793,7814,7866,111,116,59,1,10989,4,2,99,114,7047,7094,107,4,4,99,101,112,115,7058,7064,7073,7080,111,110,103,59,1,8780,112,115,105,108,111,110,59,1,1014,114,105,109,101,59,1,8245,105,109,4,2,59,101,7088,7090,1,8765,113,59,1,8909,4,2,118,119,7100,7105,101,101,59,1,8893,101,100,4,2,59,103,7113,7115,1,8965,101,59,1,8965,114,107,4,2,59,116,7127,7129,1,9141,98,114,107,59,1,9142,4,2,111,121,7141,7146,110,103,59,1,8780,59,1,1073,113,117,111,59,1,8222,4,5,99,109,112,114,116,7167,7181,7188,7193,7199,97,117,115,4,2,59,101,7176,7178,1,8757,59,1,8757,112,116,121,118,59,1,10672,115,105,59,1,1014,110,111,117,59,1,8492,4,3,97,104,119,7207,7210,7213,59,1,946,59,1,8502,101,101,110,59,1,8812,114,59,3,55349,56607,103,4,7,99,111,115,116,117,118,119,7241,7262,7288,7305,7328,7335,7340,4,3,97,105,117,7249,7253,7258,112,59,1,8898,114,99,59,1,9711,112,59,1,8899,4,3,100,112,116,7270,7275,7281,111,116,59,1,10752,108,117,115,59,1,10753,105,109,101,115,59,1,10754,4,2,113,116,7294,7300,99,117,112,59,1,10758,97,114,59,1,9733,114,105,97,110,103,108,101,4,2,100,117,7318,7324,111,119,110,59,1,9661,112,59,1,9651,112,108,117,115,59,1,10756,101,101,59,1,8897,101,100,103,101,59,1,8896,97,114,111,119,59,1,10509,4,3,97,107,111,7362,7436,7458,4,2,99,110,7368,7432,107,4,3,108,115,116,7377,7386,7394,111,122,101,110,103,101,59,1,10731,113,117,97,114,101,59,1,9642,114,105,97,110,103,108,101,4,4,59,100,108,114,7411,7413,7419,7425,1,9652,111,119,110,59,1,9662,101,102,116,59,1,9666,105,103,104,116,59,1,9656,107,59,1,9251,4,2,49,51,7442,7454,4,2,50,52,7448,7451,59,1,9618,59,1,9617,52,59,1,9619,99,107,59,1,9608,4,2,101,111,7469,7485,4,2,59,113,7475,7478,3,61,8421,117,105,118,59,3,8801,8421,116,59,1,8976,4,4,112,116,119,120,7499,7504,7517,7523,102,59,3,55349,56659,4,2,59,116,7510,7512,1,8869,111,109,59,1,8869,116,105,101,59,1,8904,4,12,68,72,85,86,98,100,104,109,112,116,117,118,7549,7571,7597,7619,7655,7660,7682,7708,7715,7721,7728,7750,4,4,76,82,108,114,7559,7562,7565,7568,59,1,9559,59,1,9556,59,1,9558,59,1,9555,4,5,59,68,85,100,117,7583,7585,7588,7591,7594,1,9552,59,1,9574,59,1,9577,59,1,9572,59,1,9575,4,4,76,82,108,114,7607,7610,7613,7616,59,1,9565,59,1,9562,59,1,9564,59,1,9561,4,7,59,72,76,82,104,108,114,7635,7637,7640,7643,7646,7649,7652,1,9553,59,1,9580,59,1,9571,59,1,9568,59,1,9579,59,1,9570,59,1,9567,111,120,59,1,10697,4,4,76,82,108,114,7670,7673,7676,7679,59,1,9557,59,1,9554,59,1,9488,59,1,9484,4,5,59,68,85,100,117,7694,7696,7699,7702,7705,1,9472,59,1,9573,59,1,9576,59,1,9516,59,1,9524,105,110,117,115,59,1,8863,108,117,115,59,1,8862,105,109,101,115,59,1,8864,4,4,76,82,108,114,7738,7741,7744,7747,59,1,9563,59,1,9560,59,1,9496,59,1,9492,4,7,59,72,76,82,104,108,114,7766,7768,7771,7774,7777,7780,7783,1,9474,59,1,9578,59,1,9569,59,1,9566,59,1,9532,59,1,9508,59,1,9500,114,105,109,101,59,1,8245,4,2,101,118,7799,7804,118,101,59,1,728,98,97,114,5,166,1,59,7812,1,166,4,4,99,101,105,111,7824,7829,7834,7846,114,59,3,55349,56503,109,105,59,1,8271,109,4,2,59,101,7841,7843,1,8765,59,1,8909,108,4,3,59,98,104,7855,7857,7860,1,92,59,1,10693,115,117,98,59,1,10184,4,2,108,109,7872,7885,108,4,2,59,101,7879,7881,1,8226,116,59,1,8226,112,4,3,59,69,101,7894,7896,7899,1,8782,59,1,10926,4,2,59,113,7905,7907,1,8783,59,1,8783,4,15,97,99,100,101,102,104,105,108,111,114,115,116,117,119,121,7942,8021,8075,8080,8121,8126,8157,8279,8295,8430,8446,8485,8491,8707,8726,4,3,99,112,114,7950,7956,8007,117,116,101,59,1,263,4,6,59,97,98,99,100,115,7970,7972,7977,7984,7998,8003,1,8745,110,100,59,1,10820,114,99,117,112,59,1,10825,4,2,97,117,7990,7994,112,59,1,10827,112,59,1,10823,111,116,59,1,10816,59,3,8745,65024,4,2,101,111,8013,8017,116,59,1,8257,110,59,1,711,4,4,97,101,105,117,8031,8046,8056,8061,4,2,112,114,8037,8041,115,59,1,10829,111,110,59,1,269,100,105,108,5,231,1,59,8054,1,231,114,99,59,1,265,112,115,4,2,59,115,8069,8071,1,10828,109,59,1,10832,111,116,59,1,267,4,3,100,109,110,8088,8097,8104,105,108,5,184,1,59,8095,1,184,112,116,121,118,59,1,10674,116,5,162,2,59,101,8112,8114,1,162,114,100,111,116,59,1,183,114,59,3,55349,56608,4,3,99,101,105,8134,8138,8154,121,59,1,1095,99,107,4,2,59,109,8146,8148,1,10003,97,114,107,59,1,10003,59,1,967,114,4,7,59,69,99,101,102,109,115,8174,8176,8179,8258,8261,8268,8273,1,9675,59,1,10691,4,3,59,101,108,8187,8189,8193,1,710,113,59,1,8791,101,4,2,97,100,8200,8223,114,114,111,119,4,2,108,114,8210,8216,101,102,116,59,1,8634,105,103,104,116,59,1,8635,4,5,82,83,97,99,100,8235,8238,8241,8246,8252,59,1,174,59,1,9416,115,116,59,1,8859,105,114,99,59,1,8858,97,115,104,59,1,8861,59,1,8791,110,105,110,116,59,1,10768,105,100,59,1,10991,99,105,114,59,1,10690,117,98,115,4,2,59,117,8288,8290,1,9827,105,116,59,1,9827,4,4,108,109,110,112,8305,8326,8376,8400,111,110,4,2,59,101,8313,8315,1,58,4,2,59,113,8321,8323,1,8788,59,1,8788,4,2,109,112,8332,8344,97,4,2,59,116,8339,8341,1,44,59,1,64,4,3,59,102,108,8352,8354,8358,1,8705,110,59,1,8728,101,4,2,109,120,8365,8371,101,110,116,59,1,8705,101,115,59,1,8450,4,2,103,105,8382,8395,4,2,59,100,8388,8390,1,8773,111,116,59,1,10861,110,116,59,1,8750,4,3,102,114,121,8408,8412,8417,59,3,55349,56660,111,100,59,1,8720,5,169,2,59,115,8424,8426,1,169,114,59,1,8471,4,2,97,111,8436,8441,114,114,59,1,8629,115,115,59,1,10007,4,2,99,117,8452,8457,114,59,3,55349,56504,4,2,98,112,8463,8474,4,2,59,101,8469,8471,1,10959,59,1,10961,4,2,59,101,8480,8482,1,10960,59,1,10962,100,111,116,59,1,8943,4,7,100,101,108,112,114,118,119,8507,8522,8536,8550,8600,8697,8702,97,114,114,4,2,108,114,8516,8519,59,1,10552,59,1,10549,4,2,112,115,8528,8532,114,59,1,8926,99,59,1,8927,97,114,114,4,2,59,112,8545,8547,1,8630,59,1,10557,4,6,59,98,99,100,111,115,8564,8566,8573,8587,8592,8596,1,8746,114,99,97,112,59,1,10824,4,2,97,117,8579,8583,112,59,1,10822,112,59,1,10826,111,116,59,1,8845,114,59,1,10821,59,3,8746,65024,4,4,97,108,114,118,8610,8623,8663,8672,114,114,4,2,59,109,8618,8620,1,8631,59,1,10556,121,4,3,101,118,119,8632,8651,8656,113,4,2,112,115,8639,8645,114,101,99,59,1,8926,117,99,99,59,1,8927,101,101,59,1,8910,101,100,103,101,59,1,8911,101,110,5,164,1,59,8670,1,164,101,97,114,114,111,119,4,2,108,114,8684,8690,101,102,116,59,1,8630,105,103,104,116,59,1,8631,101,101,59,1,8910,101,100,59,1,8911,4,2,99,105,8713,8721,111,110,105,110,116,59,1,8754,110,116,59,1,8753,108,99,116,121,59,1,9005,4,19,65,72,97,98,99,100,101,102,104,105,106,108,111,114,115,116,117,119,122,8773,8778,8783,8821,8839,8854,8887,8914,8930,8944,9036,9041,9058,9197,9227,9258,9281,9297,9305,114,114,59,1,8659,97,114,59,1,10597,4,4,103,108,114,115,8793,8799,8805,8809,103,101,114,59,1,8224,101,116,104,59,1,8504,114,59,1,8595,104,4,2,59,118,8816,8818,1,8208,59,1,8867,4,2,107,108,8827,8834,97,114,111,119,59,1,10511,97,99,59,1,733,4,2,97,121,8845,8851,114,111,110,59,1,271,59,1,1076,4,3,59,97,111,8862,8864,8880,1,8518,4,2,103,114,8870,8876,103,101,114,59,1,8225,114,59,1,8650,116,115,101,113,59,1,10871,4,3,103,108,109,8895,8902,8907,5,176,1,59,8900,1,176,116,97,59,1,948,112,116,121,118,59,1,10673,4,2,105,114,8920,8926,115,104,116,59,1,10623,59,3,55349,56609,97,114,4,2,108,114,8938,8941,59,1,8643,59,1,8642,4,5,97,101,103,115,118,8956,8986,8989,8996,9001,109,4,3,59,111,115,8965,8967,8983,1,8900,110,100,4,2,59,115,8975,8977,1,8900,117,105,116,59,1,9830,59,1,9830,59,1,168,97,109,109,97,59,1,989,105,110,59,1,8946,4,3,59,105,111,9009,9011,9031,1,247,100,101,5,247,2,59,111,9020,9022,1,247,110,116,105,109,101,115,59,1,8903,110,120,59,1,8903,99,121,59,1,1106,99,4,2,111,114,9048,9053,114,110,59,1,8990,111,112,59,1,8973,4,5,108,112,116,117,119,9070,9076,9081,9130,9144,108,97,114,59,1,36,102,59,3,55349,56661,4,5,59,101,109,112,115,9093,9095,9109,9116,9122,1,729,113,4,2,59,100,9102,9104,1,8784,111,116,59,1,8785,105,110,117,115,59,1,8760,108,117,115,59,1,8724,113,117,97,114,101,59,1,8865,98,108,101,98,97,114,119,101,100,103,101,59,1,8966,110,4,3,97,100,104,9153,9160,9172,114,114,111,119,59,1,8595,111,119,110,97,114,114,111,119,115,59,1,8650,97,114,112,111,111,110,4,2,108,114,9184,9190,101,102,116,59,1,8643,105,103,104,116,59,1,8642,4,2,98,99,9203,9211,107,97,114,111,119,59,1,10512,4,2,111,114,9217,9222,114,110,59,1,8991,111,112,59,1,8972,4,3,99,111,116,9235,9248,9252,4,2,114,121,9241,9245,59,3,55349,56505,59,1,1109,108,59,1,10742,114,111,107,59,1,273,4,2,100,114,9264,9269,111,116,59,1,8945,105,4,2,59,102,9276,9278,1,9663,59,1,9662,4,2,97,104,9287,9292,114,114,59,1,8693,97,114,59,1,10607,97,110,103,108,101,59,1,10662,4,2,99,105,9311,9315,121,59,1,1119,103,114,97,114,114,59,1,10239,4,18,68,97,99,100,101,102,103,108,109,110,111,112,113,114,115,116,117,120,9361,9376,9398,9439,9444,9447,9462,9495,9531,9585,9598,9614,9659,9755,9771,9792,9808,9826,4,2,68,111,9367,9372,111,116,59,1,10871,116,59,1,8785,4,2,99,115,9382,9392,117,116,101,5,233,1,59,9390,1,233,116,101,114,59,1,10862,4,4,97,105,111,121,9408,9414,9430,9436,114,111,110,59,1,283,114,4,2,59,99,9421,9423,1,8790,5,234,1,59,9428,1,234,108,111,110,59,1,8789,59,1,1101,111,116,59,1,279,59,1,8519,4,2,68,114,9453,9458,111,116,59,1,8786,59,3,55349,56610,4,3,59,114,115,9470,9472,9482,1,10906,97,118,101,5,232,1,59,9480,1,232,4,2,59,100,9488,9490,1,10902,111,116,59,1,10904,4,4,59,105,108,115,9505,9507,9515,9518,1,10905,110,116,101,114,115,59,1,9191,59,1,8467,4,2,59,100,9524,9526,1,10901,111,116,59,1,10903,4,3,97,112,115,9539,9544,9564,99,114,59,1,275,116,121,4,3,59,115,118,9554,9556,9561,1,8709,101,116,59,1,8709,59,1,8709,112,4,2,49,59,9571,9583,4,2,51,52,9577,9580,59,1,8196,59,1,8197,1,8195,4,2,103,115,9591,9594,59,1,331,112,59,1,8194,4,2,103,112,9604,9609,111,110,59,1,281,102,59,3,55349,56662,4,3,97,108,115,9622,9635,9640,114,4,2,59,115,9629,9631,1,8917,108,59,1,10723,117,115,59,1,10865,105,4,3,59,108,118,9649,9651,9656,1,949,111,110,59,1,949,59,1,1013,4,4,99,115,117,118,9669,9686,9716,9747,4,2,105,111,9675,9680,114,99,59,1,8790,108,111,110,59,1,8789,4,2,105,108,9692,9696,109,59,1,8770,97,110,116,4,2,103,108,9705,9710,116,114,59,1,10902,101,115,115,59,1,10901,4,3,97,101,105,9724,9729,9734,108,115,59,1,61,115,116,59,1,8799,118,4,2,59,68,9741,9743,1,8801,68,59,1,10872,112,97,114,115,108,59,1,10725,4,2,68,97,9761,9766,111,116,59,1,8787,114,114,59,1,10609,4,3,99,100,105,9779,9783,9788,114,59,1,8495,111,116,59,1,8784,109,59,1,8770,4,2,97,104,9798,9801,59,1,951,5,240,1,59,9806,1,240,4,2,109,114,9814,9822,108,5,235,1,59,9820,1,235,111,59,1,8364,4,3,99,105,112,9834,9838,9843,108,59,1,33,115,116,59,1,8707,4,2,101,111,9849,9859,99,116,97,116,105,111,110,59,1,8496,110,101,110,116,105,97,108,101,59,1,8519,4,12,97,99,101,102,105,106,108,110,111,112,114,115,9896,9910,9914,9921,9954,9960,9967,9989,9994,10027,10036,10164,108,108,105,110,103,100,111,116,115,101,113,59,1,8786,121,59,1,1092,109,97,108,101,59,1,9792,4,3,105,108,114,9929,9935,9950,108,105,103,59,1,64259,4,2,105,108,9941,9945,103,59,1,64256,105,103,59,1,64260,59,3,55349,56611,108,105,103,59,1,64257,108,105,103,59,3,102,106,4,3,97,108,116,9975,9979,9984,116,59,1,9837,105,103,59,1,64258,110,115,59,1,9649,111,102,59,1,402,4,2,112,114,10000,10005,102,59,3,55349,56663,4,2,97,107,10011,10016,108,108,59,1,8704,4,2,59,118,10022,10024,1,8916,59,1,10969,97,114,116,105,110,116,59,1,10765,4,2,97,111,10042,10159,4,2,99,115,10048,10155,4,6,49,50,51,52,53,55,10062,10102,10114,10135,10139,10151,4,6,50,51,52,53,54,56,10076,10083,10086,10093,10096,10099,5,189,1,59,10081,1,189,59,1,8531,5,188,1,59,10091,1,188,59,1,8533,59,1,8537,59,1,8539,4,2,51,53,10108,10111,59,1,8532,59,1,8534,4,3,52,53,56,10122,10129,10132,5,190,1,59,10127,1,190,59,1,8535,59,1,8540,53,59,1,8536,4,2,54,56,10145,10148,59,1,8538,59,1,8541,56,59,1,8542,108,59,1,8260,119,110,59,1,8994,99,114,59,3,55349,56507,4,17,69,97,98,99,100,101,102,103,105,106,108,110,111,114,115,116,118,10206,10217,10247,10254,10268,10273,10358,10363,10374,10380,10385,10406,10458,10464,10470,10497,10610,4,2,59,108,10212,10214,1,8807,59,1,10892,4,3,99,109,112,10225,10231,10244,117,116,101,59,1,501,109,97,4,2,59,100,10239,10241,1,947,59,1,989,59,1,10886,114,101,118,101,59,1,287,4,2,105,121,10260,10265,114,99,59,1,285,59,1,1075,111,116,59,1,289,4,4,59,108,113,115,10283,10285,10288,10308,1,8805,59,1,8923,4,3,59,113,115,10296,10298,10301,1,8805,59,1,8807,108,97,110,116,59,1,10878,4,4,59,99,100,108,10318,10320,10324,10345,1,10878,99,59,1,10921,111,116,4,2,59,111,10332,10334,1,10880,4,2,59,108,10340,10342,1,10882,59,1,10884,4,2,59,101,10351,10354,3,8923,65024,115,59,1,10900,114,59,3,55349,56612,4,2,59,103,10369,10371,1,8811,59,1,8921,109,101,108,59,1,8503,99,121,59,1,1107,4,4,59,69,97,106,10395,10397,10400,10403,1,8823,59,1,10898,59,1,10917,59,1,10916,4,4,69,97,101,115,10416,10419,10434,10453,59,1,8809,112,4,2,59,112,10426,10428,1,10890,114,111,120,59,1,10890,4,2,59,113,10440,10442,1,10888,4,2,59,113,10448,10450,1,10888,59,1,8809,105,109,59,1,8935,112,102,59,3,55349,56664,97,118,101,59,1,96,4,2,99,105,10476,10480,114,59,1,8458,109,4,3,59,101,108,10489,10491,10494,1,8819,59,1,10894,59,1,10896,5,62,6,59,99,100,108,113,114,10512,10514,10527,10532,10538,10545,1,62,4,2,99,105,10520,10523,59,1,10919,114,59,1,10874,111,116,59,1,8919,80,97,114,59,1,10645,117,101,115,116,59,1,10876,4,5,97,100,101,108,115,10557,10574,10579,10599,10605,4,2,112,114,10563,10570,112,114,111,120,59,1,10886,114,59,1,10616,111,116,59,1,8919,113,4,2,108,113,10586,10592,101,115,115,59,1,8923,108,101,115,115,59,1,10892,101,115,115,59,1,8823,105,109,59,1,8819,4,2,101,110,10616,10626,114,116,110,101,113,113,59,3,8809,65024,69,59,3,8809,65024,4,10,65,97,98,99,101,102,107,111,115,121,10653,10658,10713,10718,10724,10760,10765,10786,10850,10875,114,114,59,1,8660,4,4,105,108,109,114,10668,10674,10678,10684,114,115,112,59,1,8202,102,59,1,189,105,108,116,59,1,8459,4,2,100,114,10690,10695,99,121,59,1,1098,4,3,59,99,119,10703,10705,10710,1,8596,105,114,59,1,10568,59,1,8621,97,114,59,1,8463,105,114,99,59,1,293,4,3,97,108,114,10732,10748,10754,114,116,115,4,2,59,117,10741,10743,1,9829,105,116,59,1,9829,108,105,112,59,1,8230,99,111,110,59,1,8889,114,59,3,55349,56613,115,4,2,101,119,10772,10779,97,114,111,119,59,1,10533,97,114,111,119,59,1,10534,4,5,97,109,111,112,114,10798,10803,10809,10839,10844,114,114,59,1,8703,116,104,116,59,1,8763,107,4,2,108,114,10816,10827,101,102,116,97,114,114,111,119,59,1,8617,105,103,104,116,97,114,114,111,119,59,1,8618,102,59,3,55349,56665,98,97,114,59,1,8213,4,3,99,108,116,10858,10863,10869,114,59,3,55349,56509,97,115,104,59,1,8463,114,111,107,59,1,295,4,2,98,112,10881,10887,117,108,108,59,1,8259,104,101,110,59,1,8208,4,15,97,99,101,102,103,105,106,109,110,111,112,113,115,116,117,10925,10936,10958,10977,10990,11001,11039,11045,11101,11192,11220,11226,11237,11285,11299,99,117,116,101,5,237,1,59,10934,1,237,4,3,59,105,121,10944,10946,10955,1,8291,114,99,5,238,1,59,10953,1,238,59,1,1080,4,2,99,120,10964,10968,121,59,1,1077,99,108,5,161,1,59,10975,1,161,4,2,102,114,10983,10986,59,1,8660,59,3,55349,56614,114,97,118,101,5,236,1,59,10999,1,236,4,4,59,105,110,111,11011,11013,11028,11034,1,8520,4,2,105,110,11019,11024,110,116,59,1,10764,116,59,1,8749,102,105,110,59,1,10716,116,97,59,1,8489,108,105,103,59,1,307,4,3,97,111,112,11053,11092,11096,4,3,99,103,116,11061,11065,11088,114,59,1,299,4,3,101,108,112,11073,11076,11082,59,1,8465,105,110,101,59,1,8464,97,114,116,59,1,8465,104,59,1,305,102,59,1,8887,101,100,59,1,437,4,5,59,99,102,111,116,11113,11115,11121,11136,11142,1,8712,97,114,101,59,1,8453,105,110,4,2,59,116,11129,11131,1,8734,105,101,59,1,10717,100,111,116,59,1,305,4,5,59,99,101,108,112,11154,11156,11161,11179,11186,1,8747,97,108,59,1,8890,4,2,103,114,11167,11173,101,114,115,59,1,8484,99,97,108,59,1,8890,97,114,104,107,59,1,10775,114,111,100,59,1,10812,4,4,99,103,112,116,11202,11206,11211,11216,121,59,1,1105,111,110,59,1,303,102,59,3,55349,56666,97,59,1,953,114,111,100,59,1,10812,117,101,115,116,5,191,1,59,11235,1,191,4,2,99,105,11243,11248,114,59,3,55349,56510,110,4,5,59,69,100,115,118,11261,11263,11266,11271,11282,1,8712,59,1,8953,111,116,59,1,8949,4,2,59,118,11277,11279,1,8948,59,1,8947,59,1,8712,4,2,59,105,11291,11293,1,8290,108,100,101,59,1,297,4,2,107,109,11305,11310,99,121,59,1,1110,108,5,239,1,59,11316,1,239,4,6,99,102,109,111,115,117,11332,11346,11351,11357,11363,11380,4,2,105,121,11338,11343,114,99,59,1,309,59,1,1081,114,59,3,55349,56615,97,116,104,59,1,567,112,102,59,3,55349,56667,4,2,99,101,11369,11374,114,59,3,55349,56511,114,99,121,59,1,1112,107,99,121,59,1,1108,4,8,97,99,102,103,104,106,111,115,11404,11418,11433,11438,11445,11450,11455,11461,112,112,97,4,2,59,118,11413,11415,1,954,59,1,1008,4,2,101,121,11424,11430,100,105,108,59,1,311,59,1,1082,114,59,3,55349,56616,114,101,101,110,59,1,312,99,121,59,1,1093,99,121,59,1,1116,112,102,59,3,55349,56668,99,114,59,3,55349,56512,4,23,65,66,69,72,97,98,99,100,101,102,103,104,106,108,109,110,111,112,114,115,116,117,118,11515,11538,11544,11555,11560,11721,11780,11818,11868,12136,12160,12171,12203,12208,12246,12275,12327,12509,12523,12569,12641,12732,12752,4,3,97,114,116,11523,11528,11532,114,114,59,1,8666,114,59,1,8656,97,105,108,59,1,10523,97,114,114,59,1,10510,4,2,59,103,11550,11552,1,8806,59,1,10891,97,114,59,1,10594,4,9,99,101,103,109,110,112,113,114,116,11580,11586,11594,11600,11606,11624,11627,11636,11694,117,116,101,59,1,314,109,112,116,121,118,59,1,10676,114,97,110,59,1,8466,98,100,97,59,1,955,103,4,3,59,100,108,11615,11617,11620,1,10216,59,1,10641,101,59,1,10216,59,1,10885,117,111,5,171,1,59,11634,1,171,114,4,8,59,98,102,104,108,112,115,116,11655,11657,11669,11673,11677,11681,11685,11690,1,8592,4,2,59,102,11663,11665,1,8676,115,59,1,10527,115,59,1,10525,107,59,1,8617,112,59,1,8619,108,59,1,10553,105,109,59,1,10611,108,59,1,8610,4,3,59,97,101,11702,11704,11709,1,10923,105,108,59,1,10521,4,2,59,115,11715,11717,1,10925,59,3,10925,65024,4,3,97,98,114,11729,11734,11739,114,114,59,1,10508,114,107,59,1,10098,4,2,97,107,11745,11758,99,4,2,101,107,11752,11755,59,1,123,59,1,91,4,2,101,115,11764,11767,59,1,10635,108,4,2,100,117,11774,11777,59,1,10639,59,1,10637,4,4,97,101,117,121,11790,11796,11811,11815,114,111,110,59,1,318,4,2,100,105,11802,11807,105,108,59,1,316,108,59,1,8968,98,59,1,123,59,1,1083,4,4,99,113,114,115,11828,11832,11845,11864,97,59,1,10550,117,111,4,2,59,114,11840,11842,1,8220,59,1,8222,4,2,100,117,11851,11857,104,97,114,59,1,10599,115,104,97,114,59,1,10571,104,59,1,8626,4,5,59,102,103,113,115,11880,11882,12008,12011,12031,1,8804,116,4,5,97,104,108,114,116,11895,11913,11935,11947,11996,114,114,111,119,4,2,59,116,11905,11907,1,8592,97,105,108,59,1,8610,97,114,112,111,111,110,4,2,100,117,11925,11931,111,119,110,59,1,8637,112,59,1,8636,101,102,116,97,114,114,111,119,115,59,1,8647,105,103,104,116,4,3,97,104,115,11959,11974,11984,114,114,111,119,4,2,59,115,11969,11971,1,8596,59,1,8646,97,114,112,111,111,110,115,59,1,8651,113,117,105,103,97,114,114,111,119,59,1,8621,104,114,101,101,116,105,109,101,115,59,1,8907,59,1,8922,4,3,59,113,115,12019,12021,12024,1,8804,59,1,8806,108,97,110,116,59,1,10877,4,5,59,99,100,103,115,12043,12045,12049,12070,12083,1,10877,99,59,1,10920,111,116,4,2,59,111,12057,12059,1,10879,4,2,59,114,12065,12067,1,10881,59,1,10883,4,2,59,101,12076,12079,3,8922,65024,115,59,1,10899,4,5,97,100,101,103,115,12095,12103,12108,12126,12131,112,112,114,111,120,59,1,10885,111,116,59,1,8918,113,4,2,103,113,12115,12120,116,114,59,1,8922,103,116,114,59,1,10891,116,114,59,1,8822,105,109,59,1,8818,4,3,105,108,114,12144,12150,12156,115,104,116,59,1,10620,111,111,114,59,1,8970,59,3,55349,56617,4,2,59,69,12166,12168,1,8822,59,1,10897,4,2,97,98,12177,12198,114,4,2,100,117,12184,12187,59,1,8637,4,2,59,108,12193,12195,1,8636,59,1,10602,108,107,59,1,9604,99,121,59,1,1113,4,5,59,97,99,104,116,12220,12222,12227,12235,12241,1,8810,114,114,59,1,8647,111,114,110,101,114,59,1,8990,97,114,100,59,1,10603,114,105,59,1,9722,4,2,105,111,12252,12258,100,111,116,59,1,320,117,115,116,4,2,59,97,12267,12269,1,9136,99,104,101,59,1,9136,4,4,69,97,101,115,12285,12288,12303,12322,59,1,8808,112,4,2,59,112,12295,12297,1,10889,114,111,120,59,1,10889,4,2,59,113,12309,12311,1,10887,4,2,59,113,12317,12319,1,10887,59,1,8808,105,109,59,1,8934,4,8,97,98,110,111,112,116,119,122,12345,12359,12364,12421,12446,12467,12474,12490,4,2,110,114,12351,12355,103,59,1,10220,114,59,1,8701,114,107,59,1,10214,103,4,3,108,109,114,12373,12401,12409,101,102,116,4,2,97,114,12382,12389,114,114,111,119,59,1,10229,105,103,104,116,97,114,114,111,119,59,1,10231,97,112,115,116,111,59,1,10236,105,103,104,116,97,114,114,111,119,59,1,10230,112,97,114,114,111,119,4,2,108,114,12433,12439,101,102,116,59,1,8619,105,103,104,116,59,1,8620,4,3,97,102,108,12454,12458,12462,114,59,1,10629,59,3,55349,56669,117,115,59,1,10797,105,109,101,115,59,1,10804,4,2,97,98,12480,12485,115,116,59,1,8727,97,114,59,1,95,4,3,59,101,102,12498,12500,12506,1,9674,110,103,101,59,1,9674,59,1,10731,97,114,4,2,59,108,12517,12519,1,40,116,59,1,10643,4,5,97,99,104,109,116,12535,12540,12548,12561,12564,114,114,59,1,8646,111,114,110,101,114,59,1,8991,97,114,4,2,59,100,12556,12558,1,8651,59,1,10605,59,1,8206,114,105,59,1,8895,4,6,97,99,104,105,113,116,12583,12589,12594,12597,12614,12635,113,117,111,59,1,8249,114,59,3,55349,56513,59,1,8624,109,4,3,59,101,103,12606,12608,12611,1,8818,59,1,10893,59,1,10895,4,2,98,117,12620,12623,59,1,91,111,4,2,59,114,12630,12632,1,8216,59,1,8218,114,111,107,59,1,322,5,60,8,59,99,100,104,105,108,113,114,12660,12662,12675,12680,12686,12692,12698,12705,1,60,4,2,99,105,12668,12671,59,1,10918,114,59,1,10873,111,116,59,1,8918,114,101,101,59,1,8907,109,101,115,59,1,8905,97,114,114,59,1,10614,117,101,115,116,59,1,10875,4,2,80,105,12711,12716,97,114,59,1,10646,4,3,59,101,102,12724,12726,12729,1,9667,59,1,8884,59,1,9666,114,4,2,100,117,12739,12746,115,104,97,114,59,1,10570,104,97,114,59,1,10598,4,2,101,110,12758,12768,114,116,110,101,113,113,59,3,8808,65024,69,59,3,8808,65024,4,14,68,97,99,100,101,102,104,105,108,110,111,112,115,117,12803,12809,12893,12908,12914,12928,12933,12937,13011,13025,13032,13049,13052,13069,68,111,116,59,1,8762,4,4,99,108,112,114,12819,12827,12849,12887,114,5,175,1,59,12825,1,175,4,2,101,116,12833,12836,59,1,9794,4,2,59,101,12842,12844,1,10016,115,101,59,1,10016,4,2,59,115,12855,12857,1,8614,116,111,4,4,59,100,108,117,12869,12871,12877,12883,1,8614,111,119,110,59,1,8615,101,102,116,59,1,8612,112,59,1,8613,107,101,114,59,1,9646,4,2,111,121,12899,12905,109,109,97,59,1,10793,59,1,1084,97,115,104,59,1,8212,97,115,117,114,101,100,97,110,103,108,101,59,1,8737,114,59,3,55349,56618,111,59,1,8487,4,3,99,100,110,12945,12954,12985,114,111,5,181,1,59,12952,1,181,4,4,59,97,99,100,12964,12966,12971,12976,1,8739,115,116,59,1,42,105,114,59,1,10992,111,116,5,183,1,59,12983,1,183,117,115,4,3,59,98,100,12995,12997,13000,1,8722,59,1,8863,4,2,59,117,13006,13008,1,8760,59,1,10794,4,2,99,100,13017,13021,112,59,1,10971,114,59,1,8230,112,108,117,115,59,1,8723,4,2,100,112,13038,13044,101,108,115,59,1,8871,102,59,3,55349,56670,59,1,8723,4,2,99,116,13058,13063,114,59,3,55349,56514,112,111,115,59,1,8766,4,3,59,108,109,13077,13079,13087,1,956,116,105,109,97,112,59,1,8888,97,112,59,1,8888,4,24,71,76,82,86,97,98,99,100,101,102,103,104,105,106,108,109,111,112,114,115,116,117,118,119,13142,13165,13217,13229,13247,13330,13359,13414,13420,13508,13513,13579,13602,13626,13631,13762,13767,13855,13936,13995,14214,14285,14312,14432,4,2,103,116,13148,13152,59,3,8921,824,4,2,59,118,13158,13161,3,8811,8402,59,3,8811,824,4,3,101,108,116,13173,13200,13204,102,116,4,2,97,114,13181,13188,114,114,111,119,59,1,8653,105,103,104,116,97,114,114,111,119,59,1,8654,59,3,8920,824,4,2,59,118,13210,13213,3,8810,8402,59,3,8810,824,105,103,104,116,97,114,114,111,119,59,1,8655,4,2,68,100,13235,13241,97,115,104,59,1,8879,97,115,104,59,1,8878,4,5,98,99,110,112,116,13259,13264,13270,13275,13308,108,97,59,1,8711,117,116,101,59,1,324,103,59,3,8736,8402,4,5,59,69,105,111,112,13287,13289,13293,13298,13302,1,8777,59,3,10864,824,100,59,3,8779,824,115,59,1,329,114,111,120,59,1,8777,117,114,4,2,59,97,13316,13318,1,9838,108,4,2,59,115,13325,13327,1,9838,59,1,8469,4,2,115,117,13336,13344,112,5,160,1,59,13342,1,160,109,112,4,2,59,101,13352,13355,3,8782,824,59,3,8783,824,4,5,97,101,111,117,121,13371,13385,13391,13407,13411,4,2,112,114,13377,13380,59,1,10819,111,110,59,1,328,100,105,108,59,1,326,110,103,4,2,59,100,13399,13401,1,8775,111,116,59,3,10861,824,112,59,1,10818,59,1,1085,97,115,104,59,1,8211,4,7,59,65,97,100,113,115,120,13436,13438,13443,13466,13472,13478,13494,1,8800,114,114,59,1,8663,114,4,2,104,114,13450,13454,107,59,1,10532,4,2,59,111,13460,13462,1,8599,119,59,1,8599,111,116,59,3,8784,824,117,105,118,59,1,8802,4,2,101,105,13484,13489,97,114,59,1,10536,109,59,3,8770,824,105,115,116,4,2,59,115,13503,13505,1,8708,59,1,8708,114,59,3,55349,56619,4,4,69,101,115,116,13523,13527,13563,13568,59,3,8807,824,4,3,59,113,115,13535,13537,13559,1,8817,4,3,59,113,115,13545,13547,13551,1,8817,59,3,8807,824,108,97,110,116,59,3,10878,824,59,3,10878,824,105,109,59,1,8821,4,2,59,114,13574,13576,1,8815,59,1,8815,4,3,65,97,112,13587,13592,13597,114,114,59,1,8654,114,114,59,1,8622,97,114,59,1,10994,4,3,59,115,118,13610,13612,13623,1,8715,4,2,59,100,13618,13620,1,8956,59,1,8954,59,1,8715,99,121,59,1,1114,4,7,65,69,97,100,101,115,116,13647,13652,13656,13661,13665,13737,13742,114,114,59,1,8653,59,3,8806,824,114,114,59,1,8602,114,59,1,8229,4,4,59,102,113,115,13675,13677,13703,13725,1,8816,116,4,2,97,114,13684,13691,114,114,111,119,59,1,8602,105,103,104,116,97,114,114,111,119,59,1,8622,4,3,59,113,115,13711,13713,13717,1,8816,59,3,8806,824,108,97,110,116,59,3,10877,824,4,2,59,115,13731,13734,3,10877,824,59,1,8814,105,109,59,1,8820,4,2,59,114,13748,13750,1,8814,105,4,2,59,101,13757,13759,1,8938,59,1,8940,105,100,59,1,8740,4,2,112,116,13773,13778,102,59,3,55349,56671,5,172,3,59,105,110,13787,13789,13829,1,172,110,4,4,59,69,100,118,13800,13802,13806,13812,1,8713,59,3,8953,824,111,116,59,3,8949,824,4,3,97,98,99,13820,13823,13826,59,1,8713,59,1,8951,59,1,8950,105,4,2,59,118,13836,13838,1,8716,4,3,97,98,99,13846,13849,13852,59,1,8716,59,1,8958,59,1,8957,4,3,97,111,114,13863,13892,13899,114,4,4,59,97,115,116,13874,13876,13883,13888,1,8742,108,108,101,108,59,1,8742,108,59,3,11005,8421,59,3,8706,824,108,105,110,116,59,1,10772,4,3,59,99,101,13907,13909,13914,1,8832,117,101,59,1,8928,4,2,59,99,13920,13923,3,10927,824,4,2,59,101,13929,13931,1,8832,113,59,3,10927,824,4,4,65,97,105,116,13946,13951,13971,13982,114,114,59,1,8655,114,114,4,3,59,99,119,13961,13963,13967,1,8603,59,3,10547,824,59,3,8605,824,103,104,116,97,114,114,111,119,59,1,8603,114,105,4,2,59,101,13990,13992,1,8939,59,1,8941,4,7,99,104,105,109,112,113,117,14011,14036,14060,14080,14085,14090,14106,4,4,59,99,101,114,14021,14023,14028,14032,1,8833,117,101,59,1,8929,59,3,10928,824,59,3,55349,56515,111,114,116,4,2,109,112,14045,14050,105,100,59,1,8740,97,114,97,108,108,101,108,59,1,8742,109,4,2,59,101,14067,14069,1,8769,4,2,59,113,14075,14077,1,8772,59,1,8772,105,100,59,1,8740,97,114,59,1,8742,115,117,4,2,98,112,14098,14102,101,59,1,8930,101,59,1,8931,4,3,98,99,112,14114,14157,14171,4,4,59,69,101,115,14124,14126,14130,14133,1,8836,59,3,10949,824,59,1,8840,101,116,4,2,59,101,14141,14144,3,8834,8402,113,4,2,59,113,14151,14153,1,8840,59,3,10949,824,99,4,2,59,101,14164,14166,1,8833,113,59,3,10928,824,4,4,59,69,101,115,14181,14183,14187,14190,1,8837,59,3,10950,824,59,1,8841,101,116,4,2,59,101,14198,14201,3,8835,8402,113,4,2,59,113,14208,14210,1,8841,59,3,10950,824,4,4,103,105,108,114,14224,14228,14238,14242,108,59,1,8825,108,100,101,5,241,1,59,14236,1,241,103,59,1,8824,105,97,110,103,108,101,4,2,108,114,14254,14269,101,102,116,4,2,59,101,14263,14265,1,8938,113,59,1,8940,105,103,104,116,4,2,59,101,14279,14281,1,8939,113,59,1,8941,4,2,59,109,14291,14293,1,957,4,3,59,101,115,14301,14303,14308,1,35,114,111,59,1,8470,112,59,1,8199,4,9,68,72,97,100,103,105,108,114,115,14332,14338,14344,14349,14355,14369,14376,14408,14426,97,115,104,59,1,8877,97,114,114,59,1,10500,112,59,3,8781,8402,97,115,104,59,1,8876,4,2,101,116,14361,14365,59,3,8805,8402,59,3,62,8402,110,102,105,110,59,1,10718,4,3,65,101,116,14384,14389,14393,114,114,59,1,10498,59,3,8804,8402,4,2,59,114,14399,14402,3,60,8402,105,101,59,3,8884,8402,4,2,65,116,14414,14419,114,114,59,1,10499,114,105,101,59,3,8885,8402,105,109,59,3,8764,8402,4,3,65,97,110,14440,14445,14468,114,114,59,1,8662,114,4,2,104,114,14452,14456,107,59,1,10531,4,2,59,111,14462,14464,1,8598,119,59,1,8598,101,97,114,59,1,10535,4,18,83,97,99,100,101,102,103,104,105,108,109,111,112,114,115,116,117,118,14512,14515,14535,14560,14597,14603,14618,14643,14657,14662,14701,14741,14747,14769,14851,14877,14907,14916,59,1,9416,4,2,99,115,14521,14531,117,116,101,5,243,1,59,14529,1,243,116,59,1,8859,4,2,105,121,14541,14557,114,4,2,59,99,14548,14550,1,8858,5,244,1,59,14555,1,244,59,1,1086,4,5,97,98,105,111,115,14572,14577,14583,14587,14591,115,104,59,1,8861,108,97,99,59,1,337,118,59,1,10808,116,59,1,8857,111,108,100,59,1,10684,108,105,103,59,1,339,4,2,99,114,14609,14614,105,114,59,1,10687,59,3,55349,56620,4,3,111,114,116,14626,14630,14640,110,59,1,731,97,118,101,5,242,1,59,14638,1,242,59,1,10689,4,2,98,109,14649,14654,97,114,59,1,10677,59,1,937,110,116,59,1,8750,4,4,97,99,105,116,14672,14677,14693,14698,114,114,59,1,8634,4,2,105,114,14683,14687,114,59,1,10686,111,115,115,59,1,10683,110,101,59,1,8254,59,1,10688,4,3,97,101,105,14709,14714,14719,99,114,59,1,333,103,97,59,1,969,4,3,99,100,110,14727,14733,14736,114,111,110,59,1,959,59,1,10678,117,115,59,1,8854,112,102,59,3,55349,56672,4,3,97,101,108,14755,14759,14764,114,59,1,10679,114,112,59,1,10681,117,115,59,1,8853,4,7,59,97,100,105,111,115,118,14785,14787,14792,14831,14837,14841,14848,1,8744,114,114,59,1,8635,4,4,59,101,102,109,14802,14804,14817,14824,1,10845,114,4,2,59,111,14811,14813,1,8500,102,59,1,8500,5,170,1,59,14822,1,170,5,186,1,59,14829,1,186,103,111,102,59,1,8886,114,59,1,10838,108,111,112,101,59,1,10839,59,1,10843,4,3,99,108,111,14859,14863,14873,114,59,1,8500,97,115,104,5,248,1,59,14871,1,248,108,59,1,8856,105,4,2,108,109,14884,14893,100,101,5,245,1,59,14891,1,245,101,115,4,2,59,97,14901,14903,1,8855,115,59,1,10806,109,108,5,246,1,59,14914,1,246,98,97,114,59,1,9021,4,12,97,99,101,102,104,105,108,109,111,114,115,117,14948,14992,14996,15033,15038,15068,15090,15189,15192,15222,15427,15441,114,4,4,59,97,115,116,14959,14961,14976,14989,1,8741,5,182,2,59,108,14968,14970,1,182,108,101,108,59,1,8741,4,2,105,108,14982,14986,109,59,1,10995,59,1,11005,59,1,8706,121,59,1,1087,114,4,5,99,105,109,112,116,15009,15014,15019,15024,15027,110,116,59,1,37,111,100,59,1,46,105,108,59,1,8240,59,1,8869,101,110,107,59,1,8241,114,59,3,55349,56621,4,3,105,109,111,15046,15057,15063,4,2,59,118,15052,15054,1,966,59,1,981,109,97,116,59,1,8499,110,101,59,1,9742,4,3,59,116,118,15076,15078,15087,1,960,99,104,102,111,114,107,59,1,8916,59,1,982,4,2,97,117,15096,15119,110,4,2,99,107,15103,15115,107,4,2,59,104,15110,15112,1,8463,59,1,8462,118,59,1,8463,115,4,9,59,97,98,99,100,101,109,115,116,15140,15142,15148,15151,15156,15168,15171,15179,15184,1,43,99,105,114,59,1,10787,59,1,8862,105,114,59,1,10786,4,2,111,117,15162,15165,59,1,8724,59,1,10789,59,1,10866,110,5,177,1,59,15177,1,177,105,109,59,1,10790,119,111,59,1,10791,59,1,177,4,3,105,112,117,15200,15208,15213,110,116,105,110,116,59,1,10773,102,59,3,55349,56673,110,100,5,163,1,59,15220,1,163,4,10,59,69,97,99,101,105,110,111,115,117,15244,15246,15249,15253,15258,15334,15347,15367,15416,15421,1,8826,59,1,10931,112,59,1,10935,117,101,59,1,8828,4,2,59,99,15264,15266,1,10927,4,6,59,97,99,101,110,115,15280,15282,15290,15299,15303,15329,1,8826,112,112,114,111,120,59,1,10935,117,114,108,121,101,113,59,1,8828,113,59,1,10927,4,3,97,101,115,15311,15319,15324,112,112,114,111,120,59,1,10937,113,113,59,1,10933,105,109,59,1,8936,105,109,59,1,8830,109,101,4,2,59,115,15342,15344,1,8242,59,1,8473,4,3,69,97,115,15355,15358,15362,59,1,10933,112,59,1,10937,105,109,59,1,8936,4,3,100,102,112,15375,15378,15404,59,1,8719,4,3,97,108,115,15386,15392,15398,108,97,114,59,1,9006,105,110,101,59,1,8978,117,114,102,59,1,8979,4,2,59,116,15410,15412,1,8733,111,59,1,8733,105,109,59,1,8830,114,101,108,59,1,8880,4,2,99,105,15433,15438,114,59,3,55349,56517,59,1,968,110,99,115,112,59,1,8200,4,6,102,105,111,112,115,117,15462,15467,15472,15478,15485,15491,114,59,3,55349,56622,110,116,59,1,10764,112,102,59,3,55349,56674,114,105,109,101,59,1,8279,99,114,59,3,55349,56518,4,3,97,101,111,15499,15520,15534,116,4,2,101,105,15506,15515,114,110,105,111,110,115,59,1,8461,110,116,59,1,10774,115,116,4,2,59,101,15528,15530,1,63,113,59,1,8799,116,5,34,1,59,15540,1,34,4,21,65,66,72,97,98,99,100,101,102,104,105,108,109,110,111,112,114,115,116,117,120,15586,15609,15615,15620,15796,15855,15893,15931,15977,16001,16039,16183,16204,16222,16228,16285,16312,16318,16363,16408,16416,4,3,97,114,116,15594,15599,15603,114,114,59,1,8667,114,59,1,8658,97,105,108,59,1,10524,97,114,114,59,1,10511,97,114,59,1,10596,4,7,99,100,101,110,113,114,116,15636,15651,15656,15664,15687,15696,15770,4,2,101,117,15642,15646,59,3,8765,817,116,101,59,1,341,105,99,59,1,8730,109,112,116,121,118,59,1,10675,103,4,4,59,100,101,108,15675,15677,15680,15683,1,10217,59,1,10642,59,1,10661,101,59,1,10217,117,111,5,187,1,59,15694,1,187,114,4,11,59,97,98,99,102,104,108,112,115,116,119,15721,15723,15727,15739,15742,15746,15750,15754,15758,15763,15767,1,8594,112,59,1,10613,4,2,59,102,15733,15735,1,8677,115,59,1,10528,59,1,10547,115,59,1,10526,107,59,1,8618,112,59,1,8620,108,59,1,10565,105,109,59,1,10612,108,59,1,8611,59,1,8605,4,2,97,105,15776,15781,105,108,59,1,10522,111,4,2,59,110,15788,15790,1,8758,97,108,115,59,1,8474,4,3,97,98,114,15804,15809,15814,114,114,59,1,10509,114,107,59,1,10099,4,2,97,107,15820,15833,99,4,2,101,107,15827,15830,59,1,125,59,1,93,4,2,101,115,15839,15842,59,1,10636,108,4,2,100,117,15849,15852,59,1,10638,59,1,10640,4,4,97,101,117,121,15865,15871,15886,15890,114,111,110,59,1,345,4,2,100,105,15877,15882,105,108,59,1,343,108,59,1,8969,98,59,1,125,59,1,1088,4,4,99,108,113,115,15903,15907,15914,15927,97,59,1,10551,100,104,97,114,59,1,10601,117,111,4,2,59,114,15922,15924,1,8221,59,1,8221,104,59,1,8627,4,3,97,99,103,15939,15966,15970,108,4,4,59,105,112,115,15950,15952,15957,15963,1,8476,110,101,59,1,8475,97,114,116,59,1,8476,59,1,8477,116,59,1,9645,5,174,1,59,15975,1,174,4,3,105,108,114,15985,15991,15997,115,104,116,59,1,10621,111,111,114,59,1,8971,59,3,55349,56623,4,2,97,111,16007,16028,114,4,2,100,117,16014,16017,59,1,8641,4,2,59,108,16023,16025,1,8640,59,1,10604,4,2,59,118,16034,16036,1,961,59,1,1009,4,3,103,110,115,16047,16167,16171,104,116,4,6,97,104,108,114,115,116,16063,16081,16103,16130,16143,16155,114,114,111,119,4,2,59,116,16073,16075,1,8594,97,105,108,59,1,8611,97,114,112,111,111,110,4,2,100,117,16093,16099,111,119,110,59,1,8641,112,59,1,8640,101,102,116,4,2,97,104,16112,16120,114,114,111,119,115,59,1,8644,97,114,112,111,111,110,115,59,1,8652,105,103,104,116,97,114,114,111,119,115,59,1,8649,113,117,105,103,97,114,114,111,119,59,1,8605,104,114,101,101,116,105,109,101,115,59,1,8908,103,59,1,730,105,110,103,100,111,116,115,101,113,59,1,8787,4,3,97,104,109,16191,16196,16201,114,114,59,1,8644,97,114,59,1,8652,59,1,8207,111,117,115,116,4,2,59,97,16214,16216,1,9137,99,104,101,59,1,9137,109,105,100,59,1,10990,4,4,97,98,112,116,16238,16252,16257,16278,4,2,110,114,16244,16248,103,59,1,10221,114,59,1,8702,114,107,59,1,10215,4,3,97,102,108,16265,16269,16273,114,59,1,10630,59,3,55349,56675,117,115,59,1,10798,105,109,101,115,59,1,10805,4,2,97,112,16291,16304,114,4,2,59,103,16298,16300,1,41,116,59,1,10644,111,108,105,110,116,59,1,10770,97,114,114,59,1,8649,4,4,97,99,104,113,16328,16334,16339,16342,113,117,111,59,1,8250,114,59,3,55349,56519,59,1,8625,4,2,98,117,16348,16351,59,1,93,111,4,2,59,114,16358,16360,1,8217,59,1,8217,4,3,104,105,114,16371,16377,16383,114,101,101,59,1,8908,109,101,115,59,1,8906,105,4,4,59,101,102,108,16394,16396,16399,16402,1,9657,59,1,8885,59,1,9656,116,114,105,59,1,10702,108,117,104,97,114,59,1,10600,59,1,8478,4,19,97,98,99,100,101,102,104,105,108,109,111,112,113,114,115,116,117,119,122,16459,16466,16472,16572,16590,16672,16687,16746,16844,16850,16924,16963,16988,17115,17121,17154,17206,17614,17656,99,117,116,101,59,1,347,113,117,111,59,1,8218,4,10,59,69,97,99,101,105,110,112,115,121,16494,16496,16499,16513,16518,16531,16536,16556,16564,16569,1,8827,59,1,10932,4,2,112,114,16505,16508,59,1,10936,111,110,59,1,353,117,101,59,1,8829,4,2,59,100,16524,16526,1,10928,105,108,59,1,351,114,99,59,1,349,4,3,69,97,115,16544,16547,16551,59,1,10934,112,59,1,10938,105,109,59,1,8937,111,108,105,110,116,59,1,10771,105,109,59,1,8831,59,1,1089,111,116,4,3,59,98,101,16582,16584,16587,1,8901,59,1,8865,59,1,10854,4,7,65,97,99,109,115,116,120,16606,16611,16634,16642,16646,16652,16668,114,114,59,1,8664,114,4,2,104,114,16618,16622,107,59,1,10533,4,2,59,111,16628,16630,1,8600,119,59,1,8600,116,5,167,1,59,16640,1,167,105,59,1,59,119,97,114,59,1,10537,109,4,2,105,110,16659,16665,110,117,115,59,1,8726,59,1,8726,116,59,1,10038,114,4,2,59,111,16679,16682,3,55349,56624,119,110,59,1,8994,4,4,97,99,111,121,16697,16702,16716,16739,114,112,59,1,9839,4,2,104,121,16708,16713,99,121,59,1,1097,59,1,1096,114,116,4,2,109,112,16724,16729,105,100,59,1,8739,97,114,97,108,108,101,108,59,1,8741,5,173,1,59,16744,1,173,4,2,103,109,16752,16770,109,97,4,3,59,102,118,16762,16764,16767,1,963,59,1,962,59,1,962,4,8,59,100,101,103,108,110,112,114,16788,16790,16795,16806,16817,16828,16832,16838,1,8764,111,116,59,1,10858,4,2,59,113,16801,16803,1,8771,59,1,8771,4,2,59,69,16812,16814,1,10910,59,1,10912,4,2,59,69,16823,16825,1,10909,59,1,10911,101,59,1,8774,108,117,115,59,1,10788,97,114,114,59,1,10610,97,114,114,59,1,8592,4,4,97,101,105,116,16860,16883,16891,16904,4,2,108,115,16866,16878,108,115,101,116,109,105,110,117,115,59,1,8726,104,112,59,1,10803,112,97,114,115,108,59,1,10724,4,2,100,108,16897,16900,59,1,8739,101,59,1,8995,4,2,59,101,16910,16912,1,10922,4,2,59,115,16918,16920,1,10924,59,3,10924,65024,4,3,102,108,112,16932,16938,16958,116,99,121,59,1,1100,4,2,59,98,16944,16946,1,47,4,2,59,97,16952,16954,1,10692,114,59,1,9023,102,59,3,55349,56676,97,4,2,100,114,16970,16985,101,115,4,2,59,117,16978,16980,1,9824,105,116,59,1,9824,59,1,8741,4,3,99,115,117,16996,17028,17089,4,2,97,117,17002,17015,112,4,2,59,115,17009,17011,1,8851,59,3,8851,65024,112,4,2,59,115,17022,17024,1,8852,59,3,8852,65024,117,4,2,98,112,17035,17062,4,3,59,101,115,17043,17045,17048,1,8847,59,1,8849,101,116,4,2,59,101,17056,17058,1,8847,113,59,1,8849,4,3,59,101,115,17070,17072,17075,1,8848,59,1,8850,101,116,4,2,59,101,17083,17085,1,8848,113,59,1,8850,4,3,59,97,102,17097,17099,17112,1,9633,114,4,2,101,102,17106,17109,59,1,9633,59,1,9642,59,1,9642,97,114,114,59,1,8594,4,4,99,101,109,116,17131,17136,17142,17148,114,59,3,55349,56520,116,109,110,59,1,8726,105,108,101,59,1,8995,97,114,102,59,1,8902,4,2,97,114,17160,17172,114,4,2,59,102,17167,17169,1,9734,59,1,9733,4,2,97,110,17178,17202,105,103,104,116,4,2,101,112,17188,17197,112,115,105,108,111,110,59,1,1013,104,105,59,1,981,115,59,1,175,4,5,98,99,109,110,112,17218,17351,17420,17423,17427,4,9,59,69,100,101,109,110,112,114,115,17238,17240,17243,17248,17261,17267,17279,17285,17291,1,8834,59,1,10949,111,116,59,1,10941,4,2,59,100,17254,17256,1,8838,111,116,59,1,10947,117,108,116,59,1,10945,4,2,69,101,17273,17276,59,1,10955,59,1,8842,108,117,115,59,1,10943,97,114,114,59,1,10617,4,3,101,105,117,17299,17335,17339,116,4,3,59,101,110,17308,17310,17322,1,8834,113,4,2,59,113,17317,17319,1,8838,59,1,10949,101,113,4,2,59,113,17330,17332,1,8842,59,1,10955,109,59,1,10951,4,2,98,112,17345,17348,59,1,10965,59,1,10963,99,4,6,59,97,99,101,110,115,17366,17368,17376,17385,17389,17415,1,8827,112,112,114,111,120,59,1,10936,117,114,108,121,101,113,59,1,8829,113,59,1,10928,4,3,97,101,115,17397,17405,17410,112,112,114,111,120,59,1,10938,113,113,59,1,10934,105,109,59,1,8937,105,109,59,1,8831,59,1,8721,103,59,1,9834,4,13,49,50,51,59,69,100,101,104,108,109,110,112,115,17455,17462,17469,17476,17478,17481,17496,17509,17524,17530,17536,17548,17554,5,185,1,59,17460,1,185,5,178,1,59,17467,1,178,5,179,1,59,17474,1,179,1,8835,59,1,10950,4,2,111,115,17487,17491,116,59,1,10942,117,98,59,1,10968,4,2,59,100,17502,17504,1,8839,111,116,59,1,10948,115,4,2,111,117,17516,17520,108,59,1,10185,98,59,1,10967,97,114,114,59,1,10619,117,108,116,59,1,10946,4,2,69,101,17542,17545,59,1,10956,59,1,8843,108,117,115,59,1,10944,4,3,101,105,117,17562,17598,17602,116,4,3,59,101,110,17571,17573,17585,1,8835,113,4,2,59,113,17580,17582,1,8839,59,1,10950,101,113,4,2,59,113,17593,17595,1,8843,59,1,10956,109,59,1,10952,4,2,98,112,17608,17611,59,1,10964,59,1,10966,4,3,65,97,110,17622,17627,17650,114,114,59,1,8665,114,4,2,104,114,17634,17638,107,59,1,10534,4,2,59,111,17644,17646,1,8601,119,59,1,8601,119,97,114,59,1,10538,108,105,103,5,223,1,59,17664,1,223,4,13,97,98,99,100,101,102,104,105,111,112,114,115,119,17694,17709,17714,17737,17742,17749,17754,17860,17905,17957,17964,18090,18122,4,2,114,117,17700,17706,103,101,116,59,1,8982,59,1,964,114,107,59,1,9140,4,3,97,101,121,17722,17728,17734,114,111,110,59,1,357,100,105,108,59,1,355,59,1,1090,111,116,59,1,8411,108,114,101,99,59,1,8981,114,59,3,55349,56625,4,4,101,105,107,111,17764,17805,17836,17851,4,2,114,116,17770,17786,101,4,2,52,102,17777,17780,59,1,8756,111,114,101,59,1,8756,97,4,3,59,115,118,17795,17797,17802,1,952,121,109,59,1,977,59,1,977,4,2,99,110,17811,17831,107,4,2,97,115,17818,17826,112,112,114,111,120,59,1,8776,105,109,59,1,8764,115,112,59,1,8201,4,2,97,115,17842,17846,112,59,1,8776,105,109,59,1,8764,114,110,5,254,1,59,17858,1,254,4,3,108,109,110,17868,17873,17901,100,101,59,1,732,101,115,5,215,3,59,98,100,17884,17886,17898,1,215,4,2,59,97,17892,17894,1,8864,114,59,1,10801,59,1,10800,116,59,1,8749,4,3,101,112,115,17913,17917,17953,97,59,1,10536,4,4,59,98,99,102,17927,17929,17934,17939,1,8868,111,116,59,1,9014,105,114,59,1,10993,4,2,59,111,17945,17948,3,55349,56677,114,107,59,1,10970,97,59,1,10537,114,105,109,101,59,1,8244,4,3,97,105,112,17972,17977,18082,100,101,59,1,8482,4,7,97,100,101,109,112,115,116,17993,18051,18056,18059,18066,18072,18076,110,103,108,101,4,5,59,100,108,113,114,18009,18011,18017,18032,18035,1,9653,111,119,110,59,1,9663,101,102,116,4,2,59,101,18026,18028,1,9667,113,59,1,8884,59,1,8796,105,103,104,116,4,2,59,101,18045,18047,1,9657,113,59,1,8885,111,116,59,1,9708,59,1,8796,105,110,117,115,59,1,10810,108,117,115,59,1,10809,98,59,1,10701,105,109,101,59,1,10811,101,122,105,117,109,59,1,9186,4,3,99,104,116,18098,18111,18116,4,2,114,121,18104,18108,59,3,55349,56521,59,1,1094,99,121,59,1,1115,114,111,107,59,1,359,4,2,105,111,18128,18133,120,116,59,1,8812,104,101,97,100,4,2,108,114,18143,18154,101,102,116,97,114,114,111,119,59,1,8606,105,103,104,116,97,114,114,111,119,59,1,8608,4,18,65,72,97,98,99,100,102,103,104,108,109,111,112,114,115,116,117,119,18204,18209,18214,18234,18250,18268,18292,18308,18319,18343,18379,18397,18413,18504,18547,18553,18584,18603,114,114,59,1,8657,97,114,59,1,10595,4,2,99,114,18220,18230,117,116,101,5,250,1,59,18228,1,250,114,59,1,8593,114,4,2,99,101,18241,18245,121,59,1,1118,118,101,59,1,365,4,2,105,121,18256,18265,114,99,5,251,1,59,18263,1,251,59,1,1091,4,3,97,98,104,18276,18281,18287,114,114,59,1,8645,108,97,99,59,1,369,97,114,59,1,10606,4,2,105,114,18298,18304,115,104,116,59,1,10622,59,3,55349,56626,114,97,118,101,5,249,1,59,18317,1,249,4,2,97,98,18325,18338,114,4,2,108,114,18332,18335,59,1,8639,59,1,8638,108,107,59,1,9600,4,2,99,116,18349,18374,4,2,111,114,18355,18369,114,110,4,2,59,101,18363,18365,1,8988,114,59,1,8988,111,112,59,1,8975,114,105,59,1,9720,4,2,97,108,18385,18390,99,114,59,1,363,5,168,1,59,18395,1,168,4,2,103,112,18403,18408,111,110,59,1,371,102,59,3,55349,56678,4,6,97,100,104,108,115,117,18427,18434,18445,18470,18475,18494,114,114,111,119,59,1,8593,111,119,110,97,114,114,111,119,59,1,8597,97,114,112,111,111,110,4,2,108,114,18457,18463,101,102,116,59,1,8639,105,103,104,116,59,1,8638,117,115,59,1,8846,105,4,3,59,104,108,18484,18486,18489,1,965,59,1,978,111,110,59,1,965,112,97,114,114,111,119,115,59,1,8648,4,3,99,105,116,18512,18537,18542,4,2,111,114,18518,18532,114,110,4,2,59,101,18526,18528,1,8989,114,59,1,8989,111,112,59,1,8974,110,103,59,1,367,114,105,59,1,9721,99,114,59,3,55349,56522,4,3,100,105,114,18561,18566,18572,111,116,59,1,8944,108,100,101,59,1,361,105,4,2,59,102,18579,18581,1,9653,59,1,9652,4,2,97,109,18590,18595,114,114,59,1,8648,108,5,252,1,59,18601,1,252,97,110,103,108,101,59,1,10663,4,15,65,66,68,97,99,100,101,102,108,110,111,112,114,115,122,18643,18648,18661,18667,18847,18851,18857,18904,18909,18915,18931,18937,18943,18949,18996,114,114,59,1,8661,97,114,4,2,59,118,18656,18658,1,10984,59,1,10985,97,115,104,59,1,8872,4,2,110,114,18673,18679,103,114,116,59,1,10652,4,7,101,107,110,112,114,115,116,18695,18704,18711,18720,18742,18754,18810,112,115,105,108,111,110,59,1,1013,97,112,112,97,59,1,1008,111,116,104,105,110,103,59,1,8709,4,3,104,105,114,18728,18732,18735,105,59,1,981,59,1,982,111,112,116,111,59,1,8733,4,2,59,104,18748,18750,1,8597,111,59,1,1009,4,2,105,117,18760,18766,103,109,97,59,1,962,4,2,98,112,18772,18791,115,101,116,110,101,113,4,2,59,113,18784,18787,3,8842,65024,59,3,10955,65024,115,101,116,110,101,113,4,2,59,113,18803,18806,3,8843,65024,59,3,10956,65024,4,2,104,114,18816,18822,101,116,97,59,1,977,105,97,110,103,108,101,4,2,108,114,18834,18840,101,102,116,59,1,8882,105,103,104,116,59,1,8883,121,59,1,1074,97,115,104,59,1,8866,4,3,101,108,114,18865,18884,18890,4,3,59,98,101,18873,18875,18880,1,8744,97,114,59,1,8891,113,59,1,8794,108,105,112,59,1,8942,4,2,98,116,18896,18901,97,114,59,1,124,59,1,124,114,59,3,55349,56627,116,114,105,59,1,8882,115,117,4,2,98,112,18923,18927,59,3,8834,8402,59,3,8835,8402,112,102,59,3,55349,56679,114,111,112,59,1,8733,116,114,105,59,1,8883,4,2,99,117,18955,18960,114,59,3,55349,56523,4,2,98,112,18966,18981,110,4,2,69,101,18973,18977,59,3,10955,65024,59,3,8842,65024,110,4,2,69,101,18988,18992,59,3,10956,65024,59,3,8843,65024,105,103,122,97,103,59,1,10650,4,7,99,101,102,111,112,114,115,19020,19026,19061,19066,19072,19075,19089,105,114,99,59,1,373,4,2,100,105,19032,19055,4,2,98,103,19038,19043,97,114,59,1,10847,101,4,2,59,113,19050,19052,1,8743,59,1,8793,101,114,112,59,1,8472,114,59,3,55349,56628,112,102,59,3,55349,56680,59,1,8472,4,2,59,101,19081,19083,1,8768,97,116,104,59,1,8768,99,114,59,3,55349,56524,4,14,99,100,102,104,105,108,109,110,111,114,115,117,118,119,19125,19146,19152,19157,19173,19176,19192,19197,19202,19236,19252,19269,19286,19291,4,3,97,105,117,19133,19137,19142,112,59,1,8898,114,99,59,1,9711,112,59,1,8899,116,114,105,59,1,9661,114,59,3,55349,56629,4,2,65,97,19163,19168,114,114,59,1,10234,114,114,59,1,10231,59,1,958,4,2,65,97,19182,19187,114,114,59,1,10232,114,114,59,1,10229,97,112,59,1,10236,105,115,59,1,8955,4,3,100,112,116,19210,19215,19230,111,116,59,1,10752,4,2,102,108,19221,19225,59,3,55349,56681,117,115,59,1,10753,105,109,101,59,1,10754,4,2,65,97,19242,19247,114,114,59,1,10233,114,114,59,1,10230,4,2,99,113,19258,19263,114,59,3,55349,56525,99,117,112,59,1,10758,4,2,112,116,19275,19281,108,117,115,59,1,10756,114,105,59,1,9651,101,101,59,1,8897,101,100,103,101,59,1,8896,4,8,97,99,101,102,105,111,115,117,19316,19335,19349,19357,19362,19367,19373,19379,99,4,2,117,121,19323,19332,116,101,5,253,1,59,19330,1,253,59,1,1103,4,2,105,121,19341,19346,114,99,59,1,375,59,1,1099,110,5,165,1,59,19355,1,165,114,59,3,55349,56630,99,121,59,1,1111,112,102,59,3,55349,56682,99,114,59,3,55349,56526,4,2,99,109,19385,19389,121,59,1,1102,108,5,255,1,59,19395,1,255,4,10,97,99,100,101,102,104,105,111,115,119,19419,19426,19441,19446,19462,19467,19472,19480,19486,19492,99,117,116,101,59,1,378,4,2,97,121,19432,19438,114,111,110,59,1,382,59,1,1079,111,116,59,1,380,4,2,101,116,19452,19458,116,114,102,59,1,8488,97,59,1,950,114,59,3,55349,56631,99,121,59,1,1078,103,114,97,114,114,59,1,8669,112,102,59,3,55349,56683,99,114,59,3,55349,56527,4,2,106,110,19498,19501,59,1,8205,106,59,1,8204]); /***/ }), -/* 314 */ +/* 326 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const HTML = __webpack_require__(315); +const HTML = __webpack_require__(327); //Aliases const $ = HTML.TAG_NAMES; @@ -53237,7 +55239,7 @@ module.exports = OpenElementStack; /***/ }), -/* 315 */ +/* 327 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -53516,7 +55518,7 @@ exports.SPECIAL_ELEMENTS = { /***/ }), -/* 316 */ +/* 328 */ /***/ ((module) => { "use strict"; @@ -53704,17 +55706,17 @@ module.exports = FormattingElementList; /***/ }), -/* 317 */ +/* 329 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const Mixin = __webpack_require__(318); -const Tokenizer = __webpack_require__(309); -const LocationInfoTokenizerMixin = __webpack_require__(319); -const LocationInfoOpenElementStackMixin = __webpack_require__(321); -const HTML = __webpack_require__(315); +const Mixin = __webpack_require__(330); +const Tokenizer = __webpack_require__(321); +const LocationInfoTokenizerMixin = __webpack_require__(331); +const LocationInfoOpenElementStackMixin = __webpack_require__(333); +const HTML = __webpack_require__(327); //Aliases const $ = HTML.TAG_NAMES; @@ -53934,7 +55936,7 @@ module.exports = LocationInfoParserMixin; /***/ }), -/* 318 */ +/* 330 */ /***/ ((module) => { "use strict"; @@ -53980,15 +55982,15 @@ module.exports = Mixin; /***/ }), -/* 319 */ +/* 331 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const Mixin = __webpack_require__(318); -const Tokenizer = __webpack_require__(309); -const PositionTrackingPreprocessorMixin = __webpack_require__(320); +const Mixin = __webpack_require__(330); +const Tokenizer = __webpack_require__(321); +const PositionTrackingPreprocessorMixin = __webpack_require__(332); class LocationInfoTokenizerMixin extends Mixin { constructor(tokenizer) { @@ -54133,13 +56135,13 @@ module.exports = LocationInfoTokenizerMixin; /***/ }), -/* 320 */ +/* 332 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const Mixin = __webpack_require__(318); +const Mixin = __webpack_require__(330); class PositionTrackingPreprocessorMixin extends Mixin { constructor(preprocessor) { @@ -54204,13 +56206,13 @@ module.exports = PositionTrackingPreprocessorMixin; /***/ }), -/* 321 */ +/* 333 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const Mixin = __webpack_require__(318); +const Mixin = __webpack_require__(330); class LocationInfoOpenElementStackMixin extends Mixin { constructor(stack, opts) { @@ -54246,16 +56248,16 @@ module.exports = LocationInfoOpenElementStackMixin; /***/ }), -/* 322 */ +/* 334 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const ErrorReportingMixinBase = __webpack_require__(323); -const ErrorReportingTokenizerMixin = __webpack_require__(324); -const LocationInfoTokenizerMixin = __webpack_require__(319); -const Mixin = __webpack_require__(318); +const ErrorReportingMixinBase = __webpack_require__(335); +const ErrorReportingTokenizerMixin = __webpack_require__(336); +const LocationInfoTokenizerMixin = __webpack_require__(331); +const Mixin = __webpack_require__(330); class ErrorReportingParserMixin extends ErrorReportingMixinBase { constructor(parser, opts) { @@ -54305,13 +56307,13 @@ module.exports = ErrorReportingParserMixin; /***/ }), -/* 323 */ +/* 335 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const Mixin = __webpack_require__(318); +const Mixin = __webpack_require__(330); class ErrorReportingMixinBase extends Mixin { constructor(host, opts) { @@ -54355,15 +56357,15 @@ module.exports = ErrorReportingMixinBase; /***/ }), -/* 324 */ +/* 336 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const ErrorReportingMixinBase = __webpack_require__(323); -const ErrorReportingPreprocessorMixin = __webpack_require__(325); -const Mixin = __webpack_require__(318); +const ErrorReportingMixinBase = __webpack_require__(335); +const ErrorReportingPreprocessorMixin = __webpack_require__(337); +const Mixin = __webpack_require__(330); class ErrorReportingTokenizerMixin extends ErrorReportingMixinBase { constructor(tokenizer, opts) { @@ -54379,15 +56381,15 @@ module.exports = ErrorReportingTokenizerMixin; /***/ }), -/* 325 */ +/* 337 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const ErrorReportingMixinBase = __webpack_require__(323); -const PositionTrackingPreprocessorMixin = __webpack_require__(320); -const Mixin = __webpack_require__(318); +const ErrorReportingMixinBase = __webpack_require__(335); +const PositionTrackingPreprocessorMixin = __webpack_require__(332); +const Mixin = __webpack_require__(330); class ErrorReportingPreprocessorMixin extends ErrorReportingMixinBase { constructor(preprocessor, opts) { @@ -54410,13 +56412,13 @@ module.exports = ErrorReportingPreprocessorMixin; /***/ }), -/* 326 */ +/* 338 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -const { DOCUMENT_MODE } = __webpack_require__(315); +const { DOCUMENT_MODE } = __webpack_require__(327); //Node construction exports.createDocument = function() { @@ -54638,7 +56640,7 @@ exports.updateNodeSourceCodeLocation = function(node, endLocation) { /***/ }), -/* 327 */ +/* 339 */ /***/ ((module) => { "use strict"; @@ -54658,13 +56660,13 @@ module.exports = function mergeOptions(defaults, options) { /***/ }), -/* 328 */ +/* 340 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -const { DOCUMENT_MODE } = __webpack_require__(315); +const { DOCUMENT_MODE } = __webpack_require__(327); //Const const VALID_DOCTYPE_NAME = 'html'; @@ -54827,14 +56829,14 @@ exports.serializeContent = function(name, publicId, systemId) { /***/ }), -/* 329 */ +/* 341 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -const Tokenizer = __webpack_require__(309); -const HTML = __webpack_require__(315); +const Tokenizer = __webpack_require__(321); +const HTML = __webpack_require__(327); //Aliases const $ = HTML.TAG_NAMES; @@ -55099,16 +57101,16 @@ exports.isIntegrationPoint = function(tn, ns, attrs, foreignNS) { /***/ }), -/* 330 */ +/* 342 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const defaultTreeAdapter = __webpack_require__(326); -const mergeOptions = __webpack_require__(327); -const doctype = __webpack_require__(328); -const HTML = __webpack_require__(315); +const defaultTreeAdapter = __webpack_require__(338); +const mergeOptions = __webpack_require__(339); +const doctype = __webpack_require__(340); +const HTML = __webpack_require__(327); //Aliases const $ = HTML.TAG_NAMES; @@ -55282,14 +57284,14 @@ module.exports = Serializer; /***/ }), -/* 331 */ +/* 343 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -const doctype = __webpack_require__(328); -const { DOCUMENT_MODE } = __webpack_require__(315); +const doctype = __webpack_require__(340); +const { DOCUMENT_MODE } = __webpack_require__(327); //Conversion tables for DOM Level1 structure emulation const nodeTypes = { @@ -55637,7 +57639,7 @@ exports.updateNodeSourceCodeLocation = function(node, endLocation) { /***/ }), -/* 332 */ +/* 344 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; @@ -55647,29 +57649,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.render = exports.parse = void 0; -var htmlparser2_1 = __webpack_require__(302); +var htmlparser2_1 = __webpack_require__(303); Object.defineProperty(exports, "parse", ({ enumerable: true, get: function () { return htmlparser2_1.parseDocument; } })); -var dom_serializer_1 = __webpack_require__(271); +var dom_serializer_1 = __webpack_require__(272); Object.defineProperty(exports, "render", ({ enumerable: true, get: function () { return __importDefault(dom_serializer_1).default; } })); /***/ }), -/* 333 */ +/* 345 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.Cheerio = void 0; -var tslib_1 = __webpack_require__(256); -var parse_1 = tslib_1.__importDefault(__webpack_require__(334)); -var options_1 = tslib_1.__importDefault(__webpack_require__(259)); -var utils_1 = __webpack_require__(335); -var Attributes = tslib_1.__importStar(__webpack_require__(336)); -var Traversing = tslib_1.__importStar(__webpack_require__(337)); -var Manipulation = tslib_1.__importStar(__webpack_require__(338)); -var Css = tslib_1.__importStar(__webpack_require__(339)); -var Forms = tslib_1.__importStar(__webpack_require__(340)); +var tslib_1 = __webpack_require__(257); +var parse_1 = tslib_1.__importDefault(__webpack_require__(346)); +var options_1 = tslib_1.__importDefault(__webpack_require__(260)); +var utils_1 = __webpack_require__(347); +var Attributes = tslib_1.__importStar(__webpack_require__(348)); +var Traversing = tslib_1.__importStar(__webpack_require__(349)); +var Manipulation = tslib_1.__importStar(__webpack_require__(350)); +var Css = tslib_1.__importStar(__webpack_require__(351)); +var Forms = tslib_1.__importStar(__webpack_require__(352)); var Cheerio = /** @class */ (function () { /** * Instance of cheerio. Methods are specified in the modules. Usage of this @@ -55776,17 +57778,17 @@ function isNode(obj) { /***/ }), -/* 334 */ +/* 346 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.update = void 0; -var htmlparser2_1 = __webpack_require__(302); -var htmlparser2_adapter_1 = __webpack_require__(332); -var parse5_adapter_1 = __webpack_require__(306); -var domhandler_1 = __webpack_require__(268); +var htmlparser2_1 = __webpack_require__(303); +var htmlparser2_adapter_1 = __webpack_require__(344); +var parse5_adapter_1 = __webpack_require__(316); +var domhandler_1 = __webpack_require__(317); /* * Parser */ @@ -55850,15 +57852,15 @@ exports.update = update; /***/ }), -/* 335 */ +/* 347 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.isHtml = exports.cloneDom = exports.domEach = exports.cssCase = exports.camelCase = exports.isCheerio = exports.isTag = void 0; -var htmlparser2_1 = __webpack_require__(302); -var domhandler_1 = __webpack_require__(268); +var htmlparser2_1 = __webpack_require__(303); +var domhandler_1 = __webpack_require__(317); /** * Check if the DOM element is a tag. * @@ -55968,7 +57970,7 @@ exports.isHtml = isHtml; /***/ }), -/* 336 */ +/* 348 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; @@ -55980,8 +57982,8 @@ exports.isHtml = isHtml; */ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.toggleClass = exports.removeClass = exports.addClass = exports.hasClass = exports.removeAttr = exports.val = exports.data = exports.prop = exports.attr = void 0; -var static_1 = __webpack_require__(260); -var utils_1 = __webpack_require__(335); +var static_1 = __webpack_require__(261); +var utils_1 = __webpack_require__(347); var hasOwn = Object.prototype.hasOwnProperty; var rspace = /\s+/; var dataAttrPrefix = 'data-'; @@ -56566,7 +58568,7 @@ exports.toggleClass = toggleClass; /***/ }), -/* 337 */ +/* 349 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; @@ -56578,12 +58580,12 @@ exports.toggleClass = toggleClass; */ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.addBack = exports.add = exports.end = exports.slice = exports.index = exports.toArray = exports.get = exports.eq = exports.last = exports.first = exports.has = exports.not = exports.is = exports.filterArray = exports.filter = exports.map = exports.each = exports.contents = exports.children = exports.siblings = exports.prevUntil = exports.prevAll = exports.prev = exports.nextUntil = exports.nextAll = exports.next = exports.closest = exports.parentsUntil = exports.parents = exports.parent = exports.find = void 0; -var tslib_1 = __webpack_require__(256); -var domhandler_1 = __webpack_require__(268); -var select = tslib_1.__importStar(__webpack_require__(261)); -var utils_1 = __webpack_require__(335); -var static_1 = __webpack_require__(260); -var htmlparser2_1 = __webpack_require__(302); +var tslib_1 = __webpack_require__(257); +var domhandler_1 = __webpack_require__(317); +var select = tslib_1.__importStar(__webpack_require__(262)); +var utils_1 = __webpack_require__(347); +var static_1 = __webpack_require__(261); +var htmlparser2_1 = __webpack_require__(303); var uniqueSort = htmlparser2_1.DomUtils.uniqueSort; var reSiblingSelector = /^\s*[~+]/; /** @@ -57245,11327 +59247,7796 @@ exports.first = first; * * ```js * $('#fruits').children().last().text(); - * //=> Pear - * ``` - * - * @returns The last element. - * @see {@link https://api.jquery.com/last/} - */ -function last() { - return this.length > 0 ? this._make(this[this.length - 1]) : this; -} -exports.last = last; -/** - * Reduce the set of matched elements to the one at the specified index. Use - * `.eq(-i)` to count backwards from the last selected element. - * - * @category Traversing - * @example - * - * ```js - * $('li').eq(0).text(); - * //=> Apple - * - * $('li').eq(-1).text(); - * //=> Pear - * ``` - * - * @param i - Index of the element to select. - * @returns The element at the `i`th position. - * @see {@link https://api.jquery.com/eq/} - */ -function eq(i) { - var _a; - i = +i; - // Use the first identity optimization if possible - if (i === 0 && this.length <= 1) - return this; - if (i < 0) - i = this.length + i; - return this._make((_a = this[i]) !== null && _a !== void 0 ? _a : []); -} -exports.eq = eq; -function get(i) { - if (i == null) { - return this.toArray(); - } - return this[i < 0 ? this.length + i : i]; -} -exports.get = get; -/** - * Retrieve all the DOM elements contained in the jQuery set as an array. - * - * @example - * - * ```js - * $('li').toArray(); - * //=> [ {...}, {...}, {...} ] - * ``` - * - * @returns The contained items. - */ -function toArray() { - return Array.prototype.slice.call(this); -} -exports.toArray = toArray; -/** - * Search for a given element from among the matched elements. - * - * @category Traversing - * @example - * - * ```js - * $('.pear').index(); - * //=> 2 $('.orange').index('li'); - * //=> 1 - * $('.apple').index($('#fruit, li')); - * //=> 1 - * ``` - * - * @param selectorOrNeedle - Element to look for. - * @returns The index of the element. - * @see {@link https://api.jquery.com/index/} - */ -function index(selectorOrNeedle) { - var $haystack; - var needle; - if (selectorOrNeedle == null) { - $haystack = this.parent().children(); - needle = this[0]; - } - else if (typeof selectorOrNeedle === 'string') { - $haystack = this._make(selectorOrNeedle); - needle = this[0]; - } - else { - $haystack = this; - needle = utils_1.isCheerio(selectorOrNeedle) - ? selectorOrNeedle[0] - : selectorOrNeedle; - } - return Array.prototype.indexOf.call($haystack, needle); -} -exports.index = index; -/** - * Gets the elements matching the specified range (0-based position). - * - * @category Traversing - * @example - * - * ```js - * $('li').slice(1).eq(0).text(); - * //=> 'Orange' - * - * $('li').slice(1, 2).length; - * //=> 1 - * ``` - * - * @param start - An position at which the elements begin to be selected. If - * negative, it indicates an offset from the end of the set. - * @param end - An position at which the elements stop being selected. If - * negative, it indicates an offset from the end of the set. If omitted, the - * range continues until the end of the set. - * @returns The elements matching the specified range. - * @see {@link https://api.jquery.com/slice/} - */ -function slice(start, end) { - return this._make(Array.prototype.slice.call(this, start, end)); -} -exports.slice = slice; -/** - * End the most recent filtering operation in the current chain and return the - * set of matched elements to its previous state. - * - * @category Traversing - * @example - * - * ```js - * $('li').eq(0).end().length; - * //=> 3 - * ``` - * - * @returns The previous state of the set of matched elements. - * @see {@link https://api.jquery.com/end/} - */ -function end() { - var _a; - return (_a = this.prevObject) !== null && _a !== void 0 ? _a : this._make([]); -} -exports.end = end; -/** - * Add elements to the set of matched elements. - * - * @category Traversing - * @example - * - * ```js - * $('.apple').add('.orange').length; - * //=> 2 - * ``` - * - * @param other - Elements to add. - * @param context - Optionally the context of the new selection. - * @returns The combined set. - * @see {@link https://api.jquery.com/add/} - */ -function add(other, context) { - var selection = this._make(other, context); - var contents = uniqueSort(tslib_1.__spreadArray(tslib_1.__spreadArray([], this.get()), selection.get())); - return this._make(contents); -} -exports.add = add; -/** - * Add the previous set of elements on the stack to the current set, optionally - * filtered by a selector. - * - * @category Traversing - * @example - * - * ```js - * $('li').eq(0).addBack('.orange').length; - * //=> 2 - * ``` - * - * @param selector - Selector for the elements to add. - * @returns The combined set. - * @see {@link https://api.jquery.com/addBack/} - */ -function addBack(selector) { - return this.prevObject - ? this.add(selector ? this.prevObject.filter(selector) : this.prevObject) - : this; -} -exports.addBack = addBack; - - -/***/ }), -/* 338 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.clone = exports.text = exports.toString = exports.html = exports.empty = exports.replaceWith = exports.remove = exports.insertBefore = exports.before = exports.insertAfter = exports.after = exports.wrapAll = exports.unwrap = exports.wrapInner = exports.wrap = exports.prepend = exports.append = exports.prependTo = exports.appendTo = exports._makeDomArray = void 0; -var tslib_1 = __webpack_require__(256); -var domhandler_1 = __webpack_require__(268); -/** - * Methods for modifying the DOM structure. - * - * @module cheerio/manipulation - */ -var domhandler_2 = __webpack_require__(268); -var parse_1 = tslib_1.__importStar(__webpack_require__(334)); -var static_1 = __webpack_require__(260); -var utils_1 = __webpack_require__(335); -var htmlparser2_1 = __webpack_require__(302); -/** - * Create an array of nodes, recursing into arrays and parsing strings if necessary. - * - * @private - * @category Manipulation - * @param elem - Elements to make an array of. - * @param clone - Optionally clone nodes. - * @returns The array of nodes. - */ -function _makeDomArray(elem, clone) { - var _this = this; - if (elem == null) { - return []; - } - if (utils_1.isCheerio(elem)) { - return clone ? utils_1.cloneDom(elem.get()) : elem.get(); - } - if (Array.isArray(elem)) { - return elem.reduce(function (newElems, el) { return newElems.concat(_this._makeDomArray(el, clone)); }, []); - } - if (typeof elem === 'string') { - return parse_1.default(elem, this.options, false).children; - } - return clone ? utils_1.cloneDom([elem]) : [elem]; -} -exports._makeDomArray = _makeDomArray; -function _insert(concatenator) { - return function () { - var _this = this; - var elems = []; - for (var _i = 0; _i < arguments.length; _i++) { - elems[_i] = arguments[_i]; - } - var lastIdx = this.length - 1; - return utils_1.domEach(this, function (el, i) { - if (!domhandler_1.hasChildren(el)) - return; - var domSrc = typeof elems[0] === 'function' - ? elems[0].call(el, i, static_1.html(el.children)) - : elems; - var dom = _this._makeDomArray(domSrc, i < lastIdx); - concatenator(dom, el.children, el); - }); - }; -} -/** - * Modify an array in-place, removing some number of elements and adding new - * elements directly following them. - * - * @private - * @category Manipulation - * @param array - Target array to splice. - * @param spliceIdx - Index at which to begin changing the array. - * @param spliceCount - Number of elements to remove from the array. - * @param newElems - Elements to insert into the array. - * @param parent - The parent of the node. - * @returns The spliced array. - */ -function uniqueSplice(array, spliceIdx, spliceCount, newElems, parent) { - var _a, _b; - var spliceArgs = tslib_1.__spreadArray([ - spliceIdx, - spliceCount - ], newElems); - var prev = array[spliceIdx - 1] || null; - var next = array[spliceIdx + spliceCount] || null; - /* - * Before splicing in new elements, ensure they do not already appear in the - * current array. - */ - for (var idx = 0; idx < newElems.length; ++idx) { - var node = newElems[idx]; - var oldParent = node.parent; - if (oldParent) { - var prevIdx = oldParent.children.indexOf(newElems[idx]); - if (prevIdx > -1) { - oldParent.children.splice(prevIdx, 1); - if (parent === oldParent && spliceIdx > prevIdx) { - spliceArgs[0]--; - } - } - } - node.parent = parent; - if (node.prev) { - node.prev.next = (_a = node.next) !== null && _a !== void 0 ? _a : null; - } - if (node.next) { - node.next.prev = (_b = node.prev) !== null && _b !== void 0 ? _b : null; - } - node.prev = newElems[idx - 1] || prev; - node.next = newElems[idx + 1] || next; - } - if (prev) { - prev.next = newElems[0]; - } - if (next) { - next.prev = newElems[newElems.length - 1]; - } - return array.splice.apply(array, spliceArgs); -} -/** - * Insert every element in the set of matched elements to the end of the target. - * - * @category Manipulation - * @example - * - * ```js - * $('<li class="plum">Plum</li>').appendTo('#fruits'); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="apple">Apple</li> - * // <li class="orange">Orange</li> - * // <li class="pear">Pear</li> - * // <li class="plum">Plum</li> - * // </ul> - * ``` - * - * @param target - Element to append elements to. - * @returns The instance itself. - * @see {@link https://api.jquery.com/appendTo/} - */ -function appendTo(target) { - var appendTarget = utils_1.isCheerio(target) ? target : this._make(target); - appendTarget.append(this); - return this; -} -exports.appendTo = appendTo; -/** - * Insert every element in the set of matched elements to the beginning of the target. - * - * @category Manipulation - * @example - * - * ```js - * $('<li class="plum">Plum</li>').prependTo('#fruits'); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="plum">Plum</li> - * // <li class="apple">Apple</li> - * // <li class="orange">Orange</li> - * // <li class="pear">Pear</li> - * // </ul> - * ``` - * - * @param target - Element to prepend elements to. - * @returns The instance itself. - * @see {@link https://api.jquery.com/prependTo/} - */ -function prependTo(target) { - var prependTarget = utils_1.isCheerio(target) ? target : this._make(target); - prependTarget.prepend(this); - return this; -} -exports.prependTo = prependTo; -/** - * Inserts content as the *last* child of each of the selected elements. - * - * @category Manipulation - * @example - * - * ```js - * $('ul').append('<li class="plum">Plum</li>'); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="apple">Apple</li> - * // <li class="orange">Orange</li> - * // <li class="pear">Pear</li> - * // <li class="plum">Plum</li> - * // </ul> - * ``` - * - * @see {@link https://api.jquery.com/append/} - */ -exports.append = _insert(function (dom, children, parent) { - uniqueSplice(children, children.length, 0, dom, parent); -}); -/** - * Inserts content as the *first* child of each of the selected elements. - * - * @category Manipulation - * @example - * - * ```js - * $('ul').prepend('<li class="plum">Plum</li>'); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="plum">Plum</li> - * // <li class="apple">Apple</li> - * // <li class="orange">Orange</li> - * // <li class="pear">Pear</li> - * // </ul> - * ``` - * - * @see {@link https://api.jquery.com/prepend/} - */ -exports.prepend = _insert(function (dom, children, parent) { - uniqueSplice(children, 0, 0, dom, parent); -}); -function _wrap(insert) { - return function (wrapper) { - var lastIdx = this.length - 1; - var lastParent = this.parents().last(); - for (var i = 0; i < this.length; i++) { - var el = this[i]; - var wrap_1 = typeof wrapper === 'function' - ? wrapper.call(el, i, el) - : typeof wrapper === 'string' && !utils_1.isHtml(wrapper) - ? lastParent.find(wrapper).clone() - : wrapper; - var wrapperDom = this._makeDomArray(wrap_1, i < lastIdx)[0]; - if (!wrapperDom || !htmlparser2_1.DomUtils.hasChildren(wrapperDom)) - continue; - var elInsertLocation = wrapperDom; - /* - * Find the deepest child. Only consider the first tag child of each node - * (ignore text); stop if no children are found. - */ - var j = 0; - while (j < elInsertLocation.children.length) { - var child = elInsertLocation.children[j]; - if (utils_1.isTag(child)) { - elInsertLocation = child; - j = 0; - } - else { - j++; - } - } - insert(el, elInsertLocation, [wrapperDom]); - } - return this; - }; -} -/** - * The .wrap() function can take any string or object that could be passed to - * the $() factory function to specify a DOM structure. This structure may be - * nested several levels deep, but should contain only one inmost element. A - * copy of this structure will be wrapped around each of the elements in the set - * of matched elements. This method returns the original set of elements for - * chaining purposes. - * - * @category Manipulation - * @example - * - * ```js - * const redFruit = $('<div class="red-fruit"></div>'); - * $('.apple').wrap(redFruit); - * - * //=> <ul id="fruits"> - * // <div class="red-fruit"> - * // <li class="apple">Apple</li> - * // </div> - * // <li class="orange">Orange</li> - * // <li class="plum">Plum</li> - * // </ul> - * - * const healthy = $('<div class="healthy"></div>'); - * $('li').wrap(healthy); - * - * //=> <ul id="fruits"> - * // <div class="healthy"> - * // <li class="apple">Apple</li> - * // </div> - * // <div class="healthy"> - * // <li class="orange">Orange</li> - * // </div> - * // <div class="healthy"> - * // <li class="plum">Plum</li> - * // </div> - * // </ul> - * ``` - * - * @param wrapper - The DOM structure to wrap around each element in the selection. - * @see {@link https://api.jquery.com/wrap/} - */ -exports.wrap = _wrap(function (el, elInsertLocation, wrapperDom) { - var parent = el.parent; - if (!parent) - return; - var siblings = parent.children; - var index = siblings.indexOf(el); - parse_1.update([el], elInsertLocation); - /* - * The previous operation removed the current element from the `siblings` - * array, so the `dom` array can be inserted without removing any - * additional elements. - */ - uniqueSplice(siblings, index, 0, wrapperDom, parent); -}); -/** - * The .wrapInner() function can take any string or object that could be passed - * to the $() factory function to specify a DOM structure. This structure may be - * nested several levels deep, but should contain only one inmost element. The - * structure will be wrapped around the content of each of the elements in the - * set of matched elements. - * - * @category Manipulation - * @example - * - * ```js - * const redFruit = $('<div class="red-fruit"></div>'); - * $('.apple').wrapInner(redFruit); - * - * //=> <ul id="fruits"> - * // <li class="apple"> - * // <div class="red-fruit">Apple</div> - * // </li> - * // <li class="orange">Orange</li> - * // <li class="pear">Pear</li> - * // </ul> - * - * const healthy = $('<div class="healthy"></div>'); - * $('li').wrapInner(healthy); - * - * //=> <ul id="fruits"> - * // <li class="apple"> - * // <div class="healthy">Apple</div> - * // </li> - * // <li class="orange"> - * // <div class="healthy">Orange</div> - * // </li> - * // <li class="pear"> - * // <div class="healthy">Pear</div> - * // </li> - * // </ul> - * ``` - * - * @param wrapper - The DOM structure to wrap around the content of each element - * in the selection. - * @returns The instance itself, for chaining. - * @see {@link https://api.jquery.com/wrapInner/} - */ -exports.wrapInner = _wrap(function (el, elInsertLocation, wrapperDom) { - if (!domhandler_1.hasChildren(el)) - return; - parse_1.update(el.children, elInsertLocation); - parse_1.update(wrapperDom, el); -}); -/** - * The .unwrap() function, removes the parents of the set of matched elements - * from the DOM, leaving the matched elements in their place. - * - * @category Manipulation - * @example <caption>without selector</caption> - * - * ```js - * const $ = cheerio.load( - * '<div id=test>\n <div><p>Hello</p></div>\n <div><p>World</p></div>\n</div>' - * ); - * $('#test p').unwrap(); - * - * //=> <div id=test> - * // <p>Hello</p> - * // <p>World</p> - * // </div> - * ``` - * - * @example <caption>with selector</caption> - * - * ```js - * const $ = cheerio.load( - * '<div id=test>\n <p>Hello</p>\n <b><p>World</p></b>\n</div>' - * ); - * $('#test p').unwrap('b'); - * - * //=> <div id=test> - * // <p>Hello</p> - * // <p>World</p> - * // </div> - * ``` - * - * @param selector - A selector to check the parent element against. If an - * element's parent does not match the selector, the element won't be unwrapped. - * @returns The instance itself, for chaining. - * @see {@link https://api.jquery.com/unwrap/} - */ -function unwrap(selector) { - var _this = this; - this.parent(selector) - .not('body') - .each(function (_, el) { - _this._make(el).replaceWith(el.children); - }); - return this; -} -exports.unwrap = unwrap; -/** - * The .wrapAll() function can take any string or object that could be passed to - * the $() function to specify a DOM structure. This structure may be nested - * several levels deep, but should contain only one inmost element. The - * structure will be wrapped around all of the elements in the set of matched - * elements, as a single group. - * - * @category Manipulation - * @example <caption>With markup passed to `wrapAll`</caption> - * - * ```js - * const $ = cheerio.load( - * '<div class="container"><div class="inner">First</div><div class="inner">Second</div></div>' - * ); - * $('.inner').wrapAll("<div class='new'></div>"); - * - * //=> <div class="container"> - * // <div class='new'> - * // <div class="inner">First</div> - * // <div class="inner">Second</div> - * // </div> - * // </div> - * ``` - * - * @example <caption>With an existing cheerio instance</caption> - * - * ```js - * const $ = cheerio.load( - * '<span>Span 1</span><strong>Strong</strong><span>Span 2</span>' - * ); - * const wrap = $('<div><p><em><b></b></em></p></div>'); - * $('span').wrapAll(wrap); - * - * //=> <div> - * // <p> - * // <em> - * // <b> - * // <span>Span 1</span> - * // <span>Span 2</span> - * // </b> - * // </em> - * // </p> - * // </div> - * // <strong>Strong</strong> - * ``` - * - * @param wrapper - The DOM structure to wrap around all matched elements in the - * selection. - * @returns The instance itself. - * @see {@link https://api.jquery.com/wrapAll/} - */ -function wrapAll(wrapper) { - var el = this[0]; - if (el) { - var wrap_2 = this._make(typeof wrapper === 'function' ? wrapper.call(el, 0, el) : wrapper).insertBefore(el); - // If html is given as wrapper, wrap may contain text elements - var elInsertLocation = void 0; - for (var i = 0; i < wrap_2.length; i++) { - if (wrap_2[i].type === 'tag') - elInsertLocation = wrap_2[i]; - } - var j = 0; - /* - * Find the deepest child. Only consider the first tag child of each node - * (ignore text); stop if no children are found. - */ - while (elInsertLocation && j < elInsertLocation.children.length) { - var child = elInsertLocation.children[j]; - if (child.type === 'tag') { - elInsertLocation = child; - j = 0; - } - else { - j++; - } - } - if (elInsertLocation) - this._make(elInsertLocation).append(this); - } - return this; -} -exports.wrapAll = wrapAll; -/* eslint-disable jsdoc/check-param-names*/ -/** - * Insert content next to each element in the set of matched elements. - * - * @category Manipulation - * @example - * - * ```js - * $('.apple').after('<li class="plum">Plum</li>'); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="apple">Apple</li> - * // <li class="plum">Plum</li> - * // <li class="orange">Orange</li> - * // <li class="pear">Pear</li> - * // </ul> - * ``` - * - * @param content - HTML string, DOM element, array of DOM elements or Cheerio - * to insert after each element in the set of matched elements. - * @returns The instance itself. - * @see {@link https://api.jquery.com/after/} - */ -function after() { - var _this = this; - var elems = []; - for (var _i = 0; _i < arguments.length; _i++) { - elems[_i] = arguments[_i]; - } - var lastIdx = this.length - 1; - return utils_1.domEach(this, function (el, i) { - var parent = el.parent; - if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) { - return; - } - var siblings = parent.children; - var index = siblings.indexOf(el); - // If not found, move on - /* istanbul ignore next */ - if (index < 0) - return; - var domSrc = typeof elems[0] === 'function' - ? elems[0].call(el, i, static_1.html(el.children)) - : elems; - var dom = _this._makeDomArray(domSrc, i < lastIdx); - // Add element after `this` element - uniqueSplice(siblings, index + 1, 0, dom, parent); - }); -} -exports.after = after; -/* eslint-enable jsdoc/check-param-names*/ -/** - * Insert every element in the set of matched elements after the target. - * - * @category Manipulation - * @example - * - * ```js - * $('<li class="plum">Plum</li>').insertAfter('.apple'); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="apple">Apple</li> - * // <li class="plum">Plum</li> - * // <li class="orange">Orange</li> - * // <li class="pear">Pear</li> - * // </ul> - * ``` - * - * @param target - Element to insert elements after. - * @returns The set of newly inserted elements. - * @see {@link https://api.jquery.com/insertAfter/} - */ -function insertAfter(target) { - var _this = this; - if (typeof target === 'string') { - target = this._make(target); - } - this.remove(); - var clones = []; - this._makeDomArray(target).forEach(function (el) { - var clonedSelf = _this.clone().toArray(); - var parent = el.parent; - if (!parent) { - return; - } - var siblings = parent.children; - var index = siblings.indexOf(el); - // If not found, move on - /* istanbul ignore next */ - if (index < 0) - return; - // Add cloned `this` element(s) after target element - uniqueSplice(siblings, index + 1, 0, clonedSelf, parent); - clones.push.apply(clones, clonedSelf); - }); - return this._make(clones); -} -exports.insertAfter = insertAfter; -/* eslint-disable jsdoc/check-param-names*/ -/** - * Insert content previous to each element in the set of matched elements. - * - * @category Manipulation - * @example - * - * ```js - * $('.apple').before('<li class="plum">Plum</li>'); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="plum">Plum</li> - * // <li class="apple">Apple</li> - * // <li class="orange">Orange</li> - * // <li class="pear">Pear</li> - * // </ul> - * ``` - * - * @param content - HTML string, DOM element, array of DOM elements or Cheerio - * to insert before each element in the set of matched elements. - * @returns The instance itself. - * @see {@link https://api.jquery.com/before/} - */ -function before() { - var _this = this; - var elems = []; - for (var _i = 0; _i < arguments.length; _i++) { - elems[_i] = arguments[_i]; - } - var lastIdx = this.length - 1; - return utils_1.domEach(this, function (el, i) { - var parent = el.parent; - if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) { - return; - } - var siblings = parent.children; - var index = siblings.indexOf(el); - // If not found, move on - /* istanbul ignore next */ - if (index < 0) - return; - var domSrc = typeof elems[0] === 'function' - ? elems[0].call(el, i, static_1.html(el.children)) - : elems; - var dom = _this._makeDomArray(domSrc, i < lastIdx); - // Add element before `el` element - uniqueSplice(siblings, index, 0, dom, parent); - }); -} -exports.before = before; -/* eslint-enable jsdoc/check-param-names*/ -/** - * Insert every element in the set of matched elements before the target. - * - * @category Manipulation - * @example - * - * ```js - * $('<li class="plum">Plum</li>').insertBefore('.apple'); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="plum">Plum</li> - * // <li class="apple">Apple</li> - * // <li class="orange">Orange</li> - * // <li class="pear">Pear</li> - * // </ul> - * ``` - * - * @param target - Element to insert elements before. - * @returns The set of newly inserted elements. - * @see {@link https://api.jquery.com/insertBefore/} - */ -function insertBefore(target) { - var _this = this; - var targetArr = this._make(target); - this.remove(); - var clones = []; - utils_1.domEach(targetArr, function (el) { - var clonedSelf = _this.clone().toArray(); - var parent = el.parent; - if (!parent) { - return; - } - var siblings = parent.children; - var index = siblings.indexOf(el); - // If not found, move on - /* istanbul ignore next */ - if (index < 0) - return; - // Add cloned `this` element(s) after target element - uniqueSplice(siblings, index, 0, clonedSelf, parent); - clones.push.apply(clones, clonedSelf); - }); - return this._make(clones); -} -exports.insertBefore = insertBefore; -/** - * Removes the set of matched elements from the DOM and all their children. - * `selector` filters the set of matched elements to be removed. - * - * @category Manipulation - * @example - * - * ```js - * $('.pear').remove(); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="apple">Apple</li> - * // <li class="orange">Orange</li> - * // </ul> - * ``` - * - * @param selector - Optional selector for elements to remove. - * @returns The instance itself. - * @see {@link https://api.jquery.com/remove/} - */ -function remove(selector) { - // Filter if we have selector - var elems = selector ? this.filter(selector) : this; - utils_1.domEach(elems, function (el) { - htmlparser2_1.DomUtils.removeElement(el); - el.prev = el.next = el.parent = null; - }); - return this; -} -exports.remove = remove; -/** - * Replaces matched elements with `content`. - * - * @category Manipulation - * @example - * - * ```js - * const plum = $('<li class="plum">Plum</li>'); - * $('.pear').replaceWith(plum); - * $.html(); - * //=> <ul id="fruits"> - * // <li class="apple">Apple</li> - * // <li class="orange">Orange</li> - * // <li class="plum">Plum</li> - * // </ul> - * ``` - * - * @param content - Replacement for matched elements. - * @returns The instance itself. - * @see {@link https://api.jquery.com/replaceWith/} - */ -function replaceWith(content) { - var _this = this; - return utils_1.domEach(this, function (el, i) { - var parent = el.parent; - if (!parent) { - return; - } - var siblings = parent.children; - var cont = typeof content === 'function' ? content.call(el, i, el) : content; - var dom = _this._makeDomArray(cont); - /* - * In the case that `dom` contains nodes that already exist in other - * structures, ensure those nodes are properly removed. - */ - parse_1.update(dom, null); - var index = siblings.indexOf(el); - // Completely remove old element - uniqueSplice(siblings, index, 1, dom, parent); - if (!dom.includes(el)) { - el.parent = el.prev = el.next = null; - } - }); -} -exports.replaceWith = replaceWith; -/** - * Empties an element, removing all its children. - * - * @category Manipulation - * @example - * - * ```js - * $('ul').empty(); - * $.html(); - * //=> <ul id="fruits"></ul> - * ``` - * - * @returns The instance itself. - * @see {@link https://api.jquery.com/empty/} - */ -function empty() { - return utils_1.domEach(this, function (el) { - if (!htmlparser2_1.DomUtils.hasChildren(el)) - return; - el.children.forEach(function (child) { - child.next = child.prev = child.parent = null; - }); - el.children.length = 0; - }); -} -exports.empty = empty; -function html(str) { - if (str === undefined) { - var el = this[0]; - if (!el || !htmlparser2_1.DomUtils.hasChildren(el)) - return null; - return static_1.html(el.children, this.options); - } - // Keep main options unchanged - var opts = tslib_1.__assign(tslib_1.__assign({}, this.options), { context: null }); - return utils_1.domEach(this, function (el) { - if (!htmlparser2_1.DomUtils.hasChildren(el)) - return; - el.children.forEach(function (child) { - child.next = child.prev = child.parent = null; - }); - opts.context = el; - var content = utils_1.isCheerio(str) - ? str.toArray() - : parse_1.default("" + str, opts, false).children; - parse_1.update(content, el); - }); -} -exports.html = html; -/** - * Turns the collection to a string. Alias for `.html()`. - * - * @category Manipulation - * @returns The rendered document. - */ -function toString() { - return static_1.html(this, this.options); -} -exports.toString = toString; -function text(str) { - var _this = this; - // If `str` is undefined, act as a "getter" - if (str === undefined) { - return static_1.text(this); - } - if (typeof str === 'function') { - // Function support - return utils_1.domEach(this, function (el, i) { - text.call(_this._make(el), str.call(el, i, static_1.text([el]))); - }); - } - // Append text node to each selected elements - return utils_1.domEach(this, function (el) { - if (!htmlparser2_1.DomUtils.hasChildren(el)) - return; - el.children.forEach(function (child) { - child.next = child.prev = child.parent = null; - }); - var textNode = new domhandler_2.Text(str); - parse_1.update(textNode, el); - }); -} -exports.text = text; -/** - * Clone the cheerio object. - * - * @category Manipulation - * @example - * - * ```js - * const moreFruit = $('#fruits').clone(); - * ``` - * - * @returns The cloned object. - * @see {@link https://api.jquery.com/clone/} - */ -function clone() { - return this._make(utils_1.cloneDom(this.get())); -} -exports.clone = clone; - - -/***/ }), -/* 339 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.css = void 0; -var utils_1 = __webpack_require__(335); -function css(prop, val) { - if ((prop != null && val != null) || - // When `prop` is a "plain" object - (typeof prop === 'object' && !Array.isArray(prop))) { - return utils_1.domEach(this, function (el, i) { - if (utils_1.isTag(el)) { - // `prop` can't be an array here anymore. - setCss(el, prop, val, i); - } - }); - } - return getCss(this[0], prop); -} -exports.css = css; -/** - * Set styles of all elements. - * - * @private - * @param el - Element to set style of. - * @param prop - Name of property. - * @param value - Value to set property to. - * @param idx - Optional index within the selection. - */ -function setCss(el, prop, value, idx) { - if (typeof prop === 'string') { - var styles = getCss(el); - var val = typeof value === 'function' ? value.call(el, idx, styles[prop]) : value; - if (val === '') { - delete styles[prop]; - } - else if (val != null) { - styles[prop] = val; - } - el.attribs.style = stringify(styles); - } - else if (typeof prop === 'object') { - Object.keys(prop).forEach(function (k, i) { - setCss(el, k, prop[k], i); - }); - } -} -function getCss(el, prop) { - if (!el || !utils_1.isTag(el)) - return; - var styles = parse(el.attribs.style); - if (typeof prop === 'string') { - return styles[prop]; - } - if (Array.isArray(prop)) { - var newStyles_1 = {}; - prop.forEach(function (item) { - if (styles[item] != null) { - newStyles_1[item] = styles[item]; - } - }); - return newStyles_1; - } - return styles; -} -/** - * Stringify `obj` to styles. - * - * @private - * @category CSS - * @param obj - Object to stringify. - * @returns The serialized styles. - */ -function stringify(obj) { - return Object.keys(obj).reduce(function (str, prop) { return "" + str + (str ? ' ' : '') + prop + ": " + obj[prop] + ";"; }, ''); -} -/** - * Parse `styles`. - * - * @private - * @category CSS - * @param styles - Styles to be parsed. - * @returns The parsed styles. - */ -function parse(styles) { - styles = (styles || '').trim(); - if (!styles) - return {}; - return styles.split(';').reduce(function (obj, str) { - var n = str.indexOf(':'); - // Skip if there is no :, or if it is the first/last character - if (n < 1 || n === str.length - 1) - return obj; - obj[str.slice(0, n).trim()] = str.slice(n + 1).trim(); - return obj; - }, {}); -} - - -/***/ }), -/* 340 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.serializeArray = exports.serialize = void 0; -var utils_1 = __webpack_require__(335); -/* - * https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js - * https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js - */ -var submittableSelector = 'input,select,textarea,keygen'; -var r20 = /%20/g; -var rCRLF = /\r?\n/g; -/** - * Encode a set of form elements as a string for submission. - * - * @category Forms - * @returns The serialized form. - * @see {@link https://api.jquery.com/serialize/} - */ -function serialize() { - // Convert form elements into name/value objects - var arr = this.serializeArray(); - // Serialize each element into a key/value string - var retArr = arr.map(function (data) { - return encodeURIComponent(data.name) + "=" + encodeURIComponent(data.value); - }); - // Return the resulting serialization - return retArr.join('&').replace(r20, '+'); -} -exports.serialize = serialize; -/** - * Encode a set of form elements as an array of names and values. - * - * @category Forms - * @example - * - * ```js - * $('<form><input name="foo" value="bar" /></form>').serializeArray(); - * //=> [ { name: 'foo', value: 'bar' } ] - * ``` - * - * @returns The serialized form. - * @see {@link https://api.jquery.com/serializeArray/} - */ -function serializeArray() { - var _this = this; - // Resolve all form elements from either forms or collections of form elements - return this.map(function (_, elem) { - var $elem = _this._make(elem); - if (utils_1.isTag(elem) && elem.name === 'form') { - return $elem.find(submittableSelector).toArray(); - } - return $elem.filter(submittableSelector).toArray(); - }) - .filter( - // Verify elements have a name (`attr.name`) and are not disabled (`:enabled`) - '[name!=""]:enabled' + - // And cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`) - ':not(:submit, :button, :image, :reset, :file)' + - // And are either checked/don't have a checkable state - ':matches([checked], :not(:checkbox, :radio))' - // Convert each of the elements to its value(s) - ) - .map(function (_, elem) { - var _a; - var $elem = _this._make(elem); - var name = $elem.attr('name'); // We have filtered for elements with a name before. - // If there is no value set (e.g. `undefined`, `null`), then default value to empty - var value = (_a = $elem.val()) !== null && _a !== void 0 ? _a : ''; - // If we have an array of values (e.g. `<select multiple>`), return an array of key/value pairs - if (Array.isArray(value)) { - return value.map(function (val) { - /* - * We trim replace any line endings (e.g. `\r` or `\r\n` with `\r\n`) to guarantee consistency across platforms - * These can occur inside of `<textarea>'s` - */ - return ({ name: name, value: val.replace(rCRLF, '\r\n') }); - }); - } - // Otherwise (e.g. `<input type="text">`, return only one key/value pair - return { name: name, value: value.replace(rCRLF, '\r\n') }; - }) - .toArray(); -} -exports.serializeArray = serializeArray; - - -/***/ }), -/* 341 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -/** - * Filters the passed array from data already present in the cozy so that there is - * not duplicated data in the Cozy. - * - * @module hydrateAndFilter - */ -const bluebird = __webpack_require__(5); - -const log = (__webpack_require__(342).namespace)('hydrateAndFilter'); - -const get = __webpack_require__(358); - -const uniqBy = __webpack_require__(400); - -const { - queryAll -} = __webpack_require__(472); -/** - * Since we can use methods or basic functions for - * `shouldSave` and `shouldUpdate` we pass the - * appropriate `this` and `arguments`. - * - * If `funcOrMethod` is a method, it will be called - * with args[0] as `this` and the rest as `arguments` - * Otherwise, `this` will be null and `args` will be passed - * as `arguments`. - */ - - -const suitableCall = (funcOrMethod, ...args) => { - const arity = funcOrMethod.length; - - if (arity < args.length) { - // must be a method - return funcOrMethod.apply(args[0], args.slice(1)); - } else { - // must be a function - return funcOrMethod.apply(null, args); - } -}; -/** - * Filters the passed array from data already present in the cozy so that there is - * not duplicated data in the Cozy. - * - * You need at least the `GET` permission for the given doctype in your manifest, to be able to - * use this function. - * - * Parameters: - * - * `documents`: an array of objects corresponding to the data you want to save in the cozy - * `doctype` (string): the doctype where you want to save data (ex: 'io.cozy.bills') - * `options` : - * - `keys` (array) : List of keys used to check that two items are the same. By default it is set to `['id']'. - * - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype. - * - `selector` (optionnal object) : Mango request to get records. Default is built from the keys `{selector: {_id: {"$gt": null}}}` to get all the records. - * - * ```javascript - * const documents = [ - * { - * name: 'toto', - * height: 1.8 - * }, - * { - * name: 'titi', - * height: 1.7 - * } - * ] - * - * return hydrateAndFilter(documents, 'io.cozy.height', { - * keys: ['name'] - * }).then(filteredDocuments => addData(filteredDocuments, 'io.cozy.height')) - * - * ``` - * - * @alias module:hydrateAndFilter - */ - - -const hydrateAndFilter = (documents = [], doctype, options = {}) => { - const cozy = __webpack_require__(473); - - log('debug', `${documents.length} items before hydrateAndFilter`); - if (!doctype) return Promise.reject(new Error(`Doctype is mandatory to filter the connector data.`)); - const keys = options.keys ? options.keys : ['_id']; - const store = {}; - - const createHash = item => { - return keys.map(key => { - let result = get(item, key); - if (key === 'date') result = new Date(result); - return result; - }).join('####'); - }; - - const getIndex = () => { - const index = options.index ? Promise.resolve(options.index) : cozy.data.defineIndex(doctype, keys); - return index; - }; - - const getItems = async index => { - const selector = options.selector ? options.selector : null; - return await queryAll(doctype, selector, index); - }; - - const populateStore = store => dbitems => { - dbitems.forEach(dbitem => { - store[createHash(dbitem)] = dbitem; - }); - }; // We add _id to `documents` that we find in the database. - // This is useful when linking with bank operations (a bill - // can already be in the database but not already matched - // to an operation) since the linking operation need the _id - // of the document - - - const hydrateExistingEntries = store => () => { - documents.forEach(document => { - const key = createHash(document); - - if (store[key]) { - document._id = store[key]._id; - document._rev = store[key]._rev; - if (!document.cozyMetadata && store[key].cozyMetadata) document.cozyMetadata = store[key].cozyMetadata; - } - }); - return documents; - }; - - const defaultShouldSave = () => true; - - const defaultShouldUpdate = existing => false; // eslint-disable-line no-unused-vars - - - const filterEntries = store => async () => { - // Filter out items according to shouldSave / shouldUpdate. - // Both can be passed as option or can be part of the entry. - return uniqBy(await bluebird.filter(documents, entry => { - const shouldSave = entry.shouldSave || options.shouldSave || defaultShouldSave; - const shouldUpdate = entry.shouldUpdate || options.shouldUpdate || defaultShouldUpdate; - const existing = store[createHash(entry)]; - - if (existing) { - return suitableCall(shouldUpdate, entry, existing); - } else { - return suitableCall(shouldSave, entry); - } - }), entry => entry && entry._id || entry); - }; - - const formatOutput = entries => { - log('debug', `${entries.length} items after hydrateAndFilter`); - return entries; - }; - - return getIndex().then(getItems).then(populateStore(store)).then(hydrateExistingEntries(store)).then(filterEntries(store)).then(entries => entries.filter(Boolean)) // Filter out wrong entries - .then(formatOutput); -}; - -module.exports = hydrateAndFilter; - -/***/ }), -/* 342 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -const { filterLevel, filterSecrets } = __webpack_require__(343) -const Secret = __webpack_require__(344) -const { LOG_LEVEL } = process.env -let level = LOG_LEVEL || 'debug' -const format = __webpack_require__(345) -const filters = [filterLevel, filterSecrets] - -const filterOut = function () { - for (const filter of filters) { - if (filter.apply(null, arguments) === false) { - return true - } - } - return false -} - -/** - * Use it to log messages in your konnector. Typical types are - * - * - `debug` - * - `warning` - * - `info` - * - `error` - * - `ok` - * - * - * @example - * - * They will be colored in development mode. In production mode, those logs are formatted in JSON to be interpreted by the stack and possibly sent to the client. `error` will stop the konnector. - * - * ```js - * logger = log('my-namespace') - * logger('debug', '365 bills') - * // my-namespace : debug : 365 bills - * logger('info', 'Page fetched') - * // my-namespace : info : Page fetched - * ``` - * @param {string} type - * @param {string} message - * @param {string} label - * @param {string} namespace - */ -function log(type, message, label, namespace) { - if (filterOut(level, type, message, label, namespace)) { - return - } - // eslint-disable-next-line no-console - console.log(format(type, message, label, namespace)) -} - -log.addFilter = function (filter) { - return filters.push(filter) -} - -log.setLevel = function (lvl) { - level = lvl -} - -// Short-hands -const methods = ['debug', 'info', 'warn', 'error', 'ok', 'critical'] -methods.forEach(level => { - log[level] = function (message, label, namespace) { - return log(level, message, label, namespace) - } -}) - -module.exports = log - -log.setNoRetry = obj => { - if (obj) obj.no_retry = true - else obj = { no_retry: true } - return obj.no_retry -} -log.Secret = Secret -log.namespace = function (namespace) { - return function (type, message, label, ns = namespace) { - log(type, message, label, ns) - } -} - - -/***/ }), -/* 343 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -const levels = { - secret: 0, - debug: 10, - info: 20, - warn: 30, - error: 40, - ok: 50, - critical: 50 -} - -const Secret = __webpack_require__(344) - -const filterSecrets = function (level, type, message) { - if (type !== 'secret' && message instanceof Secret) { - throw new Error('You should log a secret with log.secret') - } -} - -const filterLevel = function (level, type) { - return levels[type] >= levels[level] -} - -module.exports = { - filterSecrets, - filterLevel -} - - -/***/ }), -/* 344 */ -/***/ ((module) => { - -const Secret = function (data) { - Object.assign(this, data) - return this -} - -Secret.prototype.toString = function () { - throw new Error('Cannot convert Secret to string') -} - -module.exports = Secret - - -/***/ }), -/* 345 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -const prodFormat = __webpack_require__(346) -const devFormat = __webpack_require__(347) - -switch (process.env.NODE_ENV) { - case 'production': - module.exports = prodFormat - break - case 'development': - module.exports = devFormat - break - case 'standalone': - module.exports = devFormat - break - case 'test': - module.exports = devFormat - break - default: - module.exports = prodFormat -} - - -/***/ }), -/* 346 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -const stringify = __webpack_require__(75) - -const LOG_LENGTH_LIMIT = 64 * 1024 - 1 - -function prodFormat(type, message, label, namespace) { - const log = { time: new Date(), type, label, namespace } - - if (typeof message === 'object') { - if (message && message.no_retry) { - log.no_retry = message.no_retry - } - if (message && message.message) { - log.message = message.message - } - } else { - log.message = message - } - - // properly display error messages - if (log.message && log.message.stack) { - log.message = log.message.stack - } - - // cut the string to avoid a fail in the stack - let result = log - try { - result = stringify(log).substr(0, LOG_LENGTH_LIMIT) - } catch (err) { - // eslint-disable-next-line no-console - console.log(err.message, 'cozy-logger: Failed to convert message to JSON') - } - return result -} - -module.exports = prodFormat - - -/***/ }), -/* 347 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -const util = __webpack_require__(64) -const chalk = __webpack_require__(348) - -if (util && util.inspect && util.inspect.defaultOptions) { - util.inspect.defaultOptions.maxArrayLength = null - util.inspect.defaultOptions.depth = 2 - util.inspect.defaultOptions.colors = true -} - -const type2color = { - debug: 'cyan', - warn: 'yellow', - info: 'blue', - error: 'red', - ok: 'green', - secret: 'red', - critical: 'red' -} - -function devFormat(type, message, label, namespace) { - let formatmessage = message - - if (typeof formatmessage !== 'string') { - formatmessage = util.inspect(formatmessage) - } - - let formatlabel = label ? ` : "${label}" ` : '' - let formatnamespace = namespace ? chalk.magenta(`${namespace}: `) : '' - - let color = type2color[type] - let formattype = color ? chalk[color](type) : type - - return `${formatnamespace}${formattype}${formatlabel} : ${formatmessage}` -} - -module.exports = devFormat - - -/***/ }), -/* 348 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - -const escapeStringRegexp = __webpack_require__(349); -const ansiStyles = __webpack_require__(350); -const stdoutColor = (__webpack_require__(355).stdout); - -const template = __webpack_require__(357); - -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); - -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; - -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); - -const styles = Object.create(null); - -function applyOptions(obj, options) { - options = options || {}; - - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; -} - -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); - - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; - - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - - chalk.template.constructor = Chalk; - - return chalk.template; - } - - applyOptions(this, options); -} - -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; -} - -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - - styles[key] = { - get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; -} - -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } -}; - -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } - - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} - -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } - - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} - -const proto = Object.defineProperties(() => {}, styles); - -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; - - builder._styles = _styles; - builder._empty = _empty; - - const self = this; - - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); - - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); - - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; - - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto - - return builder; -} - -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); - - if (argsLen === 0) { - return ''; - } - - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } - - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } - - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } - - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; - - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); - } - - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; - - return str; -} - -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } - - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; - - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); - } - - return template(chalk, parts.join('')); -} - -Object.defineProperties(Chalk.prototype, styles); - -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports["default"] = module.exports; // For TypeScript - - -/***/ }), -/* 349 */ -/***/ ((module) => { - -"use strict"; - - -var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; - -module.exports = function (str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } - - return str.replace(matchOperatorsRe, '\\$&'); -}; - - -/***/ }), -/* 350 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; -/* module decorator */ module = __webpack_require__.nmd(module); - -const colorConvert = __webpack_require__(351); - -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${code + offset}m`; -}; - -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};5;${code}m`; -}; - -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; - -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], - - // Bright color - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; - - // Fix humans - styles.color.grey = styles.color.gray; - - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; - - for (const styleName of Object.keys(group)) { - const style = group[styleName]; - - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; - - group[styleName] = styles[styleName]; - - codes.set(style[0], style[1]); - } - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - } - - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; - - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; - - for (let key of Object.keys(colorConvert)) { - if (typeof colorConvert[key] !== 'object') { - continue; - } - - const suite = colorConvert[key]; - - if (key === 'ansi16') { - key = 'ansi'; - } - - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } - - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } - - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } - } - - return styles; -} - -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); - - -/***/ }), -/* 351 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var conversions = __webpack_require__(352); -var route = __webpack_require__(354); - -var convert = {}; - -var models = Object.keys(conversions); - -function wrapRaw(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - - return fn(args); - }; - - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -function wrapRounded(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - - var result = fn(args); - - // we're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (var len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } - - return result; - }; - - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -models.forEach(function (fromModel) { - convert[fromModel] = {}; - - Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); - Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); - - var routes = route(fromModel); - var routeModels = Object.keys(routes); - - routeModels.forEach(function (toModel) { - var fn = routes[toModel]; - - convert[fromModel][toModel] = wrapRounded(fn); - convert[fromModel][toModel].raw = wrapRaw(fn); - }); -}); - -module.exports = convert; - - -/***/ }), -/* 352 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -/* MIT license */ -var cssKeywords = __webpack_require__(353); - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) - -var reverseKeywords = {}; -for (var key in cssKeywords) { - if (cssKeywords.hasOwnProperty(key)) { - reverseKeywords[cssKeywords[key]] = key; - } -} - -var convert = module.exports = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; - -// hide .channels and .labels properties -for (var model in convert) { - if (convert.hasOwnProperty(model)) { - if (!('channels' in convert[model])) { - throw new Error('missing channels property: ' + model); - } - - if (!('labels' in convert[model])) { - throw new Error('missing channel labels property: ' + model); - } - - if (convert[model].labels.length !== convert[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } - - var channels = convert[model].channels; - var labels = convert[model].labels; - delete convert[model].channels; - delete convert[model].labels; - Object.defineProperty(convert[model], 'channels', {value: channels}); - Object.defineProperty(convert[model], 'labels', {value: labels}); - } -} - -convert.rgb.hsl = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var delta = max - min; - var h; - var s; - var l; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); - - if (h < 0) { - h += 360; - } - - l = (min + max) / 2; - - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } - - return [h, s * 100, l * 100]; -}; - -convert.rgb.hsv = function (rgb) { - var rdif; - var gdif; - var bdif; - var h; - var s; - - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var v = Math.max(r, g, b); - var diff = v - Math.min(r, g, b); - var diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; - - if (diff === 0) { - h = s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); - - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - } - - return [ - h * 360, - s * 100, - v * 100 - ]; -}; - -convert.rgb.hwb = function (rgb) { - var r = rgb[0]; - var g = rgb[1]; - var b = rgb[2]; - var h = convert.rgb.hsl(rgb)[0]; - var w = 1 / 255 * Math.min(r, Math.min(g, b)); - - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - - return [h, w * 100, b * 100]; -}; - -convert.rgb.cmyk = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var c; - var m; - var y; - var k; - - k = Math.min(1 - r, 1 - g, 1 - b); - c = (1 - r - k) / (1 - k) || 0; - m = (1 - g - k) / (1 - k) || 0; - y = (1 - b - k) / (1 - k) || 0; - - return [c * 100, m * 100, y * 100, k * 100]; -}; - -/** - * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - * */ -function comparativeDistance(x, y) { - return ( - Math.pow(x[0] - y[0], 2) + - Math.pow(x[1] - y[1], 2) + - Math.pow(x[2] - y[2], 2) - ); -} - -convert.rgb.keyword = function (rgb) { - var reversed = reverseKeywords[rgb]; - if (reversed) { - return reversed; - } - - var currentClosestDistance = Infinity; - var currentClosestKeyword; - - for (var keyword in cssKeywords) { - if (cssKeywords.hasOwnProperty(keyword)) { - var value = cssKeywords[keyword]; - - // Compute comparative distance - var distance = comparativeDistance(rgb, value); - - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } - } - - return currentClosestKeyword; -}; - -convert.keyword.rgb = function (keyword) { - return cssKeywords[keyword]; -}; - -convert.rgb.xyz = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - - // assume sRGB - r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); - - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y * 100, z * 100]; -}; - -convert.rgb.lab = function (rgb) { - var xyz = convert.rgb.xyz(rgb); - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -}; - -convert.hsl.rgb = function (hsl) { - var h = hsl[0] / 360; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var t1; - var t2; - var t3; - var rgb; - var val; - - if (s === 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } - - t1 = 2 * l - t2; - - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } - if (t3 > 1) { - t3--; - } - - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } - - rgb[i] = val * 255; - } - - return rgb; -}; - -convert.hsl.hsv = function (hsl) { - var h = hsl[0]; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var smin = s; - var lmin = Math.max(l, 0.01); - var sv; - var v; - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - v = (l + s) / 2; - sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); - - return [h, sv * 100, v * 100]; -}; - -convert.hsv.rgb = function (hsv) { - var h = hsv[0] / 60; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var hi = Math.floor(h) % 6; - - var f = h - Math.floor(h); - var p = 255 * v * (1 - s); - var q = 255 * v * (1 - (s * f)); - var t = 255 * v * (1 - (s * (1 - f))); - v *= 255; - - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; - -convert.hsv.hsl = function (hsv) { - var h = hsv[0]; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var vmin = Math.max(v, 0.01); - var lmin; - var sl; - var l; - - l = (2 - s) * v; - lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; - - return [h, sl * 100, l * 100]; -}; - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert.hwb.rgb = function (hwb) { - var h = hwb[0] / 360; - var wh = hwb[1] / 100; - var bl = hwb[2] / 100; - var ratio = wh + bl; - var i; - var v; - var f; - var n; - - // wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - i = Math.floor(6 * h); - v = 1 - bl; - f = 6 * h - i; - - if ((i & 0x01) !== 0) { - f = 1 - f; - } - - n = wh + f * (v - wh); // linear interpolation - - var r; - var g; - var b; - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - - return [r * 255, g * 255, b * 255]; -}; - -convert.cmyk.rgb = function (cmyk) { - var c = cmyk[0] / 100; - var m = cmyk[1] / 100; - var y = cmyk[2] / 100; - var k = cmyk[3] / 100; - var r; - var g; - var b; - - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); - - return [r * 255, g * 255, b * 255]; -}; - -convert.xyz.rgb = function (xyz) { - var x = xyz[0] / 100; - var y = xyz[1] / 100; - var z = xyz[2] / 100; - var r; - var g; - var b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // assume sRGB - r = r > 0.0031308 - ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) - : r * 12.92; - - g = g > 0.0031308 - ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) - : g * 12.92; - - b = b > 0.0031308 - ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) - : b * 12.92; - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -}; - -convert.xyz.lab = function (xyz) { - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -}; - -convert.lab.xyz = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var x; - var y; - var z; - - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; - - var y2 = Math.pow(y, 3); - var x2 = Math.pow(x, 3); - var z2 = Math.pow(z, 3); - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; - - x *= 95.047; - y *= 100; - z *= 108.883; - - return [x, y, z]; -}; - -convert.lab.lch = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var hr; - var h; - var c; - - hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - - if (h < 0) { - h += 360; - } - - c = Math.sqrt(a * a + b * b); - - return [l, c, h]; -}; - -convert.lch.lab = function (lch) { - var l = lch[0]; - var c = lch[1]; - var h = lch[2]; - var a; - var b; - var hr; - - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); - - return [l, a, b]; -}; - -convert.rgb.ansi16 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization - - value = Math.round(value / 50); - - if (value === 0) { - return 30; - } - - var ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); - - if (value === 2) { - ansi += 60; - } - - return ansi; -}; - -convert.hsv.ansi16 = function (args) { - // optimization here; we already know the value and don't need to get - // it converted for us. - return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); -}; - -convert.rgb.ansi256 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - - // we use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } - - if (r > 248) { - return 231; - } - - return Math.round(((r - 8) / 247) * 24) + 232; - } - - var ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); - - return ansi; -}; - -convert.ansi16.rgb = function (args) { - var color = args % 10; - - // handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } - - color = color / 10.5 * 255; - - return [color, color, color]; - } - - var mult = (~~(args > 50) + 1) * 0.5; - var r = ((color & 1) * mult) * 255; - var g = (((color >> 1) & 1) * mult) * 255; - var b = (((color >> 2) & 1) * mult) * 255; - - return [r, g, b]; -}; - -convert.ansi256.rgb = function (args) { - // handle greyscale - if (args >= 232) { - var c = (args - 232) * 10 + 8; - return [c, c, c]; - } - - args -= 16; - - var rem; - var r = Math.floor(args / 36) / 5 * 255; - var g = Math.floor((rem = args % 36) / 6) / 5 * 255; - var b = (rem % 6) / 5 * 255; - - return [r, g, b]; -}; - -convert.rgb.hex = function (args) { - var integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); - - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert.hex.rgb = function (args) { - var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } - - var colorString = match[0]; - - if (match[0].length === 3) { - colorString = colorString.split('').map(function (char) { - return char + char; - }).join(''); - } - - var integer = parseInt(colorString, 16); - var r = (integer >> 16) & 0xFF; - var g = (integer >> 8) & 0xFF; - var b = integer & 0xFF; - - return [r, g, b]; -}; - -convert.rgb.hcg = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var max = Math.max(Math.max(r, g), b); - var min = Math.min(Math.min(r, g), b); - var chroma = (max - min); - var grayscale; - var hue; - - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } - - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma + 4; - } - - hue /= 6; - hue %= 1; - - return [hue * 360, chroma * 100, grayscale * 100]; -}; - -convert.hsl.hcg = function (hsl) { - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var c = 1; - var f = 0; - - if (l < 0.5) { - c = 2.0 * s * l; - } else { - c = 2.0 * s * (1.0 - l); - } - - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } - - return [hsl[0], c * 100, f * 100]; -}; - -convert.hsv.hcg = function (hsv) { - var s = hsv[1] / 100; - var v = hsv[2] / 100; - - var c = s * v; - var f = 0; - - if (c < 1.0) { - f = (v - c) / (1 - c); - } - - return [hsv[0], c * 100, f * 100]; -}; - -convert.hcg.rgb = function (hcg) { - var h = hcg[0] / 360; - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } - - var pure = [0, 0, 0]; - var hi = (h % 1) * 6; - var v = hi % 1; - var w = 1 - v; - var mg = 0; - - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } - - mg = (1.0 - c) * g; - - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; - -convert.hcg.hsv = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - var v = c + g * (1.0 - c); - var f = 0; - - if (v > 0.0) { - f = c / v; - } - - return [hcg[0], f * 100, v * 100]; -}; - -convert.hcg.hsl = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - var l = g * (1.0 - c) + 0.5 * c; - var s = 0; - - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } - - return [hcg[0], s * 100, l * 100]; -}; - -convert.hcg.hwb = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - var v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; - -convert.hwb.hcg = function (hwb) { - var w = hwb[1] / 100; - var b = hwb[2] / 100; - var v = 1 - b; - var c = v - w; - var g = 0; - - if (c < 1) { - g = (v - c) / (1 - c); - } - - return [hwb[0], c * 100, g * 100]; -}; - -convert.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; - -convert.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; - -convert.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; -}; - -convert.gray.hsl = convert.gray.hsv = function (args) { - return [0, 0, args[0]]; -}; - -convert.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; - -convert.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; - -convert.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; - -convert.gray.hex = function (gray) { - var val = Math.round(gray[0] / 100 * 255) & 0xFF; - var integer = (val << 16) + (val << 8) + val; - - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert.rgb.gray = function (rgb) { - var val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; - - -/***/ }), -/* 353 */ -/***/ ((module) => { - -"use strict"; - - -module.exports = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; - - -/***/ }), -/* 354 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var conversions = __webpack_require__(352); - -/* - this function routes a model to all other models. - - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). - - conversions that are not possible simply are not included. -*/ - -function buildGraph() { - var graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - var models = Object.keys(conversions); - - for (var len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } - - return graph; -} - -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS(fromModel) { - var graph = buildGraph(); - var queue = [fromModel]; // unshift -> queue -> pop - - graph[fromModel].distance = 0; - - while (queue.length) { - var current = queue.pop(); - var adjacents = Object.keys(conversions[current]); - - for (var len = adjacents.length, i = 0; i < len; i++) { - var adjacent = adjacents[i]; - var node = graph[adjacent]; - - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } - - return graph; -} - -function link(from, to) { - return function (args) { - return to(from(args)); - }; -} - -function wrapConversion(toModel, graph) { - var path = [graph[toModel].parent, toModel]; - var fn = conversions[graph[toModel].parent][toModel]; - - var cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link(conversions[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } - - fn.conversion = path; - return fn; -} - -module.exports = function (fromModel) { - var graph = deriveBFS(fromModel); - var conversion = {}; - - var models = Object.keys(graph); - for (var len = models.length, i = 0; i < len; i++) { - var toModel = models[i]; - var node = graph[toModel]; - - if (node.parent === null) { - // no possible conversion, or this node is the source model. - continue; - } - - conversion[toModel] = wrapConversion(toModel, graph); - } - - return conversion; -}; - - - -/***/ }), -/* 355 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - -const os = __webpack_require__(252); -const hasFlag = __webpack_require__(356); - -const env = process.env; - -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} - -function translateLevel(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } - - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } - - if (hasFlag('color=256')) { - return 2; - } - - if (stream && !stream.isTTY && forceColor !== true) { - return 0; - } - - const min = forceColor ? 1 : 0; - - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - - if ('COLORTERM' in env) { - return 1; - } - - if (env.TERM === 'dumb') { - return min; - } - - return min; -} - -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); -} - -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; - - -/***/ }), -/* 356 */ -/***/ ((module) => { - -"use strict"; - -module.exports = (flag, argv) => { - argv = argv || process.argv; - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const pos = argv.indexOf(prefix + flag); - const terminatorPos = argv.indexOf('--'); - return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); -}; - - -/***/ }), -/* 357 */ -/***/ ((module) => { - -"use strict"; - -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); - -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } - - return ESCAPES.get(c) || c; -} - -function parseArguments(name, args) { - const results = []; - const chunks = args.trim().split(/\s*,\s*/g); - let matches; - - for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } - - return results; -} - -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; - - const results = []; - let matches; - - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; - - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } - - return results; + * //=> Pear + * ``` + * + * @returns The last element. + * @see {@link https://api.jquery.com/last/} + */ +function last() { + return this.length > 0 ? this._make(this[this.length - 1]) : this; } - -function buildStyle(chalk, styles) { - const enabled = {}; - - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } - - let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } - - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } - } - - return current; +exports.last = last; +/** + * Reduce the set of matched elements to the one at the specified index. Use + * `.eq(-i)` to count backwards from the last selected element. + * + * @category Traversing + * @example + * + * ```js + * $('li').eq(0).text(); + * //=> Apple + * + * $('li').eq(-1).text(); + * //=> Pear + * ``` + * + * @param i - Index of the element to select. + * @returns The element at the `i`th position. + * @see {@link https://api.jquery.com/eq/} + */ +function eq(i) { + var _a; + i = +i; + // Use the first identity optimization if possible + if (i === 0 && this.length <= 1) + return this; + if (i < 0) + i = this.length + i; + return this._make((_a = this[i]) !== null && _a !== void 0 ? _a : []); } - -module.exports = (chalk, tmp) => { - const styles = []; - const chunks = []; - let chunk = []; - - // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); - } else if (style) { - const str = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } - - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); - - chunks.push(chunk.join('')); - - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); - } - - return chunks.join(''); -}; - - -/***/ }), -/* 358 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var baseGet = __webpack_require__(359); - +exports.eq = eq; +function get(i) { + if (i == null) { + return this.toArray(); + } + return this[i < 0 ? this.length + i : i]; +} +exports.get = get; /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. + * Retrieve all the DOM elements contained in the jQuery set as an array. * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. * @example * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * ```js + * $('li').toArray(); + * //=> [ {...}, {...}, {...} ] + * ``` * - * _.get(object, 'a[0].b.c'); - * // => 3 + * @returns The contained items. + */ +function toArray() { + return Array.prototype.slice.call(this); +} +exports.toArray = toArray; +/** + * Search for a given element from among the matched elements. * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 + * @category Traversing + * @example * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' + * ```js + * $('.pear').index(); + * //=> 2 $('.orange').index('li'); + * //=> 1 + * $('.apple').index($('#fruit, li')); + * //=> 1 + * ``` + * + * @param selectorOrNeedle - Element to look for. + * @returns The index of the element. + * @see {@link https://api.jquery.com/index/} */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; +function index(selectorOrNeedle) { + var $haystack; + var needle; + if (selectorOrNeedle == null) { + $haystack = this.parent().children(); + needle = this[0]; + } + else if (typeof selectorOrNeedle === 'string') { + $haystack = this._make(selectorOrNeedle); + needle = this[0]; + } + else { + $haystack = this; + needle = utils_1.isCheerio(selectorOrNeedle) + ? selectorOrNeedle[0] + : selectorOrNeedle; + } + return Array.prototype.indexOf.call($haystack, needle); } - -module.exports = get; - - -/***/ }), -/* 359 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var castPath = __webpack_require__(360), - toKey = __webpack_require__(399); - +exports.index = index; /** - * The base implementation of `_.get` without support for default values. + * Gets the elements matching the specified range (0-based position). * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. + * @category Traversing + * @example + * + * ```js + * $('li').slice(1).eq(0).text(); + * //=> 'Orange' + * + * $('li').slice(1, 2).length; + * //=> 1 + * ``` + * + * @param start - An position at which the elements begin to be selected. If + * negative, it indicates an offset from the end of the set. + * @param end - An position at which the elements stop being selected. If + * negative, it indicates an offset from the end of the set. If omitted, the + * range continues until the end of the set. + * @returns The elements matching the specified range. + * @see {@link https://api.jquery.com/slice/} */ -function baseGet(object, path) { - path = castPath(path, object); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; +function slice(start, end) { + return this._make(Array.prototype.slice.call(this, start, end)); } - -module.exports = baseGet; - - -/***/ }), -/* 360 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var isArray = __webpack_require__(55), - isKey = __webpack_require__(361), - stringToPath = __webpack_require__(363), - toString = __webpack_require__(396); - +exports.slice = slice; /** - * Casts `value` to a path array if it's not one. + * End the most recent filtering operation in the current chain and return the + * set of matched elements to its previous state. * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. + * @category Traversing + * @example + * + * ```js + * $('li').eq(0).end().length; + * //=> 3 + * ``` + * + * @returns The previous state of the set of matched elements. + * @see {@link https://api.jquery.com/end/} */ -function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); +function end() { + var _a; + return (_a = this.prevObject) !== null && _a !== void 0 ? _a : this._make([]); } - -module.exports = castPath; - - -/***/ }), -/* 361 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var isArray = __webpack_require__(55), - isSymbol = __webpack_require__(362); - -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; - +exports.end = end; /** - * Checks if `value` is a property name and not a property path. + * Add elements to the set of matched elements. * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + * @category Traversing + * @example + * + * ```js + * $('.apple').add('.orange').length; + * //=> 2 + * ``` + * + * @param other - Elements to add. + * @param context - Optionally the context of the new selection. + * @returns The combined set. + * @see {@link https://api.jquery.com/add/} */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); +function add(other, context) { + var selection = this._make(other, context); + var contents = uniqueSort(tslib_1.__spreadArray(tslib_1.__spreadArray([], this.get()), selection.get())); + return this._make(contents); } - -module.exports = isKey; - - -/***/ }), -/* 362 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var baseGetTag = __webpack_require__(46), - isObjectLike = __webpack_require__(53); - -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; - +exports.add = add; /** - * Checks if `value` is classified as a `Symbol` primitive or object. + * Add the previous set of elements on the stack to the current set, optionally + * filtered by a selector. * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @category Traversing * @example * - * _.isSymbol(Symbol.iterator); - * // => true + * ```js + * $('li').eq(0).addBack('.orange').length; + * //=> 2 + * ``` * - * _.isSymbol('abc'); - * // => false + * @param selector - Selector for the elements to add. + * @returns The combined set. + * @see {@link https://api.jquery.com/addBack/} */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); +function addBack(selector) { + return this.prevObject + ? this.add(selector ? this.prevObject.filter(selector) : this.prevObject) + : this; } - -module.exports = isSymbol; +exports.addBack = addBack; /***/ }), -/* 363 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var memoizeCapped = __webpack_require__(364); - -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; +/* 350 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; +"use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.clone = exports.text = exports.toString = exports.html = exports.empty = exports.replaceWith = exports.remove = exports.insertBefore = exports.before = exports.insertAfter = exports.after = exports.wrapAll = exports.unwrap = exports.wrapInner = exports.wrap = exports.prepend = exports.append = exports.prependTo = exports.appendTo = exports._makeDomArray = void 0; +var tslib_1 = __webpack_require__(257); +var domhandler_1 = __webpack_require__(317); /** - * Converts `string` to a property path array. + * Methods for modifying the DOM structure. + * + * @module cheerio/manipulation + */ +var domhandler_2 = __webpack_require__(317); +var parse_1 = tslib_1.__importStar(__webpack_require__(346)); +var static_1 = __webpack_require__(261); +var utils_1 = __webpack_require__(347); +var htmlparser2_1 = __webpack_require__(303); +/** + * Create an array of nodes, recursing into arrays and parsing strings if necessary. * * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. + * @category Manipulation + * @param elem - Elements to make an array of. + * @param clone - Optionally clone nodes. + * @returns The array of nodes. */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); - -module.exports = stringToPath; - - -/***/ }), -/* 364 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var memoize = __webpack_require__(365); - -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; - +function _makeDomArray(elem, clone) { + var _this = this; + if (elem == null) { + return []; + } + if (utils_1.isCheerio(elem)) { + return clone ? utils_1.cloneDom(elem.get()) : elem.get(); + } + if (Array.isArray(elem)) { + return elem.reduce(function (newElems, el) { return newElems.concat(_this._makeDomArray(el, clone)); }, []); + } + if (typeof elem === 'string') { + return parse_1.default(elem, this.options, false).children; + } + return clone ? utils_1.cloneDom([elem]) : [elem]; +} +exports._makeDomArray = _makeDomArray; +function _insert(concatenator) { + return function () { + var _this = this; + var elems = []; + for (var _i = 0; _i < arguments.length; _i++) { + elems[_i] = arguments[_i]; + } + var lastIdx = this.length - 1; + return utils_1.domEach(this, function (el, i) { + if (!domhandler_1.hasChildren(el)) + return; + var domSrc = typeof elems[0] === 'function' + ? elems[0].call(el, i, static_1.html(el.children)) + : elems; + var dom = _this._makeDomArray(domSrc, i < lastIdx); + concatenator(dom, el.children, el); + }); + }; +} /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * Modify an array in-place, removing some number of elements and adding new + * elements directly following them. * * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. + * @category Manipulation + * @param array - Target array to splice. + * @param spliceIdx - Index at which to begin changing the array. + * @param spliceCount - Number of elements to remove from the array. + * @param newElems - Elements to insert into the array. + * @param parent - The parent of the node. + * @returns The spliced array. */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); +function uniqueSplice(array, spliceIdx, spliceCount, newElems, parent) { + var _a, _b; + var spliceArgs = tslib_1.__spreadArray([ + spliceIdx, + spliceCount + ], newElems); + var prev = array[spliceIdx - 1] || null; + var next = array[spliceIdx + spliceCount] || null; + /* + * Before splicing in new elements, ensure they do not already appear in the + * current array. + */ + for (var idx = 0; idx < newElems.length; ++idx) { + var node = newElems[idx]; + var oldParent = node.parent; + if (oldParent) { + var prevIdx = oldParent.children.indexOf(newElems[idx]); + if (prevIdx > -1) { + oldParent.children.splice(prevIdx, 1); + if (parent === oldParent && spliceIdx > prevIdx) { + spliceArgs[0]--; + } + } + } + node.parent = parent; + if (node.prev) { + node.prev.next = (_a = node.next) !== null && _a !== void 0 ? _a : null; + } + if (node.next) { + node.next.prev = (_b = node.prev) !== null && _b !== void 0 ? _b : null; + } + node.prev = newElems[idx - 1] || prev; + node.next = newElems[idx + 1] || next; } - return key; - }); - - var cache = result.cache; - return result; + if (prev) { + prev.next = newElems[0]; + } + if (next) { + next.prev = newElems[newElems.length - 1]; + } + return array.splice.apply(array, spliceArgs); } - -module.exports = memoizeCapped; - - -/***/ }), -/* 365 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var MapCache = __webpack_require__(366); - -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. + * Insert every element in the set of matched elements to the end of the target. * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * @category Manipulation + * @example * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. + * ```js + * $('<li class="plum">Plum</li>').appendTo('#fruits'); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="apple">Apple</li> + * // <li class="orange">Orange</li> + * // <li class="pear">Pear</li> + * // <li class="plum">Plum</li> + * // </ul> + * ``` + * + * @param target - Element to append elements to. + * @returns The instance itself. + * @see {@link https://api.jquery.com/appendTo/} + */ +function appendTo(target) { + var appendTarget = utils_1.isCheerio(target) ? target : this._make(target); + appendTarget.append(this); + return this; +} +exports.appendTo = appendTo; +/** + * Insert every element in the set of matched elements to the beginning of the target. + * + * @category Manipulation * @example * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; + * ```js + * $('<li class="plum">Plum</li>').prependTo('#fruits'); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="plum">Plum</li> + * // <li class="apple">Apple</li> + * // <li class="orange">Orange</li> + * // <li class="pear">Pear</li> + * // </ul> + * ``` * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] + * @param target - Element to prepend elements to. + * @returns The instance itself. + * @see {@link https://api.jquery.com/prependTo/} + */ +function prependTo(target) { + var prependTarget = utils_1.isCheerio(target) ? target : this._make(target); + prependTarget.prepend(this); + return this; +} +exports.prependTo = prependTo; +/** + * Inserts content as the *last* child of each of the selected elements. * - * values(other); - * // => [3, 4] + * @category Manipulation + * @example * - * object.a = 2; - * values(object); - * // => [1, 2] + * ```js + * $('ul').append('<li class="plum">Plum</li>'); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="apple">Apple</li> + * // <li class="orange">Orange</li> + * // <li class="pear">Pear</li> + * // <li class="plum">Plum</li> + * // </ul> + * ``` * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] + * @see {@link https://api.jquery.com/append/} + */ +exports.append = _insert(function (dom, children, parent) { + uniqueSplice(children, children.length, 0, dom, parent); +}); +/** + * Inserts content as the *first* child of each of the selected elements. * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * @category Manipulation + * @example + * + * ```js + * $('ul').prepend('<li class="plum">Plum</li>'); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="plum">Plum</li> + * // <li class="apple">Apple</li> + * // <li class="orange">Orange</li> + * // <li class="pear">Pear</li> + * // </ul> + * ``` + * + * @see {@link https://api.jquery.com/prepend/} */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +exports.prepend = _insert(function (dom, children, parent) { + uniqueSplice(children, 0, 0, dom, parent); +}); +function _wrap(insert) { + return function (wrapper) { + var lastIdx = this.length - 1; + var lastParent = this.parents().last(); + for (var i = 0; i < this.length; i++) { + var el = this[i]; + var wrap_1 = typeof wrapper === 'function' + ? wrapper.call(el, i, el) + : typeof wrapper === 'string' && !utils_1.isHtml(wrapper) + ? lastParent.find(wrapper).clone() + : wrapper; + var wrapperDom = this._makeDomArray(wrap_1, i < lastIdx)[0]; + if (!wrapperDom || !htmlparser2_1.DomUtils.hasChildren(wrapperDom)) + continue; + var elInsertLocation = wrapperDom; + /* + * Find the deepest child. Only consider the first tag child of each node + * (ignore text); stop if no children are found. + */ + var j = 0; + while (j < elInsertLocation.children.length) { + var child = elInsertLocation.children[j]; + if (utils_1.isTag(child)) { + elInsertLocation = child; + j = 0; + } + else { + j++; + } + } + insert(el, elInsertLocation, [wrapperDom]); + } + return this; + }; } - -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; - - -/***/ }), -/* 366 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var mapCacheClear = __webpack_require__(367), - mapCacheDelete = __webpack_require__(390), - mapCacheGet = __webpack_require__(393), - mapCacheHas = __webpack_require__(394), - mapCacheSet = __webpack_require__(395); - /** - * Creates a map cache object to store key-value pairs. + * The .wrap() function can take any string or object that could be passed to + * the $() factory function to specify a DOM structure. This structure may be + * nested several levels deep, but should contain only one inmost element. A + * copy of this structure will be wrapped around each of the elements in the set + * of matched elements. This method returns the original set of elements for + * chaining purposes. * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. + * @category Manipulation + * @example + * + * ```js + * const redFruit = $('<div class="red-fruit"></div>'); + * $('.apple').wrap(redFruit); + * + * //=> <ul id="fruits"> + * // <div class="red-fruit"> + * // <li class="apple">Apple</li> + * // </div> + * // <li class="orange">Orange</li> + * // <li class="plum">Plum</li> + * // </ul> + * + * const healthy = $('<div class="healthy"></div>'); + * $('li').wrap(healthy); + * + * //=> <ul id="fruits"> + * // <div class="healthy"> + * // <li class="apple">Apple</li> + * // </div> + * // <div class="healthy"> + * // <li class="orange">Orange</li> + * // </div> + * // <div class="healthy"> + * // <li class="plum">Plum</li> + * // </div> + * // </ul> + * ``` + * + * @param wrapper - The DOM structure to wrap around each element in the selection. + * @see {@link https://api.jquery.com/wrap/} */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; - - -/***/ }), -/* 367 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var Hash = __webpack_require__(368), - ListCache = __webpack_require__(381), - Map = __webpack_require__(389); - +exports.wrap = _wrap(function (el, elInsertLocation, wrapperDom) { + var parent = el.parent; + if (!parent) + return; + var siblings = parent.children; + var index = siblings.indexOf(el); + parse_1.update([el], elInsertLocation); + /* + * The previous operation removed the current element from the `siblings` + * array, so the `dom` array can be inserted without removing any + * additional elements. + */ + uniqueSplice(siblings, index, 0, wrapperDom, parent); +}); /** - * Removes all key-value entries from the map. + * The .wrapInner() function can take any string or object that could be passed + * to the $() factory function to specify a DOM structure. This structure may be + * nested several levels deep, but should contain only one inmost element. The + * structure will be wrapped around the content of each of the elements in the + * set of matched elements. * - * @private - * @name clear - * @memberOf MapCache + * @category Manipulation + * @example + * + * ```js + * const redFruit = $('<div class="red-fruit"></div>'); + * $('.apple').wrapInner(redFruit); + * + * //=> <ul id="fruits"> + * // <li class="apple"> + * // <div class="red-fruit">Apple</div> + * // </li> + * // <li class="orange">Orange</li> + * // <li class="pear">Pear</li> + * // </ul> + * + * const healthy = $('<div class="healthy"></div>'); + * $('li').wrapInner(healthy); + * + * //=> <ul id="fruits"> + * // <li class="apple"> + * // <div class="healthy">Apple</div> + * // </li> + * // <li class="orange"> + * // <div class="healthy">Orange</div> + * // </li> + * // <li class="pear"> + * // <div class="healthy">Pear</div> + * // </li> + * // </ul> + * ``` + * + * @param wrapper - The DOM structure to wrap around the content of each element + * in the selection. + * @returns The instance itself, for chaining. + * @see {@link https://api.jquery.com/wrapInner/} */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -module.exports = mapCacheClear; - - -/***/ }), -/* 368 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var hashClear = __webpack_require__(369), - hashDelete = __webpack_require__(377), - hashGet = __webpack_require__(378), - hashHas = __webpack_require__(379), - hashSet = __webpack_require__(380); - +exports.wrapInner = _wrap(function (el, elInsertLocation, wrapperDom) { + if (!domhandler_1.hasChildren(el)) + return; + parse_1.update(el.children, elInsertLocation); + parse_1.update(wrapperDom, el); +}); /** - * Creates a hash object. + * The .unwrap() function, removes the parents of the set of matched elements + * from the DOM, leaving the matched elements in their place. * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. + * @category Manipulation + * @example <caption>without selector</caption> + * + * ```js + * const $ = cheerio.load( + * '<div id=test>\n <div><p>Hello</p></div>\n <div><p>World</p></div>\n</div>' + * ); + * $('#test p').unwrap(); + * + * //=> <div id=test> + * // <p>Hello</p> + * // <p>World</p> + * // </div> + * ``` + * + * @example <caption>with selector</caption> + * + * ```js + * const $ = cheerio.load( + * '<div id=test>\n <p>Hello</p>\n <b><p>World</p></b>\n</div>' + * ); + * $('#test p').unwrap('b'); + * + * //=> <div id=test> + * // <p>Hello</p> + * // <p>World</p> + * // </div> + * ``` + * + * @param selector - A selector to check the parent element against. If an + * element's parent does not match the selector, the element won't be unwrapped. + * @returns The instance itself, for chaining. + * @see {@link https://api.jquery.com/unwrap/} */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } +function unwrap(selector) { + var _this = this; + this.parent(selector) + .not('body') + .each(function (_, el) { + _this._make(el).replaceWith(el.children); + }); + return this; } - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -module.exports = Hash; - - -/***/ }), -/* 369 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var nativeCreate = __webpack_require__(370); - +exports.unwrap = unwrap; /** - * Removes all key-value entries from the hash. + * The .wrapAll() function can take any string or object that could be passed to + * the $() function to specify a DOM structure. This structure may be nested + * several levels deep, but should contain only one inmost element. The + * structure will be wrapped around all of the elements in the set of matched + * elements, as a single group. * - * @private - * @name clear - * @memberOf Hash + * @category Manipulation + * @example <caption>With markup passed to `wrapAll`</caption> + * + * ```js + * const $ = cheerio.load( + * '<div class="container"><div class="inner">First</div><div class="inner">Second</div></div>' + * ); + * $('.inner').wrapAll("<div class='new'></div>"); + * + * //=> <div class="container"> + * // <div class='new'> + * // <div class="inner">First</div> + * // <div class="inner">Second</div> + * // </div> + * // </div> + * ``` + * + * @example <caption>With an existing cheerio instance</caption> + * + * ```js + * const $ = cheerio.load( + * '<span>Span 1</span><strong>Strong</strong><span>Span 2</span>' + * ); + * const wrap = $('<div><p><em><b></b></em></p></div>'); + * $('span').wrapAll(wrap); + * + * //=> <div> + * // <p> + * // <em> + * // <b> + * // <span>Span 1</span> + * // <span>Span 2</span> + * // </b> + * // </em> + * // </p> + * // </div> + * // <strong>Strong</strong> + * ``` + * + * @param wrapper - The DOM structure to wrap around all matched elements in the + * selection. + * @returns The instance itself. + * @see {@link https://api.jquery.com/wrapAll/} */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; +function wrapAll(wrapper) { + var el = this[0]; + if (el) { + var wrap_2 = this._make(typeof wrapper === 'function' ? wrapper.call(el, 0, el) : wrapper).insertBefore(el); + // If html is given as wrapper, wrap may contain text elements + var elInsertLocation = void 0; + for (var i = 0; i < wrap_2.length; i++) { + if (wrap_2[i].type === 'tag') + elInsertLocation = wrap_2[i]; + } + var j = 0; + /* + * Find the deepest child. Only consider the first tag child of each node + * (ignore text); stop if no children are found. + */ + while (elInsertLocation && j < elInsertLocation.children.length) { + var child = elInsertLocation.children[j]; + if (child.type === 'tag') { + elInsertLocation = child; + j = 0; + } + else { + j++; + } + } + if (elInsertLocation) + this._make(elInsertLocation).append(this); + } + return this; } - -module.exports = hashClear; - - -/***/ }), -/* 370 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var getNative = __webpack_require__(371); - -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); - -module.exports = nativeCreate; - - -/***/ }), -/* 371 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var baseIsNative = __webpack_require__(372), - getValue = __webpack_require__(376); - +exports.wrapAll = wrapAll; +/* eslint-disable jsdoc/check-param-names*/ /** - * Gets the native function at `key` of `object`. + * Insert content next to each element in the set of matched elements. * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. + * @category Manipulation + * @example + * + * ```js + * $('.apple').after('<li class="plum">Plum</li>'); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="apple">Apple</li> + * // <li class="plum">Plum</li> + * // <li class="orange">Orange</li> + * // <li class="pear">Pear</li> + * // </ul> + * ``` + * + * @param content - HTML string, DOM element, array of DOM elements or Cheerio + * to insert after each element in the set of matched elements. + * @returns The instance itself. + * @see {@link https://api.jquery.com/after/} */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; +function after() { + var _this = this; + var elems = []; + for (var _i = 0; _i < arguments.length; _i++) { + elems[_i] = arguments[_i]; + } + var lastIdx = this.length - 1; + return utils_1.domEach(this, function (el, i) { + var parent = el.parent; + if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) { + return; + } + var siblings = parent.children; + var index = siblings.indexOf(el); + // If not found, move on + /* istanbul ignore next */ + if (index < 0) + return; + var domSrc = typeof elems[0] === 'function' + ? elems[0].call(el, i, static_1.html(el.children)) + : elems; + var dom = _this._makeDomArray(domSrc, i < lastIdx); + // Add element after `this` element + uniqueSplice(siblings, index + 1, 0, dom, parent); + }); } - -module.exports = getNative; - - -/***/ }), -/* 372 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var isFunction = __webpack_require__(45), - isMasked = __webpack_require__(373), - isObject = __webpack_require__(52), - toSource = __webpack_require__(375); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - +exports.after = after; +/* eslint-enable jsdoc/check-param-names*/ /** - * The base implementation of `_.isNative` without bad shim checks. + * Insert every element in the set of matched elements after the target. * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. + * @category Manipulation + * @example + * + * ```js + * $('<li class="plum">Plum</li>').insertAfter('.apple'); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="apple">Apple</li> + * // <li class="plum">Plum</li> + * // <li class="orange">Orange</li> + * // <li class="pear">Pear</li> + * // </ul> + * ``` + * + * @param target - Element to insert elements after. + * @returns The set of newly inserted elements. + * @see {@link https://api.jquery.com/insertAfter/} */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); +function insertAfter(target) { + var _this = this; + if (typeof target === 'string') { + target = this._make(target); + } + this.remove(); + var clones = []; + this._makeDomArray(target).forEach(function (el) { + var clonedSelf = _this.clone().toArray(); + var parent = el.parent; + if (!parent) { + return; + } + var siblings = parent.children; + var index = siblings.indexOf(el); + // If not found, move on + /* istanbul ignore next */ + if (index < 0) + return; + // Add cloned `this` element(s) after target element + uniqueSplice(siblings, index + 1, 0, clonedSelf, parent); + clones.push.apply(clones, clonedSelf); + }); + return this._make(clones); } - -module.exports = baseIsNative; - - -/***/ }), -/* 373 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var coreJsData = __webpack_require__(374); - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - +exports.insertAfter = insertAfter; +/* eslint-disable jsdoc/check-param-names*/ /** - * Checks if `func` has its source masked. + * Insert content previous to each element in the set of matched elements. * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. + * @category Manipulation + * @example + * + * ```js + * $('.apple').before('<li class="plum">Plum</li>'); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="plum">Plum</li> + * // <li class="apple">Apple</li> + * // <li class="orange">Orange</li> + * // <li class="pear">Pear</li> + * // </ul> + * ``` + * + * @param content - HTML string, DOM element, array of DOM elements or Cheerio + * to insert before each element in the set of matched elements. + * @returns The instance itself. + * @see {@link https://api.jquery.com/before/} */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); +function before() { + var _this = this; + var elems = []; + for (var _i = 0; _i < arguments.length; _i++) { + elems[_i] = arguments[_i]; + } + var lastIdx = this.length - 1; + return utils_1.domEach(this, function (el, i) { + var parent = el.parent; + if (!htmlparser2_1.DomUtils.hasChildren(el) || !parent) { + return; + } + var siblings = parent.children; + var index = siblings.indexOf(el); + // If not found, move on + /* istanbul ignore next */ + if (index < 0) + return; + var domSrc = typeof elems[0] === 'function' + ? elems[0].call(el, i, static_1.html(el.children)) + : elems; + var dom = _this._makeDomArray(domSrc, i < lastIdx); + // Add element before `el` element + uniqueSplice(siblings, index, 0, dom, parent); + }); } - -module.exports = isMasked; - - -/***/ }), -/* 374 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var root = __webpack_require__(48); - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -module.exports = coreJsData; - - -/***/ }), -/* 375 */ -/***/ ((module) => { - -/** Used for built-in method references. */ -var funcProto = Function.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - +exports.before = before; +/* eslint-enable jsdoc/check-param-names*/ /** - * Converts `func` to its source code. + * Insert every element in the set of matched elements before the target. * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. + * @category Manipulation + * @example + * + * ```js + * $('<li class="plum">Plum</li>').insertBefore('.apple'); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="plum">Plum</li> + * // <li class="apple">Apple</li> + * // <li class="orange">Orange</li> + * // <li class="pear">Pear</li> + * // </ul> + * ``` + * + * @param target - Element to insert elements before. + * @returns The set of newly inserted elements. + * @see {@link https://api.jquery.com/insertBefore/} */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; +function insertBefore(target) { + var _this = this; + var targetArr = this._make(target); + this.remove(); + var clones = []; + utils_1.domEach(targetArr, function (el) { + var clonedSelf = _this.clone().toArray(); + var parent = el.parent; + if (!parent) { + return; + } + var siblings = parent.children; + var index = siblings.indexOf(el); + // If not found, move on + /* istanbul ignore next */ + if (index < 0) + return; + // Add cloned `this` element(s) after target element + uniqueSplice(siblings, index, 0, clonedSelf, parent); + clones.push.apply(clones, clonedSelf); + }); + return this._make(clones); } - -module.exports = toSource; - - -/***/ }), -/* 376 */ -/***/ ((module) => { - +exports.insertBefore = insertBefore; /** - * Gets the value at `key` of `object`. + * Removes the set of matched elements from the DOM and all their children. + * `selector` filters the set of matched elements to be removed. * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. + * @category Manipulation + * @example + * + * ```js + * $('.pear').remove(); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="apple">Apple</li> + * // <li class="orange">Orange</li> + * // </ul> + * ``` + * + * @param selector - Optional selector for elements to remove. + * @returns The instance itself. + * @see {@link https://api.jquery.com/remove/} */ -function getValue(object, key) { - return object == null ? undefined : object[key]; +function remove(selector) { + // Filter if we have selector + var elems = selector ? this.filter(selector) : this; + utils_1.domEach(elems, function (el) { + htmlparser2_1.DomUtils.removeElement(el); + el.prev = el.next = el.parent = null; + }); + return this; } - -module.exports = getValue; - - -/***/ }), -/* 377 */ -/***/ ((module) => { - +exports.remove = remove; /** - * Removes `key` and its value from the hash. + * Replaces matched elements with `content`. * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. + * @category Manipulation + * @example + * + * ```js + * const plum = $('<li class="plum">Plum</li>'); + * $('.pear').replaceWith(plum); + * $.html(); + * //=> <ul id="fruits"> + * // <li class="apple">Apple</li> + * // <li class="orange">Orange</li> + * // <li class="plum">Plum</li> + * // </ul> + * ``` + * + * @param content - Replacement for matched elements. + * @returns The instance itself. + * @see {@link https://api.jquery.com/replaceWith/} */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; +function replaceWith(content) { + var _this = this; + return utils_1.domEach(this, function (el, i) { + var parent = el.parent; + if (!parent) { + return; + } + var siblings = parent.children; + var cont = typeof content === 'function' ? content.call(el, i, el) : content; + var dom = _this._makeDomArray(cont); + /* + * In the case that `dom` contains nodes that already exist in other + * structures, ensure those nodes are properly removed. + */ + parse_1.update(dom, null); + var index = siblings.indexOf(el); + // Completely remove old element + uniqueSplice(siblings, index, 1, dom, parent); + if (!dom.includes(el)) { + el.parent = el.prev = el.next = null; + } + }); } - -module.exports = hashDelete; - - -/***/ }), -/* 378 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var nativeCreate = __webpack_require__(370); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - +exports.replaceWith = replaceWith; /** - * Gets the hash value for `key`. + * Empties an element, removing all its children. * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. + * @category Manipulation + * @example + * + * ```js + * $('ul').empty(); + * $.html(); + * //=> <ul id="fruits"></ul> + * ``` + * + * @returns The instance itself. + * @see {@link https://api.jquery.com/empty/} */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; +function empty() { + return utils_1.domEach(this, function (el) { + if (!htmlparser2_1.DomUtils.hasChildren(el)) + return; + el.children.forEach(function (child) { + child.next = child.prev = child.parent = null; + }); + el.children.length = 0; + }); } - -module.exports = hashGet; - - -/***/ }), -/* 379 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var nativeCreate = __webpack_require__(370); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - +exports.empty = empty; +function html(str) { + if (str === undefined) { + var el = this[0]; + if (!el || !htmlparser2_1.DomUtils.hasChildren(el)) + return null; + return static_1.html(el.children, this.options); + } + // Keep main options unchanged + var opts = tslib_1.__assign(tslib_1.__assign({}, this.options), { context: null }); + return utils_1.domEach(this, function (el) { + if (!htmlparser2_1.DomUtils.hasChildren(el)) + return; + el.children.forEach(function (child) { + child.next = child.prev = child.parent = null; + }); + opts.context = el; + var content = utils_1.isCheerio(str) + ? str.toArray() + : parse_1.default("" + str, opts, false).children; + parse_1.update(content, el); + }); +} +exports.html = html; /** - * Checks if a hash value for `key` exists. + * Turns the collection to a string. Alias for `.html()`. * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @category Manipulation + * @returns The rendered document. */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); +function toString() { + return static_1.html(this, this.options); } - -module.exports = hashHas; - - -/***/ }), -/* 380 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var nativeCreate = __webpack_require__(370); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - +exports.toString = toString; +function text(str) { + var _this = this; + // If `str` is undefined, act as a "getter" + if (str === undefined) { + return static_1.text(this); + } + if (typeof str === 'function') { + // Function support + return utils_1.domEach(this, function (el, i) { + text.call(_this._make(el), str.call(el, i, static_1.text([el]))); + }); + } + // Append text node to each selected elements + return utils_1.domEach(this, function (el) { + if (!htmlparser2_1.DomUtils.hasChildren(el)) + return; + el.children.forEach(function (child) { + child.next = child.prev = child.parent = null; + }); + var textNode = new domhandler_2.Text(str); + parse_1.update(textNode, el); + }); +} +exports.text = text; /** - * Sets the hash `key` to `value`. + * Clone the cheerio object. * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. + * @category Manipulation + * @example + * + * ```js + * const moreFruit = $('#fruits').clone(); + * ``` + * + * @returns The cloned object. + * @see {@link https://api.jquery.com/clone/} */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; +function clone() { + return this._make(utils_1.cloneDom(this.get())); } - -module.exports = hashSet; +exports.clone = clone; /***/ }), -/* 381 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 351 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -var listCacheClear = __webpack_require__(382), - listCacheDelete = __webpack_require__(383), - listCacheGet = __webpack_require__(386), - listCacheHas = __webpack_require__(387), - listCacheSet = __webpack_require__(388); +"use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.css = void 0; +var utils_1 = __webpack_require__(347); +function css(prop, val) { + if ((prop != null && val != null) || + // When `prop` is a "plain" object + (typeof prop === 'object' && !Array.isArray(prop))) { + return utils_1.domEach(this, function (el, i) { + if (utils_1.isTag(el)) { + // `prop` can't be an array here anymore. + setCss(el, prop, val, i); + } + }); + } + return getCss(this[0], prop); +} +exports.css = css; /** - * Creates an list cache object. + * Set styles of all elements. * * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. + * @param el - Element to set style of. + * @param prop - Name of property. + * @param value - Value to set property to. + * @param idx - Optional index within the selection. */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } +function setCss(el, prop, value, idx) { + if (typeof prop === 'string') { + var styles = getCss(el); + var val = typeof value === 'function' ? value.call(el, idx, styles[prop]) : value; + if (val === '') { + delete styles[prop]; + } + else if (val != null) { + styles[prop] = val; + } + el.attribs.style = stringify(styles); + } + else if (typeof prop === 'object') { + Object.keys(prop).forEach(function (k, i) { + setCss(el, k, prop[k], i); + }); + } +} +function getCss(el, prop) { + if (!el || !utils_1.isTag(el)) + return; + var styles = parse(el.attribs.style); + if (typeof prop === 'string') { + return styles[prop]; + } + if (Array.isArray(prop)) { + var newStyles_1 = {}; + prop.forEach(function (item) { + if (styles[item] != null) { + newStyles_1[item] = styles[item]; + } + }); + return newStyles_1; + } + return styles; } - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; - - -/***/ }), -/* 382 */ -/***/ ((module) => { - /** - * Removes all key-value entries from the list cache. + * Stringify `obj` to styles. * * @private - * @name clear - * @memberOf ListCache + * @category CSS + * @param obj - Object to stringify. + * @returns The serialized styles. */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; +function stringify(obj) { + return Object.keys(obj).reduce(function (str, prop) { return "" + str + (str ? ' ' : '') + prop + ": " + obj[prop] + ";"; }, ''); } - -module.exports = listCacheClear; - - -/***/ }), -/* 383 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var assocIndexOf = __webpack_require__(384); - -/** Used for built-in method references. */ -var arrayProto = Array.prototype; - -/** Built-in value references. */ -var splice = arrayProto.splice; - /** - * Removes `key` and its value from the list cache. + * Parse `styles`. * * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. + * @category CSS + * @param styles - Styles to be parsed. + * @returns The parsed styles. */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; +function parse(styles) { + styles = (styles || '').trim(); + if (!styles) + return {}; + return styles.split(';').reduce(function (obj, str) { + var n = str.indexOf(':'); + // Skip if there is no :, or if it is the first/last character + if (n < 1 || n === str.length - 1) + return obj; + obj[str.slice(0, n).trim()] = str.slice(n + 1).trim(); + return obj; + }, {}); } -module.exports = listCacheDelete; - /***/ }), -/* 384 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 352 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -var eq = __webpack_require__(385); +"use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.serializeArray = exports.serialize = void 0; +var utils_1 = __webpack_require__(347); +/* + * https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js + * https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js + */ +var submittableSelector = 'input,select,textarea,keygen'; +var r20 = /%20/g; +var rCRLF = /\r?\n/g; /** - * Gets the index at which the `key` is found in `array` of key-value pairs. + * Encode a set of form elements as a string for submission. * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. + * @category Forms + * @returns The serialized form. + * @see {@link https://api.jquery.com/serialize/} */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; +function serialize() { + // Convert form elements into name/value objects + var arr = this.serializeArray(); + // Serialize each element into a key/value string + var retArr = arr.map(function (data) { + return encodeURIComponent(data.name) + "=" + encodeURIComponent(data.value); + }); + // Return the resulting serialization + return retArr.join('&').replace(r20, '+'); } - -module.exports = assocIndexOf; - - -/***/ }), -/* 385 */ -/***/ ((module) => { - +exports.serialize = serialize; /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. + * Encode a set of form elements as an array of names and values. * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @category Forms * @example * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false + * ```js + * $('<form><input name="foo" value="bar" /></form>').serializeArray(); + * //=> [ { name: 'foo', value: 'bar' } ] + * ``` * - * _.eq(NaN, NaN); - * // => true + * @returns The serialized form. + * @see {@link https://api.jquery.com/serializeArray/} */ -function eq(value, other) { - return value === other || (value !== value && other !== other); +function serializeArray() { + var _this = this; + // Resolve all form elements from either forms or collections of form elements + return this.map(function (_, elem) { + var $elem = _this._make(elem); + if (utils_1.isTag(elem) && elem.name === 'form') { + return $elem.find(submittableSelector).toArray(); + } + return $elem.filter(submittableSelector).toArray(); + }) + .filter( + // Verify elements have a name (`attr.name`) and are not disabled (`:enabled`) + '[name!=""]:enabled' + + // And cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`) + ':not(:submit, :button, :image, :reset, :file)' + + // And are either checked/don't have a checkable state + ':matches([checked], :not(:checkbox, :radio))' + // Convert each of the elements to its value(s) + ) + .map(function (_, elem) { + var _a; + var $elem = _this._make(elem); + var name = $elem.attr('name'); // We have filtered for elements with a name before. + // If there is no value set (e.g. `undefined`, `null`), then default value to empty + var value = (_a = $elem.val()) !== null && _a !== void 0 ? _a : ''; + // If we have an array of values (e.g. `<select multiple>`), return an array of key/value pairs + if (Array.isArray(value)) { + return value.map(function (val) { + /* + * We trim replace any line endings (e.g. `\r` or `\r\n` with `\r\n`) to guarantee consistency across platforms + * These can occur inside of `<textarea>'s` + */ + return ({ name: name, value: val.replace(rCRLF, '\r\n') }); + }); + } + // Otherwise (e.g. `<input type="text">`, return only one key/value pair + return { name: name, value: value.replace(rCRLF, '\r\n') }; + }) + .toArray(); } - -module.exports = eq; +exports.serializeArray = serializeArray; /***/ }), -/* 386 */ +/* 353 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var assocIndexOf = __webpack_require__(384); - /** - * Gets the list cache value for `key`. + * Filters the passed array from data already present in the cozy so that there is + * not duplicated data in the Cozy. * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. + * @module hydrateAndFilter */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; -} - -module.exports = listCacheGet; +const bluebird = __webpack_require__(5); +const log = (__webpack_require__(354).namespace)('hydrateAndFilter'); -/***/ }), -/* 387 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +const get = __webpack_require__(370); -var assocIndexOf = __webpack_require__(384); +const uniqBy = __webpack_require__(412); +const { + queryAll +} = __webpack_require__(484); /** - * Checks if a list cache value for `key` exists. + * Since we can use methods or basic functions for + * `shouldSave` and `shouldUpdate` we pass the + * appropriate `this` and `arguments`. * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * If `funcOrMethod` is a method, it will be called + * with args[0] as `this` and the rest as `arguments` + * Otherwise, `this` will be null and `args` will be passed + * as `arguments`. */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -module.exports = listCacheHas; - - -/***/ }), -/* 388 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var assocIndexOf = __webpack_require__(384); -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); +const suitableCall = (funcOrMethod, ...args) => { + const arity = funcOrMethod.length; - if (index < 0) { - ++this.size; - data.push([key, value]); + if (arity < args.length) { + // must be a method + return funcOrMethod.apply(args[0], args.slice(1)); } else { - data[index][1] = value; + // must be a function + return funcOrMethod.apply(null, args); } - return this; -} - -module.exports = listCacheSet; - - -/***/ }), -/* 389 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var getNative = __webpack_require__(371), - root = __webpack_require__(48); - -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); - -module.exports = Map; - - -/***/ }), -/* 390 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var getMapData = __webpack_require__(391); - +}; /** - * Removes `key` and its value from the map. + * Filters the passed array from data already present in the cozy so that there is + * not duplicated data in the Cozy. * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} - -module.exports = mapCacheDelete; - - -/***/ }), -/* 391 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var isKeyable = __webpack_require__(392); - -/** - * Gets the data for `map`. + * You need at least the `GET` permission for the given doctype in your manifest, to be able to + * use this function. * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - - -/***/ }), -/* 392 */ -/***/ ((module) => { - -/** - * Checks if `value` is suitable for use as unique object key. + * Parameters: * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + * `documents`: an array of objects corresponding to the data you want to save in the cozy + * `doctype` (string): the doctype where you want to save data (ex: 'io.cozy.bills') + * `options` : + * - `keys` (array) : List of keys used to check that two items are the same. By default it is set to `['id']'. + * - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype. + * - `selector` (optionnal object) : Mango request to get records. Default is built from the keys `{selector: {_id: {"$gt": null}}}` to get all the records. + * + * ```javascript + * const documents = [ + * { + * name: 'toto', + * height: 1.8 + * }, + * { + * name: 'titi', + * height: 1.7 + * } + * ] + * + * return hydrateAndFilter(documents, 'io.cozy.height', { + * keys: ['name'] + * }).then(filteredDocuments => addData(filteredDocuments, 'io.cozy.height')) + * + * ``` + * + * @alias module:hydrateAndFilter + */ -module.exports = isKeyable; +const hydrateAndFilter = (documents = [], doctype, options = {}) => { + const cozy = __webpack_require__(485); -/***/ }), -/* 393 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + log('debug', `${documents.length} items before hydrateAndFilter`); + if (!doctype) return Promise.reject(new Error(`Doctype is mandatory to filter the connector data.`)); + const keys = options.keys ? options.keys : ['_id']; + const store = {}; -var getMapData = __webpack_require__(391); + const createHash = item => { + return keys.map(key => { + let result = get(item, key); + if (key === 'date') result = new Date(result); + return result; + }).join('####'); + }; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + const getIndex = () => { + const index = options.index ? Promise.resolve(options.index) : cozy.data.defineIndex(doctype, keys); + return index; + }; -module.exports = mapCacheGet; + const getItems = async index => { + const selector = options.selector ? options.selector : null; + return await queryAll(doctype, selector, index); + }; + const populateStore = store => dbitems => { + dbitems.forEach(dbitem => { + store[createHash(dbitem)] = dbitem; + }); + }; // We add _id to `documents` that we find in the database. + // This is useful when linking with bank operations (a bill + // can already be in the database but not already matched + // to an operation) since the linking operation need the _id + // of the document -/***/ }), -/* 394 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var getMapData = __webpack_require__(391); + const hydrateExistingEntries = store => () => { + documents.forEach(document => { + const key = createHash(document); -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + if (store[key]) { + document._id = store[key]._id; + document._rev = store[key]._rev; + if (!document.cozyMetadata && store[key].cozyMetadata) document.cozyMetadata = store[key].cozyMetadata; + } + }); + return documents; + }; -module.exports = mapCacheHas; + const defaultShouldSave = () => true; + const defaultShouldUpdate = existing => false; // eslint-disable-line no-unused-vars -/***/ }), -/* 395 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var getMapData = __webpack_require__(391); + const filterEntries = store => async () => { + // Filter out items according to shouldSave / shouldUpdate. + // Both can be passed as option or can be part of the entry. + return uniqBy(await bluebird.filter(documents, entry => { + const shouldSave = entry.shouldSave || options.shouldSave || defaultShouldSave; + const shouldUpdate = entry.shouldUpdate || options.shouldUpdate || defaultShouldUpdate; + const existing = store[createHash(entry)]; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + if (existing) { + return suitableCall(shouldUpdate, entry, existing); + } else { + return suitableCall(shouldSave, entry); + } + }), entry => entry && entry._id || entry); + }; - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + const formatOutput = entries => { + log('debug', `${entries.length} items after hydrateAndFilter`); + return entries; + }; -module.exports = mapCacheSet; + return getIndex().then(getItems).then(populateStore(store)).then(hydrateExistingEntries(store)).then(filterEntries(store)).then(entries => entries.filter(Boolean)) // Filter out wrong entries + .then(formatOutput); +}; +module.exports = hydrateAndFilter; /***/ }), -/* 396 */ +/* 354 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseToString = __webpack_require__(397); +const { filterLevel, filterSecrets } = __webpack_require__(355) +const Secret = __webpack_require__(356) +const { LOG_LEVEL } = process.env +let level = LOG_LEVEL || 'debug' +const format = __webpack_require__(357) +const filters = [filterLevel, filterSecrets] + +const filterOut = function () { + for (const filter of filters) { + if (filter.apply(null, arguments) === false) { + return true + } + } + return false +} /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. + * Use it to log messages in your konnector. Typical types are * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example + * - `debug` + * - `warning` + * - `info` + * - `error` + * - `ok` * - * _.toString(null); - * // => '' * - * _.toString(-0); - * // => '-0' + * @example * - * _.toString([1, 2, 3]); - * // => '1,2,3' + * They will be colored in development mode. In production mode, those logs are formatted in JSON to be interpreted by the stack and possibly sent to the client. `error` will stop the konnector. + * + * ```js + * logger = log('my-namespace') + * logger('debug', '365 bills') + * // my-namespace : debug : 365 bills + * logger('info', 'Page fetched') + * // my-namespace : info : Page fetched + * ``` + * @param {string} type + * @param {string} message + * @param {string} label + * @param {string} namespace */ -function toString(value) { - return value == null ? '' : baseToString(value); +function log(type, message, label, namespace) { + if (filterOut(level, type, message, label, namespace)) { + return + } + // eslint-disable-next-line no-console + console.log(format(type, message, label, namespace)) } -module.exports = toString; - - -/***/ }), -/* 397 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +log.addFilter = function (filter) { + return filters.push(filter) +} -var Symbol = __webpack_require__(47), - arrayMap = __webpack_require__(398), - isArray = __webpack_require__(55), - isSymbol = __webpack_require__(362); +log.setLevel = function (lvl) { + level = lvl +} -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +// Short-hands +const methods = ['debug', 'info', 'warn', 'error', 'ok', 'critical'] +methods.forEach(level => { + log[level] = function (message, label, namespace) { + return log(level, message, label, namespace) + } +}) -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +module.exports = log -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; +log.setNoRetry = obj => { + if (obj) obj.no_retry = true + else obj = { no_retry: true } + return obj.no_retry +} +log.Secret = Secret +log.namespace = function (namespace) { + return function (type, message, label, ns = namespace) { + log(type, message, label, ns) } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } -module.exports = baseToString; - /***/ }), -/* 398 */ -/***/ ((module) => { +/* 355 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); +const levels = { + secret: 0, + debug: 10, + info: 20, + warn: 30, + error: 40, + ok: 50, + critical: 50 +} - while (++index < length) { - result[index] = iteratee(array[index], index, array); +const Secret = __webpack_require__(356) + +const filterSecrets = function (level, type, message) { + if (type !== 'secret' && message instanceof Secret) { + throw new Error('You should log a secret with log.secret') } - return result; } -module.exports = arrayMap; +const filterLevel = function (level, type) { + return levels[type] >= levels[level] +} +module.exports = { + filterSecrets, + filterLevel +} -/***/ }), -/* 399 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var isSymbol = __webpack_require__(362); +/***/ }), +/* 356 */ +/***/ ((module) => { -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +const Secret = function (data) { + Object.assign(this, data) + return this +} -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +Secret.prototype.toString = function () { + throw new Error('Cannot convert Secret to string') } -module.exports = toKey; +module.exports = Secret /***/ }), -/* 400 */ +/* 357 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseIteratee = __webpack_require__(401), - baseUniq = __webpack_require__(463); +const prodFormat = __webpack_require__(358) +const devFormat = __webpack_require__(359) -/** - * This method is like `_.uniq` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the criterion by which - * uniqueness is computed. The order of result values is determined by the - * order they occur in the array. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniqBy([2.1, 1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ -function uniqBy(array, iteratee) { - return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : []; +switch (process.env.NODE_ENV) { + case 'production': + module.exports = prodFormat + break + case 'development': + module.exports = devFormat + break + case 'standalone': + module.exports = devFormat + break + case 'test': + module.exports = devFormat + break + default: + module.exports = prodFormat } -module.exports = uniqBy; - /***/ }), -/* 401 */ +/* 358 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseMatches = __webpack_require__(402), - baseMatchesProperty = __webpack_require__(455), - identity = __webpack_require__(459), - isArray = __webpack_require__(55), - property = __webpack_require__(460); +const stringify = __webpack_require__(75) -/** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ -function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; +const LOG_LENGTH_LIMIT = 64 * 1024 - 1 + +function prodFormat(type, message, label, namespace) { + const log = { time: new Date(), type, label, namespace } + + if (typeof message === 'object') { + if (message && message.no_retry) { + log.no_retry = message.no_retry + } + if (message && message.message) { + log.message = message.message + } + } else { + log.message = message } - if (value == null) { - return identity; + + // properly display error messages + if (log.message && log.message.stack) { + log.message = log.message.stack } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); + + // cut the string to avoid a fail in the stack + let result = log + try { + result = stringify(log).substr(0, LOG_LENGTH_LIMIT) + } catch (err) { + // eslint-disable-next-line no-console + console.log(err.message, 'cozy-logger: Failed to convert message to JSON') } - return property(value); + return result } -module.exports = baseIteratee; +module.exports = prodFormat /***/ }), -/* 402 */ +/* 359 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseIsMatch = __webpack_require__(403), - getMatchData = __webpack_require__(452), - matchesStrictComparable = __webpack_require__(454); +const util = __webpack_require__(64) +const chalk = __webpack_require__(360) -/** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ -function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; +if (util && util.inspect && util.inspect.defaultOptions) { + util.inspect.defaultOptions.maxArrayLength = null + util.inspect.defaultOptions.depth = 2 + util.inspect.defaultOptions.colors = true } -module.exports = baseMatches; - - -/***/ }), -/* 403 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +const type2color = { + debug: 'cyan', + warn: 'yellow', + info: 'blue', + error: 'red', + ok: 'green', + secret: 'red', + critical: 'red' +} -var Stack = __webpack_require__(404), - baseIsEqual = __webpack_require__(410); +function devFormat(type, message, label, namespace) { + let formatmessage = message -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; + if (typeof formatmessage !== 'string') { + formatmessage = util.inspect(formatmessage) + } -/** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ -function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; + let formatlabel = label ? ` : "${label}" ` : '' + let formatnamespace = namespace ? chalk.magenta(`${namespace}: `) : '' - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; + let color = type2color[type] + let formattype = color ? chalk[color](type) : type - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) - : result - )) { - return false; - } - } - } - return true; + return `${formatnamespace}${formattype}${formatlabel} : ${formatmessage}` } -module.exports = baseIsMatch; +module.exports = devFormat /***/ }), -/* 404 */ +/* 360 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var ListCache = __webpack_require__(381), - stackClear = __webpack_require__(405), - stackDelete = __webpack_require__(406), - stackGet = __webpack_require__(407), - stackHas = __webpack_require__(408), - stackSet = __webpack_require__(409); +"use strict"; -/** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Stack(entries) { - var data = this.__data__ = new ListCache(entries); - this.size = data.size; -} +const escapeStringRegexp = __webpack_require__(361); +const ansiStyles = __webpack_require__(362); +const stdoutColor = (__webpack_require__(367).stdout); -// Add methods to `Stack`. -Stack.prototype.clear = stackClear; -Stack.prototype['delete'] = stackDelete; -Stack.prototype.get = stackGet; -Stack.prototype.has = stackHas; -Stack.prototype.set = stackSet; +const template = __webpack_require__(369); -module.exports = Stack; +const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; -/***/ }), -/* 405 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +// `color-convert` models to exclude from the Chalk API due to conflicts and such +const skipModels = new Set(['gray']); -var ListCache = __webpack_require__(381); +const styles = Object.create(null); -/** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ -function stackClear() { - this.__data__ = new ListCache; - this.size = 0; +function applyOptions(obj, options) { + options = options || {}; + + // Detect level if not set manually + const scLevel = stdoutColor ? stdoutColor.level : 0; + obj.level = options.level === undefined ? scLevel : options.level; + obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; } -module.exports = stackClear; +function Chalk(options) { + // We check for this.template here since calling `chalk.constructor()` + // by itself will have a `this` of a previously constructed chalk object + if (!this || !(this instanceof Chalk) || this.template) { + const chalk = {}; + applyOptions(chalk, options); + chalk.template = function () { + const args = [].slice.call(arguments); + return chalkTag.apply(null, [chalk.template].concat(args)); + }; -/***/ }), -/* 406 */ -/***/ ((module) => { + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); -/** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); + chalk.template.constructor = Chalk; - this.size = data.size; - return result; -} + return chalk.template; + } -module.exports = stackDelete; + applyOptions(this, options); +} +// Use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001B[94m'; +} -/***/ }), -/* 407 */ -/***/ ((module) => { +for (const key of Object.keys(ansiStyles)) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); -/** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function stackGet(key) { - return this.__data__.get(key); + styles[key] = { + get() { + const codes = ansiStyles[key]; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + } + }; } -module.exports = stackGet; - +styles.visible = { + get() { + return build.call(this, this._styles || [], true, 'visible'); + } +}; -/***/ }), -/* 408 */ -/***/ ((module) => { +ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); +for (const model of Object.keys(ansiStyles.color.ansi)) { + if (skipModels.has(model)) { + continue; + } -/** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function stackHas(key) { - return this.__data__.has(key); + styles[model] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.color.close, + closeRe: ansiStyles.color.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; } -module.exports = stackHas; +ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); +for (const model of Object.keys(ansiStyles.bgColor.ansi)) { + if (skipModels.has(model)) { + continue; + } + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); + styles[bgModel] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.bgColor.close, + closeRe: ansiStyles.bgColor.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; +} -/***/ }), -/* 409 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +const proto = Object.defineProperties(() => {}, styles); -var ListCache = __webpack_require__(381), - Map = __webpack_require__(389), - MapCache = __webpack_require__(366); +function build(_styles, _empty, key) { + const builder = function () { + return applyStyle.apply(builder, arguments); + }; -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE = 200; + builder._styles = _styles; + builder._empty = _empty; -/** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ -function stackSet(key, value) { - var data = this.__data__; - if (data instanceof ListCache) { - var pairs = data.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; -} + const self = this; -module.exports = stackSet; + Object.defineProperty(builder, 'level', { + enumerable: true, + get() { + return self.level; + }, + set(level) { + self.level = level; + } + }); + Object.defineProperty(builder, 'enabled', { + enumerable: true, + get() { + return self.enabled; + }, + set(enabled) { + self.enabled = enabled; + } + }); -/***/ }), -/* 410 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + // See below for fix regarding invisible grey/dim combination on Windows + builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; -var baseIsEqualDeep = __webpack_require__(411), - isObjectLike = __webpack_require__(53); + // `__proto__` is used because we must return a function, but there is + // no way to create a function with a different prototype + builder.__proto__ = proto; // eslint-disable-line no-proto -/** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ -function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + return builder; } -module.exports = baseIsEqual; - +function applyStyle() { + // Support varags, but simply cast to string in case there's only one arg + const args = arguments; + const argsLen = args.length; + let str = String(arguments[0]); -/***/ }), -/* 411 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (argsLen === 0) { + return ''; + } -var Stack = __webpack_require__(404), - equalArrays = __webpack_require__(412), - equalByTag = __webpack_require__(418), - equalObjects = __webpack_require__(422), - getTag = __webpack_require__(447), - isArray = __webpack_require__(55), - isBuffer = __webpack_require__(434), - isTypedArray = __webpack_require__(437); + if (argsLen > 1) { + // Don't slice `arguments`, it prevents V8 optimizations + for (let a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1; + if (!this.enabled || this.level <= 0 || !str) { + return this._empty ? '' : str; + } -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - objectTag = '[object Object]'; + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, + // see https://github.com/chalk/chalk/issues/58 + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. + const originalDim = ansiStyles.dim.open; + if (isSimpleWindowsTerm && this.hasGrey) { + ansiStyles.dim.open = ''; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + for (const code of this._styles.slice().reverse()) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + // Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS + // https://github.com/chalk/chalk/pull/92 + str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + } -/** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = objIsArr ? arrayTag : getTag(object), - othTag = othIsArr ? arrayTag : getTag(other); + // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue + ansiStyles.dim.open = originalDim; - objTag = objTag == argsTag ? objectTag : objTag; - othTag = othTag == argsTag ? objectTag : othTag; + return str; +} - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; +function chalkTag(chalk, strings) { + if (!Array.isArray(strings)) { + // If chalk() was called by itself or with a string, + // return the string itself as a string. + return [].slice.call(arguments, 1).join(' '); + } - if (isSameTag && isBuffer(object)) { - if (!isBuffer(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) - : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + const args = [].slice.call(arguments, 2); + const parts = [strings.raw[0]]; - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; + for (let i = 1; i < strings.length; i++) { + parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); + parts.push(String(strings.raw[i])); + } - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + return template(chalk, parts.join('')); } -module.exports = baseIsEqualDeep; +Object.defineProperties(Chalk.prototype, styles); + +module.exports = Chalk(); // eslint-disable-line new-cap +module.exports.supportsColor = stdoutColor; +module.exports["default"] = module.exports; // For TypeScript /***/ }), -/* 412 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 361 */ +/***/ ((module) => { -var SetCache = __webpack_require__(413), - arraySome = __webpack_require__(416), - cacheHas = __webpack_require__(417); +"use strict"; -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; -/** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ -function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - arrLength = array.length, - othLength = other.length; +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Check that cyclic values are equal. - var arrStacked = stack.get(array); - var othStacked = stack.get(other); - if (arrStacked && othStacked) { - return arrStacked == other && othStacked == array; - } - var index = -1, - result = true, - seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } - stack.set(array, other); - stack.set(other, array); + return str.replace(matchOperatorsRe, '\\$&'); +}; - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!cacheHas(seen, othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, bitmask, customizer, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; -} +/***/ }), +/* 362 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -module.exports = equalArrays; +"use strict"; +/* module decorator */ module = __webpack_require__.nmd(module); +const colorConvert = __webpack_require__(363); -/***/ }), -/* 413 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +const wrapAnsi16 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${code + offset}m`; +}; + +const wrapAnsi256 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};5;${code}m`; +}; + +const wrapAnsi16m = (fn, offset) => function () { + const rgb = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +}; -var MapCache = __webpack_require__(366), - setCacheAdd = __webpack_require__(414), - setCacheHas = __webpack_require__(415); +function assembleStyles() { + const codes = new Map(); + const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], -/** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ -function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; + // Bright color + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39] + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } -} + // Bright color + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] + } + }; -// Add methods to `SetCache`. -SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; -SetCache.prototype.has = setCacheHas; + // Fix humans + styles.color.grey = styles.color.gray; -module.exports = SetCache; + for (const groupName of Object.keys(styles)) { + const group = styles[groupName]; + for (const styleName of Object.keys(group)) { + const style = group[styleName]; -/***/ }), -/* 414 */ -/***/ ((module) => { + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m` + }; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + group[styleName] = styles[styleName]; -/** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ -function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; -} + codes.set(style[0], style[1]); + } -module.exports = setCacheAdd; + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); + } -/***/ }), -/* 415 */ -/***/ ((module) => { + const ansi2ansi = n => n; + const rgb2rgb = (r, g, b) => [r, g, b]; -/** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ -function setCacheHas(value) { - return this.__data__.has(value); -} + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; -module.exports = setCacheHas; + styles.color.ansi = { + ansi: wrapAnsi16(ansi2ansi, 0) + }; + styles.color.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 0) + }; + styles.color.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 0) + }; + styles.bgColor.ansi = { + ansi: wrapAnsi16(ansi2ansi, 10) + }; + styles.bgColor.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 10) + }; + styles.bgColor.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 10) + }; -/***/ }), -/* 416 */ -/***/ ((module) => { + for (let key of Object.keys(colorConvert)) { + if (typeof colorConvert[key] !== 'object') { + continue; + } -/** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ -function arraySome(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; + const suite = colorConvert[key]; - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; -} + if (key === 'ansi16') { + key = 'ansi'; + } -module.exports = arraySome; + if ('ansi16' in suite) { + styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); + styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); + } + if ('ansi256' in suite) { + styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); + styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); + } -/***/ }), -/* 417 */ -/***/ ((module) => { + if ('rgb' in suite) { + styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); + styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); + } + } -/** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function cacheHas(cache, key) { - return cache.has(key); + return styles; } -module.exports = cacheHas; +// Make the export immutable +Object.defineProperty(module, 'exports', { + enumerable: true, + get: assembleStyles +}); /***/ }), -/* 418 */ +/* 363 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var Symbol = __webpack_require__(47), - Uint8Array = __webpack_require__(419), - eq = __webpack_require__(385), - equalArrays = __webpack_require__(412), - mapToArray = __webpack_require__(420), - setToArray = __webpack_require__(421); +var conversions = __webpack_require__(364); +var route = __webpack_require__(366); -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; +var convert = {}; -/** `Object#toString` result references. */ -var boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - mapTag = '[object Map]', - numberTag = '[object Number]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]'; +var models = Object.keys(conversions); -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]'; +function wrapRaw(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } -/** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; + return fn(args); + }; - case arrayBufferTag: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array(object), new Uint8Array(other))) { - return false; - } - return true; + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); + return wrappedFn; +} - case errorTag: - return object.name == other.name && object.message == other.message; +function wrapRounded(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } - case mapTag: - var convert = mapToArray; + var result = fn(args); - case setTag: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG; - convert || (convert = setToArray); + // we're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (var len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG; + return result; + }; - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } - case symbolTag: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; + return wrappedFn; } -module.exports = equalByTag; +models.forEach(function (fromModel) { + convert[fromModel] = {}; + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); -/***/ }), -/* 419 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var routes = route(fromModel); + var routeModels = Object.keys(routes); -var root = __webpack_require__(48); + routeModels.forEach(function (toModel) { + var fn = routes[toModel]; -/** Built-in value references. */ -var Uint8Array = root.Uint8Array; + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); -module.exports = Uint8Array; +module.exports = convert; /***/ }), -/* 420 */ -/***/ ((module) => { +/* 364 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ -function mapToArray(map) { - var index = -1, - result = Array(map.size); +/* MIT license */ +var cssKeywords = __webpack_require__(365); - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; +// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) + +var reverseKeywords = {}; +for (var key in cssKeywords) { + if (cssKeywords.hasOwnProperty(key)) { + reverseKeywords[cssKeywords[key]] = key; + } } -module.exports = mapToArray; +var convert = module.exports = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} +}; +// hide .channels and .labels properties +for (var model in convert) { + if (convert.hasOwnProperty(model)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } -/***/ }), -/* 421 */ -/***/ ((module) => { + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } -/** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ -function setToArray(set) { - var index = -1, - result = Array(set.size); + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } - set.forEach(function(value) { - result[++index] = value; - }); - return result; + var channels = convert[model].channels; + var labels = convert[model].labels; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); + } } -module.exports = setToArray; +convert.rgb.hsl = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var delta = max - min; + var h; + var s; + var l; + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; + } -/***/ }), -/* 422 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + h = Math.min(h * 60, 360); -var getAllKeys = __webpack_require__(423); + if (h < 0) { + h += 360; + } -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1; + l = (min + max) / 2; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + return [h, s * 100, l * 100]; +}; -/** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - objProps = getAllKeys(object), - objLength = objProps.length, - othProps = getAllKeys(other), - othLength = othProps.length; +convert.rgb.hsv = function (rgb) { + var rdif; + var gdif; + var bdif; + var h; + var s; - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { - return false; - } - } - // Check that cyclic values are equal. - var objStacked = stack.get(object); - var othStacked = stack.get(other); - if (objStacked && othStacked) { - return objStacked == other && othStacked == object; - } - var result = true; - stack.set(object, other); - stack.set(other, object); + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var v = Math.max(r, g, b); + var diff = v - Math.min(r, g, b); + var diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; + if (diff === 0) { + h = s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; -} + return [ + h * 360, + s * 100, + v * 100 + ]; +}; -module.exports = equalObjects; +convert.rgb.hwb = function (rgb) { + var r = rgb[0]; + var g = rgb[1]; + var b = rgb[2]; + var h = convert.rgb.hsl(rgb)[0]; + var w = 1 / 255 * Math.min(r, Math.min(g, b)); + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); -/***/ }), -/* 423 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return [h, w * 100, b * 100]; +}; + +convert.rgb.cmyk = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var c; + var m; + var y; + var k; + + k = Math.min(1 - r, 1 - g, 1 - b); + c = (1 - r - k) / (1 - k) || 0; + m = (1 - g - k) / (1 - k) || 0; + y = (1 - b - k) / (1 - k) || 0; -var baseGetAllKeys = __webpack_require__(424), - getSymbols = __webpack_require__(426), - keys = __webpack_require__(429); + return [c * 100, m * 100, y * 100, k * 100]; +}; /** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ -function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + * */ +function comparativeDistance(x, y) { + return ( + Math.pow(x[0] - y[0], 2) + + Math.pow(x[1] - y[1], 2) + + Math.pow(x[2] - y[2], 2) + ); } -module.exports = getAllKeys; +convert.rgb.keyword = function (rgb) { + var reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } + var currentClosestDistance = Infinity; + var currentClosestKeyword; -/***/ }), -/* 424 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + for (var keyword in cssKeywords) { + if (cssKeywords.hasOwnProperty(keyword)) { + var value = cssKeywords[keyword]; -var arrayPush = __webpack_require__(425), - isArray = __webpack_require__(55); + // Compute comparative distance + var distance = comparativeDistance(rgb, value); -/** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ -function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); -} + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } + } -module.exports = baseGetAllKeys; + return currentClosestKeyword; +}; +convert.keyword.rgb = function (keyword) { + return cssKeywords[keyword]; +}; -/***/ }), -/* 425 */ -/***/ ((module) => { +convert.rgb.xyz = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; -/** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ -function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; + // assume sRGB + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); - while (++index < length) { - array[offset + index] = values[index]; - } - return array; -} + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); -module.exports = arrayPush; + return [x * 100, y * 100, z * 100]; +}; +convert.rgb.lab = function (rgb) { + var xyz = convert.rgb.xyz(rgb); + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; -/***/ }), -/* 426 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + x /= 95.047; + y /= 100; + z /= 108.883; -var arrayFilter = __webpack_require__(427), - stubArray = __webpack_require__(428); + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); -/** Used for built-in method references. */ -var objectProto = Object.prototype; + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); -/** Built-in value references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; + return [l, a, b]; +}; -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeGetSymbols = Object.getOwnPropertySymbols; +convert.hsl.rgb = function (hsl) { + var h = hsl[0] / 360; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var t1; + var t2; + var t3; + var rgb; + var val; -/** - * Creates an array of the own enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ -var getSymbols = !nativeGetSymbols ? stubArray : function(object) { - if (object == null) { - return []; - } - object = Object(object); - return arrayFilter(nativeGetSymbols(object), function(symbol) { - return propertyIsEnumerable.call(object, symbol); - }); -}; + if (s === 0) { + val = l * 255; + return [val, val, val]; + } -module.exports = getSymbols; + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } + t1 = 2 * l - t2; -/***/ }), -/* 427 */ -/***/ ((module) => { + rgb = [0, 0, 0]; + for (var i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } + if (t3 > 1) { + t3--; + } -/** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ -function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; + if (6 * t3 < 1) { + val = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + val = t2; + } else if (3 * t3 < 2) { + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + val = t1; + } - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; - } - } - return result; -} + rgb[i] = val * 255; + } -module.exports = arrayFilter; + return rgb; +}; +convert.hsl.hsv = function (hsl) { + var h = hsl[0]; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var smin = s; + var lmin = Math.max(l, 0.01); + var sv; + var v; -/***/ }), -/* 428 */ -/***/ ((module) => { + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + v = (l + s) / 2; + sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); -/** - * This method returns a new empty array. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Array} Returns the new empty array. - * @example - * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] - * - * console.log(arrays[0] === arrays[1]); - * // => false - */ -function stubArray() { - return []; -} + return [h, sv * 100, v * 100]; +}; -module.exports = stubArray; +convert.hsv.rgb = function (hsv) { + var h = hsv[0] / 60; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var hi = Math.floor(h) % 6; + var f = h - Math.floor(h); + var p = 255 * v * (1 - s); + var q = 255 * v * (1 - (s * f)); + var t = 255 * v * (1 - (s * (1 - f))); + v *= 255; -/***/ }), -/* 429 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + switch (hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; + } +}; + +convert.hsv.hsl = function (hsv) { + var h = hsv[0]; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var vmin = Math.max(v, 0.01); + var lmin; + var sl; + var l; -var arrayLikeKeys = __webpack_require__(430), - baseKeys = __webpack_require__(442), - isArrayLike = __webpack_require__(446); + l = (2 - s) * v; + lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; -/** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ -function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); -} + return [h, sl * 100, l * 100]; +}; -module.exports = keys; +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + var h = hwb[0] / 360; + var wh = hwb[1] / 100; + var bl = hwb[2] / 100; + var ratio = wh + bl; + var i; + var v; + var f; + var n; + // wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } -/***/ }), -/* 430 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + i = Math.floor(6 * h); + v = 1 - bl; + f = 6 * h - i; -var baseTimes = __webpack_require__(431), - isArguments = __webpack_require__(432), - isArray = __webpack_require__(55), - isBuffer = __webpack_require__(434), - isIndex = __webpack_require__(436), - isTypedArray = __webpack_require__(437); + if ((i & 0x01) !== 0) { + f = 1 - f; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + n = wh + f * (v - wh); // linear interpolation -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var r; + var g; + var b; + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; + } -/** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ -function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; + return [r * 255, g * 255, b * 255]; +}; - for (var key in value) { - if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } - } - return result; -} +convert.cmyk.rgb = function (cmyk) { + var c = cmyk[0] / 100; + var m = cmyk[1] / 100; + var y = cmyk[2] / 100; + var k = cmyk[3] / 100; + var r; + var g; + var b; -module.exports = arrayLikeKeys; + r = 1 - Math.min(1, c * (1 - k) + k); + g = 1 - Math.min(1, m * (1 - k) + k); + b = 1 - Math.min(1, y * (1 - k) + k); + return [r * 255, g * 255, b * 255]; +}; -/***/ }), -/* 431 */ -/***/ ((module) => { +convert.xyz.rgb = function (xyz) { + var x = xyz[0] / 100; + var y = xyz[1] / 100; + var z = xyz[2] / 100; + var r; + var g; + var b; -/** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ -function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - while (++index < n) { - result[index] = iteratee(index); - } - return result; -} + // assume sRGB + r = r > 0.0031308 + ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) + : r * 12.92; -module.exports = baseTimes; + g = g > 0.0031308 + ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + : g * 12.92; + b = b > 0.0031308 + ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + : b * 12.92; -/***/ }), -/* 432 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); -var baseIsArguments = __webpack_require__(433), - isObjectLike = __webpack_require__(53); + return [r * 255, g * 255, b * 255]; +}; -/** Used for built-in method references. */ -var objectProto = Object.prototype; +convert.xyz.lab = function (xyz) { + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + x /= 95.047; + y /= 100; + z /= 108.883; -/** Built-in value references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { - return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + + return [l, a, b]; }; -module.exports = isArguments; +convert.lab.xyz = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var x; + var y; + var z; + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; -/***/ }), -/* 433 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var y2 = Math.pow(y, 3); + var x2 = Math.pow(x, 3); + var z2 = Math.pow(z, 3); + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; -var baseGetTag = __webpack_require__(46), - isObjectLike = __webpack_require__(53); + x *= 95.047; + y *= 100; + z *= 108.883; -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]'; + return [x, y, z]; +}; -/** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ -function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; -} +convert.lab.lch = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var hr; + var h; + var c; -module.exports = baseIsArguments; + hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; + if (h < 0) { + h += 360; + } -/***/ }), -/* 434 */ -/***/ ((module, exports, __webpack_require__) => { + c = Math.sqrt(a * a + b * b); -/* module decorator */ module = __webpack_require__.nmd(module); -var root = __webpack_require__(48), - stubFalse = __webpack_require__(435); + return [l, c, h]; +}; -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; +convert.lch.lab = function (lch) { + var l = lch[0]; + var c = lch[1]; + var h = lch[2]; + var a; + var b; + var hr; -/** Detect free variable `module`. */ -var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; + hr = h / 360 * 2 * Math.PI; + a = c * Math.cos(hr); + b = c * Math.sin(hr); -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; + return [l, a, b]; +}; -/** Built-in value references. */ -var Buffer = moduleExports ? root.Buffer : undefined; +convert.rgb.ansi16 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + value = Math.round(value / 50); -/** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ -var isBuffer = nativeIsBuffer || stubFalse; + if (value === 0) { + return 30; + } -module.exports = isBuffer; + var ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); + if (value === 2) { + ansi += 60; + } -/***/ }), -/* 435 */ -/***/ ((module) => { + return ansi; +}; -/** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ -function stubFalse() { - return false; -} +convert.hsv.ansi16 = function (args) { + // optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); +}; -module.exports = stubFalse; +convert.rgb.ansi256 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + // we use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } -/***/ }), -/* 436 */ -/***/ ((module) => { + if (r > 248) { + return 231; + } -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; + return Math.round(((r - 8) / 247) * 24) + 232; + } -/** Used to detect unsigned integer values. */ -var reIsUint = /^(?:0|[1-9]\d*)$/; + var ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER : length; + return ansi; +}; - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); -} +convert.ansi16.rgb = function (args) { + var color = args % 10; -module.exports = isIndex; + // handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } + color = color / 10.5 * 255; -/***/ }), -/* 437 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return [color, color, color]; + } -var baseIsTypedArray = __webpack_require__(438), - baseUnary = __webpack_require__(440), - nodeUtil = __webpack_require__(441); + var mult = (~~(args > 50) + 1) * 0.5; + var r = ((color & 1) * mult) * 255; + var g = (((color >> 1) & 1) * mult) * 255; + var b = (((color >> 2) & 1) * mult) * 255; -/* Node.js helper references. */ -var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + return [r, g, b]; +}; -/** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ -var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; +convert.ansi256.rgb = function (args) { + // handle greyscale + if (args >= 232) { + var c = (args - 232) * 10 + 8; + return [c, c, c]; + } -module.exports = isTypedArray; + args -= 16; + var rem; + var r = Math.floor(args / 36) / 5 * 255; + var g = Math.floor((rem = args % 36) / 6) / 5 * 255; + var b = (rem % 6) / 5 * 255; -/***/ }), -/* 438 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return [r, g, b]; +}; -var baseGetTag = __webpack_require__(46), - isLength = __webpack_require__(439), - isObjectLike = __webpack_require__(53); +convert.rgb.hex = function (args) { + var integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; +convert.hex.rgb = function (args) { + var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } -/** Used to identify `toStringTag` values of typed arrays. */ -var typedArrayTags = {}; -typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = -typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = -typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = -typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = -typedArrayTags[uint32Tag] = true; -typedArrayTags[argsTag] = typedArrayTags[arrayTag] = -typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = -typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = -typedArrayTags[errorTag] = typedArrayTags[funcTag] = -typedArrayTags[mapTag] = typedArrayTags[numberTag] = -typedArrayTags[objectTag] = typedArrayTags[regexpTag] = -typedArrayTags[setTag] = typedArrayTags[stringTag] = -typedArrayTags[weakMapTag] = false; + var colorString = match[0]; -/** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ -function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; -} + if (match[0].length === 3) { + colorString = colorString.split('').map(function (char) { + return char + char; + }).join(''); + } -module.exports = baseIsTypedArray; + var integer = parseInt(colorString, 16); + var r = (integer >> 16) & 0xFF; + var g = (integer >> 8) & 0xFF; + var b = integer & 0xFF; + return [r, g, b]; +}; -/***/ }), -/* 439 */ -/***/ ((module) => { +convert.rgb.hcg = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var max = Math.max(Math.max(r, g), b); + var min = Math.min(Math.min(r, g), b); + var chroma = (max - min); + var grayscale; + var hue; -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; + } -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma + 4; + } -module.exports = isLength; + hue /= 6; + hue %= 1; + return [hue * 360, chroma * 100, grayscale * 100]; +}; -/***/ }), -/* 440 */ -/***/ ((module) => { +convert.hsl.hcg = function (hsl) { + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var c = 1; + var f = 0; -/** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ -function baseUnary(func) { - return function(value) { - return func(value); - }; -} + if (l < 0.5) { + c = 2.0 * s * l; + } else { + c = 2.0 * s * (1.0 - l); + } -module.exports = baseUnary; + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } + return [hsl[0], c * 100, f * 100]; +}; -/***/ }), -/* 441 */ -/***/ ((module, exports, __webpack_require__) => { +convert.hsv.hcg = function (hsv) { + var s = hsv[1] / 100; + var v = hsv[2] / 100; -/* module decorator */ module = __webpack_require__.nmd(module); -var freeGlobal = __webpack_require__(49); + var c = s * v; + var f = 0; -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; + if (c < 1.0) { + f = (v - c) / (1 - c); + } -/** Detect free variable `module`. */ -var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; + return [hsv[0], c * 100, f * 100]; +}; -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; +convert.hcg.rgb = function (hcg) { + var h = hcg[0] / 360; + var c = hcg[1] / 100; + var g = hcg[2] / 100; -/** Detect free variable `process` from Node.js. */ -var freeProcess = moduleExports && freeGlobal.process; + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } -/** Used to access faster Node.js helpers. */ -var nodeUtil = (function() { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule && freeModule.require && freeModule.require('util').types; + var pure = [0, 0, 0]; + var hi = (h % 1) * 6; + var v = hi % 1; + var w = 1 - v; + var mg = 0; - if (types) { - return types; - } + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; + } - // Legacy `process.binding('util')` for Node.js < 10. - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} -}()); + mg = (1.0 - c) * g; -module.exports = nodeUtil; + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; +convert.hcg.hsv = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; -/***/ }), -/* 442 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var v = c + g * (1.0 - c); + var f = 0; -var isPrototype = __webpack_require__(443), - nativeKeys = __webpack_require__(444); + if (v > 0.0) { + f = c / v; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + return [hcg[0], f * 100, v * 100]; +}; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +convert.hcg.hsl = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; -/** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; -} + var l = g * (1.0 - c) + 0.5 * c; + var s = 0; -module.exports = baseKeys; + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } + + return [hcg[0], s * 100, l * 100]; +}; +convert.hcg.hwb = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + var v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; -/***/ }), -/* 443 */ -/***/ ((module) => { +convert.hwb.hcg = function (hwb) { + var w = hwb[1] / 100; + var b = hwb[2] / 100; + var v = 1 - b; + var c = v - w; + var g = 0; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + if (c < 1) { + g = (v - c) / (1 - c); + } -/** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ -function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + return [hwb[0], c * 100, g * 100]; +}; - return value === proto; -} +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; +}; -module.exports = isPrototype; +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; -/***/ }), -/* 444 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +convert.gray.hsl = convert.gray.hsv = function (args) { + return [0, 0, args[0]]; +}; -var overArg = __webpack_require__(445); +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; +}; -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeKeys = overArg(Object.keys, Object); +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; -module.exports = nativeKeys; +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; +}; + +convert.gray.hex = function (gray) { + var val = Math.round(gray[0] / 100 * 255) & 0xFF; + var integer = (val << 16) + (val << 8) + val; + + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; + +convert.rgb.gray = function (rgb) { + var val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; +}; /***/ }), -/* 445 */ +/* 365 */ /***/ ((module) => { -/** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ -function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; -} - -module.exports = overArg; +"use strict"; + + +module.exports = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] +}; /***/ }), -/* 446 */ +/* 366 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var isFunction = __webpack_require__(45), - isLength = __webpack_require__(439); +var conversions = __webpack_require__(364); -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); +/* + this function routes a model to all other models. + + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). + + conversions that are not possible simply are not included. +*/ + +function buildGraph() { + var graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + var models = Object.keys(conversions); + + for (var len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; + } + + return graph; } -module.exports = isArrayLike; +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + var graph = buildGraph(); + var queue = [fromModel]; // unshift -> queue -> pop + graph[fromModel].distance = 0; -/***/ }), -/* 447 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + while (queue.length) { + var current = queue.pop(); + var adjacents = Object.keys(conversions[current]); -var DataView = __webpack_require__(448), - Map = __webpack_require__(389), - Promise = __webpack_require__(449), - Set = __webpack_require__(450), - WeakMap = __webpack_require__(451), - baseGetTag = __webpack_require__(46), - toSource = __webpack_require__(375); + for (var len = adjacents.length, i = 0; i < len; i++) { + var adjacent = adjacents[i]; + var node = graph[adjacent]; -/** `Object#toString` result references. */ -var mapTag = '[object Map]', - objectTag = '[object Object]', - promiseTag = '[object Promise]', - setTag = '[object Set]', - weakMapTag = '[object WeakMap]'; + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } + } -var dataViewTag = '[object DataView]'; + return graph; +} -/** Used to detect maps, sets, and weakmaps. */ -var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} -/** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -var getTag = baseGetTag; +function wrapConversion(toModel, graph) { + var path = [graph[toModel].parent, toModel]; + var fn = conversions[graph[toModel].parent][toModel]; -// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. -if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || - (Map && getTag(new Map) != mapTag) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag) || - (WeakMap && getTag(new WeakMap) != weakMapTag)) { - getTag = function(value) { - var result = baseGetTag(value), - Ctor = result == objectTag ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : ''; + var cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; + } - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag; - case mapCtorString: return mapTag; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag; - case weakMapCtorString: return weakMapTag; - } - } - return result; - }; + fn.conversion = path; + return fn; } -module.exports = getTag; +module.exports = function (fromModel) { + var graph = deriveBFS(fromModel); + var conversion = {}; + var models = Object.keys(graph); + for (var len = models.length, i = 0; i < len; i++) { + var toModel = models[i]; + var node = graph[toModel]; -/***/ }), -/* 448 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (node.parent === null) { + // no possible conversion, or this node is the source model. + continue; + } -var getNative = __webpack_require__(371), - root = __webpack_require__(48); + conversion[toModel] = wrapConversion(toModel, graph); + } -/* Built-in method references that are verified to be native. */ -var DataView = getNative(root, 'DataView'); + return conversion; +}; -module.exports = DataView; /***/ }), -/* 449 */ +/* 367 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var getNative = __webpack_require__(371), - root = __webpack_require__(48); +"use strict"; -/* Built-in method references that are verified to be native. */ -var Promise = getNative(root, 'Promise'); +const os = __webpack_require__(253); +const hasFlag = __webpack_require__(368); -module.exports = Promise; +const env = process.env; +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + forceColor = false; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = true; +} +if ('FORCE_COLOR' in env) { + forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; +} -/***/ }), -/* 450 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function translateLevel(level) { + if (level === 0) { + return false; + } -var getNative = __webpack_require__(371), - root = __webpack_require__(48); + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +} -/* Built-in method references that are verified to be native. */ -var Set = getNative(root, 'Set'); +function supportsColor(stream) { + if (forceColor === false) { + return 0; + } -module.exports = Set; + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } + if (hasFlag('color=256')) { + return 2; + } -/***/ }), -/* 451 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (stream && !stream.isTTY && forceColor !== true) { + return 0; + } -var getNative = __webpack_require__(371), - root = __webpack_require__(48); + const min = forceColor ? 1 : 0; -/* Built-in method references that are verified to be native. */ -var WeakMap = getNative(root, 'WeakMap'); + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows + // release that supports 256 colors. Windows 10 build 14931 is the first release + // that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(process.versions.node.split('.')[0]) >= 8 && + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } -module.exports = WeakMap; + return 1; + } + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } -/***/ }), -/* 452 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return min; + } -var isStrictComparable = __webpack_require__(453), - keys = __webpack_require__(429); + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } -/** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ -function getMatchData(object) { - var result = keys(object), - length = result.length; + if (env.COLORTERM === 'truecolor') { + return 3; + } - while (length--) { - var key = result[length], - value = object[key]; + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - result[length] = [key, value, isStrictComparable(value)]; - } - return result; -} + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } -module.exports = getMatchData; + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } -/***/ }), -/* 453 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if ('COLORTERM' in env) { + return 1; + } -var isObject = __webpack_require__(52); + if (env.TERM === 'dumb') { + return min; + } -/** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ -function isStrictComparable(value) { - return value === value && !isObject(value); + return min; } -module.exports = isStrictComparable; +function getSupportLevel(stream) { + const level = supportsColor(stream); + return translateLevel(level); +} + +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr) +}; /***/ }), -/* 454 */ +/* 368 */ /***/ ((module) => { -/** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ -function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; -} +"use strict"; -module.exports = matchesStrictComparable; +module.exports = (flag, argv) => { + argv = argv || process.argv; + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const pos = argv.indexOf(prefix + flag); + const terminatorPos = argv.indexOf('--'); + return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); +}; /***/ }), -/* 455 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 369 */ +/***/ ((module) => { -var baseIsEqual = __webpack_require__(410), - get = __webpack_require__(358), - hasIn = __webpack_require__(456), - isKey = __webpack_require__(361), - isStrictComparable = __webpack_require__(453), - matchesStrictComparable = __webpack_require__(454), - toKey = __webpack_require__(399); +"use strict"; -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; +const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; +const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; +const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; -/** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ -function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); - }; -} +const ESCAPES = new Map([ + ['n', '\n'], + ['r', '\r'], + ['t', '\t'], + ['b', '\b'], + ['f', '\f'], + ['v', '\v'], + ['0', '\0'], + ['\\', '\\'], + ['e', '\u001B'], + ['a', '\u0007'] +]); -module.exports = baseMatchesProperty; +function unescape(c) { + if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + return String.fromCharCode(parseInt(c.slice(1), 16)); + } + return ESCAPES.get(c) || c; +} -/***/ }), -/* 456 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function parseArguments(name, args) { + const results = []; + const chunks = args.trim().split(/\s*,\s*/g); + let matches; -var baseHasIn = __webpack_require__(457), - hasPath = __webpack_require__(458); + for (const chunk of chunks) { + if (!isNaN(chunk)) { + results.push(Number(chunk)); + } else if ((matches = chunk.match(STRING_REGEX))) { + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); + } else { + throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); + } + } -/** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ -function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); + return results; } -module.exports = hasIn; - +function parseStyle(style) { + STYLE_REGEX.lastIndex = 0; -/***/ }), -/* 457 */ -/***/ ((module) => { + const results = []; + let matches; -/** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ -function baseHasIn(object, key) { - return object != null && key in Object(object); -} + while ((matches = STYLE_REGEX.exec(style)) !== null) { + const name = matches[1]; -module.exports = baseHasIn; + if (matches[2]) { + const args = parseArguments(name, matches[2]); + results.push([name].concat(args)); + } else { + results.push([name]); + } + } + return results; +} -/***/ }), -/* 458 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function buildStyle(chalk, styles) { + const enabled = {}; -var castPath = __webpack_require__(360), - isArguments = __webpack_require__(432), - isArray = __webpack_require__(55), - isIndex = __webpack_require__(436), - isLength = __webpack_require__(439), - toKey = __webpack_require__(399); + for (const layer of styles) { + for (const style of layer.styles) { + enabled[style[0]] = layer.inverse ? null : style.slice(1); + } + } -/** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ -function hasPath(object, path, hasFunc) { - path = castPath(path, object); + let current = chalk; + for (const styleName of Object.keys(enabled)) { + if (Array.isArray(enabled[styleName])) { + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); + } - var index = -1, - length = path.length, - result = false; + if (enabled[styleName].length > 0) { + current = current[styleName].apply(current, enabled[styleName]); + } else { + current = current[styleName]; + } + } + } - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result || ++index != length) { - return result; - } - length = object == null ? 0 : object.length; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isArguments(object)); + return current; } -module.exports = hasPath; +module.exports = (chalk, tmp) => { + const styles = []; + const chunks = []; + let chunk = []; + // eslint-disable-next-line max-params + tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { + if (escapeChar) { + chunk.push(unescape(escapeChar)); + } else if (style) { + const str = chunk.join(''); + chunk = []; + chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); + styles.push({inverse, styles: parseStyle(style)}); + } else if (close) { + if (styles.length === 0) { + throw new Error('Found extraneous } in Chalk template literal'); + } -/***/ }), -/* 459 */ -/***/ ((module) => { + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); + chunk = []; + styles.pop(); + } else { + chunk.push(chr); + } + }); -/** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true - */ -function identity(value) { - return value; -} + chunks.push(chunk.join('')); -module.exports = identity; + if (styles.length > 0) { + const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMsg); + } + + return chunks.join(''); +}; /***/ }), -/* 460 */ +/* 370 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseProperty = __webpack_require__(461), - basePropertyDeep = __webpack_require__(462), - isKey = __webpack_require__(361), - toKey = __webpack_require__(399); +var baseGet = __webpack_require__(371); /** - * Creates a function that returns the value at `path` of a given object. + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. * * @static * @memberOf _ - * @since 2.4.0 - * @category Util + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. * @example * - * var objects = [ - * { 'a': { 'b': 2 } }, - * { 'a': { 'b': 1 } } - * ]; + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * - * _.map(objects, _.property('a.b')); - * // => [2, 1] + * _.get(object, 'a[0].b.c'); + * // => 3 * - * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); - * // => [1, 2] - */ -function property(path) { - return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); -} - -module.exports = property; - - -/***/ }), -/* 461 */ -/***/ ((module) => { - -/** - * The base implementation of `_.property` without support for deep paths. + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. + * _.get(object, 'a.b.c', 'default'); + * // => 'default' */ -function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; +function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; } -module.exports = baseProperty; +module.exports = get; /***/ }), -/* 462 */ +/* 371 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseGet = __webpack_require__(359); +var castPath = __webpack_require__(372), + toKey = __webpack_require__(411); /** - * A specialized version of `baseProperty` which supports deep paths. + * The base implementation of `_.get` without support for default values. * * @private + * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ -function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; -} - -module.exports = basePropertyDeep; - - -/***/ }), -/* 463 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var SetCache = __webpack_require__(413), - arrayIncludes = __webpack_require__(464), - arrayIncludesWith = __webpack_require__(469), - cacheHas = __webpack_require__(417), - createSet = __webpack_require__(470), - setToArray = __webpack_require__(421); - -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE = 200; - -/** - * The base implementation of `_.uniqBy` without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. + * @returns {*} Returns the resolved value. */ -function baseUniq(array, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - length = array.length, - isCommon = true, - result = [], - seen = result; +function baseGet(object, path) { + path = castPath(path, object); - if (comparator) { - isCommon = false; - includes = arrayIncludesWith; - } - else if (length >= LARGE_ARRAY_SIZE) { - var set = iteratee ? null : createSet(array); - if (set) { - return setToArray(set); - } - isCommon = false; - includes = cacheHas; - seen = new SetCache; - } - else { - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; + var index = 0, + length = path.length; - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (!includes(seen, computed, comparator)) { - if (seen !== result) { - seen.push(computed); - } - result.push(value); - } + while (object != null && index < length) { + object = object[toKey(path[index++])]; } - return result; + return (index && index == length) ? object : undefined; } -module.exports = baseUniq; +module.exports = baseGet; /***/ }), -/* 464 */ +/* 372 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseIndexOf = __webpack_require__(465); +var isArray = __webpack_require__(55), + isKey = __webpack_require__(373), + stringToPath = __webpack_require__(375), + toString = __webpack_require__(408); /** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. + * Casts `value` to a path array if it's not one. * * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. */ -function arrayIncludes(array, value) { - var length = array == null ? 0 : array.length; - return !!length && baseIndexOf(array, value, 0) > -1; +function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); } -module.exports = arrayIncludes; +module.exports = castPath; /***/ }), -/* 465 */ +/* 373 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseFindIndex = __webpack_require__(466), - baseIsNaN = __webpack_require__(467), - strictIndexOf = __webpack_require__(468); - -/** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseIndexOf(array, value, fromIndex) { - return value === value - ? strictIndexOf(array, value, fromIndex) - : baseFindIndex(array, baseIsNaN, fromIndex); -} - -module.exports = baseIndexOf; - - -/***/ }), -/* 466 */ -/***/ ((module) => { - -/** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; -} - -module.exports = baseFindIndex; - +var isArray = __webpack_require__(55), + isSymbol = __webpack_require__(374); -/***/ }), -/* 467 */ -/***/ ((module) => { +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; /** - * The base implementation of `_.isNaN` without support for number objects. + * Checks if `value` is a property name and not a property path. * * @private * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ -function baseIsNaN(value) { - return value !== value; -} - -module.exports = baseIsNaN; - - -/***/ }), -/* 468 */ -/***/ ((module) => { - -/** - * A specialized version of `_.indexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. */ -function strictIndexOf(array, value, fromIndex) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } +function isKey(value, object) { + if (isArray(value)) { + return false; } - return -1; -} - -module.exports = strictIndexOf; - - -/***/ }), -/* 469 */ -/***/ ((module) => { - -/** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ -function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (comparator(value, array[index])) { - return true; - } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; } - return false; + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); } -module.exports = arrayIncludesWith; +module.exports = isKey; /***/ }), -/* 470 */ +/* 374 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var Set = __webpack_require__(450), - noop = __webpack_require__(471), - setToArray = __webpack_require__(421); - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; - -/** - * Creates a set object of `values`. - * - * @private - * @param {Array} values The values to add to the set. - * @returns {Object} Returns the new set. - */ -var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { - return new Set(values); -}; - -module.exports = createSet; - +var baseGetTag = __webpack_require__(46), + isObjectLike = __webpack_require__(53); -/***/ }), -/* 471 */ -/***/ ((module) => { +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; /** - * This method returns `undefined`. + * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ - * @since 2.3.0 - * @category Util + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * - * _.times(2, _.noop); - * // => [undefined, undefined] + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false */ -function noop() { - // No operation performed. +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = noop; +module.exports = isSymbol; /***/ }), -/* 472 */ +/* 375 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/** - * Small utilities helping to develop konnectors. - * - * @module utils - */ -const cozyClient = __webpack_require__(473); - -const groupBy = __webpack_require__(724); - -const keyBy = __webpack_require__(699); - -const sortBy = __webpack_require__(840); - -const range = __webpack_require__(959); +var memoizeCapped = __webpack_require__(376); -const { - format -} = __webpack_require__(962); -/** - * This function allows to fetch all documents for a given doctype. It is the fastest to get all - * documents but without filtering possibilities - * deprecated by the findAll method from cozyClient - * - * Parameters: - * - * `doctype` (string): the doctype from which you want to fetch the data - * - */ +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; -const fetchAll = async doctype => { - return cozyClient.data.findAll(doctype); -}; /** - * This function allows to fetch all documents for a given doctype exceeding the 100 limit. - * It is slower that fetchAll because it fetches the data 100 by 100 but allows to filter the data - * with a selector and an index - * - * Parameters: - * - * `doctype` (string): the doctype from which you want to fetch the data - * `selector` (object): the mango query selector - * `index` (object): (optional) the query selector index. If not defined, the function will - * create it's own index with the keys specified in the selector - * + * Converts `string` to a property path array. * - * ```javascript - * const documents = await queryAll('io.cozy.bills', {vendor: 'Direct Energie'}) - * ``` + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. */ - - -const queryAll = async (doctype, selector, index) => { - if (!selector) { - // fetchAll is faster in this case - return await cozyClient.data.findAll(doctype); - } - - if (!index) { - index = await cozyClient.data.defineIndex(doctype, Object.keys(selector)); - } - - const result = []; - let resp = { - next: true - }; - - while (resp && resp.next) { - resp = await cozyClient.data.query(index, { - selector, - wholeResponse: true, - skip: result.length - }); - result.push(...resp.docs); +var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); } - + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); return result; -}; -/** - * This function find duplicates in a given doctype, filtered by an optional mango selector - * - * Parameters: - * - * `doctype` (string): the doctype from which you want to fetch the data - * `selector` (object): (optional) the mango query selector - * `options` : - * - `keys` (array) : List of keys used to check that two items are the same. - * - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype. - * - `selector` (optionnal object) : Mango request to get records. Gets all the records by default - * - * Returns an object with the following keys: - * `toKeep`: this is the list of unique documents that you should keep in db - * `toRemove`: this is the list of documents that can remove from db. If this is io.cozy.bills - * documents, do not forget to clean linked bank operations - * - * ```javascript - * const {toKeep, toRemove} = await findDuplicates('io.cozy.bills', {selector: {vendor: 'Direct Energie'}}) - * ``` - */ - - -const findDuplicates = async (doctype, options) => { - let hash = null; - - if (options.keys) { - hash = doc => options.keys.map(key => { - let result = doc[key]; - if (key === 'date') result = new Date(result); - return result; - }).join(','); - } else if (options.hash) { - hash = options.hash; - } else { - throw new Error('findDuplicates: you must specify keys or hash option'); - } +}); - let documents = await queryAll(doctype, options.selector); +module.exports = stringToPath; - if (doctype === 'io.cozy.bills') { - // keep the bills with the highest number of operations linked to it - const operations = await fetchAll('io.cozy.bank.operations'); - documents = sortBillsByLinkedOperationNumber(documents, operations); - } - const groups = groupBy(documents, hash); - const toKeep = []; - const toRemove = []; +/***/ }), +/* 376 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (let key in groups) { - const group = groups[key]; - toKeep.push(group[0]); - toRemove.push.apply(toRemove, group.slice(1).map(doc => ({ ...doc, - original: group[0]._id - }))); - } +var memoize = __webpack_require__(377); - return { - toKeep, - toRemove - }; -}; +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; -const sortBillsByLinkedOperationNumber = (bills, operations) => { - bills = bills.map(bill => { - bill.opNb = 0; - return bill; - }); - const billsIndex = keyBy(bills, '_id'); - if (operations) operations.forEach(op => { - if (op.bills) op.bills.forEach(billId => { - const bill = billsIndex[billId]; - if (bill) bill.opNb++; - }); - }); - const sorted = sortBy(Object.values(billsIndex), 'opNb').reverse(); - return sorted; -}; /** - * This is a shortcut to update multiple documents in one call - * - * Parameters: - * - * `doctype` (string): the doctype from which you want to fetch the data - * `ids` (array): array of ids of documents to update - * `transformation` (object): attributes to change with their values - * `options` : - * - `keys` (array) : List of keys used to check that two items are the same. - * - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype. - * - `selector` (optionnal object) : Mango request to get records. Gets all the records by default - * - * Returns a promise which resolves with all the return values of updateAttributes + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. * - * ```javascript - * await batchUpdateAttributes('io.cozy.bills', [1, 2, 3], {vendor: 'Direct Energie'}) - * ``` + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. */ +function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + var cache = result.cache; + return result; +} -const batchUpdateAttributes = async (doctype, ids, transformation) => { - const result = []; - - for (const id of ids) { - const updateResult = await cozyClient.data.updateAttributes(doctype, id, transformation); - result.push(updateResult); - } +module.exports = memoizeCapped; - return result; -}; -/** - * This is a shortcut to delete multiple documents in one call - * - * Parameters: - * - * `doctype` (string): the doctype from which you want to fetch the data - * `documents` (array): documents to delete with their ids - * `transformation` (object): attributes to change with their values - * `options` : - * - `keys` (array) : List of keys used to check that two items are the same. - * - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype. - * - `selector` (optionnal object) : Mango request to get records. Gets all the records by default - * - * Returns a promise which resolves with all the return values of updateAttributes - * - * Example to remove all the documents for a given doctype - * - * ```javascript - * const documents = await fetchAll('io.cozy.marvel') - * await batchDelete('io.cozy.marvel', documents) - * ``` - */ +/***/ }), +/* 377 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const batchDelete = async (doctype, documents) => { - const result = []; +var MapCache = __webpack_require__(378); - for (const doc of documents) { - const deleteResult = await cozyClient.data.delete(doctype, doc); - result.push(deleteResult); - } +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; - return result; -}; /** - * This function can read the content of a cozy pdf file and output its text + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. * - * Parameters: + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. * - * `fileId` (string): the id of the file in the cozy - * `options` : - * - `pages` (array or number) : The list of page you want to interpret + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] * - * You need to add pdfjs-dist package as a dependency to your connector to allow this to work + * values(other); + * // => [3, 4] * - * Returns a promise which resolves with an object with the following attributes: - * - `text` (string) : The full text of the pdf - * - `1` : The full pdfjs data for page 1 - * - `n` : The full pdfjs data for page n + * object.a = 2; + * values(object); + * // => [1, 2] * - * Example: + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] * - * ```javascript - * const pdfText = (await getPdfText('887ABCFE87687')).text - * ``` + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; */ +function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; +} -const getPdfText = async (fileId, options = {}) => { - let pdfjs; +// Expose `MapCache`. +memoize.Cache = MapCache; - try { - pdfjs = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'pdfjs-dist/legacy/build/pdf'"); e.code = 'MODULE_NOT_FOUND'; throw e; }())); - } catch (err) { - throw new Error('pdfjs-dist dependency is missing. Please add it in your package.json'); - } +module.exports = memoize; - const response = await cozyClient.files.downloadById(fileId); - const buffer = await response.buffer(); - const document = await pdfjs.getDocument(buffer).promise; - let pages; - if (options.pages) { - pages = Array.isArray(options.pages) ? options.pages : [options.pages]; - } else { - pages = range(1, document.numPages + 1); - } +/***/ }), +/* 378 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - const result = { - text: '' - }; +var mapCacheClear = __webpack_require__(379), + mapCacheDelete = __webpack_require__(402), + mapCacheGet = __webpack_require__(405), + mapCacheHas = __webpack_require__(406), + mapCacheSet = __webpack_require__(407); - for (const pageNum of pages) { - const page = await document.getPage(pageNum); - const pageItems = (await page.getTextContent()).items; - result.text += pageItems.map(doc => doc.str).join('\n'); - result[pageNum] = pageItems; +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); } +} - return result; -}; +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +module.exports = MapCache; + + +/***/ }), +/* 379 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Hash = __webpack_require__(380), + ListCache = __webpack_require__(393), + Map = __webpack_require__(401); -module.exports = { - fetchAll, - queryAll, - findDuplicates, - sortBillsByLinkedOperationNumber, - batchUpdateAttributes, - batchDelete, - getPdfText, - formatDate -}; /** - * This function convert a Date Object to a ISO date string (2018-07-31) - * - * Parameters: - * - * `date` (Date): the id of the file in the cozy - * - * Returns a string - * - * Example: + * Removes all key-value entries from the map. * - * ```javascript - * const date = formatFrenchDate(New Date.now()) - * ``` + * @private + * @name clear + * @memberOf MapCache */ - -function formatDate(date) { - return format(new Date(date), 'yyyy-MM-dd'); +function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; } +module.exports = mapCacheClear; + + /***/ }), -/* 473 */ +/* 380 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var hashClear = __webpack_require__(381), + hashDelete = __webpack_require__(389), + hashGet = __webpack_require__(390), + hashHas = __webpack_require__(391), + hashSet = __webpack_require__(392); + /** - * [cozy-client-js](https://github.com/cozy/cozy-client-js) instance already - * initialized and ready to use. + * Creates a hash object. * - * @module cozyClient + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. */ +function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; -/* eslint no-console: off */ -const { - Client, - MemoryStorage -} = __webpack_require__(474); - -const NewCozyClient = (__webpack_require__(509)["default"]); + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} -const { - models -} = __webpack_require__(509); +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; -const globalFetch = (__webpack_require__(481)["default"]); +module.exports = Hash; -global.fetch = globalFetch; -global.Headers = globalFetch.Headers; // fixes an import problem of isomorphic fetch in cozy-client and cozy-client-js -const manifest = __webpack_require__(909); +/***/ }), +/* 381 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const getCozyClient = function (environment = 'production') { - if (environment === 'standalone' || environment === 'test') { - return __webpack_require__(910); - } +var nativeCreate = __webpack_require__(382); - const cozyFields = JSON.parse(process.env.COZY_FIELDS || '{}'); - const newCozyClient = NewCozyClient.fromEnv(process.env, { - appMetadata: { - slug: manifest.data.slug, - sourceAccount: cozyFields.account, - version: manifest.data.version - } - }); - newCozyClient.models = models; - const cozyClient = cozyClientJsFromEnv(newCozyClient.stackClient.uri); - cozyClient.new = newCozyClient; - return cozyClient; -}; /** - * [cozy-client-js](https://github.com/cozy/cozy-client-js) instance already initialized and ready to use. - * - * If you want to access cozy-client-js directly, this method gives you directly an instance of it, - * initialized according to `COZY_URL` and `COZY_CREDENTIALS` environment variable given by cozy-stack - * You can refer to the [cozy-client-js documentation](https://github.com/cozy/cozy-client-js) for more information. - * - * Example : - * - * ```javascript - * const {cozyClient} = require('cozy-konnector-libs') - * - * cozyClient.data.defineIndex('my.doctype', ['_id']) - * ``` + * Removes all key-value entries from the hash. * - * @alias module:cozyClient + * @private + * @name clear + * @memberOf Hash */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; +} +module.exports = hashClear; -const cozyClient = getCozyClient( // webpack 4 now changes the NODE_ENV environment variable when you change its 'mode' option -// since we do not want to minimize the built file, we recognize the 'none' mode as production mode -process.env.NODE_ENV === 'none' ? 'production' : process.env.NODE_ENV); -function cozyClientJsFromEnv(cozyURL) { - const options = { - cozyURL - }; - let jsonCredentials = null; +/***/ }), +/* 382 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (process.env.COZY_CREDENTIALS) { - try { - jsonCredentials = JSON.parse(process.env.COZY_CREDENTIALS); - } catch (err) { - options.token = process.env.COZY_CREDENTIALS; - } - } +var getNative = __webpack_require__(383); - if (jsonCredentials) { - options.oauth = { - storage: new MemoryStorage() - }; - } +/* Built-in method references that are verified to be native. */ +var nativeCreate = getNative(Object, 'create'); - const cozyClient = new Client(options); +module.exports = nativeCreate; - if (jsonCredentials) { - jsonCredentials.token.toAuthHeader = function () { - return 'Bearer ' + jsonCredentials.client.registrationAccessToken; - }; - cozyClient.saveCredentials(jsonCredentials.oauthOptions, jsonCredentials.token); - } +/***/ }), +/* 383 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return cozyClient; +var baseIsNative = __webpack_require__(384), + getValue = __webpack_require__(388); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; } -module.exports = cozyClient; +module.exports = getNative; + /***/ }), -/* 474 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/* 384 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __nested_webpack_require_228__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_228__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __nested_webpack_require_228__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __nested_webpack_require_228__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __nested_webpack_require_228__.d = function(exports, name, getter) { -/******/ if(!__nested_webpack_require_228__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __nested_webpack_require_228__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __nested_webpack_require_228__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __nested_webpack_require_228__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __nested_webpack_require_228__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __nested_webpack_require_228__(__nested_webpack_require_228__.s = 9); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __nested_webpack_require_2505__) { +var isFunction = __webpack_require__(45), + isMasked = __webpack_require__(385), + isObject = __webpack_require__(52), + toSource = __webpack_require__(387); -"use strict"; +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.FetchError = undefined; +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /* global fetch */ +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; -exports.cozyFetch = cozyFetch; -exports.cozyFetchJSON = cozyFetchJSON; -exports.cozyFetchRawJSON = cozyFetchRawJSON; -exports.handleInvalidTokenError = handleInvalidTokenError; +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); -var _auth_v = __nested_webpack_require_2505__(3); +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} -var _utils = __nested_webpack_require_2505__(1); +module.exports = baseIsNative; -var _jsonapi = __nested_webpack_require_2505__(7); -var _jsonapi2 = _interopRequireDefault(_jsonapi); +/***/ }), +/* 385 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var coreJsData = __webpack_require__(386); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +module.exports = isMasked; -function cozyFetch(cozy, path) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - return cozy.fullpath(path).then(function (fullpath) { - var resp = void 0; - if (options.disableAuth) { - resp = fetch(fullpath, options); - } else if (options.manualAuthCredentials) { - resp = cozyFetchWithAuth(cozy, fullpath, options, options.manualAuthCredentials); - } else { - resp = cozy.authorize().then(function (credentials) { - return cozyFetchWithAuth(cozy, fullpath, options, credentials); - }); - } - return resp.then(function (res) { - return handleResponse(res, cozy._invalidTokenErrorHandler); - }); - }); -} +/***/ }), +/* 386 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function cozyFetchWithAuth(cozy, fullpath, options, credentials) { - if (credentials) { - options.headers = options.headers || {}; - options.headers['Authorization'] = credentials.token.toAuthHeader(); - } +var root = __webpack_require__(48); - // the option credentials:include tells fetch to include the cookies in the - // request even for cross-origin requests - options.credentials = 'include'; +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; - return Promise.all([cozy.isV2(), fetch(fullpath, options)]).then(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - isV2 = _ref2[0], - res = _ref2[1]; +module.exports = coreJsData; - if (res.status !== 400 && res.status !== 401 || isV2 || !credentials || options.dontRetry) { - return res; - } - // we try to refresh the token only for OAuth, ie, the client defined - // and the token is an instance of AccessToken. - var client = credentials.client, - token = credentials.token; - if (!client || !(token instanceof _auth_v.AccessToken)) { - return res; - } - options.dontRetry = true; - return (0, _utils.retry)(function () { - return (0, _auth_v.refreshToken)(cozy, client, token); - }, 3)().then(function (newToken) { - return cozy.saveCredentials(client, newToken); - }).then(function (credentials) { - return cozyFetchWithAuth(cozy, fullpath, options, credentials); - }); - }); -} +/***/ }), +/* 387 */ +/***/ ((module) => { -function cozyFetchJSON(cozy, method, path, body) { - var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; +/** Used for built-in method references. */ +var funcProto = Function.prototype; - var processJSONAPI = typeof options.processJSONAPI === 'undefined' || options.processJSONAPI; - return fetchJSON(cozy, method, path, body, options).then(function (response) { - return handleJSONResponse(response, processJSONAPI); - }); +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; } -function cozyFetchRawJSON(cozy, method, path, body) { - var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; +module.exports = toSource; - return fetchJSON(cozy, method, path, body, options).then(function (response) { - return handleJSONResponse(response, false); - }); -} -function fetchJSON(cozy, method, path, body) { - var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; +/***/ }), +/* 388 */ +/***/ ((module) => { - options.method = method; +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} - var headers = options.headers = options.headers || {}; +module.exports = getValue; - headers['Accept'] = 'application/json'; - if (method !== 'GET' && method !== 'HEAD' && body !== undefined) { - if (headers['Content-Type']) { - options.body = body; - } else { - headers['Content-Type'] = 'application/json'; - options.body = JSON.stringify(body); - } - } +/***/ }), +/* 389 */ +/***/ ((module) => { - return cozyFetch(cozy, path, options); +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; } -function handleResponse(res, invalidTokenErrorHandler) { - if (res.ok) { - return res; - } - var data = void 0; - var contentType = res.headers.get('content-type'); - if (contentType && contentType.indexOf('json') >= 0) { - data = res.json(); - } else { - data = res.text(); - } - return data.then(function (err) { - var error = new FetchError(res, err); - if (FetchError.isInvalidToken(error) && invalidTokenErrorHandler) { - invalidTokenErrorHandler(error); - } - throw error; - }); -} +module.exports = hashDelete; -function handleJSONResponse(res) { - var processJSONAPI = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - var contentType = res.headers.get('content-type'); - if (!contentType || contentType.indexOf('json') < 0) { - return res.text(function (data) { - throw new FetchError(res, new Error('Response is not JSON: ' + data)); - }); - } +/***/ }), +/* 390 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var json = res.json(); - if (contentType.indexOf('application/vnd.api+json') === 0 && processJSONAPI) { - return json.then(_jsonapi2.default); - } else { - return json; - } -} +var nativeCreate = __webpack_require__(382); -function handleInvalidTokenError(error) { - try { - var currentOrigin = window.location.origin; - var requestUrl = error.url; +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; - if (requestUrl.indexOf(currentOrigin.replace(/^(https?:\/\/\w+)-\w+\./, '$1.')) === 0) { - var redirectURL = currentOrigin + '?' + (0, _utils.encodeQuery)({ disconnect: 1 }); - window.location = redirectURL; - } - } catch (e) { - console.warn('Unable to handle invalid token error', e, error); +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; } + return hasOwnProperty.call(data, key) ? data[key] : undefined; } -var FetchError = exports.FetchError = function (_Error) { - _inherits(FetchError, _Error); +module.exports = hashGet; - function FetchError(res, reason) { - _classCallCheck(this, FetchError); - var _this = _possibleConstructorReturn(this, (FetchError.__proto__ || Object.getPrototypeOf(FetchError)).call(this)); +/***/ }), +/* 391 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (Error.captureStackTrace) { - Error.captureStackTrace(_this, _this.constructor); - } - // XXX We have to hardcode this because babel doesn't play nice when extending Error - _this.name = 'FetchError'; - _this.response = res; - _this.url = res.url; - _this.status = res.status; - _this.reason = reason; +var nativeCreate = __webpack_require__(382); - Object.defineProperty(_this, 'message', { - value: reason.message || (typeof reason === 'string' ? reason : JSON.stringify(reason)) - }); - return _this; - } +/** Used for built-in method references. */ +var objectProto = Object.prototype; - return FetchError; -}(Error); +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; -FetchError.isUnauthorized = function (err) { - // XXX We can't use err instanceof FetchError because of the caveats of babel - return err.name === 'FetchError' && err.status === 401; -}; +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); +} -FetchError.isNotFound = function (err) { - // XXX We can't use err instanceof FetchError because of the caveats of babel - return err.name === 'FetchError' && err.status === 404; -}; +module.exports = hashHas; -FetchError.isInvalidToken = function (err) { - // XXX We can't use err instanceof FetchError because of the caveats of babel - return err.name === 'FetchError' && err.status === 400 && err.reason && (err.reason.error === 'Invalid JWT token' || err.reason.error === 'Expired token'); -}; /***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { +/* 392 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; +var nativeCreate = __webpack_require__(382); +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.unpromiser = unpromiser; -exports.isPromise = isPromise; -exports.isOnline = isOnline; -exports.isOffline = isOffline; -exports.sleep = sleep; -exports.retry = retry; -exports.getFuzzedDelay = getFuzzedDelay; -exports.getBackedoffDelay = getBackedoffDelay; -exports.createPath = createPath; -exports.encodeQuery = encodeQuery; -exports.decodeQuery = decodeQuery; -exports.warn = warn; -/* global navigator */ -var FuzzFactor = 0.3; +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} -function unpromiser(fn) { - return function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } +module.exports = hashSet; - var value = fn.apply(this, args); - if (!isPromise(value)) { - return value; - } - var l = args.length; - if (l === 0 || typeof args[l - 1] !== 'function') { - return; - } - var cb = args[l - 1]; - value.then(function (res) { - return cb(null, res); - }, function (err) { - return cb(err, null); - }); - }; -} -function isPromise(value) { - return !!value && typeof value.then === 'function'; -} +/***/ }), +/* 393 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function isOnline() { - return typeof navigator !== 'undefined' ? navigator.onLine : true; -} +var listCacheClear = __webpack_require__(394), + listCacheDelete = __webpack_require__(395), + listCacheGet = __webpack_require__(398), + listCacheHas = __webpack_require__(399), + listCacheSet = __webpack_require__(400); -function isOffline() { - return !isOnline(); -} +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; -function sleep(time, args) { - return new Promise(function (resolve) { - setTimeout(resolve, time, args); - }); + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } } -function retry(fn, count) { - var delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 300; +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; - return function doTry() { - for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } +module.exports = ListCache; - return fn.apply(undefined, args).catch(function (err) { - if (--count < 0) { - throw err; - } - return sleep(getBackedoffDelay(delay, count)).then(function () { - return doTry.apply(undefined, args); - }); - }); - }; -} -function getFuzzedDelay(retryDelay) { - var fuzzingFactor = (Math.random() * 2 - 1) * FuzzFactor; - return retryDelay * (1.0 + fuzzingFactor); +/***/ }), +/* 394 */ +/***/ ((module) => { + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; + this.size = 0; } -function getBackedoffDelay(retryDelay) { - var retryCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; +module.exports = listCacheClear; - return getFuzzedDelay(retryDelay * Math.pow(2, retryCount - 1)); -} -function createPath(cozy, isV2, doctype) { - var id = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; - var query = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; +/***/ }), +/* 395 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var route = '/data/'; - if (!isV2) { - route += encodeURIComponent(doctype) + '/'; - } - if (id !== '') { - route += encodeURIComponent(id); - } - var q = encodeQuery(query); - if (q !== '') { - route += '?' + q; - } - return route; -} +var assocIndexOf = __webpack_require__(396); -function encodeQuery(query) { - if (!query) { - return ''; +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; } - var q = ''; - for (var qname in query) { - if (q !== '') { - q += '&'; - } - q += encodeURIComponent(qname) + '=' + encodeURIComponent(query[qname]); + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); } - return q; + --this.size; + return true; } -function decodeQuery(url) { - var queryIndex = url.indexOf('?'); - if (queryIndex < 0) { - queryIndex = url.length; - } - var queries = {}; - var fragIndex = url.indexOf('#'); - if (fragIndex < 0) { - fragIndex = url.length; - } - if (fragIndex < queryIndex) { - return queries; - } - var queryStr = url.slice(queryIndex + 1, fragIndex); - if (queryStr === '') { - return queries; - } - var parts = queryStr.split('&'); - for (var i = 0; i < parts.length; i++) { - var pair = parts[i].split('='); - if (pair.length === 0 || pair[0] === '') { - continue; - } - var qname = decodeURIComponent(pair[0]); - if (queries.hasOwnProperty(qname)) { - continue; - } - if (pair.length === 1) { - queries[qname] = true; - } else if (pair.length === 2) { - queries[qname] = decodeURIComponent(pair[1]); - } else { - throw new Error('Malformed URL'); +module.exports = listCacheDelete; + + +/***/ }), +/* 396 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var eq = __webpack_require__(397); + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; } } - return queries; + return -1; } -var warned = []; -function warn(text) { - if (warned.indexOf(text) === -1) { - warned.push(text); - console.warn('cozy-client-js', text); - } +module.exports = assocIndexOf; + + +/***/ }), +/* 397 */ +/***/ ((module) => { + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); } +module.exports = eq; + + /***/ }), -/* 2 */ -/***/ (function(module, exports, __nested_webpack_require_15027__) { +/* 398 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; +var assocIndexOf = __webpack_require__(396); +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.DOCTYPE_FILES = undefined; -exports.normalizeDoctype = normalizeDoctype; + return index < 0 ? undefined : data[index][1]; +} -var _utils = __nested_webpack_require_15027__(1); +module.exports = listCacheGet; -var DOCTYPE_FILES = exports.DOCTYPE_FILES = 'io.cozy.files'; -var KNOWN_DOCTYPES = { - files: DOCTYPE_FILES, - folder: DOCTYPE_FILES, - contact: 'io.cozy.contacts', - event: 'io.cozy.events', - track: 'io.cozy.labs.music.track', - playlist: 'io.cozy.labs.music.playlist' -}; +/***/ }), +/* 399 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var REVERSE_KNOWN = {}; -Object.keys(KNOWN_DOCTYPES).forEach(function (k) { - REVERSE_KNOWN[KNOWN_DOCTYPES[k]] = k; -}); +var assocIndexOf = __webpack_require__(396); -function normalizeDoctype(cozy, isV2, doctype) { - var isQualified = doctype.indexOf('.') !== -1; - if (isV2 && isQualified) { - var known = REVERSE_KNOWN[doctype]; - if (known) return known; - return doctype.replace(/\./g, '-'); - } - if (!isV2 && !isQualified) { - var _known = KNOWN_DOCTYPES[doctype]; - if (_known) { - (0, _utils.warn)('you are using a non-qualified doctype ' + doctype + ' assumed to be ' + _known); - return _known; - } - throw new Error('Doctype ' + doctype + ' should be qualified.'); - } - return doctype; +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; } -/***/ }), -/* 3 */ -/***/ (function(module, exports, __nested_webpack_require_16254__) { +module.exports = listCacheHas; -"use strict"; -/* WEBPACK VAR INJECTION */(function(btoa) { -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.AppToken = exports.AccessToken = exports.Client = exports.StateKey = exports.CredsKey = undefined; +/***/ }), +/* 400 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); +var assocIndexOf = __webpack_require__(396); -var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global btoa */ +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} -exports.client = client; -exports.registerClient = registerClient; -exports.updateClient = updateClient; -exports.unregisterClient = unregisterClient; -exports.getClient = getClient; -exports.getAuthCodeURL = getAuthCodeURL; -exports.getAccessToken = getAccessToken; -exports.refreshToken = refreshToken; -exports.oauthFlow = oauthFlow; +module.exports = listCacheSet; -var _utils = __nested_webpack_require_16254__(1); -var _fetch = __nested_webpack_require_16254__(0); +/***/ }), +/* 401 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var getNative = __webpack_require__(383), + root = __webpack_require__(48); -var StateSize = 16; +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'); -var CredsKey = exports.CredsKey = 'creds'; -var StateKey = exports.StateKey = 'state'; +module.exports = Map; -var Client = exports.Client = function () { - function Client(opts) { - _classCallCheck(this, Client); - this.clientID = opts.clientID || opts.client_id || ''; - this.clientSecret = opts.clientSecret || opts.client_secret || ''; - this.registrationAccessToken = opts.registrationAccessToken || opts.registration_access_token || ''; +/***/ }), +/* 402 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (opts.redirect_uris) { - this.redirectURI = opts.redirect_uris[0] || ''; - } else { - this.redirectURI = opts.redirectURI || ''; - } +var getMapData = __webpack_require__(403); - this.softwareID = opts.softwareID || opts.software_id || ''; - this.softwareVersion = opts.softwareVersion || opts.software_version || ''; - this.clientName = opts.clientName || opts.client_name || ''; - this.clientKind = opts.clientKind || opts.client_kind || ''; - this.clientURI = opts.clientURI || opts.client_uri || ''; +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; +} - this.logoURI = opts.logoURI || opts.logo_uri || ''; - this.policyURI = opts.policyURI || opts.policy_uri || ''; +module.exports = mapCacheDelete; - this.notificationPlatform = opts.notificationPlatform || opts.notification_platform || ''; - this.notificationDeviceToken = opts.notificationDeviceToken || opts.notification_device_token || ''; - if (!this.registrationAccessToken) { - if (this.redirectURI === '') { - throw new Error('Missing redirectURI field'); - } - if (this.softwareID === '') { - throw new Error('Missing softwareID field'); - } - if (this.clientName === '') { - throw new Error('Missing clientName field'); - } - } - } +/***/ }), +/* 403 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - _createClass(Client, [{ - key: 'isRegistered', - value: function isRegistered() { - return this.clientID !== ''; - } - }, { - key: 'toRegisterJSON', - value: function toRegisterJSON() { - return { - redirect_uris: [this.redirectURI], - software_id: this.softwareID, - software_version: this.softwareVersion, - client_name: this.clientName, - client_kind: this.clientKind, - client_uri: this.clientURI, - logo_uri: this.logoURI, - policy_uri: this.policyURI, - notification_platform: this.notificationPlatform, - notification_device_token: this.notificationDeviceToken - }; - } - }, { - key: 'toAuthHeader', - value: function toAuthHeader() { - return 'Bearer ' + this.registrationAccessToken; - } - }]); +var isKeyable = __webpack_require__(404); - return Client; -}(); +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} -var AccessToken = exports.AccessToken = function () { - function AccessToken(opts) { - _classCallCheck(this, AccessToken); +module.exports = getMapData; - this.tokenType = opts.tokenType || opts.token_type; - this.accessToken = opts.accessToken || opts.access_token; - this.refreshToken = opts.refreshToken || opts.refresh_token; - this.scope = opts.scope; - } - _createClass(AccessToken, [{ - key: 'toAuthHeader', - value: function toAuthHeader() { - return 'Bearer ' + this.accessToken; - } - }, { - key: 'toBasicAuth', - value: function toBasicAuth() { - return 'user:' + this.accessToken + '@'; - } - }]); +/***/ }), +/* 404 */ +/***/ ((module) => { - return AccessToken; -}(); +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} -var AppToken = exports.AppToken = function () { - function AppToken(opts) { - _classCallCheck(this, AppToken); +module.exports = isKeyable; - this.token = opts.token || ''; - } - _createClass(AppToken, [{ - key: 'toAuthHeader', - value: function toAuthHeader() { - return 'Bearer ' + this.token; - } - }, { - key: 'toBasicAuth', - value: function toBasicAuth() { - return 'user:' + this.token + '@'; - } - }]); +/***/ }), +/* 405 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return AppToken; -}(); +var getMapData = __webpack_require__(403); -function client(cozy, clientParams) { - if (!clientParams) { - clientParams = cozy._clientParams; - } - if (clientParams instanceof Client) { - return clientParams; - } - return new Client(clientParams); +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); } -function registerClient(cozy, clientParams) { - var cli = client(cozy, clientParams); - if (cli.isRegistered()) { - return Promise.reject(new Error('Client already registered')); - } - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/auth/register', cli.toRegisterJSON(), { - disableAuth: true - }).then(function (data) { - return new Client(data); - }); -} +module.exports = mapCacheGet; -function updateClient(cozy, clientParams) { - var resetSecret = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - var cli = client(cozy, clientParams); - if (!cli.isRegistered()) { - return Promise.reject(new Error('Client not registered')); - } - var data = cli.toRegisterJSON(); - data.client_id = cli.clientID; - if (resetSecret) data.client_secret = cli.clientSecret; +/***/ }), +/* 406 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/auth/register/' + cli.clientID, data, { - manualAuthCredentials: { - token: cli - } - }).then(function (data) { - return createClient(data, cli); - }); -} +var getMapData = __webpack_require__(403); -function unregisterClient(cozy, clientParams) { - var cli = client(cozy, clientParams); - if (!cli.isRegistered()) { - return Promise.reject(new Error('Client not registered')); - } - return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/auth/register/' + cli.clientID, null, { - manualAuthCredentials: { - token: cli - } - }); +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); } -// getClient will retrive the registered client informations from the server. -function getClient(cozy, clientParams) { - var cli = client(cozy, clientParams); - if (!cli.isRegistered()) { - return Promise.reject(new Error('Client not registered')); - } - if ((0, _utils.isOffline)()) { - return Promise.resolve(cli); - } - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/auth/register/' + cli.clientID, null, { - manualAuthCredentials: { - token: cli - } - }).then(function (data) { - return createClient(data, cli); - }).catch(function (err) { - // If we fall into an error while fetching the client (because of a - // bad connectivity for instance), we do not bail the whole process - // since the client should be able to continue with the persisted - // client and token. - // - // If it is an explicit Unauthorized error though, we bail, clear th - // cache and retry. - if (_fetch.FetchError.isUnauthorized(err) || _fetch.FetchError.isNotFound(err)) { - throw new Error('Client has been revoked'); - } - throw err; - }); -} +module.exports = mapCacheHas; -// createClient returns a new Client instance given on object containing the -// data of the client, from the API, and an old instance of the client. -function createClient(data, oldClient) { - var newClient = new Client(data); - // we need to keep track of the registrationAccessToken since it is send - // only on registration. The GET /auth/register/:client-id endpoint does - // not return this token. - var shouldPassRegistration = !!oldClient && oldClient.registrationAccessToken !== '' && newClient.registrationAccessToken === ''; - if (shouldPassRegistration) { - newClient.registrationAccessToken = oldClient.registrationAccessToken; - } - return newClient; -} -// getAuthCodeURL returns a pair {authURL,state} given a registered client. The -// state should be stored in order to be checked against on the user validation -// phase. -function getAuthCodeURL(cozy, client) { - var scopes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; +/***/ }), +/* 407 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!(client instanceof Client)) { - client = new Client(client); - } - if (!client.isRegistered()) { - throw new Error('Client not registered'); - } - var state = generateRandomState(); - var query = { - client_id: client.clientID, - redirect_uri: client.redirectURI, - state: state, - response_type: 'code', - scope: scopes.join(' ') - }; - return { - url: cozy._url + ('/auth/authorize?' + (0, _utils.encodeQuery)(query)), - state: state - }; -} +var getMapData = __webpack_require__(403); -// getAccessToken perform a request on the access_token entrypoint with the -// authorization_code grant type in order to generate a new access token for a -// newly registered client. -// -// This method extracts the access code and state from the given URL. By -// default it uses window.location.href. Also, it checks the given state with -// the one specified in the URL query parameter to prevent CSRF attacks. -function getAccessToken(cozy, client, state) { - var pageURL = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; - if (!state) { - return Promise.reject(new Error('Missing state value')); - } - var grantQueries = getGrantCodeFromPageURL(pageURL); - if (grantQueries === null) { - return Promise.reject(new Error('Missing states from current URL')); - } - if (state !== grantQueries.state) { - return Promise.reject(new Error('Given state does not match url query state')); - } - return retrieveToken(cozy, client, null, { - grant_type: 'authorization_code', - code: grantQueries.code - }); + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; } -// refreshToken perform a request on the access_token entrypoint with the -// refresh_token grant type in order to refresh the given token. -function refreshToken(cozy, client, token) { - return retrieveToken(cozy, client, token, { - grant_type: 'refresh_token', - refresh_token: token.refreshToken - }); -} +module.exports = mapCacheSet; -// oauthFlow performs the stateful registration and access granting of an OAuth -// client. -function oauthFlow(cozy, storage, clientParams, onRegistered) { - var ignoreCachedCredentials = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; - if (ignoreCachedCredentials) { - return storage.clear().then(function () { - return oauthFlow(cozy, storage, clientParams, onRegistered, false); - }); - } +/***/ }), +/* 408 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var tryCount = 0; +var baseToString = __webpack_require__(409); - function clearAndRetry(err) { - if (tryCount++ > 0) { - throw err; - } - return storage.clear().then(function () { - return oauthFlow(cozy, storage, clientParams, onRegistered); - }); - } +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString(value) { + return value == null ? '' : baseToString(value); +} - function registerNewClient() { - return storage.clear().then(function () { - return registerClient(cozy, clientParams); - }).then(function (client) { - var _getAuthCodeURL = getAuthCodeURL(cozy, client, clientParams.scopes), - url = _getAuthCodeURL.url, - state = _getAuthCodeURL.state; +module.exports = toString; - return storage.save(StateKey, { client: client, url: url, state: state }); - }); - } - return Promise.all([storage.load(CredsKey), storage.load(StateKey)]).then(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - credentials = _ref2[0], - storedState = _ref2[1]; +/***/ }), +/* 409 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // If credentials are cached we re-fetch the registered client with the - // said token. Fetching the client, if the token is outdated we should try - // the token is refreshed. - if (credentials) { - var oldClient = void 0, - _token = void 0; - try { - oldClient = new Client(credentials.client); - _token = new AccessToken(credentials.token); - } catch (err) { - // bad cache, we should clear and retry the process - return clearAndRetry(err); - } - return getClient(cozy, oldClient).then(function (client) { - return { client: client, token: _token }; - }).catch(function (err) { - // If we fall into an error while fetching the client (because of a - // bad connectivity for instance), we do not bail the whole process - // since the client should be able to continue with the persisted - // client and token. - // - // If it is an explicit Unauthorized error though, we bail, clear th - // cache and retry. - if (_fetch.FetchError.isUnauthorized(err) || _fetch.FetchError.isNotFound(err)) { - throw new Error('Client has been revoked'); - } - return { client: oldClient, token: _token }; - }); - } +var Symbol = __webpack_require__(47), + arrayMap = __webpack_require__(410), + isArray = __webpack_require__(55), + isSymbol = __webpack_require__(374); - // Otherwise register a new client if necessary (ie. no client is stored) - // and call the onRegistered callback to wait for the user to grant the - // access. Finally fetches to access token on success. - var statePromise = void 0; - if (!storedState) { - statePromise = registerNewClient(); - } else { - statePromise = Promise.resolve(storedState); - } +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; - var client = void 0, - state = void 0, - token = void 0; - return statePromise.then(function (data) { - client = data.client; - state = data.state; - return Promise.resolve(onRegistered(client, data.url)); - }).then(function (pageURL) { - return getAccessToken(cozy, client, state, pageURL); - }).then(function (t) { - token = t; - }).then(function () { - return storage.delete(StateKey); - }).then(function () { - return { client: client, token: token }; - }); - }).then(function (creds) { - return storage.save(CredsKey, creds); - }, function (err) { - if (_fetch.FetchError.isUnauthorized(err)) { - return clearAndRetry(err); - } else { - throw err; - } - }); -} +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; -// retrieveToken perform a request on the access_token entrypoint in order to -// fetch a token. -function retrieveToken(cozy, client, token, query) { - if (!(client instanceof Client)) { - client = new Client(client); +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; } - if (!client.isRegistered()) { - return Promise.reject(new Error('Client not registered')); + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; } - var body = (0, _utils.encodeQuery)(Object.assign({}, query, { - client_id: client.clientID, - client_secret: client.clientSecret - })); - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/auth/access_token', body, { - disableAuth: token === null, - dontRetry: true, - manualAuthCredentials: { client: client, token: token }, - headers: { 'Content-Type': 'application/x-www-form-urlencoded' } - }).then(function (data) { - data.refreshToken = data.refreshToken || query.refresh_token; - return new AccessToken(data); - }); + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } -// getGrantCodeFromPageURL extract the state and code query parameters from the -// given url -function getGrantCodeFromPageURL() { - var pageURL = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; +module.exports = baseToString; - if (pageURL === '' && typeof window !== 'undefined') { - pageURL = window.location.href; - } - var queries = (0, _utils.decodeQuery)(pageURL); - if (!queries.hasOwnProperty('state')) { - return null; - } - return { - state: queries['state'], - code: queries['code'] - }; -} -// generateRandomState will try to generate a 128bits random value from a secure -// pseudo random generator. It will fallback on Math.random if it cannot find -// such generator. -function generateRandomState() { - var buffer = void 0; - if (typeof window !== 'undefined' && typeof window.crypto !== 'undefined' && typeof window.crypto.getRandomValues === 'function') { - buffer = new Uint8Array(StateSize); - window.crypto.getRandomValues(buffer); - } else { - try { - buffer = __nested_webpack_require_16254__(12).randomBytes(StateSize); - } catch (e) { - buffer = null; - } - } - if (!buffer) { - buffer = new Array(StateSize); - for (var i = 0; i < buffer.length; i++) { - buffer[i] = Math.floor(Math.random() * 255); - } +/***/ }), +/* 410 */ +/***/ ((module) => { + +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); } - return btoa(String.fromCharCode.apply(null, buffer)).replace(/=+$/, '').replace(/\//g, '_').replace(/\+/g, '-'); + return result; } -/* WEBPACK VAR INJECTION */}.call(exports, __nested_webpack_require_16254__(6))) -/***/ }), -/* 4 */ -/***/ (function(module, exports) { +module.exports = arrayMap; -module.exports = __webpack_require__(475); /***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { +/* 411 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; +var isSymbol = __webpack_require__(374); +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.pickService = pickService; -// helper to serialize/deserialize an error for/from postMessage -var errorSerializer = exports.errorSerializer = function () { - function mapErrorProperties(from, to) { - var result = Object.assign(to, from); - var nativeProperties = ['name', 'message']; - return nativeProperties.reduce(function (result, property) { - if (from[property]) { - to[property] = from[property]; - } - return result; - }, result); +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; } - return { - serialize: function serialize(error) { - return mapErrorProperties(error, {}); - }, - deserialize: function deserialize(data) { - return mapErrorProperties(data, new Error(data.message)); - } - }; -}(); - -var first = function first(arr) { - return arr && arr[0]; -}; -// In a far future, the user will have to pick the desired service from a list. -// For now it's our job, an easy job as we arbitrary pick the first service of -// the list. -function pickService(intent, filterServices) { - var services = intent.attributes.services; - var filteredServices = filterServices ? (services || []).filter(filterServices) : services; - return first(filteredServices); + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } -/***/ }), -/* 6 */ -/***/ (function(module, exports) { +module.exports = toKey; -module.exports = __webpack_require__(478); /***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - +/* 412 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -Object.defineProperty(exports, "__esModule", { - value: true -}); -function indexKey(doc) { - return doc.type + '/' + doc.id; -} +var baseIteratee = __webpack_require__(413), + baseUniq = __webpack_require__(475); -function findByRef(resources, ref) { - return resources[indexKey(ref)]; +/** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The order of result values is determined by the + * order they occur in the array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ +function uniqBy(array, iteratee) { + return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : []; } -function handleResource(rawResource, resources, links) { - var resource = { - _id: rawResource.id, - _type: rawResource.type, - _rev: rawResource.meta && rawResource.meta.rev, - links: Object.assign({}, rawResource.links, links), - attributes: rawResource.attributes, - relations: function relations(name) { - var rels = rawResource.relationships[name]; - if (rels === undefined || rels.data === undefined) return undefined; - if (rels.data === null) return null; - if (!Array.isArray(rels.data)) return findByRef(resources, rels.data); - return rels.data.map(function (ref) { - return findByRef(resources, ref); - }); - } - }; - if (rawResource.relationships) { - resource.relationships = rawResource.relationships; - } - - resources[indexKey(rawResource)] = resource; +module.exports = uniqBy; - return resource; -} -function handleTopLevel(doc) { - var resources = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +/***/ }), +/* 413 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // build an index of included resource by Type & ID - var included = doc.included; +var baseMatches = __webpack_require__(414), + baseMatchesProperty = __webpack_require__(467), + identity = __webpack_require__(471), + isArray = __webpack_require__(55), + property = __webpack_require__(472); - if (Array.isArray(included)) { - included.forEach(function (r) { - return handleResource(r, resources, doc.links); - }); +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; } - - if (Array.isArray(doc.data)) { - return doc.data.map(function (r) { - return handleResource(r, resources, doc.links); - }); - } else { - return handleResource(doc.data, resources, doc.links); + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); } + return property(value); } -exports.default = handleTopLevel; - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __nested_webpack_require_36434__) { - -"use strict"; - +module.exports = baseIteratee; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.redirect = exports.getRedirectionURL = undefined; -var _regenerator = __nested_webpack_require_36434__(4); +/***/ }), +/* 414 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _regenerator2 = _interopRequireDefault(_regenerator); +var baseIsMatch = __webpack_require__(415), + getMatchData = __webpack_require__(464), + matchesStrictComparable = __webpack_require__(466); -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; +} -// Redirect to an app able to handle the doctype -// Redirections are more or less a hack of the intent API to retrieve an URL for -// accessing a given doctype or a given document. -// It needs to use a special action `REDIRECT` -var getRedirectionURL = exports.getRedirectionURL = function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, type, data) { - var intent, service, baseURL; - return _regenerator2.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - if (!(!type && !data)) { - _context.next = 2; - break; - } +module.exports = baseMatches; - throw new Error('Cannot retrieve redirection, at least type or doc must be provided'); - case 2: - _context.next = 4; - return create(cozy, 'REDIRECT', type, data); +/***/ }), +/* 415 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 4: - intent = _context.sent; - service = (0, _helpers.pickService)(intent); +var Stack = __webpack_require__(416), + baseIsEqual = __webpack_require__(422); - if (service) { - _context.next = 8; - break; - } +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; - throw new Error('Unable to find a service'); +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; - case 8: + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; - // Intents cannot be deleted now - // await deleteIntent(cozy, intent) + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} - baseURL = removeQueryString(service.href); - return _context.abrupt('return', data ? buildRedirectionURL(baseURL, data) : baseURL); +module.exports = baseIsMatch; - case 10: - case 'end': - return _context.stop(); - } - } - }, _callee, this); - })); - return function getRedirectionURL(_x3, _x4, _x5) { - return _ref.apply(this, arguments); - }; -}(); +/***/ }), +/* 416 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var redirect = exports.redirect = function () { - var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(cozy, type, doc, redirectFn) { - var redirectionURL; - return _regenerator2.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - if (window) { - _context2.next = 2; - break; - } +var ListCache = __webpack_require__(393), + stackClear = __webpack_require__(417), + stackDelete = __webpack_require__(418), + stackGet = __webpack_require__(419), + stackHas = __webpack_require__(420), + stackSet = __webpack_require__(421); - throw new Error('redirect() method can only be called in a browser'); +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; +} - case 2: - _context2.next = 4; - return getRedirectionURL(cozy, type, doc); +// Add methods to `Stack`. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; - case 4: - redirectionURL = _context2.sent; +module.exports = Stack; - if (!(redirectFn && typeof redirectFn === 'function')) { - _context2.next = 7; - break; - } - return _context2.abrupt('return', redirectFn(redirectionURL)); +/***/ }), +/* 417 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 7: +var ListCache = __webpack_require__(393); - window.location.href = redirectionURL; +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = new ListCache; + this.size = 0; +} - case 8: - case 'end': - return _context2.stop(); - } - } - }, _callee2, this); - })); +module.exports = stackClear; - return function redirect(_x6, _x7, _x8, _x9) { - return _ref2.apply(this, arguments); - }; -}(); -exports.create = create; -exports.createService = createService; +/***/ }), +/* 418 */ +/***/ ((module) => { -var _fetch = __nested_webpack_require_36434__(0); +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); -var _helpers = __nested_webpack_require_36434__(5); + this.size = data.size; + return result; +} -var _client = __nested_webpack_require_36434__(16); +module.exports = stackDelete; -var client = _interopRequireWildcard(_client); -var _service = __nested_webpack_require_36434__(17); +/***/ }), +/* 419 */ +/***/ ((module) => { -var service = _interopRequireWildcard(_service); +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } +module.exports = stackGet; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } +/***/ }), +/* 420 */ +/***/ ((module) => { -function create(cozy, action, type) { - var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; - var permissions = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : []; +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} - if (!action) throw new Error('Misformed intent, "action" property must be provided'); - if (!type) throw new Error('Misformed intent, "type" property must be provided'); +module.exports = stackHas; - var createPromise = (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/intents', { - data: { - type: 'io.cozy.intents', - attributes: { - action: action, - type: type, - data: data, - permissions: permissions - } - } - }); - createPromise.start = function (element, onReadyCallback) { - var options = { - filteredServices: data.filteredServices, - onReadyCallback: onReadyCallback - }; +/***/ }), +/* 421 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - delete data.filteredServices; +var ListCache = __webpack_require__(393), + Map = __webpack_require__(401), + MapCache = __webpack_require__(378); - return createPromise.then(function (intent) { - return client.start(cozy, intent, element, data, options); - }); - }; +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; - return createPromise; +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ +function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; } -// returns a service to communicate with intent client -function createService(cozy, intentId, serviceWindow) { - return service.start(cozy, intentId, serviceWindow); -} +module.exports = stackSet; -function removeQueryString(url) { - return url.replace(/\?[^/#]*/, ''); -} -function isSerializable(value) { - return !['object', 'function'].includes(typeof value === 'undefined' ? 'undefined' : _typeof(value)); -} +/***/ }), +/* 422 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function buildRedirectionURL(url, data) { - var parameterStrings = Object.keys(data).filter(function (key) { - return isSerializable(data[key]); - }).map(function (key) { - return key + '=' + data[key]; - }); +var baseIsEqualDeep = __webpack_require__(423), + isObjectLike = __webpack_require__(53); - return parameterStrings.length ? url + '?' + parameterStrings.join('&') : url; +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); } -/***/ }), -/* 9 */ -/***/ (function(module, exports, __nested_webpack_require_42748__) { +module.exports = baseIsEqual; -"use strict"; +/***/ }), +/* 423 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; +var Stack = __webpack_require__(416), + equalArrays = __webpack_require__(424), + equalByTag = __webpack_require__(430), + equalObjects = __webpack_require__(434), + getTag = __webpack_require__(459), + isArray = __webpack_require__(55), + isBuffer = __webpack_require__(446), + isTypedArray = __webpack_require__(449); -var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global fetch URL */ +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1; +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; -var _utils = __nested_webpack_require_42748__(1); +/** Used for built-in method references. */ +var objectProto = Object.prototype; -var _auth_storage = __nested_webpack_require_42748__(10); +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; -var _auth_v = __nested_webpack_require_42748__(11); +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : getTag(object), + othTag = othIsArr ? arrayTag : getTag(other); -var _auth_v2 = __nested_webpack_require_42748__(3); + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; -var auth = _interopRequireWildcard(_auth_v2); + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; -var _data = __nested_webpack_require_42748__(13); + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); -var data = _interopRequireWildcard(_data); + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; -var _fetch2 = __nested_webpack_require_42748__(0); + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} -var cozyFetch = _interopRequireWildcard(_fetch2); +module.exports = baseIsEqualDeep; -var _mango = __nested_webpack_require_42748__(14); -var mango = _interopRequireWildcard(_mango); +/***/ }), +/* 424 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _files = __nested_webpack_require_42748__(15); +var SetCache = __webpack_require__(425), + arraySome = __webpack_require__(428), + cacheHas = __webpack_require__(429); -var files = _interopRequireWildcard(_files); +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; -var _intents = __nested_webpack_require_42748__(8); +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; -var intents = _interopRequireWildcard(_intents); + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; -var _jobs = __nested_webpack_require_42748__(18); + stack.set(array, other); + stack.set(other, array); -var jobs = _interopRequireWildcard(_jobs); + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; -var _offline = __nested_webpack_require_42748__(19); + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} -var offline = _interopRequireWildcard(_offline); +module.exports = equalArrays; -var _settings = __nested_webpack_require_42748__(23); -var settings = _interopRequireWildcard(_settings); +/***/ }), +/* 425 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _relations = __nested_webpack_require_42748__(24); +var MapCache = __webpack_require__(378), + setCacheAdd = __webpack_require__(426), + setCacheHas = __webpack_require__(427); -var relations = _interopRequireWildcard(_relations); +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } +} -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; +SetCache.prototype.has = setCacheHas; -var AppTokenV3 = auth.AppToken, - AccessTokenV3 = auth.AccessToken, - ClientV3 = auth.Client; +module.exports = SetCache; -var AuthNone = 0; -var AuthRunning = 1; -var AuthError = 2; -var AuthOK = 3; +/***/ }), +/* 426 */ +/***/ ((module) => { -var defaultClientParams = { - softwareID: 'github.com/cozy/cozy-client-js' -}; +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; -var dataProto = { - create: data.create, - find: data.find, - findMany: data.findMany, - findAll: data.findAll, - update: data.update, - delete: data._delete, - updateAttributes: data.updateAttributes, - changesFeed: data.changesFeed, - defineIndex: mango.defineIndex, - query: mango.query, - addReferencedFiles: relations.addReferencedFiles, - removeReferencedFiles: relations.removeReferencedFiles, - listReferencedFiles: relations.listReferencedFiles, - fetchReferencedFiles: relations.fetchReferencedFiles, - destroy: function destroy() { - (0, _utils.warn)('destroy is deprecated, use cozy.data.delete instead.'); - return data._delete.apply(data, arguments); - } -}; +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} -var authProto = { - client: auth.client, - registerClient: auth.registerClient, - updateClient: auth.updateClient, - unregisterClient: auth.unregisterClient, - getClient: auth.getClient, - getAuthCodeURL: auth.getAuthCodeURL, - getAccessToken: auth.getAccessToken, - refreshToken: auth.refreshToken -}; +module.exports = setCacheAdd; -var filesProto = { - create: files.create, - createDirectory: files.createDirectory, - createDirectoryByPath: files.createDirectoryByPath, - updateById: files.updateById, - updateAttributesById: files.updateAttributesById, - updateAttributesByPath: files.updateAttributesByPath, - trashById: files.trashById, - statById: files.statById, - statByPath: files.statByPath, - downloadById: files.downloadById, - downloadByPath: files.downloadByPath, - getDownloadLinkById: files.getDownloadLinkById, - getDownloadLink: files.getDownloadLinkByPath, // DEPRECATED, should be removed very soon - getDownloadLinkByPath: files.getDownloadLinkByPath, - getArchiveLink: function getArchiveLink() { - (0, _utils.warn)('getArchiveLink is deprecated, use cozy.files.getArchiveLinkByPaths instead.'); - return files.getArchiveLinkByPaths.apply(files, arguments); - }, - getArchiveLinkByPaths: files.getArchiveLinkByPaths, - getArchiveLinkByIds: files.getArchiveLinkByIds, - getFilePath: files.getFilePath, - getCollectionShareLink: files.getCollectionShareLink, - query: mango.queryFiles, - listTrash: files.listTrash, - clearTrash: files.clearTrash, - restoreById: files.restoreById, - destroyById: files.destroyById -}; -var intentsProto = { - create: intents.create, - createService: intents.createService, - getRedirectionURL: intents.getRedirectionURL, - redirect: intents.redirect -}; +/***/ }), +/* 427 */ +/***/ ((module) => { -var jobsProto = { - create: jobs.create, - count: jobs.count, - queued: jobs.queued -}; +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} -var offlineProto = { - init: offline.init, - getDoctypes: offline.getDoctypes, - // database - hasDatabase: offline.hasDatabase, - getDatabase: offline.getDatabase, - createDatabase: offline.createDatabase, - migrateDatabase: offline.migrateDatabase, - destroyDatabase: offline.destroyDatabase, - destroyAllDatabase: offline.destroyAllDatabase, - // replication - hasReplication: offline.hasReplication, - replicateFromCozy: offline.replicateFromCozy, - stopReplication: offline.stopReplication, - stopAllReplication: offline.stopAllReplication, - // repeated replication - hasRepeatedReplication: offline.hasRepeatedReplication, - startRepeatedReplication: offline.startRepeatedReplication, - stopRepeatedReplication: offline.stopRepeatedReplication, - stopAllRepeatedReplication: offline.stopAllRepeatedReplication -}; +module.exports = setCacheHas; -var settingsProto = { - diskUsage: settings.diskUsage, - changePassphrase: settings.changePassphrase, - getInstance: settings.getInstance, - updateInstance: settings.updateInstance, - getClients: settings.getClients, - deleteClientById: settings.deleteClientById, - updateLastSync: settings.updateLastSync -}; -var ensureHasReconnectParam = function ensureHasReconnectParam(_url) { - var url = new URL(_url); - if (url.searchParams && !url.searchParams.has('reconnect')) { - url.searchParams.append('reconnect', 1); - } else if (!url.search || url.search.indexOf('reconnect') === -1) { - // Some old navigators do not have the searchParams API - // and it is not polyfilled by babel-polyfill - url.search = url.search + '&reconnect=1'; - } - return url.toString(); -}; +/***/ }), +/* 428 */ +/***/ ((module) => { -var Client = function () { - function Client(options) { - _classCallCheck(this, Client); +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; - this.data = {}; - this.files = {}; - this.intents = {}; - this.jobs = {}; - this.offline = {}; - this.settings = {}; - this.auth = { - Client: ClientV3, - AccessToken: AccessTokenV3, - AppToken: AppTokenV3, - AppTokenV2: _auth_v.AppToken, - LocalStorage: _auth_storage.LocalStorage, - MemoryStorage: _auth_storage.MemoryStorage - }; - this._inited = false; - if (options) { - this.init(options); + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; } } + return false; +} - _createClass(Client, [{ - key: 'init', - value: function init() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; +module.exports = arraySome; - this._inited = true; - this._oauth = false; // is oauth activated or not - this._token = null; // application token - this._authstate = AuthNone; - this._authcreds = null; - this._storage = null; - this._version = options.version || null; - this._offline = null; - var token = options.token; - var oauth = options.oauth; - if (token && oauth) { - throw new Error('Cannot specify an application token with a oauth activated'); - } +/***/ }), +/* 429 */ +/***/ ((module) => { - if (token) { - this._token = new AppTokenV3({ token: token }); - } else if (oauth) { - this._oauth = true; - this._storage = oauth.storage; - this._clientParams = Object.assign({}, defaultClientParams, oauth.clientParams); - this._onRegistered = oauth.onRegistered || nopOnRegistered; - } +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} - var url = options.cozyURL || ''; - while (url[url.length - 1] === '/') { - url = url.slice(0, -1); - } +module.exports = cacheHas; - this._url = url; - this._invalidTokenErrorHandler = options.onInvalidTokenError !== undefined ? options.onInvalidTokenError : cozyFetch.handleInvalidTokenError; +/***/ }), +/* 430 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var disablePromises = !!options.disablePromises; - addToProto(this, this.data, dataProto, disablePromises); - addToProto(this, this.auth, authProto, disablePromises); - addToProto(this, this.files, filesProto, disablePromises); - addToProto(this, this.intents, intentsProto, disablePromises); - addToProto(this, this.jobs, jobsProto, disablePromises); - addToProto(this, this.offline, offlineProto, disablePromises); - addToProto(this, this.settings, settingsProto, disablePromises); +var Symbol = __webpack_require__(47), + Uint8Array = __webpack_require__(431), + eq = __webpack_require__(397), + equalArrays = __webpack_require__(424), + mapToArray = __webpack_require__(432), + setToArray = __webpack_require__(433); - if (options.offline) { - this.offline.init(options.offline); - } +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; - this.fetch = function _fetch(method, url) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; - return cozyFetch.cozyFetch(this, url, _extends({}, options, { method: method })); - }; +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; - this.fetchJSON = function _fetchJSON() { - var args = [this].concat(Array.prototype.slice.call(arguments)); - return cozyFetch.cozyFetchJSON.apply(this, args); - }; - } - }, { - key: 'authorize', - value: function authorize() { - var _this = this; +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; - var forceTokenRefresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; - var state = this._authstate; - if (state === AuthOK || state === AuthRunning) { - return this._authcreds; + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; } + return true; - this._authstate = AuthRunning; - this._authcreds = this.isV2().then(function (isV2) { - if (isV2 && _this._oauth) { - throw new Error('OAuth is not supported on the V2 stack'); - } - if (_this._oauth) { - if (forceTokenRefresh && _this._clientParams.redirectURI) { - _this._clientParams.redirectURI = ensureHasReconnectParam(_this._clientParams.redirectURI); - } - return auth.oauthFlow(_this, _this._storage, _this._clientParams, _this._onRegistered, forceTokenRefresh); - } - // we expect to be on a client side application running in a browser - // with cookie-based authentication. - if (isV2) { - return (0, _auth_v.getAppToken)(); - } else if (_this._token) { - return Promise.resolve({ client: null, token: _this._token }); - } else { - throw new Error('Missing application token'); - } - }); + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); - this._authcreds.then(function () { - _this._authstate = AuthOK; - }, function () { - _this._authstate = AuthError; - }); + case errorTag: + return object.name == other.name && object.message == other.message; - return this._authcreds; - } - }, { - key: 'saveCredentials', - value: function saveCredentials(client, token) { - var creds = { client: client, token: token }; - if (!this._storage || this._authstate === AuthRunning) { - return Promise.resolve(creds); - } - this._storage.save(auth.CredsKey, creds); - this._authcreds = Promise.resolve(creds); - return this._authcreds; - } - }, { - key: 'fullpath', - value: function fullpath(path) { - var _this2 = this; + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); - return this.isV2().then(function (isV2) { - var pathprefix = isV2 ? '/ds-api' : ''; - return _this2._url + pathprefix + path; - }); - } - }, { - key: 'isV2', - value: function isV2() { - var _this3 = this; + case mapTag: + var convert = mapToArray; - if (!this._version) { - return (0, _utils.retry)(function () { - return fetch(_this3._url + '/status/'); - }, 3)().then(function (res) { - if (!res.ok) { - throw new Error('Could not fetch cozy status'); - } else { - return res.json(); - } - }).then(function (status) { - _this3._version = status.datasystem !== undefined ? 2 : 3; - return _this3.isV2(); - }); + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; } - return Promise.resolve(this._version === 2); - } - }]); + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG; - return Client; -}(); + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; -function nopOnRegistered() { - throw new Error('Missing onRegistered callback'); + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; } -function protoify(context, fn) { - return function prototyped() { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } +module.exports = equalByTag; - return fn.apply(undefined, [context].concat(args)); - }; -} -function addToProto(ctx, obj, proto, disablePromises) { - for (var attr in proto) { - var fn = protoify(ctx, proto[attr]); - if (disablePromises) { - fn = (0, _utils.unpromiser)(fn); - } - obj[attr] = fn; - } -} +/***/ }), +/* 431 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var root = __webpack_require__(48); + +/** Built-in value references. */ +var Uint8Array = root.Uint8Array; + +module.exports = Uint8Array; -module.exports = new Client(); -Object.assign(module.exports, { Client: Client, LocalStorage: _auth_storage.LocalStorage, MemoryStorage: _auth_storage.MemoryStorage }); /***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { +/* 432 */ +/***/ ((module) => { -"use strict"; +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} -Object.defineProperty(exports, "__esModule", { - value: true -}); +module.exports = mapToArray; -var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +/***/ }), +/* 433 */ +/***/ ((module) => { -var LocalStorage = exports.LocalStorage = function () { - function LocalStorage(storage, prefix) { - _classCallCheck(this, LocalStorage); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); - if (!storage && typeof window !== 'undefined') { - storage = window.localStorage; - } - this.storage = storage; - this.prefix = prefix || 'cozy:oauth:'; - } + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} - _createClass(LocalStorage, [{ - key: 'save', - value: function save(key, value) { - var _this = this; +module.exports = setToArray; - return new Promise(function (resolve) { - _this.storage.setItem(_this.prefix + key, JSON.stringify(value)); - resolve(value); - }); - } - }, { - key: 'load', - value: function load(key) { - var _this2 = this; - return new Promise(function (resolve) { - var item = _this2.storage.getItem(_this2.prefix + key); - if (!item) { - resolve(); - } else { - resolve(JSON.parse(item)); - } - }); - } - }, { - key: 'delete', - value: function _delete(key) { - var _this3 = this; +/***/ }), +/* 434 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return new Promise(function (resolve) { - return resolve(_this3.storage.removeItem(_this3.prefix + key)); - }); - } - }, { - key: 'clear', - value: function clear() { - var _this4 = this; +var getAllKeys = __webpack_require__(435); - return new Promise(function (resolve) { - var storage = _this4.storage; - for (var i = 0; i < storage.length; i++) { - var key = storage.key(i); - if (key.indexOf(_this4.prefix) === 0) { - storage.removeItem(key); - } - } - resolve(); - }); - } - }]); +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1; - return LocalStorage; -}(); +/** Used for built-in method references. */ +var objectProto = Object.prototype; -var MemoryStorage = exports.MemoryStorage = function () { - function MemoryStorage() { - _classCallCheck(this, MemoryStorage); +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - this.hash = Object.create(null); +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; } + var result = true; + stack.set(object, other); + stack.set(other, object); - _createClass(MemoryStorage, [{ - key: 'save', - value: function save(key, value) { - this.hash[key] = value; - return Promise.resolve(value); - } - }, { - key: 'load', - value: function load(key) { - return Promise.resolve(this.hash[key]); + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); } - }, { - key: 'delete', - value: function _delete(key) { - var deleted = delete this.hash[key]; - return Promise.resolve(deleted); + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; } - }, { - key: 'clear', - value: function clear() { - this.hash = Object.create(null); - return Promise.resolve(); + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; } - }]); + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +module.exports = equalObjects; - return MemoryStorage; -}(); /***/ }), -/* 11 */ -/***/ (function(module, exports, __nested_webpack_require_58943__) { +/* 435 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; -/* WEBPACK VAR INJECTION */(function(btoa) { +var baseGetAllKeys = __webpack_require__(436), + getSymbols = __webpack_require__(438), + keys = __webpack_require__(441); -Object.defineProperty(exports, "__esModule", { - value: true -}); +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); +} -var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +module.exports = getAllKeys; -exports.getAppToken = getAppToken; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +/***/ }), +/* 436 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/* global btoa */ -var V2TOKEN_ABORT_TIMEOUT = 3000; +var arrayPush = __webpack_require__(437), + isArray = __webpack_require__(55); -function getAppToken() { - return new Promise(function (resolve, reject) { - if (typeof window === 'undefined') { - return reject(new Error('getV2Token should be used in browser')); - } else if (!window.parent) { - return reject(new Error('getV2Token should be used in iframe')); - } else if (!window.parent.postMessage) { - return reject(new Error('getV2Token should be used in modern browser')); - } - var origin = window.location.origin; - var intent = { action: 'getToken' }; - var timeout = null; - var receiver = function receiver(event) { - var token = void 0; - try { - token = new AppToken({ - appName: event.data.appName, - token: event.data.token - }); - } catch (e) { - reject(e); - return; - } - window.removeEventListener('message', receiver); - clearTimeout(timeout); - resolve({ client: null, token: token }); - }; - window.addEventListener('message', receiver, false); - window.parent.postMessage(intent, origin); - timeout = setTimeout(function () { - reject(new Error('No response from parent iframe after 3s')); - }, V2TOKEN_ABORT_TIMEOUT); - }); +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); } -var AppToken = exports.AppToken = function () { - function AppToken(opts) { - _classCallCheck(this, AppToken); +module.exports = baseGetAllKeys; - this.appName = opts.appName || ''; - this.token = opts.token || ''; + +/***/ }), +/* 437 */ +/***/ ((module) => { + +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; } + return array; +} - _createClass(AppToken, [{ - key: 'toAuthHeader', - value: function toAuthHeader() { - return 'Basic ' + btoa(this.appName + ':' + this.token); - } - }]); +module.exports = arrayPush; - return AppToken; -}(); -/* WEBPACK VAR INJECTION */}.call(exports, __nested_webpack_require_58943__(6))) /***/ }), -/* 12 */ -/***/ (function(module, exports) { +/* 438 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -module.exports = __webpack_require__(76); +var arrayFilter = __webpack_require__(439), + stubArray = __webpack_require__(440); -/***/ }), -/* 13 */ -/***/ (function(module, exports, __nested_webpack_require_61680__) { +/** Used for built-in method references. */ +var objectProto = Object.prototype; -"use strict"; +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.create = create; -exports.find = find; -exports.findMany = findMany; -exports.findAll = findAll; -exports.changesFeed = changesFeed; -exports.update = update; -exports.updateAttributes = updateAttributes; -exports._delete = _delete; +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; -var _utils = __nested_webpack_require_61680__(1); +module.exports = getSymbols; -var _doctypes = __nested_webpack_require_61680__(2); -var _fetch = __nested_webpack_require_61680__(0); +/***/ }), +/* 439 */ +/***/ ((module) => { -var NOREV = 'stack-v2-no-rev'; +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; -function create(cozy, doctype, attributes) { - return cozy.isV2().then(function (isV2) { - doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); - if (isV2) { - attributes.docType = doctype; + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; } - var path = (0, _utils.createPath)(cozy, isV2, doctype, attributes._id); - var httpVerb = attributes._id ? 'PUT' : 'POST'; - delete attributes._id; - return (0, _fetch.cozyFetchJSON)(cozy, httpVerb, path, attributes).then(function (resp) { - if (isV2) { - return find(cozy, doctype, resp._id); - } else { - return resp.data; - } - }); - }); + } + return result; } -function find(cozy, doctype, id) { - return cozy.isV2().then(function (isV2) { - doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); - - if (!id) { - return Promise.reject(new Error('Missing id parameter')); - } +module.exports = arrayFilter; - var path = (0, _utils.createPath)(cozy, isV2, doctype, id); - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', path).then(function (resp) { - if (isV2) { - return Object.assign(resp, { _rev: NOREV }); - } else { - return resp; - } - }); - }); -} -function findMany(cozy, doctype, ids) { - if (!(ids instanceof Array)) { - return Promise.reject(new Error('Parameter ids must be a non-empty array')); - } - if (ids.length === 0) { - // So users don't need to be defensive regarding the array content. - // This should not hide issues in user code since the result will be an - // empty object anyway. - return Promise.resolve({}); - } +/***/ }), +/* 440 */ +/***/ ((module) => { - return cozy.isV2().then(function (isV2) { - if (isV2) { - return Promise.reject(new Error('findMany is not available on v2')); - } +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} - var path = (0, _utils.createPath)(cozy, isV2, doctype, '_all_docs', { - include_docs: true - }); +module.exports = stubArray; - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, { keys: ids }).then(function (resp) { - var docs = {}; - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; +/***/ }), +/* 441 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - try { - for (var _iterator = resp.rows[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var row = _step.value; - var key = row.key, - doc = row.doc, - error = row.error; +var arrayLikeKeys = __webpack_require__(442), + baseKeys = __webpack_require__(454), + isArrayLike = __webpack_require__(458); - docs[key] = error ? { error: error } : { doc: doc }; - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} - return docs; - }).catch(function (error) { - if (error.status !== 404) return Promise.reject(error); +module.exports = keys; - // When no doc was ever created and the database does not exist yet, - // the response will be a 404 error. - var docs = {}; - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; +/***/ }), +/* 442 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - try { - for (var _iterator2 = ids[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var id = _step2.value; +var baseTimes = __webpack_require__(443), + isArguments = __webpack_require__(444), + isArray = __webpack_require__(55), + isBuffer = __webpack_require__(446), + isIndex = __webpack_require__(448), + isTypedArray = __webpack_require__(449); - docs[id] = { error: error }; - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2.return) { - _iterator2.return(); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } +/** Used for built-in method references. */ +var objectProto = Object.prototype; - return docs; - }); - }); -} +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; -function findAll(cozy, doctype) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { include_docs: true }; +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; - return cozy.isV2().then(function (isV2) { - if (isV2) { - return Promise.reject(new Error('findAll is not available on v2')); + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); } + } + return result; +} - var path = (0, _utils.createPath)(cozy, isV2, doctype, '_all_docs', options); - - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, {}).then(function (resp) { - var docs = []; +module.exports = arrayLikeKeys; - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - try { - for (var _iterator3 = resp.rows[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var row = _step3.value; - var doc = row.doc; - // if not couchDB indexes +/***/ }), +/* 443 */ +/***/ ((module) => { - if (!doc._id.match(/_design\//)) docs.push(doc); - } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; - } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3.return) { - _iterator3.return(); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } - } - } +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); - return docs; - }).catch(function (error) { - // the _all_docs endpoint returns a 404 error if no document with the given - // doctype exists. - if (error.status === 404) return []; - throw error; - }); - }); + while (++index < n) { + result[index] = iteratee(index); + } + return result; } -function changesFeed(cozy, doctype, options) { - return cozy.isV2().then(function (isV2) { - doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); - var path = (0, _utils.createPath)(cozy, isV2, doctype, '_changes', options); - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', path); - }); -} +module.exports = baseTimes; -function update(cozy, doctype, doc, changes) { - return cozy.isV2().then(function (isV2) { - doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); - var _id = doc._id, - _rev = doc._rev; +/***/ }), +/* 444 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!_id) { - return Promise.reject(new Error('Missing _id field in passed document')); - } +var baseIsArguments = __webpack_require__(445), + isObjectLike = __webpack_require__(53); - if (!isV2 && !_rev) { - return Promise.reject(new Error('Missing _rev field in passed document')); - } +/** Used for built-in method references. */ +var objectProto = Object.prototype; - if (isV2) { - changes = Object.assign({ _id: _id }, changes); - } else { - changes = Object.assign({ _id: _id, _rev: _rev }, changes); - } +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - var path = (0, _utils.createPath)(cozy, isV2, doctype, _id); - return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', path, changes).then(function (resp) { - if (isV2) { - return find(cozy, doctype, _id); - } else { - return resp.data; - } - }); - }); -} +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; -function updateAttributes(cozy, doctype, _id, changes) { - var tries = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 3; +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); +}; - return cozy.isV2().then(function (isV2) { - doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); - return find(cozy, doctype, _id).then(function (doc) { - return update(cozy, doctype, doc, Object.assign({ _id: _id }, doc, changes)); - }).catch(function (err) { - if (tries > 0) { - return updateAttributes(cozy, doctype, _id, changes, tries - 1); - } else { - throw err; - } - }); - }); -} +module.exports = isArguments; -function _delete(cozy, doctype, doc) { - return cozy.isV2().then(function (isV2) { - doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); - var _id = doc._id, - _rev = doc._rev; +/***/ }), +/* 445 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!_id) { - return Promise.reject(new Error('Missing _id field in passed document')); - } +var baseGetTag = __webpack_require__(46), + isObjectLike = __webpack_require__(53); - if (!isV2 && !_rev) { - return Promise.reject(new Error('Missing _rev field in passed document')); - } +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]'; - var query = isV2 ? null : { rev: _rev }; - var path = (0, _utils.createPath)(cozy, isV2, doctype, _id, query); - return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', path).then(function (resp) { - if (isV2) { - return { id: _id, rev: NOREV }; - } else { - return resp; - } - }); - }); +/** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ +function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; } +module.exports = baseIsArguments; + + /***/ }), -/* 14 */ -/***/ (function(module, exports, __nested_webpack_require_69980__) { +/* 446 */ +/***/ ((module, exports, __webpack_require__) => { -"use strict"; +/* module decorator */ module = __webpack_require__.nmd(module); +var root = __webpack_require__(48), + stubFalse = __webpack_require__(447); +/** Detect free variable `exports`. */ +var freeExports = true && exports && !exports.nodeType && exports; -Object.defineProperty(exports, "__esModule", { - value: true -}); +/** Detect free variable `module`. */ +var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined; -exports.defineIndex = defineIndex; -exports.query = query; -exports.queryFiles = queryFiles; -exports.parseSelector = parseSelector; -exports.normalizeSelector = normalizeSelector; -exports.makeMapReduceQuery = makeMapReduceQuery; +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; -var _utils = __nested_webpack_require_69980__(1); +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; -var _doctypes = __nested_webpack_require_69980__(2); +module.exports = isBuffer; -var _fetch = __nested_webpack_require_69980__(0); -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +/***/ }), +/* 447 */ +/***/ ((module) => { -function defineIndex(cozy, doctype, fields) { - return cozy.isV2().then(function (isV2) { - doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); - if (!Array.isArray(fields) || fields.length === 0) { - throw new Error('defineIndex fields should be a non-empty array'); - } - if (isV2) { - return defineIndexV2(cozy, doctype, fields); - } else { - return defineIndexV3(cozy, doctype, fields); - } - }); +/** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ +function stubFalse() { + return false; } -function query(cozy, indexRef, options) { - return cozy.isV2().then(function (isV2) { - if (!indexRef) { - throw new Error('query should be passed the indexRef'); - } - if (isV2) { - return queryV2(cozy, indexRef, options); - } else { - return queryV3(cozy, indexRef, options); - } - }); -} +module.exports = stubFalse; -function queryFiles(cozy, indexRef, options) { - var opts = getV3Options(indexRef, options); - return (0, _fetch.cozyFetchRawJSON)(cozy, 'POST', '/files/_find', opts).then(function (response) { - return options.wholeResponse ? response : response.docs; - }); -} -// Internals +/***/ }), +/* 448 */ +/***/ ((module) => { -var VALUEOPERATORS = ['$eq', '$gt', '$gte', '$lt', '$lte']; -var LOGICOPERATORS = ['$or', '$and', '$not']; +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; -/* eslint-disable */ -var MAP_TEMPLATE = function (doc) { - if (doc.docType.toLowerCase() === 'DOCTYPEPLACEHOLDER') { - emit(FIELDSPLACEHOLDER, doc); - } -}.toString().replace(/ /g, '').replace(/\n/g, ''); -var COUCHDB_INFINITY = { '\uFFFF': '\uFFFF' }; -var COUCHDB_LOWEST = null; -/* eslint-enable */ +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; -// defineIndexV2 is equivalent to defineIndex but only works for V2. -// It transforms the index fields into a map reduce view. -function defineIndexV2(cozy, doctype, fields) { - var indexName = 'by' + fields.map(capitalize).join(''); - var indexDefinition = { - map: makeMapFunction(doctype, fields), - reduce: '_count' - }; - var path = '/request/' + doctype + '/' + indexName + '/'; - return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', path, indexDefinition).then(function () { - return { - doctype: doctype, - type: 'mapreduce', - name: indexName, - fields: fields - }; - }); +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); } -function defineIndexV3(cozy, doctype, fields) { - var path = (0, _utils.createPath)(cozy, false, doctype, '_index'); - var indexDefinition = { index: { fields: fields } }; - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, indexDefinition).then(function (response) { - var indexResult = { - doctype: doctype, - type: 'mango', - name: response.id, - fields: fields - }; +module.exports = isIndex; - if (response.result === 'exists') return indexResult; - // indexes might not be usable right after being created; so we delay the resolving until they are - var selector = {}; - selector[fields[0]] = { $gt: null }; +/***/ }), +/* 449 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var opts = getV3Options(indexResult, { selector: selector }); - var path = (0, _utils.createPath)(cozy, false, indexResult.doctype, '_find'); - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function () { - return indexResult; - }).catch(function () { - // one retry - return (0, _utils.sleep)(1000).then(function () { - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts); - }).then(function () { - return indexResult; - }).catch(function () { - return (0, _utils.sleep)(500).then(function () { - return indexResult; - }); - }); - }); - }); -} +var baseIsTypedArray = __webpack_require__(450), + baseUnary = __webpack_require__(452), + nodeUtil = __webpack_require__(453); -// queryV2 is equivalent to query but only works for V2. -// It transforms the query into a _views call using makeMapReduceQuery -function queryV2(cozy, indexRef, options) { - if (indexRef.type !== 'mapreduce') { - throw new Error('query indexRef should be the return value of defineIndexV2'); - } - if (options.fields) { - (0, _utils.warn)('query fields will be ignored on v2'); - } +/* Node.js helper references. */ +var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - var path = '/request/' + indexRef.doctype + '/' + indexRef.name + '/'; - var opts = makeMapReduceQuery(indexRef, options); - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function (response) { - return response.map(function (r) { - return r.value; - }); - }); -} +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; -// queryV3 is equivalent to query but only works for V3 -function queryV3(cozy, indexRef, options) { - var opts = getV3Options(indexRef, options); +module.exports = isTypedArray; - var path = (0, _utils.createPath)(cozy, false, indexRef.doctype, '_find'); - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function (response) { - return options.wholeResponse ? response : response.docs; - }); -} -function getV3Options(indexRef, options) { - if (indexRef.type !== 'mango') { - throw new Error('indexRef should be the return value of defineIndexV3'); - } +/***/ }), +/* 450 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var opts = { - use_index: indexRef.name, - fields: options.fields, - selector: options.selector, - limit: options.limit, - skip: options.skip, - since: options.since, - sort: options.sort - }; +var baseGetTag = __webpack_require__(46), + isLength = __webpack_require__(451), + isObjectLike = __webpack_require__(53); - if (options.descending) { - opts.sort = indexRef.fields.map(function (f) { - return _defineProperty({}, f, 'desc'); - }); - } +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; - return opts; -} +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; -// misc -function capitalize(name) { - return name.charAt(0).toUpperCase() + name.slice(1); +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = +typedArrayTags[errorTag] = typedArrayTags[funcTag] = +typedArrayTags[mapTag] = typedArrayTags[numberTag] = +typedArrayTags[objectTag] = typedArrayTags[regexpTag] = +typedArrayTags[setTag] = typedArrayTags[stringTag] = +typedArrayTags[weakMapTag] = false; + +/** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ +function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; } -function makeMapFunction(doctype, fields) { - fields = '[' + fields.map(function (name) { - return 'doc.' + name; - }).join(',') + ']'; +module.exports = baseIsTypedArray; - return MAP_TEMPLATE.replace('DOCTYPEPLACEHOLDER', doctype.toLowerCase()).replace('FIELDSPLACEHOLDER', fields); -} -// parseSelector takes a mango selector and returns it as an array of filter -// a filter is [path, operator, value] array -// a path is an array of field names -// This function is only exported so it can be unit tested. -// Example : -// parseSelector({"test":{"deep": {"$gt": 3}}}) -// [[['test', 'deep'], '$gt', 3 ]] -function parseSelector(selector) { - var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - var operator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '$eq'; +/***/ }), +/* 451 */ +/***/ ((module) => { - if ((typeof selector === 'undefined' ? 'undefined' : _typeof(selector)) !== 'object') { - return [[path, operator, selector]]; - } +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; - var keys = Object.keys(selector); - if (keys.length === 0) { - throw new Error('empty selector'); - } else { - return keys.reduce(function (acc, k) { - if (LOGICOPERATORS.indexOf(k) !== -1) { - throw new Error('cozy-client-js does not support mango logic ops'); - } else if (VALUEOPERATORS.indexOf(k) !== -1) { - return acc.concat(parseSelector(selector[k], path, k)); - } else { - return acc.concat(parseSelector(selector[k], path.concat(k), '$eq')); - } - }, []); - } +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } -// normalizeSelector takes a mango selector and returns it as an object -// normalized. -// This function is only exported so it can be unit tested. -// Example : -// parseSelector({"test":{"deep": {"$gt": 3}}}) -// {"test.deep": {"$gt": 3}} -function normalizeSelector(selector) { - var filters = parseSelector(selector); - return filters.reduce(function (acc, filter) { - var _filter = _slicedToArray(filter, 3), - path = _filter[0], - op = _filter[1], - value = _filter[2]; +module.exports = isLength; - var field = path.join('.'); - acc[field] = acc[field] || {}; - acc[field][op] = value; - return acc; - }, {}); + +/***/ }), +/* 452 */ +/***/ ((module) => { + +/** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ +function baseUnary(func) { + return function(value) { + return func(value); + }; } -// applySelector takes the normalized selector for the current field -// and append the proper values to opts.startkey, opts.endkey -function applySelector(selector, opts) { - var value = selector['$eq']; - var lower = COUCHDB_LOWEST; - var upper = COUCHDB_INFINITY; - var inclusiveEnd = void 0; +module.exports = baseUnary; - if (value) { - opts.startkey.push(value); - opts.endkey.push(value); - return false; - } - value = selector['$gt']; - if (value) { - throw new Error('operator $gt (strict greater than) not supported'); - } +/***/ }), +/* 453 */ +/***/ ((module, exports, __webpack_require__) => { - value = selector['$gte']; - if (value) { - lower = value; - } +/* module decorator */ module = __webpack_require__.nmd(module); +var freeGlobal = __webpack_require__(49); - value = selector['$lte']; - if (value) { - upper = value; - inclusiveEnd = true; - } +/** Detect free variable `exports`. */ +var freeExports = true && exports && !exports.nodeType && exports; - value = selector['$lt']; - if (value) { - upper = value; - inclusiveEnd = false; - } +/** Detect free variable `module`. */ +var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; - opts.startkey.push(lower); - opts.endkey.push(upper); - if (inclusiveEnd !== undefined) opts.inclusive_end = inclusiveEnd; - return true; -} +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; -// makeMapReduceQuery takes a mango query and generate _views call parameters -// to obtain same results depending on fields in the passed indexRef. -function makeMapReduceQuery(indexRef, query) { - var mrquery = { - startkey: [], - endkey: [], - reduce: false - }; - var firstFreeValueField = null; - var normalizedSelector = normalizeSelector(query.selector); +/** Detect free variable `process` from Node.js. */ +var freeProcess = moduleExports && freeGlobal.process; - indexRef.fields.forEach(function (field) { - var selector = normalizedSelector[field]; +/** Used to access faster Node.js helpers. */ +var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; - if (selector && firstFreeValueField != null) { - throw new Error('Selector on field ' + field + ', but not on ' + firstFreeValueField + ' which is higher in index fields.'); - } else if (selector) { - selector.used = true; - var isFreeValue = applySelector(selector, mrquery); - if (isFreeValue) firstFreeValueField = field; - } else if (firstFreeValueField == null) { - firstFreeValueField = field; - mrquery.endkey.push(COUCHDB_INFINITY); + if (types) { + return types; } - }); - Object.keys(normalizedSelector).forEach(function (field) { - if (!normalizedSelector[field].used) { - throw new Error('Cant apply selector on ' + field + ', it is not in index'); - } - }); + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} +}()); - if (query.descending) { - mrquery = { - descending: true, - reduce: false, - startkey: mrquery.endkey, - endkey: mrquery.startkey, - inclusive_end: mrquery.inclusive_end - }; - } +module.exports = nodeUtil; - return mrquery; -} /***/ }), -/* 15 */ -/***/ (function(module, exports, __nested_webpack_require_80935__) { +/* 454 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; +var isPrototype = __webpack_require__(455), + nativeKeys = __webpack_require__(456); +/** Used for built-in method references. */ +var objectProto = Object.prototype; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.TRASH_DIR_ID = exports.ROOT_DIR_ID = undefined; +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; -var _regenerator = __nested_webpack_require_80935__(4); +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} -var _regenerator2 = _interopRequireDefault(_regenerator); +module.exports = baseKeys; -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* global Blob, File */ +/***/ }), +/* 455 */ +/***/ ((module) => { +/** Used for built-in method references. */ +var objectProto = Object.prototype; -var doUpload = function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, data, method, path, options) { - var isBuffer, isFile, isBlob, isStream, isString, _ref2, contentType, contentLength, checksum, createdAt, updatedAt, executable, lastModifiedDate, ifMatch, metadata, sourceAccount, sourceAccountIdentifier, signal, finalpath, metadataId, headers; +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - return _regenerator2.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - if (data) { - _context.next = 2; - break; - } + return value === proto; +} - throw new Error('missing data argument'); +module.exports = isPrototype; - case 2: - // transform any ArrayBufferView to ArrayBuffer - if (data.buffer && data.buffer instanceof ArrayBuffer) { - data = data.buffer; - } +/***/ }), +/* 456 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - isBuffer = typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer; - isFile = typeof File !== 'undefined' && data instanceof File; - isBlob = typeof Blob !== 'undefined' && data instanceof Blob; - isStream = data.readable === true && typeof data.pipe === 'function'; - isString = typeof data === 'string'; +var overArg = __webpack_require__(457); - if (!(!isBuffer && !isFile && !isBlob && !isStream && !isString)) { - _context.next = 10; - break; - } +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = overArg(Object.keys, Object); - throw new Error('invalid data type'); +module.exports = nativeKeys; - case 10: - _ref2 = options || {}, contentType = _ref2.contentType, contentLength = _ref2.contentLength, checksum = _ref2.checksum, createdAt = _ref2.createdAt, updatedAt = _ref2.updatedAt, executable = _ref2.executable, lastModifiedDate = _ref2.lastModifiedDate, ifMatch = _ref2.ifMatch, metadata = _ref2.metadata, sourceAccount = _ref2.sourceAccount, sourceAccountIdentifier = _ref2.sourceAccountIdentifier, signal = _ref2.signal; - if (!contentType) { - if (isBuffer) { - contentType = contentTypeOctetStream; - } else if (isFile) { - contentType = data.type || getFileTypeFromName(data.name.toLowerCase()) || contentTypeOctetStream; - if (!lastModifiedDate) { - lastModifiedDate = data.lastModifiedDate; - } - } else if (isBlob) { - contentType = data.type || contentTypeOctetStream; - } else if (isStream) { - contentType = contentTypeOctetStream; - } else if (typeof data === 'string') { - contentType = 'text/plain'; - } - } +/***/ }), +/* 457 */ +/***/ ((module) => { - if (lastModifiedDate && typeof lastModifiedDate === 'string') { - lastModifiedDate = new Date(lastModifiedDate); - } - if (!createdAt) { - createdAt = lastModifiedDate; - } - if (!updatedAt) { - updatedAt = lastModifiedDate; - } +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} - if (!executable) { - executable = false; - } +module.exports = overArg; - finalpath = path; - if (!metadata) { - _context.next = 22; - break; - } +/***/ }), +/* 458 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - _context.next = 20; - return sendMetadata(cozy, metadata); +var isFunction = __webpack_require__(45), + isLength = __webpack_require__(451); - case 20: - metadataId = _context.sent; +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} - if (metadataId) { - finalpath = addQuerystringParam(finalpath, 'MetadataID', metadataId); - } +module.exports = isArrayLike; - case 22: - if (sourceAccount) { - finalpath = addQuerystringParam(finalpath, 'SourceAccount', sourceAccount); - } - if (sourceAccountIdentifier) { - finalpath = addQuerystringParam(finalpath, 'SourceAccountIdentifier', sourceAccountIdentifier); - } - if (createdAt) { - finalpath = addQuerystringParam(finalpath, 'CreatedAt', dateString(createdAt)); - } - if (updatedAt) { - finalpath = addQuerystringParam(finalpath, 'UpdatedAt', dateString(updatedAt)); - } - if (executable) { - finalpath = addQuerystringParam(finalpath, 'Executable', executable); - } - headers = { - 'Content-Type': contentType - }; +/***/ }), +/* 459 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (contentLength) { - headers['Content-Length'] = String(contentLength); - finalpath = addQuerystringParam(finalpath, 'Size', String(contentLength)); - } - if (checksum) headers['Content-MD5'] = checksum; - if (lastModifiedDate) headers['Date'] = lastModifiedDate.toGMTString(); - if (ifMatch) headers['If-Match'] = ifMatch; +var DataView = __webpack_require__(460), + Map = __webpack_require__(401), + Promise = __webpack_require__(461), + Set = __webpack_require__(462), + WeakMap = __webpack_require__(463), + baseGetTag = __webpack_require__(46), + toSource = __webpack_require__(387); - return _context.abrupt('return', (0, _fetch.cozyFetch)(cozy, finalpath, { - method: method, - headers: headers, - body: data, - signal: signal - }).then(function (res) { - var json = res.json(); - if (!res.ok) { - return json.then(function (err) { - throw err; - }); - } else { - return json.then(_jsonapi2.default); - } - })); +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + setTag = '[object Set]', + weakMapTag = '[object WeakMap]'; - case 33: - case 'end': - return _context.stop(); - } - } - }, _callee, this); - })); +var dataViewTag = '[object DataView]'; - return function doUpload(_x, _x2, _x3, _x4, _x5) { - return _ref.apply(this, arguments); - }; -}(); +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); -var sendMetadata = function () { - var _ref3 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(cozy, metadata) { - var result; - return _regenerator2.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _context2.next = 2; - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/upload/metadata', { - data: { type: 'io.cozy.files.metadata', attributes: metadata } - }); +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +var getTag = baseGetTag; - case 2: - result = _context2.sent; - return _context2.abrupt('return', result && result._id ? result._id : false); +// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. +if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; - case 4: - case 'end': - return _context2.stop(); - } + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; } - }, _callee2, this); - })); - - return function sendMetadata(_x6, _x7) { - return _ref3.apply(this, arguments); + } + return result; }; -}(); +} -exports.create = create; -exports.createDirectory = createDirectory; -exports.createDirectoryByPath = createDirectoryByPath; -exports.updateById = updateById; -exports.updateAttributesById = updateAttributesById; -exports.updateAttributesByPath = updateAttributesByPath; -exports.trashById = trashById; -exports.statById = statById; -exports.statByPath = statByPath; -exports.downloadById = downloadById; -exports.downloadByPath = downloadByPath; -exports.getDownloadLinkByPath = getDownloadLinkByPath; -exports.getDownloadLinkById = getDownloadLinkById; -exports.getFilePath = getFilePath; -exports.getCollectionShareLink = getCollectionShareLink; -exports.getArchiveLinkByPaths = getArchiveLinkByPaths; -exports.getArchiveLinkByIds = getArchiveLinkByIds; -exports.listTrash = listTrash; -exports.clearTrash = clearTrash; -exports.restoreById = restoreById; -exports.destroyById = destroyById; +module.exports = getTag; -var _fetch = __nested_webpack_require_80935__(0); -var _jsonapi = __nested_webpack_require_80935__(7); +/***/ }), +/* 460 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _jsonapi2 = _interopRequireDefault(_jsonapi); +var getNative = __webpack_require__(383), + root = __webpack_require__(48); -var _doctypes = __nested_webpack_require_80935__(2); +/* Built-in method references that are verified to be native. */ +var DataView = getNative(root, 'DataView'); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +module.exports = DataView; -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } -// global variables -var ROOT_DIR_ID = exports.ROOT_DIR_ID = 'io.cozy.files.root-dir'; -var TRASH_DIR_ID = exports.TRASH_DIR_ID = 'io.cozy.files.trash-dir'; +/***/ }), +/* 461 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var contentTypeOctetStream = 'application/octet-stream'; +var getNative = __webpack_require__(383), + root = __webpack_require__(48); -function sanitizeFileName(name) { - return name && name.trim(); -} +/* Built-in method references that are verified to be native. */ +var Promise = getNative(root, 'Promise'); -function getFileTypeFromName(name) { - if (/\.heic$/i.test(name)) return 'image/heic';else if (/\.heif$/i.test(name)) return 'image/heif';else return null; -} +module.exports = Promise; -function dateString(date) { - return (typeof date === 'undefined' ? 'undefined' : _typeof(date)) === 'object' ? date.toISOString() : date; -} -function create(cozy, data, options) { - var _ref4 = options || {}, - name = _ref4.name, - dirID = _ref4.dirID, - noSanitize = _ref4.noSanitize; +/***/ }), +/* 462 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // handle case where data is a file and contains the name +var getNative = __webpack_require__(383), + root = __webpack_require__(48); +/* Built-in method references that are verified to be native. */ +var Set = getNative(root, 'Set'); - if (!name && typeof data.name === 'string') { - name = data.name; - } +module.exports = Set; - if (!noSanitize) { - name = sanitizeFileName(name); - } - if (typeof name !== 'string' || name === '') { - throw new Error('missing name argument'); - } +/***/ }), +/* 463 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var path = '/files/' + encodeURIComponent(dirID || ''); - var query = '?Name=' + encodeURIComponent(name) + '&Type=file'; - return doUpload(cozy, data, 'POST', '' + path + query, options); -} +var getNative = __webpack_require__(383), + root = __webpack_require__(48); -function createDirectory(cozy, options) { - var _ref5 = options || {}, - name = _ref5.name, - dirID = _ref5.dirID, - createdAt = _ref5.createdAt, - updatedAt = _ref5.updatedAt, - lastModifiedDate = _ref5.lastModifiedDate, - noSanitize = _ref5.noSanitize; +/* Built-in method references that are verified to be native. */ +var WeakMap = getNative(root, 'WeakMap'); - if (!noSanitize) { - name = sanitizeFileName(name); - } +module.exports = WeakMap; - if (typeof name !== 'string' || name === '') { - throw new Error('missing name argument'); - } - if (lastModifiedDate && typeof lastModifiedDate === 'string') { - lastModifiedDate = new Date(lastModifiedDate); - } - if (!createdAt) { - createdAt = lastModifiedDate; - } - if (!updatedAt) { - updatedAt = lastModifiedDate; - } +/***/ }), +/* 464 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var path = '/files/' + encodeURIComponent(dirID || ''); - var query = '?Name=' + encodeURIComponent(name) + '&Type=directory'; +var isStrictComparable = __webpack_require__(465), + keys = __webpack_require__(441); - var finalpath = '' + path + query; - if (createdAt) { - finalpath = addQuerystringParam(finalpath, 'CreatedAt', dateString(createdAt)); - } - if (updatedAt) { - finalpath = addQuerystringParam(finalpath, 'UpdatedAt', dateString(updatedAt)); - } +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = keys(object), + length = result.length; - var headers = {}; - if (lastModifiedDate) headers['Date'] = lastModifiedDate.toGMTString(); + while (length--) { + var key = result[length], + value = object[key]; - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', finalpath, undefined, { - headers: headers - }); + result[length] = [key, value, isStrictComparable(value)]; + } + return result; } -function getDirectoryOrCreate(cozy, name, parentDirectory, options) { - if (parentDirectory && !parentDirectory.attributes) throw new Error('Malformed parent directory'); - - var _ref6 = options || {}, - noSanitize = _ref6.noSanitize; +module.exports = getMatchData; - if (!noSanitize) { - name = sanitizeFileName(name); - } - var path = (parentDirectory._id === ROOT_DIR_ID ? '' : parentDirectory.attributes.path) + '/' + name; +/***/ }), +/* 465 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return cozy.files.statByPath(path || '/').catch(function (error) { - var parsedError = JSON.parse(error.message); - var errors = parsedError.errors; - if (errors && errors.length && errors[0].status === '404') { - return cozy.files.createDirectory({ - name: name, - dirID: parentDirectory && parentDirectory._id - }); - } +var isObject = __webpack_require__(52); - throw errors; - }); +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !isObject(value); } -function createDirectoryByPath(cozy, path, offline, options) { - var parts = path.split('/').filter(function (part) { - return part !== ''; - }); +module.exports = isStrictComparable; - var rootDirectoryPromise = cozy.files.statById(ROOT_DIR_ID, offline); - return parts.length ? parts.reduce(function (parentDirectoryPromise, part) { - return parentDirectoryPromise.then(function (parentDirectory) { - return getDirectoryOrCreate(cozy, part, parentDirectory, options); - }); - }, rootDirectoryPromise) : rootDirectoryPromise; -} +/***/ }), +/* 466 */ +/***/ ((module) => { -function updateById(cozy, id, data, options) { - return doUpload(cozy, data, 'PUT', '/files/' + encodeURIComponent(id), options); +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; } -function doUpdateAttributes(cozy, attrs, path, options) { - if (!attrs || (typeof attrs === 'undefined' ? 'undefined' : _typeof(attrs)) !== 'object') { - throw new Error('missing attrs argument'); - } +module.exports = matchesStrictComparable; - var _ref7 = options || {}, - ifMatch = _ref7.ifMatch, - noSanitize = _ref7.noSanitize; - var name = attrs.name; - if (!noSanitize) { - name = sanitizeFileName(name); - } +/***/ }), +/* 467 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var body = { - data: { - attributes: Object.assign({}, attrs, { - name: name - }) - } +var baseIsEqual = __webpack_require__(422), + get = __webpack_require__(370), + hasIn = __webpack_require__(468), + isKey = __webpack_require__(373), + isStrictComparable = __webpack_require__(465), + matchesStrictComparable = __webpack_require__(466), + toKey = __webpack_require__(411); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); }; - return (0, _fetch.cozyFetchJSON)(cozy, 'PATCH', path, body, { - headers: { - 'If-Match': ifMatch || '' - } - }); } -function updateAttributesById(cozy, id, attrs, options) { - return doUpdateAttributes(cozy, attrs, '/files/' + encodeURIComponent(id), options); -} +module.exports = baseMatchesProperty; -function updateAttributesByPath(cozy, path, attrs, options) { - return doUpdateAttributes(cozy, attrs, '/files/metadata?Path=' + encodeURIComponent(path), options); -} -function trashById(cozy, id, options) { - if (typeof id !== 'string' || id === '') { - throw new Error('missing id argument'); - } +/***/ }), +/* 468 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var _ref8 = options || {}, - ifMatch = _ref8.ifMatch; +var baseHasIn = __webpack_require__(469), + hasPath = __webpack_require__(470); - return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/' + encodeURIComponent(id), undefined, { - headers: { - 'If-Match': ifMatch || '' - } - }); +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); } -function statById(cozy, id) { - var offline = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; - var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; +module.exports = hasIn; - if (offline && cozy.offline.hasDatabase(_doctypes.DOCTYPE_FILES)) { - var db = cozy.offline.getDatabase(_doctypes.DOCTYPE_FILES); - return Promise.all([db.get(id), db.find(Object.assign({ selector: { dir_id: id } }, options))]).then(function (_ref9) { - var _ref10 = _slicedToArray(_ref9, 2), - doc = _ref10[0], - children = _ref10[1]; - if (id === ROOT_DIR_ID) { - children.docs = children.docs.filter(function (doc) { - return doc._id !== TRASH_DIR_ID; - }); - } - children = sortFiles(children.docs.map(function (doc) { - return addIsDir(toJsonApi(cozy, doc)); - })); - return addIsDir(toJsonApi(cozy, doc, children)); - }); - } - var query = Object.keys(options).length === 0 ? '' : '?' + encodePageOptions(options); - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/' + encodeURIComponent(id) + query).then(addIsDir); -} +/***/ }), +/* 469 */ +/***/ ((module) => { -function statByPath(cozy, path) { - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/metadata?Path=' + encodeURIComponent(path)).then(addIsDir); +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); } -function downloadById(cozy, id) { - return (0, _fetch.cozyFetch)(cozy, '/files/download/' + encodeURIComponent(id)); -} +module.exports = baseHasIn; -function downloadByPath(cozy, path) { - return (0, _fetch.cozyFetch)(cozy, '/files/download?Path=' + encodeURIComponent(path)); -} -function extractResponseLinkRelated(res) { - var href = res.links && res.links.related; - if (!href) throw new Error('No related link in server response'); - return href; -} +/***/ }), +/* 470 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function getDownloadLinkByPath(cozy, path) { - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/downloads?Path=' + encodeURIComponent(path)).then(extractResponseLinkRelated); -} +var castPath = __webpack_require__(372), + isArguments = __webpack_require__(444), + isArray = __webpack_require__(55), + isIndex = __webpack_require__(448), + isLength = __webpack_require__(451), + toKey = __webpack_require__(411); -function getDownloadLinkById(cozy, id) { - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/downloads?Id=' + encodeURIComponent(id)).then(extractResponseLinkRelated); -} +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = castPath(path, object); -function getFilePath(cozy) { - var file = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var folder = arguments[2]; + var index = -1, + length = path.length, + result = false; - if (!folder || !folder.attributes) { - throw Error('Folder should be valid with an attributes.path property'); + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); +} - var folderPath = folder.attributes.path.endsWith('/') ? folder.attributes.path : folder.attributes.path + '/'; +module.exports = hasPath; - return '' + folderPath + file.name; + +/***/ }), +/* 471 */ +/***/ ((module) => { + +/** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ +function identity(value) { + return value; } -function getCollectionShareLink(cozy, id, collectionType) { - if (!id) { - return Promise.reject(Error('An id should be provided to create a share link')); - } - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/permissions?codes=email', { - data: { - type: 'io.cozy.permissions', - attributes: { - permissions: { - files: { - type: 'io.cozy.files', - verbs: ['GET'], - values: [id], - selector: 'referenced_by' - }, - collection: { - type: collectionType, - verbs: ['GET'], - values: [id] - } - } - } - } - }).then(function (data) { - return { - sharecode: 'sharecode=' + data.attributes.codes.email, - id: 'id=' + id - }; - }); +module.exports = identity; + + +/***/ }), +/* 472 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseProperty = __webpack_require__(473), + basePropertyDeep = __webpack_require__(474), + isKey = __webpack_require__(373), + toKey = __webpack_require__(411); + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); } -function getArchiveLinkByPaths(cozy, paths) { - var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'files'; +module.exports = property; - var archive = { - type: 'io.cozy.archives', - attributes: { - name: name, - files: paths - } + +/***/ }), +/* 473 */ +/***/ ((module) => { + +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; }; - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/archive', { data: archive }).then(extractResponseLinkRelated); } -function getArchiveLinkByIds(cozy, ids) { - var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'files'; +module.exports = baseProperty; - var archive = { - type: 'io.cozy.archives', - attributes: { - name: name, - ids: ids - } + +/***/ }), +/* 474 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseGet = __webpack_require__(371); + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); }; - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/archive', { data: archive }).then(extractResponseLinkRelated); } -function listTrash(cozy) { - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/trash'); -} +module.exports = basePropertyDeep; -function clearTrash(cozy) { - return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/trash'); -} -function restoreById(cozy, id) { - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/trash/' + encodeURIComponent(id)); -} +/***/ }), +/* 475 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function destroyById(cozy, id, options) { - var _ref11 = options || {}, - ifMatch = _ref11.ifMatch; +var SetCache = __webpack_require__(425), + arrayIncludes = __webpack_require__(476), + arrayIncludesWith = __webpack_require__(481), + cacheHas = __webpack_require__(429), + createSet = __webpack_require__(482), + setToArray = __webpack_require__(433); - return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/trash/' + encodeURIComponent(id), undefined, { - headers: { - 'If-Match': ifMatch || '' - } - }); -} +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; -function addIsDir(obj) { - obj.isDir = obj.attributes.type === 'directory'; - return obj; -} +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; -function encodePageOptions(options) { - var opts = []; - for (var name in options) { - opts.push('page[' + encodeURIComponent(name) + ']=' + encodeURIComponent(options[name])); + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; } - return opts.join('&'); -} - -function toJsonApi(cozy, doc) { - var contents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; - var clone = JSON.parse(JSON.stringify(doc)); - delete clone._id; - delete clone._rev; - return { - _id: doc._id, - _rev: doc._rev, - _type: _doctypes.DOCTYPE_FILES, - attributes: clone, - relationships: { - contents: { - data: contents, - meta: { - count: contents.length + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; } } - }, - relations: function relations(name) { - if (name === 'contents') { - return contents; + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); } + result.push(value); } - }; + } + return result; } -function sortFiles(allFiles) { - var folders = allFiles.filter(function (f) { - return f.attributes.type === 'directory'; - }); - var files = allFiles.filter(function (f) { - return f.attributes.type !== 'directory'; - }); - var sort = function sort(files) { - return files.sort(function (a, b) { - return a.attributes.name.localeCompare(b.attributes.name); - }); - }; - return sort(folders).concat(sort(files)); -} +module.exports = baseUniq; -function addQuerystringParam(path, key, value) { - return '' + path + (path.includes('?') ? '&' : '?') + key + '=' + value; -} /***/ }), -/* 16 */ -/***/ (function(module, exports, __nested_webpack_require_101343__) { - -"use strict"; +/* 476 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var baseIndexOf = __webpack_require__(477); -Object.defineProperty(exports, "__esModule", { - value: true -}); +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && baseIndexOf(array, value, 0) > -1; +} -var _regenerator = __nested_webpack_require_101343__(4); +module.exports = arrayIncludes; -var _regenerator2 = _interopRequireDefault(_regenerator); -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; +/***/ }), +/* 477 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -exports.start = start; +var baseFindIndex = __webpack_require__(478), + baseIsNaN = __webpack_require__(479), + strictIndexOf = __webpack_require__(480); -var _helpers = __nested_webpack_require_101343__(5); +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); +} -var _ = __nested_webpack_require_101343__(8); +module.exports = baseIndexOf; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } +/***/ }), +/* 478 */ +/***/ ((module) => { -var intentClass = 'coz-intent'; +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); -function hideIntentIframe(iframe) { - iframe.style.display = 'none'; + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; } -function showIntentFrame(iframe) { - iframe.style.display = 'block'; -} +module.exports = baseFindIndex; -function buildIntentIframe(intent, element, url) { - var document = element.ownerDocument; - if (!document) return Promise.reject(new Error('Cannot retrieve document object from given element')); - var iframe = document.createElement('iframe'); - // TODO: implement 'title' attribute - iframe.setAttribute('id', 'intent-' + intent._id); - iframe.setAttribute('src', url); - iframe.classList.add(intentClass); - return iframe; +/***/ }), +/* 479 */ +/***/ ((module) => { + +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; } -function injectIntentIframe(intent, element, url, options) { - var onReadyCallback = options.onReadyCallback; +module.exports = baseIsNaN; - var iframe = buildIntentIframe(intent, element, url, options.onReadyCallback); - // if callback provided for when iframe is loaded - if (typeof onReadyCallback === 'function') iframe.onload = onReadyCallback; - element.appendChild(iframe); - iframe.focus(); - return iframe; -} -// inject iframe for service in given element -function connectIntentIframe(cozy, iframe, element, intent, data) { - var _this = this; +/***/ }), +/* 480 */ +/***/ ((module) => { - var compose = function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, action, doctype, data) { - var intent, doc; - return _regenerator2.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return (0, _.create)(cozy, action, doctype, data); +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; - case 2: - intent = _context.sent; + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} - hideIntentIframe(iframe); - _context.next = 6; - return start(cozy, intent, element, _extends({}, data, { - exposeIntentFrameRemoval: false - })); +module.exports = strictIndexOf; - case 6: - doc = _context.sent; - showIntentFrame(iframe); - return _context.abrupt('return', doc); +/***/ }), +/* 481 */ +/***/ ((module) => { - case 9: - case 'end': - return _context.stop(); - } - } - }, _callee, this); - })); +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; - return function compose(_x, _x2, _x3, _x4) { - return _ref.apply(this, arguments); - }; - }(); + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} - var document = element.ownerDocument; - if (!document) return Promise.reject(new Error('Cannot retrieve document object from given element')); +module.exports = arrayIncludesWith; - var window = document.defaultView; - if (!window) return Promise.reject(new Error('Cannot retrieve window object from document')); - // Keeps only http://domain:port/ - var serviceOrigin = iframe.src.split('/', 3).join('/'); +/***/ }), +/* 482 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return new Promise(function (resolve, reject) { - var handshaken = false; - var messageHandler = function () { - var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(event) { - var eventType, _event$data, action, doctype, _data, doc, removeIntentFrame; +var Set = __webpack_require__(462), + noop = __webpack_require__(483), + setToArray = __webpack_require__(433); - return _regenerator2.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - if (!(event.origin !== serviceOrigin)) { - _context2.next = 2; - break; - } +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; - return _context2.abrupt('return'); +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { + return new Set(values); +}; - case 2: - eventType = event.data.type; +module.exports = createSet; - if (!(eventType === 'load')) { - _context2.next = 6; - break; - } - // Safari 9.1 (At least) send a MessageEvent when the iframe loads, - // making the handshake fails. - console.warn && console.warn('Cozy Client ignored MessageEvent having data.type `load`.'); - return _context2.abrupt('return'); +/***/ }), +/* 483 */ +/***/ ((module) => { - case 6: - if (!(eventType === 'intent-' + intent._id + ':ready')) { - _context2.next = 9; - break; - } +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} - handshaken = true; - return _context2.abrupt('return', event.source.postMessage(data, event.origin)); +module.exports = noop; - case 9: - if (!(handshaken && eventType === 'intent-' + intent._id + ':resize')) { - _context2.next = 13; - break; - } - ;['width', 'height', 'maxWidth', 'maxHeight'].forEach(function (prop) { - if (event.data.transition) element.style.transition = event.data.transition; - if (event.data.dimensions[prop]) element.style[prop] = event.data.dimensions[prop] + 'px'; - }); +/***/ }), +/* 484 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return _context2.abrupt('return', true); +/** + * Small utilities helping to develop konnectors. + * + * @module utils + */ +const cozyClient = __webpack_require__(485); - case 13: - if (!(handshaken && eventType === 'intent-' + intent._id + ':compose')) { - _context2.next = 19; - break; - } +const groupBy = __webpack_require__(736); - // Let start to name `type` as `doctype`, as `event.data` already have a `type` attribute. - _event$data = event.data, action = _event$data.action, doctype = _event$data.doctype, _data = _event$data.data; - _context2.next = 17; - return compose(cozy, action, doctype, _data); +const keyBy = __webpack_require__(711); - case 17: - doc = _context2.sent; - return _context2.abrupt('return', event.source.postMessage(doc, event.origin)); +const sortBy = __webpack_require__(838); - case 19: +const range = __webpack_require__(959); - window.removeEventListener('message', messageHandler); +const { + format +} = __webpack_require__(962); +/** + * This function allows to fetch all documents for a given doctype. It is the fastest to get all + * documents but without filtering possibilities + * deprecated by the findAll method from cozyClient + * + * Parameters: + * + * `doctype` (string): the doctype from which you want to fetch the data + * + */ - removeIntentFrame = function removeIntentFrame() { - // check if the parent node has not been already removed from the DOM - iframe.parentNode && iframe.parentNode.removeChild(iframe); - }; - if (!(handshaken && eventType === 'intent-' + intent._id + ':exposeFrameRemoval')) { - _context2.next = 23; - break; - } +const fetchAll = async doctype => { + return cozyClient.data.findAll(doctype); +}; +/** + * This function allows to fetch all documents for a given doctype exceeding the 100 limit. + * It is slower that fetchAll because it fetches the data 100 by 100 but allows to filter the data + * with a selector and an index + * + * Parameters: + * + * `doctype` (string): the doctype from which you want to fetch the data + * `selector` (object): the mango query selector + * `index` (object): (optional) the query selector index. If not defined, the function will + * create it's own index with the keys specified in the selector + * + * + * ```javascript + * const documents = await queryAll('io.cozy.bills', {vendor: 'Direct Energie'}) + * ``` + */ - return _context2.abrupt('return', resolve({ removeIntentFrame: removeIntentFrame, doc: event.data.document })); - case 23: +const queryAll = async (doctype, selector, index) => { + if (!selector) { + // fetchAll is faster in this case + return await cozyClient.data.findAll(doctype); + } - removeIntentFrame(); + if (!index) { + index = await cozyClient.data.defineIndex(doctype, Object.keys(selector)); + } - if (!(eventType === 'intent-' + intent._id + ':error')) { - _context2.next = 26; - break; - } + const result = []; + let resp = { + next: true + }; - return _context2.abrupt('return', reject(_helpers.errorSerializer.deserialize(event.data.error))); + while (resp && resp.next) { + resp = await cozyClient.data.query(index, { + selector, + wholeResponse: true, + skip: result.length + }); + result.push(...resp.docs); + } - case 26: - if (!(handshaken && eventType === 'intent-' + intent._id + ':cancel')) { - _context2.next = 28; - break; - } + return result; +}; +/** + * This function find duplicates in a given doctype, filtered by an optional mango selector + * + * Parameters: + * + * `doctype` (string): the doctype from which you want to fetch the data + * `selector` (object): (optional) the mango query selector + * `options` : + * - `keys` (array) : List of keys used to check that two items are the same. + * - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype. + * - `selector` (optionnal object) : Mango request to get records. Gets all the records by default + * + * Returns an object with the following keys: + * `toKeep`: this is the list of unique documents that you should keep in db + * `toRemove`: this is the list of documents that can remove from db. If this is io.cozy.bills + * documents, do not forget to clean linked bank operations + * + * ```javascript + * const {toKeep, toRemove} = await findDuplicates('io.cozy.bills', {selector: {vendor: 'Direct Energie'}}) + * ``` + */ - return _context2.abrupt('return', resolve(null)); - case 28: - if (!(handshaken && eventType === 'intent-' + intent._id + ':done')) { - _context2.next = 30; - break; - } +const findDuplicates = async (doctype, options) => { + let hash = null; - return _context2.abrupt('return', resolve(event.data.document)); + if (options.keys) { + hash = doc => options.keys.map(key => { + let result = doc[key]; + if (key === 'date') result = new Date(result); + return result; + }).join(','); + } else if (options.hash) { + hash = options.hash; + } else { + throw new Error('findDuplicates: you must specify keys or hash option'); + } - case 30: - if (handshaken) { - _context2.next = 32; - break; - } + let documents = await queryAll(doctype, options.selector); - return _context2.abrupt('return', reject(new Error('Unexpected handshake message from intent service'))); + if (doctype === 'io.cozy.bills') { + // keep the bills with the highest number of operations linked to it + const operations = await fetchAll('io.cozy.bank.operations'); + documents = sortBillsByLinkedOperationNumber(documents, operations); + } - case 32: - case 'end': - return _context2.stop(); - } - } - }, _callee2, _this); - })); + const groups = groupBy(documents, hash); + const toKeep = []; + const toRemove = []; - return function messageHandler(_x5) { - return _ref2.apply(this, arguments); - }; - }(); + for (let key in groups) { + const group = groups[key]; + toKeep.push(group[0]); + toRemove.push.apply(toRemove, group.slice(1).map(doc => ({ ...doc, + original: group[0]._id + }))); + } - window.addEventListener('message', messageHandler); + return { + toKeep, + toRemove + }; +}; + +const sortBillsByLinkedOperationNumber = (bills, operations) => { + bills = bills.map(bill => { + bill.opNb = 0; + return bill; }); -} + const billsIndex = keyBy(bills, '_id'); + if (operations) operations.forEach(op => { + if (op.bills) op.bills.forEach(billId => { + const bill = billsIndex[billId]; + if (bill) bill.opNb++; + }); + }); + const sorted = sortBy(Object.values(billsIndex), 'opNb').reverse(); + return sorted; +}; +/** + * This is a shortcut to update multiple documents in one call + * + * Parameters: + * + * `doctype` (string): the doctype from which you want to fetch the data + * `ids` (array): array of ids of documents to update + * `transformation` (object): attributes to change with their values + * `options` : + * - `keys` (array) : List of keys used to check that two items are the same. + * - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype. + * - `selector` (optionnal object) : Mango request to get records. Gets all the records by default + * + * Returns a promise which resolves with all the return values of updateAttributes + * + * ```javascript + * await batchUpdateAttributes('io.cozy.bills', [1, 2, 3], {vendor: 'Direct Energie'}) + * ``` + */ -function start(cozy, intent, element) { - var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; - var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; - var service = (0, _helpers.pickService)(intent, options.filterServices); +const batchUpdateAttributes = async (doctype, ids, transformation) => { + const result = []; - if (!service) { - throw new Error('Unable to find a service'); + for (const id of ids) { + const updateResult = await cozyClient.data.updateAttributes(doctype, id, transformation); + result.push(updateResult); } - var iframe = injectIntentIframe(intent, element, service.href, options); - - return connectIntentIframe(cozy, iframe, element, intent, data, options.onReadyCallback); -} - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __nested_webpack_require_110507__) { + return result; +}; +/** + * This is a shortcut to delete multiple documents in one call + * + * Parameters: + * + * `doctype` (string): the doctype from which you want to fetch the data + * `documents` (array): documents to delete with their ids + * `transformation` (object): attributes to change with their values + * `options` : + * - `keys` (array) : List of keys used to check that two items are the same. + * - `index` (optionnal) : Return value returned by `cozy.data.defineIndex`, the default will correspond to all documents of the selected doctype. + * - `selector` (optionnal object) : Mango request to get records. Gets all the records by default + * + * Returns a promise which resolves with all the return values of updateAttributes + * + * Example to remove all the documents for a given doctype + * + * ```javascript + * const documents = await fetchAll('io.cozy.marvel') + * await batchDelete('io.cozy.marvel', documents) + * ``` + */ -"use strict"; +const batchDelete = async (doctype, documents) => { + const result = []; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.start = start; + for (const doc of documents) { + const deleteResult = await cozyClient.data.delete(doctype, doc); + result.push(deleteResult); + } -var _fetch = __nested_webpack_require_110507__(0); + return result; +}; +/** + * This function can read the content of a cozy pdf file and output its text + * + * Parameters: + * + * `fileId` (string): the id of the file in the cozy + * `options` : + * - `pages` (array or number) : The list of page you want to interpret + * + * + * You need to add pdfjs-dist package as a dependency to your connector to allow this to work + * + * Returns a promise which resolves with an object with the following attributes: + * - `text` (string) : The full text of the pdf + * - `1` : The full pdfjs data for page 1 + * - `n` : The full pdfjs data for page n + * + * Example: + * + * ```javascript + * const pdfText = (await getPdfText('887ABCFE87687')).text + * ``` + */ -var _helpers = __nested_webpack_require_110507__(5); -function listenClientData(intent, window) { - return new Promise(function (resolve) { - var messageEventListener = function messageEventListener(event) { - if (event.origin !== intent.attributes.client) return; +const getPdfText = async (fileId, options = {}) => { + let pdfjs; - window.removeEventListener('message', messageEventListener); - resolve(event.data); - }; + try { + pdfjs = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'pdfjs-dist/legacy/build/pdf'"); e.code = 'MODULE_NOT_FOUND'; throw e; }())); + } catch (err) { + throw new Error('pdfjs-dist dependency is missing. Please add it in your package.json'); + } - window.addEventListener('message', messageEventListener); - window.parent.postMessage({ - type: 'intent-' + intent._id + ':ready' - }, intent.attributes.client); - }); -} + const response = await cozyClient.files.downloadById(fileId); + const buffer = await response.buffer(); + const document = await pdfjs.getDocument(buffer).promise; + let pages; -// maximize the height of an element -function maximize(element) { - if (element && element.style) { - element.style.height = '100%'; + if (options.pages) { + pages = Array.isArray(options.pages) ? options.pages : [options.pages]; + } else { + pages = range(1, document.numPages + 1); } -} -function start(cozy, intentId, serviceWindow) { - serviceWindow = serviceWindow || typeof window !== 'undefined' && window; - if (!serviceWindow || !serviceWindow.document) { - return Promise.reject(new Error('Intent service should be used in browser')); + const result = { + text: '' + }; + + for (const pageNum of pages) { + const page = await document.getPage(pageNum); + const pageItems = (await page.getTextContent()).items; + result.text += pageItems.map(doc => doc.str).join('\n'); + result[pageNum] = pageItems; } - // Maximize document, the whole iframe is handled by intents, clients and - // services - serviceWindow.addEventListener('load', function () { - var _serviceWindow = serviceWindow, - document = _serviceWindow.document; - [document.documentElement, document.body].forEach(maximize); - }); + return result; +}; - intentId = intentId || serviceWindow.location.search.split('=')[1]; - if (!intentId) return Promise.reject(new Error('Cannot retrieve intent from URL')); +module.exports = { + fetchAll, + queryAll, + findDuplicates, + sortBillsByLinkedOperationNumber, + batchUpdateAttributes, + batchDelete, + getPdfText, + formatDate +}; +/** + * This function convert a Date Object to a ISO date string (2018-07-31) + * + * Parameters: + * + * `date` (Date): the id of the file in the cozy + * + * Returns a string + * + * Example: + * + * ```javascript + * const date = formatFrenchDate(New Date.now()) + * ``` + */ - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/intents/' + intentId).then(function (intent) { - var terminated = false; +function formatDate(date) { + return format(new Date(date), 'yyyy-MM-dd'); +} - var sendMessage = function sendMessage(message) { - if (terminated) throw new Error('Intent service has already been terminated'); - serviceWindow.parent.postMessage(message, intent.attributes.client); - }; +/***/ }), +/* 485 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var compose = function compose(action, doctype, data) { - return new Promise(function (resolve) { - var composeEventListener = function composeEventListener(event) { - if (event.origin !== intent.attributes.client) return; - serviceWindow.removeEventListener('message', composeEventListener); - return resolve(event.data); - }; +/** + * [cozy-client-js](https://github.com/cozy/cozy-client-js) instance already + * initialized and ready to use. + * + * @module cozyClient + */ - serviceWindow.addEventListener('message', composeEventListener); +/* eslint no-console: off */ +const { + Client, + MemoryStorage +} = __webpack_require__(486); - sendMessage({ - type: 'intent-' + intent._id + ':compose', - action: action, - doctype: doctype, - data: data - }); - }); - }; +const NewCozyClient = (__webpack_require__(521)["default"]); - var _terminate = function _terminate(message) { - sendMessage(message); - terminated = true; - }; +const { + models +} = __webpack_require__(521); - var resizeClient = function resizeClient(dimensions, transitionProperty) { - if (terminated) throw new Error('Intent service has been terminated'); +const globalFetch = (__webpack_require__(493)["default"]); - sendMessage({ - type: 'intent-' + intent._id + ':resize', - // if a dom element is passed, calculate its size - dimensions: dimensions.element ? Object.assign({}, dimensions, { - maxHeight: dimensions.element.clientHeight, - maxWidth: dimensions.element.clientWidth - }) : dimensions, - transition: transitionProperty - }); - }; +global.fetch = globalFetch; +global.Headers = globalFetch.Headers; // fixes an import problem of isomorphic fetch in cozy-client and cozy-client-js - var cancel = function cancel() { - _terminate({ type: 'intent-' + intent._id + ':cancel' }); - }; +const manifest = __webpack_require__(909); - // Prevent unfulfilled client promises when this window unloads for a - // reason or another. - serviceWindow.addEventListener('unload', function () { - if (!terminated) cancel(); - }); +const getCozyClient = function (environment = 'production') { + if (environment === 'standalone' || environment === 'test') { + return __webpack_require__(910); + } - return listenClientData(intent, serviceWindow).then(function (data) { - return { - compose: compose, - getData: function getData() { - return data; - }, - getIntent: function getIntent() { - return intent; - }, - terminate: function terminate(doc) { - var eventName = data && data.exposeIntentFrameRemoval ? 'exposeFrameRemoval' : 'done'; - return _terminate({ - type: 'intent-' + intent._id + ':' + eventName, - document: doc - }); - }, - throw: function _throw(error) { - return _terminate({ - type: 'intent-' + intent._id + ':error', - error: _helpers.errorSerializer.serialize(error) - }); - }, - resizeClient: resizeClient, - cancel: cancel - }; - }); + const cozyFields = JSON.parse(process.env.COZY_FIELDS || '{}'); + const newCozyClient = NewCozyClient.fromEnv(process.env, { + appMetadata: { + slug: manifest.data.slug, + sourceAccount: cozyFields.account, + version: manifest.data.version + } }); -} + newCozyClient.models = models; + const cozyClient = cozyClientJsFromEnv(newCozyClient.stackClient.uri); + cozyClient.new = newCozyClient; + return cozyClient; +}; +/** + * [cozy-client-js](https://github.com/cozy/cozy-client-js) instance already initialized and ready to use. + * + * If you want to access cozy-client-js directly, this method gives you directly an instance of it, + * initialized according to `COZY_URL` and `COZY_CREDENTIALS` environment variable given by cozy-stack + * You can refer to the [cozy-client-js documentation](https://github.com/cozy/cozy-client-js) for more information. + * + * Example : + * + * ```javascript + * const {cozyClient} = require('cozy-konnector-libs') + * + * cozyClient.data.defineIndex('my.doctype', ['_id']) + * ``` + * + * @alias module:cozyClient + */ -/***/ }), -/* 18 */ -/***/ (function(module, exports, __nested_webpack_require_114916__) { -"use strict"; +const cozyClient = getCozyClient( // webpack 4 now changes the NODE_ENV environment variable when you change its 'mode' option +// since we do not want to minimize the built file, we recognize the 'none' mode as production mode +process.env.NODE_ENV === 'none' ? 'production' : process.env.NODE_ENV); +function cozyClientJsFromEnv(cozyURL) { + const options = { + cozyURL + }; + let jsonCredentials = null; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.count = count; -exports.queued = queued; -exports.create = create; + if (process.env.COZY_CREDENTIALS) { + try { + jsonCredentials = JSON.parse(process.env.COZY_CREDENTIALS); + } catch (err) { + options.token = process.env.COZY_CREDENTIALS; + } + } -var _fetch = __nested_webpack_require_114916__(0); + if (jsonCredentials) { + options.oauth = { + storage: new MemoryStorage() + }; + } -function count(cozy, workerType) { - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/jobs/queue/' + workerType).then(function (data) { - return data.length; - }); -} + const cozyClient = new Client(options); -function queued(cozy, workerType) { - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/jobs/queue/' + workerType); -} + if (jsonCredentials) { + jsonCredentials.token.toAuthHeader = function () { + return 'Bearer ' + jsonCredentials.client.registrationAccessToken; + }; -function create(cozy, workerType, args, options) { - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/jobs/queue/' + workerType, { - data: { - type: 'io.cozy.jobs', - attributes: { - arguments: args || {}, - options: options || {} - } - } - }); + cozyClient.saveCredentials(jsonCredentials.oauthOptions, jsonCredentials.token); + } + + return cozyClient; } +module.exports = cozyClient; + /***/ }), -/* 19 */ -/***/ (function(module, exports, __nested_webpack_require_115746__) { +/* 486 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __nested_webpack_require_228__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_228__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __nested_webpack_require_228__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __nested_webpack_require_228__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __nested_webpack_require_228__.d = function(exports, name, getter) { +/******/ if(!__nested_webpack_require_228__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __nested_webpack_require_228__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __nested_webpack_require_228__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __nested_webpack_require_228__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __nested_webpack_require_228__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __nested_webpack_require_228__(__nested_webpack_require_228__.s = 9); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __nested_webpack_require_2505__) { "use strict"; @@ -68573,371 +67044,398 @@ function create(cozy, workerType, args, options) { Object.defineProperty(exports, "__esModule", { value: true }); -exports.replicationOfflineError = undefined; - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // Define global `fetch` so it's made available to `pouchdb-browser` +exports.FetchError = undefined; +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /* global fetch */ -exports.init = init; -exports.getDoctypes = getDoctypes; -exports.hasDatabase = hasDatabase; -exports.getDatabase = getDatabase; -exports.setDatabase = setDatabase; -exports.migrateDatabase = migrateDatabase; -exports.createDatabase = createDatabase; -exports.destroyDatabase = destroyDatabase; -exports.destroyAllDatabase = destroyAllDatabase; -exports.hasReplication = hasReplication; -exports.replicateFromCozy = replicateFromCozy; -exports.stopReplication = stopReplication; -exports.stopAllReplication = stopAllReplication; -exports.hasRepeatedReplication = hasRepeatedReplication; -exports.startRepeatedReplication = startRepeatedReplication; -exports.stopRepeatedReplication = stopRepeatedReplication; -exports.stopAllRepeatedReplication = stopAllRepeatedReplication; -__nested_webpack_require_115746__(20); +exports.cozyFetch = cozyFetch; +exports.cozyFetchJSON = cozyFetchJSON; +exports.cozyFetchRawJSON = cozyFetchRawJSON; +exports.handleInvalidTokenError = handleInvalidTokenError; -var _doctypes = __nested_webpack_require_115746__(2); +var _auth_v = __nested_webpack_require_2505__(3); -var _auth_v = __nested_webpack_require_115746__(3); +var _utils = __nested_webpack_require_2505__(1); -var _utils = __nested_webpack_require_115746__(1); +var _jsonapi = __nested_webpack_require_2505__(7); -var _pouchdbBrowser = __nested_webpack_require_115746__(21); +var _jsonapi2 = _interopRequireDefault(_jsonapi); -var _pouchdbBrowser2 = _interopRequireDefault(_pouchdbBrowser); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _pouchdbFind = __nested_webpack_require_115746__(22); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var _pouchdbFind2 = _interopRequireDefault(_pouchdbFind); +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var replicationOfflineError = exports.replicationOfflineError = 'Replication abort, your device is actually offline.'; +function cozyFetch(cozy, path) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; -var pluginLoaded = false; + return cozy.fullpath(path).then(function (fullpath) { + var resp = void 0; + if (options.disableAuth) { + resp = fetch(fullpath, options); + } else if (options.manualAuthCredentials) { + resp = cozyFetchWithAuth(cozy, fullpath, options, options.manualAuthCredentials); + } else { + resp = cozy.authorize().then(function (credentials) { + return cozyFetchWithAuth(cozy, fullpath, options, credentials); + }); + } + return resp.then(function (res) { + return handleResponse(res, cozy._invalidTokenErrorHandler); + }); + }); +} -/* - For each doctype we have some parameters: - cozy._offline[doctype] = { - database: pouchdb database - replication: the pouchdb replication - replicationPromise: promise of replication - interval: repeated replication interval +function cozyFetchWithAuth(cozy, fullpath, options, credentials) { + if (credentials) { + options.headers = options.headers || {}; + options.headers['Authorization'] = credentials.token.toAuthHeader(); } -*/ -function init(cozy, _ref) { - var _ref$options = _ref.options, - options = _ref$options === undefined ? {} : _ref$options, - _ref$doctypes = _ref.doctypes, - doctypes = _ref$doctypes === undefined ? [] : _ref$doctypes; - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; + // the option credentials:include tells fetch to include the cookies in the + // request even for cross-origin requests + options.credentials = 'include'; - try { - for (var _iterator = doctypes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var doctype = _step.value; + return Promise.all([cozy.isV2(), fetch(fullpath, options)]).then(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + isV2 = _ref2[0], + res = _ref2[1]; - createDatabase(cozy, doctype, options); + if (res.status !== 400 && res.status !== 401 || isV2 || !credentials || options.dontRetry) { + return res; } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } + // we try to refresh the token only for OAuth, ie, the client defined + // and the token is an instance of AccessToken. + var client = credentials.client, + token = credentials.token; + + if (!client || !(token instanceof _auth_v.AccessToken)) { + return res; } - } + options.dontRetry = true; + return (0, _utils.retry)(function () { + return (0, _auth_v.refreshToken)(cozy, client, token); + }, 3)().then(function (newToken) { + return cozy.saveCredentials(client, newToken); + }).then(function (credentials) { + return cozyFetchWithAuth(cozy, fullpath, options, credentials); + }); + }); } -// helper +function cozyFetchJSON(cozy, method, path, body) { + var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; -function getInfo(cozy, doctype) { - cozy._offline = cozy._offline || []; - cozy._offline[doctype] = cozy._offline[doctype] || {}; - return cozy._offline[doctype]; + var processJSONAPI = typeof options.processJSONAPI === 'undefined' || options.processJSONAPI; + return fetchJSON(cozy, method, path, body, options).then(function (response) { + return handleJSONResponse(response, processJSONAPI); + }); } -function getDoctypes(cozy) { - cozy._offline = cozy._offline || []; - return Object.keys(cozy._offline); +function cozyFetchRawJSON(cozy, method, path, body) { + var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + + return fetchJSON(cozy, method, path, body, options).then(function (response) { + return handleJSONResponse(response, false); + }); } -// -// DATABASE -// +function fetchJSON(cozy, method, path, body) { + var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; -function hasDatabase(cozy, doctype) { - return getDatabase(cozy, doctype) !== undefined; -} + options.method = method; -function getDatabase(cozy, doctype) { - return getInfo(cozy, doctype).database; -} + var headers = options.headers = options.headers || {}; -function setDatabase(cozy, doctype, database) { - cozy._offline[doctype].database = database; - return getDatabase(cozy, doctype); -} + headers['Accept'] = 'application/json'; -function migrateDatabase(cozy, doctype) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + if (method !== 'GET' && method !== 'HEAD' && body !== undefined) { + if (headers['Content-Type']) { + options.body = body; + } else { + headers['Content-Type'] = 'application/json'; + options.body = JSON.stringify(body); + } + } - var oldDb = getDatabase(cozy, doctype); - var newOptions = _extends({ - adapter: 'idb' - }, options); - var newDb = new _pouchdbBrowser2.default(doctype, newOptions); + return cozyFetch(cozy, path, options); +} - return oldDb.replicate.to(newDb).then(function () { - setDatabase(cozy, doctype, newDb); - oldDb.destroy(); - return newDb; +function handleResponse(res, invalidTokenErrorHandler) { + if (res.ok) { + return res; + } + var data = void 0; + var contentType = res.headers.get('content-type'); + if (contentType && contentType.indexOf('json') >= 0) { + data = res.json(); + } else { + data = res.text(); + } + return data.then(function (err) { + var error = new FetchError(res, err); + if (FetchError.isInvalidToken(error) && invalidTokenErrorHandler) { + invalidTokenErrorHandler(error); + } + throw error; }); } -function createDatabase(cozy, doctype) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; +function handleJSONResponse(res) { + var processJSONAPI = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - if (!pluginLoaded) { - _pouchdbBrowser2.default.plugin(_pouchdbFind2.default); - pluginLoaded = true; + var contentType = res.headers.get('content-type'); + if (!contentType || contentType.indexOf('json') < 0) { + return res.text(function (data) { + throw new FetchError(res, new Error('Response is not JSON: ' + data)); + }); } - if (hasDatabase(cozy, doctype)) { - return Promise.resolve(getDatabase(cozy, doctype)); + var json = res.json(); + if (contentType.indexOf('application/vnd.api+json') === 0 && processJSONAPI) { + return json.then(_jsonapi2.default); + } else { + return json; } - - setDatabase(cozy, doctype, new _pouchdbBrowser2.default(doctype, options)); - return createIndexes(cozy, doctype).then(function () { - return getDatabase(cozy, doctype); - }); } -function destroyDatabase(cozy, doctype) { - if (!hasDatabase(cozy, doctype)) { - return Promise.resolve(false); - } +function handleInvalidTokenError(error) { + try { + var currentOrigin = window.location.origin; + var requestUrl = error.url; - return stopRepeatedReplication(cozy, doctype).then(function () { - return stopReplication(cozy, doctype); - }).then(function () { - return getDatabase(cozy, doctype).destroy(); - }).then(function (response) { - setDatabase(cozy, doctype, undefined); - return response; - }); + if (requestUrl.indexOf(currentOrigin.replace(/^(https?:\/\/\w+)-\w+\./, '$1.')) === 0) { + var redirectURL = currentOrigin + '?' + (0, _utils.encodeQuery)({ disconnect: 1 }); + window.location = redirectURL; + } + } catch (e) { + console.warn('Unable to handle invalid token error', e, error); + } } -function destroyAllDatabase(cozy) { - var doctypes = getDoctypes(cozy); - var destroy = function destroy(doctype) { - return destroyDatabase(cozy, doctype); - }; - return Promise.all(doctypes.map(destroy)); -} +var FetchError = exports.FetchError = function (_Error) { + _inherits(FetchError, _Error); -function createIndexes(cozy, doctype) { - if (doctype === _doctypes.DOCTYPE_FILES) { - return getDatabase(cozy, doctype).createIndex({ - index: { fields: ['dir_id'] } + function FetchError(res, reason) { + _classCallCheck(this, FetchError); + + var _this = _possibleConstructorReturn(this, (FetchError.__proto__ || Object.getPrototypeOf(FetchError)).call(this)); + + if (Error.captureStackTrace) { + Error.captureStackTrace(_this, _this.constructor); + } + // XXX We have to hardcode this because babel doesn't play nice when extending Error + _this.name = 'FetchError'; + _this.response = res; + _this.url = res.url; + _this.status = res.status; + _this.reason = reason; + + Object.defineProperty(_this, 'message', { + value: reason.message || (typeof reason === 'string' ? reason : JSON.stringify(reason)) }); + return _this; } - return Promise.resolve(); -} -// -// REPLICATION -// + return FetchError; +}(Error); -function hasReplication(cozy, doctype) { - return getReplication(cozy, doctype) !== undefined; -} +FetchError.isUnauthorized = function (err) { + // XXX We can't use err instanceof FetchError because of the caveats of babel + return err.name === 'FetchError' && err.status === 401; +}; -function getReplication(cozy, doctype) { - return getInfo(cozy, doctype).replication; -} +FetchError.isNotFound = function (err) { + // XXX We can't use err instanceof FetchError because of the caveats of babel + return err.name === 'FetchError' && err.status === 404; +}; -function setReplication(cozy, doctype, replication) { - cozy._offline[doctype].replication = replication; - return getReplication(cozy, doctype); -} +FetchError.isInvalidToken = function (err) { + // XXX We can't use err instanceof FetchError because of the caveats of babel + return err.name === 'FetchError' && err.status === 400 && err.reason && (err.reason.error === 'Invalid JWT token' || err.reason.error === 'Expired token'); +}; -function getReplicationUrl(cozy, doctype) { - return cozy.authorize().then(function (credentials) { - var basic = credentials.token.toBasicAuth(); - return (cozy._url + '/data/' + doctype).replace('//', '//' + basic); - }); -} +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { -function getReplicationPromise(cozy, doctype) { - return getInfo(cozy, doctype).replicationPromise; -} +"use strict"; -function setReplicationPromise(cozy, doctype, promise) { - cozy._offline[doctype].replicationPromise = promise; - return getReplicationPromise(cozy, doctype); -} -function replicateFromCozy(cozy, doctype) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.unpromiser = unpromiser; +exports.isPromise = isPromise; +exports.isOnline = isOnline; +exports.isOffline = isOffline; +exports.sleep = sleep; +exports.retry = retry; +exports.getFuzzedDelay = getFuzzedDelay; +exports.getBackedoffDelay = getBackedoffDelay; +exports.createPath = createPath; +exports.encodeQuery = encodeQuery; +exports.decodeQuery = decodeQuery; +exports.warn = warn; +/* global navigator */ +var FuzzFactor = 0.3; - return setReplicationPromise(cozy, doctype, new Promise(function (resolve, reject) { - if (!hasDatabase(cozy, doctype)) { - createDatabase(cozy, doctype); - } - if (options.live === true) { - return reject(new Error("You can't use `live` option with Cozy couchdb.")); +function unpromiser(fn) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; } - if ((0, _utils.isOffline)()) { - reject(replicationOfflineError); - options.onError && options.onError(replicationOfflineError); + var value = fn.apply(this, args); + if (!isPromise(value)) { + return value; + } + var l = args.length; + if (l === 0 || typeof args[l - 1] !== 'function') { return; } + var cb = args[l - 1]; + value.then(function (res) { + return cb(null, res); + }, function (err) { + return cb(err, null); + }); + }; +} - getReplicationUrl(cozy, doctype).then(function (url) { - return setReplication(cozy, doctype, getDatabase(cozy, doctype).replicate.from(url, options).on('complete', function (info) { - setReplication(cozy, doctype, undefined); - resolve(info); - options.onComplete && options.onComplete(info); - }).on('error', function (err) { - if (err.error === 'code=400, message=Expired token') { - cozy.authorize().then(function (_ref2) { - var client = _ref2.client, - token = _ref2.token; +function isPromise(value) { + return !!value && typeof value.then === 'function'; +} - (0, _auth_v.refreshToken)(cozy, client, token).then(function (newToken) { - return cozy.saveCredentials(client, newToken); - }).then(function () { - return replicateFromCozy(cozy, doctype, options); - }); - }); - } else { - console.warn('ReplicateFromCozy \'' + doctype + '\' Error:'); - console.warn(err); - setReplication(cozy, doctype, undefined); - reject(err); - options.onError && options.onError(err); - } - })); - }); - })); +function isOnline() { + return typeof navigator !== 'undefined' ? navigator.onLine : true; } -function stopReplication(cozy, doctype) { - if (!getDatabase(cozy, doctype) || !hasReplication(cozy, doctype)) { - return Promise.resolve(); - } +function isOffline() { + return !isOnline(); +} +function sleep(time, args) { return new Promise(function (resolve) { - try { - getReplicationPromise(cozy, doctype).then(function () { - resolve(); - }); - getReplication(cozy, doctype).cancel(); - // replication is set to undefined by complete replication - } catch (e) { - resolve(); - } + setTimeout(resolve, time, args); }); } -function stopAllReplication(cozy) { - var doctypes = getDoctypes(cozy); - var stop = function stop(doctype) { - return stopReplication(cozy, doctype); - }; - return Promise.all(doctypes.map(stop)); -} +function retry(fn, count) { + var delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 300; -// -// REPEATED REPLICATION -// + return function doTry() { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } -function getRepeatedReplication(cozy, doctype) { - return getInfo(cozy, doctype).interval; + return fn.apply(undefined, args).catch(function (err) { + if (--count < 0) { + throw err; + } + return sleep(getBackedoffDelay(delay, count)).then(function () { + return doTry.apply(undefined, args); + }); + }); + }; } -function setRepeatedReplication(cozy, doctype, interval) { - cozy._offline[doctype].interval = interval; +function getFuzzedDelay(retryDelay) { + var fuzzingFactor = (Math.random() * 2 - 1) * FuzzFactor; + return retryDelay * (1.0 + fuzzingFactor); } -function hasRepeatedReplication(cozy, doctype) { - return getRepeatedReplication(cozy, doctype) !== undefined; +function getBackedoffDelay(retryDelay) { + var retryCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + + return getFuzzedDelay(retryDelay * Math.pow(2, retryCount - 1)); } -function startRepeatedReplication(cozy, doctype, timer) { - var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; +function createPath(cozy, isV2, doctype) { + var id = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; + var query = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; - // TODO: add timer limitation for not flooding Gozy - if (hasRepeatedReplication(cozy, doctype)) { - return getRepeatedReplication(cozy, doctype); + var route = '/data/'; + if (!isV2) { + route += encodeURIComponent(doctype) + '/'; + } + if (id !== '') { + route += encodeURIComponent(id); + } + var q = encodeQuery(query); + if (q !== '') { + route += '?' + q; } + return route; +} - return setRepeatedReplication(cozy, doctype, setInterval(function () { - if ((0, _utils.isOffline)()) { - // network is offline, replication cannot be launched - console.info(replicationOfflineError); - return; - } - if (!hasReplication(cozy, doctype)) { - replicateFromCozy(cozy, doctype, options); - // TODO: add replicationToCozy +function encodeQuery(query) { + if (!query) { + return ''; + } + var q = ''; + for (var qname in query) { + if (q !== '') { + q += '&'; } - }, timer * 1000)); + q += encodeURIComponent(qname) + '=' + encodeURIComponent(query[qname]); + } + return q; } -function stopRepeatedReplication(cozy, doctype) { - if (hasRepeatedReplication(cozy, doctype)) { - clearInterval(getRepeatedReplication(cozy, doctype)); - setRepeatedReplication(cozy, doctype, undefined); +function decodeQuery(url) { + var queryIndex = url.indexOf('?'); + if (queryIndex < 0) { + queryIndex = url.length; } - if (hasReplication(cozy, doctype)) { - return stopReplication(cozy, doctype); + var queries = {}; + var fragIndex = url.indexOf('#'); + if (fragIndex < 0) { + fragIndex = url.length; } - - return Promise.resolve(); + if (fragIndex < queryIndex) { + return queries; + } + var queryStr = url.slice(queryIndex + 1, fragIndex); + if (queryStr === '') { + return queries; + } + var parts = queryStr.split('&'); + for (var i = 0; i < parts.length; i++) { + var pair = parts[i].split('='); + if (pair.length === 0 || pair[0] === '') { + continue; + } + var qname = decodeURIComponent(pair[0]); + if (queries.hasOwnProperty(qname)) { + continue; + } + if (pair.length === 1) { + queries[qname] = true; + } else if (pair.length === 2) { + queries[qname] = decodeURIComponent(pair[1]); + } else { + throw new Error('Malformed URL'); + } + } + return queries; } -function stopAllRepeatedReplication(cozy) { - var doctypes = getDoctypes(cozy); - var stop = function stop(doctype) { - return stopRepeatedReplication(cozy, doctype); - }; - return Promise.all(doctypes.map(stop)); +var warned = []; +function warn(text) { + if (warned.indexOf(text) === -1) { + warned.push(text); + console.warn('cozy-client-js', text); + } } /***/ }), -/* 20 */ -/***/ (function(module, exports) { - -module.exports = __webpack_require__(479); - -/***/ }), -/* 21 */ -/***/ (function(module, exports) { - -module.exports = __webpack_require__(482); - -/***/ }), -/* 22 */ -/***/ (function(module, exports) { - -module.exports = __webpack_require__(494); - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __nested_webpack_require_126289__) { +/* 2 */ +/***/ (function(module, exports, __nested_webpack_require_15027__) { "use strict"; @@ -68945,37555 +67443,37810 @@ module.exports = __webpack_require__(494); Object.defineProperty(exports, "__esModule", { value: true }); -exports.diskUsage = diskUsage; -exports.changePassphrase = changePassphrase; -exports.getInstance = getInstance; -exports.updateInstance = updateInstance; -exports.getClients = getClients; -exports.deleteClientById = deleteClientById; -exports.updateLastSync = updateLastSync; - -var _fetch = __nested_webpack_require_126289__(0); - -function diskUsage(cozy) { - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/disk-usage'); -} - -function changePassphrase(cozy, currentPassPhrase, newPassPhrase) { - return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/settings/passphrase', { - current_passphrase: currentPassPhrase, - new_passphrase: newPassPhrase - }); -} +exports.DOCTYPE_FILES = undefined; +exports.normalizeDoctype = normalizeDoctype; -function getInstance(cozy) { - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/instance'); -} +var _utils = __nested_webpack_require_15027__(1); -function updateInstance(cozy, instance) { - return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/settings/instance', instance); -} +var DOCTYPE_FILES = exports.DOCTYPE_FILES = 'io.cozy.files'; -function getClients(cozy) { - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/clients'); -} +var KNOWN_DOCTYPES = { + files: DOCTYPE_FILES, + folder: DOCTYPE_FILES, + contact: 'io.cozy.contacts', + event: 'io.cozy.events', + track: 'io.cozy.labs.music.track', + playlist: 'io.cozy.labs.music.playlist' +}; -function deleteClientById(cozy, id) { - return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/settings/clients/' + id); -} +var REVERSE_KNOWN = {}; +Object.keys(KNOWN_DOCTYPES).forEach(function (k) { + REVERSE_KNOWN[KNOWN_DOCTYPES[k]] = k; +}); -function updateLastSync(cozy) { - return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/settings/synchronized'); +function normalizeDoctype(cozy, isV2, doctype) { + var isQualified = doctype.indexOf('.') !== -1; + if (isV2 && isQualified) { + var known = REVERSE_KNOWN[doctype]; + if (known) return known; + return doctype.replace(/\./g, '-'); + } + if (!isV2 && !isQualified) { + var _known = KNOWN_DOCTYPES[doctype]; + if (_known) { + (0, _utils.warn)('you are using a non-qualified doctype ' + doctype + ' assumed to be ' + _known); + return _known; + } + throw new Error('Doctype ' + doctype + ' should be qualified.'); + } + return doctype; } /***/ }), -/* 24 */ -/***/ (function(module, exports, __nested_webpack_require_127648__) { +/* 3 */ +/***/ (function(module, exports, __nested_webpack_require_16254__) { "use strict"; - +/* WEBPACK VAR INJECTION */(function(btoa) { Object.defineProperty(exports, "__esModule", { value: true }); -exports.removeReferencedFiles = exports.addReferencedFiles = undefined; -exports.listReferencedFiles = listReferencedFiles; -exports.fetchReferencedFiles = fetchReferencedFiles; - -var _fetch = __nested_webpack_require_127648__(0); - -var _doctypes = __nested_webpack_require_127648__(2); - -function updateRelations(verb) { - return function (cozy, doc, ids) { - if (!doc) throw new Error('missing doc argument'); - if (!Array.isArray(ids)) ids = [ids]; - - var refs = ids.map(function (id) { - return { type: _doctypes.DOCTYPE_FILES, id: id }; - }); - - return (0, _fetch.cozyFetchJSON)(cozy, verb, makeReferencesPath(doc), { data: refs }); - }; -} +exports.AppToken = exports.AccessToken = exports.Client = exports.StateKey = exports.CredsKey = undefined; -var addReferencedFiles = exports.addReferencedFiles = updateRelations('POST'); -var removeReferencedFiles = exports.removeReferencedFiles = updateRelations('DELETE'); +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); -function listReferencedFiles(cozy, doc) { - if (!doc) throw new Error('missing doc argument'); - return (0, _fetch.cozyFetchJSON)(cozy, 'GET', makeReferencesPath(doc)).then(function (files) { - return files.map(function (file) { - return file._id; - }); - }); -} +var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global btoa */ -function fetchReferencedFiles(cozy, doc, options, sort) { - if (!doc) throw new Error('missing doc argument'); - var params = Object.keys(options).map(function (key) { - var value = encodeURIComponent(JSON.stringify(options[key])); - return '&page[' + key + ']=' + value; - }).join(''); - // Datetime is the default sort, but 'id' is also available - if (!sort) { - sort = 'datetime'; - } - return (0, _fetch.cozyFetchRawJSON)(cozy, 'GET', makeReferencesPath(doc) + '?include=files&sort=' + sort + params); -} -function makeReferencesPath(doc) { - var type = encodeURIComponent(doc._type); - var id = encodeURIComponent(doc._id); - return '/data/' + type + '/' + id + '/relationships/references'; -} +exports.client = client; +exports.registerClient = registerClient; +exports.updateClient = updateClient; +exports.unregisterClient = unregisterClient; +exports.getClient = getClient; +exports.getAuthCodeURL = getAuthCodeURL; +exports.getAccessToken = getAccessToken; +exports.refreshToken = refreshToken; +exports.oauthFlow = oauthFlow; -/***/ }) -/******/ ]))); -//# sourceMappingURL=cozy-client.node.js.map +var _utils = __nested_webpack_require_16254__(1); -/***/ }), -/* 475 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _fetch = __nested_webpack_require_16254__(0); -module.exports = __webpack_require__(476); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var StateSize = 16; -/***/ }), -/* 476 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var CredsKey = exports.CredsKey = 'creds'; +var StateKey = exports.StateKey = 'state'; -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +var Client = exports.Client = function () { + function Client(opts) { + _classCallCheck(this, Client); -// This method of obtaining a reference to the global object needs to be -// kept identical to the way it is obtained in runtime.js -var g = (function() { return this })() || Function("return this")(); + this.clientID = opts.clientID || opts.client_id || ''; + this.clientSecret = opts.clientSecret || opts.client_secret || ''; + this.registrationAccessToken = opts.registrationAccessToken || opts.registration_access_token || ''; -// Use `getOwnPropertyNames` because not all browsers support calling -// `hasOwnProperty` on the global `self` object in a worker. See #183. -var hadRuntime = g.regeneratorRuntime && - Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0; + if (opts.redirect_uris) { + this.redirectURI = opts.redirect_uris[0] || ''; + } else { + this.redirectURI = opts.redirectURI || ''; + } -// Save the old regeneratorRuntime in case it needs to be restored later. -var oldRuntime = hadRuntime && g.regeneratorRuntime; + this.softwareID = opts.softwareID || opts.software_id || ''; + this.softwareVersion = opts.softwareVersion || opts.software_version || ''; + this.clientName = opts.clientName || opts.client_name || ''; + this.clientKind = opts.clientKind || opts.client_kind || ''; + this.clientURI = opts.clientURI || opts.client_uri || ''; -// Force reevalutation of runtime.js. -g.regeneratorRuntime = undefined; + this.logoURI = opts.logoURI || opts.logo_uri || ''; + this.policyURI = opts.policyURI || opts.policy_uri || ''; -module.exports = __webpack_require__(477); + this.notificationPlatform = opts.notificationPlatform || opts.notification_platform || ''; + this.notificationDeviceToken = opts.notificationDeviceToken || opts.notification_device_token || ''; -if (hadRuntime) { - // Restore the original runtime. - g.regeneratorRuntime = oldRuntime; -} else { - // Remove the global property added by runtime.js. - try { - delete g.regeneratorRuntime; - } catch(e) { - g.regeneratorRuntime = undefined; + if (!this.registrationAccessToken) { + if (this.redirectURI === '') { + throw new Error('Missing redirectURI field'); + } + if (this.softwareID === '') { + throw new Error('Missing softwareID field'); + } + if (this.clientName === '') { + throw new Error('Missing clientName field'); + } + } } -} - - -/***/ }), -/* 477 */ -/***/ ((module) => { -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ + _createClass(Client, [{ + key: 'isRegistered', + value: function isRegistered() { + return this.clientID !== ''; + } + }, { + key: 'toRegisterJSON', + value: function toRegisterJSON() { + return { + redirect_uris: [this.redirectURI], + software_id: this.softwareID, + software_version: this.softwareVersion, + client_name: this.clientName, + client_kind: this.clientKind, + client_uri: this.clientURI, + logo_uri: this.logoURI, + policy_uri: this.policyURI, + notification_platform: this.notificationPlatform, + notification_device_token: this.notificationDeviceToken + }; + } + }, { + key: 'toAuthHeader', + value: function toAuthHeader() { + return 'Bearer ' + this.registrationAccessToken; + } + }]); -!(function(global) { - "use strict"; + return Client; +}(); - var Op = Object.prototype; - var hasOwn = Op.hasOwnProperty; - var undefined; // More compressible than void 0. - var $Symbol = typeof Symbol === "function" ? Symbol : {}; - var iteratorSymbol = $Symbol.iterator || "@@iterator"; - var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; - var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; +var AccessToken = exports.AccessToken = function () { + function AccessToken(opts) { + _classCallCheck(this, AccessToken); - var inModule = "object" === "object"; - var runtime = global.regeneratorRuntime; - if (runtime) { - if (inModule) { - // If regeneratorRuntime is defined globally and we're in a module, - // make the exports object identical to regeneratorRuntime. - module.exports = runtime; - } - // Don't bother evaluating the rest of this file if the runtime was - // already defined globally. - return; + this.tokenType = opts.tokenType || opts.token_type; + this.accessToken = opts.accessToken || opts.access_token; + this.refreshToken = opts.refreshToken || opts.refresh_token; + this.scope = opts.scope; } - // Define the runtime globally (as expected by generated code) as either - // module.exports (if we're in a module) or a new, empty object. - runtime = global.regeneratorRuntime = inModule ? module.exports : {}; + _createClass(AccessToken, [{ + key: 'toAuthHeader', + value: function toAuthHeader() { + return 'Bearer ' + this.accessToken; + } + }, { + key: 'toBasicAuth', + value: function toBasicAuth() { + return 'user:' + this.accessToken + '@'; + } + }]); - function wrap(innerFn, outerFn, self, tryLocsList) { - // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. - var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; - var generator = Object.create(protoGenerator.prototype); - var context = new Context(tryLocsList || []); + return AccessToken; +}(); - // The ._invoke method unifies the implementations of the .next, - // .throw, and .return methods. - generator._invoke = makeInvokeMethod(innerFn, self, context); +var AppToken = exports.AppToken = function () { + function AppToken(opts) { + _classCallCheck(this, AppToken); - return generator; + this.token = opts.token || ''; } - runtime.wrap = wrap; - // Try/catch helper to minimize deoptimizations. Returns a completion - // record like context.tryEntries[i].completion. This interface could - // have been (and was previously) designed to take a closure to be - // invoked without arguments, but in all the cases we care about we - // already have an existing method we want to call, so there's no need - // to create a new function object. We can even get away with assuming - // the method takes exactly one argument, since that happens to be true - // in every case, so we don't have to touch the arguments object. The - // only additional allocation required is the completion record, which - // has a stable shape and so hopefully should be cheap to allocate. - function tryCatch(fn, obj, arg) { - try { - return { type: "normal", arg: fn.call(obj, arg) }; - } catch (err) { - return { type: "throw", arg: err }; + _createClass(AppToken, [{ + key: 'toAuthHeader', + value: function toAuthHeader() { + return 'Bearer ' + this.token; } - } - - var GenStateSuspendedStart = "suspendedStart"; - var GenStateSuspendedYield = "suspendedYield"; - var GenStateExecuting = "executing"; - var GenStateCompleted = "completed"; - - // Returning this object from the innerFn has the same effect as - // breaking out of the dispatch switch statement. - var ContinueSentinel = {}; - - // Dummy constructor functions that we use as the .constructor and - // .constructor.prototype properties for functions that return Generator - // objects. For full spec compliance, you may wish to configure your - // minifier not to mangle the names of these two functions. - function Generator() {} - function GeneratorFunction() {} - function GeneratorFunctionPrototype() {} + }, { + key: 'toBasicAuth', + value: function toBasicAuth() { + return 'user:' + this.token + '@'; + } + }]); - // This is a polyfill for %IteratorPrototype% for environments that - // don't natively support it. - var IteratorPrototype = {}; - IteratorPrototype[iteratorSymbol] = function () { - return this; - }; + return AppToken; +}(); - var getProto = Object.getPrototypeOf; - var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); - if (NativeIteratorPrototype && - NativeIteratorPrototype !== Op && - hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { - // This environment has a native %IteratorPrototype%; use it instead - // of the polyfill. - IteratorPrototype = NativeIteratorPrototype; +function client(cozy, clientParams) { + if (!clientParams) { + clientParams = cozy._clientParams; } - - var Gp = GeneratorFunctionPrototype.prototype = - Generator.prototype = Object.create(IteratorPrototype); - GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; - GeneratorFunctionPrototype.constructor = GeneratorFunction; - GeneratorFunctionPrototype[toStringTagSymbol] = - GeneratorFunction.displayName = "GeneratorFunction"; - - // Helper for defining the .next, .throw, and .return methods of the - // Iterator interface in terms of a single ._invoke method. - function defineIteratorMethods(prototype) { - ["next", "throw", "return"].forEach(function(method) { - prototype[method] = function(arg) { - return this._invoke(method, arg); - }; - }); + if (clientParams instanceof Client) { + return clientParams; } + return new Client(clientParams); +} - runtime.isGeneratorFunction = function(genFun) { - var ctor = typeof genFun === "function" && genFun.constructor; - return ctor - ? ctor === GeneratorFunction || - // For the native GeneratorFunction constructor, the best we can - // do is to check its .name property. - (ctor.displayName || ctor.name) === "GeneratorFunction" - : false; - }; - - runtime.mark = function(genFun) { - if (Object.setPrototypeOf) { - Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); - } else { - genFun.__proto__ = GeneratorFunctionPrototype; - if (!(toStringTagSymbol in genFun)) { - genFun[toStringTagSymbol] = "GeneratorFunction"; - } - } - genFun.prototype = Object.create(Gp); - return genFun; - }; - - // Within the body of any async function, `await x` is transformed to - // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test - // `hasOwn.call(value, "__await")` to determine if the yielded value is - // meant to be awaited. - runtime.awrap = function(arg) { - return { __await: arg }; - }; - - function AsyncIterator(generator) { - function invoke(method, arg, resolve, reject) { - var record = tryCatch(generator[method], generator, arg); - if (record.type === "throw") { - reject(record.arg); - } else { - var result = record.arg; - var value = result.value; - if (value && - typeof value === "object" && - hasOwn.call(value, "__await")) { - return Promise.resolve(value.__await).then(function(value) { - invoke("next", value, resolve, reject); - }, function(err) { - invoke("throw", err, resolve, reject); - }); - } +function registerClient(cozy, clientParams) { + var cli = client(cozy, clientParams); + if (cli.isRegistered()) { + return Promise.reject(new Error('Client already registered')); + } + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/auth/register', cli.toRegisterJSON(), { + disableAuth: true + }).then(function (data) { + return new Client(data); + }); +} - return Promise.resolve(value).then(function(unwrapped) { - // When a yielded Promise is resolved, its final value becomes - // the .value of the Promise<{value,done}> result for the - // current iteration. If the Promise is rejected, however, the - // result for this iteration will be rejected with the same - // reason. Note that rejections of yielded Promises are not - // thrown back into the generator function, as is the case - // when an awaited Promise is rejected. This difference in - // behavior between yield and await is important, because it - // allows the consumer to decide what to do with the yielded - // rejection (swallow it and continue, manually .throw it back - // into the generator, abandon iteration, whatever). With - // await, by contrast, there is no opportunity to examine the - // rejection reason outside the generator function, so the - // only option is to throw it from the await expression, and - // let the generator function handle the exception. - result.value = unwrapped; - resolve(result); - }, reject); - } - } +function updateClient(cozy, clientParams) { + var resetSecret = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - var previousPromise; + var cli = client(cozy, clientParams); + if (!cli.isRegistered()) { + return Promise.reject(new Error('Client not registered')); + } + var data = cli.toRegisterJSON(); + data.client_id = cli.clientID; + if (resetSecret) data.client_secret = cli.clientSecret; - function enqueue(method, arg) { - function callInvokeWithMethodAndArg() { - return new Promise(function(resolve, reject) { - invoke(method, arg, resolve, reject); - }); - } + return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/auth/register/' + cli.clientID, data, { + manualAuthCredentials: { + token: cli + } + }).then(function (data) { + return createClient(data, cli); + }); +} - return previousPromise = - // If enqueue has been called before, then we want to wait until - // all previous Promises have been resolved before calling invoke, - // so that results are always delivered in the correct order. If - // enqueue has not been called before, then it is important to - // call invoke immediately, without waiting on a callback to fire, - // so that the async generator function has the opportunity to do - // any necessary setup in a predictable way. This predictability - // is why the Promise constructor synchronously invokes its - // executor callback, and why async functions synchronously - // execute code before the first await. Since we implement simple - // async functions in terms of async generators, it is especially - // important to get this right, even though it requires care. - previousPromise ? previousPromise.then( - callInvokeWithMethodAndArg, - // Avoid propagating failures to Promises returned by later - // invocations of the iterator. - callInvokeWithMethodAndArg - ) : callInvokeWithMethodAndArg(); +function unregisterClient(cozy, clientParams) { + var cli = client(cozy, clientParams); + if (!cli.isRegistered()) { + return Promise.reject(new Error('Client not registered')); + } + return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/auth/register/' + cli.clientID, null, { + manualAuthCredentials: { + token: cli } + }); +} - // Define the unified helper method that is used to implement .next, - // .throw, and .return (see defineIteratorMethods). - this._invoke = enqueue; +// getClient will retrive the registered client informations from the server. +function getClient(cozy, clientParams) { + var cli = client(cozy, clientParams); + if (!cli.isRegistered()) { + return Promise.reject(new Error('Client not registered')); + } + if ((0, _utils.isOffline)()) { + return Promise.resolve(cli); } + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/auth/register/' + cli.clientID, null, { + manualAuthCredentials: { + token: cli + } + }).then(function (data) { + return createClient(data, cli); + }).catch(function (err) { + // If we fall into an error while fetching the client (because of a + // bad connectivity for instance), we do not bail the whole process + // since the client should be able to continue with the persisted + // client and token. + // + // If it is an explicit Unauthorized error though, we bail, clear th + // cache and retry. + if (_fetch.FetchError.isUnauthorized(err) || _fetch.FetchError.isNotFound(err)) { + throw new Error('Client has been revoked'); + } + throw err; + }); +} - defineIteratorMethods(AsyncIterator.prototype); - AsyncIterator.prototype[asyncIteratorSymbol] = function () { - return this; - }; - runtime.AsyncIterator = AsyncIterator; +// createClient returns a new Client instance given on object containing the +// data of the client, from the API, and an old instance of the client. +function createClient(data, oldClient) { + var newClient = new Client(data); + // we need to keep track of the registrationAccessToken since it is send + // only on registration. The GET /auth/register/:client-id endpoint does + // not return this token. + var shouldPassRegistration = !!oldClient && oldClient.registrationAccessToken !== '' && newClient.registrationAccessToken === ''; + if (shouldPassRegistration) { + newClient.registrationAccessToken = oldClient.registrationAccessToken; + } + return newClient; +} - // Note that simple async functions are implemented on top of - // AsyncIterator objects; they just return a Promise for the value of - // the final result produced by the iterator. - runtime.async = function(innerFn, outerFn, self, tryLocsList) { - var iter = new AsyncIterator( - wrap(innerFn, outerFn, self, tryLocsList) - ); +// getAuthCodeURL returns a pair {authURL,state} given a registered client. The +// state should be stored in order to be checked against on the user validation +// phase. +function getAuthCodeURL(cozy, client) { + var scopes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; - return runtime.isGeneratorFunction(outerFn) - ? iter // If outerFn is a generator, return the full iterator. - : iter.next().then(function(result) { - return result.done ? result.value : iter.next(); - }); + if (!(client instanceof Client)) { + client = new Client(client); + } + if (!client.isRegistered()) { + throw new Error('Client not registered'); + } + var state = generateRandomState(); + var query = { + client_id: client.clientID, + redirect_uri: client.redirectURI, + state: state, + response_type: 'code', + scope: scopes.join(' ') + }; + return { + url: cozy._url + ('/auth/authorize?' + (0, _utils.encodeQuery)(query)), + state: state }; +} - function makeInvokeMethod(innerFn, self, context) { - var state = GenStateSuspendedStart; +// getAccessToken perform a request on the access_token entrypoint with the +// authorization_code grant type in order to generate a new access token for a +// newly registered client. +// +// This method extracts the access code and state from the given URL. By +// default it uses window.location.href. Also, it checks the given state with +// the one specified in the URL query parameter to prevent CSRF attacks. +function getAccessToken(cozy, client, state) { + var pageURL = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; - return function invoke(method, arg) { - if (state === GenStateExecuting) { - throw new Error("Generator is already running"); - } + if (!state) { + return Promise.reject(new Error('Missing state value')); + } + var grantQueries = getGrantCodeFromPageURL(pageURL); + if (grantQueries === null) { + return Promise.reject(new Error('Missing states from current URL')); + } + if (state !== grantQueries.state) { + return Promise.reject(new Error('Given state does not match url query state')); + } + return retrieveToken(cozy, client, null, { + grant_type: 'authorization_code', + code: grantQueries.code + }); +} - if (state === GenStateCompleted) { - if (method === "throw") { - throw arg; - } +// refreshToken perform a request on the access_token entrypoint with the +// refresh_token grant type in order to refresh the given token. +function refreshToken(cozy, client, token) { + return retrieveToken(cozy, client, token, { + grant_type: 'refresh_token', + refresh_token: token.refreshToken + }); +} - // Be forgiving, per 25.3.3.3.3 of the spec: - // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume - return doneResult(); - } +// oauthFlow performs the stateful registration and access granting of an OAuth +// client. +function oauthFlow(cozy, storage, clientParams, onRegistered) { + var ignoreCachedCredentials = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; - context.method = method; - context.arg = arg; + if (ignoreCachedCredentials) { + return storage.clear().then(function () { + return oauthFlow(cozy, storage, clientParams, onRegistered, false); + }); + } - while (true) { - var delegate = context.delegate; - if (delegate) { - var delegateResult = maybeInvokeDelegate(delegate, context); - if (delegateResult) { - if (delegateResult === ContinueSentinel) continue; - return delegateResult; - } - } + var tryCount = 0; - if (context.method === "next") { - // Setting context._sent for legacy support of Babel's - // function.sent implementation. - context.sent = context._sent = context.arg; + function clearAndRetry(err) { + if (tryCount++ > 0) { + throw err; + } + return storage.clear().then(function () { + return oauthFlow(cozy, storage, clientParams, onRegistered); + }); + } - } else if (context.method === "throw") { - if (state === GenStateSuspendedStart) { - state = GenStateCompleted; - throw context.arg; - } + function registerNewClient() { + return storage.clear().then(function () { + return registerClient(cozy, clientParams); + }).then(function (client) { + var _getAuthCodeURL = getAuthCodeURL(cozy, client, clientParams.scopes), + url = _getAuthCodeURL.url, + state = _getAuthCodeURL.state; - context.dispatchException(context.arg); + return storage.save(StateKey, { client: client, url: url, state: state }); + }); + } - } else if (context.method === "return") { - context.abrupt("return", context.arg); + return Promise.all([storage.load(CredsKey), storage.load(StateKey)]).then(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + credentials = _ref2[0], + storedState = _ref2[1]; + + // If credentials are cached we re-fetch the registered client with the + // said token. Fetching the client, if the token is outdated we should try + // the token is refreshed. + if (credentials) { + var oldClient = void 0, + _token = void 0; + try { + oldClient = new Client(credentials.client); + _token = new AccessToken(credentials.token); + } catch (err) { + // bad cache, we should clear and retry the process + return clearAndRetry(err); + } + return getClient(cozy, oldClient).then(function (client) { + return { client: client, token: _token }; + }).catch(function (err) { + // If we fall into an error while fetching the client (because of a + // bad connectivity for instance), we do not bail the whole process + // since the client should be able to continue with the persisted + // client and token. + // + // If it is an explicit Unauthorized error though, we bail, clear th + // cache and retry. + if (_fetch.FetchError.isUnauthorized(err) || _fetch.FetchError.isNotFound(err)) { + throw new Error('Client has been revoked'); } + return { client: oldClient, token: _token }; + }); + } - state = GenStateExecuting; + // Otherwise register a new client if necessary (ie. no client is stored) + // and call the onRegistered callback to wait for the user to grant the + // access. Finally fetches to access token on success. + var statePromise = void 0; + if (!storedState) { + statePromise = registerNewClient(); + } else { + statePromise = Promise.resolve(storedState); + } - var record = tryCatch(innerFn, self, context); - if (record.type === "normal") { - // If an exception is thrown from innerFn, we leave state === - // GenStateExecuting and loop back for another invocation. - state = context.done - ? GenStateCompleted - : GenStateSuspendedYield; + var client = void 0, + state = void 0, + token = void 0; + return statePromise.then(function (data) { + client = data.client; + state = data.state; + return Promise.resolve(onRegistered(client, data.url)); + }).then(function (pageURL) { + return getAccessToken(cozy, client, state, pageURL); + }).then(function (t) { + token = t; + }).then(function () { + return storage.delete(StateKey); + }).then(function () { + return { client: client, token: token }; + }); + }).then(function (creds) { + return storage.save(CredsKey, creds); + }, function (err) { + if (_fetch.FetchError.isUnauthorized(err)) { + return clearAndRetry(err); + } else { + throw err; + } + }); +} - if (record.arg === ContinueSentinel) { - continue; - } +// retrieveToken perform a request on the access_token entrypoint in order to +// fetch a token. +function retrieveToken(cozy, client, token, query) { + if (!(client instanceof Client)) { + client = new Client(client); + } + if (!client.isRegistered()) { + return Promise.reject(new Error('Client not registered')); + } + var body = (0, _utils.encodeQuery)(Object.assign({}, query, { + client_id: client.clientID, + client_secret: client.clientSecret + })); + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/auth/access_token', body, { + disableAuth: token === null, + dontRetry: true, + manualAuthCredentials: { client: client, token: token }, + headers: { 'Content-Type': 'application/x-www-form-urlencoded' } + }).then(function (data) { + data.refreshToken = data.refreshToken || query.refresh_token; + return new AccessToken(data); + }); +} - return { - value: record.arg, - done: context.done - }; +// getGrantCodeFromPageURL extract the state and code query parameters from the +// given url +function getGrantCodeFromPageURL() { + var pageURL = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; - } else if (record.type === "throw") { - state = GenStateCompleted; - // Dispatch the exception by looping back around to the - // context.dispatchException(context.arg) call above. - context.method = "throw"; - context.arg = record.arg; - } - } - }; + if (pageURL === '' && typeof window !== 'undefined') { + pageURL = window.location.href; + } + var queries = (0, _utils.decodeQuery)(pageURL); + if (!queries.hasOwnProperty('state')) { + return null; } + return { + state: queries['state'], + code: queries['code'] + }; +} - // Call delegate.iterator[context.method](context.arg) and handle the - // result, either by returning a { value, done } result from the - // delegate iterator, or by modifying context.method and context.arg, - // setting context.delegate to null, and returning the ContinueSentinel. - function maybeInvokeDelegate(delegate, context) { - var method = delegate.iterator[context.method]; - if (method === undefined) { - // A .throw or .return when the delegate iterator has no .throw - // method always terminates the yield* loop. - context.delegate = null; +// generateRandomState will try to generate a 128bits random value from a secure +// pseudo random generator. It will fallback on Math.random if it cannot find +// such generator. +function generateRandomState() { + var buffer = void 0; + if (typeof window !== 'undefined' && typeof window.crypto !== 'undefined' && typeof window.crypto.getRandomValues === 'function') { + buffer = new Uint8Array(StateSize); + window.crypto.getRandomValues(buffer); + } else { + try { + buffer = __nested_webpack_require_16254__(12).randomBytes(StateSize); + } catch (e) { + buffer = null; + } + } + if (!buffer) { + buffer = new Array(StateSize); + for (var i = 0; i < buffer.length; i++) { + buffer[i] = Math.floor(Math.random() * 255); + } + } + return btoa(String.fromCharCode.apply(null, buffer)).replace(/=+$/, '').replace(/\//g, '_').replace(/\+/g, '-'); +} +/* WEBPACK VAR INJECTION */}.call(exports, __nested_webpack_require_16254__(6))) - if (context.method === "throw") { - if (delegate.iterator.return) { - // If the delegate iterator has a return method, give it a - // chance to clean up. - context.method = "return"; - context.arg = undefined; - maybeInvokeDelegate(delegate, context); +/***/ }), +/* 4 */ +/***/ (function(module, exports) { - if (context.method === "throw") { - // If maybeInvokeDelegate(context) changed context.method from - // "return" to "throw", let that override the TypeError below. - return ContinueSentinel; - } - } +module.exports = __webpack_require__(487); - context.method = "throw"; - context.arg = new TypeError( - "The iterator does not provide a 'throw' method"); - } +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { - return ContinueSentinel; - } +"use strict"; - var record = tryCatch(method, delegate.iterator, context.arg); - if (record.type === "throw") { - context.method = "throw"; - context.arg = record.arg; - context.delegate = null; - return ContinueSentinel; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.pickService = pickService; +// helper to serialize/deserialize an error for/from postMessage +var errorSerializer = exports.errorSerializer = function () { + function mapErrorProperties(from, to) { + var result = Object.assign(to, from); + var nativeProperties = ['name', 'message']; + return nativeProperties.reduce(function (result, property) { + if (from[property]) { + to[property] = from[property]; + } + return result; + }, result); + } + return { + serialize: function serialize(error) { + return mapErrorProperties(error, {}); + }, + deserialize: function deserialize(data) { + return mapErrorProperties(data, new Error(data.message)); } + }; +}(); - var info = record.arg; - - if (! info) { - context.method = "throw"; - context.arg = new TypeError("iterator result is not an object"); - context.delegate = null; - return ContinueSentinel; - } +var first = function first(arr) { + return arr && arr[0]; +}; +// In a far future, the user will have to pick the desired service from a list. +// For now it's our job, an easy job as we arbitrary pick the first service of +// the list. +function pickService(intent, filterServices) { + var services = intent.attributes.services; + var filteredServices = filterServices ? (services || []).filter(filterServices) : services; + return first(filteredServices); +} - if (info.done) { - // Assign the result of the finished delegate to the temporary - // variable specified by delegate.resultName (see delegateYield). - context[delegate.resultName] = info.value; +/***/ }), +/* 6 */ +/***/ (function(module, exports) { - // Resume execution at the desired location (see delegateYield). - context.next = delegate.nextLoc; +module.exports = __webpack_require__(490); - // If context.method was "throw" but the delegate handled the - // exception, let the outer generator proceed normally. If - // context.method was "next", forget context.arg since it has been - // "consumed" by the delegate iterator. If context.method was - // "return", allow the original .return call to continue in the - // outer generator. - if (context.method !== "return") { - context.method = "next"; - context.arg = undefined; - } +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { - } else { - // Re-yield the result returned by the delegate method. - return info; - } +"use strict"; - // The delegate iterator is finished, so forget it and continue with - // the outer generator. - context.delegate = null; - return ContinueSentinel; - } - // Define Generator.prototype.{next,throw,return} in terms of the - // unified ._invoke helper method. - defineIteratorMethods(Gp); +Object.defineProperty(exports, "__esModule", { + value: true +}); +function indexKey(doc) { + return doc.type + '/' + doc.id; +} - Gp[toStringTagSymbol] = "Generator"; +function findByRef(resources, ref) { + return resources[indexKey(ref)]; +} - // A Generator should always return itself as the iterator object when the - // @@iterator function is called on it. Some browsers' implementations of the - // iterator prototype chain incorrectly implement this, causing the Generator - // object to not be returned from this call. This ensures that doesn't happen. - // See https://github.com/facebook/regenerator/issues/274 for more details. - Gp[iteratorSymbol] = function() { - return this; +function handleResource(rawResource, resources, links) { + var resource = { + _id: rawResource.id, + _type: rawResource.type, + _rev: rawResource.meta && rawResource.meta.rev, + links: Object.assign({}, rawResource.links, links), + attributes: rawResource.attributes, + relations: function relations(name) { + var rels = rawResource.relationships[name]; + if (rels === undefined || rels.data === undefined) return undefined; + if (rels.data === null) return null; + if (!Array.isArray(rels.data)) return findByRef(resources, rels.data); + return rels.data.map(function (ref) { + return findByRef(resources, ref); + }); + } }; + if (rawResource.relationships) { + resource.relationships = rawResource.relationships; + } - Gp.toString = function() { - return "[object Generator]"; - }; + resources[indexKey(rawResource)] = resource; - function pushTryEntry(locs) { - var entry = { tryLoc: locs[0] }; + return resource; +} - if (1 in locs) { - entry.catchLoc = locs[1]; - } +function handleTopLevel(doc) { + var resources = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (2 in locs) { - entry.finallyLoc = locs[2]; - entry.afterLoc = locs[3]; - } + // build an index of included resource by Type & ID + var included = doc.included; - this.tryEntries.push(entry); + if (Array.isArray(included)) { + included.forEach(function (r) { + return handleResource(r, resources, doc.links); + }); } - function resetTryEntry(entry) { - var record = entry.completion || {}; - record.type = "normal"; - delete record.arg; - entry.completion = record; + if (Array.isArray(doc.data)) { + return doc.data.map(function (r) { + return handleResource(r, resources, doc.links); + }); + } else { + return handleResource(doc.data, resources, doc.links); } +} - function Context(tryLocsList) { - // The root entry object (effectively a try statement without a catch - // or a finally block) gives us a place to store values thrown from - // locations where there is no enclosing try statement. - this.tryEntries = [{ tryLoc: "root" }]; - tryLocsList.forEach(pushTryEntry, this); - this.reset(true); - } +exports.default = handleTopLevel; - runtime.keys = function(object) { - var keys = []; - for (var key in object) { - keys.push(key); - } - keys.reverse(); +/***/ }), +/* 8 */ +/***/ (function(module, exports, __nested_webpack_require_36434__) { - // Rather than returning an object with a next method, we keep - // things simple and return the next function itself. - return function next() { - while (keys.length) { - var key = keys.pop(); - if (key in object) { - next.value = key; - next.done = false; - return next; - } - } +"use strict"; - // To avoid creating an additional object, we just hang the .value - // and .done properties off the next function object itself. This - // also ensures that the minifier will not anonymize the function. - next.done = true; - return next; - }; - }; - function values(iterable) { - if (iterable) { - var iteratorMethod = iterable[iteratorSymbol]; - if (iteratorMethod) { - return iteratorMethod.call(iterable); - } +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.redirect = exports.getRedirectionURL = undefined; - if (typeof iterable.next === "function") { - return iterable; - } +var _regenerator = __nested_webpack_require_36434__(4); - if (!isNaN(iterable.length)) { - var i = -1, next = function next() { - while (++i < iterable.length) { - if (hasOwn.call(iterable, i)) { - next.value = iterable[i]; - next.done = false; - return next; - } - } +var _regenerator2 = _interopRequireDefault(_regenerator); - next.value = undefined; - next.done = true; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - return next; - }; +// Redirect to an app able to handle the doctype +// Redirections are more or less a hack of the intent API to retrieve an URL for +// accessing a given doctype or a given document. +// It needs to use a special action `REDIRECT` +var getRedirectionURL = exports.getRedirectionURL = function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, type, data) { + var intent, service, baseURL; + return _regenerator2.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!(!type && !data)) { + _context.next = 2; + break; + } - return next.next = next; - } - } + throw new Error('Cannot retrieve redirection, at least type or doc must be provided'); - // Return an iterator with no values. - return { next: doneResult }; - } - runtime.values = values; + case 2: + _context.next = 4; + return create(cozy, 'REDIRECT', type, data); - function doneResult() { - return { value: undefined, done: true }; - } + case 4: + intent = _context.sent; + service = (0, _helpers.pickService)(intent); - Context.prototype = { - constructor: Context, + if (service) { + _context.next = 8; + break; + } - reset: function(skipTempReset) { - this.prev = 0; - this.next = 0; - // Resetting context._sent for legacy support of Babel's - // function.sent implementation. - this.sent = this._sent = undefined; - this.done = false; - this.delegate = null; + throw new Error('Unable to find a service'); - this.method = "next"; - this.arg = undefined; + case 8: - this.tryEntries.forEach(resetTryEntry); + // Intents cannot be deleted now + // await deleteIntent(cozy, intent) - if (!skipTempReset) { - for (var name in this) { - // Not sure about the optimal order of these conditions: - if (name.charAt(0) === "t" && - hasOwn.call(this, name) && - !isNaN(+name.slice(1))) { - this[name] = undefined; - } + baseURL = removeQueryString(service.href); + return _context.abrupt('return', data ? buildRedirectionURL(baseURL, data) : baseURL); + + case 10: + case 'end': + return _context.stop(); } } - }, + }, _callee, this); + })); - stop: function() { - this.done = true; + return function getRedirectionURL(_x3, _x4, _x5) { + return _ref.apply(this, arguments); + }; +}(); - var rootEntry = this.tryEntries[0]; - var rootRecord = rootEntry.completion; - if (rootRecord.type === "throw") { - throw rootRecord.arg; - } +var redirect = exports.redirect = function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(cozy, type, doc, redirectFn) { + var redirectionURL; + return _regenerator2.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (window) { + _context2.next = 2; + break; + } - return this.rval; - }, + throw new Error('redirect() method can only be called in a browser'); - dispatchException: function(exception) { - if (this.done) { - throw exception; - } + case 2: + _context2.next = 4; + return getRedirectionURL(cozy, type, doc); - var context = this; - function handle(loc, caught) { - record.type = "throw"; - record.arg = exception; - context.next = loc; + case 4: + redirectionURL = _context2.sent; - if (caught) { - // If the dispatched exception was caught by a catch block, - // then let that catch block handle the exception normally. - context.method = "next"; - context.arg = undefined; - } + if (!(redirectFn && typeof redirectFn === 'function')) { + _context2.next = 7; + break; + } - return !! caught; - } + return _context2.abrupt('return', redirectFn(redirectionURL)); - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - var record = entry.completion; + case 7: - if (entry.tryLoc === "root") { - // Exception thrown outside of any try block that could handle - // it, so set the completion value of the entire function to - // throw the exception. - return handle("end"); + window.location.href = redirectionURL; + + case 8: + case 'end': + return _context2.stop(); } + } + }, _callee2, this); + })); - if (entry.tryLoc <= this.prev) { - var hasCatch = hasOwn.call(entry, "catchLoc"); - var hasFinally = hasOwn.call(entry, "finallyLoc"); + return function redirect(_x6, _x7, _x8, _x9) { + return _ref2.apply(this, arguments); + }; +}(); - if (hasCatch && hasFinally) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } else if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } +exports.create = create; +exports.createService = createService; - } else if (hasCatch) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } +var _fetch = __nested_webpack_require_36434__(0); - } else if (hasFinally) { - if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } +var _helpers = __nested_webpack_require_36434__(5); - } else { - throw new Error("try statement without catch or finally"); - } - } - } - }, +var _client = __nested_webpack_require_36434__(16); - abrupt: function(type, arg) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.tryLoc <= this.prev && - hasOwn.call(entry, "finallyLoc") && - this.prev < entry.finallyLoc) { - var finallyEntry = entry; - break; - } - } +var client = _interopRequireWildcard(_client); - if (finallyEntry && - (type === "break" || - type === "continue") && - finallyEntry.tryLoc <= arg && - arg <= finallyEntry.finallyLoc) { - // Ignore the finally entry if control is not jumping to a - // location outside the try/catch block. - finallyEntry = null; - } +var _service = __nested_webpack_require_36434__(17); - var record = finallyEntry ? finallyEntry.completion : {}; - record.type = type; - record.arg = arg; +var service = _interopRequireWildcard(_service); - if (finallyEntry) { - this.method = "next"; - this.next = finallyEntry.finallyLoc; - return ContinueSentinel; - } +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - return this.complete(record); - }, +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - complete: function(record, afterLoc) { - if (record.type === "throw") { - throw record.arg; - } +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } - if (record.type === "break" || - record.type === "continue") { - this.next = record.arg; - } else if (record.type === "return") { - this.rval = this.arg = record.arg; - this.method = "return"; - this.next = "end"; - } else if (record.type === "normal" && afterLoc) { - this.next = afterLoc; - } +function create(cozy, action, type) { + var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var permissions = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : []; - return ContinueSentinel; - }, + if (!action) throw new Error('Misformed intent, "action" property must be provided'); + if (!type) throw new Error('Misformed intent, "type" property must be provided'); - finish: function(finallyLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.finallyLoc === finallyLoc) { - this.complete(entry.completion, entry.afterLoc); - resetTryEntry(entry); - return ContinueSentinel; - } + var createPromise = (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/intents', { + data: { + type: 'io.cozy.intents', + attributes: { + action: action, + type: type, + data: data, + permissions: permissions } - }, + } + }); - "catch": function(tryLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.tryLoc === tryLoc) { - var record = entry.completion; - if (record.type === "throw") { - var thrown = record.arg; - resetTryEntry(entry); - } - return thrown; - } - } + createPromise.start = function (element, onReadyCallback) { + var options = { + filteredServices: data.filteredServices, + onReadyCallback: onReadyCallback + }; - // The context.catch method must only be called with a location - // argument that corresponds to a known catch block. - throw new Error("illegal catch attempt"); - }, + delete data.filteredServices; - delegateYield: function(iterable, resultName, nextLoc) { - this.delegate = { - iterator: values(iterable), - resultName: resultName, - nextLoc: nextLoc - }; + return createPromise.then(function (intent) { + return client.start(cozy, intent, element, data, options); + }); + }; - if (this.method === "next") { - // Deliberately forget the last sent value so that we don't - // accidentally pass it on to the delegate. - this.arg = undefined; - } + return createPromise; +} - return ContinueSentinel; - } - }; -})( - // In sloppy mode, unbound `this` refers to the global object, fallback to - // Function constructor if we're in global strict mode. That is sadly a form - // of indirect eval which violates Content Security Policy. - (function() { return this })() || Function("return this")() -); +// returns a service to communicate with intent client +function createService(cozy, intentId, serviceWindow) { + return service.start(cozy, intentId, serviceWindow); +} +function removeQueryString(url) { + return url.replace(/\?[^/#]*/, ''); +} -/***/ }), -/* 478 */ -/***/ ((module) => { +function isSerializable(value) { + return !['object', 'function'].includes(typeof value === 'undefined' ? 'undefined' : _typeof(value)); +} -(function () { - "use strict"; +function buildRedirectionURL(url, data) { + var parameterStrings = Object.keys(data).filter(function (key) { + return isSerializable(data[key]); + }).map(function (key) { + return key + '=' + data[key]; + }); - function btoa(str) { - var buffer; + return parameterStrings.length ? url + '?' + parameterStrings.join('&') : url; +} - if (str instanceof Buffer) { - buffer = str; - } else { - buffer = Buffer.from(str.toString(), 'binary'); - } +/***/ }), +/* 9 */ +/***/ (function(module, exports, __nested_webpack_require_42748__) { - return buffer.toString('base64'); - } +"use strict"; - module.exports = btoa; -}()); +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -/***/ }), -/* 479 */ -/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { +var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global fetch URL */ -const fetchNode = __webpack_require__(480) -const fetch = fetchNode.fetch.bind({}) -fetch.polyfill = true +var _utils = __nested_webpack_require_42748__(1); -if (!global.fetch) { - global.fetch = fetch - global.Response = fetchNode.Response - global.Headers = fetchNode.Headers - global.Request = fetchNode.Request -} +var _auth_storage = __nested_webpack_require_42748__(10); +var _auth_v = __nested_webpack_require_42748__(11); -/***/ }), -/* 480 */ -/***/ ((module, exports, __webpack_require__) => { +var _auth_v2 = __nested_webpack_require_42748__(3); -const nodeFetch = __webpack_require__(481) -const realFetch = nodeFetch.default || nodeFetch +var auth = _interopRequireWildcard(_auth_v2); -const fetch = function (url, options) { - // Support schemaless URIs on the server for parity with the browser. - // Ex: //github.com/ -> https://github.com/ - if (/^\/\//.test(url)) { - url = 'https:' + url - } - return realFetch.call(this, url, options) -} +var _data = __nested_webpack_require_42748__(13); -fetch.ponyfill = true +var data = _interopRequireWildcard(_data); -module.exports = exports = fetch -exports.fetch = fetch -exports.Headers = nodeFetch.Headers -exports.Request = nodeFetch.Request -exports.Response = nodeFetch.Response +var _fetch2 = __nested_webpack_require_42748__(0); -// Needed for TypeScript consumers without esModuleInterop. -exports["default"] = fetch +var cozyFetch = _interopRequireWildcard(_fetch2); +var _mango = __nested_webpack_require_42748__(14); -/***/ }), -/* 481 */ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { +var mango = _interopRequireWildcard(_mango); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), -/* harmony export */ "Headers": () => (/* binding */ Headers), -/* harmony export */ "Request": () => (/* binding */ Request), -/* harmony export */ "Response": () => (/* binding */ Response), -/* harmony export */ "FetchError": () => (/* binding */ FetchError) -/* harmony export */ }); -/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82); -/* harmony import */ var http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(80); -/* harmony import */ var url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(63); -/* harmony import */ var https__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(81); -/* harmony import */ var zlib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(83); +var _files = __nested_webpack_require_42748__(15); + +var files = _interopRequireWildcard(_files); +var _intents = __nested_webpack_require_42748__(8); +var intents = _interopRequireWildcard(_intents); +var _jobs = __nested_webpack_require_42748__(18); +var jobs = _interopRequireWildcard(_jobs); +var _offline = __nested_webpack_require_42748__(19); -// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js +var offline = _interopRequireWildcard(_offline); -// fix for "Readable" isn't a named export issue -const Readable = stream__WEBPACK_IMPORTED_MODULE_0__.Readable; +var _settings = __nested_webpack_require_42748__(23); -const BUFFER = Symbol('buffer'); -const TYPE = Symbol('type'); +var settings = _interopRequireWildcard(_settings); -class Blob { - constructor() { - this[TYPE] = ''; +var _relations = __nested_webpack_require_42748__(24); - const blobParts = arguments[0]; - const options = arguments[1]; +var relations = _interopRequireWildcard(_relations); - const buffers = []; - let size = 0; +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - if (blobParts) { - const a = blobParts; - const length = Number(a.length); - for (let i = 0; i < length; i++) { - const element = a[i]; - let buffer; - if (element instanceof Buffer) { - buffer = element; - } else if (ArrayBuffer.isView(element)) { - buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); - } else if (element instanceof ArrayBuffer) { - buffer = Buffer.from(element); - } else if (element instanceof Blob) { - buffer = element[BUFFER]; - } else { - buffer = Buffer.from(typeof element === 'string' ? element : String(element)); - } - size += buffer.length; - buffers.push(buffer); - } - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - this[BUFFER] = Buffer.concat(buffers); +var AppTokenV3 = auth.AppToken, + AccessTokenV3 = auth.AccessToken, + ClientV3 = auth.Client; - let type = options && options.type !== undefined && String(options.type).toLowerCase(); - if (type && !/[^\u0020-\u007E]/.test(type)) { - this[TYPE] = type; - } - } - get size() { - return this[BUFFER].length; - } - get type() { - return this[TYPE]; - } - text() { - return Promise.resolve(this[BUFFER].toString()); - } - arrayBuffer() { - const buf = this[BUFFER]; - const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - return Promise.resolve(ab); - } - stream() { - const readable = new Readable(); - readable._read = function () {}; - readable.push(this[BUFFER]); - readable.push(null); - return readable; - } - toString() { - return '[object Blob]'; - } - slice() { - const size = this.size; - const start = arguments[0]; - const end = arguments[1]; - let relativeStart, relativeEnd; - if (start === undefined) { - relativeStart = 0; - } else if (start < 0) { - relativeStart = Math.max(size + start, 0); - } else { - relativeStart = Math.min(start, size); - } - if (end === undefined) { - relativeEnd = size; - } else if (end < 0) { - relativeEnd = Math.max(size + end, 0); - } else { - relativeEnd = Math.min(end, size); - } - const span = Math.max(relativeEnd - relativeStart, 0); +var AuthNone = 0; +var AuthRunning = 1; +var AuthError = 2; +var AuthOK = 3; - const buffer = this[BUFFER]; - const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); - const blob = new Blob([], { type: arguments[2] }); - blob[BUFFER] = slicedBuffer; - return blob; - } -} +var defaultClientParams = { + softwareID: 'github.com/cozy/cozy-client-js' +}; -Object.defineProperties(Blob.prototype, { - size: { enumerable: true }, - type: { enumerable: true }, - slice: { enumerable: true } -}); +var dataProto = { + create: data.create, + find: data.find, + findMany: data.findMany, + findAll: data.findAll, + update: data.update, + delete: data._delete, + updateAttributes: data.updateAttributes, + changesFeed: data.changesFeed, + defineIndex: mango.defineIndex, + query: mango.query, + addReferencedFiles: relations.addReferencedFiles, + removeReferencedFiles: relations.removeReferencedFiles, + listReferencedFiles: relations.listReferencedFiles, + fetchReferencedFiles: relations.fetchReferencedFiles, + destroy: function destroy() { + (0, _utils.warn)('destroy is deprecated, use cozy.data.delete instead.'); + return data._delete.apply(data, arguments); + } +}; -Object.defineProperty(Blob.prototype, Symbol.toStringTag, { - value: 'Blob', - writable: false, - enumerable: false, - configurable: true -}); +var authProto = { + client: auth.client, + registerClient: auth.registerClient, + updateClient: auth.updateClient, + unregisterClient: auth.unregisterClient, + getClient: auth.getClient, + getAuthCodeURL: auth.getAuthCodeURL, + getAccessToken: auth.getAccessToken, + refreshToken: auth.refreshToken +}; -/** - * fetch-error.js - * - * FetchError interface for operational errors - */ +var filesProto = { + create: files.create, + createDirectory: files.createDirectory, + createDirectoryByPath: files.createDirectoryByPath, + updateById: files.updateById, + updateAttributesById: files.updateAttributesById, + updateAttributesByPath: files.updateAttributesByPath, + trashById: files.trashById, + statById: files.statById, + statByPath: files.statByPath, + downloadById: files.downloadById, + downloadByPath: files.downloadByPath, + getDownloadLinkById: files.getDownloadLinkById, + getDownloadLink: files.getDownloadLinkByPath, // DEPRECATED, should be removed very soon + getDownloadLinkByPath: files.getDownloadLinkByPath, + getArchiveLink: function getArchiveLink() { + (0, _utils.warn)('getArchiveLink is deprecated, use cozy.files.getArchiveLinkByPaths instead.'); + return files.getArchiveLinkByPaths.apply(files, arguments); + }, + getArchiveLinkByPaths: files.getArchiveLinkByPaths, + getArchiveLinkByIds: files.getArchiveLinkByIds, + getFilePath: files.getFilePath, + getCollectionShareLink: files.getCollectionShareLink, + query: mango.queryFiles, + listTrash: files.listTrash, + clearTrash: files.clearTrash, + restoreById: files.restoreById, + destroyById: files.destroyById +}; -/** - * Create FetchError instance - * - * @param String message Error message for human - * @param String type Error type for machine - * @param String systemError For Node.js system error - * @return FetchError - */ -function FetchError(message, type, systemError) { - Error.call(this, message); +var intentsProto = { + create: intents.create, + createService: intents.createService, + getRedirectionURL: intents.getRedirectionURL, + redirect: intents.redirect +}; - this.message = message; - this.type = type; +var jobsProto = { + create: jobs.create, + count: jobs.count, + queued: jobs.queued +}; - // when err.type is `system`, err.code contains system error code - if (systemError) { - this.code = this.errno = systemError.code; - } +var offlineProto = { + init: offline.init, + getDoctypes: offline.getDoctypes, + // database + hasDatabase: offline.hasDatabase, + getDatabase: offline.getDatabase, + createDatabase: offline.createDatabase, + migrateDatabase: offline.migrateDatabase, + destroyDatabase: offline.destroyDatabase, + destroyAllDatabase: offline.destroyAllDatabase, + // replication + hasReplication: offline.hasReplication, + replicateFromCozy: offline.replicateFromCozy, + stopReplication: offline.stopReplication, + stopAllReplication: offline.stopAllReplication, + // repeated replication + hasRepeatedReplication: offline.hasRepeatedReplication, + startRepeatedReplication: offline.startRepeatedReplication, + stopRepeatedReplication: offline.stopRepeatedReplication, + stopAllRepeatedReplication: offline.stopAllRepeatedReplication +}; - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); -} +var settingsProto = { + diskUsage: settings.diskUsage, + changePassphrase: settings.changePassphrase, + getInstance: settings.getInstance, + updateInstance: settings.updateInstance, + getClients: settings.getClients, + deleteClientById: settings.deleteClientById, + updateLastSync: settings.updateLastSync +}; -FetchError.prototype = Object.create(Error.prototype); -FetchError.prototype.constructor = FetchError; -FetchError.prototype.name = 'FetchError'; +var ensureHasReconnectParam = function ensureHasReconnectParam(_url) { + var url = new URL(_url); + if (url.searchParams && !url.searchParams.has('reconnect')) { + url.searchParams.append('reconnect', 1); + } else if (!url.search || url.search.indexOf('reconnect') === -1) { + // Some old navigators do not have the searchParams API + // and it is not polyfilled by babel-polyfill + url.search = url.search + '&reconnect=1'; + } + return url.toString(); +}; -let convert; -try { - convert = require('encoding').convert; -} catch (e) {} +var Client = function () { + function Client(options) { + _classCallCheck(this, Client); -const INTERNALS = Symbol('Body internals'); + this.data = {}; + this.files = {}; + this.intents = {}; + this.jobs = {}; + this.offline = {}; + this.settings = {}; + this.auth = { + Client: ClientV3, + AccessToken: AccessTokenV3, + AppToken: AppTokenV3, + AppTokenV2: _auth_v.AppToken, + LocalStorage: _auth_storage.LocalStorage, + MemoryStorage: _auth_storage.MemoryStorage + }; + this._inited = false; + if (options) { + this.init(options); + } + } -// fix an issue where "PassThrough" isn't a named export for node <10 -const PassThrough = stream__WEBPACK_IMPORTED_MODULE_0__.PassThrough; + _createClass(Client, [{ + key: 'init', + value: function init() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; -/** - * Body mixin - * - * Ref: https://fetch.spec.whatwg.org/#body - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -function Body(body) { - var _this = this; + this._inited = true; + this._oauth = false; // is oauth activated or not + this._token = null; // application token + this._authstate = AuthNone; + this._authcreds = null; + this._storage = null; + this._version = options.version || null; + this._offline = null; - var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, - _ref$size = _ref.size; + var token = options.token; + var oauth = options.oauth; + if (token && oauth) { + throw new Error('Cannot specify an application token with a oauth activated'); + } - let size = _ref$size === undefined ? 0 : _ref$size; - var _ref$timeout = _ref.timeout; - let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; + if (token) { + this._token = new AppTokenV3({ token: token }); + } else if (oauth) { + this._oauth = true; + this._storage = oauth.storage; + this._clientParams = Object.assign({}, defaultClientParams, oauth.clientParams); + this._onRegistered = oauth.onRegistered || nopOnRegistered; + } - if (body == null) { - // body is undefined or null - body = null; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - body = Buffer.from(body.toString()); - } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - body = Buffer.from(body); - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); - } else if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) ; else { - // none of the above - // coerce to string then buffer - body = Buffer.from(String(body)); - } - this[INTERNALS] = { - body, - disturbed: false, - error: null - }; - this.size = size; - this.timeout = timeout; + var url = options.cozyURL || ''; + while (url[url.length - 1] === '/') { + url = url.slice(0, -1); + } - if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) { - body.on('error', function (err) { - const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); - _this[INTERNALS].error = error; - }); - } -} + this._url = url; -Body.prototype = { - get body() { - return this[INTERNALS].body; - }, + this._invalidTokenErrorHandler = options.onInvalidTokenError !== undefined ? options.onInvalidTokenError : cozyFetch.handleInvalidTokenError; - get bodyUsed() { - return this[INTERNALS].disturbed; - }, + var disablePromises = !!options.disablePromises; + addToProto(this, this.data, dataProto, disablePromises); + addToProto(this, this.auth, authProto, disablePromises); + addToProto(this, this.files, filesProto, disablePromises); + addToProto(this, this.intents, intentsProto, disablePromises); + addToProto(this, this.jobs, jobsProto, disablePromises); + addToProto(this, this.offline, offlineProto, disablePromises); + addToProto(this, this.settings, settingsProto, disablePromises); - /** - * Decode response as ArrayBuffer - * - * @return Promise - */ - arrayBuffer() { - return consumeBody.call(this).then(function (buf) { - return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - }); - }, + if (options.offline) { + this.offline.init(options.offline); + } - /** - * Return raw response as Blob - * - * @return Promise - */ - blob() { - let ct = this.headers && this.headers.get('content-type') || ''; - return consumeBody.call(this).then(function (buf) { - return Object.assign( - // Prevent copying - new Blob([], { - type: ct.toLowerCase() - }), { - [BUFFER]: buf - }); - }); - }, + this.fetch = function _fetch(method, url) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - /** - * Decode response as json - * - * @return Promise - */ - json() { - var _this2 = this; + return cozyFetch.cozyFetch(this, url, _extends({}, options, { method: method })); + }; - return consumeBody.call(this).then(function (buffer) { - try { - return JSON.parse(buffer.toString()); - } catch (err) { - return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); - } - }); - }, + this.fetchJSON = function _fetchJSON() { + var args = [this].concat(Array.prototype.slice.call(arguments)); + return cozyFetch.cozyFetchJSON.apply(this, args); + }; + } + }, { + key: 'authorize', + value: function authorize() { + var _this = this; - /** - * Decode response as text - * - * @return Promise - */ - text() { - return consumeBody.call(this).then(function (buffer) { - return buffer.toString(); - }); - }, + var forceTokenRefresh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - /** - * Decode response as buffer (non-spec api) - * - * @return Promise - */ - buffer() { - return consumeBody.call(this); - }, + var state = this._authstate; + if (state === AuthOK || state === AuthRunning) { + return this._authcreds; + } - /** - * Decode response as text, while automatically detecting the encoding and - * trying to decode to UTF-8 (non-spec api) - * - * @return Promise - */ - textConverted() { - var _this3 = this; + this._authstate = AuthRunning; + this._authcreds = this.isV2().then(function (isV2) { + if (isV2 && _this._oauth) { + throw new Error('OAuth is not supported on the V2 stack'); + } + if (_this._oauth) { + if (forceTokenRefresh && _this._clientParams.redirectURI) { + _this._clientParams.redirectURI = ensureHasReconnectParam(_this._clientParams.redirectURI); + } + return auth.oauthFlow(_this, _this._storage, _this._clientParams, _this._onRegistered, forceTokenRefresh); + } + // we expect to be on a client side application running in a browser + // with cookie-based authentication. + if (isV2) { + return (0, _auth_v.getAppToken)(); + } else if (_this._token) { + return Promise.resolve({ client: null, token: _this._token }); + } else { + throw new Error('Missing application token'); + } + }); - return consumeBody.call(this).then(function (buffer) { - return convertBody(buffer, _this3.headers); - }); - } -}; + this._authcreds.then(function () { + _this._authstate = AuthOK; + }, function () { + _this._authstate = AuthError; + }); -// In browsers, all properties are enumerable. -Object.defineProperties(Body.prototype, { - body: { enumerable: true }, - bodyUsed: { enumerable: true }, - arrayBuffer: { enumerable: true }, - blob: { enumerable: true }, - json: { enumerable: true }, - text: { enumerable: true } -}); + return this._authcreds; + } + }, { + key: 'saveCredentials', + value: function saveCredentials(client, token) { + var creds = { client: client, token: token }; + if (!this._storage || this._authstate === AuthRunning) { + return Promise.resolve(creds); + } + this._storage.save(auth.CredsKey, creds); + this._authcreds = Promise.resolve(creds); + return this._authcreds; + } + }, { + key: 'fullpath', + value: function fullpath(path) { + var _this2 = this; -Body.mixIn = function (proto) { - for (const name of Object.getOwnPropertyNames(Body.prototype)) { - // istanbul ignore else: future proof - if (!(name in proto)) { - const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); - Object.defineProperty(proto, name, desc); - } - } -}; + return this.isV2().then(function (isV2) { + var pathprefix = isV2 ? '/ds-api' : ''; + return _this2._url + pathprefix + path; + }); + } + }, { + key: 'isV2', + value: function isV2() { + var _this3 = this; -/** - * Consume and convert an entire Body to a Buffer. - * - * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body - * - * @return Promise - */ -function consumeBody() { - var _this4 = this; + if (!this._version) { + return (0, _utils.retry)(function () { + return fetch(_this3._url + '/status/'); + }, 3)().then(function (res) { + if (!res.ok) { + throw new Error('Could not fetch cozy status'); + } else { + return res.json(); + } + }).then(function (status) { + _this3._version = status.datasystem !== undefined ? 2 : 3; + return _this3.isV2(); + }); + } + return Promise.resolve(this._version === 2); + } + }]); - if (this[INTERNALS].disturbed) { - return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); - } + return Client; +}(); - this[INTERNALS].disturbed = true; +function nopOnRegistered() { + throw new Error('Missing onRegistered callback'); +} - if (this[INTERNALS].error) { - return Body.Promise.reject(this[INTERNALS].error); - } +function protoify(context, fn) { + return function prototyped() { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } - let body = this.body; + return fn.apply(undefined, [context].concat(args)); + }; +} - // body is null - if (body === null) { - return Body.Promise.resolve(Buffer.alloc(0)); - } +function addToProto(ctx, obj, proto, disablePromises) { + for (var attr in proto) { + var fn = protoify(ctx, proto[attr]); + if (disablePromises) { + fn = (0, _utils.unpromiser)(fn); + } + obj[attr] = fn; + } +} - // body is blob - if (isBlob(body)) { - body = body.stream(); - } +module.exports = new Client(); +Object.assign(module.exports, { Client: Client, LocalStorage: _auth_storage.LocalStorage, MemoryStorage: _auth_storage.MemoryStorage }); - // body is buffer - if (Buffer.isBuffer(body)) { - return Body.Promise.resolve(body); - } +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { - // istanbul ignore if: should never happen - if (!(body instanceof stream__WEBPACK_IMPORTED_MODULE_0__)) { - return Body.Promise.resolve(Buffer.alloc(0)); - } +"use strict"; - // body is stream - // get ready to actually consume the body - let accum = []; - let accumBytes = 0; - let abort = false; - return new Body.Promise(function (resolve, reject) { - let resTimeout; +Object.defineProperty(exports, "__esModule", { + value: true +}); - // allow timeout on slow response body - if (_this4.timeout) { - resTimeout = setTimeout(function () { - abort = true; - reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); - }, _this4.timeout); - } +var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - // handle stream errors - body.on('error', function (err) { - if (err.name === 'AbortError') { - // if the request was aborted, reject with this Error - abort = true; - reject(err); - } else { - // other errors, such as incorrect content-encoding - reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); - } - }); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - body.on('data', function (chunk) { - if (abort || chunk === null) { - return; - } +var LocalStorage = exports.LocalStorage = function () { + function LocalStorage(storage, prefix) { + _classCallCheck(this, LocalStorage); - if (_this4.size && accumBytes + chunk.length > _this4.size) { - abort = true; - reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); - return; - } + if (!storage && typeof window !== 'undefined') { + storage = window.localStorage; + } + this.storage = storage; + this.prefix = prefix || 'cozy:oauth:'; + } - accumBytes += chunk.length; - accum.push(chunk); - }); + _createClass(LocalStorage, [{ + key: 'save', + value: function save(key, value) { + var _this = this; - body.on('end', function () { - if (abort) { - return; - } + return new Promise(function (resolve) { + _this.storage.setItem(_this.prefix + key, JSON.stringify(value)); + resolve(value); + }); + } + }, { + key: 'load', + value: function load(key) { + var _this2 = this; - clearTimeout(resTimeout); + return new Promise(function (resolve) { + var item = _this2.storage.getItem(_this2.prefix + key); + if (!item) { + resolve(); + } else { + resolve(JSON.parse(item)); + } + }); + } + }, { + key: 'delete', + value: function _delete(key) { + var _this3 = this; - try { - resolve(Buffer.concat(accum, accumBytes)); - } catch (err) { - // handle streams that have accumulated too much data (issue #414) - reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); - } - }); - }); -} + return new Promise(function (resolve) { + return resolve(_this3.storage.removeItem(_this3.prefix + key)); + }); + } + }, { + key: 'clear', + value: function clear() { + var _this4 = this; -/** - * Detect buffer encoding and convert to target encoding - * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding - * - * @param Buffer buffer Incoming buffer - * @param String encoding Target encoding - * @return String - */ -function convertBody(buffer, headers) { - if (typeof convert !== 'function') { - throw new Error('The package `encoding` must be installed to use the textConverted() function'); - } + return new Promise(function (resolve) { + var storage = _this4.storage; + for (var i = 0; i < storage.length; i++) { + var key = storage.key(i); + if (key.indexOf(_this4.prefix) === 0) { + storage.removeItem(key); + } + } + resolve(); + }); + } + }]); - const ct = headers.get('content-type'); - let charset = 'utf-8'; - let res, str; + return LocalStorage; +}(); - // header - if (ct) { - res = /charset=([^;]*)/i.exec(ct); - } +var MemoryStorage = exports.MemoryStorage = function () { + function MemoryStorage() { + _classCallCheck(this, MemoryStorage); - // no charset in content type, peek at response body for at most 1024 bytes - str = buffer.slice(0, 1024).toString(); + this.hash = Object.create(null); + } - // html5 - if (!res && str) { - res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str); - } + _createClass(MemoryStorage, [{ + key: 'save', + value: function save(key, value) { + this.hash[key] = value; + return Promise.resolve(value); + } + }, { + key: 'load', + value: function load(key) { + return Promise.resolve(this.hash[key]); + } + }, { + key: 'delete', + value: function _delete(key) { + var deleted = delete this.hash[key]; + return Promise.resolve(deleted); + } + }, { + key: 'clear', + value: function clear() { + this.hash = Object.create(null); + return Promise.resolve(); + } + }]); - // html4 - if (!res && str) { - res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str); - if (!res) { - res = /<meta[\s]+?content=(['"])(.+?)\1[\s]+?http-equiv=(['"])content-type\3/i.exec(str); - if (res) { - res.pop(); // drop last quote - } - } + return MemoryStorage; +}(); - if (res) { - res = /charset=(.*)/i.exec(res.pop()); - } - } +/***/ }), +/* 11 */ +/***/ (function(module, exports, __nested_webpack_require_58943__) { - // xml - if (!res && str) { - res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str); - } +"use strict"; +/* WEBPACK VAR INJECTION */(function(btoa) { - // found charset - if (res) { - charset = res.pop(); +Object.defineProperty(exports, "__esModule", { + value: true +}); - // prevent decode issues when sites use incorrect encoding - // ref: https://hsivonen.fi/encoding-menu/ - if (charset === 'gb2312' || charset === 'gbk') { - charset = 'gb18030'; - } - } +var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - // turn raw buffers into a single utf-8 buffer - return convert(buffer, 'UTF-8', charset).toString(); -} +exports.getAppToken = getAppToken; -/** - * Detect a URLSearchParams object - * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 - * - * @param Object obj Object to detect by type or brand - * @return String - */ -function isURLSearchParams(obj) { - // Duck-typing as a necessary condition. - if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { - return false; - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - // Brand-checking and more duck-typing as optional condition. - return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; -} +/* global btoa */ +var V2TOKEN_ABORT_TIMEOUT = 3000; -/** - * Check if `obj` is a W3C `Blob` object (which `File` inherits from) - * @param {*} obj - * @return {boolean} - */ -function isBlob(obj) { - return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); +function getAppToken() { + return new Promise(function (resolve, reject) { + if (typeof window === 'undefined') { + return reject(new Error('getV2Token should be used in browser')); + } else if (!window.parent) { + return reject(new Error('getV2Token should be used in iframe')); + } else if (!window.parent.postMessage) { + return reject(new Error('getV2Token should be used in modern browser')); + } + var origin = window.location.origin; + var intent = { action: 'getToken' }; + var timeout = null; + var receiver = function receiver(event) { + var token = void 0; + try { + token = new AppToken({ + appName: event.data.appName, + token: event.data.token + }); + } catch (e) { + reject(e); + return; + } + window.removeEventListener('message', receiver); + clearTimeout(timeout); + resolve({ client: null, token: token }); + }; + window.addEventListener('message', receiver, false); + window.parent.postMessage(intent, origin); + timeout = setTimeout(function () { + reject(new Error('No response from parent iframe after 3s')); + }, V2TOKEN_ABORT_TIMEOUT); + }); } -/** - * Clone body given Res/Req instance - * - * @param Mixed instance Response or Request instance - * @return Mixed - */ -function clone(instance) { - let p1, p2; - let body = instance.body; - - // don't allow cloning a used body - if (instance.bodyUsed) { - throw new Error('cannot clone body after it is used'); - } - - // check that body is a stream and not form-data object - // note: we can't clone the form-data object without having it as a dependency - if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__ && typeof body.getBoundary !== 'function') { - // tee instance body - p1 = new PassThrough(); - p2 = new PassThrough(); - body.pipe(p1); - body.pipe(p2); - // set instance body to teed body and return the other teed body - instance[INTERNALS].body = p1; - body = p2; - } +var AppToken = exports.AppToken = function () { + function AppToken(opts) { + _classCallCheck(this, AppToken); - return body; -} + this.appName = opts.appName || ''; + this.token = opts.token || ''; + } -/** - * Performs the operation "extract a `Content-Type` value from |object|" as - * specified in the specification: - * https://fetch.spec.whatwg.org/#concept-bodyinit-extract - * - * This function assumes that instance.body is present. - * - * @param Mixed instance Any options.body input - */ -function extractContentType(body) { - if (body === null) { - // body is null - return null; - } else if (typeof body === 'string') { - // body is string - return 'text/plain;charset=UTF-8'; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - return 'application/x-www-form-urlencoded;charset=UTF-8'; - } else if (isBlob(body)) { - // body is blob - return body.type || null; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return null; - } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - return null; - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - return null; - } else if (typeof body.getBoundary === 'function') { - // detect form data input from form-data module - return `multipart/form-data;boundary=${body.getBoundary()}`; - } else if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) { - // body is stream - // can't really do much about this - return null; - } else { - // Body constructor defaults other things to string - return 'text/plain;charset=UTF-8'; - } -} + _createClass(AppToken, [{ + key: 'toAuthHeader', + value: function toAuthHeader() { + return 'Basic ' + btoa(this.appName + ':' + this.token); + } + }]); -/** - * The Fetch Standard treats this as if "total bytes" is a property on the body. - * For us, we have to explicitly get it with a function. - * - * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes - * - * @param Body instance Instance of Body - * @return Number? Number of bytes, or null if not possible - */ -function getTotalBytes(instance) { - const body = instance.body; + return AppToken; +}(); +/* WEBPACK VAR INJECTION */}.call(exports, __nested_webpack_require_58943__(6))) +/***/ }), +/* 12 */ +/***/ (function(module, exports) { - if (body === null) { - // body is null - return 0; - } else if (isBlob(body)) { - return body.size; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return body.length; - } else if (body && typeof body.getLengthSync === 'function') { - // detect form data input from form-data module - if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x - body.hasKnownLength && body.hasKnownLength()) { - // 2.x - return body.getLengthSync(); - } - return null; - } else { - // body is stream - return null; - } -} +module.exports = __webpack_require__(76); -/** - * Write a Body to a Node.js WritableStream (e.g. http.Request) object. - * - * @param Body instance Instance of Body - * @return Void - */ -function writeToStream(dest, instance) { - const body = instance.body; +/***/ }), +/* 13 */ +/***/ (function(module, exports, __nested_webpack_require_61680__) { +"use strict"; - if (body === null) { - // body is null - dest.end(); - } else if (isBlob(body)) { - body.stream().pipe(dest); - } else if (Buffer.isBuffer(body)) { - // body is buffer - dest.write(body); - dest.end(); - } else { - // body is stream - body.pipe(dest); - } -} -// expose Promise -Body.Promise = global.Promise; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.create = create; +exports.find = find; +exports.findMany = findMany; +exports.findAll = findAll; +exports.changesFeed = changesFeed; +exports.update = update; +exports.updateAttributes = updateAttributes; +exports._delete = _delete; -/** - * headers.js - * - * Headers class offers convenient helpers - */ +var _utils = __nested_webpack_require_61680__(1); -const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; -const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; +var _doctypes = __nested_webpack_require_61680__(2); -function validateName(name) { - name = `${name}`; - if (invalidTokenRegex.test(name) || name === '') { - throw new TypeError(`${name} is not a legal HTTP header name`); - } -} +var _fetch = __nested_webpack_require_61680__(0); -function validateValue(value) { - value = `${value}`; - if (invalidHeaderCharRegex.test(value)) { - throw new TypeError(`${value} is not a legal HTTP header value`); - } +var NOREV = 'stack-v2-no-rev'; + +function create(cozy, doctype, attributes) { + return cozy.isV2().then(function (isV2) { + doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); + if (isV2) { + attributes.docType = doctype; + } + var path = (0, _utils.createPath)(cozy, isV2, doctype, attributes._id); + var httpVerb = attributes._id ? 'PUT' : 'POST'; + delete attributes._id; + return (0, _fetch.cozyFetchJSON)(cozy, httpVerb, path, attributes).then(function (resp) { + if (isV2) { + return find(cozy, doctype, resp._id); + } else { + return resp.data; + } + }); + }); } -/** - * Find the key in the map object given a header name. - * - * Returns undefined if not found. - * - * @param String name Header name - * @return String|Undefined - */ -function find(map, name) { - name = name.toLowerCase(); - for (const key in map) { - if (key.toLowerCase() === name) { - return key; - } - } - return undefined; +function find(cozy, doctype, id) { + return cozy.isV2().then(function (isV2) { + doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); + + if (!id) { + return Promise.reject(new Error('Missing id parameter')); + } + + var path = (0, _utils.createPath)(cozy, isV2, doctype, id); + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', path).then(function (resp) { + if (isV2) { + return Object.assign(resp, { _rev: NOREV }); + } else { + return resp; + } + }); + }); } -const MAP = Symbol('map'); -class Headers { - /** - * Headers class - * - * @param Object headers Response headers - * @return Void - */ - constructor() { - let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; +function findMany(cozy, doctype, ids) { + if (!(ids instanceof Array)) { + return Promise.reject(new Error('Parameter ids must be a non-empty array')); + } + if (ids.length === 0) { + // So users don't need to be defensive regarding the array content. + // This should not hide issues in user code since the result will be an + // empty object anyway. + return Promise.resolve({}); + } - this[MAP] = Object.create(null); + return cozy.isV2().then(function (isV2) { + if (isV2) { + return Promise.reject(new Error('findMany is not available on v2')); + } - if (init instanceof Headers) { - const rawHeaders = init.raw(); - const headerNames = Object.keys(rawHeaders); + var path = (0, _utils.createPath)(cozy, isV2, doctype, '_all_docs', { + include_docs: true + }); - for (const headerName of headerNames) { - for (const value of rawHeaders[headerName]) { - this.append(headerName, value); - } - } + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, { keys: ids }).then(function (resp) { + var docs = {}; - return; - } + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - // We don't worry about converting prop to ByteString here as append() - // will handle it. - if (init == null) ; else if (typeof init === 'object') { - const method = init[Symbol.iterator]; - if (method != null) { - if (typeof method !== 'function') { - throw new TypeError('Header pairs must be iterable'); - } + try { + for (var _iterator = resp.rows[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var row = _step.value; + var key = row.key, + doc = row.doc, + error = row.error; - // sequence<sequence<ByteString>> - // Note: per spec we have to first exhaust the lists then process them - const pairs = []; - for (const pair of init) { - if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { - throw new TypeError('Each header pair must be iterable'); - } - pairs.push(Array.from(pair)); - } + docs[key] = error ? { error: error } : { doc: doc }; + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } - for (const pair of pairs) { - if (pair.length !== 2) { - throw new TypeError('Each header pair must be a name/value tuple'); - } - this.append(pair[0], pair[1]); - } - } else { - // record<ByteString, ByteString> - for (const key of Object.keys(init)) { - const value = init[key]; - this.append(key, value); - } - } - } else { - throw new TypeError('Provided initializer must be an object'); - } - } + return docs; + }).catch(function (error) { + if (error.status !== 404) return Promise.reject(error); - /** - * Return combined header value given name - * - * @param String name Header name - * @return Mixed - */ - get(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key === undefined) { - return null; - } + // When no doc was ever created and the database does not exist yet, + // the response will be a 404 error. + var docs = {}; - return this[MAP][key].join(', '); - } + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; - /** - * Iterate over all headers - * - * @param Function callback Executed for each item with parameters (value, name, thisArg) - * @param Boolean thisArg `this` context for callback function - * @return Void - */ - forEach(callback) { - let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + try { + for (var _iterator2 = ids[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var id = _step2.value; - let pairs = getHeaders(this); - let i = 0; - while (i < pairs.length) { - var _pairs$i = pairs[i]; - const name = _pairs$i[0], - value = _pairs$i[1]; + docs[id] = { error: error }; + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } - callback.call(thisArg, value, name, this); - pairs = getHeaders(this); - i++; - } - } + return docs; + }); + }); +} - /** - * Overwrite header values given name - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - set(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - this[MAP][key !== undefined ? key : name] = [value]; - } +function findAll(cozy, doctype) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { include_docs: true }; - /** - * Append a value onto existing header - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - append(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - if (key !== undefined) { - this[MAP][key].push(value); - } else { - this[MAP][name] = [value]; - } - } + return cozy.isV2().then(function (isV2) { + if (isV2) { + return Promise.reject(new Error('findAll is not available on v2')); + } - /** - * Check for header name existence - * - * @param String name Header name - * @return Boolean - */ - has(name) { - name = `${name}`; - validateName(name); - return find(this[MAP], name) !== undefined; - } + var path = (0, _utils.createPath)(cozy, isV2, doctype, '_all_docs', options); - /** - * Delete all header values given name - * - * @param String name Header name - * @return Void - */ - delete(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key !== undefined) { - delete this[MAP][key]; - } - } + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, {}).then(function (resp) { + var docs = []; - /** - * Return raw headers (non-spec api) - * - * @return Object - */ - raw() { - return this[MAP]; - } + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; - /** - * Get an iterator on keys. - * - * @return Iterator - */ - keys() { - return createHeadersIterator(this, 'key'); - } + try { + for (var _iterator3 = resp.rows[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var row = _step3.value; + var doc = row.doc; + // if not couchDB indexes - /** - * Get an iterator on values. - * - * @return Iterator - */ - values() { - return createHeadersIterator(this, 'value'); - } + if (!doc._id.match(/_design\//)) docs.push(doc); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } - /** - * Get an iterator on entries. - * - * This is the default iterator of the Headers object. - * - * @return Iterator - */ - [Symbol.iterator]() { - return createHeadersIterator(this, 'key+value'); - } + return docs; + }).catch(function (error) { + // the _all_docs endpoint returns a 404 error if no document with the given + // doctype exists. + if (error.status === 404) return []; + throw error; + }); + }); } -Headers.prototype.entries = Headers.prototype[Symbol.iterator]; -Object.defineProperty(Headers.prototype, Symbol.toStringTag, { - value: 'Headers', - writable: false, - enumerable: false, - configurable: true -}); +function changesFeed(cozy, doctype, options) { + return cozy.isV2().then(function (isV2) { + doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); + var path = (0, _utils.createPath)(cozy, isV2, doctype, '_changes', options); + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', path); + }); +} -Object.defineProperties(Headers.prototype, { - get: { enumerable: true }, - forEach: { enumerable: true }, - set: { enumerable: true }, - append: { enumerable: true }, - has: { enumerable: true }, - delete: { enumerable: true }, - keys: { enumerable: true }, - values: { enumerable: true }, - entries: { enumerable: true } -}); +function update(cozy, doctype, doc, changes) { + return cozy.isV2().then(function (isV2) { + doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); + var _id = doc._id, + _rev = doc._rev; -function getHeaders(headers) { - let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; - const keys = Object.keys(headers[MAP]).sort(); - return keys.map(kind === 'key' ? function (k) { - return k.toLowerCase(); - } : kind === 'value' ? function (k) { - return headers[MAP][k].join(', '); - } : function (k) { - return [k.toLowerCase(), headers[MAP][k].join(', ')]; - }); + if (!_id) { + return Promise.reject(new Error('Missing _id field in passed document')); + } + + if (!isV2 && !_rev) { + return Promise.reject(new Error('Missing _rev field in passed document')); + } + + if (isV2) { + changes = Object.assign({ _id: _id }, changes); + } else { + changes = Object.assign({ _id: _id, _rev: _rev }, changes); + } + + var path = (0, _utils.createPath)(cozy, isV2, doctype, _id); + return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', path, changes).then(function (resp) { + if (isV2) { + return find(cozy, doctype, _id); + } else { + return resp.data; + } + }); + }); } -const INTERNAL = Symbol('internal'); +function updateAttributes(cozy, doctype, _id, changes) { + var tries = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 3; -function createHeadersIterator(target, kind) { - const iterator = Object.create(HeadersIteratorPrototype); - iterator[INTERNAL] = { - target, - kind, - index: 0 - }; - return iterator; + return cozy.isV2().then(function (isV2) { + doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); + return find(cozy, doctype, _id).then(function (doc) { + return update(cozy, doctype, doc, Object.assign({ _id: _id }, doc, changes)); + }).catch(function (err) { + if (tries > 0) { + return updateAttributes(cozy, doctype, _id, changes, tries - 1); + } else { + throw err; + } + }); + }); } -const HeadersIteratorPrototype = Object.setPrototypeOf({ - next() { - // istanbul ignore if - if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { - throw new TypeError('Value of `this` is not a HeadersIterator'); - } +function _delete(cozy, doctype, doc) { + return cozy.isV2().then(function (isV2) { + doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); + var _id = doc._id, + _rev = doc._rev; - var _INTERNAL = this[INTERNAL]; - const target = _INTERNAL.target, - kind = _INTERNAL.kind, - index = _INTERNAL.index; - const values = getHeaders(target, kind); - const len = values.length; - if (index >= len) { - return { - value: undefined, - done: true - }; - } + if (!_id) { + return Promise.reject(new Error('Missing _id field in passed document')); + } - this[INTERNAL].index = index + 1; + if (!isV2 && !_rev) { + return Promise.reject(new Error('Missing _rev field in passed document')); + } - return { - value: values[index], - done: false - }; - } -}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + var query = isV2 ? null : { rev: _rev }; + var path = (0, _utils.createPath)(cozy, isV2, doctype, _id, query); + return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', path).then(function (resp) { + if (isV2) { + return { id: _id, rev: NOREV }; + } else { + return resp; + } + }); + }); +} -Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { - value: 'HeadersIterator', - writable: false, - enumerable: false, - configurable: true +/***/ }), +/* 14 */ +/***/ (function(module, exports, __nested_webpack_require_69980__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true }); -/** - * Export the Headers object in a form that Node.js can consume. - * - * @param Headers headers - * @return Object - */ -function exportNodeCompatibleHeaders(headers) { - const obj = Object.assign({ __proto__: null }, headers[MAP]); +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - // http.request() only supports string as Host header. This hack makes - // specifying custom Host header possible. - const hostHeaderKey = find(headers[MAP], 'Host'); - if (hostHeaderKey !== undefined) { - obj[hostHeaderKey] = obj[hostHeaderKey][0]; - } +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - return obj; -} +exports.defineIndex = defineIndex; +exports.query = query; +exports.queryFiles = queryFiles; +exports.parseSelector = parseSelector; +exports.normalizeSelector = normalizeSelector; +exports.makeMapReduceQuery = makeMapReduceQuery; -/** - * Create a Headers object from an object of headers, ignoring those that do - * not conform to HTTP grammar productions. - * - * @param Object obj Object of headers - * @return Headers - */ -function createHeadersLenient(obj) { - const headers = new Headers(); - for (const name of Object.keys(obj)) { - if (invalidTokenRegex.test(name)) { - continue; - } - if (Array.isArray(obj[name])) { - for (const val of obj[name]) { - if (invalidHeaderCharRegex.test(val)) { - continue; - } - if (headers[MAP][name] === undefined) { - headers[MAP][name] = [val]; - } else { - headers[MAP][name].push(val); - } - } - } else if (!invalidHeaderCharRegex.test(obj[name])) { - headers[MAP][name] = [obj[name]]; - } - } - return headers; -} +var _utils = __nested_webpack_require_69980__(1); -const INTERNALS$1 = Symbol('Response internals'); +var _doctypes = __nested_webpack_require_69980__(2); -// fix an issue where "STATUS_CODES" aren't a named export for node <10 -const STATUS_CODES = http__WEBPACK_IMPORTED_MODULE_1__.STATUS_CODES; +var _fetch = __nested_webpack_require_69980__(0); -/** - * Response class - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -class Response { - constructor() { - let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - Body.call(this, body, opts); +function defineIndex(cozy, doctype, fields) { + return cozy.isV2().then(function (isV2) { + doctype = (0, _doctypes.normalizeDoctype)(cozy, isV2, doctype); + if (!Array.isArray(fields) || fields.length === 0) { + throw new Error('defineIndex fields should be a non-empty array'); + } + if (isV2) { + return defineIndexV2(cozy, doctype, fields); + } else { + return defineIndexV3(cozy, doctype, fields); + } + }); +} - const status = opts.status || 200; - const headers = new Headers(opts.headers); +function query(cozy, indexRef, options) { + return cozy.isV2().then(function (isV2) { + if (!indexRef) { + throw new Error('query should be passed the indexRef'); + } + if (isV2) { + return queryV2(cozy, indexRef, options); + } else { + return queryV3(cozy, indexRef, options); + } + }); +} - if (body != null && !headers.has('Content-Type')) { - const contentType = extractContentType(body); - if (contentType) { - headers.append('Content-Type', contentType); - } - } +function queryFiles(cozy, indexRef, options) { + var opts = getV3Options(indexRef, options); + return (0, _fetch.cozyFetchRawJSON)(cozy, 'POST', '/files/_find', opts).then(function (response) { + return options.wholeResponse ? response : response.docs; + }); +} - this[INTERNALS$1] = { - url: opts.url, - status, - statusText: opts.statusText || STATUS_CODES[status], - headers, - counter: opts.counter - }; - } +// Internals - get url() { - return this[INTERNALS$1].url || ''; - } +var VALUEOPERATORS = ['$eq', '$gt', '$gte', '$lt', '$lte']; +var LOGICOPERATORS = ['$or', '$and', '$not']; - get status() { - return this[INTERNALS$1].status; - } +/* eslint-disable */ +var MAP_TEMPLATE = function (doc) { + if (doc.docType.toLowerCase() === 'DOCTYPEPLACEHOLDER') { + emit(FIELDSPLACEHOLDER, doc); + } +}.toString().replace(/ /g, '').replace(/\n/g, ''); +var COUCHDB_INFINITY = { '\uFFFF': '\uFFFF' }; +var COUCHDB_LOWEST = null; +/* eslint-enable */ - /** - * Convenience property representing if the request ended normally - */ - get ok() { - return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; - } +// defineIndexV2 is equivalent to defineIndex but only works for V2. +// It transforms the index fields into a map reduce view. +function defineIndexV2(cozy, doctype, fields) { + var indexName = 'by' + fields.map(capitalize).join(''); + var indexDefinition = { + map: makeMapFunction(doctype, fields), + reduce: '_count' + }; + var path = '/request/' + doctype + '/' + indexName + '/'; + return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', path, indexDefinition).then(function () { + return { + doctype: doctype, + type: 'mapreduce', + name: indexName, + fields: fields + }; + }); +} - get redirected() { - return this[INTERNALS$1].counter > 0; - } +function defineIndexV3(cozy, doctype, fields) { + var path = (0, _utils.createPath)(cozy, false, doctype, '_index'); + var indexDefinition = { index: { fields: fields } }; + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, indexDefinition).then(function (response) { + var indexResult = { + doctype: doctype, + type: 'mango', + name: response.id, + fields: fields + }; - get statusText() { - return this[INTERNALS$1].statusText; - } + if (response.result === 'exists') return indexResult; - get headers() { - return this[INTERNALS$1].headers; - } + // indexes might not be usable right after being created; so we delay the resolving until they are + var selector = {}; + selector[fields[0]] = { $gt: null }; - /** - * Clone this response - * - * @return Response - */ - clone() { - return new Response(clone(this), { - url: this.url, - status: this.status, - statusText: this.statusText, - headers: this.headers, - ok: this.ok, - redirected: this.redirected - }); - } + var opts = getV3Options(indexResult, { selector: selector }); + var path = (0, _utils.createPath)(cozy, false, indexResult.doctype, '_find'); + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function () { + return indexResult; + }).catch(function () { + // one retry + return (0, _utils.sleep)(1000).then(function () { + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts); + }).then(function () { + return indexResult; + }).catch(function () { + return (0, _utils.sleep)(500).then(function () { + return indexResult; + }); + }); + }); + }); } -Body.mixIn(Response.prototype); +// queryV2 is equivalent to query but only works for V2. +// It transforms the query into a _views call using makeMapReduceQuery +function queryV2(cozy, indexRef, options) { + if (indexRef.type !== 'mapreduce') { + throw new Error('query indexRef should be the return value of defineIndexV2'); + } + if (options.fields) { + (0, _utils.warn)('query fields will be ignored on v2'); + } -Object.defineProperties(Response.prototype, { - url: { enumerable: true }, - status: { enumerable: true }, - ok: { enumerable: true }, - redirected: { enumerable: true }, - statusText: { enumerable: true }, - headers: { enumerable: true }, - clone: { enumerable: true } -}); + var path = '/request/' + indexRef.doctype + '/' + indexRef.name + '/'; + var opts = makeMapReduceQuery(indexRef, options); + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function (response) { + return response.map(function (r) { + return r.value; + }); + }); +} -Object.defineProperty(Response.prototype, Symbol.toStringTag, { - value: 'Response', - writable: false, - enumerable: false, - configurable: true -}); +// queryV3 is equivalent to query but only works for V3 +function queryV3(cozy, indexRef, options) { + var opts = getV3Options(indexRef, options); -const INTERNALS$2 = Symbol('Request internals'); + var path = (0, _utils.createPath)(cozy, false, indexRef.doctype, '_find'); + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', path, opts).then(function (response) { + return options.wholeResponse ? response : response.docs; + }); +} -// fix an issue where "format", "parse" aren't a named export for node <10 -const parse_url = url__WEBPACK_IMPORTED_MODULE_2__.parse; -const format_url = url__WEBPACK_IMPORTED_MODULE_2__.format; +function getV3Options(indexRef, options) { + if (indexRef.type !== 'mango') { + throw new Error('indexRef should be the return value of defineIndexV3'); + } -const streamDestructionSupported = 'destroy' in stream__WEBPACK_IMPORTED_MODULE_0__.Readable.prototype; + var opts = { + use_index: indexRef.name, + fields: options.fields, + selector: options.selector, + limit: options.limit, + skip: options.skip, + since: options.since, + sort: options.sort + }; -/** - * Check if a value is an instance of Request. - * - * @param Mixed input - * @return Boolean - */ -function isRequest(input) { - return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; + if (options.descending) { + opts.sort = indexRef.fields.map(function (f) { + return _defineProperty({}, f, 'desc'); + }); + } + + return opts; } -function isAbortSignal(signal) { - const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); - return !!(proto && proto.constructor.name === 'AbortSignal'); +// misc +function capitalize(name) { + return name.charAt(0).toUpperCase() + name.slice(1); } -/** - * Request class - * - * @param Mixed input Url or Request instance - * @param Object init Custom options - * @return Void - */ -class Request { - constructor(input) { - let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +function makeMapFunction(doctype, fields) { + fields = '[' + fields.map(function (name) { + return 'doc.' + name; + }).join(',') + ']'; - let parsedURL; + return MAP_TEMPLATE.replace('DOCTYPEPLACEHOLDER', doctype.toLowerCase()).replace('FIELDSPLACEHOLDER', fields); +} - // normalize input - if (!isRequest(input)) { - if (input && input.href) { - // in order to support Node.js' Url objects; though WHATWG's URL objects - // will fall into this branch also (since their `toString()` will return - // `href` property anyway) - parsedURL = parse_url(input.href); - } else { - // coerce input to a string before attempting to parse - parsedURL = parse_url(`${input}`); - } - input = {}; - } else { - parsedURL = parse_url(input.url); - } +// parseSelector takes a mango selector and returns it as an array of filter +// a filter is [path, operator, value] array +// a path is an array of field names +// This function is only exported so it can be unit tested. +// Example : +// parseSelector({"test":{"deep": {"$gt": 3}}}) +// [[['test', 'deep'], '$gt', 3 ]] +function parseSelector(selector) { + var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var operator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '$eq'; - let method = init.method || input.method || 'GET'; - method = method.toUpperCase(); + if ((typeof selector === 'undefined' ? 'undefined' : _typeof(selector)) !== 'object') { + return [[path, operator, selector]]; + } - if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { - throw new TypeError('Request with GET/HEAD method cannot have body'); - } + var keys = Object.keys(selector); + if (keys.length === 0) { + throw new Error('empty selector'); + } else { + return keys.reduce(function (acc, k) { + if (LOGICOPERATORS.indexOf(k) !== -1) { + throw new Error('cozy-client-js does not support mango logic ops'); + } else if (VALUEOPERATORS.indexOf(k) !== -1) { + return acc.concat(parseSelector(selector[k], path, k)); + } else { + return acc.concat(parseSelector(selector[k], path.concat(k), '$eq')); + } + }, []); + } +} - let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; +// normalizeSelector takes a mango selector and returns it as an object +// normalized. +// This function is only exported so it can be unit tested. +// Example : +// parseSelector({"test":{"deep": {"$gt": 3}}}) +// {"test.deep": {"$gt": 3}} +function normalizeSelector(selector) { + var filters = parseSelector(selector); + return filters.reduce(function (acc, filter) { + var _filter = _slicedToArray(filter, 3), + path = _filter[0], + op = _filter[1], + value = _filter[2]; - Body.call(this, inputBody, { - timeout: init.timeout || input.timeout || 0, - size: init.size || input.size || 0 - }); + var field = path.join('.'); + acc[field] = acc[field] || {}; + acc[field][op] = value; + return acc; + }, {}); +} - const headers = new Headers(init.headers || input.headers || {}); +// applySelector takes the normalized selector for the current field +// and append the proper values to opts.startkey, opts.endkey +function applySelector(selector, opts) { + var value = selector['$eq']; + var lower = COUCHDB_LOWEST; + var upper = COUCHDB_INFINITY; + var inclusiveEnd = void 0; - if (inputBody != null && !headers.has('Content-Type')) { - const contentType = extractContentType(inputBody); - if (contentType) { - headers.append('Content-Type', contentType); - } - } + if (value) { + opts.startkey.push(value); + opts.endkey.push(value); + return false; + } - let signal = isRequest(input) ? input.signal : null; - if ('signal' in init) signal = init.signal; + value = selector['$gt']; + if (value) { + throw new Error('operator $gt (strict greater than) not supported'); + } - if (signal != null && !isAbortSignal(signal)) { - throw new TypeError('Expected signal to be an instanceof AbortSignal'); - } + value = selector['$gte']; + if (value) { + lower = value; + } - this[INTERNALS$2] = { - method, - redirect: init.redirect || input.redirect || 'follow', - headers, - parsedURL, - signal - }; + value = selector['$lte']; + if (value) { + upper = value; + inclusiveEnd = true; + } - // node-fetch-only options - this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; - this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; - this.counter = init.counter || input.counter || 0; - this.agent = init.agent || input.agent; - } + value = selector['$lt']; + if (value) { + upper = value; + inclusiveEnd = false; + } - get method() { - return this[INTERNALS$2].method; - } + opts.startkey.push(lower); + opts.endkey.push(upper); + if (inclusiveEnd !== undefined) opts.inclusive_end = inclusiveEnd; + return true; +} - get url() { - return format_url(this[INTERNALS$2].parsedURL); - } +// makeMapReduceQuery takes a mango query and generate _views call parameters +// to obtain same results depending on fields in the passed indexRef. +function makeMapReduceQuery(indexRef, query) { + var mrquery = { + startkey: [], + endkey: [], + reduce: false + }; + var firstFreeValueField = null; + var normalizedSelector = normalizeSelector(query.selector); - get headers() { - return this[INTERNALS$2].headers; - } + indexRef.fields.forEach(function (field) { + var selector = normalizedSelector[field]; + + if (selector && firstFreeValueField != null) { + throw new Error('Selector on field ' + field + ', but not on ' + firstFreeValueField + ' which is higher in index fields.'); + } else if (selector) { + selector.used = true; + var isFreeValue = applySelector(selector, mrquery); + if (isFreeValue) firstFreeValueField = field; + } else if (firstFreeValueField == null) { + firstFreeValueField = field; + mrquery.endkey.push(COUCHDB_INFINITY); + } + }); - get redirect() { - return this[INTERNALS$2].redirect; - } + Object.keys(normalizedSelector).forEach(function (field) { + if (!normalizedSelector[field].used) { + throw new Error('Cant apply selector on ' + field + ', it is not in index'); + } + }); - get signal() { - return this[INTERNALS$2].signal; - } + if (query.descending) { + mrquery = { + descending: true, + reduce: false, + startkey: mrquery.endkey, + endkey: mrquery.startkey, + inclusive_end: mrquery.inclusive_end + }; + } - /** - * Clone this request - * - * @return Request - */ - clone() { - return new Request(this); - } + return mrquery; } -Body.mixIn(Request.prototype); - -Object.defineProperty(Request.prototype, Symbol.toStringTag, { - value: 'Request', - writable: false, - enumerable: false, - configurable: true -}); +/***/ }), +/* 15 */ +/***/ (function(module, exports, __nested_webpack_require_80935__) { -Object.defineProperties(Request.prototype, { - method: { enumerable: true }, - url: { enumerable: true }, - headers: { enumerable: true }, - redirect: { enumerable: true }, - clone: { enumerable: true }, - signal: { enumerable: true } -}); +"use strict"; -/** - * Convert a Request to Node.js http request options. - * - * @param Request A Request instance - * @return Object The options object to be passed to http.request - */ -function getNodeRequestOptions(request) { - const parsedURL = request[INTERNALS$2].parsedURL; - const headers = new Headers(request[INTERNALS$2].headers); - // fetch step 1.3 - if (!headers.has('Accept')) { - headers.set('Accept', '*/*'); - } +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TRASH_DIR_ID = exports.ROOT_DIR_ID = undefined; - // Basic fetch - if (!parsedURL.protocol || !parsedURL.hostname) { - throw new TypeError('Only absolute URLs are supported'); - } +var _regenerator = __nested_webpack_require_80935__(4); - if (!/^https?:$/.test(parsedURL.protocol)) { - throw new TypeError('Only HTTP(S) protocols are supported'); - } +var _regenerator2 = _interopRequireDefault(_regenerator); - if (request.signal && request.body instanceof stream__WEBPACK_IMPORTED_MODULE_0__.Readable && !streamDestructionSupported) { - throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); - } +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - // HTTP-network-or-cache fetch steps 2.4-2.7 - let contentLengthValue = null; - if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { - contentLengthValue = '0'; - } - if (request.body != null) { - const totalBytes = getTotalBytes(request); - if (typeof totalBytes === 'number') { - contentLengthValue = String(totalBytes); - } - } - if (contentLengthValue) { - headers.set('Content-Length', contentLengthValue); - } +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* global Blob, File */ - // HTTP-network-or-cache fetch step 2.11 - if (!headers.has('User-Agent')) { - headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); - } - // HTTP-network-or-cache fetch step 2.15 - if (request.compress && !headers.has('Accept-Encoding')) { - headers.set('Accept-Encoding', 'gzip,deflate'); - } +var doUpload = function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, data, method, path, options) { + var isBuffer, isFile, isBlob, isStream, isString, _ref2, contentType, contentLength, checksum, createdAt, updatedAt, executable, lastModifiedDate, ifMatch, metadata, sourceAccount, sourceAccountIdentifier, signal, finalpath, metadataId, headers; - let agent = request.agent; - if (typeof agent === 'function') { - agent = agent(parsedURL); - } + return _regenerator2.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (data) { + _context.next = 2; + break; + } - if (!headers.has('Connection') && !agent) { - headers.set('Connection', 'close'); - } + throw new Error('missing data argument'); - // HTTP-network fetch step 4.2 - // chunked encoding is handled by Node.js + case 2: - return Object.assign({}, parsedURL, { - method: request.method, - headers: exportNodeCompatibleHeaders(headers), - agent - }); -} + // transform any ArrayBufferView to ArrayBuffer + if (data.buffer && data.buffer instanceof ArrayBuffer) { + data = data.buffer; + } -/** - * abort-error.js - * - * AbortError interface for cancelled requests - */ + isBuffer = typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer; + isFile = typeof File !== 'undefined' && data instanceof File; + isBlob = typeof Blob !== 'undefined' && data instanceof Blob; + isStream = data.readable === true && typeof data.pipe === 'function'; + isString = typeof data === 'string'; -/** - * Create AbortError instance - * - * @param String message Error message for human - * @return AbortError - */ -function AbortError(message) { - Error.call(this, message); + if (!(!isBuffer && !isFile && !isBlob && !isStream && !isString)) { + _context.next = 10; + break; + } - this.type = 'aborted'; - this.message = message; + throw new Error('invalid data type'); - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); -} + case 10: + _ref2 = options || {}, contentType = _ref2.contentType, contentLength = _ref2.contentLength, checksum = _ref2.checksum, createdAt = _ref2.createdAt, updatedAt = _ref2.updatedAt, executable = _ref2.executable, lastModifiedDate = _ref2.lastModifiedDate, ifMatch = _ref2.ifMatch, metadata = _ref2.metadata, sourceAccount = _ref2.sourceAccount, sourceAccountIdentifier = _ref2.sourceAccountIdentifier, signal = _ref2.signal; -AbortError.prototype = Object.create(Error.prototype); -AbortError.prototype.constructor = AbortError; -AbortError.prototype.name = 'AbortError'; + if (!contentType) { + if (isBuffer) { + contentType = contentTypeOctetStream; + } else if (isFile) { + contentType = data.type || getFileTypeFromName(data.name.toLowerCase()) || contentTypeOctetStream; + if (!lastModifiedDate) { + lastModifiedDate = data.lastModifiedDate; + } + } else if (isBlob) { + contentType = data.type || contentTypeOctetStream; + } else if (isStream) { + contentType = contentTypeOctetStream; + } else if (typeof data === 'string') { + contentType = 'text/plain'; + } + } -// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 -const PassThrough$1 = stream__WEBPACK_IMPORTED_MODULE_0__.PassThrough; -const resolve_url = url__WEBPACK_IMPORTED_MODULE_2__.resolve; + if (lastModifiedDate && typeof lastModifiedDate === 'string') { + lastModifiedDate = new Date(lastModifiedDate); + } + if (!createdAt) { + createdAt = lastModifiedDate; + } + if (!updatedAt) { + updatedAt = lastModifiedDate; + } -/** - * Fetch function - * - * @param Mixed url Absolute url or Request instance - * @param Object opts Fetch options - * @return Promise - */ -function fetch(url, opts) { + if (!executable) { + executable = false; + } - // allow custom promise - if (!fetch.Promise) { - throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); - } + finalpath = path; - Body.Promise = fetch.Promise; + if (!metadata) { + _context.next = 22; + break; + } - // wrap http.request into fetch - return new fetch.Promise(function (resolve, reject) { - // build request object - const request = new Request(url, opts); - const options = getNodeRequestOptions(request); + _context.next = 20; + return sendMetadata(cozy, metadata); - const send = (options.protocol === 'https:' ? https__WEBPACK_IMPORTED_MODULE_3__ : http__WEBPACK_IMPORTED_MODULE_1__).request; - const signal = request.signal; + case 20: + metadataId = _context.sent; - let response = null; + if (metadataId) { + finalpath = addQuerystringParam(finalpath, 'MetadataID', metadataId); + } - const abort = function abort() { - let error = new AbortError('The user aborted a request.'); - reject(error); - if (request.body && request.body instanceof stream__WEBPACK_IMPORTED_MODULE_0__.Readable) { - request.body.destroy(error); - } - if (!response || !response.body) return; - response.body.emit('error', error); - }; + case 22: + if (sourceAccount) { + finalpath = addQuerystringParam(finalpath, 'SourceAccount', sourceAccount); + } + if (sourceAccountIdentifier) { + finalpath = addQuerystringParam(finalpath, 'SourceAccountIdentifier', sourceAccountIdentifier); + } + if (createdAt) { + finalpath = addQuerystringParam(finalpath, 'CreatedAt', dateString(createdAt)); + } + if (updatedAt) { + finalpath = addQuerystringParam(finalpath, 'UpdatedAt', dateString(updatedAt)); + } + if (executable) { + finalpath = addQuerystringParam(finalpath, 'Executable', executable); + } - if (signal && signal.aborted) { - abort(); - return; - } + headers = { + 'Content-Type': contentType + }; - const abortAndFinalize = function abortAndFinalize() { - abort(); - finalize(); - }; + if (contentLength) { + headers['Content-Length'] = String(contentLength); + finalpath = addQuerystringParam(finalpath, 'Size', String(contentLength)); + } + if (checksum) headers['Content-MD5'] = checksum; + if (lastModifiedDate) headers['Date'] = lastModifiedDate.toGMTString(); + if (ifMatch) headers['If-Match'] = ifMatch; - // send request - const req = send(options); - let reqTimeout; + return _context.abrupt('return', (0, _fetch.cozyFetch)(cozy, finalpath, { + method: method, + headers: headers, + body: data, + signal: signal + }).then(function (res) { + var json = res.json(); + if (!res.ok) { + return json.then(function (err) { + throw err; + }); + } else { + return json.then(_jsonapi2.default); + } + })); - if (signal) { - signal.addEventListener('abort', abortAndFinalize); - } + case 33: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); - function finalize() { - req.abort(); - if (signal) signal.removeEventListener('abort', abortAndFinalize); - clearTimeout(reqTimeout); - } + return function doUpload(_x, _x2, _x3, _x4, _x5) { + return _ref.apply(this, arguments); + }; +}(); - if (request.timeout) { - req.once('socket', function (socket) { - reqTimeout = setTimeout(function () { - reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); - finalize(); - }, request.timeout); - }); - } +var sendMetadata = function () { + var _ref3 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(cozy, metadata) { + var result; + return _regenerator2.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/upload/metadata', { + data: { type: 'io.cozy.files.metadata', attributes: metadata } + }); - req.on('error', function (err) { - reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); - finalize(); - }); + case 2: + result = _context2.sent; + return _context2.abrupt('return', result && result._id ? result._id : false); - req.on('response', function (res) { - clearTimeout(reqTimeout); + case 4: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); - const headers = createHeadersLenient(res.headers); + return function sendMetadata(_x6, _x7) { + return _ref3.apply(this, arguments); + }; +}(); - // HTTP fetch step 5 - if (fetch.isRedirect(res.statusCode)) { - // HTTP fetch step 5.2 - const location = headers.get('Location'); +exports.create = create; +exports.createDirectory = createDirectory; +exports.createDirectoryByPath = createDirectoryByPath; +exports.updateById = updateById; +exports.updateAttributesById = updateAttributesById; +exports.updateAttributesByPath = updateAttributesByPath; +exports.trashById = trashById; +exports.statById = statById; +exports.statByPath = statByPath; +exports.downloadById = downloadById; +exports.downloadByPath = downloadByPath; +exports.getDownloadLinkByPath = getDownloadLinkByPath; +exports.getDownloadLinkById = getDownloadLinkById; +exports.getFilePath = getFilePath; +exports.getCollectionShareLink = getCollectionShareLink; +exports.getArchiveLinkByPaths = getArchiveLinkByPaths; +exports.getArchiveLinkByIds = getArchiveLinkByIds; +exports.listTrash = listTrash; +exports.clearTrash = clearTrash; +exports.restoreById = restoreById; +exports.destroyById = destroyById; - // HTTP fetch step 5.3 - const locationURL = location === null ? null : resolve_url(request.url, location); +var _fetch = __nested_webpack_require_80935__(0); - // HTTP fetch step 5.5 - switch (request.redirect) { - case 'error': - reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); - finalize(); - return; - case 'manual': - // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. - if (locationURL !== null) { - // handle corrupted header - try { - headers.set('Location', locationURL); - } catch (err) { - // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request - reject(err); - } - } - break; - case 'follow': - // HTTP-redirect fetch step 2 - if (locationURL === null) { - break; - } +var _jsonapi = __nested_webpack_require_80935__(7); - // HTTP-redirect fetch step 5 - if (request.counter >= request.follow) { - reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); - finalize(); - return; - } +var _jsonapi2 = _interopRequireDefault(_jsonapi); - // HTTP-redirect fetch step 6 (counter increment) - // Create a new Request object. - const requestOpts = { - headers: new Headers(request.headers), - follow: request.follow, - counter: request.counter + 1, - agent: request.agent, - compress: request.compress, - method: request.method, - body: request.body, - signal: request.signal, - timeout: request.timeout, - size: request.size - }; +var _doctypes = __nested_webpack_require_80935__(2); - // HTTP-redirect fetch step 9 - if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { - reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); - finalize(); - return; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // HTTP-redirect fetch step 11 - if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { - requestOpts.method = 'GET'; - requestOpts.body = undefined; - requestOpts.headers.delete('content-length'); - } +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } - // HTTP-redirect fetch step 15 - resolve(fetch(new Request(locationURL, requestOpts))); - finalize(); - return; - } - } +// global variables +var ROOT_DIR_ID = exports.ROOT_DIR_ID = 'io.cozy.files.root-dir'; +var TRASH_DIR_ID = exports.TRASH_DIR_ID = 'io.cozy.files.trash-dir'; - // prepare response - res.once('end', function () { - if (signal) signal.removeEventListener('abort', abortAndFinalize); - }); - let body = res.pipe(new PassThrough$1()); +var contentTypeOctetStream = 'application/octet-stream'; - const response_options = { - url: request.url, - status: res.statusCode, - statusText: res.statusMessage, - headers: headers, - size: request.size, - timeout: request.timeout, - counter: request.counter - }; +function sanitizeFileName(name) { + return name && name.trim(); +} - // HTTP-network fetch step 12.1.1.3 - const codings = headers.get('Content-Encoding'); +function getFileTypeFromName(name) { + if (/\.heic$/i.test(name)) return 'image/heic';else if (/\.heif$/i.test(name)) return 'image/heif';else return null; +} - // HTTP-network fetch step 12.1.1.4: handle content codings +function dateString(date) { + return (typeof date === 'undefined' ? 'undefined' : _typeof(date)) === 'object' ? date.toISOString() : date; +} - // in following scenarios we ignore compression support - // 1. compression support is disabled - // 2. HEAD request - // 3. no Content-Encoding header - // 4. no content response (204) - // 5. content not modified response (304) - if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { - response = new Response(body, response_options); - resolve(response); - return; - } +function create(cozy, data, options) { + var _ref4 = options || {}, + name = _ref4.name, + dirID = _ref4.dirID, + noSanitize = _ref4.noSanitize; - // For Node v6+ - // Be less strict when decoding compressed responses, since sometimes - // servers send slightly invalid responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - const zlibOptions = { - flush: zlib__WEBPACK_IMPORTED_MODULE_4__.Z_SYNC_FLUSH, - finishFlush: zlib__WEBPACK_IMPORTED_MODULE_4__.Z_SYNC_FLUSH - }; + // handle case where data is a file and contains the name - // for gzip - if (codings == 'gzip' || codings == 'x-gzip') { - body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createGunzip(zlibOptions)); - response = new Response(body, response_options); - resolve(response); - return; - } - // for deflate - if (codings == 'deflate' || codings == 'x-deflate') { - // handle the infamous raw deflate response from old servers - // a hack for old IIS and Apache servers - const raw = res.pipe(new PassThrough$1()); - raw.once('data', function (chunk) { - // see http://stackoverflow.com/questions/37519828 - if ((chunk[0] & 0x0F) === 0x08) { - body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createInflate()); - } else { - body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createInflateRaw()); - } - response = new Response(body, response_options); - resolve(response); - }); - return; - } + if (!name && typeof data.name === 'string') { + name = data.name; + } - // for br - if (codings == 'br' && typeof zlib__WEBPACK_IMPORTED_MODULE_4__.createBrotliDecompress === 'function') { - body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createBrotliDecompress()); - response = new Response(body, response_options); - resolve(response); - return; - } + if (!noSanitize) { + name = sanitizeFileName(name); + } - // otherwise, use response as-is - response = new Response(body, response_options); - resolve(response); - }); + if (typeof name !== 'string' || name === '') { + throw new Error('missing name argument'); + } - writeToStream(req, request); - }); + var path = '/files/' + encodeURIComponent(dirID || ''); + var query = '?Name=' + encodeURIComponent(name) + '&Type=file'; + return doUpload(cozy, data, 'POST', '' + path + query, options); } -/** - * Redirect code matching - * - * @param Number code Status code - * @return Boolean - */ -fetch.isRedirect = function (code) { - return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; -}; -// expose Promise -fetch.Promise = global.Promise; +function createDirectory(cozy, options) { + var _ref5 = options || {}, + name = _ref5.name, + dirID = _ref5.dirID, + createdAt = _ref5.createdAt, + updatedAt = _ref5.updatedAt, + lastModifiedDate = _ref5.lastModifiedDate, + noSanitize = _ref5.noSanitize; -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (fetch); + if (!noSanitize) { + name = sanitizeFileName(name); + } + if (typeof name !== 'string' || name === '') { + throw new Error('missing name argument'); + } + if (lastModifiedDate && typeof lastModifiedDate === 'string') { + lastModifiedDate = new Date(lastModifiedDate); + } + if (!createdAt) { + createdAt = lastModifiedDate; + } + if (!updatedAt) { + updatedAt = lastModifiedDate; + } -/***/ }), -/* 482 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var path = '/files/' + encodeURIComponent(dirID || ''); + var query = '?Name=' + encodeURIComponent(name) + '&Type=directory'; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(483); -/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var immediate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(484); -/* harmony import */ var immediate__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(immediate__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(250); -/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(485); -/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var spark_md5__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(487); -/* harmony import */ var spark_md5__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(spark_md5__WEBPACK_IMPORTED_MODULE_4__); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(488); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_5__); -/* harmony import */ var vuvuzela__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(493); + var finalpath = '' + path + query; + if (createdAt) { + finalpath = addQuerystringParam(finalpath, 'CreatedAt', dateString(createdAt)); + } + if (updatedAt) { + finalpath = addQuerystringParam(finalpath, 'UpdatedAt', dateString(updatedAt)); + } + var headers = {}; + if (lastModifiedDate) headers['Date'] = lastModifiedDate.toGMTString(); + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', finalpath, undefined, { + headers: headers + }); +} +function getDirectoryOrCreate(cozy, name, parentDirectory, options) { + if (parentDirectory && !parentDirectory.attributes) throw new Error('Malformed parent directory'); + var _ref6 = options || {}, + noSanitize = _ref6.noSanitize; + if (!noSanitize) { + name = sanitizeFileName(name); + } + var path = (parentDirectory._id === ROOT_DIR_ID ? '' : parentDirectory.attributes.path) + '/' + name; + return cozy.files.statByPath(path || '/').catch(function (error) { + var parsedError = JSON.parse(error.message); + var errors = parsedError.errors; + if (errors && errors.length && errors[0].status === '404') { + return cozy.files.createDirectory({ + name: name, + dirID: parentDirectory && parentDirectory._id + }); + } -function isBinaryObject(object) { - return (typeof ArrayBuffer !== 'undefined' && object instanceof ArrayBuffer) || - (typeof Blob !== 'undefined' && object instanceof Blob); + throw errors; + }); } -function cloneArrayBuffer(buff) { - if (typeof buff.slice === 'function') { - return buff.slice(0); - } - // IE10-11 slice() polyfill - var target = new ArrayBuffer(buff.byteLength); - var targetArray = new Uint8Array(target); - var sourceArray = new Uint8Array(buff); - targetArray.set(sourceArray); - return target; -} +function createDirectoryByPath(cozy, path, offline, options) { + var parts = path.split('/').filter(function (part) { + return part !== ''; + }); -function cloneBinaryObject(object) { - if (object instanceof ArrayBuffer) { - return cloneArrayBuffer(object); - } - var size = object.size; - var type = object.type; - // Blob - if (typeof object.slice === 'function') { - return object.slice(0, size, type); - } - // PhantomJS slice() replacement - return object.webkitSlice(0, size, type); -} + var rootDirectoryPromise = cozy.files.statById(ROOT_DIR_ID, offline); -// most of this is borrowed from lodash.isPlainObject: -// https://github.com/fis-components/lodash.isplainobject/ -// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js + return parts.length ? parts.reduce(function (parentDirectoryPromise, part) { + return parentDirectoryPromise.then(function (parentDirectory) { + return getDirectoryOrCreate(cozy, part, parentDirectory, options); + }); + }, rootDirectoryPromise) : rootDirectoryPromise; +} -var funcToString = Function.prototype.toString; -var objectCtorString = funcToString.call(Object); +function updateById(cozy, id, data, options) { + return doUpload(cozy, data, 'PUT', '/files/' + encodeURIComponent(id), options); +} -function isPlainObject(value) { - var proto = Object.getPrototypeOf(value); - /* istanbul ignore if */ - if (proto === null) { // not sure when this happens, but I guess it can - return true; +function doUpdateAttributes(cozy, attrs, path, options) { + if (!attrs || (typeof attrs === 'undefined' ? 'undefined' : _typeof(attrs)) !== 'object') { + throw new Error('missing attrs argument'); } - var Ctor = proto.constructor; - return (typeof Ctor == 'function' && - Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); -} -function clone(object) { - var newObject; - var i; - var len; + var _ref7 = options || {}, + ifMatch = _ref7.ifMatch, + noSanitize = _ref7.noSanitize; - if (!object || typeof object !== 'object') { - return object; + var name = attrs.name; + if (!noSanitize) { + name = sanitizeFileName(name); } - if (Array.isArray(object)) { - newObject = []; - for (i = 0, len = object.length; i < len; i++) { - newObject[i] = clone(object[i]); + var body = { + data: { + attributes: Object.assign({}, attrs, { + name: name + }) } - return newObject; - } + }; + return (0, _fetch.cozyFetchJSON)(cozy, 'PATCH', path, body, { + headers: { + 'If-Match': ifMatch || '' + } + }); +} - // special case: to avoid inconsistencies between IndexedDB - // and other backends, we automatically stringify Dates - if (object instanceof Date) { - return object.toISOString(); - } +function updateAttributesById(cozy, id, attrs, options) { + return doUpdateAttributes(cozy, attrs, '/files/' + encodeURIComponent(id), options); +} - if (isBinaryObject(object)) { - return cloneBinaryObject(object); - } +function updateAttributesByPath(cozy, path, attrs, options) { + return doUpdateAttributes(cozy, attrs, '/files/metadata?Path=' + encodeURIComponent(path), options); +} - if (!isPlainObject(object)) { - return object; // don't clone objects like Workers +function trashById(cozy, id, options) { + if (typeof id !== 'string' || id === '') { + throw new Error('missing id argument'); } - newObject = {}; - for (i in object) { - /* istanbul ignore else */ - if (Object.prototype.hasOwnProperty.call(object, i)) { - var value = clone(object[i]); - if (typeof value !== 'undefined') { - newObject[i] = value; - } - } - } - return newObject; -} + var _ref8 = options || {}, + ifMatch = _ref8.ifMatch; -function once(fun) { - var called = false; - return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { - /* istanbul ignore if */ - if (called) { - // this is a smoke test and should never actually happen - throw new Error('once called more than once'); - } else { - called = true; - fun.apply(this, args); + return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/' + encodeURIComponent(id), undefined, { + headers: { + 'If-Match': ifMatch || '' } }); } -function toPromise(func) { - //create the function we will be returning - return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { - // Clone arguments - args = clone(args); - var self = this; - // if the last argument is a function, assume its a callback - var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false; - var promise = new Promise(function (fulfill, reject) { - var resp; - try { - var callback = once(function (err, mesg) { - if (err) { - reject(err); - } else { - fulfill(mesg); - } +function statById(cozy, id) { + var offline = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + if (offline && cozy.offline.hasDatabase(_doctypes.DOCTYPE_FILES)) { + var db = cozy.offline.getDatabase(_doctypes.DOCTYPE_FILES); + return Promise.all([db.get(id), db.find(Object.assign({ selector: { dir_id: id } }, options))]).then(function (_ref9) { + var _ref10 = _slicedToArray(_ref9, 2), + doc = _ref10[0], + children = _ref10[1]; + + if (id === ROOT_DIR_ID) { + children.docs = children.docs.filter(function (doc) { + return doc._id !== TRASH_DIR_ID; }); - // create a callback for this invocation - // apply the function in the orig context - args.push(callback); - resp = func.apply(self, args); - if (resp && typeof resp.then === 'function') { - fulfill(resp); - } - } catch (e) { - reject(e); } + children = sortFiles(children.docs.map(function (doc) { + return addIsDir(toJsonApi(cozy, doc)); + })); + return addIsDir(toJsonApi(cozy, doc, children)); }); - // if there is a callback, call it back - if (usedCB) { - promise.then(function (result) { - usedCB(null, result); - }, usedCB); - } - return promise; - }); + } + var query = Object.keys(options).length === 0 ? '' : '?' + encodePageOptions(options); + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/' + encodeURIComponent(id) + query).then(addIsDir); } -function logApiCall(self, name, args) { - /* istanbul ignore if */ - if (self.constructor.listeners('debug').length) { - var logArgs = ['api', self.name, name]; - for (var i = 0; i < args.length - 1; i++) { - logArgs.push(args[i]); - } - self.constructor.emit('debug', logArgs); +function statByPath(cozy, path) { + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/metadata?Path=' + encodeURIComponent(path)).then(addIsDir); +} - // override the callback itself to log the response - var origCallback = args[args.length - 1]; - args[args.length - 1] = function (err, res) { - var responseArgs = ['api', self.name, name]; - responseArgs = responseArgs.concat( - err ? ['error', err] : ['success', res] - ); - self.constructor.emit('debug', responseArgs); - origCallback(err, res); - }; - } +function downloadById(cozy, id) { + return (0, _fetch.cozyFetch)(cozy, '/files/download/' + encodeURIComponent(id)); } -function adapterFun(name, callback) { - return toPromise(argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { - if (this._closed) { - return Promise.reject(new Error('database is closed')); - } - if (this._destroyed) { - return Promise.reject(new Error('database is destroyed')); - } - var self = this; - logApiCall(self, name, args); - if (!this.taskqueue.isReady) { - return new Promise(function (fulfill, reject) { - self.taskqueue.addTask(function (failed) { - if (failed) { - reject(failed); - } else { - fulfill(self[name].apply(self, args)); - } - }); - }); - } - return callback.apply(this, args); - })); +function downloadByPath(cozy, path) { + return (0, _fetch.cozyFetch)(cozy, '/files/download?Path=' + encodeURIComponent(path)); } -function mangle(key) { - return '$' + key; +function extractResponseLinkRelated(res) { + var href = res.links && res.links.related; + if (!href) throw new Error('No related link in server response'); + return href; } -function unmangle(key) { - return key.substring(1); + +function getDownloadLinkByPath(cozy, path) { + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/downloads?Path=' + encodeURIComponent(path)).then(extractResponseLinkRelated); } -function Map$1() { - this._store = {}; + +function getDownloadLinkById(cozy, id) { + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/downloads?Id=' + encodeURIComponent(id)).then(extractResponseLinkRelated); } -Map$1.prototype.get = function (key) { - var mangled = mangle(key); - return this._store[mangled]; -}; -Map$1.prototype.set = function (key, value) { - var mangled = mangle(key); - this._store[mangled] = value; - return true; -}; -Map$1.prototype.has = function (key) { - var mangled = mangle(key); - return mangled in this._store; -}; -Map$1.prototype.delete = function (key) { - var mangled = mangle(key); - var res = mangled in this._store; - delete this._store[mangled]; - return res; -}; -Map$1.prototype.forEach = function (cb) { - var keys = Object.keys(this._store); - for (var i = 0, len = keys.length; i < len; i++) { - var key = keys[i]; - var value = this._store[key]; - key = unmangle(key); - cb(value, key); - } -}; -Object.defineProperty(Map$1.prototype, 'size', { - get: function () { - return Object.keys(this._store).length; - } -}); -function Set$1(array) { - this._store = new Map$1(); +function getFilePath(cozy) { + var file = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var folder = arguments[2]; - // init with an array - if (array && Array.isArray(array)) { - for (var i = 0, len = array.length; i < len; i++) { - this.add(array[i]); - } + if (!folder || !folder.attributes) { + throw Error('Folder should be valid with an attributes.path property'); } + + var folderPath = folder.attributes.path.endsWith('/') ? folder.attributes.path : folder.attributes.path + '/'; + + return '' + folderPath + file.name; } -Set$1.prototype.add = function (key) { - return this._store.set(key, true); -}; -Set$1.prototype.has = function (key) { - return this._store.has(key); -}; -Set$1.prototype.forEach = function (cb) { - this._store.forEach(function (value, key) { - cb(key); - }); -}; -Object.defineProperty(Set$1.prototype, 'size', { - get: function () { - return this._store.size; - } -}); -/* global Map,Set,Symbol */ -// Based on https://kangax.github.io/compat-table/es6/ we can sniff out -// incomplete Map/Set implementations which would otherwise cause our tests to fail. -// Notably they fail in IE11 and iOS 8.4, which this prevents. -function supportsMapAndSet() { - if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') { - return false; +function getCollectionShareLink(cozy, id, collectionType) { + if (!id) { + return Promise.reject(Error('An id should be provided to create a share link')); } - var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species); - return prop && 'get' in prop && Map[Symbol.species] === Map; + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/permissions?codes=email', { + data: { + type: 'io.cozy.permissions', + attributes: { + permissions: { + files: { + type: 'io.cozy.files', + verbs: ['GET'], + values: [id], + selector: 'referenced_by' + }, + collection: { + type: collectionType, + verbs: ['GET'], + values: [id] + } + } + } + } + }).then(function (data) { + return { + sharecode: 'sharecode=' + data.attributes.codes.email, + id: 'id=' + id + }; + }); } -// based on https://github.com/montagejs/collections - -var ExportedSet; -var ExportedMap; +function getArchiveLinkByPaths(cozy, paths) { + var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'files'; -{ - if (supportsMapAndSet()) { // prefer built-in Map/Set - ExportedSet = Set; - ExportedMap = Map; - } else { // fall back to our polyfill - ExportedSet = Set$1; - ExportedMap = Map$1; - } + var archive = { + type: 'io.cozy.archives', + attributes: { + name: name, + files: paths + } + }; + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/archive', { data: archive }).then(extractResponseLinkRelated); } - -// like underscore/lodash _.pick() -function pick(obj, arr) { - var res = {}; - for (var i = 0, len = arr.length; i < len; i++) { - var prop = arr[i]; - if (prop in obj) { - res[prop] = obj[prop]; + +function getArchiveLinkByIds(cozy, ids) { + var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'files'; + + var archive = { + type: 'io.cozy.archives', + attributes: { + name: name, + ids: ids } - } - return res; + }; + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/archive', { data: archive }).then(extractResponseLinkRelated); } -// Most browsers throttle concurrent requests at 6, so it's silly -// to shim _bulk_get by trying to launch potentially hundreds of requests -// and then letting the majority time out. We can handle this ourselves. -var MAX_NUM_CONCURRENT_REQUESTS = 6; +function listTrash(cozy) { + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/files/trash'); +} -function identityFunction(x) { - return x; +function clearTrash(cozy) { + return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/trash'); } -function formatResultForOpenRevsGet(result) { - return [{ - ok: result - }]; +function restoreById(cozy, id) { + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/files/trash/' + encodeURIComponent(id)); } -// shim for P/CouchDB adapters that don't directly implement _bulk_get -function bulkGet(db, opts, callback) { - var requests = opts.docs; +function destroyById(cozy, id, options) { + var _ref11 = options || {}, + ifMatch = _ref11.ifMatch; - // consolidate into one request per doc if possible - var requestsById = new ExportedMap(); - requests.forEach(function (request) { - if (requestsById.has(request.id)) { - requestsById.get(request.id).push(request); - } else { - requestsById.set(request.id, [request]); + return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/files/trash/' + encodeURIComponent(id), undefined, { + headers: { + 'If-Match': ifMatch || '' } }); +} - var numDocs = requestsById.size; - var numDone = 0; - var perDocResults = new Array(numDocs); +function addIsDir(obj) { + obj.isDir = obj.attributes.type === 'directory'; + return obj; +} - function collapseResultsAndFinish() { - var results = []; - perDocResults.forEach(function (res) { - res.docs.forEach(function (info) { - results.push({ - id: res.id, - docs: [info] - }); - }); - }); - callback(null, {results: results}); +function encodePageOptions(options) { + var opts = []; + for (var name in options) { + opts.push('page[' + encodeURIComponent(name) + ']=' + encodeURIComponent(options[name])); } + return opts.join('&'); +} - function checkDone() { - if (++numDone === numDocs) { - collapseResultsAndFinish(); - } - } +function toJsonApi(cozy, doc) { + var contents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; - function gotResult(docIndex, id, docs) { - perDocResults[docIndex] = {id: id, docs: docs}; - checkDone(); - } + var clone = JSON.parse(JSON.stringify(doc)); + delete clone._id; + delete clone._rev; + return { + _id: doc._id, + _rev: doc._rev, + _type: _doctypes.DOCTYPE_FILES, + attributes: clone, + relationships: { + contents: { + data: contents, + meta: { + count: contents.length + } + } + }, + relations: function relations(name) { + if (name === 'contents') { + return contents; + } + } + }; +} - var allRequests = []; - requestsById.forEach(function (value, key) { - allRequests.push(key); +function sortFiles(allFiles) { + var folders = allFiles.filter(function (f) { + return f.attributes.type === 'directory'; + }); + var files = allFiles.filter(function (f) { + return f.attributes.type !== 'directory'; }); + var sort = function sort(files) { + return files.sort(function (a, b) { + return a.attributes.name.localeCompare(b.attributes.name); + }); + }; + return sort(folders).concat(sort(files)); +} - var i = 0; +function addQuerystringParam(path, key, value) { + return '' + path + (path.includes('?') ? '&' : '?') + key + '=' + value; +} - function nextBatch() { +/***/ }), +/* 16 */ +/***/ (function(module, exports, __nested_webpack_require_101343__) { - if (i >= allRequests.length) { - return; - } +"use strict"; - var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length); - var batch = allRequests.slice(i, upTo); - processBatch(batch, i); - i += batch.length; - } - function processBatch(batch, offset) { - batch.forEach(function (docId, j) { - var docIdx = offset + j; - var docRequests = requestsById.get(docId); +Object.defineProperty(exports, "__esModule", { + value: true +}); - // just use the first request as the "template" - // TODO: The _bulk_get API allows for more subtle use cases than this, - // but for now it is unlikely that there will be a mix of different - // "atts_since" or "attachments" in the same request, since it's just - // replicate.js that is using this for the moment. - // Also, atts_since is aspirational, since we don't support it yet. - var docOpts = pick(docRequests[0], ['atts_since', 'attachments']); - docOpts.open_revs = docRequests.map(function (request) { - // rev is optional, open_revs disallowed - return request.rev; - }); +var _regenerator = __nested_webpack_require_101343__(4); - // remove falsey / undefined revisions - docOpts.open_revs = docOpts.open_revs.filter(identityFunction); +var _regenerator2 = _interopRequireDefault(_regenerator); - var formatResult = identityFunction; +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - if (docOpts.open_revs.length === 0) { - delete docOpts.open_revs; +exports.start = start; - // when fetching only the "winning" leaf, - // transform the result so it looks like an open_revs - // request - formatResult = formatResultForOpenRevsGet; - } +var _helpers = __nested_webpack_require_101343__(5); - // globally-supplied options - ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) { - if (param in opts) { - docOpts[param] = opts[param]; - } - }); - db.get(docId, docOpts, function (err, res) { - var result; - /* istanbul ignore if */ - if (err) { - result = [{error: err}]; - } else { - result = formatResult(res); - } - gotResult(docIdx, docId, result); - nextBatch(); - }); - }); - } +var _ = __nested_webpack_require_101343__(8); - nextBatch(); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -} +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } -var hasLocal; +var intentClass = 'coz-intent'; -try { - localStorage.setItem('_pouch_check_localstorage', 1); - hasLocal = !!localStorage.getItem('_pouch_check_localstorage'); -} catch (e) { - hasLocal = false; +function hideIntentIframe(iframe) { + iframe.style.display = 'none'; } -function hasLocalStorage() { - return hasLocal; +function showIntentFrame(iframe) { + iframe.style.display = 'block'; } -// Custom nextTick() shim for browsers. In node, this will just be process.nextTick(). We - -inherits__WEBPACK_IMPORTED_MODULE_3___default()(Changes, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); +function buildIntentIframe(intent, element, url) { + var document = element.ownerDocument; + if (!document) return Promise.reject(new Error('Cannot retrieve document object from given element')); -/* istanbul ignore next */ -function attachBrowserEvents(self) { - if (hasLocalStorage()) { - addEventListener("storage", function (e) { - self.emit(e.key); - }); - } + var iframe = document.createElement('iframe'); + // TODO: implement 'title' attribute + iframe.setAttribute('id', 'intent-' + intent._id); + iframe.setAttribute('src', url); + iframe.classList.add(intentClass); + return iframe; } -function Changes() { - events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this); - this._listeners = {}; +function injectIntentIframe(intent, element, url, options) { + var onReadyCallback = options.onReadyCallback; - attachBrowserEvents(this); + var iframe = buildIntentIframe(intent, element, url, options.onReadyCallback); + // if callback provided for when iframe is loaded + if (typeof onReadyCallback === 'function') iframe.onload = onReadyCallback; + element.appendChild(iframe); + iframe.focus(); + return iframe; } -Changes.prototype.addListener = function (dbName, id, db, opts) { - /* istanbul ignore if */ - if (this._listeners[id]) { - return; - } - var self = this; - var inprogress = false; - function eventFunction() { - /* istanbul ignore if */ - if (!self._listeners[id]) { - return; - } - if (inprogress) { - inprogress = 'waiting'; - return; - } - inprogress = true; - var changesOpts = pick(opts, [ - 'style', 'include_docs', 'attachments', 'conflicts', 'filter', - 'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs' - ]); - /* istanbul ignore next */ - function onError() { - inprogress = false; - } +// inject iframe for service in given element +function connectIntentIframe(cozy, iframe, element, intent, data) { + var _this = this; - db.changes(changesOpts).on('change', function (c) { - if (c.seq > opts.since && !opts.cancelled) { - opts.since = c.seq; - opts.onChange(c); - } - }).on('complete', function () { - if (inprogress === 'waiting') { - immediate__WEBPACK_IMPORTED_MODULE_1___default()(eventFunction); - } - inprogress = false; - }).on('error', onError); - } - this._listeners[id] = eventFunction; - this.on(dbName, eventFunction); -}; + var compose = function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(cozy, action, doctype, data) { + var intent, doc; + return _regenerator2.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return (0, _.create)(cozy, action, doctype, data); -Changes.prototype.removeListener = function (dbName, id) { - /* istanbul ignore if */ - if (!(id in this._listeners)) { - return; - } - events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype.removeListener.call(this, dbName, - this._listeners[id]); - delete this._listeners[id]; -}; + case 2: + intent = _context.sent; + hideIntentIframe(iframe); + _context.next = 6; + return start(cozy, intent, element, _extends({}, data, { + exposeIntentFrameRemoval: false + })); -/* istanbul ignore next */ -Changes.prototype.notifyLocalWindows = function (dbName) { - //do a useless change on a storage thing - //in order to get other windows's listeners to activate - if (hasLocalStorage()) { - localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a"; - } -}; + case 6: + doc = _context.sent; -Changes.prototype.notify = function (dbName) { - this.emit(dbName); - this.notifyLocalWindows(dbName); -}; + showIntentFrame(iframe); + return _context.abrupt('return', doc); -function guardedConsole(method) { - /* istanbul ignore else */ - if (typeof console !== 'undefined' && typeof console[method] === 'function') { - var args = Array.prototype.slice.call(arguments, 1); - console[method].apply(console, args); - } -} + case 9: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); -function randomNumber(min, max) { - var maxTimeout = 600000; // Hard-coded default of 10 minutes - min = parseInt(min, 10) || 0; - max = parseInt(max, 10); - if (max !== max || max <= min) { - max = (min || 1) << 1; //doubling - } else { - max = max + 1; - } - // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout - if (max > maxTimeout) { - min = maxTimeout >> 1; // divide by two - max = maxTimeout; - } - var ratio = Math.random(); - var range = max - min; + return function compose(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; + }(); - return ~~(range * ratio + min); // ~~ coerces to an int, but fast. -} + var document = element.ownerDocument; + if (!document) return Promise.reject(new Error('Cannot retrieve document object from given element')); -function defaultBackOff(min) { - var max = 0; - if (!min) { - max = 2000; - } - return randomNumber(min, max); -} + var window = document.defaultView; + if (!window) return Promise.reject(new Error('Cannot retrieve window object from document')); -// designed to give info to browser users, who are disturbed -// when they see http errors in the console -function explainError(status, str) { - guardedConsole('info', 'The above ' + status + ' is totally normal. ' + str); -} + // Keeps only http://domain:port/ + var serviceOrigin = iframe.src.split('/', 3).join('/'); -var assign; -{ - if (typeof Object.assign === 'function') { - assign = Object.assign; - } else { - // lite Object.assign polyfill based on - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - assign = function (target) { - var to = Object(target); + return new Promise(function (resolve, reject) { + var handshaken = false; + var messageHandler = function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(event) { + var eventType, _event$data, action, doctype, _data, doc, removeIntentFrame; - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; + return _regenerator2.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (!(event.origin !== serviceOrigin)) { + _context2.next = 2; + break; + } - if (nextSource != null) { // Skip over if undefined or null - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to; - }; - } -} + return _context2.abrupt('return'); -var $inject_Object_assign = assign; + case 2: + eventType = event.data.type; -inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchError, Error); + if (!(eventType === 'load')) { + _context2.next = 6; + break; + } -function PouchError(status, error, reason) { - Error.call(this, reason); - this.status = status; - this.name = error; - this.message = reason; - this.error = true; -} + // Safari 9.1 (At least) send a MessageEvent when the iframe loads, + // making the handshake fails. + console.warn && console.warn('Cozy Client ignored MessageEvent having data.type `load`.'); + return _context2.abrupt('return'); -PouchError.prototype.toString = function () { - return JSON.stringify({ - status: this.status, - name: this.name, - message: this.message, - reason: this.reason - }); -}; + case 6: + if (!(eventType === 'intent-' + intent._id + ':ready')) { + _context2.next = 9; + break; + } -var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect."); -var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'"); -var MISSING_DOC = new PouchError(404, 'not_found', 'missing'); -var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict'); -var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string'); -var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts'); -var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.'); -var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open'); -var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error'); -var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid'); -var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid'); -var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid'); -var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member'); -var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request'); -var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object'); -var DB_MISSING = new PouchError(404, 'not_found', 'Database not found'); -var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown'); -var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown'); -var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown'); -var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function'); -var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format'); -var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.'); -var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found'); -var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid'); + handshaken = true; + return _context2.abrupt('return', event.source.postMessage(data, event.origin)); -function createError(error, reason) { - function CustomPouchError(reason) { - // inherit error properties from our parent error manually - // so as to allow proper JSON parsing. - /* jshint ignore:start */ - for (var p in error) { - if (typeof error[p] !== 'function') { - this[p] = error[p]; - } - } - /* jshint ignore:end */ - if (reason !== undefined) { - this.reason = reason; - } - } - CustomPouchError.prototype = PouchError.prototype; - return new CustomPouchError(reason); -} + case 9: + if (!(handshaken && eventType === 'intent-' + intent._id + ':resize')) { + _context2.next = 13; + break; + } -function generateErrorFromResponse(err) { + ;['width', 'height', 'maxWidth', 'maxHeight'].forEach(function (prop) { + if (event.data.transition) element.style.transition = event.data.transition; + if (event.data.dimensions[prop]) element.style[prop] = event.data.dimensions[prop] + 'px'; + }); - if (typeof err !== 'object') { - var data = err; - err = UNKNOWN_ERROR; - err.data = data; - } + return _context2.abrupt('return', true); - if ('error' in err && err.error === 'conflict') { - err.name = 'conflict'; - err.status = 409; - } + case 13: + if (!(handshaken && eventType === 'intent-' + intent._id + ':compose')) { + _context2.next = 19; + break; + } - if (!('name' in err)) { - err.name = err.error || 'unknown'; - } + // Let start to name `type` as `doctype`, as `event.data` already have a `type` attribute. + _event$data = event.data, action = _event$data.action, doctype = _event$data.doctype, _data = _event$data.data; + _context2.next = 17; + return compose(cozy, action, doctype, _data); - if (!('status' in err)) { - err.status = 500; - } + case 17: + doc = _context2.sent; + return _context2.abrupt('return', event.source.postMessage(doc, event.origin)); - if (!('message' in err)) { - err.message = err.message || err.reason; - } + case 19: - return err; -} + window.removeEventListener('message', messageHandler); -function tryFilter(filter, doc, req) { - try { - return !filter(doc, req); - } catch (err) { - var msg = 'Filter function threw: ' + err.toString(); - return createError(BAD_REQUEST, msg); - } -} + removeIntentFrame = function removeIntentFrame() { + // check if the parent node has not been already removed from the DOM + iframe.parentNode && iframe.parentNode.removeChild(iframe); + }; -function filterChange(opts) { - var req = {}; - var hasFilter = opts.filter && typeof opts.filter === 'function'; - req.query = opts.query_params; + if (!(handshaken && eventType === 'intent-' + intent._id + ':exposeFrameRemoval')) { + _context2.next = 23; + break; + } - return function filter(change) { - if (!change.doc) { - // CSG sends events on the changes feed that don't have documents, - // this hack makes a whole lot of existing code robust. - change.doc = {}; - } + return _context2.abrupt('return', resolve({ removeIntentFrame: removeIntentFrame, doc: event.data.document })); - var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req); + case 23: - if (typeof filterReturn === 'object') { - return filterReturn; - } + removeIntentFrame(); - if (filterReturn) { - return false; - } + if (!(eventType === 'intent-' + intent._id + ':error')) { + _context2.next = 26; + break; + } - if (!opts.include_docs) { - delete change.doc; - } else if (!opts.attachments) { - for (var att in change.doc._attachments) { - /* istanbul ignore else */ - if (change.doc._attachments.hasOwnProperty(att)) { - change.doc._attachments[att].stub = true; - } - } - } - return true; - }; -} + return _context2.abrupt('return', reject(_helpers.errorSerializer.deserialize(event.data.error))); -function flatten(arrs) { - var res = []; - for (var i = 0, len = arrs.length; i < len; i++) { - res = res.concat(arrs[i]); - } - return res; -} + case 26: + if (!(handshaken && eventType === 'intent-' + intent._id + ':cancel')) { + _context2.next = 28; + break; + } -// shim for Function.prototype.name, + return _context2.abrupt('return', resolve(null)); -// Determine id an ID is valid -// - invalid IDs begin with an underescore that does not begin '_design' or -// '_local' -// - any other string value is a valid id -// Returns the specific error object for each case -function invalidIdError(id) { - var err; - if (!id) { - err = createError(MISSING_ID); - } else if (typeof id !== 'string') { - err = createError(INVALID_ID); - } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) { - err = createError(RESERVED_ID); - } - if (err) { - throw err; - } -} + case 28: + if (!(handshaken && eventType === 'intent-' + intent._id + ':done')) { + _context2.next = 30; + break; + } -// Checks if a PouchDB object is "remote" or not. This is + return _context2.abrupt('return', resolve(event.data.document)); -function isRemote(db) { - if (typeof db._remote === 'boolean') { - return db._remote; - } - /* istanbul ignore next */ - if (typeof db.type === 'function') { - guardedConsole('warn', - 'db.type() is deprecated and will be removed in ' + - 'a future version of PouchDB'); - return db.type() === 'http'; - } - /* istanbul ignore next */ - return false; -} + case 30: + if (handshaken) { + _context2.next = 32; + break; + } -function listenerCount(ee, type) { - return 'listenerCount' in ee ? ee.listenerCount(type) : - events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.listenerCount(ee, type); -} + return _context2.abrupt('return', reject(new Error('Unexpected handshake message from intent service'))); -function parseDesignDocFunctionName(s) { - if (!s) { - return null; - } - var parts = s.split('/'); - if (parts.length === 2) { - return parts; - } - if (parts.length === 1) { - return [s, s]; - } - return null; -} + case 32: + case 'end': + return _context2.stop(); + } + } + }, _callee2, _this); + })); -function normalizeDesignDocFunctionName(s) { - var normalized = parseDesignDocFunctionName(s); - return normalized ? normalized.join('/') : null; -} + return function messageHandler(_x5) { + return _ref2.apply(this, arguments); + }; + }(); -// originally parseUri 1.2.2, now patched by us -// (c) Steven Levithan <stevenlevithan.com> -// MIT License -var keys = ["source", "protocol", "authority", "userInfo", "user", "password", - "host", "port", "relative", "path", "directory", "file", "query", "anchor"]; -var qName ="queryKey"; -var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g; + window.addEventListener('message', messageHandler); + }); +} -// use the "loose" parser -/* eslint maxlen: 0, no-useless-escape: 0 */ -var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; +function start(cozy, intent, element) { + var data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; -function parseUri(str) { - var m = parser.exec(str); - var uri = {}; - var i = 14; + var service = (0, _helpers.pickService)(intent, options.filterServices); - while (i--) { - var key = keys[i]; - var value = m[i] || ""; - var encoded = ['user', 'password'].indexOf(key) !== -1; - uri[key] = encoded ? decodeURIComponent(value) : value; + if (!service) { + throw new Error('Unable to find a service'); } - uri[qName] = {}; - uri[keys[12]].replace(qParser, function ($0, $1, $2) { - if ($1) { - uri[qName][$1] = $2; - } - }); + var iframe = injectIntentIframe(intent, element, service.href, options); - return uri; + return connectIntentIframe(cozy, iframe, element, intent, data, options.onReadyCallback); } -// Based on https://github.com/alexdavid/scope-eval v0.0.3 -// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js) -// This is basically just a wrapper around new Function() +/***/ }), +/* 17 */ +/***/ (function(module, exports, __nested_webpack_require_110507__) { -function scopeEval(source, scope) { - var keys = []; - var values = []; - for (var key in scope) { - if (scope.hasOwnProperty(key)) { - keys.push(key); - values.push(scope[key]); - } - } - keys.push(source); - return Function.apply(null, keys).apply(null, values); -} +"use strict"; -// this is essentially the "update sugar" function from daleharvey/pouchdb#1388 -// the diffFun tells us what delta to apply to the doc. it either returns -// the doc, or false if it doesn't need to do an update after all -function upsert(db, docId, diffFun) { - return new Promise(function (fulfill, reject) { - db.get(docId, function (err, doc) { - if (err) { - /* istanbul ignore next */ - if (err.status !== 404) { - return reject(err); - } - doc = {}; - } - // the user might change the _rev, so save it for posterity - var docRev = doc._rev; - var newDoc = diffFun(doc); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.start = start; - if (!newDoc) { - // if the diffFun returns falsy, we short-circuit as - // an optimization - return fulfill({updated: false, rev: docRev}); - } +var _fetch = __nested_webpack_require_110507__(0); - // users aren't allowed to modify these values, - // so reset them here - newDoc._id = docId; - newDoc._rev = docRev; - fulfill(tryAndPut(db, newDoc, diffFun)); - }); - }); -} +var _helpers = __nested_webpack_require_110507__(5); -function tryAndPut(db, doc, diffFun) { - return db.put(doc).then(function (res) { - return { - updated: true, - rev: res.rev +function listenClientData(intent, window) { + return new Promise(function (resolve) { + var messageEventListener = function messageEventListener(event) { + if (event.origin !== intent.attributes.client) return; + + window.removeEventListener('message', messageEventListener); + resolve(event.data); }; - }, function (err) { - /* istanbul ignore next */ - if (err.status !== 409) { - throw err; - } - return upsert(db, doc._id, diffFun); + + window.addEventListener('message', messageEventListener); + window.parent.postMessage({ + type: 'intent-' + intent._id + ':ready' + }, intent.attributes.client); }); } -var thisAtob = function (str) { - return atob(str); -}; - -var thisBtoa = function (str) { - return btoa(str); -}; - -// Abstracts constructing a Blob object, so it also works in older -// browsers that don't support the native Blob constructor (e.g. -// old QtWebKit versions, Android < 4.4). -function createBlob(parts, properties) { - /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */ - parts = parts || []; - properties = properties || {}; - try { - return new Blob(parts, properties); - } catch (e) { - if (e.name !== "TypeError") { - throw e; - } - var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : - typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : - typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : - WebKitBlobBuilder; - var builder = new Builder(); - for (var i = 0; i < parts.length; i += 1) { - builder.append(parts[i]); - } - return builder.getBlob(properties.type); +// maximize the height of an element +function maximize(element) { + if (element && element.style) { + element.style.height = '100%'; } } -// From http://stackoverflow.com/questions/14967647/ (continues on next line) -// encode-decode-image-with-base64-breaks-image (2013-04-21) -function binaryStringToArrayBuffer(bin) { - var length = bin.length; - var buf = new ArrayBuffer(length); - var arr = new Uint8Array(buf); - for (var i = 0; i < length; i++) { - arr[i] = bin.charCodeAt(i); +function start(cozy, intentId, serviceWindow) { + serviceWindow = serviceWindow || typeof window !== 'undefined' && window; + if (!serviceWindow || !serviceWindow.document) { + return Promise.reject(new Error('Intent service should be used in browser')); } - return buf; -} -function binStringToBluffer(binString, type) { - return createBlob([binaryStringToArrayBuffer(binString)], {type: type}); -} + // Maximize document, the whole iframe is handled by intents, clients and + // services + serviceWindow.addEventListener('load', function () { + var _serviceWindow = serviceWindow, + document = _serviceWindow.document; + [document.documentElement, document.body].forEach(maximize); + }); -function b64ToBluffer(b64, type) { - return binStringToBluffer(thisAtob(b64), type); -} + intentId = intentId || serviceWindow.location.search.split('=')[1]; + if (!intentId) return Promise.reject(new Error('Cannot retrieve intent from URL')); -//Can't find original post, but this is close -//http://stackoverflow.com/questions/6965107/ (continues on next line) -//converting-between-strings-and-arraybuffers -function arrayBufferToBinaryString(buffer) { - var binary = ''; - var bytes = new Uint8Array(buffer); - var length = bytes.byteLength; - for (var i = 0; i < length; i++) { - binary += String.fromCharCode(bytes[i]); - } - return binary; -} + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/intents/' + intentId).then(function (intent) { + var terminated = false; -// shim for browsers that don't support it -function readAsBinaryString(blob, callback) { - var reader = new FileReader(); - var hasBinaryString = typeof reader.readAsBinaryString === 'function'; - reader.onloadend = function (e) { - var result = e.target.result || ''; - if (hasBinaryString) { - return callback(result); - } - callback(arrayBufferToBinaryString(result)); - }; - if (hasBinaryString) { - reader.readAsBinaryString(blob); - } else { - reader.readAsArrayBuffer(blob); - } -} + var sendMessage = function sendMessage(message) { + if (terminated) throw new Error('Intent service has already been terminated'); + serviceWindow.parent.postMessage(message, intent.attributes.client); + }; -function blobToBinaryString(blobOrBuffer, callback) { - readAsBinaryString(blobOrBuffer, function (bin) { - callback(bin); - }); -} + var compose = function compose(action, doctype, data) { + return new Promise(function (resolve) { + var composeEventListener = function composeEventListener(event) { + if (event.origin !== intent.attributes.client) return; + serviceWindow.removeEventListener('message', composeEventListener); + return resolve(event.data); + }; -function blobToBase64(blobOrBuffer, callback) { - blobToBinaryString(blobOrBuffer, function (base64) { - callback(thisBtoa(base64)); - }); -} + serviceWindow.addEventListener('message', composeEventListener); -// simplified API. universal browser support is assumed -function readAsArrayBuffer(blob, callback) { - var reader = new FileReader(); - reader.onloadend = function (e) { - var result = e.target.result || new ArrayBuffer(0); - callback(result); - }; - reader.readAsArrayBuffer(blob); -} + sendMessage({ + type: 'intent-' + intent._id + ':compose', + action: action, + doctype: doctype, + data: data + }); + }); + }; -// this is not used in the browser + var _terminate = function _terminate(message) { + sendMessage(message); + terminated = true; + }; -var setImmediateShim = global.setImmediate || global.setTimeout; -var MD5_CHUNK_SIZE = 32768; + var resizeClient = function resizeClient(dimensions, transitionProperty) { + if (terminated) throw new Error('Intent service has been terminated'); -function rawToBase64(raw) { - return thisBtoa(raw); -} + sendMessage({ + type: 'intent-' + intent._id + ':resize', + // if a dom element is passed, calculate its size + dimensions: dimensions.element ? Object.assign({}, dimensions, { + maxHeight: dimensions.element.clientHeight, + maxWidth: dimensions.element.clientWidth + }) : dimensions, + transition: transitionProperty + }); + }; -function sliceBlob(blob, start, end) { - if (blob.webkitSlice) { - return blob.webkitSlice(start, end); - } - return blob.slice(start, end); -} + var cancel = function cancel() { + _terminate({ type: 'intent-' + intent._id + ':cancel' }); + }; -function appendBlob(buffer, blob, start, end, callback) { - if (start > 0 || end < blob.size) { - // only slice blob if we really need to - blob = sliceBlob(blob, start, end); - } - readAsArrayBuffer(blob, function (arrayBuffer) { - buffer.append(arrayBuffer); - callback(); + // Prevent unfulfilled client promises when this window unloads for a + // reason or another. + serviceWindow.addEventListener('unload', function () { + if (!terminated) cancel(); + }); + + return listenClientData(intent, serviceWindow).then(function (data) { + return { + compose: compose, + getData: function getData() { + return data; + }, + getIntent: function getIntent() { + return intent; + }, + terminate: function terminate(doc) { + var eventName = data && data.exposeIntentFrameRemoval ? 'exposeFrameRemoval' : 'done'; + return _terminate({ + type: 'intent-' + intent._id + ':' + eventName, + document: doc + }); + }, + throw: function _throw(error) { + return _terminate({ + type: 'intent-' + intent._id + ':error', + error: _helpers.errorSerializer.serialize(error) + }); + }, + resizeClient: resizeClient, + cancel: cancel + }; + }); }); } -function appendString(buffer, string, start, end, callback) { - if (start > 0 || end < string.length) { - // only create a substring if we really need to - string = string.substring(start, end); - } - buffer.appendBinary(string); - callback(); -} +/***/ }), +/* 18 */ +/***/ (function(module, exports, __nested_webpack_require_114916__) { -function binaryMd5(data, callback) { - var inputIsString = typeof data === 'string'; - var len = inputIsString ? data.length : data.size; - var chunkSize = Math.min(MD5_CHUNK_SIZE, len); - var chunks = Math.ceil(len / chunkSize); - var currentChunk = 0; - var buffer = inputIsString ? new (spark_md5__WEBPACK_IMPORTED_MODULE_4___default())() : new (spark_md5__WEBPACK_IMPORTED_MODULE_4___default().ArrayBuffer)(); +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.count = count; +exports.queued = queued; +exports.create = create; - var append = inputIsString ? appendString : appendBlob; +var _fetch = __nested_webpack_require_114916__(0); - function next() { - setImmediateShim(loadNextChunk); - } +function count(cozy, workerType) { + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/jobs/queue/' + workerType).then(function (data) { + return data.length; + }); +} - function done() { - var raw = buffer.end(true); - var base64 = rawToBase64(raw); - callback(base64); - buffer.destroy(); - } +function queued(cozy, workerType) { + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/jobs/queue/' + workerType); +} - function loadNextChunk() { - var start = currentChunk * chunkSize; - var end = start + chunkSize; - currentChunk++; - if (currentChunk < chunks) { - append(buffer, data, start, end, next); - } else { - append(buffer, data, start, end, done); +function create(cozy, workerType, args, options) { + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/jobs/queue/' + workerType, { + data: { + type: 'io.cozy.jobs', + attributes: { + arguments: args || {}, + options: options || {} + } } - } - loadNextChunk(); + }); } -function stringMd5(string) { - return spark_md5__WEBPACK_IMPORTED_MODULE_4___default().hash(string); -} +/***/ }), +/* 19 */ +/***/ (function(module, exports, __nested_webpack_require_115746__) { -function rev$$1(doc, deterministic_revs) { - var clonedDoc = clone(doc); - if (!deterministic_revs) { - return uuid__WEBPACK_IMPORTED_MODULE_5___default().v4().replace(/-/g, '').toLowerCase(); - } +"use strict"; - delete clonedDoc._rev_tree; - return stringMd5(JSON.stringify(clonedDoc)); -} -var uuid = (uuid__WEBPACK_IMPORTED_MODULE_5___default().v4); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.replicationOfflineError = undefined; -// We fetch all leafs of the revision tree, and sort them based on tree length -// and whether they were deleted, undeleted documents with the longest revision -// tree (most edits) win -// The final sort algorithm is slightly documented in a sidebar here: -// http://guide.couchdb.org/draft/conflicts.html -function winningRev(metadata) { - var winningId; - var winningPos; - var winningDeleted; - var toVisit = metadata.rev_tree.slice(); - var node; - while ((node = toVisit.pop())) { - var tree = node.ids; - var branches = tree[2]; - var pos = node.pos; - if (branches.length) { // non-leaf - for (var i = 0, len = branches.length; i < len; i++) { - toVisit.push({pos: pos + 1, ids: branches[i]}); - } - continue; - } - var deleted = !!tree[1].deleted; - var id = tree[0]; - // sort by deleted, then pos, then id - if (!winningId || (winningDeleted !== deleted ? winningDeleted : - winningPos !== pos ? winningPos < pos : winningId < id)) { - winningId = id; - winningPos = pos; - winningDeleted = deleted; - } - } +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // Define global `fetch` so it's made available to `pouchdb-browser` - return winningPos + '-' + winningId; -} -// Pretty much all below can be combined into a higher order function to -// traverse revisions -// The return value from the callback will be passed as context to all -// children of that node -function traverseRevTree(revs, callback) { - var toVisit = revs.slice(); +exports.init = init; +exports.getDoctypes = getDoctypes; +exports.hasDatabase = hasDatabase; +exports.getDatabase = getDatabase; +exports.setDatabase = setDatabase; +exports.migrateDatabase = migrateDatabase; +exports.createDatabase = createDatabase; +exports.destroyDatabase = destroyDatabase; +exports.destroyAllDatabase = destroyAllDatabase; +exports.hasReplication = hasReplication; +exports.replicateFromCozy = replicateFromCozy; +exports.stopReplication = stopReplication; +exports.stopAllReplication = stopAllReplication; +exports.hasRepeatedReplication = hasRepeatedReplication; +exports.startRepeatedReplication = startRepeatedReplication; +exports.stopRepeatedReplication = stopRepeatedReplication; +exports.stopAllRepeatedReplication = stopAllRepeatedReplication; - var node; - while ((node = toVisit.pop())) { - var pos = node.pos; - var tree = node.ids; - var branches = tree[2]; - var newCtx = - callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]); - for (var i = 0, len = branches.length; i < len; i++) { - toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx}); - } - } -} +__nested_webpack_require_115746__(20); -function sortByPos(a, b) { - return a.pos - b.pos; -} +var _doctypes = __nested_webpack_require_115746__(2); -function collectLeaves(revs) { - var leaves = []; - traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) { - if (isLeaf) { - leaves.push({rev: pos + "-" + id, pos: pos, opts: opts}); - } - }); - leaves.sort(sortByPos).reverse(); - for (var i = 0, len = leaves.length; i < len; i++) { - delete leaves[i].pos; - } - return leaves; -} +var _auth_v = __nested_webpack_require_115746__(3); -// returns revs of all conflicts that is leaves such that -// 1. are not deleted and -// 2. are different than winning revision -function collectConflicts(metadata) { - var win = winningRev(metadata); - var leaves = collectLeaves(metadata.rev_tree); - var conflicts = []; - for (var i = 0, len = leaves.length; i < len; i++) { - var leaf = leaves[i]; - if (leaf.rev !== win && !leaf.opts.deleted) { - conflicts.push(leaf.rev); - } - } - return conflicts; -} +var _utils = __nested_webpack_require_115746__(1); -// compact a tree by marking its non-leafs as missing, -// and return a list of revs to delete -function compactTree(metadata) { - var revs = []; - traverseRevTree(metadata.rev_tree, function (isLeaf, pos, - revHash, ctx, opts) { - if (opts.status === 'available' && !isLeaf) { - revs.push(pos + '-' + revHash); - opts.status = 'missing'; - } - }); - return revs; -} +var _pouchdbBrowser = __nested_webpack_require_115746__(21); -// build up a list of all the paths to the leafs in this revision tree -function rootToLeaf(revs) { - var paths = []; - var toVisit = revs.slice(); - var node; - while ((node = toVisit.pop())) { - var pos = node.pos; - var tree = node.ids; - var id = tree[0]; - var opts = tree[1]; - var branches = tree[2]; - var isLeaf = branches.length === 0; +var _pouchdbBrowser2 = _interopRequireDefault(_pouchdbBrowser); - var history = node.history ? node.history.slice() : []; - history.push({id: id, opts: opts}); - if (isLeaf) { - paths.push({pos: (pos + 1 - history.length), ids: history}); - } - for (var i = 0, len = branches.length; i < len; i++) { - toVisit.push({pos: pos + 1, ids: branches[i], history: history}); - } - } - return paths.reverse(); -} +var _pouchdbFind = __nested_webpack_require_115746__(22); -// for a better overview of what this is doing, read: +var _pouchdbFind2 = _interopRequireDefault(_pouchdbFind); -function sortByPos$1(a, b) { - return a.pos - b.pos; -} +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -// classic binary search -function binarySearch(arr, item, comparator) { - var low = 0; - var high = arr.length; - var mid; - while (low < high) { - mid = (low + high) >>> 1; - if (comparator(arr[mid], item) < 0) { - low = mid + 1; - } else { - high = mid; - } - } - return low; -} +var replicationOfflineError = exports.replicationOfflineError = 'Replication abort, your device is actually offline.'; -// assuming the arr is sorted, insert the item in the proper place -function insertSorted(arr, item, comparator) { - var idx = binarySearch(arr, item, comparator); - arr.splice(idx, 0, item); -} +var pluginLoaded = false; -// Turn a path as a flat array into a tree with a single branch. -// If any should be stemmed from the beginning of the array, that's passed -// in as the second argument -function pathToTree(path, numStemmed) { - var root; - var leaf; - for (var i = numStemmed, len = path.length; i < len; i++) { - var node = path[i]; - var currentLeaf = [node.id, node.opts, []]; - if (leaf) { - leaf[2].push(currentLeaf); - leaf = currentLeaf; - } else { - root = leaf = currentLeaf; - } +/* + For each doctype we have some parameters: + cozy._offline[doctype] = { + database: pouchdb database + replication: the pouchdb replication + replicationPromise: promise of replication + interval: repeated replication interval } - return root; -} +*/ -// compare the IDs of two trees -function compareTree(a, b) { - return a[0] < b[0] ? -1 : 1; -} +function init(cozy, _ref) { + var _ref$options = _ref.options, + options = _ref$options === undefined ? {} : _ref$options, + _ref$doctypes = _ref.doctypes, + doctypes = _ref$doctypes === undefined ? [] : _ref$doctypes; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; -// Merge two trees together -// The roots of tree1 and tree2 must be the same revision -function mergeTree(in_tree1, in_tree2) { - var queue = [{tree1: in_tree1, tree2: in_tree2}]; - var conflicts = false; - while (queue.length > 0) { - var item = queue.pop(); - var tree1 = item.tree1; - var tree2 = item.tree2; + try { + for (var _iterator = doctypes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var doctype = _step.value; - if (tree1[1].status || tree2[1].status) { - tree1[1].status = - (tree1[1].status === 'available' || - tree2[1].status === 'available') ? 'available' : 'missing'; + createDatabase(cozy, doctype, options); } - - for (var i = 0; i < tree2[2].length; i++) { - if (!tree1[2][0]) { - conflicts = 'new_leaf'; - tree1[2][0] = tree2[2][i]; - continue; - } - - var merged = false; - for (var j = 0; j < tree1[2].length; j++) { - if (tree1[2][j][0] === tree2[2][i][0]) { - queue.push({tree1: tree1[2][j], tree2: tree2[2][i]}); - merged = true; - } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); } - if (!merged) { - conflicts = 'new_branch'; - insertSorted(tree1[2], tree2[2][i], compareTree); + } finally { + if (_didIteratorError) { + throw _iteratorError; } } } - return {conflicts: conflicts, tree: in_tree1}; } -function doMerge(tree, path, dontExpand) { - var restree = []; - var conflicts = false; - var merged = false; - var res; - - if (!tree.length) { - return {tree: [path], conflicts: 'new_leaf'}; - } +// helper - for (var i = 0, len = tree.length; i < len; i++) { - var branch = tree[i]; - if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) { - // Paths start at the same position and have the same root, so they need - // merged - res = mergeTree(branch.ids, path.ids); - restree.push({pos: branch.pos, ids: res.tree}); - conflicts = conflicts || res.conflicts; - merged = true; - } else if (dontExpand !== true) { - // The paths start at a different position, take the earliest path and - // traverse up until it as at the same point from root as the path we - // want to merge. If the keys match we return the longer path with the - // other merged After stemming we dont want to expand the trees +function getInfo(cozy, doctype) { + cozy._offline = cozy._offline || []; + cozy._offline[doctype] = cozy._offline[doctype] || {}; + return cozy._offline[doctype]; +} - var t1 = branch.pos < path.pos ? branch : path; - var t2 = branch.pos < path.pos ? path : branch; - var diff = t2.pos - t1.pos; +function getDoctypes(cozy) { + cozy._offline = cozy._offline || []; + return Object.keys(cozy._offline); +} - var candidateParents = []; +// +// DATABASE +// - var trees = []; - trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null}); - while (trees.length > 0) { - var item = trees.pop(); - if (item.diff === 0) { - if (item.ids[0] === t2.ids[0]) { - candidateParents.push(item); - } - continue; - } - var elements = item.ids[2]; - for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) { - trees.push({ - ids: elements[j], - diff: item.diff - 1, - parent: item.ids, - parentIdx: j - }); - } - } +function hasDatabase(cozy, doctype) { + return getDatabase(cozy, doctype) !== undefined; +} - var el = candidateParents[0]; +function getDatabase(cozy, doctype) { + return getInfo(cozy, doctype).database; +} - if (!el) { - restree.push(branch); - } else { - res = mergeTree(el.ids, t2.ids); - el.parent[2][el.parentIdx] = res.tree; - restree.push({pos: t1.pos, ids: t1.ids}); - conflicts = conflicts || res.conflicts; - merged = true; - } - } else { - restree.push(branch); - } - } +function setDatabase(cozy, doctype, database) { + cozy._offline[doctype].database = database; + return getDatabase(cozy, doctype); +} - // We didnt find - if (!merged) { - restree.push(path); - } +function migrateDatabase(cozy, doctype) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - restree.sort(sortByPos$1); + var oldDb = getDatabase(cozy, doctype); + var newOptions = _extends({ + adapter: 'idb' + }, options); + var newDb = new _pouchdbBrowser2.default(doctype, newOptions); - return { - tree: restree, - conflicts: conflicts || 'internal_node' - }; + return oldDb.replicate.to(newDb).then(function () { + setDatabase(cozy, doctype, newDb); + oldDb.destroy(); + return newDb; + }); } -// To ensure we dont grow the revision tree infinitely, we stem old revisions -function stem(tree, depth) { - // First we break out the tree into a complete list of root to leaf paths - var paths = rootToLeaf(tree); - var stemmedRevs; - - var result; - for (var i = 0, len = paths.length; i < len; i++) { - // Then for each path, we cut off the start of the path based on the - // `depth` to stem to, and generate a new set of flat trees - var path = paths[i]; - var stemmed = path.ids; - var node; - if (stemmed.length > depth) { - // only do the stemming work if we actually need to stem - if (!stemmedRevs) { - stemmedRevs = {}; // avoid allocating this object unnecessarily - } - var numStemmed = stemmed.length - depth; - node = { - pos: path.pos + numStemmed, - ids: pathToTree(stemmed, numStemmed) - }; +function createDatabase(cozy, doctype) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - for (var s = 0; s < numStemmed; s++) { - var rev = (path.pos + s) + '-' + stemmed[s].id; - stemmedRevs[rev] = true; - } - } else { // no need to actually stem - node = { - pos: path.pos, - ids: pathToTree(stemmed, 0) - }; - } + if (!pluginLoaded) { + _pouchdbBrowser2.default.plugin(_pouchdbFind2.default); + pluginLoaded = true; + } - // Then we remerge all those flat trees together, ensuring that we dont - // connect trees that would go beyond the depth limit - if (result) { - result = doMerge(result, node, true).tree; - } else { - result = [node]; - } + if (hasDatabase(cozy, doctype)) { + return Promise.resolve(getDatabase(cozy, doctype)); } - // this is memory-heavy per Chrome profiler, avoid unless we actually stemmed - if (stemmedRevs) { - traverseRevTree(result, function (isLeaf, pos, revHash) { - // some revisions may have been removed in a branch but not in another - delete stemmedRevs[pos + '-' + revHash]; - }); + setDatabase(cozy, doctype, new _pouchdbBrowser2.default(doctype, options)); + return createIndexes(cozy, doctype).then(function () { + return getDatabase(cozy, doctype); + }); +} + +function destroyDatabase(cozy, doctype) { + if (!hasDatabase(cozy, doctype)) { + return Promise.resolve(false); } - return { - tree: result, - revs: stemmedRevs ? Object.keys(stemmedRevs) : [] - }; + return stopRepeatedReplication(cozy, doctype).then(function () { + return stopReplication(cozy, doctype); + }).then(function () { + return getDatabase(cozy, doctype).destroy(); + }).then(function (response) { + setDatabase(cozy, doctype, undefined); + return response; + }); } -function merge(tree, path, depth) { - var newTree = doMerge(tree, path); - var stemmed = stem(newTree.tree, depth); - return { - tree: stemmed.tree, - stemmedRevs: stemmed.revs, - conflicts: newTree.conflicts +function destroyAllDatabase(cozy) { + var doctypes = getDoctypes(cozy); + var destroy = function destroy(doctype) { + return destroyDatabase(cozy, doctype); }; + return Promise.all(doctypes.map(destroy)); } -// return true if a rev exists in the rev tree, false otherwise -function revExists(revs, rev) { - var toVisit = revs.slice(); - var splitRev = rev.split('-'); - var targetPos = parseInt(splitRev[0], 10); - var targetId = splitRev[1]; - - var node; - while ((node = toVisit.pop())) { - if (node.pos === targetPos && node.ids[0] === targetId) { - return true; - } - var branches = node.ids[2]; - for (var i = 0, len = branches.length; i < len; i++) { - toVisit.push({pos: node.pos + 1, ids: branches[i]}); - } +function createIndexes(cozy, doctype) { + if (doctype === _doctypes.DOCTYPE_FILES) { + return getDatabase(cozy, doctype).createIndex({ + index: { fields: ['dir_id'] } + }); } - return false; + return Promise.resolve(); } -function getTrees(node) { - return node.ids; +// +// REPLICATION +// + +function hasReplication(cozy, doctype) { + return getReplication(cozy, doctype) !== undefined; } -// check if a specific revision of a doc has been deleted -// - metadata: the metadata object from the doc store -// - rev: (optional) the revision to check. defaults to winning revision -function isDeleted(metadata, rev) { - if (!rev) { - rev = winningRev(metadata); - } - var id = rev.substring(rev.indexOf('-') + 1); - var toVisit = metadata.rev_tree.map(getTrees); +function getReplication(cozy, doctype) { + return getInfo(cozy, doctype).replication; +} - var tree; - while ((tree = toVisit.pop())) { - if (tree[0] === id) { - return !!tree[1].deleted; - } - toVisit = toVisit.concat(tree[2]); - } +function setReplication(cozy, doctype, replication) { + cozy._offline[doctype].replication = replication; + return getReplication(cozy, doctype); } -function isLocalId(id) { - return (/^_local/).test(id); +function getReplicationUrl(cozy, doctype) { + return cozy.authorize().then(function (credentials) { + var basic = credentials.token.toBasicAuth(); + return (cozy._url + '/data/' + doctype).replace('//', '//' + basic); + }); } -// returns the current leaf node for a given revision -function latest(rev, metadata) { - var toVisit = metadata.rev_tree.slice(); - var node; - while ((node = toVisit.pop())) { - var pos = node.pos; - var tree = node.ids; - var id = tree[0]; - var opts = tree[1]; - var branches = tree[2]; - var isLeaf = branches.length === 0; +function getReplicationPromise(cozy, doctype) { + return getInfo(cozy, doctype).replicationPromise; +} - var history = node.history ? node.history.slice() : []; - history.push({id: id, pos: pos, opts: opts}); +function setReplicationPromise(cozy, doctype, promise) { + cozy._offline[doctype].replicationPromise = promise; + return getReplicationPromise(cozy, doctype); +} - if (isLeaf) { - for (var i = 0, len = history.length; i < len; i++) { - var historyNode = history[i]; - var historyRev = historyNode.pos + '-' + historyNode.id; +function replicateFromCozy(cozy, doctype) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - if (historyRev === rev) { - // return the rev of this leaf - return pos + '-' + id; - } - } + return setReplicationPromise(cozy, doctype, new Promise(function (resolve, reject) { + if (!hasDatabase(cozy, doctype)) { + createDatabase(cozy, doctype); + } + if (options.live === true) { + return reject(new Error("You can't use `live` option with Cozy couchdb.")); } - for (var j = 0, l = branches.length; j < l; j++) { - toVisit.push({pos: pos + 1, ids: branches[j], history: history}); + if ((0, _utils.isOffline)()) { + reject(replicationOfflineError); + options.onError && options.onError(replicationOfflineError); + return; } - } - /* istanbul ignore next */ - throw new Error('Unable to resolve latest revision for id ' + metadata.id + ', rev ' + rev); -} + getReplicationUrl(cozy, doctype).then(function (url) { + return setReplication(cozy, doctype, getDatabase(cozy, doctype).replicate.from(url, options).on('complete', function (info) { + setReplication(cozy, doctype, undefined); + resolve(info); + options.onComplete && options.onComplete(info); + }).on('error', function (err) { + if (err.error === 'code=400, message=Expired token') { + cozy.authorize().then(function (_ref2) { + var client = _ref2.client, + token = _ref2.token; -inherits__WEBPACK_IMPORTED_MODULE_3___default()(Changes$1, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); + (0, _auth_v.refreshToken)(cozy, client, token).then(function (newToken) { + return cozy.saveCredentials(client, newToken); + }).then(function () { + return replicateFromCozy(cozy, doctype, options); + }); + }); + } else { + console.warn('ReplicateFromCozy \'' + doctype + '\' Error:'); + console.warn(err); + setReplication(cozy, doctype, undefined); + reject(err); + options.onError && options.onError(err); + } + })); + }); + })); +} -function tryCatchInChangeListener(self, change, pending, lastSeq) { - // isolate try/catches to avoid V8 deoptimizations - try { - self.emit('change', change, pending, lastSeq); - } catch (e) { - guardedConsole('error', 'Error in .on("change", function):', e); +function stopReplication(cozy, doctype) { + if (!getDatabase(cozy, doctype) || !hasReplication(cozy, doctype)) { + return Promise.resolve(); } -} -function Changes$1(db, opts, callback) { - events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this); - var self = this; - this.db = db; - opts = opts ? clone(opts) : {}; - var complete = opts.complete = once(function (err, resp) { - if (err) { - if (listenerCount(self, 'error') > 0) { - self.emit('error', err); - } - } else { - self.emit('complete', resp); + return new Promise(function (resolve) { + try { + getReplicationPromise(cozy, doctype).then(function () { + resolve(); + }); + getReplication(cozy, doctype).cancel(); + // replication is set to undefined by complete replication + } catch (e) { + resolve(); } - self.removeAllListeners(); - db.removeListener('destroyed', onDestroy); }); - if (callback) { - self.on('complete', function (resp) { - callback(null, resp); - }); - self.on('error', callback); - } - function onDestroy() { - self.cancel(); - } - db.once('destroyed', onDestroy); +} - opts.onChange = function (change, pending, lastSeq) { - /* istanbul ignore if */ - if (self.isCancelled) { - return; - } - tryCatchInChangeListener(self, change, pending, lastSeq); +function stopAllReplication(cozy) { + var doctypes = getDoctypes(cozy); + var stop = function stop(doctype) { + return stopReplication(cozy, doctype); }; + return Promise.all(doctypes.map(stop)); +} - var promise = new Promise(function (fulfill, reject) { - opts.complete = function (err, res) { - if (err) { - reject(err); - } else { - fulfill(res); - } - }; - }); - self.once('cancel', function () { - db.removeListener('destroyed', onDestroy); - opts.complete(null, {status: 'cancelled'}); - }); - this.then = promise.then.bind(promise); - this['catch'] = promise['catch'].bind(promise); - this.then(function (result) { - complete(null, result); - }, complete); +// +// REPEATED REPLICATION +// +function getRepeatedReplication(cozy, doctype) { + return getInfo(cozy, doctype).interval; +} +function setRepeatedReplication(cozy, doctype, interval) { + cozy._offline[doctype].interval = interval; +} - if (!db.taskqueue.isReady) { - db.taskqueue.addTask(function (failed) { - if (failed) { - opts.complete(failed); - } else if (self.isCancelled) { - self.emit('cancel'); - } else { - self.validateChanges(opts); - } - }); - } else { - self.validateChanges(opts); - } +function hasRepeatedReplication(cozy, doctype) { + return getRepeatedReplication(cozy, doctype) !== undefined; } -Changes$1.prototype.cancel = function () { - this.isCancelled = true; - if (this.db.taskqueue.isReady) { - this.emit('cancel'); - } -}; -function processChange(doc, metadata, opts) { - var changeList = [{rev: doc._rev}]; - if (opts.style === 'all_docs') { - changeList = collectLeaves(metadata.rev_tree) - .map(function (x) { return {rev: x.rev}; }); - } - var change = { - id: metadata.id, - changes: changeList, - doc: doc - }; - if (isDeleted(metadata, doc._rev)) { - change.deleted = true; +function startRepeatedReplication(cozy, doctype, timer) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + // TODO: add timer limitation for not flooding Gozy + if (hasRepeatedReplication(cozy, doctype)) { + return getRepeatedReplication(cozy, doctype); } - if (opts.conflicts) { - change.doc._conflicts = collectConflicts(metadata); - if (!change.doc._conflicts.length) { - delete change.doc._conflicts; + + return setRepeatedReplication(cozy, doctype, setInterval(function () { + if ((0, _utils.isOffline)()) { + // network is offline, replication cannot be launched + console.info(replicationOfflineError); + return; + } + if (!hasReplication(cozy, doctype)) { + replicateFromCozy(cozy, doctype, options); + // TODO: add replicationToCozy } + }, timer * 1000)); +} + +function stopRepeatedReplication(cozy, doctype) { + if (hasRepeatedReplication(cozy, doctype)) { + clearInterval(getRepeatedReplication(cozy, doctype)); + setRepeatedReplication(cozy, doctype, undefined); } - return change; + if (hasReplication(cozy, doctype)) { + return stopReplication(cozy, doctype); + } + + return Promise.resolve(); } -Changes$1.prototype.validateChanges = function (opts) { - var callback = opts.complete; - var self = this; +function stopAllRepeatedReplication(cozy) { + var doctypes = getDoctypes(cozy); + var stop = function stop(doctype) { + return stopRepeatedReplication(cozy, doctype); + }; + return Promise.all(doctypes.map(stop)); +} - /* istanbul ignore else */ - if (PouchDB._changesFilterPlugin) { - PouchDB._changesFilterPlugin.validate(opts, function (err) { - if (err) { - return callback(err); - } - self.doChanges(opts); - }); - } else { - self.doChanges(opts); - } -}; +/***/ }), +/* 20 */ +/***/ (function(module, exports) { -Changes$1.prototype.doChanges = function (opts) { - var self = this; - var callback = opts.complete; +module.exports = __webpack_require__(491); - opts = clone(opts); - if ('live' in opts && !('continuous' in opts)) { - opts.continuous = opts.live; - } - opts.processChange = processChange; +/***/ }), +/* 21 */ +/***/ (function(module, exports) { - if (opts.since === 'latest') { - opts.since = 'now'; - } - if (!opts.since) { - opts.since = 0; - } - if (opts.since === 'now') { - this.db.info().then(function (info) { - /* istanbul ignore if */ - if (self.isCancelled) { - callback(null, {status: 'cancelled'}); - return; - } - opts.since = info.update_seq; - self.doChanges(opts); - }, callback); - return; - } +module.exports = __webpack_require__(494); - /* istanbul ignore else */ - if (PouchDB._changesFilterPlugin) { - PouchDB._changesFilterPlugin.normalize(opts); - if (PouchDB._changesFilterPlugin.shouldFilter(this, opts)) { - return PouchDB._changesFilterPlugin.filter(this, opts); - } - } else { - ['doc_ids', 'filter', 'selector', 'view'].forEach(function (key) { - if (key in opts) { - guardedConsole('warn', - 'The "' + key + '" option was passed in to changes/replicate, ' + - 'but pouchdb-changes-filter plugin is not installed, so it ' + - 'was ignored. Please install the plugin to enable filtering.' - ); - } - }); - } +/***/ }), +/* 22 */ +/***/ (function(module, exports) { - if (!('descending' in opts)) { - opts.descending = false; - } +module.exports = __webpack_require__(506); - // 0 and 1 should return 1 document - opts.limit = opts.limit === 0 ? 1 : opts.limit; - opts.complete = callback; - var newPromise = this.db._changes(opts); - /* istanbul ignore else */ - if (newPromise && typeof newPromise.cancel === 'function') { - var cancel = self.cancel; - self.cancel = argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { - newPromise.cancel(); - cancel.apply(this, args); - }); - } -}; +/***/ }), +/* 23 */ +/***/ (function(module, exports, __nested_webpack_require_126289__) { -/* - * A generic pouch adapter - */ +"use strict"; -function compare(left, right) { - return left < right ? -1 : left > right ? 1 : 0; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.diskUsage = diskUsage; +exports.changePassphrase = changePassphrase; +exports.getInstance = getInstance; +exports.updateInstance = updateInstance; +exports.getClients = getClients; +exports.deleteClientById = deleteClientById; +exports.updateLastSync = updateLastSync; + +var _fetch = __nested_webpack_require_126289__(0); + +function diskUsage(cozy) { + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/disk-usage'); } -// Wrapper for functions that call the bulkdocs api with a single doc, -// if the first result is an error, return an error -function yankError(callback, docId) { - return function (err, results) { - if (err || (results[0] && results[0].error)) { - err = err || results[0]; - err.docId = docId; - callback(err); - } else { - callback(null, results.length ? results[0] : results); - } - }; +function changePassphrase(cozy, currentPassPhrase, newPassPhrase) { + return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/settings/passphrase', { + current_passphrase: currentPassPhrase, + new_passphrase: newPassPhrase + }); } -// clean docs given to us by the user -function cleanDocs(docs) { - for (var i = 0; i < docs.length; i++) { - var doc = docs[i]; - if (doc._deleted) { - delete doc._attachments; // ignore atts for deleted docs - } else if (doc._attachments) { - // filter out extraneous keys from _attachments - var atts = Object.keys(doc._attachments); - for (var j = 0; j < atts.length; j++) { - var att = atts[j]; - doc._attachments[att] = pick(doc._attachments[att], - ['data', 'digest', 'content_type', 'length', 'revpos', 'stub']); - } - } - } +function getInstance(cozy) { + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/instance'); } -// compare two docs, first by _id then by _rev -function compareByIdThenRev(a, b) { - var idCompare = compare(a._id, b._id); - if (idCompare !== 0) { - return idCompare; - } - var aStart = a._revisions ? a._revisions.start : 0; - var bStart = b._revisions ? b._revisions.start : 0; - return compare(aStart, bStart); +function updateInstance(cozy, instance) { + return (0, _fetch.cozyFetchJSON)(cozy, 'PUT', '/settings/instance', instance); } -// for every node in a revision tree computes its distance from the closest -// leaf -function computeHeight(revs) { - var height = {}; - var edges = []; - traverseRevTree(revs, function (isLeaf, pos, id, prnt) { - var rev = pos + "-" + id; - if (isLeaf) { - height[rev] = 0; - } - if (prnt !== undefined) { - edges.push({from: prnt, to: rev}); - } - return rev; - }); +function getClients(cozy) { + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', '/settings/clients'); +} - edges.reverse(); - edges.forEach(function (edge) { - if (height[edge.from] === undefined) { - height[edge.from] = 1 + height[edge.to]; - } else { - height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]); - } - }); - return height; +function deleteClientById(cozy, id) { + return (0, _fetch.cozyFetchJSON)(cozy, 'DELETE', '/settings/clients/' + id); } -function allDocsKeysParse(opts) { - var keys = ('limit' in opts) ? - opts.keys.slice(opts.skip, opts.limit + opts.skip) : - (opts.skip > 0) ? opts.keys.slice(opts.skip) : opts.keys; - opts.keys = keys; - opts.skip = 0; - delete opts.limit; - if (opts.descending) { - keys.reverse(); - opts.descending = false; - } +function updateLastSync(cozy) { + return (0, _fetch.cozyFetchJSON)(cozy, 'POST', '/settings/synchronized'); +} + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __nested_webpack_require_127648__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.removeReferencedFiles = exports.addReferencedFiles = undefined; +exports.listReferencedFiles = listReferencedFiles; +exports.fetchReferencedFiles = fetchReferencedFiles; + +var _fetch = __nested_webpack_require_127648__(0); + +var _doctypes = __nested_webpack_require_127648__(2); + +function updateRelations(verb) { + return function (cozy, doc, ids) { + if (!doc) throw new Error('missing doc argument'); + if (!Array.isArray(ids)) ids = [ids]; + + var refs = ids.map(function (id) { + return { type: _doctypes.DOCTYPE_FILES, id: id }; + }); + + return (0, _fetch.cozyFetchJSON)(cozy, verb, makeReferencesPath(doc), { data: refs }); + }; } -// all compaction is done in a queue, to avoid attaching -// too many listeners at once -function doNextCompaction(self) { - var task = self._compactionQueue[0]; - var opts = task.opts; - var callback = task.callback; - self.get('_local/compaction').catch(function () { - return false; - }).then(function (doc) { - if (doc && doc.last_seq) { - opts.last_seq = doc.last_seq; - } - self._compact(opts, function (err, res) { - /* istanbul ignore if */ - if (err) { - callback(err); - } else { - callback(null, res); - } - immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { - self._compactionQueue.shift(); - if (self._compactionQueue.length) { - doNextCompaction(self); - } - }); +var addReferencedFiles = exports.addReferencedFiles = updateRelations('POST'); +var removeReferencedFiles = exports.removeReferencedFiles = updateRelations('DELETE'); + +function listReferencedFiles(cozy, doc) { + if (!doc) throw new Error('missing doc argument'); + return (0, _fetch.cozyFetchJSON)(cozy, 'GET', makeReferencesPath(doc)).then(function (files) { + return files.map(function (file) { + return file._id; }); }); } -function attachmentNameError(name) { - if (name.charAt(0) === '_') { - return name + ' is not a valid attachment name, attachment ' + - 'names cannot start with \'_\''; +function fetchReferencedFiles(cozy, doc, options, sort) { + if (!doc) throw new Error('missing doc argument'); + var params = Object.keys(options).map(function (key) { + var value = encodeURIComponent(JSON.stringify(options[key])); + return '&page[' + key + ']=' + value; + }).join(''); + // Datetime is the default sort, but 'id' is also available + if (!sort) { + sort = 'datetime'; } - return false; + return (0, _fetch.cozyFetchRawJSON)(cozy, 'GET', makeReferencesPath(doc) + '?include=files&sort=' + sort + params); } -inherits__WEBPACK_IMPORTED_MODULE_3___default()(AbstractPouchDB, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); +function makeReferencesPath(doc) { + var type = encodeURIComponent(doc._type); + var id = encodeURIComponent(doc._id); + return '/data/' + type + '/' + id + '/relationships/references'; +} -function AbstractPouchDB() { - events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this); +/***/ }) +/******/ ]))); +//# sourceMappingURL=cozy-client.node.js.map - // re-bind prototyped methods - for (var p in AbstractPouchDB.prototype) { - if (typeof this[p] === 'function') { - this[p] = this[p].bind(this); - } +/***/ }), +/* 487 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +module.exports = __webpack_require__(488); + + +/***/ }), +/* 488 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// This method of obtaining a reference to the global object needs to be +// kept identical to the way it is obtained in runtime.js +var g = (function() { return this })() || Function("return this")(); + +// Use `getOwnPropertyNames` because not all browsers support calling +// `hasOwnProperty` on the global `self` object in a worker. See #183. +var hadRuntime = g.regeneratorRuntime && + Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0; + +// Save the old regeneratorRuntime in case it needs to be restored later. +var oldRuntime = hadRuntime && g.regeneratorRuntime; + +// Force reevalutation of runtime.js. +g.regeneratorRuntime = undefined; + +module.exports = __webpack_require__(489); + +if (hadRuntime) { + // Restore the original runtime. + g.regeneratorRuntime = oldRuntime; +} else { + // Remove the global property added by runtime.js. + try { + delete g.regeneratorRuntime; + } catch(e) { + g.regeneratorRuntime = undefined; } } -AbstractPouchDB.prototype.post = - adapterFun('post', function (doc, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - if (typeof doc !== 'object' || Array.isArray(doc)) { - return callback(createError(NOT_AN_OBJECT)); - } - this.bulkDocs({docs: [doc]}, opts, yankError(callback, doc._id)); -}); -AbstractPouchDB.prototype.put = adapterFun('put', function (doc, opts, cb) { - if (typeof opts === 'function') { - cb = opts; - opts = {}; - } - if (typeof doc !== 'object' || Array.isArray(doc)) { - return cb(createError(NOT_AN_OBJECT)); - } - invalidIdError(doc._id); - if (isLocalId(doc._id) && typeof this._putLocal === 'function') { - if (doc._deleted) { - return this._removeLocal(doc, cb); - } else { - return this._putLocal(doc, cb); - } - } - var self = this; - if (opts.force && doc._rev) { - transformForceOptionToNewEditsOption(); - putDoc(function (err) { - var result = err ? null : {ok: true, id: doc._id, rev: doc._rev}; - cb(err, result); - }); - } else { - putDoc(cb); - } +/***/ }), +/* 489 */ +/***/ ((module) => { - function transformForceOptionToNewEditsOption() { - var parts = doc._rev.split('-'); - var oldRevId = parts[1]; - var oldRevNum = parseInt(parts[0], 10); +/** + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ - var newRevNum = oldRevNum + 1; - var newRevId = rev$$1(); +!(function(global) { + "use strict"; - doc._revisions = { - start: newRevNum, - ids: [newRevId, oldRevId] - }; - doc._rev = newRevNum + '-' + newRevId; - opts.new_edits = false; - } - function putDoc(next) { - if (typeof self._put === 'function' && opts.new_edits !== false) { - self._put(doc, opts, next); - } else { - self.bulkDocs({docs: [doc]}, opts, yankError(next, doc._id)); + var Op = Object.prototype; + var hasOwn = Op.hasOwnProperty; + var undefined; // More compressible than void 0. + var $Symbol = typeof Symbol === "function" ? Symbol : {}; + var iteratorSymbol = $Symbol.iterator || "@@iterator"; + var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; + var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; + + var inModule = "object" === "object"; + var runtime = global.regeneratorRuntime; + if (runtime) { + if (inModule) { + // If regeneratorRuntime is defined globally and we're in a module, + // make the exports object identical to regeneratorRuntime. + module.exports = runtime; } + // Don't bother evaluating the rest of this file if the runtime was + // already defined globally. + return; } -}); -AbstractPouchDB.prototype.putAttachment = - adapterFun('putAttachment', function (docId, attachmentId, rev, - blob, type) { - var api = this; - if (typeof type === 'function') { - type = blob; - blob = rev; - rev = null; - } - // Lets fix in https://github.com/pouchdb/pouchdb/issues/3267 - /* istanbul ignore if */ - if (typeof type === 'undefined') { - type = blob; - blob = rev; - rev = null; - } - if (!type) { - guardedConsole('warn', 'Attachment', attachmentId, 'on document', docId, 'is missing content_type'); - } + // Define the runtime globally (as expected by generated code) as either + // module.exports (if we're in a module) or a new, empty object. + runtime = global.regeneratorRuntime = inModule ? module.exports : {}; - function createAttachment(doc) { - var prevrevpos = '_rev' in doc ? parseInt(doc._rev, 10) : 0; - doc._attachments = doc._attachments || {}; - doc._attachments[attachmentId] = { - content_type: type, - data: blob, - revpos: ++prevrevpos - }; - return api.put(doc); + function wrap(innerFn, outerFn, self, tryLocsList) { + // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. + var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; + var generator = Object.create(protoGenerator.prototype); + var context = new Context(tryLocsList || []); + + // The ._invoke method unifies the implementations of the .next, + // .throw, and .return methods. + generator._invoke = makeInvokeMethod(innerFn, self, context); + + return generator; } + runtime.wrap = wrap; - return api.get(docId).then(function (doc) { - if (doc._rev !== rev) { - throw createError(REV_CONFLICT); + // Try/catch helper to minimize deoptimizations. Returns a completion + // record like context.tryEntries[i].completion. This interface could + // have been (and was previously) designed to take a closure to be + // invoked without arguments, but in all the cases we care about we + // already have an existing method we want to call, so there's no need + // to create a new function object. We can even get away with assuming + // the method takes exactly one argument, since that happens to be true + // in every case, so we don't have to touch the arguments object. The + // only additional allocation required is the completion record, which + // has a stable shape and so hopefully should be cheap to allocate. + function tryCatch(fn, obj, arg) { + try { + return { type: "normal", arg: fn.call(obj, arg) }; + } catch (err) { + return { type: "throw", arg: err }; } + } - return createAttachment(doc); - }, function (err) { - // create new doc - /* istanbul ignore else */ - if (err.reason === MISSING_DOC.message) { - return createAttachment({_id: docId}); - } else { - throw err; - } - }); -}); + var GenStateSuspendedStart = "suspendedStart"; + var GenStateSuspendedYield = "suspendedYield"; + var GenStateExecuting = "executing"; + var GenStateCompleted = "completed"; -AbstractPouchDB.prototype.removeAttachment = - adapterFun('removeAttachment', function (docId, attachmentId, rev, - callback) { - var self = this; - self.get(docId, function (err, obj) { - /* istanbul ignore if */ - if (err) { - callback(err); - return; - } - if (obj._rev !== rev) { - callback(createError(REV_CONFLICT)); - return; - } - /* istanbul ignore if */ - if (!obj._attachments) { - return callback(); - } - delete obj._attachments[attachmentId]; - if (Object.keys(obj._attachments).length === 0) { - delete obj._attachments; - } - self.put(obj, callback); - }); -}); + // Returning this object from the innerFn has the same effect as + // breaking out of the dispatch switch statement. + var ContinueSentinel = {}; -AbstractPouchDB.prototype.remove = - adapterFun('remove', function (docOrId, optsOrRev, opts, callback) { - var doc; - if (typeof optsOrRev === 'string') { - // id, rev, opts, callback style - doc = { - _id: docOrId, - _rev: optsOrRev - }; - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - } else { - // doc, opts, callback style - doc = docOrId; - if (typeof optsOrRev === 'function') { - callback = optsOrRev; - opts = {}; - } else { - callback = opts; - opts = optsOrRev; - } - } - opts = opts || {}; - opts.was_delete = true; - var newDoc = {_id: doc._id, _rev: (doc._rev || opts.rev)}; - newDoc._deleted = true; - if (isLocalId(newDoc._id) && typeof this._removeLocal === 'function') { - return this._removeLocal(doc, callback); - } - this.bulkDocs({docs: [newDoc]}, opts, yankError(callback, newDoc._id)); -}); + // Dummy constructor functions that we use as the .constructor and + // .constructor.prototype properties for functions that return Generator + // objects. For full spec compliance, you may wish to configure your + // minifier not to mangle the names of these two functions. + function Generator() {} + function GeneratorFunction() {} + function GeneratorFunctionPrototype() {} -AbstractPouchDB.prototype.revsDiff = - adapterFun('revsDiff', function (req, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - var ids = Object.keys(req); + // This is a polyfill for %IteratorPrototype% for environments that + // don't natively support it. + var IteratorPrototype = {}; + IteratorPrototype[iteratorSymbol] = function () { + return this; + }; - if (!ids.length) { - return callback(null, {}); + var getProto = Object.getPrototypeOf; + var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); + if (NativeIteratorPrototype && + NativeIteratorPrototype !== Op && + hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { + // This environment has a native %IteratorPrototype%; use it instead + // of the polyfill. + IteratorPrototype = NativeIteratorPrototype; } - var count = 0; - var missing = new ExportedMap(); + var Gp = GeneratorFunctionPrototype.prototype = + Generator.prototype = Object.create(IteratorPrototype); + GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; + GeneratorFunctionPrototype.constructor = GeneratorFunction; + GeneratorFunctionPrototype[toStringTagSymbol] = + GeneratorFunction.displayName = "GeneratorFunction"; - function addToMissing(id, revId) { - if (!missing.has(id)) { - missing.set(id, {missing: []}); - } - missing.get(id).missing.push(revId); + // Helper for defining the .next, .throw, and .return methods of the + // Iterator interface in terms of a single ._invoke method. + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function(method) { + prototype[method] = function(arg) { + return this._invoke(method, arg); + }; + }); } - function processDoc(id, rev_tree) { - // Is this fast enough? Maybe we should switch to a set simulated by a map - var missingForId = req[id].slice(0); - traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx, - opts) { - var rev = pos + '-' + revHash; - var idx = missingForId.indexOf(rev); - if (idx === -1) { - return; - } + runtime.isGeneratorFunction = function(genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor + ? ctor === GeneratorFunction || + // For the native GeneratorFunction constructor, the best we can + // do is to check its .name property. + (ctor.displayName || ctor.name) === "GeneratorFunction" + : false; + }; - missingForId.splice(idx, 1); - /* istanbul ignore if */ - if (opts.status !== 'available') { - addToMissing(id, rev); - } - }); + runtime.mark = function(genFun) { + if (Object.setPrototypeOf) { + Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); + } else { + genFun.__proto__ = GeneratorFunctionPrototype; + if (!(toStringTagSymbol in genFun)) { + genFun[toStringTagSymbol] = "GeneratorFunction"; + } + } + genFun.prototype = Object.create(Gp); + return genFun; + }; - // Traversing the tree is synchronous, so now `missingForId` contains - // revisions that were not found in the tree - missingForId.forEach(function (rev) { - addToMissing(id, rev); - }); - } + // Within the body of any async function, `await x` is transformed to + // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test + // `hasOwn.call(value, "__await")` to determine if the yielded value is + // meant to be awaited. + runtime.awrap = function(arg) { + return { __await: arg }; + }; - ids.map(function (id) { - this._getRevisionTree(id, function (err, rev_tree) { - if (err && err.status === 404 && err.message === 'missing') { - missing.set(id, {missing: req[id]}); - } else if (err) { - /* istanbul ignore next */ - return callback(err); + function AsyncIterator(generator) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); + if (record.type === "throw") { + reject(record.arg); } else { - processDoc(id, rev_tree); - } + var result = record.arg; + var value = result.value; + if (value && + typeof value === "object" && + hasOwn.call(value, "__await")) { + return Promise.resolve(value.__await).then(function(value) { + invoke("next", value, resolve, reject); + }, function(err) { + invoke("throw", err, resolve, reject); + }); + } - if (++count === ids.length) { - // convert LazyMap to object - var missingObj = {}; - missing.forEach(function (value, key) { - missingObj[key] = value; - }); - return callback(null, missingObj); + return Promise.resolve(value).then(function(unwrapped) { + // When a yielded Promise is resolved, its final value becomes + // the .value of the Promise<{value,done}> result for the + // current iteration. If the Promise is rejected, however, the + // result for this iteration will be rejected with the same + // reason. Note that rejections of yielded Promises are not + // thrown back into the generator function, as is the case + // when an awaited Promise is rejected. This difference in + // behavior between yield and await is important, because it + // allows the consumer to decide what to do with the yielded + // rejection (swallow it and continue, manually .throw it back + // into the generator, abandon iteration, whatever). With + // await, by contrast, there is no opportunity to examine the + // rejection reason outside the generator function, so the + // only option is to throw it from the await expression, and + // let the generator function handle the exception. + result.value = unwrapped; + resolve(result); + }, reject); } - }); - }, this); -}); + } -// _bulk_get API for faster replication, as described in -// https://github.com/apache/couchdb-chttpd/pull/33 -// At the "abstract" level, it will just run multiple get()s in -// parallel, because this isn't much of a performance cost -// for local databases (except the cost of multiple transactions, which is -// small). The http adapter overrides this in order -// to do a more efficient single HTTP request. -AbstractPouchDB.prototype.bulkGet = - adapterFun('bulkGet', function (opts, callback) { - bulkGet(this, opts, callback); -}); + var previousPromise; -// compact one document and fire callback -// by compacting we mean removing all revisions which -// are further from the leaf in revision tree than max_height -AbstractPouchDB.prototype.compactDocument = - adapterFun('compactDocument', function (docId, maxHeight, callback) { - var self = this; - this._getRevisionTree(docId, function (err, revTree) { - /* istanbul ignore if */ - if (err) { - return callback(err); - } - var height = computeHeight(revTree); - var candidates = []; - var revs = []; - Object.keys(height).forEach(function (rev) { - if (height[rev] > maxHeight) { - candidates.push(rev); + function enqueue(method, arg) { + function callInvokeWithMethodAndArg() { + return new Promise(function(resolve, reject) { + invoke(method, arg, resolve, reject); + }); } - }); - traverseRevTree(revTree, function (isLeaf, pos, revHash, ctx, opts) { - var rev = pos + '-' + revHash; - if (opts.status === 'available' && candidates.indexOf(rev) !== -1) { - revs.push(rev); - } - }); - self._doCompaction(docId, revs, callback); - }); -}); + return previousPromise = + // If enqueue has been called before, then we want to wait until + // all previous Promises have been resolved before calling invoke, + // so that results are always delivered in the correct order. If + // enqueue has not been called before, then it is important to + // call invoke immediately, without waiting on a callback to fire, + // so that the async generator function has the opportunity to do + // any necessary setup in a predictable way. This predictability + // is why the Promise constructor synchronously invokes its + // executor callback, and why async functions synchronously + // execute code before the first await. Since we implement simple + // async functions in terms of async generators, it is especially + // important to get this right, even though it requires care. + previousPromise ? previousPromise.then( + callInvokeWithMethodAndArg, + // Avoid propagating failures to Promises returned by later + // invocations of the iterator. + callInvokeWithMethodAndArg + ) : callInvokeWithMethodAndArg(); + } -// compact the whole database using single document -// compaction -AbstractPouchDB.prototype.compact = - adapterFun('compact', function (opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; + // Define the unified helper method that is used to implement .next, + // .throw, and .return (see defineIteratorMethods). + this._invoke = enqueue; } - var self = this; - opts = opts || {}; + defineIteratorMethods(AsyncIterator.prototype); + AsyncIterator.prototype[asyncIteratorSymbol] = function () { + return this; + }; + runtime.AsyncIterator = AsyncIterator; - self._compactionQueue = self._compactionQueue || []; - self._compactionQueue.push({opts: opts, callback: callback}); - if (self._compactionQueue.length === 1) { - doNextCompaction(self); - } -}); -AbstractPouchDB.prototype._compact = function (opts, callback) { - var self = this; - var changesOpts = { - return_docs: false, - last_seq: opts.last_seq || 0 + // Note that simple async functions are implemented on top of + // AsyncIterator objects; they just return a Promise for the value of + // the final result produced by the iterator. + runtime.async = function(innerFn, outerFn, self, tryLocsList) { + var iter = new AsyncIterator( + wrap(innerFn, outerFn, self, tryLocsList) + ); + + return runtime.isGeneratorFunction(outerFn) + ? iter // If outerFn is a generator, return the full iterator. + : iter.next().then(function(result) { + return result.done ? result.value : iter.next(); + }); }; - var promises = []; - function onChange(row) { - promises.push(self.compactDocument(row.id, 0)); - } - function onComplete(resp) { - var lastSeq = resp.last_seq; - Promise.all(promises).then(function () { - return upsert(self, '_local/compaction', function deltaFunc(doc) { - if (!doc.last_seq || doc.last_seq < lastSeq) { - doc.last_seq = lastSeq; - return doc; + function makeInvokeMethod(innerFn, self, context) { + var state = GenStateSuspendedStart; + + return function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } + + if (state === GenStateCompleted) { + if (method === "throw") { + throw arg; } - return false; // somebody else got here first, don't update - }); - }).then(function () { - callback(null, {ok: true}); - }).catch(callback); - } - self.changes(changesOpts) - .on('change', onChange) - .on('complete', onComplete) - .on('error', callback); -}; -/* Begin api wrappers. Specific functionality to storage belongs in the - _[method] */ -AbstractPouchDB.prototype.get = adapterFun('get', function (id, opts, cb) { - if (typeof opts === 'function') { - cb = opts; - opts = {}; - } - if (typeof id !== 'string') { - return cb(createError(INVALID_ID)); - } - if (isLocalId(id) && typeof this._getLocal === 'function') { - return this._getLocal(id, cb); - } - var leaves = [], self = this; + // Be forgiving, per 25.3.3.3.3 of the spec: + // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume + return doneResult(); + } - function finishOpenRevs() { - var result = []; - var count = leaves.length; - /* istanbul ignore if */ - if (!count) { - return cb(null, result); - } + context.method = method; + context.arg = arg; - // order with open_revs is unspecified - leaves.forEach(function (leaf) { - self.get(id, { - rev: leaf, - revs: opts.revs, - latest: opts.latest, - attachments: opts.attachments, - binary: opts.binary - }, function (err, doc) { - if (!err) { - // using latest=true can produce duplicates - var existing; - for (var i = 0, l = result.length; i < l; i++) { - if (result[i].ok && result[i].ok._rev === doc._rev) { - existing = true; - break; - } - } - if (!existing) { - result.push({ok: doc}); + while (true) { + var delegate = context.delegate; + if (delegate) { + var delegateResult = maybeInvokeDelegate(delegate, context); + if (delegateResult) { + if (delegateResult === ContinueSentinel) continue; + return delegateResult; } - } else { - result.push({missing: leaf}); } - count--; - if (!count) { - cb(null, result); - } - }); - }); - } - if (opts.open_revs) { - if (opts.open_revs === "all") { - this._getRevisionTree(id, function (err, rev_tree) { - /* istanbul ignore if */ - if (err) { - return cb(err); + if (context.method === "next") { + // Setting context._sent for legacy support of Babel's + // function.sent implementation. + context.sent = context._sent = context.arg; + + } else if (context.method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw context.arg; + } + + context.dispatchException(context.arg); + + } else if (context.method === "return") { + context.abrupt("return", context.arg); } - leaves = collectLeaves(rev_tree).map(function (leaf) { - return leaf.rev; - }); - finishOpenRevs(); - }); - } else { - if (Array.isArray(opts.open_revs)) { - leaves = opts.open_revs; - for (var i = 0; i < leaves.length; i++) { - var l = leaves[i]; - // looks like it's the only thing couchdb checks - if (!(typeof (l) === "string" && /^\d+-/.test(l))) { - return cb(createError(INVALID_REV)); + + state = GenStateExecuting; + + var record = tryCatch(innerFn, self, context); + if (record.type === "normal") { + // If an exception is thrown from innerFn, we leave state === + // GenStateExecuting and loop back for another invocation. + state = context.done + ? GenStateCompleted + : GenStateSuspendedYield; + + if (record.arg === ContinueSentinel) { + continue; } + + return { + value: record.arg, + done: context.done + }; + + } else if (record.type === "throw") { + state = GenStateCompleted; + // Dispatch the exception by looping back around to the + // context.dispatchException(context.arg) call above. + context.method = "throw"; + context.arg = record.arg; } - finishOpenRevs(); - } else { - return cb(createError(UNKNOWN_ERROR, 'function_clause')); } - } - return; // open_revs does not like other options + }; } - return this._get(id, opts, function (err, result) { - if (err) { - err.docId = id; - return cb(err); - } + // Call delegate.iterator[context.method](context.arg) and handle the + // result, either by returning a { value, done } result from the + // delegate iterator, or by modifying context.method and context.arg, + // setting context.delegate to null, and returning the ContinueSentinel. + function maybeInvokeDelegate(delegate, context) { + var method = delegate.iterator[context.method]; + if (method === undefined) { + // A .throw or .return when the delegate iterator has no .throw + // method always terminates the yield* loop. + context.delegate = null; - var doc = result.doc; - var metadata = result.metadata; - var ctx = result.ctx; + if (context.method === "throw") { + if (delegate.iterator.return) { + // If the delegate iterator has a return method, give it a + // chance to clean up. + context.method = "return"; + context.arg = undefined; + maybeInvokeDelegate(delegate, context); - if (opts.conflicts) { - var conflicts = collectConflicts(metadata); - if (conflicts.length) { - doc._conflicts = conflicts; + if (context.method === "throw") { + // If maybeInvokeDelegate(context) changed context.method from + // "return" to "throw", let that override the TypeError below. + return ContinueSentinel; + } + } + + context.method = "throw"; + context.arg = new TypeError( + "The iterator does not provide a 'throw' method"); } - } - if (isDeleted(metadata, doc._rev)) { - doc._deleted = true; + return ContinueSentinel; } - if (opts.revs || opts.revs_info) { - var splittedRev = doc._rev.split('-'); - var revNo = parseInt(splittedRev[0], 10); - var revHash = splittedRev[1]; + var record = tryCatch(method, delegate.iterator, context.arg); - var paths = rootToLeaf(metadata.rev_tree); - var path = null; + if (record.type === "throw") { + context.method = "throw"; + context.arg = record.arg; + context.delegate = null; + return ContinueSentinel; + } - for (var i = 0; i < paths.length; i++) { - var currentPath = paths[i]; - var hashIndex = currentPath.ids.map(function (x) { return x.id; }) - .indexOf(revHash); - var hashFoundAtRevPos = hashIndex === (revNo - 1); + var info = record.arg; - if (hashFoundAtRevPos || (!path && hashIndex !== -1)) { - path = currentPath; - } - } + if (! info) { + context.method = "throw"; + context.arg = new TypeError("iterator result is not an object"); + context.delegate = null; + return ContinueSentinel; + } - var indexOfRev = path.ids.map(function (x) { return x.id; }) - .indexOf(doc._rev.split('-')[1]) + 1; - var howMany = path.ids.length - indexOfRev; - path.ids.splice(indexOfRev, howMany); - path.ids.reverse(); + if (info.done) { + // Assign the result of the finished delegate to the temporary + // variable specified by delegate.resultName (see delegateYield). + context[delegate.resultName] = info.value; - if (opts.revs) { - doc._revisions = { - start: (path.pos + path.ids.length) - 1, - ids: path.ids.map(function (rev) { - return rev.id; - }) - }; - } - if (opts.revs_info) { - var pos = path.pos + path.ids.length; - doc._revs_info = path.ids.map(function (rev) { - pos--; - return { - rev: pos + '-' + rev.id, - status: rev.opts.status - }; - }); - } - } + // Resume execution at the desired location (see delegateYield). + context.next = delegate.nextLoc; - if (opts.attachments && doc._attachments) { - var attachments = doc._attachments; - var count = Object.keys(attachments).length; - if (count === 0) { - return cb(null, doc); + // If context.method was "throw" but the delegate handled the + // exception, let the outer generator proceed normally. If + // context.method was "next", forget context.arg since it has been + // "consumed" by the delegate iterator. If context.method was + // "return", allow the original .return call to continue in the + // outer generator. + if (context.method !== "return") { + context.method = "next"; + context.arg = undefined; } - Object.keys(attachments).forEach(function (key) { - this._getAttachment(doc._id, key, attachments[key], { - // Previously the revision handling was done in adapter.js - // getAttachment, however since idb-next doesnt we need to - // pass the rev through - rev: doc._rev, - binary: opts.binary, - ctx: ctx - }, function (err, data) { - var att = doc._attachments[key]; - att.data = data; - delete att.stub; - delete att.length; - if (!--count) { - cb(null, doc); - } - }); - }, self); + } else { - if (doc._attachments) { - for (var key in doc._attachments) { - /* istanbul ignore else */ - if (doc._attachments.hasOwnProperty(key)) { - doc._attachments[key].stub = true; - } - } - } - cb(null, doc); + // Re-yield the result returned by the delegate method. + return info; } - }); -}); -// TODO: I dont like this, it forces an extra read for every -// attachment read and enforces a confusing api between -// adapter.js and the adapter implementation -AbstractPouchDB.prototype.getAttachment = - adapterFun('getAttachment', function (docId, attachmentId, opts, callback) { - var self = this; - if (opts instanceof Function) { - callback = opts; - opts = {}; + // The delegate iterator is finished, so forget it and continue with + // the outer generator. + context.delegate = null; + return ContinueSentinel; } - this._get(docId, opts, function (err, res) { - if (err) { - return callback(err); + + // Define Generator.prototype.{next,throw,return} in terms of the + // unified ._invoke helper method. + defineIteratorMethods(Gp); + + Gp[toStringTagSymbol] = "Generator"; + + // A Generator should always return itself as the iterator object when the + // @@iterator function is called on it. Some browsers' implementations of the + // iterator prototype chain incorrectly implement this, causing the Generator + // object to not be returned from this call. This ensures that doesn't happen. + // See https://github.com/facebook/regenerator/issues/274 for more details. + Gp[iteratorSymbol] = function() { + return this; + }; + + Gp.toString = function() { + return "[object Generator]"; + }; + + function pushTryEntry(locs) { + var entry = { tryLoc: locs[0] }; + + if (1 in locs) { + entry.catchLoc = locs[1]; } - if (res.doc._attachments && res.doc._attachments[attachmentId]) { - opts.ctx = res.ctx; - opts.binary = true; - self._getAttachment(docId, attachmentId, - res.doc._attachments[attachmentId], opts, callback); - } else { - return callback(createError(MISSING_DOC)); + + if (2 in locs) { + entry.finallyLoc = locs[2]; + entry.afterLoc = locs[3]; } - }); -}); -AbstractPouchDB.prototype.allDocs = - adapterFun('allDocs', function (opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; + this.tryEntries.push(entry); } - opts.skip = typeof opts.skip !== 'undefined' ? opts.skip : 0; - if (opts.start_key) { - opts.startkey = opts.start_key; + + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal"; + delete record.arg; + entry.completion = record; } - if (opts.end_key) { - opts.endkey = opts.end_key; + + function Context(tryLocsList) { + // The root entry object (effectively a try statement without a catch + // or a finally block) gives us a place to store values thrown from + // locations where there is no enclosing try statement. + this.tryEntries = [{ tryLoc: "root" }]; + tryLocsList.forEach(pushTryEntry, this); + this.reset(true); } - if ('keys' in opts) { - if (!Array.isArray(opts.keys)) { - return callback(new TypeError('options.keys must be an array')); - } - var incompatibleOpt = - ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) { - return incompatibleOpt in opts; - })[0]; - if (incompatibleOpt) { - callback(createError(QUERY_PARSE_ERROR, - 'Query parameter `' + incompatibleOpt + - '` is not compatible with multi-get' - )); - return; + + runtime.keys = function(object) { + var keys = []; + for (var key in object) { + keys.push(key); } - if (!isRemote(this)) { - allDocsKeysParse(opts); - if (opts.keys.length === 0) { - return this._allDocs({limit: 0}, callback); + keys.reverse(); + + // Rather than returning an object with a next method, we keep + // things simple and return the next function itself. + return function next() { + while (keys.length) { + var key = keys.pop(); + if (key in object) { + next.value = key; + next.done = false; + return next; + } } - } - } - return this._allDocs(opts, callback); -}); + // To avoid creating an additional object, we just hang the .value + // and .done properties off the next function object itself. This + // also ensures that the minifier will not anonymize the function. + next.done = true; + return next; + }; + }; -AbstractPouchDB.prototype.changes = function (opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } - opts = opts || {}; + if (typeof iterable.next === "function") { + return iterable; + } - // By default set return_docs to false if the caller has opts.live = true, - // this will prevent us from collecting the set of changes indefinitely - // resulting in growing memory - opts.return_docs = ('return_docs' in opts) ? opts.return_docs : !opts.live; + if (!isNaN(iterable.length)) { + var i = -1, next = function next() { + while (++i < iterable.length) { + if (hasOwn.call(iterable, i)) { + next.value = iterable[i]; + next.done = false; + return next; + } + } - return new Changes$1(this, opts, callback); -}; + next.value = undefined; + next.done = true; -AbstractPouchDB.prototype.close = adapterFun('close', function (callback) { - this._closed = true; - this.emit('closed'); - return this._close(callback); -}); + return next; + }; -AbstractPouchDB.prototype.info = adapterFun('info', function (callback) { - var self = this; - this._info(function (err, info) { - if (err) { - return callback(err); + return next.next = next; + } } - // assume we know better than the adapter, unless it informs us - info.db_name = info.db_name || self.name; - info.auto_compaction = !!(self.auto_compaction && !isRemote(self)); - info.adapter = self.adapter; - callback(null, info); - }); -}); - -AbstractPouchDB.prototype.id = adapterFun('id', function (callback) { - return this._id(callback); -}); -/* istanbul ignore next */ -AbstractPouchDB.prototype.type = function () { - return (typeof this._type === 'function') ? this._type() : this.adapter; -}; + // Return an iterator with no values. + return { next: doneResult }; + } + runtime.values = values; -AbstractPouchDB.prototype.bulkDocs = - adapterFun('bulkDocs', function (req, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; + function doneResult() { + return { value: undefined, done: true }; } - opts = opts || {}; + Context.prototype = { + constructor: Context, - if (Array.isArray(req)) { - req = { - docs: req - }; - } + reset: function(skipTempReset) { + this.prev = 0; + this.next = 0; + // Resetting context._sent for legacy support of Babel's + // function.sent implementation. + this.sent = this._sent = undefined; + this.done = false; + this.delegate = null; - if (!req || !req.docs || !Array.isArray(req.docs)) { - return callback(createError(MISSING_BULK_DOCS)); - } + this.method = "next"; + this.arg = undefined; - for (var i = 0; i < req.docs.length; ++i) { - if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) { - return callback(createError(NOT_AN_OBJECT)); - } - } + this.tryEntries.forEach(resetTryEntry); - var attachmentError; - req.docs.forEach(function (doc) { - if (doc._attachments) { - Object.keys(doc._attachments).forEach(function (name) { - attachmentError = attachmentError || attachmentNameError(name); - if (!doc._attachments[name].content_type) { - guardedConsole('warn', 'Attachment', name, 'on document', doc._id, 'is missing content_type'); + if (!skipTempReset) { + for (var name in this) { + // Not sure about the optimal order of these conditions: + if (name.charAt(0) === "t" && + hasOwn.call(this, name) && + !isNaN(+name.slice(1))) { + this[name] = undefined; + } } - }); - } - }); + } + }, - if (attachmentError) { - return callback(createError(BAD_REQUEST, attachmentError)); - } + stop: function() { + this.done = true; - if (!('new_edits' in opts)) { - if ('new_edits' in req) { - opts.new_edits = req.new_edits; - } else { - opts.new_edits = true; - } - } + var rootEntry = this.tryEntries[0]; + var rootRecord = rootEntry.completion; + if (rootRecord.type === "throw") { + throw rootRecord.arg; + } - var adapter = this; - if (!opts.new_edits && !isRemote(adapter)) { - // ensure revisions of the same doc are sorted, so that - // the local adapter processes them correctly (#2935) - req.docs.sort(compareByIdThenRev); - } + return this.rval; + }, - cleanDocs(req.docs); + dispatchException: function(exception) { + if (this.done) { + throw exception; + } - // in the case of conflicts, we want to return the _ids to the user - // however, the underlying adapter may destroy the docs array, so - // create a copy here - var ids = req.docs.map(function (doc) { - return doc._id; - }); + var context = this; + function handle(loc, caught) { + record.type = "throw"; + record.arg = exception; + context.next = loc; - return this._bulkDocs(req, opts, function (err, res) { - if (err) { - return callback(err); - } - if (!opts.new_edits) { - // this is what couch does when new_edits is false - res = res.filter(function (x) { - return x.error; - }); - } - // add ids for error/conflict responses (not required for CouchDB) - if (!isRemote(adapter)) { - for (var i = 0, l = res.length; i < l; i++) { - res[i].id = res[i].id || ids[i]; + if (caught) { + // If the dispatched exception was caught by a catch block, + // then let that catch block handle the exception normally. + context.method = "next"; + context.arg = undefined; + } + + return !! caught; } - } - callback(null, res); - }); -}); + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + var record = entry.completion; -AbstractPouchDB.prototype.registerDependentDatabase = - adapterFun('registerDependentDatabase', function (dependentDb, - callback) { - var depDB = new this.constructor(dependentDb, this.__opts); + if (entry.tryLoc === "root") { + // Exception thrown outside of any try block that could handle + // it, so set the completion value of the entire function to + // throw the exception. + return handle("end"); + } - function diffFun(doc) { - doc.dependentDbs = doc.dependentDbs || {}; - if (doc.dependentDbs[dependentDb]) { - return false; // no update required - } - doc.dependentDbs[dependentDb] = true; - return doc; - } - upsert(this, '_local/_pouch_dependentDbs', diffFun) - .then(function () { - callback(null, {db: depDB}); - }).catch(callback); -}); + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"); + var hasFinally = hasOwn.call(entry, "finallyLoc"); -AbstractPouchDB.prototype.destroy = - adapterFun('destroy', function (opts, callback) { + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } else if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } + } else if (hasCatch) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } - var self = this; - var usePrefix = 'use_prefix' in self ? self.use_prefix : true; + } else if (hasFinally) { + if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } - function destroyDb() { - // call destroy method of the particular adaptor - self._destroy(opts, function (err, resp) { - if (err) { - return callback(err); + } else { + throw new Error("try statement without catch or finally"); + } + } } - self._destroyed = true; - self.emit('destroyed'); - callback(null, resp || { 'ok': true }); - }); - } + }, - if (isRemote(self)) { - // no need to check for dependent DBs if it's a remote DB - return destroyDb(); - } + abrupt: function(type, arg) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && + hasOwn.call(entry, "finallyLoc") && + this.prev < entry.finallyLoc) { + var finallyEntry = entry; + break; + } + } - self.get('_local/_pouch_dependentDbs', function (err, localDoc) { - if (err) { - /* istanbul ignore if */ - if (err.status !== 404) { - return callback(err); - } else { // no dependencies - return destroyDb(); + if (finallyEntry && + (type === "break" || + type === "continue") && + finallyEntry.tryLoc <= arg && + arg <= finallyEntry.finallyLoc) { + // Ignore the finally entry if control is not jumping to a + // location outside the try/catch block. + finallyEntry = null; } - } - var dependentDbs = localDoc.dependentDbs; - var PouchDB = self.constructor; - var deletedMap = Object.keys(dependentDbs).map(function (name) { - // use_prefix is only false in the browser - /* istanbul ignore next */ - var trueName = usePrefix ? - name.replace(new RegExp('^' + PouchDB.prefix), '') : name; - return new PouchDB(trueName, self.__opts).destroy(); - }); - Promise.all(deletedMap).then(destroyDb, callback); - }); -}); -function TaskQueue() { - this.isReady = false; - this.failed = false; - this.queue = []; -} + var record = finallyEntry ? finallyEntry.completion : {}; + record.type = type; + record.arg = arg; -TaskQueue.prototype.execute = function () { - var fun; - if (this.failed) { - while ((fun = this.queue.shift())) { - fun(this.failed); - } - } else { - while ((fun = this.queue.shift())) { - fun(); - } - } -}; + if (finallyEntry) { + this.method = "next"; + this.next = finallyEntry.finallyLoc; + return ContinueSentinel; + } -TaskQueue.prototype.fail = function (err) { - this.failed = err; - this.execute(); -}; + return this.complete(record); + }, -TaskQueue.prototype.ready = function (db) { - this.isReady = true; - this.db = db; - this.execute(); -}; + complete: function(record, afterLoc) { + if (record.type === "throw") { + throw record.arg; + } -TaskQueue.prototype.addTask = function (fun) { - this.queue.push(fun); - if (this.failed) { - this.execute(); - } -}; + if (record.type === "break" || + record.type === "continue") { + this.next = record.arg; + } else if (record.type === "return") { + this.rval = this.arg = record.arg; + this.method = "return"; + this.next = "end"; + } else if (record.type === "normal" && afterLoc) { + this.next = afterLoc; + } -function parseAdapter(name, opts) { - var match = name.match(/([a-z-]*):\/\/(.*)/); - if (match) { - // the http adapter expects the fully qualified name - return { - name: /https?/.test(match[1]) ? match[1] + '://' + match[2] : match[2], - adapter: match[1] - }; - } + return ContinueSentinel; + }, - var adapters = PouchDB.adapters; - var preferredAdapters = PouchDB.preferredAdapters; - var prefix = PouchDB.prefix; - var adapterName = opts.adapter; + finish: function(finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.finallyLoc === finallyLoc) { + this.complete(entry.completion, entry.afterLoc); + resetTryEntry(entry); + return ContinueSentinel; + } + } + }, - if (!adapterName) { // automatically determine adapter - for (var i = 0; i < preferredAdapters.length; ++i) { - adapterName = preferredAdapters[i]; - // check for browsers that have been upgraded from websql-only to websql+idb - /* istanbul ignore if */ - if (adapterName === 'idb' && 'websql' in adapters && - hasLocalStorage() && localStorage['_pouch__websqldb_' + prefix + name]) { - // log it, because this can be confusing during development - guardedConsole('log', 'PouchDB is downgrading "' + name + '" to WebSQL to' + - ' avoid data loss, because it was already opened with WebSQL.'); - continue; // keep using websql to avoid user data loss + "catch": function(tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if (record.type === "throw") { + var thrown = record.arg; + resetTryEntry(entry); + } + return thrown; + } } - break; - } - } - var adapter = adapters[adapterName]; + // The context.catch method must only be called with a location + // argument that corresponds to a known catch block. + throw new Error("illegal catch attempt"); + }, - // if adapter is invalid, then an error will be thrown later - var usePrefix = (adapter && 'use_prefix' in adapter) ? - adapter.use_prefix : true; + delegateYield: function(iterable, resultName, nextLoc) { + this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }; - return { - name: usePrefix ? (prefix + name) : name, - adapter: adapterName + if (this.method === "next") { + // Deliberately forget the last sent value so that we don't + // accidentally pass it on to the delegate. + this.arg = undefined; + } + + return ContinueSentinel; + } }; -} +})( + // In sloppy mode, unbound `this` refers to the global object, fallback to + // Function constructor if we're in global strict mode. That is sadly a form + // of indirect eval which violates Content Security Policy. + (function() { return this })() || Function("return this")() +); -// OK, so here's the deal. Consider this code: -// var db1 = new PouchDB('foo'); -// var db2 = new PouchDB('foo'); -// db1.destroy(); -// ^ these two both need to emit 'destroyed' events, -// as well as the PouchDB constructor itself. -// So we have one db object (whichever one got destroy() called on it) -// responsible for emitting the initial event, which then gets emitted -// by the constructor, which then broadcasts it to any other dbs -// that may have been created with the same name. -function prepareForDestruction(self) { - function onDestroyed(from_constructor) { - self.removeListener('closed', onClosed); - if (!from_constructor) { - self.constructor.emit('destroyed', self.name); +/***/ }), +/* 490 */ +/***/ ((module) => { + +(function () { + "use strict"; + + function btoa(str) { + var buffer; + + if (str instanceof Buffer) { + buffer = str; + } else { + buffer = Buffer.from(str.toString(), 'binary'); } - } - function onClosed() { - self.removeListener('destroyed', onDestroyed); - self.constructor.emit('unref', self); + return buffer.toString('base64'); } - self.once('destroyed', onDestroyed); - self.once('closed', onClosed); - self.constructor.emit('ref', self); + module.exports = btoa; +}()); + + +/***/ }), +/* 491 */ +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +const fetchNode = __webpack_require__(492) +const fetch = fetchNode.fetch.bind({}) + +fetch.polyfill = true + +if (!global.fetch) { + global.fetch = fetch + global.Response = fetchNode.Response + global.Headers = fetchNode.Headers + global.Request = fetchNode.Request } -inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchDB, AbstractPouchDB); -function PouchDB(name, opts) { - // In Node our test suite only tests this for PouchAlt unfortunately - /* istanbul ignore if */ - if (!(this instanceof PouchDB)) { - return new PouchDB(name, opts); - } - var self = this; - opts = opts || {}; +/***/ }), +/* 492 */ +/***/ ((module, exports, __webpack_require__) => { - if (name && typeof name === 'object') { - opts = name; - name = opts.name; - delete opts.name; - } +const nodeFetch = __webpack_require__(493) +const realFetch = nodeFetch.default || nodeFetch - if (opts.deterministic_revs === undefined) { - opts.deterministic_revs = true; +const fetch = function (url, options) { + // Support schemaless URIs on the server for parity with the browser. + // Ex: //github.com/ -> https://github.com/ + if (/^\/\//.test(url)) { + url = 'https:' + url } + return realFetch.call(this, url, options) +} - this.__opts = opts = clone(opts); +fetch.ponyfill = true - self.auto_compaction = opts.auto_compaction; - self.prefix = PouchDB.prefix; +module.exports = exports = fetch +exports.fetch = fetch +exports.Headers = nodeFetch.Headers +exports.Request = nodeFetch.Request +exports.Response = nodeFetch.Response - if (typeof name !== 'string') { - throw new Error('Missing/invalid DB name'); - } +// Needed for TypeScript consumers without esModuleInterop. +exports["default"] = fetch - var prefixedName = (opts.prefix || '') + name; - var backend = parseAdapter(prefixedName, opts); - opts.name = backend.name; - opts.adapter = opts.adapter || backend.adapter; +/***/ }), +/* 493 */ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - self.name = name; - self._adapter = opts.adapter; - PouchDB.emit('debug', ['adapter', 'Picked adapter: ', opts.adapter]); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), +/* harmony export */ "Headers": () => (/* binding */ Headers), +/* harmony export */ "Request": () => (/* binding */ Request), +/* harmony export */ "Response": () => (/* binding */ Response), +/* harmony export */ "FetchError": () => (/* binding */ FetchError) +/* harmony export */ }); +/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82); +/* harmony import */ var http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(80); +/* harmony import */ var url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(63); +/* harmony import */ var https__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(81); +/* harmony import */ var zlib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(83); - if (!PouchDB.adapters[opts.adapter] || - !PouchDB.adapters[opts.adapter].valid()) { - throw new Error('Invalid Adapter: ' + opts.adapter); - } - AbstractPouchDB.call(self); - self.taskqueue = new TaskQueue(); - self.adapter = opts.adapter; - PouchDB.adapters[opts.adapter].call(self, opts, function (err) { - if (err) { - return self.taskqueue.fail(err); - } - prepareForDestruction(self); - self.emit('created', self); - PouchDB.emit('created', self.name); - self.taskqueue.ready(self); - }); -} +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js -// AbortController was introduced quite a while after fetch and -// isnt required for PouchDB to function so polyfill if needed -var a = (typeof AbortController !== 'undefined') - ? AbortController - : function () { return {abort: function () {}}; }; +// fix for "Readable" isn't a named export issue +const Readable = stream__WEBPACK_IMPORTED_MODULE_0__.Readable; -var f$1 = fetch; -var h = Headers; +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); -PouchDB.adapters = {}; -PouchDB.preferredAdapters = []; +class Blob { + constructor() { + this[TYPE] = ''; -PouchDB.prefix = '_pouch_'; + const blobParts = arguments[0]; + const options = arguments[1]; -var eventEmitter = new events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter(); + const buffers = []; + let size = 0; -function setUpEventEmitter(Pouch) { - Object.keys(events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype).forEach(function (key) { - if (typeof events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype[key] === 'function') { - Pouch[key] = eventEmitter[key].bind(eventEmitter); - } - }); + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } - // these are created in constructor.js, and allow us to notify each DB with - // the same name that it was destroyed, via the constructor object - var destructListeners = Pouch._destructionListeners = new ExportedMap(); + this[BUFFER] = Buffer.concat(buffers); - Pouch.on('ref', function onConstructorRef(db) { - if (!destructListeners.has(db.name)) { - destructListeners.set(db.name, []); - } - destructListeners.get(db.name).push(db); - }); + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; - Pouch.on('unref', function onConstructorUnref(db) { - if (!destructListeners.has(db.name)) { - return; - } - var dbList = destructListeners.get(db.name); - var pos = dbList.indexOf(db); - if (pos < 0) { - /* istanbul ignore next */ - return; - } - dbList.splice(pos, 1); - if (dbList.length > 1) { - /* istanbul ignore next */ - destructListeners.set(db.name, dbList); - } else { - destructListeners.delete(db.name); - } - }); + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); - Pouch.on('destroyed', function onConstructorDestroyed(name) { - if (!destructListeners.has(name)) { - return; - } - var dbList = destructListeners.get(name); - destructListeners.delete(name); - dbList.forEach(function (db) { - db.emit('destroyed',true); - }); - }); + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } } -setUpEventEmitter(PouchDB); - -PouchDB.adapter = function (id, obj, addToPreferredAdapters) { - /* istanbul ignore else */ - if (obj.valid()) { - PouchDB.adapters[id] = obj; - if (addToPreferredAdapters) { - PouchDB.preferredAdapters.push(id); - } - } -}; +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); -PouchDB.plugin = function (obj) { - if (typeof obj === 'function') { // function style for plugins - obj(PouchDB); - } else if (typeof obj !== 'object' || Object.keys(obj).length === 0) { - throw new Error('Invalid plugin: got "' + obj + '", expected an object or a function'); - } else { - Object.keys(obj).forEach(function (id) { // object style for plugins - PouchDB.prototype[id] = obj[id]; - }); - } - if (this.__defaults) { - PouchDB.__defaults = $inject_Object_assign({}, this.__defaults); - } - return PouchDB; -}; +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); -PouchDB.defaults = function (defaultOpts) { - function PouchAlt(name, opts) { - if (!(this instanceof PouchAlt)) { - return new PouchAlt(name, opts); - } +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ - opts = opts || {}; +/** + * Create FetchError instance + * + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError + */ +function FetchError(message, type, systemError) { + Error.call(this, message); - if (name && typeof name === 'object') { - opts = name; - name = opts.name; - delete opts.name; - } + this.message = message; + this.type = type; - opts = $inject_Object_assign({}, PouchAlt.__defaults, opts); - PouchDB.call(this, name, opts); + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; } - inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchAlt, PouchDB); + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} - PouchAlt.preferredAdapters = PouchDB.preferredAdapters.slice(); - Object.keys(PouchDB).forEach(function (key) { - if (!(key in PouchAlt)) { - PouchAlt[key] = PouchDB[key]; - } - }); +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; - // make default options transitive - // https://github.com/pouchdb/pouchdb/issues/5922 - PouchAlt.__defaults = $inject_Object_assign({}, this.__defaults, defaultOpts); +let convert; +try { + convert = require('encoding').convert; +} catch (e) {} - return PouchAlt; -}; +const INTERNALS = Symbol('Body internals'); -PouchDB.fetch = function (url, opts) { - return f$1(url, opts); -}; +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = stream__WEBPACK_IMPORTED_MODULE_0__.PassThrough; -// managed automatically by set-version.js -var version = "7.0.0"; +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +function Body(body) { + var _this = this; -// this would just be "return doc[field]", but fields -// can be "deep" due to dot notation -function getFieldFromDoc(doc, parsedField) { - var value = doc; - for (var i = 0, len = parsedField.length; i < len; i++) { - var key = parsedField[i]; - value = value[key]; - if (!value) { - break; - } - } - return value; -} + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; -function compare$1(left, right) { - return left < right ? -1 : left > right ? 1 : 0; -} + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; -// Converts a string in dot notation to an array of its components, with backslash escaping -function parseField(fieldName) { - // fields may be deep (e.g. "foo.bar.baz"), so parse - var fields = []; - var current = ''; - for (var i = 0, len = fieldName.length; i < len; i++) { - var ch = fieldName[i]; - if (ch === '.') { - if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter - current = current.substring(0, current.length - 1) + '.'; - } else { // not escaped, so delimiter - fields.push(current); - current = ''; - } - } else { // normal character - current += ch; - } - } - fields.push(current); - return fields; -} + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; -var combinationFields = ['$or', '$nor', '$not']; -function isCombinationalField(field) { - return combinationFields.indexOf(field) > -1; + if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } } -function getKey(obj) { - return Object.keys(obj)[0]; -} +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, -function getValue(obj) { - return obj[getKey(obj)]; -} + get bodyUsed() { + return this[INTERNALS].disturbed; + }, + + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, + + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, + + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; + + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, + + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; + + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); + +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; + +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +function consumeBody() { + var _this4 = this; + + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } -// flatten an array of selectors joined by an $and operator -function mergeAndedSelectors(selectors) { + this[INTERNALS].disturbed = true; - // sort to ensure that e.g. if the user specified - // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into - // just {$gt: 'b'} - var res = {}; + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } - selectors.forEach(function (selector) { - Object.keys(selector).forEach(function (field) { - var matcher = selector[field]; - if (typeof matcher !== 'object') { - matcher = {$eq: matcher}; - } + let body = this.body; - if (isCombinationalField(field)) { - if (matcher instanceof Array) { - res[field] = matcher.map(function (m) { - return mergeAndedSelectors([m]); - }); - } else { - res[field] = mergeAndedSelectors([matcher]); - } - } else { - var fieldMatchers = res[field] = res[field] || {}; - Object.keys(matcher).forEach(function (operator) { - var value = matcher[operator]; + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } - if (operator === '$gt' || operator === '$gte') { - return mergeGtGte(operator, value, fieldMatchers); - } else if (operator === '$lt' || operator === '$lte') { - return mergeLtLte(operator, value, fieldMatchers); - } else if (operator === '$ne') { - return mergeNe(value, fieldMatchers); - } else if (operator === '$eq') { - return mergeEq(value, fieldMatchers); - } - fieldMatchers[operator] = value; - }); - } - }); - }); + // body is blob + if (isBlob(body)) { + body = body.stream(); + } - return res; -} + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + // istanbul ignore if: should never happen + if (!(body instanceof stream__WEBPACK_IMPORTED_MODULE_0__)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; -// collapse logically equivalent gt/gte values -function mergeGtGte(operator, value, fieldMatchers) { - if (typeof fieldMatchers.$eq !== 'undefined') { - return; // do nothing - } - if (typeof fieldMatchers.$gte !== 'undefined') { - if (operator === '$gte') { - if (value > fieldMatchers.$gte) { // more specificity - fieldMatchers.$gte = value; - } - } else { // operator === '$gt' - if (value >= fieldMatchers.$gte) { // more specificity - delete fieldMatchers.$gte; - fieldMatchers.$gt = value; - } - } - } else if (typeof fieldMatchers.$gt !== 'undefined') { - if (operator === '$gte') { - if (value > fieldMatchers.$gt) { // more specificity - delete fieldMatchers.$gt; - fieldMatchers.$gte = value; - } - } else { // operator === '$gt' - if (value > fieldMatchers.$gt) { // more specificity - fieldMatchers.$gt = value; - } - } - } else { - fieldMatchers[operator] = value; - } -} + return new Body.Promise(function (resolve, reject) { + let resTimeout; -// collapse logically equivalent lt/lte values -function mergeLtLte(operator, value, fieldMatchers) { - if (typeof fieldMatchers.$eq !== 'undefined') { - return; // do nothing - } - if (typeof fieldMatchers.$lte !== 'undefined') { - if (operator === '$lte') { - if (value < fieldMatchers.$lte) { // more specificity - fieldMatchers.$lte = value; - } - } else { // operator === '$gt' - if (value <= fieldMatchers.$lte) { // more specificity - delete fieldMatchers.$lte; - fieldMatchers.$lt = value; - } - } - } else if (typeof fieldMatchers.$lt !== 'undefined') { - if (operator === '$lte') { - if (value < fieldMatchers.$lt) { // more specificity - delete fieldMatchers.$lt; - fieldMatchers.$lte = value; - } - } else { // operator === '$gt' - if (value < fieldMatchers.$lt) { // more specificity - fieldMatchers.$lt = value; - } - } - } else { - fieldMatchers[operator] = value; - } -} + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } -// combine $ne values into one array -function mergeNe(value, fieldMatchers) { - if ('$ne' in fieldMatchers) { - // there are many things this could "not" be - fieldMatchers.$ne.push(value); - } else { // doesn't exist yet - fieldMatchers.$ne = [value]; - } -} + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); -// add $eq into the mix -function mergeEq(value, fieldMatchers) { - // these all have less specificity than the $eq - // TODO: check for user errors here - delete fieldMatchers.$gt; - delete fieldMatchers.$gte; - delete fieldMatchers.$lt; - delete fieldMatchers.$lte; - delete fieldMatchers.$ne; - fieldMatchers.$eq = value; -} + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } -// -// normalize the selector -// -function massageSelector(input) { - var result = clone(input); - var wasAnded = false; - if ('$and' in result) { - result = mergeAndedSelectors(result['$and']); - wasAnded = true; - } + accumBytes += chunk.length; + accum.push(chunk); + }); - ['$or', '$nor'].forEach(function (orOrNor) { - if (orOrNor in result) { - // message each individual selector - // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}} - result[orOrNor].forEach(function (subSelector) { - var fields = Object.keys(subSelector); - for (var i = 0; i < fields.length; i++) { - var field = fields[i]; - var matcher = subSelector[field]; - if (typeof matcher !== 'object' || matcher === null) { - subSelector[field] = {$eq: matcher}; - } - } - }); - } - }); + body.on('end', function () { + if (abort) { + return; + } - if ('$not' in result) { - //This feels a little like forcing, but it will work for now, - //I would like to come back to this and make the merging of selectors a little more generic - result['$not'] = mergeAndedSelectors([result['$not']]); - } + clearTimeout(resTimeout); - var fields = Object.keys(result); + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} - for (var i = 0; i < fields.length; i++) { - var field = fields[i]; - var matcher = result[field]; +/** + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String + */ +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } - if (typeof matcher !== 'object' || matcher === null) { - matcher = {$eq: matcher}; - } else if ('$ne' in matcher && !wasAnded) { - // I put these in an array, since there may be more than one - // but in the "mergeAnded" operation, I already take care of that - matcher.$ne = [matcher.$ne]; - } - result[field] = matcher; - } + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; - return result; -} + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } -function pad(str, padWith, upToLength) { - var padding = ''; - var targetLength = upToLength - str.length; - /* istanbul ignore next */ - while (padding.length < targetLength) { - padding += padWith; - } - return padding; -} + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); -function padLeft(str, padWith, upToLength) { - var padding = pad(str, padWith, upToLength); - return padding + str; -} + // html5 + if (!res && str) { + res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str); + } -var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE -var MAGNITUDE_DIGITS = 3; // ditto -var SEP = ''; // set to '_' for easier debugging + // html4 + if (!res && str) { + res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str); + if (!res) { + res = /<meta[\s]+?content=(['"])(.+?)\1[\s]+?http-equiv=(['"])content-type\3/i.exec(str); + if (res) { + res.pop(); // drop last quote + } + } -function collate(a, b) { + if (res) { + res = /charset=(.*)/i.exec(res.pop()); + } + } - if (a === b) { - return 0; - } + // xml + if (!res && str) { + res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str); + } - a = normalizeKey(a); - b = normalizeKey(b); + // found charset + if (res) { + charset = res.pop(); - var ai = collationIndex(a); - var bi = collationIndex(b); - if ((ai - bi) !== 0) { - return ai - bi; - } - switch (typeof a) { - case 'number': - return a - b; - case 'boolean': - return a < b ? -1 : 1; - case 'string': - return stringCollate(a, b); - } - return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b); -} + // prevent decode issues when sites use incorrect encoding + // ref: https://hsivonen.fi/encoding-menu/ + if (charset === 'gb2312' || charset === 'gbk') { + charset = 'gb18030'; + } + } -// couch considers null/NaN/Infinity/-Infinity === undefined, -// for the purposes of mapreduce indexes. also, dates get stringified. -function normalizeKey(key) { - switch (typeof key) { - case 'undefined': - return null; - case 'number': - if (key === Infinity || key === -Infinity || isNaN(key)) { - return null; - } - return key; - case 'object': - var origKey = key; - if (Array.isArray(key)) { - var len = key.length; - key = new Array(len); - for (var i = 0; i < len; i++) { - key[i] = normalizeKey(origKey[i]); - } - /* istanbul ignore next */ - } else if (key instanceof Date) { - return key.toJSON(); - } else if (key !== null) { // generic object - key = {}; - for (var k in origKey) { - if (origKey.hasOwnProperty(k)) { - var val = origKey[k]; - if (typeof val !== 'undefined') { - key[k] = normalizeKey(val); - } - } - } - } - } - return key; + // turn raw buffers into a single utf-8 buffer + return convert(buffer, 'UTF-8', charset).toString(); } -function indexify(key) { - if (key !== null) { - switch (typeof key) { - case 'boolean': - return key ? 1 : 0; - case 'number': - return numToIndexableString(key); - case 'string': - // We've to be sure that key does not contain \u0000 - // Do order-preserving replacements: - // 0 -> 1, 1 - // 1 -> 1, 2 - // 2 -> 2, 2 - /* eslint-disable no-control-regex */ - return key - .replace(/\u0002/g, '\u0002\u0002') - .replace(/\u0001/g, '\u0001\u0002') - .replace(/\u0000/g, '\u0001\u0001'); - /* eslint-enable no-control-regex */ - case 'object': - var isArray = Array.isArray(key); - var arr = isArray ? key : Object.keys(key); - var i = -1; - var len = arr.length; - var result = ''; - if (isArray) { - while (++i < len) { - result += toIndexableString(arr[i]); - } - } else { - while (++i < len) { - var objKey = arr[i]; - result += toIndexableString(objKey) + - toIndexableString(key[objKey]); - } - } - return result; - } - } - return ''; -} +/** + * Detect a URLSearchParams object + * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 + * + * @param Object obj Object to detect by type or brand + * @return String + */ +function isURLSearchParams(obj) { + // Duck-typing as a necessary condition. + if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { + return false; + } -// convert the given key to a string that would be appropriate -// for lexical sorting, e.g. within a database, where the -// sorting is the same given by the collate() function. -function toIndexableString(key) { - var zero = '\u0000'; - key = normalizeKey(key); - return collationIndex(key) + SEP + indexify(key) + zero; + // Brand-checking and more duck-typing as optional condition. + return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; } -function parseNumber(str, i) { - var originalIdx = i; - var num; - var zero = str[i] === '1'; - if (zero) { - num = 0; - i++; - } else { - var neg = str[i] === '0'; - i++; - var numAsString = ''; - var magAsString = str.substring(i, i + MAGNITUDE_DIGITS); - var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE; - /* istanbul ignore next */ - if (neg) { - magnitude = -magnitude; - } - i += MAGNITUDE_DIGITS; - while (true) { - var ch = str[i]; - if (ch === '\u0000') { - break; - } else { - numAsString += ch; - } - i++; - } - numAsString = numAsString.split('.'); - if (numAsString.length === 1) { - num = parseInt(numAsString, 10); - } else { - /* istanbul ignore next */ - num = parseFloat(numAsString[0] + '.' + numAsString[1]); - } - /* istanbul ignore next */ - if (neg) { - num = num - 10; - } - /* istanbul ignore next */ - if (magnitude !== 0) { - // parseFloat is more reliable than pow due to rounding errors - // e.g. Number.MAX_VALUE would return Infinity if we did - // num * Math.pow(10, magnitude); - num = parseFloat(num + 'e' + magnitude); - } - } - return {num: num, length : i - originalIdx}; +/** + * Check if `obj` is a W3C `Blob` object (which `File` inherits from) + * @param {*} obj + * @return {boolean} + */ +function isBlob(obj) { + return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); } -// move up the stack while parsing -// this function moved outside of parseIndexableString for performance -function pop(stack, metaStack) { - var obj = stack.pop(); - - if (metaStack.length) { - var lastMetaElement = metaStack[metaStack.length - 1]; - if (obj === lastMetaElement.element) { - // popping a meta-element, e.g. an object whose value is another object - metaStack.pop(); - lastMetaElement = metaStack[metaStack.length - 1]; - } - var element = lastMetaElement.element; - var lastElementIndex = lastMetaElement.index; - if (Array.isArray(element)) { - element.push(obj); - } else if (lastElementIndex === stack.length - 2) { // obj with key+value - var key = stack.pop(); - element[key] = obj; - } else { - stack.push(obj); // obj with key only - } - } -} +/** + * Clone body given Res/Req instance + * + * @param Mixed instance Response or Request instance + * @return Mixed + */ +function clone(instance) { + let p1, p2; + let body = instance.body; -function parseIndexableString(str) { - var stack = []; - var metaStack = []; // stack for arrays and objects - var i = 0; + // don't allow cloning a used body + if (instance.bodyUsed) { + throw new Error('cannot clone body after it is used'); + } - /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/ - while (true) { - var collationIndex = str[i++]; - if (collationIndex === '\u0000') { - if (stack.length === 1) { - return stack.pop(); - } else { - pop(stack, metaStack); - continue; - } - } - switch (collationIndex) { - case '1': - stack.push(null); - break; - case '2': - stack.push(str[i] === '1'); - i++; - break; - case '3': - var parsedNum = parseNumber(str, i); - stack.push(parsedNum.num); - i += parsedNum.length; - break; - case '4': - var parsedStr = ''; - /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/ - while (true) { - var ch = str[i]; - if (ch === '\u0000') { - break; - } - parsedStr += ch; - i++; - } - // perform the reverse of the order-preserving replacement - // algorithm (see above) - /* eslint-disable no-control-regex */ - parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000') - .replace(/\u0001\u0002/g, '\u0001') - .replace(/\u0002\u0002/g, '\u0002'); - /* eslint-enable no-control-regex */ - stack.push(parsedStr); - break; - case '5': - var arrayElement = { element: [], index: stack.length }; - stack.push(arrayElement.element); - metaStack.push(arrayElement); - break; - case '6': - var objElement = { element: {}, index: stack.length }; - stack.push(objElement.element); - metaStack.push(objElement); - break; - /* istanbul ignore next */ - default: - throw new Error( - 'bad collationIndex or unexpectedly reached end of input: ' + - collationIndex); - } - } -} + // check that body is a stream and not form-data object + // note: we can't clone the form-data object without having it as a dependency + if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__ && typeof body.getBoundary !== 'function') { + // tee instance body + p1 = new PassThrough(); + p2 = new PassThrough(); + body.pipe(p1); + body.pipe(p2); + // set instance body to teed body and return the other teed body + instance[INTERNALS].body = p1; + body = p2; + } -function arrayCollate(a, b) { - var len = Math.min(a.length, b.length); - for (var i = 0; i < len; i++) { - var sort = collate(a[i], b[i]); - if (sort !== 0) { - return sort; - } - } - return (a.length === b.length) ? 0 : - (a.length > b.length) ? 1 : -1; -} -function stringCollate(a, b) { - // See: https://github.com/daleharvey/pouchdb/issues/40 - // This is incompatible with the CouchDB implementation, but its the - // best we can do for now - return (a === b) ? 0 : ((a > b) ? 1 : -1); + return body; } -function objectCollate(a, b) { - var ak = Object.keys(a), bk = Object.keys(b); - var len = Math.min(ak.length, bk.length); - for (var i = 0; i < len; i++) { - // First sort the keys - var sort = collate(ak[i], bk[i]); - if (sort !== 0) { - return sort; - } - // if the keys are equal sort the values - sort = collate(a[ak[i]], b[bk[i]]); - if (sort !== 0) { - return sort; - } - } - return (ak.length === bk.length) ? 0 : - (ak.length > bk.length) ? 1 : -1; -} -// The collation is defined by erlangs ordered terms -// the atoms null, true, false come first, then numbers, strings, -// arrays, then objects -// null/undefined/NaN/Infinity/-Infinity are all considered null -function collationIndex(x) { - var id = ['boolean', 'number', 'string', 'object']; - var idx = id.indexOf(typeof x); - //false if -1 otherwise true, but fast!!!!1 - if (~idx) { - if (x === null) { - return 1; - } - if (Array.isArray(x)) { - return 5; - } - return idx < 3 ? (idx + 2) : (idx + 3); - } - /* istanbul ignore next */ - if (Array.isArray(x)) { - return 5; - } +/** + * Performs the operation "extract a `Content-Type` value from |object|" as + * specified in the specification: + * https://fetch.spec.whatwg.org/#concept-bodyinit-extract + * + * This function assumes that instance.body is present. + * + * @param Mixed instance Any options.body input + */ +function extractContentType(body) { + if (body === null) { + // body is null + return null; + } else if (typeof body === 'string') { + // body is string + return 'text/plain;charset=UTF-8'; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + return 'application/x-www-form-urlencoded;charset=UTF-8'; + } else if (isBlob(body)) { + // body is blob + return body.type || null; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return null; + } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + return null; + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + return null; + } else if (typeof body.getBoundary === 'function') { + // detect form data input from form-data module + return `multipart/form-data;boundary=${body.getBoundary()}`; + } else if (body instanceof stream__WEBPACK_IMPORTED_MODULE_0__) { + // body is stream + // can't really do much about this + return null; + } else { + // Body constructor defaults other things to string + return 'text/plain;charset=UTF-8'; + } } -// conversion: -// x yyy zz...zz -// x = 0 for negative, 1 for 0, 2 for positive -// y = exponent (for negative numbers negated) moved so that it's >= 0 -// z = mantisse -function numToIndexableString(num) { - - if (num === 0) { - return '1'; - } - - // convert number to exponential format for easier and - // more succinct string sorting - var expFormat = num.toExponential().split(/e\+?/); - var magnitude = parseInt(expFormat[1], 10); +/** + * The Fetch Standard treats this as if "total bytes" is a property on the body. + * For us, we have to explicitly get it with a function. + * + * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes + * + * @param Body instance Instance of Body + * @return Number? Number of bytes, or null if not possible + */ +function getTotalBytes(instance) { + const body = instance.body; - var neg = num < 0; - var result = neg ? '0' : '2'; + if (body === null) { + // body is null + return 0; + } else if (isBlob(body)) { + return body.size; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return body.length; + } else if (body && typeof body.getLengthSync === 'function') { + // detect form data input from form-data module + if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x + body.hasKnownLength && body.hasKnownLength()) { + // 2.x + return body.getLengthSync(); + } + return null; + } else { + // body is stream + return null; + } +} - // first sort by magnitude - // it's easier if all magnitudes are positive - var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE); - var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS); +/** + * Write a Body to a Node.js WritableStream (e.g. http.Request) object. + * + * @param Body instance Instance of Body + * @return Void + */ +function writeToStream(dest, instance) { + const body = instance.body; - result += SEP + magString; - // then sort by the factor - var factor = Math.abs(parseFloat(expFormat[0])); // [1..10) - /* istanbul ignore next */ - if (neg) { // for negative reverse ordering - factor = 10 - factor; - } + if (body === null) { + // body is null + dest.end(); + } else if (isBlob(body)) { + body.stream().pipe(dest); + } else if (Buffer.isBuffer(body)) { + // body is buffer + dest.write(body); + dest.end(); + } else { + // body is stream + body.pipe(dest); + } +} - var factorStr = factor.toFixed(20); +// expose Promise +Body.Promise = global.Promise; - // strip zeros from the end - factorStr = factorStr.replace(/\.?0+$/, ''); +/** + * headers.js + * + * Headers class offers convenient helpers + */ - result += SEP + factorStr; +const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; +const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; - return result; +function validateName(name) { + name = `${name}`; + if (invalidTokenRegex.test(name) || name === '') { + throw new TypeError(`${name} is not a legal HTTP header name`); + } } -// create a comparator based on the sort object -function createFieldSorter(sort) { - - function getFieldValuesAsArray(doc) { - return sort.map(function (sorting) { - var fieldName = getKey(sorting); - var parsedField = parseField(fieldName); - var docFieldValue = getFieldFromDoc(doc, parsedField); - return docFieldValue; - }); - } +function validateValue(value) { + value = `${value}`; + if (invalidHeaderCharRegex.test(value)) { + throw new TypeError(`${value} is not a legal HTTP header value`); + } +} - return function (aRow, bRow) { - var aFieldValues = getFieldValuesAsArray(aRow.doc); - var bFieldValues = getFieldValuesAsArray(bRow.doc); - var collation = collate(aFieldValues, bFieldValues); - if (collation !== 0) { - return collation; - } - // this is what mango seems to do - return compare$1(aRow.doc._id, bRow.doc._id); - }; +/** + * Find the key in the map object given a header name. + * + * Returns undefined if not found. + * + * @param String name Header name + * @return String|Undefined + */ +function find(map, name) { + name = name.toLowerCase(); + for (const key in map) { + if (key.toLowerCase() === name) { + return key; + } + } + return undefined; } -function filterInMemoryFields(rows, requestDef, inMemoryFields) { - rows = rows.filter(function (row) { - return rowFilter(row.doc, requestDef.selector, inMemoryFields); - }); +const MAP = Symbol('map'); +class Headers { + /** + * Headers class + * + * @param Object headers Response headers + * @return Void + */ + constructor() { + let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; - if (requestDef.sort) { - // in-memory sort - var fieldSorter = createFieldSorter(requestDef.sort); - rows = rows.sort(fieldSorter); - if (typeof requestDef.sort[0] !== 'string' && - getValue(requestDef.sort[0]) === 'desc') { - rows = rows.reverse(); - } - } + this[MAP] = Object.create(null); - if ('limit' in requestDef || 'skip' in requestDef) { - // have to do the limit in-memory - var skip = requestDef.skip || 0; - var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip; - rows = rows.slice(skip, limit); - } - return rows; -} + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); -function rowFilter(doc, selector, inMemoryFields) { - return inMemoryFields.every(function (field) { - var matcher = selector[field]; - var parsedField = parseField(field); - var docFieldValue = getFieldFromDoc(doc, parsedField); - if (isCombinationalField(field)) { - return matchCominationalSelector(field, matcher, doc); - } + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } - return matchSelector(matcher, doc, parsedField, docFieldValue); - }); -} + return; + } -function matchSelector(matcher, doc, parsedField, docFieldValue) { - if (!matcher) { - // no filtering necessary; this field is just needed for sorting - return true; - } + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } - return Object.keys(matcher).every(function (userOperator) { - var userValue = matcher[userOperator]; - return match(userOperator, doc, userValue, parsedField, docFieldValue); - }); -} + // sequence<sequence<ByteString>> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } -function matchCominationalSelector(field, matcher, doc) { + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record<ByteString, ByteString> + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } - if (field === '$or') { - return matcher.some(function (orMatchers) { - return rowFilter(doc, orMatchers, Object.keys(orMatchers)); - }); - } + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } - if (field === '$not') { - return !rowFilter(doc, matcher, Object.keys(matcher)); - } + return this[MAP][key].join(', '); + } - //`$nor` - return !matcher.find(function (orMatchers) { - return rowFilter(doc, orMatchers, Object.keys(orMatchers)); - }); + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; -} + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; -function match(userOperator, doc, userValue, parsedField, docFieldValue) { - if (!matchers[userOperator]) { - throw new Error('unknown operator "' + userOperator + - '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' + - '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all'); - } - return matchers[userOperator](doc, userValue, parsedField, docFieldValue); -} + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } -function fieldExists(docFieldValue) { - return typeof docFieldValue !== 'undefined' && docFieldValue !== null; -} + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } + + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } -function fieldIsNotUndefined(docFieldValue) { - return typeof docFieldValue !== 'undefined'; -} + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } -function modField(docFieldValue, userValue) { - var divisor = userValue[0]; - var mod = userValue[1]; - if (divisor === 0) { - throw new Error('Bad divisor, cannot divide by zero'); - } + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } - if (parseInt(divisor, 10) !== divisor ) { - throw new Error('Divisor is not an integer'); - } + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } - if (parseInt(mod, 10) !== mod ) { - throw new Error('Modulus is not an integer'); - } + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } - if (parseInt(docFieldValue, 10) !== docFieldValue) { - return false; - } + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } - return docFieldValue % divisor === mod; + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } } +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; -function arrayContainsValue(docFieldValue, userValue) { - return userValue.some(function (val) { - if (docFieldValue instanceof Array) { - return docFieldValue.indexOf(val) > -1; - } +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); - return docFieldValue === val; - }); -} +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); -function arrayContainsAllValues(docFieldValue, userValue) { - return userValue.every(function (val) { - return docFieldValue.indexOf(val) > -1; - }); -} +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; -function arraySize(docFieldValue, userValue) { - return docFieldValue.length === userValue; + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); } -function regexMatch(docFieldValue, userValue) { - var re = new RegExp(userValue); +const INTERNAL = Symbol('internal'); - return re.test(docFieldValue); +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; } -function typeMatch(docFieldValue, userValue) { +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } - switch (userValue) { - case 'null': - return docFieldValue === null; - case 'boolean': - return typeof (docFieldValue) === 'boolean'; - case 'number': - return typeof (docFieldValue) === 'number'; - case 'string': - return typeof (docFieldValue) === 'string'; - case 'array': - return docFieldValue instanceof Array; - case 'object': - return ({}).toString.call(docFieldValue) === '[object Object]'; - } + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; - throw new Error(userValue + ' not supported as a type.' + - 'Please use one of object, string, array, number, boolean or null.'); + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } -} + this[INTERNAL].index = index + 1; -var matchers = { + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); - '$elemMatch': function (doc, userValue, parsedField, docFieldValue) { - if (!Array.isArray(docFieldValue)) { - return false; - } +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); - if (docFieldValue.length === 0) { - return false; - } +/** + * Export the Headers object in a form that Node.js can consume. + * + * @param Headers headers + * @return Object + */ +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); - if (typeof docFieldValue[0] === 'object') { - return docFieldValue.some(function (val) { - return rowFilter(val, userValue, Object.keys(userValue)); - }); - } + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } - return docFieldValue.some(function (val) { - return matchSelector(userValue, doc, parsedField, val); - }); - }, + return obj; +} - '$allMatch': function (doc, userValue, parsedField, docFieldValue) { - if (!Array.isArray(docFieldValue)) { - return false; - } +/** + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. + * + * @param Object obj Object of headers + * @return Headers + */ +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; +} - /* istanbul ignore next */ - if (docFieldValue.length === 0) { - return false; - } +const INTERNALS$1 = Symbol('Response internals'); - if (typeof docFieldValue[0] === 'object') { - return docFieldValue.every(function (val) { - return rowFilter(val, userValue, Object.keys(userValue)); - }); - } +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http__WEBPACK_IMPORTED_MODULE_1__.STATUS_CODES; - return docFieldValue.every(function (val) { - return matchSelector(userValue, doc, parsedField, val); - }); - }, +/** + * Response class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - '$eq': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) === 0; - }, + Body.call(this, body, opts); - '$gte': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) >= 0; - }, + const status = opts.status || 200; + const headers = new Headers(opts.headers); - '$gt': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) > 0; - }, + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } - '$lte': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) <= 0; - }, + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } - '$lt': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) < 0; - }, + get url() { + return this[INTERNALS$1].url || ''; + } - '$exists': function (doc, userValue, parsedField, docFieldValue) { - //a field that is null is still considered to exist - if (userValue) { - return fieldIsNotUndefined(docFieldValue); - } + get status() { + return this[INTERNALS$1].status; + } - return !fieldIsNotUndefined(docFieldValue); - }, + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } - '$mod': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && modField(docFieldValue, userValue); - }, + get redirected() { + return this[INTERNALS$1].counter > 0; + } - '$ne': function (doc, userValue, parsedField, docFieldValue) { - return userValue.every(function (neValue) { - return collate(docFieldValue, neValue) !== 0; - }); - }, - '$in': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue); - }, + get statusText() { + return this[INTERNALS$1].statusText; + } - '$nin': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue); - }, + get headers() { + return this[INTERNALS$1].headers; + } - '$size': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue); - }, + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } +} - '$all': function (doc, userValue, parsedField, docFieldValue) { - return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue); - }, +Body.mixIn(Response.prototype); - '$regex': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue); - }, +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); - '$type': function (doc, userValue, parsedField, docFieldValue) { - return typeMatch(docFieldValue, userValue); - } -}; +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); -// return true if the given doc matches the supplied selector -function matchesSelector(doc, selector) { - /* istanbul ignore if */ - if (typeof selector !== 'object') { - // match the CouchDB error message - throw new Error('Selector error: expected a JSON object'); - } +const INTERNALS$2 = Symbol('Request internals'); - selector = massageSelector(selector); - var row = { - 'doc': doc - }; +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = url__WEBPACK_IMPORTED_MODULE_2__.parse; +const format_url = url__WEBPACK_IMPORTED_MODULE_2__.format; - var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector)); - return rowsMatched && rowsMatched.length === 1; +const streamDestructionSupported = 'destroy' in stream__WEBPACK_IMPORTED_MODULE_0__.Readable.prototype; + +/** + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean + */ +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; } -function evalFilter(input) { - return scopeEval('"use strict";\nreturn ' + input + ';', {}); +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); } -function evalView(input) { - var code = [ - 'return function(doc) {', - ' "use strict";', - ' var emitted = false;', - ' var emit = function (a, b) {', - ' emitted = true;', - ' };', - ' var view = ' + input + ';', - ' view(doc);', - ' if (emitted) {', - ' return true;', - ' }', - '};' - ].join('\n'); +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - return scopeEval(code, {}); -} + let parsedURL; -function validate(opts, callback) { - if (opts.selector) { - if (opts.filter && opts.filter !== '_selector') { - var filterName = typeof opts.filter === 'string' ? - opts.filter : 'function'; - return callback(new Error('selector invalid for filter "' + filterName + '"')); - } - } - callback(); -} + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parse_url(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parse_url(`${input}`); + } + input = {}; + } else { + parsedURL = parse_url(input.url); + } -function normalize(opts) { - if (opts.view && !opts.filter) { - opts.filter = '_view'; - } + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); - if (opts.selector && !opts.filter) { - opts.filter = '_selector'; - } + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } - if (opts.filter && typeof opts.filter === 'string') { - if (opts.filter === '_view') { - opts.view = normalizeDesignDocFunctionName(opts.view); - } else { - opts.filter = normalizeDesignDocFunctionName(opts.filter); - } - } -} + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; -function shouldFilter(changesHandler, opts) { - return opts.filter && typeof opts.filter === 'string' && - !opts.doc_ids && !isRemote(changesHandler.db); -} + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); -function filter(changesHandler, opts) { - var callback = opts.complete; - if (opts.filter === '_view') { - if (!opts.view || typeof opts.view !== 'string') { - var err = createError(BAD_REQUEST, - '`view` filter parameter not found or invalid.'); - return callback(err); - } - // fetch a view from a design doc, make it behave like a filter - var viewName = parseDesignDocFunctionName(opts.view); - changesHandler.db.get('_design/' + viewName[0], function (err, ddoc) { - /* istanbul ignore if */ - if (changesHandler.isCancelled) { - return callback(null, {status: 'cancelled'}); - } - /* istanbul ignore next */ - if (err) { - return callback(generateErrorFromResponse(err)); - } - var mapFun = ddoc && ddoc.views && ddoc.views[viewName[1]] && - ddoc.views[viewName[1]].map; - if (!mapFun) { - return callback(createError(MISSING_DOC, - (ddoc.views ? 'missing json key: ' + viewName[1] : - 'missing json key: views'))); - } - opts.filter = evalView(mapFun); - changesHandler.doChanges(opts); - }); - } else if (opts.selector) { - opts.filter = function (doc) { - return matchesSelector(doc, opts.selector); - }; - changesHandler.doChanges(opts); - } else { - // fetch a filter from a design doc - var filterName = parseDesignDocFunctionName(opts.filter); - changesHandler.db.get('_design/' + filterName[0], function (err, ddoc) { - /* istanbul ignore if */ - if (changesHandler.isCancelled) { - return callback(null, {status: 'cancelled'}); - } - /* istanbul ignore next */ - if (err) { - return callback(generateErrorFromResponse(err)); - } - var filterFun = ddoc && ddoc.filters && ddoc.filters[filterName[1]]; - if (!filterFun) { - return callback(createError(MISSING_DOC, - ((ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1] - : 'missing json key: filters'))); - } - opts.filter = evalFilter(filterFun); - changesHandler.doChanges(opts); - }); - } -} + const headers = new Headers(init.headers || input.headers || {}); -function applyChangesFilterPlugin(PouchDB) { - PouchDB._changesFilterPlugin = { - validate: validate, - normalize: normalize, - shouldFilter: shouldFilter, - filter: filter - }; -} + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } -// TODO: remove from pouchdb-core (breaking) -PouchDB.plugin(applyChangesFilterPlugin); + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; -PouchDB.version = version; + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } -function toObject(array) { - return array.reduce(function (obj, item) { - obj[item] = true; - return obj; - }, {}); -} -// List of top level reserved words for doc -var reservedWords = toObject([ - '_id', - '_rev', - '_attachments', - '_deleted', - '_revisions', - '_revs_info', - '_conflicts', - '_deleted_conflicts', - '_local_seq', - '_rev_tree', - //replication documents - '_replication_id', - '_replication_state', - '_replication_state_time', - '_replication_state_reason', - '_replication_stats', - // Specific to Couchbase Sync Gateway - '_removed' -]); + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; -// List of reserved words that should end up the document -var dataWords = toObject([ - '_attachments', - //replication documents - '_replication_id', - '_replication_state', - '_replication_state_time', - '_replication_state_reason', - '_replication_stats' -]); + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } -function parseRevisionInfo(rev) { - if (!/^\d+-./.test(rev)) { - return createError(INVALID_REV); - } - var idx = rev.indexOf('-'); - var left = rev.substring(0, idx); - var right = rev.substring(idx + 1); - return { - prefix: parseInt(left, 10), - id: right - }; -} + get method() { + return this[INTERNALS$2].method; + } -function makeRevTreeFromRevisions(revisions, opts) { - var pos = revisions.start - revisions.ids.length + 1; + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } - var revisionIds = revisions.ids; - var ids = [revisionIds[0], opts, []]; + get headers() { + return this[INTERNALS$2].headers; + } - for (var i = 1, len = revisionIds.length; i < len; i++) { - ids = [revisionIds[i], {status: 'missing'}, [ids]]; - } + get redirect() { + return this[INTERNALS$2].redirect; + } - return [{ - pos: pos, - ids: ids - }]; + get signal() { + return this[INTERNALS$2].signal; + } + + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } } -// Preprocess documents, parse their revisions, assign an id and a -// revision for new writes that are missing them, etc -function parseDoc(doc, newEdits, dbOpts) { - if (!dbOpts) { - dbOpts = { - deterministic_revs: true - }; - } +Body.mixIn(Request.prototype); - var nRevNum; - var newRevId; - var revInfo; - var opts = {status: 'available'}; - if (doc._deleted) { - opts.deleted = true; - } +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); - if (newEdits) { - if (!doc._id) { - doc._id = uuid(); - } - newRevId = rev$$1(doc, dbOpts.deterministic_revs); - if (doc._rev) { - revInfo = parseRevisionInfo(doc._rev); - if (revInfo.error) { - return revInfo; - } - doc._rev_tree = [{ - pos: revInfo.prefix, - ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]] - }]; - nRevNum = revInfo.prefix + 1; - } else { - doc._rev_tree = [{ - pos: 1, - ids : [newRevId, opts, []] - }]; - nRevNum = 1; - } - } else { - if (doc._revisions) { - doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts); - nRevNum = doc._revisions.start; - newRevId = doc._revisions.ids[0]; - } - if (!doc._rev_tree) { - revInfo = parseRevisionInfo(doc._rev); - if (revInfo.error) { - return revInfo; - } - nRevNum = revInfo.prefix; - newRevId = revInfo.id; - doc._rev_tree = [{ - pos: nRevNum, - ids: [newRevId, opts, []] - }]; - } - } +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); - invalidIdError(doc._id); +/** + * Convert a Request to Node.js http request options. + * + * @param Request A Request instance + * @return Object The options object to be passed to http.request + */ +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); - doc._rev = nRevNum + '-' + newRevId; + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } - var result = {metadata : {}, data : {}}; - for (var key in doc) { - /* istanbul ignore else */ - if (Object.prototype.hasOwnProperty.call(doc, key)) { - var specialKey = key[0] === '_'; - if (specialKey && !reservedWords[key]) { - var error = createError(DOC_VALIDATION, key); - error.message = DOC_VALIDATION.message + ': ' + key; - throw error; - } else if (specialKey && !dataWords[key]) { - result.metadata[key.slice(1)] = doc[key]; - } else { - result.data[key] = doc[key]; - } - } - } - return result; -} + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } -function parseBase64(data) { - try { - return thisAtob(data); - } catch (e) { - var err = createError(BAD_ARG, - 'Attachment is not a valid base64 string'); - return {error: err}; - } -} + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } -function preprocessString(att, blobType, callback) { - var asBinary = parseBase64(att.data); - if (asBinary.error) { - return callback(asBinary.error); - } + if (request.signal && request.body instanceof stream__WEBPACK_IMPORTED_MODULE_0__.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } - att.length = asBinary.length; - if (blobType === 'blob') { - att.data = binStringToBluffer(asBinary, att.content_type); - } else if (blobType === 'base64') { - att.data = thisBtoa(asBinary); - } else { // binary - att.data = asBinary; - } - binaryMd5(asBinary, function (result) { - att.digest = 'md5-' + result; - callback(); - }); -} + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } -function preprocessBlob(att, blobType, callback) { - binaryMd5(att.data, function (md5) { - att.digest = 'md5-' + md5; - // size is for blobs (browser), length is for buffers (node) - att.length = att.data.size || att.data.length || 0; - if (blobType === 'binary') { - blobToBinaryString(att.data, function (binString) { - att.data = binString; - callback(); - }); - } else if (blobType === 'base64') { - blobToBase64(att.data, function (b64) { - att.data = b64; - callback(); - }); - } else { - callback(); - } - }); -} + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } -function preprocessAttachment(att, blobType, callback) { - if (att.stub) { - return callback(); - } - if (typeof att.data === 'string') { // input is a base64 string - preprocessString(att, blobType, callback); - } else { // input is a blob - preprocessBlob(att, blobType, callback); - } -} + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } -function preprocessAttachments(docInfos, blobType, callback) { + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } - if (!docInfos.length) { - return callback(); - } + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } - var docv = 0; - var overallErr; + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js - docInfos.forEach(function (docInfo) { - var attachments = docInfo.data && docInfo.data._attachments ? - Object.keys(docInfo.data._attachments) : []; - var recv = 0; + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} - if (!attachments.length) { - return done(); - } +/** + * abort-error.js + * + * AbortError interface for cancelled requests + */ - function processedAttachment(err) { - overallErr = err; - recv++; - if (recv === attachments.length) { - done(); - } - } +/** + * Create AbortError instance + * + * @param String message Error message for human + * @return AbortError + */ +function AbortError(message) { + Error.call(this, message); - for (var key in docInfo.data._attachments) { - if (docInfo.data._attachments.hasOwnProperty(key)) { - preprocessAttachment(docInfo.data._attachments[key], - blobType, processedAttachment); - } - } - }); + this.type = 'aborted'; + this.message = message; - function done() { - docv++; - if (docInfos.length === docv) { - if (overallErr) { - callback(overallErr); - } else { - callback(); - } - } - } + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); } -function updateDoc(revLimit, prev, docInfo, results, - i, cb, writeDoc, newEdits) { +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; - if (revExists(prev.rev_tree, docInfo.metadata.rev) && !newEdits) { - results[i] = docInfo; - return cb(); - } +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = stream__WEBPACK_IMPORTED_MODULE_0__.PassThrough; +const resolve_url = url__WEBPACK_IMPORTED_MODULE_2__.resolve; - // sometimes this is pre-calculated. historically not always - var previousWinningRev = prev.winningRev || winningRev(prev); - var previouslyDeleted = 'deleted' in prev ? prev.deleted : - isDeleted(prev, previousWinningRev); - var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted : - isDeleted(docInfo.metadata); - var isRoot = /^1-/.test(docInfo.metadata.rev); +/** + * Fetch function + * + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise + */ +function fetch(url, opts) { - if (previouslyDeleted && !deleted && newEdits && isRoot) { - var newDoc = docInfo.data; - newDoc._rev = previousWinningRev; - newDoc._id = docInfo.metadata.id; - docInfo = parseDoc(newDoc, newEdits); - } + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } - var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit); + Body.Promise = fetch.Promise; - var inConflict = newEdits && (( - (previouslyDeleted && deleted && merged.conflicts !== 'new_leaf') || - (!previouslyDeleted && merged.conflicts !== 'new_leaf') || - (previouslyDeleted && !deleted && merged.conflicts === 'new_branch'))); + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); - if (inConflict) { - var err = createError(REV_CONFLICT); - results[i] = err; - return cb(); - } + const send = (options.protocol === 'https:' ? https__WEBPACK_IMPORTED_MODULE_3__ : http__WEBPACK_IMPORTED_MODULE_1__).request; + const signal = request.signal; - var newRev = docInfo.metadata.rev; - docInfo.metadata.rev_tree = merged.tree; - docInfo.stemmedRevs = merged.stemmedRevs || []; - /* istanbul ignore else */ - if (prev.rev_map) { - docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb - } + let response = null; - // recalculate - var winningRev$$1 = winningRev(docInfo.metadata); - var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$1); + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof stream__WEBPACK_IMPORTED_MODULE_0__.Readable) { + request.body.destroy(error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; - // calculate the total number of documents that were added/removed, - // from the perspective of total_rows/doc_count - var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 : - previouslyDeleted < winningRevIsDeleted ? -1 : 1; + if (signal && signal.aborted) { + abort(); + return; + } - var newRevIsDeleted; - if (newRev === winningRev$$1) { - // if the new rev is the same as the winning rev, we can reuse that value - newRevIsDeleted = winningRevIsDeleted; - } else { - // if they're not the same, then we need to recalculate - newRevIsDeleted = isDeleted(docInfo.metadata, newRev); - } + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; - writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted, - true, delta, i, cb); -} + // send request + const req = send(options); + let reqTimeout; -function rootIsMissing(docInfo) { - return docInfo.metadata.rev_tree[0].ids[1].status === 'missing'; -} + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } -function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results, - writeDoc, opts, overallCallback) { + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } - // Default to 1000 locally - revLimit = revLimit || 1000; + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } - function insertDoc(docInfo, resultsIdx, callback) { - // Cant insert new deleted documents - var winningRev$$1 = winningRev(docInfo.metadata); - var deleted = isDeleted(docInfo.metadata, winningRev$$1); - if ('was_delete' in opts && deleted) { - results[resultsIdx] = createError(MISSING_DOC, 'deleted'); - return callback(); - } + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + finalize(); + }); - // 4712 - detect whether a new document was inserted with a _rev - var inConflict = newEdits && rootIsMissing(docInfo); + req.on('response', function (res) { + clearTimeout(reqTimeout); - if (inConflict) { - var err = createError(REV_CONFLICT); - results[resultsIdx] = err; - return callback(); - } + const headers = createHeadersLenient(res.headers); - var delta = deleted ? 0 : 1; + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); - writeDoc(docInfo, winningRev$$1, deleted, deleted, false, - delta, resultsIdx, callback); - } + // HTTP fetch step 5.3 + const locationURL = location === null ? null : resolve_url(request.url, location); - var newEdits = opts.new_edits; - var idsToDocs = new ExportedMap(); + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } - var docsDone = 0; - var docsToDo = docInfos.length; + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } - function checkAllDocsDone() { - if (++docsDone === docsToDo && overallCallback) { - overallCallback(); - } - } + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; - docInfos.forEach(function (currentDoc, resultsIdx) { + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } - if (currentDoc._id && isLocalId(currentDoc._id)) { - var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal'; - api[fun](currentDoc, {ctx: tx}, function (err, res) { - results[resultsIdx] = err || res; - checkAllDocsDone(); - }); - return; - } + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } - var id = currentDoc.metadata.id; - if (idsToDocs.has(id)) { - docsToDo--; // duplicate - idsToDocs.get(id).push([currentDoc, resultsIdx]); - } else { - idsToDocs.set(id, [[currentDoc, resultsIdx]]); - } - }); + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } - // in the case of new_edits, the user can provide multiple docs - // with the same id. these need to be processed sequentially - idsToDocs.forEach(function (docs, id) { - var numDone = 0; + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); - function docWritten() { - if (++numDone < docs.length) { - nextDoc(); - } else { - checkAllDocsDone(); - } - } - function nextDoc() { - var value = docs[numDone]; - var currentDoc = value[0]; - var resultsIdx = value[1]; + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; - if (fetchedDocs.has(id)) { - updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results, - resultsIdx, docWritten, writeDoc, newEdits); - } else { - // Ensure stemming applies to new writes as well - var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit); - currentDoc.metadata.rev_tree = merged.tree; - currentDoc.stemmedRevs = merged.stemmedRevs || []; - insertDoc(currentDoc, resultsIdx, docWritten); - } - } - nextDoc(); - }); -} + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); -// IndexedDB requires a versioned database structure, so we use the -// version here to manage migrations. -var ADAPTER_VERSION = 5; + // HTTP-network fetch step 12.1.1.4: handle content codings -// The object stores created for each database -// DOC_STORE stores the document meta data, its revision history and state -// Keyed by document id -var DOC_STORE = 'document-store'; -// BY_SEQ_STORE stores a particular version of a document, keyed by its -// sequence id -var BY_SEQ_STORE = 'by-sequence'; -// Where we store attachments -var ATTACH_STORE = 'attach-store'; -// Where we store many-to-many relations -// between attachment digests and seqs -var ATTACH_AND_SEQ_STORE = 'attach-seq-store'; + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } -// Where we store database-wide meta data in a single record -// keyed by id: META_STORE -var META_STORE = 'meta-store'; -// Where we store local documents -var LOCAL_STORE = 'local-store'; -// Where we detect blob support -var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support'; + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib__WEBPACK_IMPORTED_MODULE_4__.Z_SYNC_FLUSH, + finishFlush: zlib__WEBPACK_IMPORTED_MODULE_4__.Z_SYNC_FLUSH + }; -function safeJsonParse(str) { - // This try/catch guards against stack overflow errors. - // JSON.parse() is faster than vuvuzela.parse() but vuvuzela - // cannot overflow. - try { - return JSON.parse(str); - } catch (e) { - /* istanbul ignore next */ - return vuvuzela__WEBPACK_IMPORTED_MODULE_6__.parse(str); - } -} + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } -function safeJsonStringify(json) { - try { - return JSON.stringify(json); - } catch (e) { - /* istanbul ignore next */ - return vuvuzela__WEBPACK_IMPORTED_MODULE_6__.stringify(json); - } -} + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createInflate()); + } else { + body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + return; + } -function idbError(callback) { - return function (evt) { - var message = 'unknown_error'; - if (evt.target && evt.target.error) { - message = evt.target.error.name || evt.target.error.message; - } - callback(createError(IDB_ERROR, message, evt.type)); - }; -} + // for br + if (codings == 'br' && typeof zlib__WEBPACK_IMPORTED_MODULE_4__.createBrotliDecompress === 'function') { + body = body.pipe(zlib__WEBPACK_IMPORTED_MODULE_4__.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } -// Unfortunately, the metadata has to be stringified -// when it is put into the database, because otherwise -// IndexedDB can throw errors for deeply-nested objects. -// Originally we just used JSON.parse/JSON.stringify; now -// we use this custom vuvuzela library that avoids recursion. -// If we could do it all over again, we'd probably use a -// format for the revision trees other than JSON. -function encodeMetadata(metadata, winningRev, deleted) { - return { - data: safeJsonStringify(metadata), - winningRev: winningRev, - deletedOrLocal: deleted ? '1' : '0', - seq: metadata.seq, // highest seq for this doc - id: metadata.id - }; -} + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); -function decodeMetadata(storedObject) { - if (!storedObject) { - return null; - } - var metadata = safeJsonParse(storedObject.data); - metadata.winningRev = storedObject.winningRev; - metadata.deleted = storedObject.deletedOrLocal === '1'; - metadata.seq = storedObject.seq; - return metadata; + writeToStream(req, request); + }); } +/** + * Redirect code matching + * + * @param Number code Status code + * @return Boolean + */ +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; -// read the doc back out from the database. we don't store the -// _id or _rev because we already have _doc_id_rev. -function decodeDoc(doc) { - if (!doc) { - return doc; - } - var idx = doc._doc_id_rev.lastIndexOf(':'); - doc._id = doc._doc_id_rev.substring(0, idx - 1); - doc._rev = doc._doc_id_rev.substring(idx + 1); - delete doc._doc_id_rev; - return doc; -} +// expose Promise +fetch.Promise = global.Promise; -// Read a blob from the database, encoding as necessary -// and translating from base64 if the IDB doesn't support -// native Blobs -function readBlobData(body, type, asBlob, callback) { - if (asBlob) { - if (!body) { - callback(createBlob([''], {type: type})); - } else if (typeof body !== 'string') { // we have blob support - callback(body); - } else { // no blob support - callback(b64ToBluffer(body, type)); - } - } else { // as base64 string - if (!body) { - callback(''); - } else if (typeof body !== 'string') { // we have blob support - readAsBinaryString(body, function (binary) { - callback(thisBtoa(binary)); - }); - } else { // no blob support - callback(body); - } - } -} +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (fetch); -function fetchAttachmentsIfNecessary(doc, opts, txn, cb) { - var attachments = Object.keys(doc._attachments || {}); - if (!attachments.length) { - return cb && cb(); - } - var numDone = 0; - function checkDone() { - if (++numDone === attachments.length && cb) { - cb(); - } - } - function fetchAttachment(doc, att) { - var attObj = doc._attachments[att]; - var digest = attObj.digest; - var req = txn.objectStore(ATTACH_STORE).get(digest); - req.onsuccess = function (e) { - attObj.body = e.target.result.body; - checkDone(); - }; - } +/***/ }), +/* 494 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - attachments.forEach(function (att) { - if (opts.attachments && opts.include_docs) { - fetchAttachment(doc, att); - } else { - doc._attachments[att].stub = true; - checkDone(); - } - }); -} +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(495); +/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var immediate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(496); +/* harmony import */ var immediate__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(immediate__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(250); +/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(497); +/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var spark_md5__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(499); +/* harmony import */ var spark_md5__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(spark_md5__WEBPACK_IMPORTED_MODULE_4__); +/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(500); +/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_5__); +/* harmony import */ var vuvuzela__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(505); -// IDB-specific postprocessing necessary because -// we don't know whether we stored a true Blob or -// a base64-encoded string, and if it's a Blob it -// needs to be read outside of the transaction context -function postProcessAttachments(results, asBlob) { - return Promise.all(results.map(function (row) { - if (row.doc && row.doc._attachments) { - var attNames = Object.keys(row.doc._attachments); - return Promise.all(attNames.map(function (att) { - var attObj = row.doc._attachments[att]; - if (!('body' in attObj)) { // already processed - return; - } - var body = attObj.body; - var type = attObj.content_type; - return new Promise(function (resolve) { - readBlobData(body, type, asBlob, function (data) { - row.doc._attachments[att] = $inject_Object_assign( - pick(attObj, ['digest', 'content_type']), - {data: data} - ); - resolve(); - }); - }); - })); - } - })); -} -function compactRevs(revs, docId, txn) { - var possiblyOrphanedDigests = []; - var seqStore = txn.objectStore(BY_SEQ_STORE); - var attStore = txn.objectStore(ATTACH_STORE); - var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE); - var count = revs.length; - function checkDone() { - count--; - if (!count) { // done processing all revs - deleteOrphanedAttachments(); - } - } - function deleteOrphanedAttachments() { - if (!possiblyOrphanedDigests.length) { - return; - } - possiblyOrphanedDigests.forEach(function (digest) { - var countReq = attAndSeqStore.index('digestSeq').count( - IDBKeyRange.bound( - digest + '::', digest + '::\uffff', false, false)); - countReq.onsuccess = function (e) { - var count = e.target.result; - if (!count) { - // orphaned - attStore.delete(digest); - } - }; - }); - } - revs.forEach(function (rev) { - var index = seqStore.index('_doc_id_rev'); - var key = docId + "::" + rev; - index.getKey(key).onsuccess = function (e) { - var seq = e.target.result; - if (typeof seq !== 'number') { - return checkDone(); - } - seqStore.delete(seq); - var cursor = attAndSeqStore.index('seq') - .openCursor(IDBKeyRange.only(seq)); - cursor.onsuccess = function (event) { - var cursor = event.target.result; - if (cursor) { - var digest = cursor.value.digestSeq.split('::')[0]; - possiblyOrphanedDigests.push(digest); - attAndSeqStore.delete(cursor.primaryKey); - cursor.continue(); - } else { // done - checkDone(); - } - }; - }; - }); +function isBinaryObject(object) { + return (typeof ArrayBuffer !== 'undefined' && object instanceof ArrayBuffer) || + (typeof Blob !== 'undefined' && object instanceof Blob); } -function openTransactionSafely(idb, stores, mode) { - try { - return { - txn: idb.transaction(stores, mode) - }; - } catch (err) { - return { - error: err - }; +function cloneArrayBuffer(buff) { + if (typeof buff.slice === 'function') { + return buff.slice(0); } + // IE10-11 slice() polyfill + var target = new ArrayBuffer(buff.byteLength); + var targetArray = new Uint8Array(target); + var sourceArray = new Uint8Array(buff); + targetArray.set(sourceArray); + return target; } -var changesHandler = new Changes(); - -function idbBulkDocs(dbOpts, req, opts, api, idb, callback) { - var docInfos = req.docs; - var txn; - var docStore; - var bySeqStore; - var attachStore; - var attachAndSeqStore; - var metaStore; - var docInfoError; - var metaDoc; - - for (var i = 0, len = docInfos.length; i < len; i++) { - var doc = docInfos[i]; - if (doc._id && isLocalId(doc._id)) { - continue; - } - doc = docInfos[i] = parseDoc(doc, opts.new_edits, dbOpts); - if (doc.error && !docInfoError) { - docInfoError = doc; - } +function cloneBinaryObject(object) { + if (object instanceof ArrayBuffer) { + return cloneArrayBuffer(object); } - - if (docInfoError) { - return callback(docInfoError); + var size = object.size; + var type = object.type; + // Blob + if (typeof object.slice === 'function') { + return object.slice(0, size, type); } + // PhantomJS slice() replacement + return object.webkitSlice(0, size, type); +} - var allDocsProcessed = false; - var docCountDelta = 0; - var results = new Array(docInfos.length); - var fetchedDocs = new ExportedMap(); - var preconditionErrored = false; - var blobType = api._meta.blobSupport ? 'blob' : 'base64'; - - preprocessAttachments(docInfos, blobType, function (err) { - if (err) { - return callback(err); - } - startTransaction(); - }); - - function startTransaction() { - - var stores = [ - DOC_STORE, BY_SEQ_STORE, - ATTACH_STORE, - LOCAL_STORE, ATTACH_AND_SEQ_STORE, - META_STORE - ]; - var txnResult = openTransactionSafely(idb, stores, 'readwrite'); - if (txnResult.error) { - return callback(txnResult.error); - } - txn = txnResult.txn; - txn.onabort = idbError(callback); - txn.ontimeout = idbError(callback); - txn.oncomplete = complete; - docStore = txn.objectStore(DOC_STORE); - bySeqStore = txn.objectStore(BY_SEQ_STORE); - attachStore = txn.objectStore(ATTACH_STORE); - attachAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE); - metaStore = txn.objectStore(META_STORE); +// most of this is borrowed from lodash.isPlainObject: +// https://github.com/fis-components/lodash.isplainobject/ +// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js - metaStore.get(META_STORE).onsuccess = function (e) { - metaDoc = e.target.result; - updateDocCountIfReady(); - }; +var funcToString = Function.prototype.toString; +var objectCtorString = funcToString.call(Object); - verifyAttachments(function (err) { - if (err) { - preconditionErrored = true; - return callback(err); - } - fetchExistingDocs(); - }); +function isPlainObject(value) { + var proto = Object.getPrototypeOf(value); + /* istanbul ignore if */ + if (proto === null) { // not sure when this happens, but I guess it can + return true; } + var Ctor = proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); +} - function onAllDocsProcessed() { - allDocsProcessed = true; - updateDocCountIfReady(); - } +function clone(object) { + var newObject; + var i; + var len; - function idbProcessDocs() { - processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs, - txn, results, writeDoc, opts, onAllDocsProcessed); + if (!object || typeof object !== 'object') { + return object; } - function updateDocCountIfReady() { - if (!metaDoc || !allDocsProcessed) { - return; + if (Array.isArray(object)) { + newObject = []; + for (i = 0, len = object.length; i < len; i++) { + newObject[i] = clone(object[i]); } - // caching the docCount saves a lot of time in allDocs() and - // info(), which is why we go to all the trouble of doing this - metaDoc.docCount += docCountDelta; - metaStore.put(metaDoc); + return newObject; } - function fetchExistingDocs() { + // special case: to avoid inconsistencies between IndexedDB + // and other backends, we automatically stringify Dates + if (object instanceof Date) { + return object.toISOString(); + } - if (!docInfos.length) { - return; - } + if (isBinaryObject(object)) { + return cloneBinaryObject(object); + } - var numFetched = 0; + if (!isPlainObject(object)) { + return object; // don't clone objects like Workers + } - function checkDone() { - if (++numFetched === docInfos.length) { - idbProcessDocs(); + newObject = {}; + for (i in object) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(object, i)) { + var value = clone(object[i]); + if (typeof value !== 'undefined') { + newObject[i] = value; } } + } + return newObject; +} - function readMetadata(event) { - var metadata = decodeMetadata(event.target.result); - - if (metadata) { - fetchedDocs.set(metadata.id, metadata); - } - checkDone(); +function once(fun) { + var called = false; + return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { + /* istanbul ignore if */ + if (called) { + // this is a smoke test and should never actually happen + throw new Error('once called more than once'); + } else { + called = true; + fun.apply(this, args); } + }); +} - for (var i = 0, len = docInfos.length; i < len; i++) { - var docInfo = docInfos[i]; - if (docInfo._id && isLocalId(docInfo._id)) { - checkDone(); // skip local docs - continue; +function toPromise(func) { + //create the function we will be returning + return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { + // Clone arguments + args = clone(args); + var self = this; + // if the last argument is a function, assume its a callback + var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false; + var promise = new Promise(function (fulfill, reject) { + var resp; + try { + var callback = once(function (err, mesg) { + if (err) { + reject(err); + } else { + fulfill(mesg); + } + }); + // create a callback for this invocation + // apply the function in the orig context + args.push(callback); + resp = func.apply(self, args); + if (resp && typeof resp.then === 'function') { + fulfill(resp); + } + } catch (e) { + reject(e); } - var req = docStore.get(docInfo.metadata.id); - req.onsuccess = readMetadata; + }); + // if there is a callback, call it back + if (usedCB) { + promise.then(function (result) { + usedCB(null, result); + }, usedCB); } - } + return promise; + }); +} - function complete() { - if (preconditionErrored) { - return; +function logApiCall(self, name, args) { + /* istanbul ignore if */ + if (self.constructor.listeners('debug').length) { + var logArgs = ['api', self.name, name]; + for (var i = 0; i < args.length - 1; i++) { + logArgs.push(args[i]); } + self.constructor.emit('debug', logArgs); - changesHandler.notify(api._meta.name); - callback(null, results); - } - - function verifyAttachment(digest, callback) { - - var req = attachStore.get(digest); - req.onsuccess = function (e) { - if (!e.target.result) { - var err = createError(MISSING_STUB, - 'unknown stub attachment with digest ' + - digest); - err.status = 412; - callback(err); - } else { - callback(); - } + // override the callback itself to log the response + var origCallback = args[args.length - 1]; + args[args.length - 1] = function (err, res) { + var responseArgs = ['api', self.name, name]; + responseArgs = responseArgs.concat( + err ? ['error', err] : ['success', res] + ); + self.constructor.emit('debug', responseArgs); + origCallback(err, res); }; } +} - function verifyAttachments(finish) { - - - var digests = []; - docInfos.forEach(function (docInfo) { - if (docInfo.data && docInfo.data._attachments) { - Object.keys(docInfo.data._attachments).forEach(function (filename) { - var att = docInfo.data._attachments[filename]; - if (att.stub) { - digests.push(att.digest); +function adapterFun(name, callback) { + return toPromise(argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { + if (this._closed) { + return Promise.reject(new Error('database is closed')); + } + if (this._destroyed) { + return Promise.reject(new Error('database is destroyed')); + } + var self = this; + logApiCall(self, name, args); + if (!this.taskqueue.isReady) { + return new Promise(function (fulfill, reject) { + self.taskqueue.addTask(function (failed) { + if (failed) { + reject(failed); + } else { + fulfill(self[name].apply(self, args)); } }); - } - }); - if (!digests.length) { - return finish(); + }); } - var numDone = 0; - var err; + return callback.apply(this, args); + })); +} - function checkDone() { - if (++numDone === digests.length) { - finish(err); - } - } - digests.forEach(function (digest) { - verifyAttachment(digest, function (attErr) { - if (attErr && !err) { - err = attErr; - } - checkDone(); - }); - }); +function mangle(key) { + return '$' + key; +} +function unmangle(key) { + return key.substring(1); +} +function Map$1() { + this._store = {}; +} +Map$1.prototype.get = function (key) { + var mangled = mangle(key); + return this._store[mangled]; +}; +Map$1.prototype.set = function (key, value) { + var mangled = mangle(key); + this._store[mangled] = value; + return true; +}; +Map$1.prototype.has = function (key) { + var mangled = mangle(key); + return mangled in this._store; +}; +Map$1.prototype.delete = function (key) { + var mangled = mangle(key); + var res = mangled in this._store; + delete this._store[mangled]; + return res; +}; +Map$1.prototype.forEach = function (cb) { + var keys = Object.keys(this._store); + for (var i = 0, len = keys.length; i < len; i++) { + var key = keys[i]; + var value = this._store[key]; + key = unmangle(key); + cb(value, key); } +}; +Object.defineProperty(Map$1.prototype, 'size', { + get: function () { + return Object.keys(this._store).length; + } +}); - function writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted, - isUpdate, delta, resultsIdx, callback) { - - docInfo.metadata.winningRev = winningRev$$1; - docInfo.metadata.deleted = winningRevIsDeleted; - - var doc = docInfo.data; - doc._id = docInfo.metadata.id; - doc._rev = docInfo.metadata.rev; - - if (newRevIsDeleted) { - doc._deleted = true; - } +function Set$1(array) { + this._store = new Map$1(); - var hasAttachments = doc._attachments && - Object.keys(doc._attachments).length; - if (hasAttachments) { - return writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted, - isUpdate, resultsIdx, callback); + // init with an array + if (array && Array.isArray(array)) { + for (var i = 0, len = array.length; i < len; i++) { + this.add(array[i]); } - - docCountDelta += delta; - updateDocCountIfReady(); - - finishDoc(docInfo, winningRev$$1, winningRevIsDeleted, - isUpdate, resultsIdx, callback); } +} +Set$1.prototype.add = function (key) { + return this._store.set(key, true); +}; +Set$1.prototype.has = function (key) { + return this._store.has(key); +}; +Set$1.prototype.forEach = function (cb) { + this._store.forEach(function (value, key) { + cb(key); + }); +}; +Object.defineProperty(Set$1.prototype, 'size', { + get: function () { + return this._store.size; + } +}); - function finishDoc(docInfo, winningRev$$1, winningRevIsDeleted, - isUpdate, resultsIdx, callback) { +/* global Map,Set,Symbol */ +// Based on https://kangax.github.io/compat-table/es6/ we can sniff out +// incomplete Map/Set implementations which would otherwise cause our tests to fail. +// Notably they fail in IE11 and iOS 8.4, which this prevents. +function supportsMapAndSet() { + if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') { + return false; + } + var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species); + return prop && 'get' in prop && Map[Symbol.species] === Map; +} - var doc = docInfo.data; - var metadata = docInfo.metadata; +// based on https://github.com/montagejs/collections - doc._doc_id_rev = metadata.id + '::' + metadata.rev; - delete doc._id; - delete doc._rev; +var ExportedSet; +var ExportedMap; - function afterPutDoc(e) { - var revsToDelete = docInfo.stemmedRevs || []; +{ + if (supportsMapAndSet()) { // prefer built-in Map/Set + ExportedSet = Set; + ExportedMap = Map; + } else { // fall back to our polyfill + ExportedSet = Set$1; + ExportedMap = Map$1; + } +} - if (isUpdate && api.auto_compaction) { - revsToDelete = revsToDelete.concat(compactTree(docInfo.metadata)); - } +// like underscore/lodash _.pick() +function pick(obj, arr) { + var res = {}; + for (var i = 0, len = arr.length; i < len; i++) { + var prop = arr[i]; + if (prop in obj) { + res[prop] = obj[prop]; + } + } + return res; +} - if (revsToDelete && revsToDelete.length) { - compactRevs(revsToDelete, docInfo.metadata.id, txn); - } +// Most browsers throttle concurrent requests at 6, so it's silly +// to shim _bulk_get by trying to launch potentially hundreds of requests +// and then letting the majority time out. We can handle this ourselves. +var MAX_NUM_CONCURRENT_REQUESTS = 6; - metadata.seq = e.target.result; - // Current _rev is calculated from _rev_tree on read - // delete metadata.rev; - var metadataToStore = encodeMetadata(metadata, winningRev$$1, - winningRevIsDeleted); - var metaDataReq = docStore.put(metadataToStore); - metaDataReq.onsuccess = afterPutMetadata; - } +function identityFunction(x) { + return x; +} - function afterPutDocError(e) { - // ConstraintError, need to update, not put (see #1638 for details) - e.preventDefault(); // avoid transaction abort - e.stopPropagation(); // avoid transaction onerror - var index = bySeqStore.index('_doc_id_rev'); - var getKeyReq = index.getKey(doc._doc_id_rev); - getKeyReq.onsuccess = function (e) { - var putReq = bySeqStore.put(doc, e.target.result); - putReq.onsuccess = afterPutDoc; - }; - } +function formatResultForOpenRevsGet(result) { + return [{ + ok: result + }]; +} - function afterPutMetadata() { - results[resultsIdx] = { - ok: true, - id: metadata.id, - rev: metadata.rev - }; - fetchedDocs.set(docInfo.metadata.id, docInfo.metadata); - insertAttachmentMappings(docInfo, metadata.seq, callback); +// shim for P/CouchDB adapters that don't directly implement _bulk_get +function bulkGet(db, opts, callback) { + var requests = opts.docs; + + // consolidate into one request per doc if possible + var requestsById = new ExportedMap(); + requests.forEach(function (request) { + if (requestsById.has(request.id)) { + requestsById.get(request.id).push(request); + } else { + requestsById.set(request.id, [request]); } + }); - var putReq = bySeqStore.put(doc); + var numDocs = requestsById.size; + var numDone = 0; + var perDocResults = new Array(numDocs); - putReq.onsuccess = afterPutDoc; - putReq.onerror = afterPutDocError; + function collapseResultsAndFinish() { + var results = []; + perDocResults.forEach(function (res) { + res.docs.forEach(function (info) { + results.push({ + id: res.id, + docs: [info] + }); + }); + }); + callback(null, {results: results}); } - function writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted, - isUpdate, resultsIdx, callback) { + function checkDone() { + if (++numDone === numDocs) { + collapseResultsAndFinish(); + } + } + function gotResult(docIndex, id, docs) { + perDocResults[docIndex] = {id: id, docs: docs}; + checkDone(); + } - var doc = docInfo.data; + var allRequests = []; + requestsById.forEach(function (value, key) { + allRequests.push(key); + }); - var numDone = 0; - var attachments = Object.keys(doc._attachments); + var i = 0; - function collectResults() { - if (numDone === attachments.length) { - finishDoc(docInfo, winningRev$$1, winningRevIsDeleted, - isUpdate, resultsIdx, callback); - } - } + function nextBatch() { - function attachmentSaved() { - numDone++; - collectResults(); + if (i >= allRequests.length) { + return; } - attachments.forEach(function (key) { - var att = docInfo.data._attachments[key]; - if (!att.stub) { - var data = att.data; - delete att.data; - att.revpos = parseInt(winningRev$$1, 10); - var digest = att.digest; - saveAttachment(digest, data, attachmentSaved); - } else { - numDone++; - collectResults(); - } - }); + var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length); + var batch = allRequests.slice(i, upTo); + processBatch(batch, i); + i += batch.length; } - // map seqs to attachment digests, which - // we will need later during compaction - function insertAttachmentMappings(docInfo, seq, callback) { + function processBatch(batch, offset) { + batch.forEach(function (docId, j) { + var docIdx = offset + j; + var docRequests = requestsById.get(docId); - var attsAdded = 0; - var attsToAdd = Object.keys(docInfo.data._attachments || {}); + // just use the first request as the "template" + // TODO: The _bulk_get API allows for more subtle use cases than this, + // but for now it is unlikely that there will be a mix of different + // "atts_since" or "attachments" in the same request, since it's just + // replicate.js that is using this for the moment. + // Also, atts_since is aspirational, since we don't support it yet. + var docOpts = pick(docRequests[0], ['atts_since', 'attachments']); + docOpts.open_revs = docRequests.map(function (request) { + // rev is optional, open_revs disallowed + return request.rev; + }); - if (!attsToAdd.length) { - return callback(); - } + // remove falsey / undefined revisions + docOpts.open_revs = docOpts.open_revs.filter(identityFunction); - function checkDone() { - if (++attsAdded === attsToAdd.length) { - callback(); + var formatResult = identityFunction; + + if (docOpts.open_revs.length === 0) { + delete docOpts.open_revs; + + // when fetching only the "winning" leaf, + // transform the result so it looks like an open_revs + // request + formatResult = formatResultForOpenRevsGet; } - } - function add(att) { - var digest = docInfo.data._attachments[att].digest; - var req = attachAndSeqStore.put({ - seq: seq, - digestSeq: digest + '::' + seq + // globally-supplied options + ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) { + if (param in opts) { + docOpts[param] = opts[param]; + } }); - - req.onsuccess = checkDone; - req.onerror = function (e) { - // this callback is for a constaint error, which we ignore - // because this docid/rev has already been associated with - // the digest (e.g. when new_edits == false) - e.preventDefault(); // avoid transaction abort - e.stopPropagation(); // avoid transaction onerror - checkDone(); - }; - } - for (var i = 0; i < attsToAdd.length; i++) { - add(attsToAdd[i]); // do in parallel - } + db.get(docId, docOpts, function (err, res) { + var result; + /* istanbul ignore if */ + if (err) { + result = [{error: err}]; + } else { + result = formatResult(res); + } + gotResult(docIdx, docId, result); + nextBatch(); + }); + }); } - function saveAttachment(digest, data, callback) { - + nextBatch(); - var getKeyReq = attachStore.count(digest); - getKeyReq.onsuccess = function (e) { - var count = e.target.result; - if (count) { - return callback(); // already exists - } - var newAtt = { - digest: digest, - body: data - }; - var putReq = attachStore.put(newAtt); - putReq.onsuccess = callback; - }; - } } -// Abstraction over IDBCursor and getAll()/getAllKeys() that allows us to batch our operations -// while falling back to a normal IDBCursor operation on browsers that don't support getAll() or -// getAllKeys(). This allows for a much faster implementation than just straight-up cursors, because -// we're not processing each document one-at-a-time. -function runBatchedCursor(objectStore, keyRange, descending, batchSize, onBatch) { +var hasLocal; - if (batchSize === -1) { - batchSize = 1000; - } +try { + localStorage.setItem('_pouch_check_localstorage', 1); + hasLocal = !!localStorage.getItem('_pouch_check_localstorage'); +} catch (e) { + hasLocal = false; +} - // Bail out of getAll()/getAllKeys() in the following cases: - // 1) either method is unsupported - we need both - // 2) batchSize is 1 (might as well use IDBCursor) - // 3) descending – no real way to do this via getAll()/getAllKeys() +function hasLocalStorage() { + return hasLocal; +} - var useGetAll = typeof objectStore.getAll === 'function' && - typeof objectStore.getAllKeys === 'function' && - batchSize > 1 && !descending; +// Custom nextTick() shim for browsers. In node, this will just be process.nextTick(). We - var keysBatch; - var valuesBatch; - var pseudoCursor; +inherits__WEBPACK_IMPORTED_MODULE_3___default()(Changes, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); - function onGetAll(e) { - valuesBatch = e.target.result; - if (keysBatch) { - onBatch(keysBatch, valuesBatch, pseudoCursor); - } +/* istanbul ignore next */ +function attachBrowserEvents(self) { + if (hasLocalStorage()) { + addEventListener("storage", function (e) { + self.emit(e.key); + }); } +} - function onGetAllKeys(e) { - keysBatch = e.target.result; - if (valuesBatch) { - onBatch(keysBatch, valuesBatch, pseudoCursor); - } - } +function Changes() { + events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this); + this._listeners = {}; - function continuePseudoCursor() { - if (!keysBatch.length) { // no more results - return onBatch(); + attachBrowserEvents(this); +} +Changes.prototype.addListener = function (dbName, id, db, opts) { + /* istanbul ignore if */ + if (this._listeners[id]) { + return; + } + var self = this; + var inprogress = false; + function eventFunction() { + /* istanbul ignore if */ + if (!self._listeners[id]) { + return; } - // fetch next batch, exclusive start - var lastKey = keysBatch[keysBatch.length - 1]; - var newKeyRange; - if (keyRange && keyRange.upper) { - try { - newKeyRange = IDBKeyRange.bound(lastKey, keyRange.upper, - true, keyRange.upperOpen); - } catch (e) { - if (e.name === "DataError" && e.code === 0) { - return onBatch(); // we're done, startkey and endkey are equal - } - } - } else { - newKeyRange = IDBKeyRange.lowerBound(lastKey, true); + if (inprogress) { + inprogress = 'waiting'; + return; } - keyRange = newKeyRange; - keysBatch = null; - valuesBatch = null; - objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll; - objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys; - } + inprogress = true; + var changesOpts = pick(opts, [ + 'style', 'include_docs', 'attachments', 'conflicts', 'filter', + 'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs' + ]); - function onCursor(e) { - var cursor = e.target.result; - if (!cursor) { // done - return onBatch(); + /* istanbul ignore next */ + function onError() { + inprogress = false; } - // regular IDBCursor acts like a batch where batch size is always 1 - onBatch([cursor.key], [cursor.value], cursor); - } - if (useGetAll) { - pseudoCursor = {"continue": continuePseudoCursor}; - objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll; - objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys; - } else if (descending) { - objectStore.openCursor(keyRange, 'prev').onsuccess = onCursor; - } else { - objectStore.openCursor(keyRange).onsuccess = onCursor; + db.changes(changesOpts).on('change', function (c) { + if (c.seq > opts.since && !opts.cancelled) { + opts.since = c.seq; + opts.onChange(c); + } + }).on('complete', function () { + if (inprogress === 'waiting') { + immediate__WEBPACK_IMPORTED_MODULE_1___default()(eventFunction); + } + inprogress = false; + }).on('error', onError); } -} + this._listeners[id] = eventFunction; + this.on(dbName, eventFunction); +}; -// simple shim for objectStore.getAll(), falling back to IDBCursor -function getAll(objectStore, keyRange, onSuccess) { - if (typeof objectStore.getAll === 'function') { - // use native getAll - objectStore.getAll(keyRange).onsuccess = onSuccess; +Changes.prototype.removeListener = function (dbName, id) { + /* istanbul ignore if */ + if (!(id in this._listeners)) { return; } - // fall back to cursors - var values = []; + events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype.removeListener.call(this, dbName, + this._listeners[id]); + delete this._listeners[id]; +}; - function onCursor(e) { - var cursor = e.target.result; - if (cursor) { - values.push(cursor.value); - cursor.continue(); - } else { - onSuccess({ - target: { - result: values - } - }); - } - } - objectStore.openCursor(keyRange).onsuccess = onCursor; -} +/* istanbul ignore next */ +Changes.prototype.notifyLocalWindows = function (dbName) { + //do a useless change on a storage thing + //in order to get other windows's listeners to activate + if (hasLocalStorage()) { + localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a"; + } +}; -function allDocsKeys(keys, docStore, onBatch) { - // It's not guaranted to be returned in right order - var valuesBatch = new Array(keys.length); - var count = 0; - keys.forEach(function (key, index) { - docStore.get(key).onsuccess = function (event) { - if (event.target.result) { - valuesBatch[index] = event.target.result; - } else { - valuesBatch[index] = {key: key, error: 'not_found'}; - } - count++; - if (count === keys.length) { - onBatch(keys, valuesBatch, {}); - } - }; - }); -} +Changes.prototype.notify = function (dbName) { + this.emit(dbName); + this.notifyLocalWindows(dbName); +}; -function createKeyRange(start, end, inclusiveEnd, key, descending) { - try { - if (start && end) { - if (descending) { - return IDBKeyRange.bound(end, start, !inclusiveEnd, false); - } else { - return IDBKeyRange.bound(start, end, false, !inclusiveEnd); - } - } else if (start) { - if (descending) { - return IDBKeyRange.upperBound(start); - } else { - return IDBKeyRange.lowerBound(start); - } - } else if (end) { - if (descending) { - return IDBKeyRange.lowerBound(end, !inclusiveEnd); - } else { - return IDBKeyRange.upperBound(end, !inclusiveEnd); - } - } else if (key) { - return IDBKeyRange.only(key); - } - } catch (e) { - return {error: e}; +function guardedConsole(method) { + /* istanbul ignore else */ + if (typeof console !== 'undefined' && typeof console[method] === 'function') { + var args = Array.prototype.slice.call(arguments, 1); + console[method].apply(console, args); } - return null; } -function idbAllDocs(opts, idb, callback) { - var start = 'startkey' in opts ? opts.startkey : false; - var end = 'endkey' in opts ? opts.endkey : false; - var key = 'key' in opts ? opts.key : false; - var keys = 'keys' in opts ? opts.keys : false; - var skip = opts.skip || 0; - var limit = typeof opts.limit === 'number' ? opts.limit : -1; - var inclusiveEnd = opts.inclusive_end !== false; - - var keyRange ; - var keyRangeError; - if (!keys) { - keyRange = createKeyRange(start, end, inclusiveEnd, key, opts.descending); - keyRangeError = keyRange && keyRange.error; - if (keyRangeError && - !(keyRangeError.name === "DataError" && keyRangeError.code === 0)) { - // DataError with error code 0 indicates start is less than end, so - // can just do an empty query. Else need to throw - return callback(createError(IDB_ERROR, - keyRangeError.name, keyRangeError.message)); - } +function randomNumber(min, max) { + var maxTimeout = 600000; // Hard-coded default of 10 minutes + min = parseInt(min, 10) || 0; + max = parseInt(max, 10); + if (max !== max || max <= min) { + max = (min || 1) << 1; //doubling + } else { + max = max + 1; + } + // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout + if (max > maxTimeout) { + min = maxTimeout >> 1; // divide by two + max = maxTimeout; } + var ratio = Math.random(); + var range = max - min; - var stores = [DOC_STORE, BY_SEQ_STORE, META_STORE]; + return ~~(range * ratio + min); // ~~ coerces to an int, but fast. +} - if (opts.attachments) { - stores.push(ATTACH_STORE); - } - var txnResult = openTransactionSafely(idb, stores, 'readonly'); - if (txnResult.error) { - return callback(txnResult.error); +function defaultBackOff(min) { + var max = 0; + if (!min) { + max = 2000; } - var txn = txnResult.txn; - txn.oncomplete = onTxnComplete; - txn.onabort = idbError(callback); - var docStore = txn.objectStore(DOC_STORE); - var seqStore = txn.objectStore(BY_SEQ_STORE); - var metaStore = txn.objectStore(META_STORE); - var docIdRevIndex = seqStore.index('_doc_id_rev'); - var results = []; - var docCount; - var updateSeq; + return randomNumber(min, max); +} - metaStore.get(META_STORE).onsuccess = function (e) { - docCount = e.target.result.docCount; - }; +// designed to give info to browser users, who are disturbed +// when they see http errors in the console +function explainError(status, str) { + guardedConsole('info', 'The above ' + status + ' is totally normal. ' + str); +} - /* istanbul ignore if */ - if (opts.update_seq) { - getMaxUpdateSeq(seqStore, function (e) { - if (e.target.result && e.target.result.length > 0) { - updateSeq = e.target.result[0]; - } - }); - } +var assign; +{ + if (typeof Object.assign === 'function') { + assign = Object.assign; + } else { + // lite Object.assign polyfill based on + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + assign = function (target) { + var to = Object(target); - function getMaxUpdateSeq(objectStore, onSuccess) { - function onCursor(e) { - var cursor = e.target.result; - var maxKey = undefined; - if (cursor && cursor.key) { - maxKey = cursor.key; - } - return onSuccess({ - target: { - result: [maxKey] - } - }); - } - objectStore.openCursor(null, 'prev').onsuccess = onCursor; - } + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; - // if the user specifies include_docs=true, then we don't - // want to block the main cursor while we're fetching the doc - function fetchDocAsynchronously(metadata, row, winningRev$$1) { - var key = metadata.id + "::" + winningRev$$1; - docIdRevIndex.get(key).onsuccess = function onGetDoc(e) { - row.doc = decodeDoc(e.target.result) || {}; - if (opts.conflicts) { - var conflicts = collectConflicts(metadata); - if (conflicts.length) { - row.doc._conflicts = conflicts; + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } } } - fetchAttachmentsIfNecessary(row.doc, opts, txn); + return to; }; } +} - function allDocsInner(winningRev$$1, metadata) { - var row = { - id: metadata.id, - key: metadata.id, - value: { - rev: winningRev$$1 - } - }; - var deleted = metadata.deleted; - if (deleted) { - if (keys) { - results.push(row); - // deleted docs are okay with "keys" requests - row.value.deleted = true; - row.doc = null; - } - } else if (skip-- <= 0) { - results.push(row); - if (opts.include_docs) { - fetchDocAsynchronously(metadata, row, winningRev$$1); - } - } - } +var $inject_Object_assign = assign; - function processBatch(batchValues) { - for (var i = 0, len = batchValues.length; i < len; i++) { - if (results.length === limit) { - break; - } - var batchValue = batchValues[i]; - if (batchValue.error && keys) { - // key was not found with "keys" requests - results.push(batchValue); - continue; - } - var metadata = decodeMetadata(batchValue); - var winningRev$$1 = metadata.winningRev; - allDocsInner(winningRev$$1, metadata); - } - } +inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchError, Error); - function onBatch(batchKeys, batchValues, cursor) { - if (!cursor) { - return; +function PouchError(status, error, reason) { + Error.call(this, reason); + this.status = status; + this.name = error; + this.message = reason; + this.error = true; +} + +PouchError.prototype.toString = function () { + return JSON.stringify({ + status: this.status, + name: this.name, + message: this.message, + reason: this.reason + }); +}; + +var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect."); +var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'"); +var MISSING_DOC = new PouchError(404, 'not_found', 'missing'); +var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict'); +var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string'); +var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts'); +var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.'); +var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open'); +var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error'); +var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid'); +var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid'); +var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid'); +var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member'); +var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request'); +var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object'); +var DB_MISSING = new PouchError(404, 'not_found', 'Database not found'); +var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown'); +var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown'); +var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown'); +var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function'); +var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format'); +var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.'); +var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found'); +var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid'); + +function createError(error, reason) { + function CustomPouchError(reason) { + // inherit error properties from our parent error manually + // so as to allow proper JSON parsing. + /* jshint ignore:start */ + for (var p in error) { + if (typeof error[p] !== 'function') { + this[p] = error[p]; + } } - processBatch(batchValues); - if (results.length < limit) { - cursor.continue(); + /* jshint ignore:end */ + if (reason !== undefined) { + this.reason = reason; } } + CustomPouchError.prototype = PouchError.prototype; + return new CustomPouchError(reason); +} - function onGetAll(e) { - var values = e.target.result; - if (opts.descending) { - values = values.reverse(); - } - processBatch(values); +function generateErrorFromResponse(err) { + + if (typeof err !== 'object') { + var data = err; + err = UNKNOWN_ERROR; + err.data = data; } - function onResultsReady() { - var returnVal = { - total_rows: docCount, - offset: opts.skip, - rows: results - }; - - /* istanbul ignore if */ - if (opts.update_seq && updateSeq !== undefined) { - returnVal.update_seq = updateSeq; - } - callback(null, returnVal); + if ('error' in err && err.error === 'conflict') { + err.name = 'conflict'; + err.status = 409; } - function onTxnComplete() { - if (opts.attachments) { - postProcessAttachments(results, opts.binary).then(onResultsReady); - } else { - onResultsReady(); - } + if (!('name' in err)) { + err.name = err.error || 'unknown'; } - // don't bother doing any requests if start > end or limit === 0 - if (keyRangeError || limit === 0) { - return; + if (!('status' in err)) { + err.status = 500; } - if (keys) { - return allDocsKeys(opts.keys, docStore, onBatch); + + if (!('message' in err)) { + err.message = err.message || err.reason; } - if (limit === -1) { // just fetch everything - return getAll(docStore, keyRange, onGetAll); + + return err; +} + +function tryFilter(filter, doc, req) { + try { + return !filter(doc, req); + } catch (err) { + var msg = 'Filter function threw: ' + err.toString(); + return createError(BAD_REQUEST, msg); } - // else do a cursor - // choose a batch size based on the skip, since we'll need to skip that many - runBatchedCursor(docStore, keyRange, opts.descending, limit + skip, onBatch); } -// -// Blobs are not supported in all versions of IndexedDB, notably -// Chrome <37 and Android <5. In those versions, storing a blob will throw. -// -// Various other blob bugs exist in Chrome v37-42 (inclusive). -// Detecting them is expensive and confusing to users, and Chrome 37-42 -// is at very low usage worldwide, so we do a hacky userAgent check instead. -// -// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120 -// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916 -// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836 -// -function checkBlobSupport(txn) { - return new Promise(function (resolve) { - var blob$$1 = createBlob(['']); - var req = txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob$$1, 'key'); +function filterChange(opts) { + var req = {}; + var hasFilter = opts.filter && typeof opts.filter === 'function'; + req.query = opts.query_params; - req.onsuccess = function () { - var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/); - var matchedEdge = navigator.userAgent.match(/Edge\//); - // MS Edge pretends to be Chrome 42: - // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx - resolve(matchedEdge || !matchedChrome || - parseInt(matchedChrome[1], 10) >= 43); - }; + return function filter(change) { + if (!change.doc) { + // CSG sends events on the changes feed that don't have documents, + // this hack makes a whole lot of existing code robust. + change.doc = {}; + } - req.onerror = txn.onabort = function (e) { - // If the transaction aborts now its due to not being able to - // write to the database, likely due to the disk being full - e.preventDefault(); - e.stopPropagation(); - resolve(false); - }; - }).catch(function () { - return false; // error, so assume unsupported - }); -} + var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req); -function countDocs(txn, cb) { - var index = txn.objectStore(DOC_STORE).index('deletedOrLocal'); - index.count(IDBKeyRange.only('0')).onsuccess = function (e) { - cb(e.target.result); + if (typeof filterReturn === 'object') { + return filterReturn; + } + + if (filterReturn) { + return false; + } + + if (!opts.include_docs) { + delete change.doc; + } else if (!opts.attachments) { + for (var att in change.doc._attachments) { + /* istanbul ignore else */ + if (change.doc._attachments.hasOwnProperty(att)) { + change.doc._attachments[att].stub = true; + } + } + } + return true; }; } -// This task queue ensures that IDB open calls are done in their own tick +function flatten(arrs) { + var res = []; + for (var i = 0, len = arrs.length; i < len; i++) { + res = res.concat(arrs[i]); + } + return res; +} -var running = false; -var queue = []; +// shim for Function.prototype.name, -function tryCode(fun, err, res, PouchDB) { - try { - fun(err, res); - } catch (err) { - // Shouldn't happen, but in some odd cases - // IndexedDB implementations might throw a sync - // error, in which case this will at least log it. - PouchDB.emit('error', err); +// Determine id an ID is valid +// - invalid IDs begin with an underescore that does not begin '_design' or +// '_local' +// - any other string value is a valid id +// Returns the specific error object for each case +function invalidIdError(id) { + var err; + if (!id) { + err = createError(MISSING_ID); + } else if (typeof id !== 'string') { + err = createError(INVALID_ID); + } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) { + err = createError(RESERVED_ID); + } + if (err) { + throw err; } } -function applyNext() { - if (running || !queue.length) { - return; +// Checks if a PouchDB object is "remote" or not. This is + +function isRemote(db) { + if (typeof db._remote === 'boolean') { + return db._remote; } - running = true; - queue.shift()(); + /* istanbul ignore next */ + if (typeof db.type === 'function') { + guardedConsole('warn', + 'db.type() is deprecated and will be removed in ' + + 'a future version of PouchDB'); + return db.type() === 'http'; + } + /* istanbul ignore next */ + return false; } -function enqueueTask(action, callback, PouchDB) { - queue.push(function runAction() { - action(function runCallback(err, res) { - tryCode(callback, err, res, PouchDB); - running = false; - immediate__WEBPACK_IMPORTED_MODULE_1___default()(function runNext() { - applyNext(PouchDB); - }); - }); - }); - applyNext(); +function listenerCount(ee, type) { + return 'listenerCount' in ee ? ee.listenerCount(type) : + events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.listenerCount(ee, type); } -function changes(opts, api, dbName, idb) { - opts = clone(opts); - - if (opts.continuous) { - var id = dbName + ':' + uuid(); - changesHandler.addListener(dbName, id, api, opts); - changesHandler.notify(dbName); - return { - cancel: function () { - changesHandler.removeListener(dbName, id); - } - }; +function parseDesignDocFunctionName(s) { + if (!s) { + return null; + } + var parts = s.split('/'); + if (parts.length === 2) { + return parts; + } + if (parts.length === 1) { + return [s, s]; } + return null; +} - var docIds = opts.doc_ids && new ExportedSet(opts.doc_ids); +function normalizeDesignDocFunctionName(s) { + var normalized = parseDesignDocFunctionName(s); + return normalized ? normalized.join('/') : null; +} - opts.since = opts.since || 0; - var lastSeq = opts.since; +// originally parseUri 1.2.2, now patched by us +// (c) Steven Levithan <stevenlevithan.com> +// MIT License +var keys = ["source", "protocol", "authority", "userInfo", "user", "password", + "host", "port", "relative", "path", "directory", "file", "query", "anchor"]; +var qName ="queryKey"; +var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g; - var limit = 'limit' in opts ? opts.limit : -1; - if (limit === 0) { - limit = 1; // per CouchDB _changes spec - } +// use the "loose" parser +/* eslint maxlen: 0, no-useless-escape: 0 */ +var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; - var results = []; - var numResults = 0; - var filter = filterChange(opts); - var docIdsToMetadata = new ExportedMap(); +function parseUri(str) { + var m = parser.exec(str); + var uri = {}; + var i = 14; - var txn; - var bySeqStore; - var docStore; - var docIdRevIndex; + while (i--) { + var key = keys[i]; + var value = m[i] || ""; + var encoded = ['user', 'password'].indexOf(key) !== -1; + uri[key] = encoded ? decodeURIComponent(value) : value; + } - function onBatch(batchKeys, batchValues, cursor) { - if (!cursor || !batchKeys.length) { // done - return; + uri[qName] = {}; + uri[keys[12]].replace(qParser, function ($0, $1, $2) { + if ($1) { + uri[qName][$1] = $2; } + }); - var winningDocs = new Array(batchKeys.length); - var metadatas = new Array(batchKeys.length); - - function processMetadataAndWinningDoc(metadata, winningDoc) { - var change = opts.processChange(winningDoc, metadata, opts); - lastSeq = change.seq = metadata.seq; + return uri; +} - var filtered = filter(change); - if (typeof filtered === 'object') { // anything but true/false indicates error - return Promise.reject(filtered); - } +// Based on https://github.com/alexdavid/scope-eval v0.0.3 +// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js) +// This is basically just a wrapper around new Function() - if (!filtered) { - return Promise.resolve(); - } - numResults++; - if (opts.return_docs) { - results.push(change); - } - // process the attachment immediately - // for the benefit of live listeners - if (opts.attachments && opts.include_docs) { - return new Promise(function (resolve) { - fetchAttachmentsIfNecessary(winningDoc, opts, txn, function () { - postProcessAttachments([change], opts.binary).then(function () { - resolve(change); - }); - }); - }); - } else { - return Promise.resolve(change); - } +function scopeEval(source, scope) { + var keys = []; + var values = []; + for (var key in scope) { + if (scope.hasOwnProperty(key)) { + keys.push(key); + values.push(scope[key]); } + } + keys.push(source); + return Function.apply(null, keys).apply(null, values); +} - function onBatchDone() { - var promises = []; - for (var i = 0, len = winningDocs.length; i < len; i++) { - if (numResults === limit) { - break; - } - var winningDoc = winningDocs[i]; - if (!winningDoc) { - continue; +// this is essentially the "update sugar" function from daleharvey/pouchdb#1388 +// the diffFun tells us what delta to apply to the doc. it either returns +// the doc, or false if it doesn't need to do an update after all +function upsert(db, docId, diffFun) { + return new Promise(function (fulfill, reject) { + db.get(docId, function (err, doc) { + if (err) { + /* istanbul ignore next */ + if (err.status !== 404) { + return reject(err); } - var metadata = metadatas[i]; - promises.push(processMetadataAndWinningDoc(metadata, winningDoc)); + doc = {}; } - Promise.all(promises).then(function (changes) { - for (var i = 0, len = changes.length; i < len; i++) { - if (changes[i]) { - opts.onChange(changes[i]); - } - } - }).catch(opts.complete); + // the user might change the _rev, so save it for posterity + var docRev = doc._rev; + var newDoc = diffFun(doc); - if (numResults !== limit) { - cursor.continue(); + if (!newDoc) { + // if the diffFun returns falsy, we short-circuit as + // an optimization + return fulfill({updated: false, rev: docRev}); } - } - // Fetch all metadatas/winningdocs from this batch in parallel, then process - // them all only once all data has been collected. This is done in parallel - // because it's faster than doing it one-at-a-time. - var numDone = 0; - batchValues.forEach(function (value, i) { - var doc = decodeDoc(value); - var seq = batchKeys[i]; - fetchWinningDocAndMetadata(doc, seq, function (metadata, winningDoc) { - metadatas[i] = metadata; - winningDocs[i] = winningDoc; - if (++numDone === batchKeys.length) { - onBatchDone(); - } - }); + // users aren't allowed to modify these values, + // so reset them here + newDoc._id = docId; + newDoc._rev = docRev; + fulfill(tryAndPut(db, newDoc, diffFun)); }); - } + }); +} - function onGetMetadata(doc, seq, metadata, cb) { - if (metadata.seq !== seq) { - // some other seq is later - return cb(); +function tryAndPut(db, doc, diffFun) { + return db.put(doc).then(function (res) { + return { + updated: true, + rev: res.rev + }; + }, function (err) { + /* istanbul ignore next */ + if (err.status !== 409) { + throw err; + } + return upsert(db, doc._id, diffFun); + }); +} + +var thisAtob = function (str) { + return atob(str); +}; + +var thisBtoa = function (str) { + return btoa(str); +}; + +// Abstracts constructing a Blob object, so it also works in older +// browsers that don't support the native Blob constructor (e.g. +// old QtWebKit versions, Android < 4.4). +function createBlob(parts, properties) { + /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */ + parts = parts || []; + properties = properties || {}; + try { + return new Blob(parts, properties); + } catch (e) { + if (e.name !== "TypeError") { + throw e; } - - if (metadata.winningRev === doc._rev) { - // this is the winning doc - return cb(metadata, doc); + var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : + typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : + typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : + WebKitBlobBuilder; + var builder = new Builder(); + for (var i = 0; i < parts.length; i += 1) { + builder.append(parts[i]); } + return builder.getBlob(properties.type); + } +} - // fetch winning doc in separate request - var docIdRev = doc._id + '::' + metadata.winningRev; - var req = docIdRevIndex.get(docIdRev); - req.onsuccess = function (e) { - cb(metadata, decodeDoc(e.target.result)); - }; +// From http://stackoverflow.com/questions/14967647/ (continues on next line) +// encode-decode-image-with-base64-breaks-image (2013-04-21) +function binaryStringToArrayBuffer(bin) { + var length = bin.length; + var buf = new ArrayBuffer(length); + var arr = new Uint8Array(buf); + for (var i = 0; i < length; i++) { + arr[i] = bin.charCodeAt(i); } + return buf; +} - function fetchWinningDocAndMetadata(doc, seq, cb) { - if (docIds && !docIds.has(doc._id)) { - return cb(); - } +function binStringToBluffer(binString, type) { + return createBlob([binaryStringToArrayBuffer(binString)], {type: type}); +} - var metadata = docIdsToMetadata.get(doc._id); - if (metadata) { // cached - return onGetMetadata(doc, seq, metadata, cb); - } - // metadata not cached, have to go fetch it - docStore.get(doc._id).onsuccess = function (e) { - metadata = decodeMetadata(e.target.result); - docIdsToMetadata.set(doc._id, metadata); - onGetMetadata(doc, seq, metadata, cb); - }; - } +function b64ToBluffer(b64, type) { + return binStringToBluffer(thisAtob(b64), type); +} - function finish() { - opts.complete(null, { - results: results, - last_seq: lastSeq - }); +//Can't find original post, but this is close +//http://stackoverflow.com/questions/6965107/ (continues on next line) +//converting-between-strings-and-arraybuffers +function arrayBufferToBinaryString(buffer) { + var binary = ''; + var bytes = new Uint8Array(buffer); + var length = bytes.byteLength; + for (var i = 0; i < length; i++) { + binary += String.fromCharCode(bytes[i]); } + return binary; +} - function onTxnComplete() { - if (!opts.continuous && opts.attachments) { - // cannot guarantee that postProcessing was already done, - // so do it again - postProcessAttachments(results).then(finish); - } else { - finish(); +// shim for browsers that don't support it +function readAsBinaryString(blob, callback) { + var reader = new FileReader(); + var hasBinaryString = typeof reader.readAsBinaryString === 'function'; + reader.onloadend = function (e) { + var result = e.target.result || ''; + if (hasBinaryString) { + return callback(result); } + callback(arrayBufferToBinaryString(result)); + }; + if (hasBinaryString) { + reader.readAsBinaryString(blob); + } else { + reader.readAsArrayBuffer(blob); } +} - var objectStores = [DOC_STORE, BY_SEQ_STORE]; - if (opts.attachments) { - objectStores.push(ATTACH_STORE); - } - var txnResult = openTransactionSafely(idb, objectStores, 'readonly'); - if (txnResult.error) { - return opts.complete(txnResult.error); - } - txn = txnResult.txn; - txn.onabort = idbError(opts.complete); - txn.oncomplete = onTxnComplete; - - bySeqStore = txn.objectStore(BY_SEQ_STORE); - docStore = txn.objectStore(DOC_STORE); - docIdRevIndex = bySeqStore.index('_doc_id_rev'); +function blobToBinaryString(blobOrBuffer, callback) { + readAsBinaryString(blobOrBuffer, function (bin) { + callback(bin); + }); +} - var keyRange = (opts.since && !opts.descending) ? - IDBKeyRange.lowerBound(opts.since, true) : null; +function blobToBase64(blobOrBuffer, callback) { + blobToBinaryString(blobOrBuffer, function (base64) { + callback(thisBtoa(base64)); + }); +} - runBatchedCursor(bySeqStore, keyRange, opts.descending, limit, onBatch); +// simplified API. universal browser support is assumed +function readAsArrayBuffer(blob, callback) { + var reader = new FileReader(); + reader.onloadend = function (e) { + var result = e.target.result || new ArrayBuffer(0); + callback(result); + }; + reader.readAsArrayBuffer(blob); } -var cachedDBs = new ExportedMap(); -var blobSupportPromise; -var openReqList = new ExportedMap(); +// this is not used in the browser -function IdbPouch(opts, callback) { - var api = this; +var setImmediateShim = global.setImmediate || global.setTimeout; +var MD5_CHUNK_SIZE = 32768; - enqueueTask(function (thisCallback) { - init(api, opts, thisCallback); - }, callback, api.constructor); +function rawToBase64(raw) { + return thisBtoa(raw); } -function init(api, opts, callback) { - - var dbName = opts.name; +function sliceBlob(blob, start, end) { + if (blob.webkitSlice) { + return blob.webkitSlice(start, end); + } + return blob.slice(start, end); +} - var idb = null; - api._meta = null; +function appendBlob(buffer, blob, start, end, callback) { + if (start > 0 || end < blob.size) { + // only slice blob if we really need to + blob = sliceBlob(blob, start, end); + } + readAsArrayBuffer(blob, function (arrayBuffer) { + buffer.append(arrayBuffer); + callback(); + }); +} - // called when creating a fresh new database - function createSchema(db) { - var docStore = db.createObjectStore(DOC_STORE, {keyPath : 'id'}); - db.createObjectStore(BY_SEQ_STORE, {autoIncrement: true}) - .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true}); - db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'}); - db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false}); - db.createObjectStore(DETECT_BLOB_SUPPORT_STORE); +function appendString(buffer, string, start, end, callback) { + if (start > 0 || end < string.length) { + // only create a substring if we really need to + string = string.substring(start, end); + } + buffer.appendBinary(string); + callback(); +} - // added in v2 - docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false}); +function binaryMd5(data, callback) { + var inputIsString = typeof data === 'string'; + var len = inputIsString ? data.length : data.size; + var chunkSize = Math.min(MD5_CHUNK_SIZE, len); + var chunks = Math.ceil(len / chunkSize); + var currentChunk = 0; + var buffer = inputIsString ? new (spark_md5__WEBPACK_IMPORTED_MODULE_4___default())() : new (spark_md5__WEBPACK_IMPORTED_MODULE_4___default().ArrayBuffer)(); - // added in v3 - db.createObjectStore(LOCAL_STORE, {keyPath: '_id'}); + var append = inputIsString ? appendString : appendBlob; - // added in v4 - var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE, - {autoIncrement: true}); - attAndSeqStore.createIndex('seq', 'seq'); - attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true}); + function next() { + setImmediateShim(loadNextChunk); } - // migration to version 2 - // unfortunately "deletedOrLocal" is a misnomer now that we no longer - // store local docs in the main doc-store, but whaddyagonnado - function addDeletedOrLocalIndex(txn, callback) { - var docStore = txn.objectStore(DOC_STORE); - docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false}); - - docStore.openCursor().onsuccess = function (event) { - var cursor = event.target.result; - if (cursor) { - var metadata = cursor.value; - var deleted = isDeleted(metadata); - metadata.deletedOrLocal = deleted ? "1" : "0"; - docStore.put(metadata); - cursor.continue(); - } else { - callback(); - } - }; + function done() { + var raw = buffer.end(true); + var base64 = rawToBase64(raw); + callback(base64); + buffer.destroy(); } - // migration to version 3 (part 1) - function createLocalStoreSchema(db) { - db.createObjectStore(LOCAL_STORE, {keyPath: '_id'}) - .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true}); + function loadNextChunk() { + var start = currentChunk * chunkSize; + var end = start + chunkSize; + currentChunk++; + if (currentChunk < chunks) { + append(buffer, data, start, end, next); + } else { + append(buffer, data, start, end, done); + } } + loadNextChunk(); +} - // migration to version 3 (part 2) - function migrateLocalStore(txn, cb) { - var localStore = txn.objectStore(LOCAL_STORE); - var docStore = txn.objectStore(DOC_STORE); - var seqStore = txn.objectStore(BY_SEQ_STORE); +function stringMd5(string) { + return spark_md5__WEBPACK_IMPORTED_MODULE_4___default().hash(string); +} - var cursor = docStore.openCursor(); - cursor.onsuccess = function (event) { - var cursor = event.target.result; - if (cursor) { - var metadata = cursor.value; - var docId = metadata.id; - var local = isLocalId(docId); - var rev = winningRev(metadata); - if (local) { - var docIdRev = docId + "::" + rev; - // remove all seq entries - // associated with this docId - var start = docId + "::"; - var end = docId + "::~"; - var index = seqStore.index('_doc_id_rev'); - var range = IDBKeyRange.bound(start, end, false, false); - var seqCursor = index.openCursor(range); - seqCursor.onsuccess = function (e) { - seqCursor = e.target.result; - if (!seqCursor) { - // done - docStore.delete(cursor.primaryKey); - cursor.continue(); - } else { - var data = seqCursor.value; - if (data._doc_id_rev === docIdRev) { - localStore.put(data); - } - seqStore.delete(seqCursor.primaryKey); - seqCursor.continue(); - } - }; - } else { - cursor.continue(); - } - } else if (cb) { - cb(); - } - }; +function rev$$1(doc, deterministic_revs) { + var clonedDoc = clone(doc); + if (!deterministic_revs) { + return uuid__WEBPACK_IMPORTED_MODULE_5___default().v4().replace(/-/g, '').toLowerCase(); } - // migration to version 4 (part 1) - function addAttachAndSeqStore(db) { - var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE, - {autoIncrement: true}); - attAndSeqStore.createIndex('seq', 'seq'); - attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true}); - } + delete clonedDoc._rev_tree; + return stringMd5(JSON.stringify(clonedDoc)); +} - // migration to version 4 (part 2) - function migrateAttsAndSeqs(txn, callback) { - var seqStore = txn.objectStore(BY_SEQ_STORE); - var attStore = txn.objectStore(ATTACH_STORE); - var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE); +var uuid = (uuid__WEBPACK_IMPORTED_MODULE_5___default().v4); - // need to actually populate the table. this is the expensive part, - // so as an optimization, check first that this database even - // contains attachments - var req = attStore.count(); - req.onsuccess = function (e) { - var count = e.target.result; - if (!count) { - return callback(); // done +// We fetch all leafs of the revision tree, and sort them based on tree length +// and whether they were deleted, undeleted documents with the longest revision +// tree (most edits) win +// The final sort algorithm is slightly documented in a sidebar here: +// http://guide.couchdb.org/draft/conflicts.html +function winningRev(metadata) { + var winningId; + var winningPos; + var winningDeleted; + var toVisit = metadata.rev_tree.slice(); + var node; + while ((node = toVisit.pop())) { + var tree = node.ids; + var branches = tree[2]; + var pos = node.pos; + if (branches.length) { // non-leaf + for (var i = 0, len = branches.length; i < len; i++) { + toVisit.push({pos: pos + 1, ids: branches[i]}); } - - seqStore.openCursor().onsuccess = function (e) { - var cursor = e.target.result; - if (!cursor) { - return callback(); // done - } - var doc = cursor.value; - var seq = cursor.primaryKey; - var atts = Object.keys(doc._attachments || {}); - var digestMap = {}; - for (var j = 0; j < atts.length; j++) { - var att = doc._attachments[atts[j]]; - digestMap[att.digest] = true; // uniq digests, just in case - } - var digests = Object.keys(digestMap); - for (j = 0; j < digests.length; j++) { - var digest = digests[j]; - attAndSeqStore.put({ - seq: seq, - digestSeq: digest + '::' + seq - }); - } - cursor.continue(); - }; - }; + continue; + } + var deleted = !!tree[1].deleted; + var id = tree[0]; + // sort by deleted, then pos, then id + if (!winningId || (winningDeleted !== deleted ? winningDeleted : + winningPos !== pos ? winningPos < pos : winningId < id)) { + winningId = id; + winningPos = pos; + winningDeleted = deleted; + } } - // migration to version 5 - // Instead of relying on on-the-fly migration of metadata, - // this brings the doc-store to its modern form: - // - metadata.winningrev - // - metadata.seq - // - stringify the metadata when storing it - function migrateMetadata(txn) { + return winningPos + '-' + winningId; +} - function decodeMetadataCompat(storedObject) { - if (!storedObject.data) { - // old format, when we didn't store it stringified - storedObject.deleted = storedObject.deletedOrLocal === '1'; - return storedObject; - } - return decodeMetadata(storedObject); +// Pretty much all below can be combined into a higher order function to +// traverse revisions +// The return value from the callback will be passed as context to all +// children of that node +function traverseRevTree(revs, callback) { + var toVisit = revs.slice(); + + var node; + while ((node = toVisit.pop())) { + var pos = node.pos; + var tree = node.ids; + var branches = tree[2]; + var newCtx = + callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]); + for (var i = 0, len = branches.length; i < len; i++) { + toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx}); } + } +} - // ensure that every metadata has a winningRev and seq, - // which was previously created on-the-fly but better to migrate - var bySeqStore = txn.objectStore(BY_SEQ_STORE); - var docStore = txn.objectStore(DOC_STORE); - var cursor = docStore.openCursor(); - cursor.onsuccess = function (e) { - var cursor = e.target.result; - if (!cursor) { - return; // done - } - var metadata = decodeMetadataCompat(cursor.value); +function sortByPos(a, b) { + return a.pos - b.pos; +} - metadata.winningRev = metadata.winningRev || - winningRev(metadata); +function collectLeaves(revs) { + var leaves = []; + traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) { + if (isLeaf) { + leaves.push({rev: pos + "-" + id, pos: pos, opts: opts}); + } + }); + leaves.sort(sortByPos).reverse(); + for (var i = 0, len = leaves.length; i < len; i++) { + delete leaves[i].pos; + } + return leaves; +} - function fetchMetadataSeq() { - // metadata.seq was added post-3.2.0, so if it's missing, - // we need to fetch it manually - var start = metadata.id + '::'; - var end = metadata.id + '::\uffff'; - var req = bySeqStore.index('_doc_id_rev').openCursor( - IDBKeyRange.bound(start, end)); +// returns revs of all conflicts that is leaves such that +// 1. are not deleted and +// 2. are different than winning revision +function collectConflicts(metadata) { + var win = winningRev(metadata); + var leaves = collectLeaves(metadata.rev_tree); + var conflicts = []; + for (var i = 0, len = leaves.length; i < len; i++) { + var leaf = leaves[i]; + if (leaf.rev !== win && !leaf.opts.deleted) { + conflicts.push(leaf.rev); + } + } + return conflicts; +} - var metadataSeq = 0; - req.onsuccess = function (e) { - var cursor = e.target.result; - if (!cursor) { - metadata.seq = metadataSeq; - return onGetMetadataSeq(); - } - var seq = cursor.primaryKey; - if (seq > metadataSeq) { - metadataSeq = seq; - } - cursor.continue(); - }; - } +// compact a tree by marking its non-leafs as missing, +// and return a list of revs to delete +function compactTree(metadata) { + var revs = []; + traverseRevTree(metadata.rev_tree, function (isLeaf, pos, + revHash, ctx, opts) { + if (opts.status === 'available' && !isLeaf) { + revs.push(pos + '-' + revHash); + opts.status = 'missing'; + } + }); + return revs; +} - function onGetMetadataSeq() { - var metadataToStore = encodeMetadata(metadata, - metadata.winningRev, metadata.deleted); +// build up a list of all the paths to the leafs in this revision tree +function rootToLeaf(revs) { + var paths = []; + var toVisit = revs.slice(); + var node; + while ((node = toVisit.pop())) { + var pos = node.pos; + var tree = node.ids; + var id = tree[0]; + var opts = tree[1]; + var branches = tree[2]; + var isLeaf = branches.length === 0; - var req = docStore.put(metadataToStore); - req.onsuccess = function () { - cursor.continue(); - }; - } + var history = node.history ? node.history.slice() : []; + history.push({id: id, opts: opts}); + if (isLeaf) { + paths.push({pos: (pos + 1 - history.length), ids: history}); + } + for (var i = 0, len = branches.length; i < len; i++) { + toVisit.push({pos: pos + 1, ids: branches[i], history: history}); + } + } + return paths.reverse(); +} - if (metadata.seq) { - return onGetMetadataSeq(); - } +// for a better overview of what this is doing, read: - fetchMetadataSeq(); - }; +function sortByPos$1(a, b) { + return a.pos - b.pos; +} +// classic binary search +function binarySearch(arr, item, comparator) { + var low = 0; + var high = arr.length; + var mid; + while (low < high) { + mid = (low + high) >>> 1; + if (comparator(arr[mid], item) < 0) { + low = mid + 1; + } else { + high = mid; + } } + return low; +} - api._remote = false; - api.type = function () { - return 'idb'; - }; +// assuming the arr is sorted, insert the item in the proper place +function insertSorted(arr, item, comparator) { + var idx = binarySearch(arr, item, comparator); + arr.splice(idx, 0, item); +} - api._id = toPromise(function (callback) { - callback(null, api._meta.instanceId); - }); +// Turn a path as a flat array into a tree with a single branch. +// If any should be stemmed from the beginning of the array, that's passed +// in as the second argument +function pathToTree(path, numStemmed) { + var root; + var leaf; + for (var i = numStemmed, len = path.length; i < len; i++) { + var node = path[i]; + var currentLeaf = [node.id, node.opts, []]; + if (leaf) { + leaf[2].push(currentLeaf); + leaf = currentLeaf; + } else { + root = leaf = currentLeaf; + } + } + return root; +} - api._bulkDocs = function idb_bulkDocs(req, reqOpts, callback) { - idbBulkDocs(opts, req, reqOpts, api, idb, callback); - }; +// compare the IDs of two trees +function compareTree(a, b) { + return a[0] < b[0] ? -1 : 1; +} - // First we look up the metadata in the ids database, then we fetch the - // current revision(s) from the by sequence store - api._get = function idb_get(id, opts, callback) { - var doc; - var metadata; - var err; - var txn = opts.ctx; - if (!txn) { - var txnResult = openTransactionSafely(idb, - [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly'); - if (txnResult.error) { - return callback(txnResult.error); - } - txn = txnResult.txn; - } +// Merge two trees together +// The roots of tree1 and tree2 must be the same revision +function mergeTree(in_tree1, in_tree2) { + var queue = [{tree1: in_tree1, tree2: in_tree2}]; + var conflicts = false; + while (queue.length > 0) { + var item = queue.pop(); + var tree1 = item.tree1; + var tree2 = item.tree2; - function finish() { - callback(err, {doc: doc, metadata: metadata, ctx: txn}); + if (tree1[1].status || tree2[1].status) { + tree1[1].status = + (tree1[1].status === 'available' || + tree2[1].status === 'available') ? 'available' : 'missing'; } - txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) { - metadata = decodeMetadata(e.target.result); - // we can determine the result here if: - // 1. there is no such document - // 2. the document is deleted and we don't ask about specific rev - // When we ask with opts.rev we expect the answer to be either - // doc (possibly with _deleted=true) or missing error - if (!metadata) { - err = createError(MISSING_DOC, 'missing'); - return finish(); + for (var i = 0; i < tree2[2].length; i++) { + if (!tree1[2][0]) { + conflicts = 'new_leaf'; + tree1[2][0] = tree2[2][i]; + continue; } - var rev; - if (!opts.rev) { - rev = metadata.winningRev; - var deleted = isDeleted(metadata); - if (deleted) { - err = createError(MISSING_DOC, "deleted"); - return finish(); + var merged = false; + for (var j = 0; j < tree1[2].length; j++) { + if (tree1[2][j][0] === tree2[2][i][0]) { + queue.push({tree1: tree1[2][j], tree2: tree2[2][i]}); + merged = true; } - } else { - rev = opts.latest ? latest(opts.rev, metadata) : opts.rev; } - - var objectStore = txn.objectStore(BY_SEQ_STORE); - var key = metadata.id + '::' + rev; - - objectStore.index('_doc_id_rev').get(key).onsuccess = function (e) { - doc = e.target.result; - if (doc) { - doc = decodeDoc(doc); - } - if (!doc) { - err = createError(MISSING_DOC, 'missing'); - return finish(); - } - finish(); - }; - }; - }; - - api._getAttachment = function (docId, attachId, attachment, opts, callback) { - var txn; - if (opts.ctx) { - txn = opts.ctx; - } else { - var txnResult = openTransactionSafely(idb, - [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly'); - if (txnResult.error) { - return callback(txnResult.error); + if (!merged) { + conflicts = 'new_branch'; + insertSorted(tree1[2], tree2[2][i], compareTree); } - txn = txnResult.txn; } - var digest = attachment.digest; - var type = attachment.content_type; + } + return {conflicts: conflicts, tree: in_tree1}; +} - txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) { - var body = e.target.result.body; - readBlobData(body, type, opts.binary, function (blobData) { - callback(null, blobData); - }); - }; - }; +function doMerge(tree, path, dontExpand) { + var restree = []; + var conflicts = false; + var merged = false; + var res; - api._info = function idb_info(callback) { - var updateSeq; - var docCount; + if (!tree.length) { + return {tree: [path], conflicts: 'new_leaf'}; + } - var txnResult = openTransactionSafely(idb, [META_STORE, BY_SEQ_STORE], 'readonly'); - if (txnResult.error) { - return callback(txnResult.error); - } - var txn = txnResult.txn; - txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) { - docCount = e.target.result.docCount; - }; - txn.objectStore(BY_SEQ_STORE).openCursor(null, 'prev').onsuccess = function (e) { - var cursor = e.target.result; - updateSeq = cursor ? cursor.key : 0; - }; + for (var i = 0, len = tree.length; i < len; i++) { + var branch = tree[i]; + if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) { + // Paths start at the same position and have the same root, so they need + // merged + res = mergeTree(branch.ids, path.ids); + restree.push({pos: branch.pos, ids: res.tree}); + conflicts = conflicts || res.conflicts; + merged = true; + } else if (dontExpand !== true) { + // The paths start at a different position, take the earliest path and + // traverse up until it as at the same point from root as the path we + // want to merge. If the keys match we return the longer path with the + // other merged After stemming we dont want to expand the trees - txn.oncomplete = function () { - callback(null, { - doc_count: docCount, - update_seq: updateSeq, - // for debugging - idb_attachment_format: (api._meta.blobSupport ? 'binary' : 'base64') - }); - }; - }; + var t1 = branch.pos < path.pos ? branch : path; + var t2 = branch.pos < path.pos ? path : branch; + var diff = t2.pos - t1.pos; - api._allDocs = function idb_allDocs(opts, callback) { - idbAllDocs(opts, idb, callback); - }; + var candidateParents = []; - api._changes = function idbChanges(opts) { - return changes(opts, api, dbName, idb); - }; + var trees = []; + trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null}); + while (trees.length > 0) { + var item = trees.pop(); + if (item.diff === 0) { + if (item.ids[0] === t2.ids[0]) { + candidateParents.push(item); + } + continue; + } + var elements = item.ids[2]; + for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) { + trees.push({ + ids: elements[j], + diff: item.diff - 1, + parent: item.ids, + parentIdx: j + }); + } + } - api._close = function (callback) { - // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close - // "Returns immediately and closes the connection in a separate thread..." - idb.close(); - cachedDBs.delete(dbName); - callback(); - }; + var el = candidateParents[0]; - api._getRevisionTree = function (docId, callback) { - var txnResult = openTransactionSafely(idb, [DOC_STORE], 'readonly'); - if (txnResult.error) { - return callback(txnResult.error); - } - var txn = txnResult.txn; - var req = txn.objectStore(DOC_STORE).get(docId); - req.onsuccess = function (event) { - var doc = decodeMetadata(event.target.result); - if (!doc) { - callback(createError(MISSING_DOC)); + if (!el) { + restree.push(branch); } else { - callback(null, doc.rev_tree); + res = mergeTree(el.ids, t2.ids); + el.parent[2][el.parentIdx] = res.tree; + restree.push({pos: t1.pos, ids: t1.ids}); + conflicts = conflicts || res.conflicts; + merged = true; } - }; - }; - - // This function removes revisions of document docId - // which are listed in revs and sets this document - // revision to to rev_tree - api._doCompaction = function (docId, revs, callback) { - var stores = [ - DOC_STORE, - BY_SEQ_STORE, - ATTACH_STORE, - ATTACH_AND_SEQ_STORE - ]; - var txnResult = openTransactionSafely(idb, stores, 'readwrite'); - if (txnResult.error) { - return callback(txnResult.error); + } else { + restree.push(branch); } - var txn = txnResult.txn; - - var docStore = txn.objectStore(DOC_STORE); - - docStore.get(docId).onsuccess = function (event) { - var metadata = decodeMetadata(event.target.result); - traverseRevTree(metadata.rev_tree, function (isLeaf, pos, - revHash, ctx, opts) { - var rev = pos + '-' + revHash; - if (revs.indexOf(rev) !== -1) { - opts.status = 'missing'; - } - }); - compactRevs(revs, docId, txn); - var winningRev$$1 = metadata.winningRev; - var deleted = metadata.deleted; - txn.objectStore(DOC_STORE).put( - encodeMetadata(metadata, winningRev$$1, deleted)); - }; - txn.onabort = idbError(callback); - txn.oncomplete = function () { - callback(); - }; - }; + } + // We didnt find + if (!merged) { + restree.push(path); + } - api._getLocal = function (id, callback) { - var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readonly'); - if (txnResult.error) { - return callback(txnResult.error); - } - var tx = txnResult.txn; - var req = tx.objectStore(LOCAL_STORE).get(id); + restree.sort(sortByPos$1); - req.onerror = idbError(callback); - req.onsuccess = function (e) { - var doc = e.target.result; - if (!doc) { - callback(createError(MISSING_DOC)); - } else { - delete doc['_doc_id_rev']; // for backwards compat - callback(null, doc); - } - }; + return { + tree: restree, + conflicts: conflicts || 'internal_node' }; +} - api._putLocal = function (doc, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - delete doc._revisions; // ignore this, trust the rev - var oldRev = doc._rev; - var id = doc._id; - if (!oldRev) { - doc._rev = '0-1'; - } else { - doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1); - } +// To ensure we dont grow the revision tree infinitely, we stem old revisions +function stem(tree, depth) { + // First we break out the tree into a complete list of root to leaf paths + var paths = rootToLeaf(tree); + var stemmedRevs; - var tx = opts.ctx; - var ret; - if (!tx) { - var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite'); - if (txnResult.error) { - return callback(txnResult.error); + var result; + for (var i = 0, len = paths.length; i < len; i++) { + // Then for each path, we cut off the start of the path based on the + // `depth` to stem to, and generate a new set of flat trees + var path = paths[i]; + var stemmed = path.ids; + var node; + if (stemmed.length > depth) { + // only do the stemming work if we actually need to stem + if (!stemmedRevs) { + stemmedRevs = {}; // avoid allocating this object unnecessarily } - tx = txnResult.txn; - tx.onerror = idbError(callback); - tx.oncomplete = function () { - if (ret) { - callback(null, ret); - } - }; - } - - var oStore = tx.objectStore(LOCAL_STORE); - var req; - if (oldRev) { - req = oStore.get(id); - req.onsuccess = function (e) { - var oldDoc = e.target.result; - if (!oldDoc || oldDoc._rev !== oldRev) { - callback(createError(REV_CONFLICT)); - } else { // update - var req = oStore.put(doc); - req.onsuccess = function () { - ret = {ok: true, id: doc._id, rev: doc._rev}; - if (opts.ctx) { // return immediately - callback(null, ret); - } - }; - } - }; - } else { // new doc - req = oStore.add(doc); - req.onerror = function (e) { - // constraint error, already exists - callback(createError(REV_CONFLICT)); - e.preventDefault(); // avoid transaction abort - e.stopPropagation(); // avoid transaction onerror - }; - req.onsuccess = function () { - ret = {ok: true, id: doc._id, rev: doc._rev}; - if (opts.ctx) { // return immediately - callback(null, ret); - } + var numStemmed = stemmed.length - depth; + node = { + pos: path.pos + numStemmed, + ids: pathToTree(stemmed, numStemmed) }; - } - }; - api._removeLocal = function (doc, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - var tx = opts.ctx; - if (!tx) { - var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite'); - if (txnResult.error) { - return callback(txnResult.error); + for (var s = 0; s < numStemmed; s++) { + var rev = (path.pos + s) + '-' + stemmed[s].id; + stemmedRevs[rev] = true; } - tx = txnResult.txn; - tx.oncomplete = function () { - if (ret) { - callback(null, ret); - } + } else { // no need to actually stem + node = { + pos: path.pos, + ids: pathToTree(stemmed, 0) }; } - var ret; - var id = doc._id; - var oStore = tx.objectStore(LOCAL_STORE); - var req = oStore.get(id); - - req.onerror = idbError(callback); - req.onsuccess = function (e) { - var oldDoc = e.target.result; - if (!oldDoc || oldDoc._rev !== doc._rev) { - callback(createError(MISSING_DOC)); - } else { - oStore.delete(id); - ret = {ok: true, id: id, rev: '0-0'}; - if (opts.ctx) { // return immediately - callback(null, ret); - } - } - }; - }; - - api._destroy = function (opts, callback) { - changesHandler.removeAllListeners(dbName); - //Close open request for "dbName" database to fix ie delay. - var openReq = openReqList.get(dbName); - if (openReq && openReq.result) { - openReq.result.close(); - cachedDBs.delete(dbName); + // Then we remerge all those flat trees together, ensuring that we dont + // connect trees that would go beyond the depth limit + if (result) { + result = doMerge(result, node, true).tree; + } else { + result = [node]; } - var req = indexedDB.deleteDatabase(dbName); - - req.onsuccess = function () { - //Remove open request from the list. - openReqList.delete(dbName); - if (hasLocalStorage() && (dbName in localStorage)) { - delete localStorage[dbName]; - } - callback(null, { 'ok': true }); - }; - - req.onerror = idbError(callback); - }; - - var cached = cachedDBs.get(dbName); + } - if (cached) { - idb = cached.idb; - api._meta = cached.global; - return immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { - callback(null, api); + // this is memory-heavy per Chrome profiler, avoid unless we actually stemmed + if (stemmedRevs) { + traverseRevTree(result, function (isLeaf, pos, revHash) { + // some revisions may have been removed in a branch but not in another + delete stemmedRevs[pos + '-' + revHash]; }); } - var req = indexedDB.open(dbName, ADAPTER_VERSION); - openReqList.set(dbName, req); + return { + tree: result, + revs: stemmedRevs ? Object.keys(stemmedRevs) : [] + }; +} - req.onupgradeneeded = function (e) { - var db = e.target.result; - if (e.oldVersion < 1) { - return createSchema(db); // new db, initial schema - } - // do migrations +function merge(tree, path, depth) { + var newTree = doMerge(tree, path); + var stemmed = stem(newTree.tree, depth); + return { + tree: stemmed.tree, + stemmedRevs: stemmed.revs, + conflicts: newTree.conflicts + }; +} - var txn = e.currentTarget.transaction; - // these migrations have to be done in this function, before - // control is returned to the event loop, because IndexedDB +// return true if a rev exists in the rev tree, false otherwise +function revExists(revs, rev) { + var toVisit = revs.slice(); + var splitRev = rev.split('-'); + var targetPos = parseInt(splitRev[0], 10); + var targetId = splitRev[1]; - if (e.oldVersion < 3) { - createLocalStoreSchema(db); // v2 -> v3 + var node; + while ((node = toVisit.pop())) { + if (node.pos === targetPos && node.ids[0] === targetId) { + return true; } - if (e.oldVersion < 4) { - addAttachAndSeqStore(db); // v3 -> v4 + var branches = node.ids[2]; + for (var i = 0, len = branches.length; i < len; i++) { + toVisit.push({pos: node.pos + 1, ids: branches[i]}); } + } + return false; +} - var migrations = [ - addDeletedOrLocalIndex, // v1 -> v2 - migrateLocalStore, // v2 -> v3 - migrateAttsAndSeqs, // v3 -> v4 - migrateMetadata // v4 -> v5 - ]; +function getTrees(node) { + return node.ids; +} - var i = e.oldVersion; +// check if a specific revision of a doc has been deleted +// - metadata: the metadata object from the doc store +// - rev: (optional) the revision to check. defaults to winning revision +function isDeleted(metadata, rev) { + if (!rev) { + rev = winningRev(metadata); + } + var id = rev.substring(rev.indexOf('-') + 1); + var toVisit = metadata.rev_tree.map(getTrees); - function next() { - var migration = migrations[i - 1]; - i++; - if (migration) { - migration(txn, next); - } + var tree; + while ((tree = toVisit.pop())) { + if (tree[0] === id) { + return !!tree[1].deleted; } + toVisit = toVisit.concat(tree[2]); + } +} - next(); - }; +function isLocalId(id) { + return (/^_local/).test(id); +} - req.onsuccess = function (e) { +// returns the current leaf node for a given revision +function latest(rev, metadata) { + var toVisit = metadata.rev_tree.slice(); + var node; + while ((node = toVisit.pop())) { + var pos = node.pos; + var tree = node.ids; + var id = tree[0]; + var opts = tree[1]; + var branches = tree[2]; + var isLeaf = branches.length === 0; - idb = e.target.result; + var history = node.history ? node.history.slice() : []; + history.push({id: id, pos: pos, opts: opts}); - idb.onversionchange = function () { - idb.close(); - cachedDBs.delete(dbName); - }; + if (isLeaf) { + for (var i = 0, len = history.length; i < len; i++) { + var historyNode = history[i]; + var historyRev = historyNode.pos + '-' + historyNode.id; - idb.onabort = function (e) { - guardedConsole('error', 'Database has a global failure', e.target.error); - idb.close(); - cachedDBs.delete(dbName); - }; + if (historyRev === rev) { + // return the rev of this leaf + return pos + '-' + id; + } + } + } - // Do a few setup operations (in parallel as much as possible): - // 1. Fetch meta doc - // 2. Check blob support - // 3. Calculate docCount - // 4. Generate an instanceId if necessary - // 5. Store docCount and instanceId on meta doc + for (var j = 0, l = branches.length; j < l; j++) { + toVisit.push({pos: pos + 1, ids: branches[j], history: history}); + } + } - var txn = idb.transaction([ - META_STORE, - DETECT_BLOB_SUPPORT_STORE, - DOC_STORE - ], 'readwrite'); + /* istanbul ignore next */ + throw new Error('Unable to resolve latest revision for id ' + metadata.id + ', rev ' + rev); +} - var storedMetaDoc = false; - var metaDoc; - var docCount; - var blobSupport; - var instanceId; +inherits__WEBPACK_IMPORTED_MODULE_3___default()(Changes$1, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); - function completeSetup() { - if (typeof blobSupport === 'undefined' || !storedMetaDoc) { - return; +function tryCatchInChangeListener(self, change, pending, lastSeq) { + // isolate try/catches to avoid V8 deoptimizations + try { + self.emit('change', change, pending, lastSeq); + } catch (e) { + guardedConsole('error', 'Error in .on("change", function):', e); + } +} + +function Changes$1(db, opts, callback) { + events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this); + var self = this; + this.db = db; + opts = opts ? clone(opts) : {}; + var complete = opts.complete = once(function (err, resp) { + if (err) { + if (listenerCount(self, 'error') > 0) { + self.emit('error', err); } - api._meta = { - name: dbName, - instanceId: instanceId, - blobSupport: blobSupport - }; + } else { + self.emit('complete', resp); + } + self.removeAllListeners(); + db.removeListener('destroyed', onDestroy); + }); + if (callback) { + self.on('complete', function (resp) { + callback(null, resp); + }); + self.on('error', callback); + } + function onDestroy() { + self.cancel(); + } + db.once('destroyed', onDestroy); - cachedDBs.set(dbName, { - idb: idb, - global: api._meta - }); - callback(null, api); + opts.onChange = function (change, pending, lastSeq) { + /* istanbul ignore if */ + if (self.isCancelled) { + return; } + tryCatchInChangeListener(self, change, pending, lastSeq); + }; - function storeMetaDocIfReady() { - if (typeof docCount === 'undefined' || typeof metaDoc === 'undefined') { - return; - } - var instanceKey = dbName + '_id'; - if (instanceKey in metaDoc) { - instanceId = metaDoc[instanceKey]; + var promise = new Promise(function (fulfill, reject) { + opts.complete = function (err, res) { + if (err) { + reject(err); } else { - metaDoc[instanceKey] = instanceId = uuid(); + fulfill(res); } - metaDoc.docCount = docCount; - txn.objectStore(META_STORE).put(metaDoc); - } - - // - // fetch or generate the instanceId - // - txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) { - metaDoc = e.target.result || { id: META_STORE }; - storeMetaDocIfReady(); }; + }); + self.once('cancel', function () { + db.removeListener('destroyed', onDestroy); + opts.complete(null, {status: 'cancelled'}); + }); + this.then = promise.then.bind(promise); + this['catch'] = promise['catch'].bind(promise); + this.then(function (result) { + complete(null, result); + }, complete); - // - // countDocs - // - countDocs(txn, function (count) { - docCount = count; - storeMetaDocIfReady(); - }); - // - // check blob support - // - if (!blobSupportPromise) { - // make sure blob support is only checked once - blobSupportPromise = checkBlobSupport(txn); - } - blobSupportPromise.then(function (val) { - blobSupport = val; - completeSetup(); + if (!db.taskqueue.isReady) { + db.taskqueue.addTask(function (failed) { + if (failed) { + opts.complete(failed); + } else if (self.isCancelled) { + self.emit('cancel'); + } else { + self.validateChanges(opts); + } }); - - // only when the metadata put transaction has completed, - // consider the setup done - txn.oncomplete = function () { - storedMetaDoc = true; - completeSetup(); - }; - txn.onabort = idbError(callback); + } else { + self.validateChanges(opts); + } +} +Changes$1.prototype.cancel = function () { + this.isCancelled = true; + if (this.db.taskqueue.isReady) { + this.emit('cancel'); + } +}; +function processChange(doc, metadata, opts) { + var changeList = [{rev: doc._rev}]; + if (opts.style === 'all_docs') { + changeList = collectLeaves(metadata.rev_tree) + .map(function (x) { return {rev: x.rev}; }); + } + var change = { + id: metadata.id, + changes: changeList, + doc: doc }; - req.onerror = function () { - var msg = 'Failed to open indexedDB, are you in private browsing mode?'; - guardedConsole('error', msg); - callback(createError(IDB_ERROR, msg)); - }; + if (isDeleted(metadata, doc._rev)) { + change.deleted = true; + } + if (opts.conflicts) { + change.doc._conflicts = collectConflicts(metadata); + if (!change.doc._conflicts.length) { + delete change.doc._conflicts; + } + } + return change; } -IdbPouch.valid = function () { - // Following #7085 buggy idb versions (typically Safari < 10.1) are - // considered valid. +Changes$1.prototype.validateChanges = function (opts) { + var callback = opts.complete; + var self = this; - // On Firefox SecurityError is thrown while referencing indexedDB if cookies - // are not allowed. `typeof indexedDB` also triggers the error. - try { - // some outdated implementations of IDB that appear on Samsung - // and HTC Android devices <4.4 are missing IDBKeyRange - return typeof indexedDB !== 'undefined' && typeof IDBKeyRange !== 'undefined'; - } catch (e) { - return false; + /* istanbul ignore else */ + if (PouchDB._changesFilterPlugin) { + PouchDB._changesFilterPlugin.validate(opts, function (err) { + if (err) { + return callback(err); + } + self.doChanges(opts); + }); + } else { + self.doChanges(opts); } }; -function IDBPouch (PouchDB) { - PouchDB.adapter('idb', IdbPouch, true); -} - -// dead simple promise pool, inspired by https://github.com/timdp/es6-promise-pool -// but much smaller in code size. limits the number of concurrent promises that are executed +Changes$1.prototype.doChanges = function (opts) { + var self = this; + var callback = opts.complete; + opts = clone(opts); + if ('live' in opts && !('continuous' in opts)) { + opts.continuous = opts.live; + } + opts.processChange = processChange; -function pool(promiseFactories, limit) { - return new Promise(function (resolve, reject) { - var running = 0; - var current = 0; - var done = 0; - var len = promiseFactories.length; - var err; + if (opts.since === 'latest') { + opts.since = 'now'; + } + if (!opts.since) { + opts.since = 0; + } + if (opts.since === 'now') { + this.db.info().then(function (info) { + /* istanbul ignore if */ + if (self.isCancelled) { + callback(null, {status: 'cancelled'}); + return; + } + opts.since = info.update_seq; + self.doChanges(opts); + }, callback); + return; + } - function runNext() { - running++; - promiseFactories[current++]().then(onSuccess, onError); + /* istanbul ignore else */ + if (PouchDB._changesFilterPlugin) { + PouchDB._changesFilterPlugin.normalize(opts); + if (PouchDB._changesFilterPlugin.shouldFilter(this, opts)) { + return PouchDB._changesFilterPlugin.filter(this, opts); } - - function doNext() { - if (++done === len) { - /* istanbul ignore if */ - if (err) { - reject(err); - } else { - resolve(); - } - } else { - runNextBatch(); + } else { + ['doc_ids', 'filter', 'selector', 'view'].forEach(function (key) { + if (key in opts) { + guardedConsole('warn', + 'The "' + key + '" option was passed in to changes/replicate, ' + + 'but pouchdb-changes-filter plugin is not installed, so it ' + + 'was ignored. Please install the plugin to enable filtering.' + ); } - } + }); + } - function onSuccess() { - running--; - doNext(); - } + if (!('descending' in opts)) { + opts.descending = false; + } - /* istanbul ignore next */ - function onError(thisErr) { - running--; - err = err || thisErr; - doNext(); + // 0 and 1 should return 1 document + opts.limit = opts.limit === 0 ? 1 : opts.limit; + opts.complete = callback; + var newPromise = this.db._changes(opts); + /* istanbul ignore else */ + if (newPromise && typeof newPromise.cancel === 'function') { + var cancel = self.cancel; + self.cancel = argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { + newPromise.cancel(); + cancel.apply(this, args); + }); + } +}; + +/* + * A generic pouch adapter + */ + +function compare(left, right) { + return left < right ? -1 : left > right ? 1 : 0; +} + +// Wrapper for functions that call the bulkdocs api with a single doc, +// if the first result is an error, return an error +function yankError(callback, docId) { + return function (err, results) { + if (err || (results[0] && results[0].error)) { + err = err || results[0]; + err.docId = docId; + callback(err); + } else { + callback(null, results.length ? results[0] : results); } + }; +} - function runNextBatch() { - while (running < limit && current < len) { - runNext(); +// clean docs given to us by the user +function cleanDocs(docs) { + for (var i = 0; i < docs.length; i++) { + var doc = docs[i]; + if (doc._deleted) { + delete doc._attachments; // ignore atts for deleted docs + } else if (doc._attachments) { + // filter out extraneous keys from _attachments + var atts = Object.keys(doc._attachments); + for (var j = 0; j < atts.length; j++) { + var att = atts[j]; + doc._attachments[att] = pick(doc._attachments[att], + ['data', 'digest', 'content_type', 'length', 'revpos', 'stub']); } } + } +} - runNextBatch(); - }); +// compare two docs, first by _id then by _rev +function compareByIdThenRev(a, b) { + var idCompare = compare(a._id, b._id); + if (idCompare !== 0) { + return idCompare; + } + var aStart = a._revisions ? a._revisions.start : 0; + var bStart = b._revisions ? b._revisions.start : 0; + return compare(aStart, bStart); } -var CHANGES_BATCH_SIZE = 25; -var MAX_SIMULTANEOUS_REVS = 50; -var CHANGES_TIMEOUT_BUFFER = 5000; -var DEFAULT_HEARTBEAT = 10000; +// for every node in a revision tree computes its distance from the closest +// leaf +function computeHeight(revs) { + var height = {}; + var edges = []; + traverseRevTree(revs, function (isLeaf, pos, id, prnt) { + var rev = pos + "-" + id; + if (isLeaf) { + height[rev] = 0; + } + if (prnt !== undefined) { + edges.push({from: prnt, to: rev}); + } + return rev; + }); -var supportsBulkGetMap = {}; + edges.reverse(); + edges.forEach(function (edge) { + if (height[edge.from] === undefined) { + height[edge.from] = 1 + height[edge.to]; + } else { + height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]); + } + }); + return height; +} -function readAttachmentsAsBlobOrBuffer(row) { - var doc = row.doc || row.ok; - var atts = doc._attachments; - if (!atts) { - return; +function allDocsKeysParse(opts) { + var keys = ('limit' in opts) ? + opts.keys.slice(opts.skip, opts.limit + opts.skip) : + (opts.skip > 0) ? opts.keys.slice(opts.skip) : opts.keys; + opts.keys = keys; + opts.skip = 0; + delete opts.limit; + if (opts.descending) { + keys.reverse(); + opts.descending = false; } - Object.keys(atts).forEach(function (filename) { - var att = atts[filename]; - att.data = b64ToBluffer(att.data, att.content_type); +} + +// all compaction is done in a queue, to avoid attaching +// too many listeners at once +function doNextCompaction(self) { + var task = self._compactionQueue[0]; + var opts = task.opts; + var callback = task.callback; + self.get('_local/compaction').catch(function () { + return false; + }).then(function (doc) { + if (doc && doc.last_seq) { + opts.last_seq = doc.last_seq; + } + self._compact(opts, function (err, res) { + /* istanbul ignore if */ + if (err) { + callback(err); + } else { + callback(null, res); + } + immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { + self._compactionQueue.shift(); + if (self._compactionQueue.length) { + doNextCompaction(self); + } + }); + }); }); } -function encodeDocId(id) { - if (/^_design/.test(id)) { - return '_design/' + encodeURIComponent(id.slice(8)); - } - if (/^_local/.test(id)) { - return '_local/' + encodeURIComponent(id.slice(7)); +function attachmentNameError(name) { + if (name.charAt(0) === '_') { + return name + ' is not a valid attachment name, attachment ' + + 'names cannot start with \'_\''; } - return encodeURIComponent(id); + return false; } -function preprocessAttachments$1(doc) { - if (!doc._attachments || !Object.keys(doc._attachments)) { - return Promise.resolve(); - } +inherits__WEBPACK_IMPORTED_MODULE_3___default()(AbstractPouchDB, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); - return Promise.all(Object.keys(doc._attachments).map(function (key) { - var attachment = doc._attachments[key]; - if (attachment.data && typeof attachment.data !== 'string') { - return new Promise(function (resolve) { - blobToBase64(attachment.data, resolve); - }).then(function (b64) { - attachment.data = b64; - }); - } - })); -} +function AbstractPouchDB() { + events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this); -function hasUrlPrefix(opts) { - if (!opts.prefix) { - return false; + // re-bind prototyped methods + for (var p in AbstractPouchDB.prototype) { + if (typeof this[p] === 'function') { + this[p] = this[p].bind(this); + } } - var protocol = parseUri(opts.prefix).protocol; - return protocol === 'http' || protocol === 'https'; } -// Get all the information you possibly can about the URI given by name and -// return it as a suitable object. -function getHost(name, opts) { - // encode db name if opts.prefix is a url (#5574) - if (hasUrlPrefix(opts)) { - var dbName = opts.name.substr(opts.prefix.length); - // Ensure prefix has a trailing slash - var prefix = opts.prefix.replace(/\/?$/, '/'); - name = prefix + encodeURIComponent(dbName); +AbstractPouchDB.prototype.post = + adapterFun('post', function (doc, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + if (typeof doc !== 'object' || Array.isArray(doc)) { + return callback(createError(NOT_AN_OBJECT)); } + this.bulkDocs({docs: [doc]}, opts, yankError(callback, doc._id)); +}); - var uri = parseUri(name); - if (uri.user || uri.password) { - uri.auth = {username: uri.user, password: uri.password}; +AbstractPouchDB.prototype.put = adapterFun('put', function (doc, opts, cb) { + if (typeof opts === 'function') { + cb = opts; + opts = {}; + } + if (typeof doc !== 'object' || Array.isArray(doc)) { + return cb(createError(NOT_AN_OBJECT)); + } + invalidIdError(doc._id); + if (isLocalId(doc._id) && typeof this._putLocal === 'function') { + if (doc._deleted) { + return this._removeLocal(doc, cb); + } else { + return this._putLocal(doc, cb); + } + } + var self = this; + if (opts.force && doc._rev) { + transformForceOptionToNewEditsOption(); + putDoc(function (err) { + var result = err ? null : {ok: true, id: doc._id, rev: doc._rev}; + cb(err, result); + }); + } else { + putDoc(cb); } - // Split the path part of the URI into parts using '/' as the delimiter - // after removing any leading '/' and any trailing '/' - var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/'); + function transformForceOptionToNewEditsOption() { + var parts = doc._rev.split('-'); + var oldRevId = parts[1]; + var oldRevNum = parseInt(parts[0], 10); - uri.db = parts.pop(); - // Prevent double encoding of URI component - if (uri.db.indexOf('%') === -1) { - uri.db = encodeURIComponent(uri.db); + var newRevNum = oldRevNum + 1; + var newRevId = rev$$1(); + + doc._revisions = { + start: newRevNum, + ids: [newRevId, oldRevId] + }; + doc._rev = newRevNum + '-' + newRevId; + opts.new_edits = false; } + function putDoc(next) { + if (typeof self._put === 'function' && opts.new_edits !== false) { + self._put(doc, opts, next); + } else { + self.bulkDocs({docs: [doc]}, opts, yankError(next, doc._id)); + } + } +}); - uri.path = parts.join('/'); +AbstractPouchDB.prototype.putAttachment = + adapterFun('putAttachment', function (docId, attachmentId, rev, + blob, type) { + var api = this; + if (typeof type === 'function') { + type = blob; + blob = rev; + rev = null; + } + // Lets fix in https://github.com/pouchdb/pouchdb/issues/3267 + /* istanbul ignore if */ + if (typeof type === 'undefined') { + type = blob; + blob = rev; + rev = null; + } + if (!type) { + guardedConsole('warn', 'Attachment', attachmentId, 'on document', docId, 'is missing content_type'); + } - return uri; -} + function createAttachment(doc) { + var prevrevpos = '_rev' in doc ? parseInt(doc._rev, 10) : 0; + doc._attachments = doc._attachments || {}; + doc._attachments[attachmentId] = { + content_type: type, + data: blob, + revpos: ++prevrevpos + }; + return api.put(doc); + } -// Generate a URL with the host data given by opts and the given path -function genDBUrl(opts, path) { - return genUrl(opts, opts.db + '/' + path); -} + return api.get(docId).then(function (doc) { + if (doc._rev !== rev) { + throw createError(REV_CONFLICT); + } -// Generate a URL with the host data given by opts and the given path -function genUrl(opts, path) { - // If the host already has a path, then we need to have a path delimiter - // Otherwise, the path delimiter is the empty string - var pathDel = !opts.path ? '' : '/'; + return createAttachment(doc); + }, function (err) { + // create new doc + /* istanbul ignore else */ + if (err.reason === MISSING_DOC.message) { + return createAttachment({_id: docId}); + } else { + throw err; + } + }); +}); - // If the host already has a path, then we need to have a path delimiter - // Otherwise, the path delimiter is the empty string - return opts.protocol + '://' + opts.host + - (opts.port ? (':' + opts.port) : '') + - '/' + opts.path + pathDel + path; -} +AbstractPouchDB.prototype.removeAttachment = + adapterFun('removeAttachment', function (docId, attachmentId, rev, + callback) { + var self = this; + self.get(docId, function (err, obj) { + /* istanbul ignore if */ + if (err) { + callback(err); + return; + } + if (obj._rev !== rev) { + callback(createError(REV_CONFLICT)); + return; + } + /* istanbul ignore if */ + if (!obj._attachments) { + return callback(); + } + delete obj._attachments[attachmentId]; + if (Object.keys(obj._attachments).length === 0) { + delete obj._attachments; + } + self.put(obj, callback); + }); +}); -function paramsToStr(params) { - return '?' + Object.keys(params).map(function (k) { - return k + '=' + encodeURIComponent(params[k]); - }).join('&'); -} +AbstractPouchDB.prototype.remove = + adapterFun('remove', function (docOrId, optsOrRev, opts, callback) { + var doc; + if (typeof optsOrRev === 'string') { + // id, rev, opts, callback style + doc = { + _id: docOrId, + _rev: optsOrRev + }; + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + } else { + // doc, opts, callback style + doc = docOrId; + if (typeof optsOrRev === 'function') { + callback = optsOrRev; + opts = {}; + } else { + callback = opts; + opts = optsOrRev; + } + } + opts = opts || {}; + opts.was_delete = true; + var newDoc = {_id: doc._id, _rev: (doc._rev || opts.rev)}; + newDoc._deleted = true; + if (isLocalId(newDoc._id) && typeof this._removeLocal === 'function') { + return this._removeLocal(doc, callback); + } + this.bulkDocs({docs: [newDoc]}, opts, yankError(callback, newDoc._id)); +}); -function shouldCacheBust(opts) { - var ua = (typeof navigator !== 'undefined' && navigator.userAgent) ? - navigator.userAgent.toLowerCase() : ''; - var isIE = ua.indexOf('msie') !== -1; - var isTrident = ua.indexOf('trident') !== -1; - var isEdge = ua.indexOf('edge') !== -1; - var isGET = !('method' in opts) || opts.method === 'GET'; - return (isIE || isTrident || isEdge) && isGET; -} +AbstractPouchDB.prototype.revsDiff = + adapterFun('revsDiff', function (req, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + var ids = Object.keys(req); -// Implements the PouchDB API for dealing with CouchDB instances over HTTP -function HttpPouch(opts, callback) { + if (!ids.length) { + return callback(null, {}); + } - // The functions that will be publicly available for HttpPouch - var api = this; + var count = 0; + var missing = new ExportedMap(); - var host = getHost(opts.name, opts); - var dbUrl = genDBUrl(host, ''); + function addToMissing(id, revId) { + if (!missing.has(id)) { + missing.set(id, {missing: []}); + } + missing.get(id).missing.push(revId); + } - opts = clone(opts); + function processDoc(id, rev_tree) { + // Is this fast enough? Maybe we should switch to a set simulated by a map + var missingForId = req[id].slice(0); + traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx, + opts) { + var rev = pos + '-' + revHash; + var idx = missingForId.indexOf(rev); + if (idx === -1) { + return; + } - var ourFetch = function (url, options) { + missingForId.splice(idx, 1); + /* istanbul ignore if */ + if (opts.status !== 'available') { + addToMissing(id, rev); + } + }); - options = options || {}; - options.headers = options.headers || new h(); + // Traversing the tree is synchronous, so now `missingForId` contains + // revisions that were not found in the tree + missingForId.forEach(function (rev) { + addToMissing(id, rev); + }); + } - if (opts.auth || host.auth) { - var nAuth = opts.auth || host.auth; - var str = nAuth.username + ':' + nAuth.password; - var token = thisBtoa(unescape(encodeURIComponent(str))); - options.headers.set('Authorization', 'Basic ' + token); - } + ids.map(function (id) { + this._getRevisionTree(id, function (err, rev_tree) { + if (err && err.status === 404 && err.message === 'missing') { + missing.set(id, {missing: req[id]}); + } else if (err) { + /* istanbul ignore next */ + return callback(err); + } else { + processDoc(id, rev_tree); + } - var headers = opts.headers || {}; - Object.keys(headers).forEach(function (key) { - options.headers.append(key, headers[key]); + if (++count === ids.length) { + // convert LazyMap to object + var missingObj = {}; + missing.forEach(function (value, key) { + missingObj[key] = value; + }); + return callback(null, missingObj); + } }); + }, this); +}); + +// _bulk_get API for faster replication, as described in +// https://github.com/apache/couchdb-chttpd/pull/33 +// At the "abstract" level, it will just run multiple get()s in +// parallel, because this isn't much of a performance cost +// for local databases (except the cost of multiple transactions, which is +// small). The http adapter overrides this in order +// to do a more efficient single HTTP request. +AbstractPouchDB.prototype.bulkGet = + adapterFun('bulkGet', function (opts, callback) { + bulkGet(this, opts, callback); +}); +// compact one document and fire callback +// by compacting we mean removing all revisions which +// are further from the leaf in revision tree than max_height +AbstractPouchDB.prototype.compactDocument = + adapterFun('compactDocument', function (docId, maxHeight, callback) { + var self = this; + this._getRevisionTree(docId, function (err, revTree) { /* istanbul ignore if */ - if (shouldCacheBust(options)) { - url += (url.indexOf('?') === -1 ? '?' : '&') + '_nonce=' + Date.now(); + if (err) { + return callback(err); } + var height = computeHeight(revTree); + var candidates = []; + var revs = []; + Object.keys(height).forEach(function (rev) { + if (height[rev] > maxHeight) { + candidates.push(rev); + } + }); - var fetchFun = opts.fetch || f$1; - return fetchFun(url, options); - }; + traverseRevTree(revTree, function (isLeaf, pos, revHash, ctx, opts) { + var rev = pos + '-' + revHash; + if (opts.status === 'available' && candidates.indexOf(rev) !== -1) { + revs.push(rev); + } + }); + self._doCompaction(docId, revs, callback); + }); +}); - function adapterFun$$1(name, fun) { - return adapterFun(name, argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { - setup().then(function () { - return fun.apply(this, args); - }).catch(function (e) { - var callback = args.pop(); - callback(e); - }); - })).bind(api); +// compact the whole database using single document +// compaction +AbstractPouchDB.prototype.compact = + adapterFun('compact', function (opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; } - function fetchJSON(url, options, callback) { + var self = this; + opts = opts || {}; - var result = {}; + self._compactionQueue = self._compactionQueue || []; + self._compactionQueue.push({opts: opts, callback: callback}); + if (self._compactionQueue.length === 1) { + doNextCompaction(self); + } +}); +AbstractPouchDB.prototype._compact = function (opts, callback) { + var self = this; + var changesOpts = { + return_docs: false, + last_seq: opts.last_seq || 0 + }; + var promises = []; - options = options || {}; - options.headers = options.headers || new h(); + function onChange(row) { + promises.push(self.compactDocument(row.id, 0)); + } + function onComplete(resp) { + var lastSeq = resp.last_seq; + Promise.all(promises).then(function () { + return upsert(self, '_local/compaction', function deltaFunc(doc) { + if (!doc.last_seq || doc.last_seq < lastSeq) { + doc.last_seq = lastSeq; + return doc; + } + return false; // somebody else got here first, don't update + }); + }).then(function () { + callback(null, {ok: true}); + }).catch(callback); + } + self.changes(changesOpts) + .on('change', onChange) + .on('complete', onComplete) + .on('error', callback); +}; - if (!options.headers.get('Content-Type')) { - options.headers.set('Content-Type', 'application/json'); - } - if (!options.headers.get('Accept')) { - options.headers.set('Accept', 'application/json'); +/* Begin api wrappers. Specific functionality to storage belongs in the + _[method] */ +AbstractPouchDB.prototype.get = adapterFun('get', function (id, opts, cb) { + if (typeof opts === 'function') { + cb = opts; + opts = {}; + } + if (typeof id !== 'string') { + return cb(createError(INVALID_ID)); + } + if (isLocalId(id) && typeof this._getLocal === 'function') { + return this._getLocal(id, cb); + } + var leaves = [], self = this; + + function finishOpenRevs() { + var result = []; + var count = leaves.length; + /* istanbul ignore if */ + if (!count) { + return cb(null, result); } - return ourFetch(url, options).then(function (response) { - result.ok = response.ok; - result.status = response.status; - return response.json(); - }).then(function (json) { - result.data = json; - if (!result.ok) { - result.data.status = result.status; - var err = generateErrorFromResponse(result.data); - if (callback) { - return callback(err); + // order with open_revs is unspecified + leaves.forEach(function (leaf) { + self.get(id, { + rev: leaf, + revs: opts.revs, + latest: opts.latest, + attachments: opts.attachments, + binary: opts.binary + }, function (err, doc) { + if (!err) { + // using latest=true can produce duplicates + var existing; + for (var i = 0, l = result.length; i < l; i++) { + if (result[i].ok && result[i].ok._rev === doc._rev) { + existing = true; + break; + } + } + if (!existing) { + result.push({ok: doc}); + } } else { - throw err; + result.push({missing: leaf}); } - } + count--; + if (!count) { + cb(null, result); + } + }); + }); + } - if (Array.isArray(result.data)) { - result.data = result.data.map(function (v) { - if (v.error || v.missing) { - return generateErrorFromResponse(v); - } else { - return v; - } + if (opts.open_revs) { + if (opts.open_revs === "all") { + this._getRevisionTree(id, function (err, rev_tree) { + /* istanbul ignore if */ + if (err) { + return cb(err); + } + leaves = collectLeaves(rev_tree).map(function (leaf) { + return leaf.rev; }); - } - - if (callback) { - callback(null, result.data); + finishOpenRevs(); + }); + } else { + if (Array.isArray(opts.open_revs)) { + leaves = opts.open_revs; + for (var i = 0; i < leaves.length; i++) { + var l = leaves[i]; + // looks like it's the only thing couchdb checks + if (!(typeof (l) === "string" && /^\d+-/.test(l))) { + return cb(createError(INVALID_REV)); + } + } + finishOpenRevs(); } else { - return result; + return cb(createError(UNKNOWN_ERROR, 'function_clause')); } - }); + } + return; // open_revs does not like other options } - var setupPromise; - - function setup() { - if (opts.skip_setup) { - return Promise.resolve(); + return this._get(id, opts, function (err, result) { + if (err) { + err.docId = id; + return cb(err); } - // If there is a setup in process or previous successful setup - // done then we will use that - // If previous setups have been rejected we will try again - if (setupPromise) { - return setupPromise; - } + var doc = result.doc; + var metadata = result.metadata; + var ctx = result.ctx; - setupPromise = fetchJSON(dbUrl).catch(function (err) { - if (err && err.status && err.status === 404) { - // Doesnt exist, create it - explainError(404, 'PouchDB is just detecting if the remote exists.'); - return fetchJSON(dbUrl, {method: 'PUT'}); - } else { - return Promise.reject(err); - } - }).catch(function (err) { - // If we try to create a database that already exists, skipped in - // istanbul since its catching a race condition. - /* istanbul ignore if */ - if (err && err.status && err.status === 412) { - return true; + if (opts.conflicts) { + var conflicts = collectConflicts(metadata); + if (conflicts.length) { + doc._conflicts = conflicts; } - return Promise.reject(err); - }); + } - setupPromise.catch(function () { - setupPromise = null; - }); + if (isDeleted(metadata, doc._rev)) { + doc._deleted = true; + } - return setupPromise; - } + if (opts.revs || opts.revs_info) { + var splittedRev = doc._rev.split('-'); + var revNo = parseInt(splittedRev[0], 10); + var revHash = splittedRev[1]; - immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { - callback(null, api); - }); + var paths = rootToLeaf(metadata.rev_tree); + var path = null; - api._remote = true; + for (var i = 0; i < paths.length; i++) { + var currentPath = paths[i]; + var hashIndex = currentPath.ids.map(function (x) { return x.id; }) + .indexOf(revHash); + var hashFoundAtRevPos = hashIndex === (revNo - 1); - /* istanbul ignore next */ - api.type = function () { - return 'http'; - }; + if (hashFoundAtRevPos || (!path && hashIndex !== -1)) { + path = currentPath; + } + } - api.id = adapterFun$$1('id', function (callback) { - ourFetch(genUrl(host, '')).then(function (response) { - return response.json(); - }).then(function (result) { - var uuid$$1 = (result && result.uuid) ? - (result.uuid + host.db) : genDBUrl(host, ''); - callback(null, uuid$$1); - }).catch(function (err) { - callback(err); - }); - }); + var indexOfRev = path.ids.map(function (x) { return x.id; }) + .indexOf(doc._rev.split('-')[1]) + 1; + var howMany = path.ids.length - indexOfRev; + path.ids.splice(indexOfRev, howMany); + path.ids.reverse(); - // Sends a POST request to the host calling the couchdb _compact function - // version: The version of CouchDB it is running - api.compact = adapterFun$$1('compact', function (opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; + if (opts.revs) { + doc._revisions = { + start: (path.pos + path.ids.length) - 1, + ids: path.ids.map(function (rev) { + return rev.id; + }) + }; + } + if (opts.revs_info) { + var pos = path.pos + path.ids.length; + doc._revs_info = path.ids.map(function (rev) { + pos--; + return { + rev: pos + '-' + rev.id, + status: rev.opts.status + }; + }); + } } - opts = clone(opts); - fetchJSON(genDBUrl(host, '_compact'), {method: 'POST'}).then(function () { - function ping() { - api.info(function (err, res) { - // CouchDB may send a "compact_running:true" if it's - // already compacting. PouchDB Server doesn't. - /* istanbul ignore else */ - if (res && !res.compact_running) { - callback(null, {ok: true}); - } else { - setTimeout(ping, opts.interval || 200); + if (opts.attachments && doc._attachments) { + var attachments = doc._attachments; + var count = Object.keys(attachments).length; + if (count === 0) { + return cb(null, doc); + } + Object.keys(attachments).forEach(function (key) { + this._getAttachment(doc._id, key, attachments[key], { + // Previously the revision handling was done in adapter.js + // getAttachment, however since idb-next doesnt we need to + // pass the rev through + rev: doc._rev, + binary: opts.binary, + ctx: ctx + }, function (err, data) { + var att = doc._attachments[key]; + att.data = data; + delete att.stub; + delete att.length; + if (!--count) { + cb(null, doc); } }); + }, self); + } else { + if (doc._attachments) { + for (var key in doc._attachments) { + /* istanbul ignore else */ + if (doc._attachments.hasOwnProperty(key)) { + doc._attachments[key].stub = true; + } + } } - // Ping the http if it's finished compaction - ping(); - }); + cb(null, doc); + } }); +}); - api.bulkGet = adapterFun('bulkGet', function (opts, callback) { - var self = this; +// TODO: I dont like this, it forces an extra read for every +// attachment read and enforces a confusing api between +// adapter.js and the adapter implementation +AbstractPouchDB.prototype.getAttachment = + adapterFun('getAttachment', function (docId, attachmentId, opts, callback) { + var self = this; + if (opts instanceof Function) { + callback = opts; + opts = {}; + } + this._get(docId, opts, function (err, res) { + if (err) { + return callback(err); + } + if (res.doc._attachments && res.doc._attachments[attachmentId]) { + opts.ctx = res.ctx; + opts.binary = true; + self._getAttachment(docId, attachmentId, + res.doc._attachments[attachmentId], opts, callback); + } else { + return callback(createError(MISSING_DOC)); + } + }); +}); - function doBulkGet(cb) { - var params = {}; - if (opts.revs) { - params.revs = true; - } - if (opts.attachments) { - /* istanbul ignore next */ - params.attachments = true; - } - if (opts.latest) { - params.latest = true; +AbstractPouchDB.prototype.allDocs = + adapterFun('allDocs', function (opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + opts.skip = typeof opts.skip !== 'undefined' ? opts.skip : 0; + if (opts.start_key) { + opts.startkey = opts.start_key; + } + if (opts.end_key) { + opts.endkey = opts.end_key; + } + if ('keys' in opts) { + if (!Array.isArray(opts.keys)) { + return callback(new TypeError('options.keys must be an array')); + } + var incompatibleOpt = + ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) { + return incompatibleOpt in opts; + })[0]; + if (incompatibleOpt) { + callback(createError(QUERY_PARSE_ERROR, + 'Query parameter `' + incompatibleOpt + + '` is not compatible with multi-get' + )); + return; + } + if (!isRemote(this)) { + allDocsKeysParse(opts); + if (opts.keys.length === 0) { + return this._allDocs({limit: 0}, callback); } - fetchJSON(genDBUrl(host, '_bulk_get' + paramsToStr(params)), { - method: 'POST', - body: JSON.stringify({ docs: opts.docs}) - }).then(function (result) { - if (opts.attachments && opts.binary) { - result.data.results.forEach(function (res) { - res.docs.forEach(readAttachmentsAsBlobOrBuffer); - }); - } - cb(null, result.data); - }).catch(cb); } + } - /* istanbul ignore next */ - function doBulkGetShim() { - // avoid "url too long error" by splitting up into multiple requests - var batchSize = MAX_SIMULTANEOUS_REVS; - var numBatches = Math.ceil(opts.docs.length / batchSize); - var numDone = 0; - var results = new Array(numBatches); + return this._allDocs(opts, callback); +}); - function onResult(batchNum) { - return function (err, res) { - // err is impossible because shim returns a list of errs in that case - results[batchNum] = res.results; - if (++numDone === numBatches) { - callback(null, {results: flatten(results)}); - } - }; - } +AbstractPouchDB.prototype.changes = function (opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } - for (var i = 0; i < numBatches; i++) { - var subOpts = pick(opts, ['revs', 'attachments', 'binary', 'latest']); - subOpts.docs = opts.docs.slice(i * batchSize, - Math.min(opts.docs.length, (i + 1) * batchSize)); - bulkGet(self, subOpts, onResult(i)); - } - } + opts = opts || {}; - // mark the whole database as either supporting or not supporting _bulk_get - var dbUrl = genUrl(host, ''); - var supportsBulkGet = supportsBulkGetMap[dbUrl]; + // By default set return_docs to false if the caller has opts.live = true, + // this will prevent us from collecting the set of changes indefinitely + // resulting in growing memory + opts.return_docs = ('return_docs' in opts) ? opts.return_docs : !opts.live; - /* istanbul ignore next */ - if (typeof supportsBulkGet !== 'boolean') { - // check if this database supports _bulk_get - doBulkGet(function (err, res) { - if (err) { - supportsBulkGetMap[dbUrl] = false; - explainError( - err.status, - 'PouchDB is just detecting if the remote ' + - 'supports the _bulk_get API.' - ); - doBulkGetShim(); - } else { - supportsBulkGetMap[dbUrl] = true; - callback(null, res); - } - }); - } else if (supportsBulkGet) { - doBulkGet(callback); - } else { - doBulkGetShim(); + return new Changes$1(this, opts, callback); +}; + +AbstractPouchDB.prototype.close = adapterFun('close', function (callback) { + this._closed = true; + this.emit('closed'); + return this._close(callback); +}); + +AbstractPouchDB.prototype.info = adapterFun('info', function (callback) { + var self = this; + this._info(function (err, info) { + if (err) { + return callback(err); } + // assume we know better than the adapter, unless it informs us + info.db_name = info.db_name || self.name; + info.auto_compaction = !!(self.auto_compaction && !isRemote(self)); + info.adapter = self.adapter; + callback(null, info); }); +}); - // Calls GET on the host, which gets back a JSON string containing - // couchdb: A welcome string - // version: The version of CouchDB it is running - api._info = function (callback) { - setup().then(function () { - return ourFetch(genDBUrl(host, '')); - }).then(function (response) { - return response.json(); - }).then(function (info) { - info.host = genDBUrl(host, ''); - callback(null, info); - }).catch(callback); - }; +AbstractPouchDB.prototype.id = adapterFun('id', function (callback) { + return this._id(callback); +}); - api.fetch = function (path, options) { - return setup().then(function () { - return ourFetch(genDBUrl(host, path), options); - }); - }; +/* istanbul ignore next */ +AbstractPouchDB.prototype.type = function () { + return (typeof this._type === 'function') ? this._type() : this.adapter; +}; - // Get the document with the given id from the database given by host. - // The id could be solely the _id in the database, or it may be a - // _design/ID or _local/ID path - api.get = adapterFun$$1('get', function (id, opts, callback) { - // If no options were given, set the callback to the second parameter - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - opts = clone(opts); +AbstractPouchDB.prototype.bulkDocs = + adapterFun('bulkDocs', function (req, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } - // List of parameters to add to the GET request - var params = {}; + opts = opts || {}; - if (opts.revs) { - params.revs = true; - } + if (Array.isArray(req)) { + req = { + docs: req + }; + } - if (opts.revs_info) { - params.revs_info = true; - } + if (!req || !req.docs || !Array.isArray(req.docs)) { + return callback(createError(MISSING_BULK_DOCS)); + } - if (opts.latest) { - params.latest = true; + for (var i = 0; i < req.docs.length; ++i) { + if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) { + return callback(createError(NOT_AN_OBJECT)); } + } - if (opts.open_revs) { - if (opts.open_revs !== "all") { - opts.open_revs = JSON.stringify(opts.open_revs); - } - params.open_revs = opts.open_revs; + var attachmentError; + req.docs.forEach(function (doc) { + if (doc._attachments) { + Object.keys(doc._attachments).forEach(function (name) { + attachmentError = attachmentError || attachmentNameError(name); + if (!doc._attachments[name].content_type) { + guardedConsole('warn', 'Attachment', name, 'on document', doc._id, 'is missing content_type'); + } + }); } + }); - if (opts.rev) { - params.rev = opts.rev; - } + if (attachmentError) { + return callback(createError(BAD_REQUEST, attachmentError)); + } - if (opts.conflicts) { - params.conflicts = opts.conflicts; + if (!('new_edits' in opts)) { + if ('new_edits' in req) { + opts.new_edits = req.new_edits; + } else { + opts.new_edits = true; } + } - /* istanbul ignore if */ - if (opts.update_seq) { - params.update_seq = opts.update_seq; - } + var adapter = this; + if (!opts.new_edits && !isRemote(adapter)) { + // ensure revisions of the same doc are sorted, so that + // the local adapter processes them correctly (#2935) + req.docs.sort(compareByIdThenRev); + } - id = encodeDocId(id); + cleanDocs(req.docs); - function fetchAttachments(doc) { - var atts = doc._attachments; - var filenames = atts && Object.keys(atts); - if (!atts || !filenames.length) { - return; - } - // we fetch these manually in separate XHRs, because - // Sync Gateway would normally send it back as multipart/mixed, - // which we cannot parse. Also, this is more efficient than - // receiving attachments as base64-encoded strings. - function fetchData(filename) { - var att = atts[filename]; - var path = encodeDocId(doc._id) + '/' + encodeAttachmentId(filename) + - '?rev=' + doc._rev; - return ourFetch(genDBUrl(host, path)).then(function (response) { - if (typeof process !== 'undefined' && !process.browser) { - return response.buffer(); - } else { - /* istanbul ignore next */ - return response.blob(); - } - }).then(function (blob) { - if (opts.binary) { - // TODO: Can we remove this? - if (typeof process !== 'undefined' && !process.browser) { - blob.type = att.content_type; - } - return blob; - } - return new Promise(function (resolve) { - blobToBase64(blob, resolve); - }); - }).then(function (data) { - delete att.stub; - delete att.length; - att.data = data; - }); - } + // in the case of conflicts, we want to return the _ids to the user + // however, the underlying adapter may destroy the docs array, so + // create a copy here + var ids = req.docs.map(function (doc) { + return doc._id; + }); - var promiseFactories = filenames.map(function (filename) { - return function () { - return fetchData(filename); - }; + return this._bulkDocs(req, opts, function (err, res) { + if (err) { + return callback(err); + } + if (!opts.new_edits) { + // this is what couch does when new_edits is false + res = res.filter(function (x) { + return x.error; }); - - // This limits the number of parallel xhr requests to 5 any time - // to avoid issues with maximum browser request limits - return pool(promiseFactories, 5); } - - function fetchAllAttachments(docOrDocs) { - if (Array.isArray(docOrDocs)) { - return Promise.all(docOrDocs.map(function (doc) { - if (doc.ok) { - return fetchAttachments(doc.ok); - } - })); + // add ids for error/conflict responses (not required for CouchDB) + if (!isRemote(adapter)) { + for (var i = 0, l = res.length; i < l; i++) { + res[i].id = res[i].id || ids[i]; } - return fetchAttachments(docOrDocs); } - var url = genDBUrl(host, id + paramsToStr(params)); - fetchJSON(url).then(function (res) { - return Promise.resolve().then(function () { - if (opts.attachments) { - return fetchAllAttachments(res.data); - } - }).then(function () { - callback(null, res.data); - }); - }).catch(function (e) { - e.docId = id; - callback(e); - }); + callback(null, res); }); +}); +AbstractPouchDB.prototype.registerDependentDatabase = + adapterFun('registerDependentDatabase', function (dependentDb, + callback) { + var depDB = new this.constructor(dependentDb, this.__opts); - // Delete the document given by doc from the database given by host. - api.remove = adapterFun$$1('remove', function (docOrId, optsOrRev, opts, cb) { - var doc; - if (typeof optsOrRev === 'string') { - // id, rev, opts, callback style - doc = { - _id: docOrId, - _rev: optsOrRev - }; - if (typeof opts === 'function') { - cb = opts; - opts = {}; - } - } else { - // doc, opts, callback style - doc = docOrId; - if (typeof optsOrRev === 'function') { - cb = optsOrRev; - opts = {}; - } else { - cb = opts; - opts = optsOrRev; - } + function diffFun(doc) { + doc.dependentDbs = doc.dependentDbs || {}; + if (doc.dependentDbs[dependentDb]) { + return false; // no update required } + doc.dependentDbs[dependentDb] = true; + return doc; + } + upsert(this, '_local/_pouch_dependentDbs', diffFun) + .then(function () { + callback(null, {db: depDB}); + }).catch(callback); +}); - var rev = (doc._rev || opts.rev); - var url = genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev; - - fetchJSON(url, {method: 'DELETE'}, cb).catch(cb); - }); +AbstractPouchDB.prototype.destroy = + adapterFun('destroy', function (opts, callback) { - function encodeAttachmentId(attachmentId) { - return attachmentId.split("/").map(encodeURIComponent).join("/"); + if (typeof opts === 'function') { + callback = opts; + opts = {}; } - // Get the attachment - api.getAttachment = adapterFun$$1('getAttachment', function (docId, attachmentId, - opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - var params = opts.rev ? ('?rev=' + opts.rev) : ''; - var url = genDBUrl(host, encodeDocId(docId)) + '/' + - encodeAttachmentId(attachmentId) + params; - var contentType; - ourFetch(url, {method: 'GET'}).then(function (response) { - contentType = response.headers.get('content-type'); - if (!response.ok) { - throw response; - } else { - if (typeof process !== 'undefined' && !process.browser) { - return response.buffer(); - } else { - /* istanbul ignore next */ - return response.blob(); - } + var self = this; + var usePrefix = 'use_prefix' in self ? self.use_prefix : true; + + function destroyDb() { + // call destroy method of the particular adaptor + self._destroy(opts, function (err, resp) { + if (err) { + return callback(err); } - }).then(function (blob) { - // TODO: also remove - if (typeof process !== 'undefined' && !process.browser) { - blob.type = contentType; + self._destroyed = true; + self.emit('destroyed'); + callback(null, resp || { 'ok': true }); + }); + } + + if (isRemote(self)) { + // no need to check for dependent DBs if it's a remote DB + return destroyDb(); + } + + self.get('_local/_pouch_dependentDbs', function (err, localDoc) { + if (err) { + /* istanbul ignore if */ + if (err.status !== 404) { + return callback(err); + } else { // no dependencies + return destroyDb(); } - callback(null, blob); - }).catch(function (err) { - callback(err); + } + var dependentDbs = localDoc.dependentDbs; + var PouchDB = self.constructor; + var deletedMap = Object.keys(dependentDbs).map(function (name) { + // use_prefix is only false in the browser + /* istanbul ignore next */ + var trueName = usePrefix ? + name.replace(new RegExp('^' + PouchDB.prefix), '') : name; + return new PouchDB(trueName, self.__opts).destroy(); }); + Promise.all(deletedMap).then(destroyDb, callback); }); +}); - // Remove the attachment given by the id and rev - api.removeAttachment = adapterFun$$1('removeAttachment', function (docId, - attachmentId, - rev, - callback) { - var url = genDBUrl(host, encodeDocId(docId) + '/' + - encodeAttachmentId(attachmentId)) + '?rev=' + rev; - fetchJSON(url, {method: 'DELETE'}, callback).catch(callback); - }); +function TaskQueue() { + this.isReady = false; + this.failed = false; + this.queue = []; +} - // Add the attachment given by blob and its contentType property - // to the document with the given id, the revision given by rev, and - // add it to the database given by host. - api.putAttachment = adapterFun$$1('putAttachment', function (docId, attachmentId, - rev, blob, - type, callback) { - if (typeof type === 'function') { - callback = type; - type = blob; - blob = rev; - rev = null; +TaskQueue.prototype.execute = function () { + var fun; + if (this.failed) { + while ((fun = this.queue.shift())) { + fun(this.failed); } - var id = encodeDocId(docId) + '/' + encodeAttachmentId(attachmentId); - var url = genDBUrl(host, id); - if (rev) { - url += '?rev=' + rev; + } else { + while ((fun = this.queue.shift())) { + fun(); } + } +}; - if (typeof blob === 'string') { - // input is assumed to be a base64 string - var binary; - try { - binary = thisAtob(blob); - } catch (err) { - return callback(createError(BAD_ARG, - 'Attachment is not a valid base64 string')); +TaskQueue.prototype.fail = function (err) { + this.failed = err; + this.execute(); +}; + +TaskQueue.prototype.ready = function (db) { + this.isReady = true; + this.db = db; + this.execute(); +}; + +TaskQueue.prototype.addTask = function (fun) { + this.queue.push(fun); + if (this.failed) { + this.execute(); + } +}; + +function parseAdapter(name, opts) { + var match = name.match(/([a-z-]*):\/\/(.*)/); + if (match) { + // the http adapter expects the fully qualified name + return { + name: /https?/.test(match[1]) ? match[1] + '://' + match[2] : match[2], + adapter: match[1] + }; + } + + var adapters = PouchDB.adapters; + var preferredAdapters = PouchDB.preferredAdapters; + var prefix = PouchDB.prefix; + var adapterName = opts.adapter; + + if (!adapterName) { // automatically determine adapter + for (var i = 0; i < preferredAdapters.length; ++i) { + adapterName = preferredAdapters[i]; + // check for browsers that have been upgraded from websql-only to websql+idb + /* istanbul ignore if */ + if (adapterName === 'idb' && 'websql' in adapters && + hasLocalStorage() && localStorage['_pouch__websqldb_' + prefix + name]) { + // log it, because this can be confusing during development + guardedConsole('log', 'PouchDB is downgrading "' + name + '" to WebSQL to' + + ' avoid data loss, because it was already opened with WebSQL.'); + continue; // keep using websql to avoid user data loss } - blob = binary ? binStringToBluffer(binary, type) : ''; + break; } + } - // Add the attachment - fetchJSON(url, { - headers: new h({'Content-Type': type}), - method: 'PUT', - body: blob - }, callback).catch(callback); - }); + var adapter = adapters[adapterName]; - // Update/create multiple documents given by req in the database - // given by host. - api._bulkDocs = function (req, opts, callback) { - // If new_edits=false then it prevents the database from creating - // new revision numbers for the documents. Instead it just uses - // the old ones. This is used in database replication. - req.new_edits = opts.new_edits; + // if adapter is invalid, then an error will be thrown later + var usePrefix = (adapter && 'use_prefix' in adapter) ? + adapter.use_prefix : true; - setup().then(function () { - return Promise.all(req.docs.map(preprocessAttachments$1)); - }).then(function () { - // Update/create the documents - return fetchJSON(genDBUrl(host, '_bulk_docs'), { - method: 'POST', - body: JSON.stringify(req) - }, callback); - }).catch(callback); + return { + name: usePrefix ? (prefix + name) : name, + adapter: adapterName }; +} +// OK, so here's the deal. Consider this code: +// var db1 = new PouchDB('foo'); +// var db2 = new PouchDB('foo'); +// db1.destroy(); +// ^ these two both need to emit 'destroyed' events, +// as well as the PouchDB constructor itself. +// So we have one db object (whichever one got destroy() called on it) +// responsible for emitting the initial event, which then gets emitted +// by the constructor, which then broadcasts it to any other dbs +// that may have been created with the same name. +function prepareForDestruction(self) { - // Update/create document - api._put = function (doc, opts, callback) { - setup().then(function () { - return preprocessAttachments$1(doc); - }).then(function () { - return fetchJSON(genDBUrl(host, encodeDocId(doc._id)), { - method: 'PUT', - body: JSON.stringify(doc) - }); - }).then(function (result) { - callback(null, result.data); - }).catch(function (err) { - err.docId = doc && doc._id; - callback(err); - }); - }; + function onDestroyed(from_constructor) { + self.removeListener('closed', onClosed); + if (!from_constructor) { + self.constructor.emit('destroyed', self.name); + } + } + function onClosed() { + self.removeListener('destroyed', onDestroyed); + self.constructor.emit('unref', self); + } - // Get a listing of the documents in the database given - // by host and ordered by increasing id. - api.allDocs = adapterFun$$1('allDocs', function (opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - opts = clone(opts); + self.once('destroyed', onDestroyed); + self.once('closed', onClosed); + self.constructor.emit('ref', self); +} - // List of parameters to add to the GET request - var params = {}; - var body; - var method = 'GET'; +inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchDB, AbstractPouchDB); +function PouchDB(name, opts) { + // In Node our test suite only tests this for PouchAlt unfortunately + /* istanbul ignore if */ + if (!(this instanceof PouchDB)) { + return new PouchDB(name, opts); + } - if (opts.conflicts) { - params.conflicts = true; - } + var self = this; + opts = opts || {}; - /* istanbul ignore if */ - if (opts.update_seq) { - params.update_seq = true; - } + if (name && typeof name === 'object') { + opts = name; + name = opts.name; + delete opts.name; + } - if (opts.descending) { - params.descending = true; - } + if (opts.deterministic_revs === undefined) { + opts.deterministic_revs = true; + } - if (opts.include_docs) { - params.include_docs = true; - } + this.__opts = opts = clone(opts); - // added in CouchDB 1.6.0 - if (opts.attachments) { - params.attachments = true; - } + self.auto_compaction = opts.auto_compaction; + self.prefix = PouchDB.prefix; - if (opts.key) { - params.key = JSON.stringify(opts.key); - } + if (typeof name !== 'string') { + throw new Error('Missing/invalid DB name'); + } - if (opts.start_key) { - opts.startkey = opts.start_key; - } + var prefixedName = (opts.prefix || '') + name; + var backend = parseAdapter(prefixedName, opts); - if (opts.startkey) { - params.startkey = JSON.stringify(opts.startkey); - } + opts.name = backend.name; + opts.adapter = opts.adapter || backend.adapter; - if (opts.end_key) { - opts.endkey = opts.end_key; - } + self.name = name; + self._adapter = opts.adapter; + PouchDB.emit('debug', ['adapter', 'Picked adapter: ', opts.adapter]); - if (opts.endkey) { - params.endkey = JSON.stringify(opts.endkey); - } + if (!PouchDB.adapters[opts.adapter] || + !PouchDB.adapters[opts.adapter].valid()) { + throw new Error('Invalid Adapter: ' + opts.adapter); + } - if (typeof opts.inclusive_end !== 'undefined') { - params.inclusive_end = !!opts.inclusive_end; - } + AbstractPouchDB.call(self); + self.taskqueue = new TaskQueue(); - if (typeof opts.limit !== 'undefined') { - params.limit = opts.limit; + self.adapter = opts.adapter; + + PouchDB.adapters[opts.adapter].call(self, opts, function (err) { + if (err) { + return self.taskqueue.fail(err); } + prepareForDestruction(self); - if (typeof opts.skip !== 'undefined') { - params.skip = opts.skip; + self.emit('created', self); + PouchDB.emit('created', self.name); + self.taskqueue.ready(self); + }); + +} + +// AbortController was introduced quite a while after fetch and +// isnt required for PouchDB to function so polyfill if needed +var a = (typeof AbortController !== 'undefined') + ? AbortController + : function () { return {abort: function () {}}; }; + +var f$1 = fetch; +var h = Headers; + +PouchDB.adapters = {}; +PouchDB.preferredAdapters = []; + +PouchDB.prefix = '_pouch_'; + +var eventEmitter = new events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter(); + +function setUpEventEmitter(Pouch) { + Object.keys(events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype).forEach(function (key) { + if (typeof events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.prototype[key] === 'function') { + Pouch[key] = eventEmitter[key].bind(eventEmitter); } + }); - var paramStr = paramsToStr(params); + // these are created in constructor.js, and allow us to notify each DB with + // the same name that it was destroyed, via the constructor object + var destructListeners = Pouch._destructionListeners = new ExportedMap(); - if (typeof opts.keys !== 'undefined') { - method = 'POST'; - body = {keys: opts.keys}; + Pouch.on('ref', function onConstructorRef(db) { + if (!destructListeners.has(db.name)) { + destructListeners.set(db.name, []); } + destructListeners.get(db.name).push(db); + }); - fetchJSON(genDBUrl(host, '_all_docs' + paramStr), { - method: method, - body: JSON.stringify(body) - }).then(function (result) { - if (opts.include_docs && opts.attachments && opts.binary) { - result.data.rows.forEach(readAttachmentsAsBlobOrBuffer); - } - callback(null, result.data); - }).catch(callback); + Pouch.on('unref', function onConstructorUnref(db) { + if (!destructListeners.has(db.name)) { + return; + } + var dbList = destructListeners.get(db.name); + var pos = dbList.indexOf(db); + if (pos < 0) { + /* istanbul ignore next */ + return; + } + dbList.splice(pos, 1); + if (dbList.length > 1) { + /* istanbul ignore next */ + destructListeners.set(db.name, dbList); + } else { + destructListeners.delete(db.name); + } }); - // Get a list of changes made to documents in the database given by host. - // TODO According to the README, there should be two other methods here, - // api.changes.addListener and api.changes.removeListener. - api._changes = function (opts) { + Pouch.on('destroyed', function onConstructorDestroyed(name) { + if (!destructListeners.has(name)) { + return; + } + var dbList = destructListeners.get(name); + destructListeners.delete(name); + dbList.forEach(function (db) { + db.emit('destroyed',true); + }); + }); +} - // We internally page the results of a changes request, this means - // if there is a large set of changes to be returned we can start - // processing them quicker instead of waiting on the entire - // set of changes to return and attempting to process them at once - var batchSize = 'batch_size' in opts ? opts.batch_size : CHANGES_BATCH_SIZE; +setUpEventEmitter(PouchDB); - opts = clone(opts); +PouchDB.adapter = function (id, obj, addToPreferredAdapters) { + /* istanbul ignore else */ + if (obj.valid()) { + PouchDB.adapters[id] = obj; + if (addToPreferredAdapters) { + PouchDB.preferredAdapters.push(id); + } + } +}; + +PouchDB.plugin = function (obj) { + if (typeof obj === 'function') { // function style for plugins + obj(PouchDB); + } else if (typeof obj !== 'object' || Object.keys(obj).length === 0) { + throw new Error('Invalid plugin: got "' + obj + '", expected an object or a function'); + } else { + Object.keys(obj).forEach(function (id) { // object style for plugins + PouchDB.prototype[id] = obj[id]; + }); + } + if (this.__defaults) { + PouchDB.__defaults = $inject_Object_assign({}, this.__defaults); + } + return PouchDB; +}; - if (opts.continuous && !('heartbeat' in opts)) { - opts.heartbeat = DEFAULT_HEARTBEAT; +PouchDB.defaults = function (defaultOpts) { + function PouchAlt(name, opts) { + if (!(this instanceof PouchAlt)) { + return new PouchAlt(name, opts); } - var requestTimeout = ('timeout' in opts) ? opts.timeout : 30 * 1000; - - // ensure CHANGES_TIMEOUT_BUFFER applies - if ('timeout' in opts && opts.timeout && - (requestTimeout - opts.timeout) < CHANGES_TIMEOUT_BUFFER) { - requestTimeout = opts.timeout + CHANGES_TIMEOUT_BUFFER; - } + opts = opts || {}; - /* istanbul ignore if */ - if ('heartbeat' in opts && opts.heartbeat && - (requestTimeout - opts.heartbeat) < CHANGES_TIMEOUT_BUFFER) { - requestTimeout = opts.heartbeat + CHANGES_TIMEOUT_BUFFER; + if (name && typeof name === 'object') { + opts = name; + name = opts.name; + delete opts.name; } - var params = {}; - if ('timeout' in opts && opts.timeout) { - params.timeout = opts.timeout; - } + opts = $inject_Object_assign({}, PouchAlt.__defaults, opts); + PouchDB.call(this, name, opts); + } - var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false; - var leftToFetch = limit; + inherits__WEBPACK_IMPORTED_MODULE_3___default()(PouchAlt, PouchDB); - if (opts.style) { - params.style = opts.style; + PouchAlt.preferredAdapters = PouchDB.preferredAdapters.slice(); + Object.keys(PouchDB).forEach(function (key) { + if (!(key in PouchAlt)) { + PouchAlt[key] = PouchDB[key]; } + }); - if (opts.include_docs || opts.filter && typeof opts.filter === 'function') { - params.include_docs = true; - } + // make default options transitive + // https://github.com/pouchdb/pouchdb/issues/5922 + PouchAlt.__defaults = $inject_Object_assign({}, this.__defaults, defaultOpts); - if (opts.attachments) { - params.attachments = true; - } + return PouchAlt; +}; - if (opts.continuous) { - params.feed = 'longpoll'; - } +PouchDB.fetch = function (url, opts) { + return f$1(url, opts); +}; - if (opts.seq_interval) { - params.seq_interval = opts.seq_interval; - } +// managed automatically by set-version.js +var version = "7.0.0"; - if (opts.conflicts) { - params.conflicts = true; +// this would just be "return doc[field]", but fields +// can be "deep" due to dot notation +function getFieldFromDoc(doc, parsedField) { + var value = doc; + for (var i = 0, len = parsedField.length; i < len; i++) { + var key = parsedField[i]; + value = value[key]; + if (!value) { + break; } + } + return value; +} - if (opts.descending) { - params.descending = true; - } - - /* istanbul ignore if */ - if (opts.update_seq) { - params.update_seq = true; - } +function compare$1(left, right) { + return left < right ? -1 : left > right ? 1 : 0; +} - if ('heartbeat' in opts) { - // If the heartbeat value is false, it disables the default heartbeat - if (opts.heartbeat) { - params.heartbeat = opts.heartbeat; +// Converts a string in dot notation to an array of its components, with backslash escaping +function parseField(fieldName) { + // fields may be deep (e.g. "foo.bar.baz"), so parse + var fields = []; + var current = ''; + for (var i = 0, len = fieldName.length; i < len; i++) { + var ch = fieldName[i]; + if (ch === '.') { + if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter + current = current.substring(0, current.length - 1) + '.'; + } else { // not escaped, so delimiter + fields.push(current); + current = ''; } + } else { // normal character + current += ch; } + } + fields.push(current); + return fields; +} - if (opts.filter && typeof opts.filter === 'string') { - params.filter = opts.filter; - } +var combinationFields = ['$or', '$nor', '$not']; +function isCombinationalField(field) { + return combinationFields.indexOf(field) > -1; +} - if (opts.view && typeof opts.view === 'string') { - params.filter = '_view'; - params.view = opts.view; - } +function getKey(obj) { + return Object.keys(obj)[0]; +} - // If opts.query_params exists, pass it through to the changes request. - // These parameters may be used by the filter on the source database. - if (opts.query_params && typeof opts.query_params === 'object') { - for (var param_name in opts.query_params) { - /* istanbul ignore else */ - if (opts.query_params.hasOwnProperty(param_name)) { - params[param_name] = opts.query_params[param_name]; - } - } - } +function getValue(obj) { + return obj[getKey(obj)]; +} - var method = 'GET'; - var body; - if (opts.doc_ids) { - // set this automagically for the user; it's annoying that couchdb - // requires both a "filter" and a "doc_ids" param. - params.filter = '_doc_ids'; - method = 'POST'; - body = {doc_ids: opts.doc_ids }; - } - /* istanbul ignore next */ - else if (opts.selector) { - // set this automagically for the user, similar to above - params.filter = '_selector'; - method = 'POST'; - body = {selector: opts.selector }; - } +// flatten an array of selectors joined by an $and operator +function mergeAndedSelectors(selectors) { - var controller = new a(); - var lastFetchedSeq; + // sort to ensure that e.g. if the user specified + // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into + // just {$gt: 'b'} + var res = {}; - // Get all the changes starting wtih the one immediately after the - // sequence number given by since. - var fetchData = function (since, callback) { - if (opts.aborted) { - return; - } - params.since = since; - // "since" can be any kind of json object in Cloudant/CouchDB 2.x - /* istanbul ignore next */ - if (typeof params.since === "object") { - params.since = JSON.stringify(params.since); + selectors.forEach(function (selector) { + Object.keys(selector).forEach(function (field) { + var matcher = selector[field]; + if (typeof matcher !== 'object') { + matcher = {$eq: matcher}; } - if (opts.descending) { - if (limit) { - params.limit = leftToFetch; + if (isCombinationalField(field)) { + if (matcher instanceof Array) { + res[field] = matcher.map(function (m) { + return mergeAndedSelectors([m]); + }); + } else { + res[field] = mergeAndedSelectors([matcher]); } } else { - params.limit = (!limit || leftToFetch > batchSize) ? - batchSize : leftToFetch; - } - - // Set the options for the ajax call - var url = genDBUrl(host, '_changes' + paramsToStr(params)); - var fetchOpts = { - signal: controller.signal, - method: method, - body: JSON.stringify(body) - }; - lastFetchedSeq = since; - - /* istanbul ignore if */ - if (opts.aborted) { - return; - } - - // Get the changes - setup().then(function () { - return fetchJSON(url, fetchOpts, callback); - }).catch(callback); - }; - - // If opts.since exists, get all the changes from the sequence - // number given by opts.since. Otherwise, get all the changes - // from the sequence number 0. - var results = {results: []}; + var fieldMatchers = res[field] = res[field] || {}; + Object.keys(matcher).forEach(function (operator) { + var value = matcher[operator]; - var fetched = function (err, res) { - if (opts.aborted) { - return; - } - var raw_results_length = 0; - // If the result of the ajax call (res) contains changes (res.results) - if (res && res.results) { - raw_results_length = res.results.length; - results.last_seq = res.last_seq; - var pending = null; - var lastSeq = null; - // Attach 'pending' property if server supports it (CouchDB 2.0+) - /* istanbul ignore if */ - if (typeof res.pending === 'number') { - pending = res.pending; - } - if (typeof results.last_seq === 'string' || typeof results.last_seq === 'number') { - lastSeq = results.last_seq; - } - // For each change - var req = {}; - req.query = opts.query_params; - res.results = res.results.filter(function (c) { - leftToFetch--; - var ret = filterChange(opts)(c); - if (ret) { - if (opts.include_docs && opts.attachments && opts.binary) { - readAttachmentsAsBlobOrBuffer(c); - } - if (opts.return_docs) { - results.results.push(c); - } - opts.onChange(c, pending, lastSeq); + if (operator === '$gt' || operator === '$gte') { + return mergeGtGte(operator, value, fieldMatchers); + } else if (operator === '$lt' || operator === '$lte') { + return mergeLtLte(operator, value, fieldMatchers); + } else if (operator === '$ne') { + return mergeNe(value, fieldMatchers); + } else if (operator === '$eq') { + return mergeEq(value, fieldMatchers); } - return ret; + fieldMatchers[operator] = value; }); - } else if (err) { - // In case of an error, stop listening for changes and call - // opts.complete - opts.aborted = true; - opts.complete(err); - return; - } - - // The changes feed may have timed out with no results - // if so reuse last update sequence - if (res && res.last_seq) { - lastFetchedSeq = res.last_seq; } + }); + }); - var finished = (limit && leftToFetch <= 0) || - (res && raw_results_length < batchSize) || - (opts.descending); + return res; +} - if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) { - // Queue a call to fetch again with the newest sequence number - immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { fetchData(lastFetchedSeq, fetched); }); - } else { - // We're done, call the callback - opts.complete(null, results); - } - }; - fetchData(opts.since || 0, fetched); - // Return a method to cancel this method from processing any more - return { - cancel: function () { - opts.aborted = true; - controller.abort(); +// collapse logically equivalent gt/gte values +function mergeGtGte(operator, value, fieldMatchers) { + if (typeof fieldMatchers.$eq !== 'undefined') { + return; // do nothing + } + if (typeof fieldMatchers.$gte !== 'undefined') { + if (operator === '$gte') { + if (value > fieldMatchers.$gte) { // more specificity + fieldMatchers.$gte = value; + } + } else { // operator === '$gt' + if (value >= fieldMatchers.$gte) { // more specificity + delete fieldMatchers.$gte; + fieldMatchers.$gt = value; } - }; - }; - - // Given a set of document/revision IDs (given by req), tets the subset of - // those that do NOT correspond to revisions stored in the database. - // See http://wiki.apache.org/couchdb/HttpPostRevsDiff - api.revsDiff = adapterFun$$1('revsDiff', function (req, opts, callback) { - // If no options were given, set the callback to be the second parameter - if (typeof opts === 'function') { - callback = opts; - opts = {}; } - - // Get the missing document/revision IDs - fetchJSON(genDBUrl(host, '_revs_diff'), { - method: 'POST', - body: JSON.stringify(req) - }, callback).catch(callback); - }); - - api._close = function (callback) { - callback(); - }; - - api._destroy = function (options, callback) { - fetchJSON(genDBUrl(host, ''), {method: 'DELETE'}).then(function (json) { - callback(null, json); - }).catch(function (err) { - /* istanbul ignore if */ - if (err.status === 404) { - callback(null, {ok: true}); - } else { - callback(err); + } else if (typeof fieldMatchers.$gt !== 'undefined') { + if (operator === '$gte') { + if (value > fieldMatchers.$gt) { // more specificity + delete fieldMatchers.$gt; + fieldMatchers.$gte = value; } - }); - }; -} - -// HttpPouch is a valid adapter. -HttpPouch.valid = function () { - return true; -}; - -function HttpPouch$1 (PouchDB) { - PouchDB.adapter('http', HttpPouch, false); - PouchDB.adapter('https', HttpPouch, false); + } else { // operator === '$gt' + if (value > fieldMatchers.$gt) { // more specificity + fieldMatchers.$gt = value; + } + } + } else { + fieldMatchers[operator] = value; + } } -function QueryParseError(message) { - this.status = 400; - this.name = 'query_parse_error'; - this.message = message; - this.error = true; - try { - Error.captureStackTrace(this, QueryParseError); - } catch (e) {} +// collapse logically equivalent lt/lte values +function mergeLtLte(operator, value, fieldMatchers) { + if (typeof fieldMatchers.$eq !== 'undefined') { + return; // do nothing + } + if (typeof fieldMatchers.$lte !== 'undefined') { + if (operator === '$lte') { + if (value < fieldMatchers.$lte) { // more specificity + fieldMatchers.$lte = value; + } + } else { // operator === '$gt' + if (value <= fieldMatchers.$lte) { // more specificity + delete fieldMatchers.$lte; + fieldMatchers.$lt = value; + } + } + } else if (typeof fieldMatchers.$lt !== 'undefined') { + if (operator === '$lte') { + if (value < fieldMatchers.$lt) { // more specificity + delete fieldMatchers.$lt; + fieldMatchers.$lte = value; + } + } else { // operator === '$gt' + if (value < fieldMatchers.$lt) { // more specificity + fieldMatchers.$lt = value; + } + } + } else { + fieldMatchers[operator] = value; + } } -inherits__WEBPACK_IMPORTED_MODULE_3___default()(QueryParseError, Error); - -function NotFoundError(message) { - this.status = 404; - this.name = 'not_found'; - this.message = message; - this.error = true; - try { - Error.captureStackTrace(this, NotFoundError); - } catch (e) {} +// combine $ne values into one array +function mergeNe(value, fieldMatchers) { + if ('$ne' in fieldMatchers) { + // there are many things this could "not" be + fieldMatchers.$ne.push(value); + } else { // doesn't exist yet + fieldMatchers.$ne = [value]; + } } -inherits__WEBPACK_IMPORTED_MODULE_3___default()(NotFoundError, Error); - -function BuiltInError(message) { - this.status = 500; - this.name = 'invalid_value'; - this.message = message; - this.error = true; - try { - Error.captureStackTrace(this, BuiltInError); - } catch (e) {} +// add $eq into the mix +function mergeEq(value, fieldMatchers) { + // these all have less specificity than the $eq + // TODO: check for user errors here + delete fieldMatchers.$gt; + delete fieldMatchers.$gte; + delete fieldMatchers.$lt; + delete fieldMatchers.$lte; + delete fieldMatchers.$ne; + fieldMatchers.$eq = value; } -inherits__WEBPACK_IMPORTED_MODULE_3___default()(BuiltInError, Error); -function promisedCallback(promise, callback) { - if (callback) { - promise.then(function (res) { - immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { - callback(null, res); - }); - }, function (reason) { - immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { - callback(reason); - }); - }); +// +// normalize the selector +// +function massageSelector(input) { + var result = clone(input); + var wasAnded = false; + if ('$and' in result) { + result = mergeAndedSelectors(result['$and']); + wasAnded = true; } - return promise; -} -function callbackify(fun) { - return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { - var cb = args.pop(); - var promise = fun.apply(this, args); - if (typeof cb === 'function') { - promisedCallback(promise, cb); + ['$or', '$nor'].forEach(function (orOrNor) { + if (orOrNor in result) { + // message each individual selector + // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}} + result[orOrNor].forEach(function (subSelector) { + var fields = Object.keys(subSelector); + for (var i = 0; i < fields.length; i++) { + var field = fields[i]; + var matcher = subSelector[field]; + if (typeof matcher !== 'object' || matcher === null) { + subSelector[field] = {$eq: matcher}; + } + } + }); } - return promise; - }); -} - -// Promise finally util similar to Q.finally -function fin(promise, finalPromiseFactory) { - return promise.then(function (res) { - return finalPromiseFactory().then(function () { - return res; - }); - }, function (reason) { - return finalPromiseFactory().then(function () { - throw reason; - }); }); -} - -function sequentialize(queue, promiseFactory) { - return function () { - var args = arguments; - var that = this; - return queue.add(function () { - return promiseFactory.apply(that, args); - }); - }; -} -// uniq an array of strings, order not guaranteed -// similar to underscore/lodash _.uniq -function uniq(arr) { - var theSet = new ExportedSet(arr); - var result = new Array(theSet.size); - var index = -1; - theSet.forEach(function (value) { - result[++index] = value; - }); - return result; -} + if ('$not' in result) { + //This feels a little like forcing, but it will work for now, + //I would like to come back to this and make the merging of selectors a little more generic + result['$not'] = mergeAndedSelectors([result['$not']]); + } -function mapToKeysArray(map) { - var result = new Array(map.size); - var index = -1; - map.forEach(function (value, key) { - result[++index] = key; - }); - return result; -} + var fields = Object.keys(result); -function createBuiltInError(name) { - var message = 'builtin ' + name + - ' function requires map values to be numbers' + - ' or number arrays'; - return new BuiltInError(message); -} + for (var i = 0; i < fields.length; i++) { + var field = fields[i]; + var matcher = result[field]; -function sum(values) { - var result = 0; - for (var i = 0, len = values.length; i < len; i++) { - var num = values[i]; - if (typeof num !== 'number') { - if (Array.isArray(num)) { - // lists of numbers are also allowed, sum them separately - result = typeof result === 'number' ? [result] : result; - for (var j = 0, jLen = num.length; j < jLen; j++) { - var jNum = num[j]; - if (typeof jNum !== 'number') { - throw createBuiltInError('_sum'); - } else if (typeof result[j] === 'undefined') { - result.push(jNum); - } else { - result[j] += jNum; - } - } - } else { // not array/number - throw createBuiltInError('_sum'); - } - } else if (typeof result === 'number') { - result += num; - } else { // add number to array - result[0] += num; + if (typeof matcher !== 'object' || matcher === null) { + matcher = {$eq: matcher}; + } else if ('$ne' in matcher && !wasAnded) { + // I put these in an array, since there may be more than one + // but in the "mergeAnded" operation, I already take care of that + matcher.$ne = [matcher.$ne]; } + result[field] = matcher; } + return result; } -var log = guardedConsole.bind(null, 'log'); -var isArray = Array.isArray; -var toJSON = JSON.parse; +function pad(str, padWith, upToLength) { + var padding = ''; + var targetLength = upToLength - str.length; + /* istanbul ignore next */ + while (padding.length < targetLength) { + padding += padWith; + } + return padding; +} -function evalFunctionWithEval(func, emit) { - return scopeEval( - "return (" + func.replace(/;\s*$/, "") + ");", - { - emit: emit, - sum: sum, - log: log, - isArray: isArray, - toJSON: toJSON - } - ); +function padLeft(str, padWith, upToLength) { + var padding = pad(str, padWith, upToLength); + return padding + str; } -/* - * Simple task queue to sequentialize actions. Assumes - * callbacks will eventually fire (once). - */ +var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE +var MAGNITUDE_DIGITS = 3; // ditto +var SEP = ''; // set to '_' for easier debugging +function collate(a, b) { -function TaskQueue$1() { - this.promise = new Promise(function (fulfill) {fulfill(); }); -} -TaskQueue$1.prototype.add = function (promiseFactory) { - this.promise = this.promise.catch(function () { - // just recover - }).then(function () { - return promiseFactory(); - }); - return this.promise; -}; -TaskQueue$1.prototype.finish = function () { - return this.promise; -}; + if (a === b) { + return 0; + } -function stringify(input) { - if (!input) { - return 'undefined'; // backwards compat for empty reduce + a = normalizeKey(a); + b = normalizeKey(b); + + var ai = collationIndex(a); + var bi = collationIndex(b); + if ((ai - bi) !== 0) { + return ai - bi; } - // for backwards compat with mapreduce, functions/strings are stringified - // as-is. everything else is JSON-stringified. - switch (typeof input) { - case 'function': - // e.g. a mapreduce map - return input.toString(); + switch (typeof a) { + case 'number': + return a - b; + case 'boolean': + return a < b ? -1 : 1; case 'string': - // e.g. a mapreduce built-in _reduce function - return input.toString(); - default: - // e.g. a JSON object in the case of mango queries - return JSON.stringify(input); + return stringCollate(a, b); } + return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b); } -/* create a string signature for a view so we can cache it and uniq it */ -function createViewSignature(mapFun, reduceFun) { - // the "undefined" part is for backwards compatibility - return stringify(mapFun) + stringify(reduceFun) + 'undefined'; +// couch considers null/NaN/Infinity/-Infinity === undefined, +// for the purposes of mapreduce indexes. also, dates get stringified. +function normalizeKey(key) { + switch (typeof key) { + case 'undefined': + return null; + case 'number': + if (key === Infinity || key === -Infinity || isNaN(key)) { + return null; + } + return key; + case 'object': + var origKey = key; + if (Array.isArray(key)) { + var len = key.length; + key = new Array(len); + for (var i = 0; i < len; i++) { + key[i] = normalizeKey(origKey[i]); + } + /* istanbul ignore next */ + } else if (key instanceof Date) { + return key.toJSON(); + } else if (key !== null) { // generic object + key = {}; + for (var k in origKey) { + if (origKey.hasOwnProperty(k)) { + var val = origKey[k]; + if (typeof val !== 'undefined') { + key[k] = normalizeKey(val); + } + } + } + } + } + return key; } -function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) { - var viewSignature = createViewSignature(mapFun, reduceFun); - - var cachedViews; - if (!temporary) { - // cache this to ensure we don't try to update the same view twice - cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {}; - if (cachedViews[viewSignature]) { - return cachedViews[viewSignature]; +function indexify(key) { + if (key !== null) { + switch (typeof key) { + case 'boolean': + return key ? 1 : 0; + case 'number': + return numToIndexableString(key); + case 'string': + // We've to be sure that key does not contain \u0000 + // Do order-preserving replacements: + // 0 -> 1, 1 + // 1 -> 1, 2 + // 2 -> 2, 2 + /* eslint-disable no-control-regex */ + return key + .replace(/\u0002/g, '\u0002\u0002') + .replace(/\u0001/g, '\u0001\u0002') + .replace(/\u0000/g, '\u0001\u0001'); + /* eslint-enable no-control-regex */ + case 'object': + var isArray = Array.isArray(key); + var arr = isArray ? key : Object.keys(key); + var i = -1; + var len = arr.length; + var result = ''; + if (isArray) { + while (++i < len) { + result += toIndexableString(arr[i]); + } + } else { + while (++i < len) { + var objKey = arr[i]; + result += toIndexableString(objKey) + + toIndexableString(key[objKey]); + } + } + return result; } } + return ''; +} - var promiseForView = sourceDB.info().then(function (info) { - - var depDbName = info.db_name + '-mrview-' + - (temporary ? 'temp' : stringMd5(viewSignature)); +// convert the given key to a string that would be appropriate +// for lexical sorting, e.g. within a database, where the +// sorting is the same given by the collate() function. +function toIndexableString(key) { + var zero = '\u0000'; + key = normalizeKey(key); + return collationIndex(key) + SEP + indexify(key) + zero; +} - // save the view name in the source db so it can be cleaned up if necessary - // (e.g. when the _design doc is deleted, remove all associated view data) - function diffFunction(doc) { - doc.views = doc.views || {}; - var fullViewName = viewName; - if (fullViewName.indexOf('/') === -1) { - fullViewName = viewName + '/' + viewName; - } - var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {}; - /* istanbul ignore if */ - if (depDbs[depDbName]) { - return; // no update necessary +function parseNumber(str, i) { + var originalIdx = i; + var num; + var zero = str[i] === '1'; + if (zero) { + num = 0; + i++; + } else { + var neg = str[i] === '0'; + i++; + var numAsString = ''; + var magAsString = str.substring(i, i + MAGNITUDE_DIGITS); + var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE; + /* istanbul ignore next */ + if (neg) { + magnitude = -magnitude; + } + i += MAGNITUDE_DIGITS; + while (true) { + var ch = str[i]; + if (ch === '\u0000') { + break; + } else { + numAsString += ch; } - depDbs[depDbName] = true; - return doc; + i++; + } + numAsString = numAsString.split('.'); + if (numAsString.length === 1) { + num = parseInt(numAsString, 10); + } else { + /* istanbul ignore next */ + num = parseFloat(numAsString[0] + '.' + numAsString[1]); + } + /* istanbul ignore next */ + if (neg) { + num = num - 10; + } + /* istanbul ignore next */ + if (magnitude !== 0) { + // parseFloat is more reliable than pow due to rounding errors + // e.g. Number.MAX_VALUE would return Infinity if we did + // num * Math.pow(10, magnitude); + num = parseFloat(num + 'e' + magnitude); } - return upsert(sourceDB, '_local/' + localDocName, diffFunction).then(function () { - return sourceDB.registerDependentDatabase(depDbName).then(function (res) { - var db = res.db; - db.auto_compaction = true; - var view = { - name: depDbName, - db: db, - sourceDB: sourceDB, - adapter: sourceDB.adapter, - mapFun: mapFun, - reduceFun: reduceFun - }; - return view.db.get('_local/lastSeq').catch(function (err) { - /* istanbul ignore if */ - if (err.status !== 404) { - throw err; - } - }).then(function (lastSeqDoc) { - view.seq = lastSeqDoc ? lastSeqDoc.seq : 0; - if (cachedViews) { - view.db.once('destroyed', function () { - delete cachedViews[viewSignature]; - }); - } - return view; - }); - }); - }); - }); - - if (cachedViews) { - cachedViews[viewSignature] = promiseForView; } - return promiseForView; + return {num: num, length : i - originalIdx}; } -var persistentQueues = {}; -var tempViewQueue = new TaskQueue$1(); -var CHANGES_BATCH_SIZE$1 = 50; +// move up the stack while parsing +// this function moved outside of parseIndexableString for performance +function pop(stack, metaStack) { + var obj = stack.pop(); -function parseViewName(name) { - // can be either 'ddocname/viewname' or just 'viewname' - // (where the ddoc name is the same) - return name.indexOf('/') === -1 ? [name, name] : name.split('/'); + if (metaStack.length) { + var lastMetaElement = metaStack[metaStack.length - 1]; + if (obj === lastMetaElement.element) { + // popping a meta-element, e.g. an object whose value is another object + metaStack.pop(); + lastMetaElement = metaStack[metaStack.length - 1]; + } + var element = lastMetaElement.element; + var lastElementIndex = lastMetaElement.index; + if (Array.isArray(element)) { + element.push(obj); + } else if (lastElementIndex === stack.length - 2) { // obj with key+value + var key = stack.pop(); + element[key] = obj; + } else { + stack.push(obj); // obj with key only + } + } } -function isGenOne(changes) { - // only return true if the current change is 1- - // and there are no other leafs - return changes.length === 1 && /^1-/.test(changes[0].rev); -} +function parseIndexableString(str) { + var stack = []; + var metaStack = []; // stack for arrays and objects + var i = 0; -function emitError(db, e) { - try { - db.emit('error', e); - } catch (err) { - guardedConsole('error', - 'The user\'s map/reduce function threw an uncaught error.\n' + - 'You can debug this error by doing:\n' + - 'myDatabase.on(\'error\', function (err) { debugger; });\n' + - 'Please double-check your map/reduce function.'); - guardedConsole('error', e); + /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/ + while (true) { + var collationIndex = str[i++]; + if (collationIndex === '\u0000') { + if (stack.length === 1) { + return stack.pop(); + } else { + pop(stack, metaStack); + continue; + } + } + switch (collationIndex) { + case '1': + stack.push(null); + break; + case '2': + stack.push(str[i] === '1'); + i++; + break; + case '3': + var parsedNum = parseNumber(str, i); + stack.push(parsedNum.num); + i += parsedNum.length; + break; + case '4': + var parsedStr = ''; + /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/ + while (true) { + var ch = str[i]; + if (ch === '\u0000') { + break; + } + parsedStr += ch; + i++; + } + // perform the reverse of the order-preserving replacement + // algorithm (see above) + /* eslint-disable no-control-regex */ + parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000') + .replace(/\u0001\u0002/g, '\u0001') + .replace(/\u0002\u0002/g, '\u0002'); + /* eslint-enable no-control-regex */ + stack.push(parsedStr); + break; + case '5': + var arrayElement = { element: [], index: stack.length }; + stack.push(arrayElement.element); + metaStack.push(arrayElement); + break; + case '6': + var objElement = { element: {}, index: stack.length }; + stack.push(objElement.element); + metaStack.push(objElement); + break; + /* istanbul ignore next */ + default: + throw new Error( + 'bad collationIndex or unexpectedly reached end of input: ' + + collationIndex); + } } } -/** - * Returns an "abstract" mapreduce object of the form: - * - * { - * query: queryFun, - * viewCleanup: viewCleanupFun - * } - * - * Arguments are: - * - * localDoc: string - * This is for the local doc that gets saved in order to track the - * "dependent" DBs and clean them up for viewCleanup. It should be - * unique, so that indexer plugins don't collide with each other. - * mapper: function (mapFunDef, emit) - * Returns a map function based on the mapFunDef, which in the case of - * normal map/reduce is just the de-stringified function, but may be - * something else, such as an object in the case of pouchdb-find. - * reducer: function (reduceFunDef) - * Ditto, but for reducing. Modules don't have to support reducing - * (e.g. pouchdb-find). - * ddocValidator: function (ddoc, viewName) - * Throws an error if the ddoc or viewName is not valid. - * This could be a way to communicate to the user that the configuration for the - * indexer is invalid. - */ -function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) { - - function tryMap(db, fun, doc) { - // emit an event if there was an error thrown by a map function. - // putting try/catches in a single function also avoids deoptimizations. - try { - fun(doc); - } catch (e) { - emitError(db, e); +function arrayCollate(a, b) { + var len = Math.min(a.length, b.length); + for (var i = 0; i < len; i++) { + var sort = collate(a[i], b[i]); + if (sort !== 0) { + return sort; } } - - function tryReduce(db, fun, keys, values, rereduce) { - // same as above, but returning the result or an error. there are two separate - // functions to avoid extra memory allocations since the tryCode() case is used - // for custom map functions (common) vs this function, which is only used for - // custom reduce functions (rare) - try { - return {output : fun(keys, values, rereduce)}; - } catch (e) { - emitError(db, e); - return {error: e}; + return (a.length === b.length) ? 0 : + (a.length > b.length) ? 1 : -1; +} +function stringCollate(a, b) { + // See: https://github.com/daleharvey/pouchdb/issues/40 + // This is incompatible with the CouchDB implementation, but its the + // best we can do for now + return (a === b) ? 0 : ((a > b) ? 1 : -1); +} +function objectCollate(a, b) { + var ak = Object.keys(a), bk = Object.keys(b); + var len = Math.min(ak.length, bk.length); + for (var i = 0; i < len; i++) { + // First sort the keys + var sort = collate(ak[i], bk[i]); + if (sort !== 0) { + return sort; + } + // if the keys are equal sort the values + sort = collate(a[ak[i]], b[bk[i]]); + if (sort !== 0) { + return sort; } - } - function sortByKeyThenValue(x, y) { - var keyCompare = collate(x.key, y.key); - return keyCompare !== 0 ? keyCompare : collate(x.value, y.value); } - - function sliceResults(results, limit, skip) { - skip = skip || 0; - if (typeof limit === 'number') { - return results.slice(skip, limit + skip); - } else if (skip > 0) { - return results.slice(skip); + return (ak.length === bk.length) ? 0 : + (ak.length > bk.length) ? 1 : -1; +} +// The collation is defined by erlangs ordered terms +// the atoms null, true, false come first, then numbers, strings, +// arrays, then objects +// null/undefined/NaN/Infinity/-Infinity are all considered null +function collationIndex(x) { + var id = ['boolean', 'number', 'string', 'object']; + var idx = id.indexOf(typeof x); + //false if -1 otherwise true, but fast!!!!1 + if (~idx) { + if (x === null) { + return 1; } - return results; + if (Array.isArray(x)) { + return 5; + } + return idx < 3 ? (idx + 2) : (idx + 3); } - - function rowToDocId(row) { - var val = row.value; - // Users can explicitly specify a joined doc _id, or it - // defaults to the doc _id that emitted the key/value. - var docId = (val && typeof val === 'object' && val._id) || row.id; - return docId; + /* istanbul ignore next */ + if (Array.isArray(x)) { + return 5; } +} - function readAttachmentsAsBlobOrBuffer(res) { - res.rows.forEach(function (row) { - var atts = row.doc && row.doc._attachments; - if (!atts) { - return; - } - Object.keys(atts).forEach(function (filename) { - var att = atts[filename]; - atts[filename].data = b64ToBluffer(att.data, att.content_type); - }); - }); - } +// conversion: +// x yyy zz...zz +// x = 0 for negative, 1 for 0, 2 for positive +// y = exponent (for negative numbers negated) moved so that it's >= 0 +// z = mantisse +function numToIndexableString(num) { - function postprocessAttachments(opts) { - return function (res) { - if (opts.include_docs && opts.attachments && opts.binary) { - readAttachmentsAsBlobOrBuffer(res); - } - return res; - }; + if (num === 0) { + return '1'; } - function addHttpParam(paramName, opts, params, asJson) { - // add an http param from opts to params, optionally json-encoded - var val = opts[paramName]; - if (typeof val !== 'undefined') { - if (asJson) { - val = encodeURIComponent(JSON.stringify(val)); - } - params.push(paramName + '=' + val); - } - } + // convert number to exponential format for easier and + // more succinct string sorting + var expFormat = num.toExponential().split(/e\+?/); + var magnitude = parseInt(expFormat[1], 10); - function coerceInteger(integerCandidate) { - if (typeof integerCandidate !== 'undefined') { - var asNumber = Number(integerCandidate); - // prevents e.g. '1foo' or '1.1' being coerced to 1 - if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) { - return asNumber; - } else { - return integerCandidate; - } - } - } + var neg = num < 0; - function coerceOptions(opts) { - opts.group_level = coerceInteger(opts.group_level); - opts.limit = coerceInteger(opts.limit); - opts.skip = coerceInteger(opts.skip); - return opts; - } + var result = neg ? '0' : '2'; - function checkPositiveInteger(number) { - if (number) { - if (typeof number !== 'number') { - return new QueryParseError('Invalid value for integer: "' + - number + '"'); - } - if (number < 0) { - return new QueryParseError('Invalid value for positive integer: ' + - '"' + number + '"'); - } - } - } + // first sort by magnitude + // it's easier if all magnitudes are positive + var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE); + var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS); - function checkQueryParseError(options, fun) { - var startkeyName = options.descending ? 'endkey' : 'startkey'; - var endkeyName = options.descending ? 'startkey' : 'endkey'; + result += SEP + magString; - if (typeof options[startkeyName] !== 'undefined' && - typeof options[endkeyName] !== 'undefined' && - collate(options[startkeyName], options[endkeyName]) > 0) { - throw new QueryParseError('No rows can match your key range, ' + - 'reverse your start_key and end_key or set {descending : true}'); - } else if (fun.reduce && options.reduce !== false) { - if (options.include_docs) { - throw new QueryParseError('{include_docs:true} is invalid for reduce'); - } else if (options.keys && options.keys.length > 1 && - !options.group && !options.group_level) { - throw new QueryParseError('Multi-key fetches for reduce views must use ' + - '{group: true}'); - } - } - ['group_level', 'limit', 'skip'].forEach(function (optionName) { - var error = checkPositiveInteger(options[optionName]); - if (error) { - throw error; - } - }); + // then sort by the factor + var factor = Math.abs(parseFloat(expFormat[0])); // [1..10) + /* istanbul ignore next */ + if (neg) { // for negative reverse ordering + factor = 10 - factor; } - function httpQuery(db, fun, opts) { - // List of parameters to add to the PUT request - var params = []; - var body; - var method = 'GET'; - var ok, status; - - // If opts.reduce exists and is defined, then add it to the list - // of parameters. - // If reduce=false then the results are that of only the map function - // not the final result of map and reduce. - addHttpParam('reduce', opts, params); - addHttpParam('include_docs', opts, params); - addHttpParam('attachments', opts, params); - addHttpParam('limit', opts, params); - addHttpParam('descending', opts, params); - addHttpParam('group', opts, params); - addHttpParam('group_level', opts, params); - addHttpParam('skip', opts, params); - addHttpParam('stale', opts, params); - addHttpParam('conflicts', opts, params); - addHttpParam('startkey', opts, params, true); - addHttpParam('start_key', opts, params, true); - addHttpParam('endkey', opts, params, true); - addHttpParam('end_key', opts, params, true); - addHttpParam('inclusive_end', opts, params); - addHttpParam('key', opts, params, true); - addHttpParam('update_seq', opts, params); + var factorStr = factor.toFixed(20); - // Format the list of parameters into a valid URI query string - params = params.join('&'); - params = params === '' ? '' : '?' + params; + // strip zeros from the end + factorStr = factorStr.replace(/\.?0+$/, ''); - // If keys are supplied, issue a POST to circumvent GET query string limits - // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options - if (typeof opts.keys !== 'undefined') { - var MAX_URL_LENGTH = 2000; - // according to http://stackoverflow.com/a/417184/680742, - // the de facto URL length limit is 2000 characters + result += SEP + factorStr; - var keysAsString = - 'keys=' + encodeURIComponent(JSON.stringify(opts.keys)); - if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) { - // If the keys are short enough, do a GET. we do this to work around - // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239) - params += (params[0] === '?' ? '&' : '?') + keysAsString; - } else { - method = 'POST'; - if (typeof fun === 'string') { - body = {keys: opts.keys}; - } else { // fun is {map : mapfun}, so append to this - fun.keys = opts.keys; - } - } - } + return result; +} - // We are referencing a query defined in the design doc - if (typeof fun === 'string') { - var parts = parseViewName(fun); - return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, { - headers: new h({'Content-Type': 'application/json'}), - method: method, - body: JSON.stringify(body) - }).then(function (response) { - ok = response.ok; - status = response.status; - return response.json(); - }).then(function (result) { - if (!ok) { - result.status = status; - throw generateErrorFromResponse(result); - } - // fail the entire request if the result contains an error - result.rows.forEach(function (row) { - /* istanbul ignore if */ - if (row.value && row.value.error && row.value.error === "builtin_reduce_error") { - throw new Error(row.reason); - } - }); - return result; - }).then(postprocessAttachments(opts)); - } +// create a comparator based on the sort object +function createFieldSorter(sort) { - // We are using a temporary view, terrible for performance, good for testing - body = body || {}; - Object.keys(fun).forEach(function (key) { - if (Array.isArray(fun[key])) { - body[key] = fun[key]; - } else { - body[key] = fun[key].toString(); - } + function getFieldValuesAsArray(doc) { + return sort.map(function (sorting) { + var fieldName = getKey(sorting); + var parsedField = parseField(fieldName); + var docFieldValue = getFieldFromDoc(doc, parsedField); + return docFieldValue; }); - - return db.fetch('_temp_view' + params, { - headers: new h({'Content-Type': 'application/json'}), - method: 'POST', - body: JSON.stringify(body) - }).then(function (response) { - ok = response.ok; - status = response.status; - return response.json(); - }).then(function (result) { - if (!ok) { - result.status = status; - throw generateErrorFromResponse(result); - } - return result; - }).then(postprocessAttachments(opts)); } - // custom adapters can define their own api._query - // and override the default behavior - /* istanbul ignore next */ - function customQuery(db, fun, opts) { - return new Promise(function (resolve, reject) { - db._query(fun, opts, function (err, res) { - if (err) { - return reject(err); - } - resolve(res); - }); - }); - } + return function (aRow, bRow) { + var aFieldValues = getFieldValuesAsArray(aRow.doc); + var bFieldValues = getFieldValuesAsArray(bRow.doc); + var collation = collate(aFieldValues, bFieldValues); + if (collation !== 0) { + return collation; + } + // this is what mango seems to do + return compare$1(aRow.doc._id, bRow.doc._id); + }; +} - // custom adapters can define their own api._viewCleanup - // and override the default behavior - /* istanbul ignore next */ - function customViewCleanup(db) { - return new Promise(function (resolve, reject) { - db._viewCleanup(function (err, res) { - if (err) { - return reject(err); - } - resolve(res); - }); - }); - } +function filterInMemoryFields(rows, requestDef, inMemoryFields) { + rows = rows.filter(function (row) { + return rowFilter(row.doc, requestDef.selector, inMemoryFields); + }); - function defaultsTo(value) { - return function (reason) { - /* istanbul ignore else */ - if (reason.status === 404) { - return value; - } else { - throw reason; - } - }; + if (requestDef.sort) { + // in-memory sort + var fieldSorter = createFieldSorter(requestDef.sort); + rows = rows.sort(fieldSorter); + if (typeof requestDef.sort[0] !== 'string' && + getValue(requestDef.sort[0]) === 'desc') { + rows = rows.reverse(); + } } - // returns a promise for a list of docs to update, based on the input docId. - // the order doesn't matter, because post-3.2.0, bulkDocs - // is an atomic operation in all three adapters. - function getDocsToPersist(docId, view, docIdsToChangesAndEmits) { - var metaDocId = '_local/doc_' + docId; - var defaultMetaDoc = {_id: metaDocId, keys: []}; - var docData = docIdsToChangesAndEmits.get(docId); - var indexableKeysToKeyValues = docData[0]; - var changes = docData[1]; + if ('limit' in requestDef || 'skip' in requestDef) { + // have to do the limit in-memory + var skip = requestDef.skip || 0; + var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip; + rows = rows.slice(skip, limit); + } + return rows; +} - function getMetaDoc() { - if (isGenOne(changes)) { - // generation 1, so we can safely assume initial state - // for performance reasons (avoids unnecessary GETs) - return Promise.resolve(defaultMetaDoc); - } - return view.db.get(metaDocId).catch(defaultsTo(defaultMetaDoc)); +function rowFilter(doc, selector, inMemoryFields) { + return inMemoryFields.every(function (field) { + var matcher = selector[field]; + var parsedField = parseField(field); + var docFieldValue = getFieldFromDoc(doc, parsedField); + if (isCombinationalField(field)) { + return matchCominationalSelector(field, matcher, doc); } - function getKeyValueDocs(metaDoc) { - if (!metaDoc.keys.length) { - // no keys, no need for a lookup - return Promise.resolve({rows: []}); - } - return view.db.allDocs({ - keys: metaDoc.keys, - include_docs: true - }); - } + return matchSelector(matcher, doc, parsedField, docFieldValue); + }); +} - function processKeyValueDocs(metaDoc, kvDocsRes) { - var kvDocs = []; - var oldKeys = new ExportedSet(); +function matchSelector(matcher, doc, parsedField, docFieldValue) { + if (!matcher) { + // no filtering necessary; this field is just needed for sorting + return true; + } - for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) { - var row = kvDocsRes.rows[i]; - var doc = row.doc; - if (!doc) { // deleted - continue; - } - kvDocs.push(doc); - oldKeys.add(doc._id); - doc._deleted = !indexableKeysToKeyValues.has(doc._id); - if (!doc._deleted) { - var keyValue = indexableKeysToKeyValues.get(doc._id); - if ('value' in keyValue) { - doc.value = keyValue.value; - } - } - } - var newKeys = mapToKeysArray(indexableKeysToKeyValues); - newKeys.forEach(function (key) { - if (!oldKeys.has(key)) { - // new doc - var kvDoc = { - _id: key - }; - var keyValue = indexableKeysToKeyValues.get(key); - if ('value' in keyValue) { - kvDoc.value = keyValue.value; - } - kvDocs.push(kvDoc); - } - }); - metaDoc.keys = uniq(newKeys.concat(metaDoc.keys)); - kvDocs.push(metaDoc); + return Object.keys(matcher).every(function (userOperator) { + var userValue = matcher[userOperator]; + return match(userOperator, doc, userValue, parsedField, docFieldValue); + }); +} - return kvDocs; - } +function matchCominationalSelector(field, matcher, doc) { - return getMetaDoc().then(function (metaDoc) { - return getKeyValueDocs(metaDoc).then(function (kvDocsRes) { - return processKeyValueDocs(metaDoc, kvDocsRes); - }); + if (field === '$or') { + return matcher.some(function (orMatchers) { + return rowFilter(doc, orMatchers, Object.keys(orMatchers)); }); } - // updates all emitted key/value docs and metaDocs in the mrview database - // for the given batch of documents from the source database - function saveKeyValues(view, docIdsToChangesAndEmits, seq) { - var seqDocId = '_local/lastSeq'; - return view.db.get(seqDocId) - .catch(defaultsTo({_id: seqDocId, seq: 0})) - .then(function (lastSeqDoc) { - var docIds = mapToKeysArray(docIdsToChangesAndEmits); - return Promise.all(docIds.map(function (docId) { - return getDocsToPersist(docId, view, docIdsToChangesAndEmits); - })).then(function (listOfDocsToPersist) { - var docsToPersist = flatten(listOfDocsToPersist); - lastSeqDoc.seq = seq; - docsToPersist.push(lastSeqDoc); - // write all docs in a single operation, update the seq once - return view.db.bulkDocs({docs : docsToPersist}); - }); - }); + if (field === '$not') { + return !rowFilter(doc, matcher, Object.keys(matcher)); } - function getQueue(view) { - var viewName = typeof view === 'string' ? view : view.name; - var queue = persistentQueues[viewName]; - if (!queue) { - queue = persistentQueues[viewName] = new TaskQueue$1(); - } - return queue; - } + //`$nor` + return !matcher.find(function (orMatchers) { + return rowFilter(doc, orMatchers, Object.keys(orMatchers)); + }); - function updateView(view) { - return sequentialize(getQueue(view), function () { - return updateViewInQueue(view); - })(); +} + +function match(userOperator, doc, userValue, parsedField, docFieldValue) { + if (!matchers[userOperator]) { + throw new Error('unknown operator "' + userOperator + + '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' + + '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all'); } + return matchers[userOperator](doc, userValue, parsedField, docFieldValue); +} - function updateViewInQueue(view) { - // bind the emit function once - var mapResults; - var doc; +function fieldExists(docFieldValue) { + return typeof docFieldValue !== 'undefined' && docFieldValue !== null; +} - function emit(key, value) { - var output = {id: doc._id, key: normalizeKey(key)}; - // Don't explicitly store the value unless it's defined and non-null. - // This saves on storage space, because often people don't use it. - if (typeof value !== 'undefined' && value !== null) { - output.value = normalizeKey(value); - } - mapResults.push(output); - } +function fieldIsNotUndefined(docFieldValue) { + return typeof docFieldValue !== 'undefined'; +} - var mapFun = mapper(view.mapFun, emit); +function modField(docFieldValue, userValue) { + var divisor = userValue[0]; + var mod = userValue[1]; + if (divisor === 0) { + throw new Error('Bad divisor, cannot divide by zero'); + } - var currentSeq = view.seq || 0; + if (parseInt(divisor, 10) !== divisor ) { + throw new Error('Divisor is not an integer'); + } - function processChange(docIdsToChangesAndEmits, seq) { - return function () { - return saveKeyValues(view, docIdsToChangesAndEmits, seq); - }; - } + if (parseInt(mod, 10) !== mod ) { + throw new Error('Modulus is not an integer'); + } - var queue = new TaskQueue$1(); + if (parseInt(docFieldValue, 10) !== docFieldValue) { + return false; + } - function processNextBatch() { - return view.sourceDB.changes({ - return_docs: true, - conflicts: true, - include_docs: true, - style: 'all_docs', - since: currentSeq, - limit: CHANGES_BATCH_SIZE$1 - }).then(processBatch); - } + return docFieldValue % divisor === mod; +} - function processBatch(response) { - var results = response.results; - if (!results.length) { - return; - } - var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results); - queue.add(processChange(docIdsToChangesAndEmits, currentSeq)); - if (results.length < CHANGES_BATCH_SIZE$1) { - return; - } - return processNextBatch(); +function arrayContainsValue(docFieldValue, userValue) { + return userValue.some(function (val) { + if (docFieldValue instanceof Array) { + return docFieldValue.indexOf(val) > -1; } - function createDocIdsToChangesAndEmits(results) { - var docIdsToChangesAndEmits = new ExportedMap(); - for (var i = 0, len = results.length; i < len; i++) { - var change = results[i]; - if (change.doc._id[0] !== '_') { - mapResults = []; - doc = change.doc; + return docFieldValue === val; + }); +} - if (!doc._deleted) { - tryMap(view.sourceDB, mapFun, doc); - } - mapResults.sort(sortByKeyThenValue); +function arrayContainsAllValues(docFieldValue, userValue) { + return userValue.every(function (val) { + return docFieldValue.indexOf(val) > -1; + }); +} - var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults); - docIdsToChangesAndEmits.set(change.doc._id, [ - indexableKeysToKeyValues, - change.changes - ]); - } - currentSeq = change.seq; - } - return docIdsToChangesAndEmits; - } +function arraySize(docFieldValue, userValue) { + return docFieldValue.length === userValue; +} - function createIndexableKeysToKeyValues(mapResults) { - var indexableKeysToKeyValues = new ExportedMap(); - var lastKey; - for (var i = 0, len = mapResults.length; i < len; i++) { - var emittedKeyValue = mapResults[i]; - var complexKey = [emittedKeyValue.key, emittedKeyValue.id]; - if (i > 0 && collate(emittedKeyValue.key, lastKey) === 0) { - complexKey.push(i); // dup key+id, so make it unique - } - indexableKeysToKeyValues.set(toIndexableString(complexKey), emittedKeyValue); - lastKey = emittedKeyValue.key; - } - return indexableKeysToKeyValues; - } +function regexMatch(docFieldValue, userValue) { + var re = new RegExp(userValue); - return processNextBatch().then(function () { - return queue.finish(); - }).then(function () { - view.seq = currentSeq; - }); - } + return re.test(docFieldValue); +} - function reduceView(view, results, options) { - if (options.group_level === 0) { - delete options.group_level; - } +function typeMatch(docFieldValue, userValue) { - var shouldGroup = options.group || options.group_level; + switch (userValue) { + case 'null': + return docFieldValue === null; + case 'boolean': + return typeof (docFieldValue) === 'boolean'; + case 'number': + return typeof (docFieldValue) === 'number'; + case 'string': + return typeof (docFieldValue) === 'string'; + case 'array': + return docFieldValue instanceof Array; + case 'object': + return ({}).toString.call(docFieldValue) === '[object Object]'; + } - var reduceFun = reducer(view.reduceFun); + throw new Error(userValue + ' not supported as a type.' + + 'Please use one of object, string, array, number, boolean or null.'); - var groups = []; - var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY : - options.group_level; - results.forEach(function (e) { - var last = groups[groups.length - 1]; - var groupKey = shouldGroup ? e.key : null; +} - // only set group_level for array keys - if (shouldGroup && Array.isArray(groupKey)) { - groupKey = groupKey.slice(0, lvl); - } +var matchers = { - if (last && collate(last.groupKey, groupKey) === 0) { - last.keys.push([e.key, e.id]); - last.values.push(e.value); - return; - } - groups.push({ - keys: [[e.key, e.id]], - values: [e.value], - groupKey: groupKey - }); - }); - results = []; - for (var i = 0, len = groups.length; i < len; i++) { - var e = groups[i]; - var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false); - if (reduceTry.error && reduceTry.error instanceof BuiltInError) { - // CouchDB returns an error if a built-in errors out - throw reduceTry.error; - } - results.push({ - // CouchDB just sets the value to null if a non-built-in errors out - value: reduceTry.error ? null : reduceTry.output, - key: e.groupKey - }); + '$elemMatch': function (doc, userValue, parsedField, docFieldValue) { + if (!Array.isArray(docFieldValue)) { + return false; } - // no total_rows/offset when reducing - return {rows: sliceResults(results, options.limit, options.skip)}; - } - - function queryView(view, opts) { - return sequentialize(getQueue(view), function () { - return queryViewInQueue(view, opts); - })(); - } - function queryViewInQueue(view, opts) { - var totalRows; - var shouldReduce = view.reduceFun && opts.reduce !== false; - var skip = opts.skip || 0; - if (typeof opts.keys !== 'undefined' && !opts.keys.length) { - // equivalent query - opts.limit = 0; - delete opts.keys; + if (docFieldValue.length === 0) { + return false; } - function fetchFromView(viewOpts) { - viewOpts.include_docs = true; - return view.db.allDocs(viewOpts).then(function (res) { - totalRows = res.total_rows; - return res.rows.map(function (result) { - - // implicit migration - in older versions of PouchDB, - // we explicitly stored the doc as {id: ..., key: ..., value: ...} - // this is tested in a migration test - /* istanbul ignore next */ - if ('value' in result.doc && typeof result.doc.value === 'object' && - result.doc.value !== null) { - var keys = Object.keys(result.doc.value).sort(); - // this detection method is not perfect, but it's unlikely the user - // emitted a value which was an object with these 3 exact keys - var expectedKeys = ['id', 'key', 'value']; - if (!(keys < expectedKeys || keys > expectedKeys)) { - return result.doc.value; - } - } - - var parsedKeyAndDocId = parseIndexableString(result.doc._id); - return { - key: parsedKeyAndDocId[0], - id: parsedKeyAndDocId[1], - value: ('value' in result.doc ? result.doc.value : null) - }; - }); + if (typeof docFieldValue[0] === 'object') { + return docFieldValue.some(function (val) { + return rowFilter(val, userValue, Object.keys(userValue)); }); } - function onMapResultsReady(rows) { - var finalResults; - if (shouldReduce) { - finalResults = reduceView(view, rows, opts); - } else { - finalResults = { - total_rows: totalRows, - offset: skip, - rows: rows - }; - } - /* istanbul ignore if */ - if (opts.update_seq) { - finalResults.update_seq = view.seq; - } - if (opts.include_docs) { - var docIds = uniq(rows.map(rowToDocId)); + return docFieldValue.some(function (val) { + return matchSelector(userValue, doc, parsedField, val); + }); + }, - return view.sourceDB.allDocs({ - keys: docIds, - include_docs: true, - conflicts: opts.conflicts, - attachments: opts.attachments, - binary: opts.binary - }).then(function (allDocsRes) { - var docIdsToDocs = new ExportedMap(); - allDocsRes.rows.forEach(function (row) { - docIdsToDocs.set(row.id, row.doc); - }); - rows.forEach(function (row) { - var docId = rowToDocId(row); - var doc = docIdsToDocs.get(docId); - if (doc) { - row.doc = doc; - } - }); - return finalResults; - }); - } else { - return finalResults; - } + '$allMatch': function (doc, userValue, parsedField, docFieldValue) { + if (!Array.isArray(docFieldValue)) { + return false; } - if (typeof opts.keys !== 'undefined') { - var keys = opts.keys; - var fetchPromises = keys.map(function (key) { - var viewOpts = { - startkey : toIndexableString([key]), - endkey : toIndexableString([key, {}]) - }; - /* istanbul ignore if */ - if (opts.update_seq) { - viewOpts.update_seq = true; - } - return fetchFromView(viewOpts); - }); - return Promise.all(fetchPromises).then(flatten).then(onMapResultsReady); - } else { // normal query, no 'keys' - var viewOpts = { - descending : opts.descending - }; - /* istanbul ignore if */ - if (opts.update_seq) { - viewOpts.update_seq = true; - } - var startkey; - var endkey; - if ('start_key' in opts) { - startkey = opts.start_key; - } - if ('startkey' in opts) { - startkey = opts.startkey; - } - if ('end_key' in opts) { - endkey = opts.end_key; - } - if ('endkey' in opts) { - endkey = opts.endkey; - } - if (typeof startkey !== 'undefined') { - viewOpts.startkey = opts.descending ? - toIndexableString([startkey, {}]) : - toIndexableString([startkey]); - } - if (typeof endkey !== 'undefined') { - var inclusiveEnd = opts.inclusive_end !== false; - if (opts.descending) { - inclusiveEnd = !inclusiveEnd; - } + /* istanbul ignore next */ + if (docFieldValue.length === 0) { + return false; + } - viewOpts.endkey = toIndexableString( - inclusiveEnd ? [endkey, {}] : [endkey]); - } - if (typeof opts.key !== 'undefined') { - var keyStart = toIndexableString([opts.key]); - var keyEnd = toIndexableString([opts.key, {}]); - if (viewOpts.descending) { - viewOpts.endkey = keyStart; - viewOpts.startkey = keyEnd; - } else { - viewOpts.startkey = keyStart; - viewOpts.endkey = keyEnd; - } - } - if (!shouldReduce) { - if (typeof opts.limit === 'number') { - viewOpts.limit = opts.limit; - } - viewOpts.skip = skip; - } - return fetchFromView(viewOpts).then(onMapResultsReady); + if (typeof docFieldValue[0] === 'object') { + return docFieldValue.every(function (val) { + return rowFilter(val, userValue, Object.keys(userValue)); + }); } - } - function httpViewCleanup(db) { - return db.fetch('_view_cleanup', { - headers: new h({'Content-Type': 'application/json'}), - method: 'POST' - }).then(function (response) { - return response.json(); + return docFieldValue.every(function (val) { + return matchSelector(userValue, doc, parsedField, val); }); - } - - function localViewCleanup(db) { - return db.get('_local/' + localDocName).then(function (metaDoc) { - var docsToViews = new ExportedMap(); - Object.keys(metaDoc.views).forEach(function (fullViewName) { - var parts = parseViewName(fullViewName); - var designDocName = '_design/' + parts[0]; - var viewName = parts[1]; - var views = docsToViews.get(designDocName); - if (!views) { - views = new ExportedSet(); - docsToViews.set(designDocName, views); - } - views.add(viewName); - }); - var opts = { - keys : mapToKeysArray(docsToViews), - include_docs : true - }; - return db.allDocs(opts).then(function (res) { - var viewsToStatus = {}; - res.rows.forEach(function (row) { - var ddocName = row.key.substring(8); // cuts off '_design/' - docsToViews.get(row.key).forEach(function (viewName) { - var fullViewName = ddocName + '/' + viewName; - /* istanbul ignore if */ - if (!metaDoc.views[fullViewName]) { - // new format, without slashes, to support PouchDB 2.2.0 - // migration test in pouchdb's browser.migration.js verifies this - fullViewName = viewName; - } - var viewDBNames = Object.keys(metaDoc.views[fullViewName]); - // design doc deleted, or view function nonexistent - var statusIsGood = row.doc && row.doc.views && - row.doc.views[viewName]; - viewDBNames.forEach(function (viewDBName) { - viewsToStatus[viewDBName] = - viewsToStatus[viewDBName] || statusIsGood; - }); - }); - }); - var dbsToDelete = Object.keys(viewsToStatus).filter( - function (viewDBName) { return !viewsToStatus[viewDBName]; }); - var destroyPromises = dbsToDelete.map(function (viewDBName) { - return sequentialize(getQueue(viewDBName), function () { - return new db.constructor(viewDBName, db.__opts).destroy(); - })(); - }); - return Promise.all(destroyPromises).then(function () { - return {ok: true}; - }); - }); - }, defaultsTo({ok: true})); - } + }, - function queryPromised(db, fun, opts) { - /* istanbul ignore next */ - if (typeof db._query === 'function') { - return customQuery(db, fun, opts); - } - if (isRemote(db)) { - return httpQuery(db, fun, opts); - } + '$eq': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) === 0; + }, - if (typeof fun !== 'string') { - // temp_view - checkQueryParseError(opts, fun); + '$gte': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) >= 0; + }, - tempViewQueue.add(function () { - var createViewPromise = createView( - /* sourceDB */ db, - /* viewName */ 'temp_view/temp_view', - /* mapFun */ fun.map, - /* reduceFun */ fun.reduce, - /* temporary */ true, - /* localDocName */ localDocName); - return createViewPromise.then(function (view) { - return fin(updateView(view).then(function () { - return queryView(view, opts); - }), function () { - return view.db.destroy(); - }); - }); - }); - return tempViewQueue.finish(); - } else { - // persistent view - var fullViewName = fun; - var parts = parseViewName(fullViewName); - var designDocName = parts[0]; - var viewName = parts[1]; - return db.get('_design/' + designDocName).then(function (doc) { - var fun = doc.views && doc.views[viewName]; + '$gt': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) > 0; + }, - if (!fun) { - // basic validator; it's assumed that every subclass would want this - throw new NotFoundError('ddoc ' + doc._id + ' has no view named ' + - viewName); - } + '$lte': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) <= 0; + }, - ddocValidator(doc, viewName); - checkQueryParseError(opts, fun); + '$lt': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) < 0; + }, - var createViewPromise = createView( - /* sourceDB */ db, - /* viewName */ fullViewName, - /* mapFun */ fun.map, - /* reduceFun */ fun.reduce, - /* temporary */ false, - /* localDocName */ localDocName); - return createViewPromise.then(function (view) { - if (opts.stale === 'ok' || opts.stale === 'update_after') { - if (opts.stale === 'update_after') { - immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { - updateView(view); - }); - } - return queryView(view, opts); - } else { // stale not ok - return updateView(view).then(function () { - return queryView(view, opts); - }); - } - }); - }); + '$exists': function (doc, userValue, parsedField, docFieldValue) { + //a field that is null is still considered to exist + if (userValue) { + return fieldIsNotUndefined(docFieldValue); } - } - function abstractQuery(fun, opts, callback) { - var db = this; - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - opts = opts ? coerceOptions(opts) : {}; + return !fieldIsNotUndefined(docFieldValue); + }, - if (typeof fun === 'function') { - fun = {map : fun}; - } + '$mod': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && modField(docFieldValue, userValue); + }, - var promise = Promise.resolve().then(function () { - return queryPromised(db, fun, opts); + '$ne': function (doc, userValue, parsedField, docFieldValue) { + return userValue.every(function (neValue) { + return collate(docFieldValue, neValue) !== 0; }); - promisedCallback(promise, callback); - return promise; - } - - var abstractViewCleanup = callbackify(function () { - var db = this; - /* istanbul ignore next */ - if (typeof db._viewCleanup === 'function') { - return customViewCleanup(db); - } - if (isRemote(db)) { - return httpViewCleanup(db); - } - return localViewCleanup(db); - }); + }, + '$in': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue); + }, - return { - query: abstractQuery, - viewCleanup: abstractViewCleanup - }; -} + '$nin': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue); + }, -var builtInReduce = { - _sum: function (keys, values) { - return sum(values); + '$size': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue); }, - _count: function (keys, values) { - return values.length; + '$all': function (doc, userValue, parsedField, docFieldValue) { + return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue); }, - _stats: function (keys, values) { - // no need to implement rereduce=true, because Pouch - // will never call it - function sumsqr(values) { - var _sumsqr = 0; - for (var i = 0, len = values.length; i < len; i++) { - var num = values[i]; - _sumsqr += (num * num); - } - return _sumsqr; - } - return { - sum : sum(values), - min : Math.min.apply(null, values), - max : Math.max.apply(null, values), - count : values.length, - sumsqr : sumsqr(values) - }; + '$regex': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue); + }, + + '$type': function (doc, userValue, parsedField, docFieldValue) { + return typeMatch(docFieldValue, userValue); } }; -function getBuiltIn(reduceFunString) { - if (/^_sum/.test(reduceFunString)) { - return builtInReduce._sum; - } else if (/^_count/.test(reduceFunString)) { - return builtInReduce._count; - } else if (/^_stats/.test(reduceFunString)) { - return builtInReduce._stats; - } else if (/^_/.test(reduceFunString)) { - throw new Error(reduceFunString + ' is not a supported reduce function.'); +// return true if the given doc matches the supplied selector +function matchesSelector(doc, selector) { + /* istanbul ignore if */ + if (typeof selector !== 'object') { + // match the CouchDB error message + throw new Error('Selector error: expected a JSON object'); } + + selector = massageSelector(selector); + var row = { + 'doc': doc + }; + + var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector)); + return rowsMatched && rowsMatched.length === 1; } -function mapper(mapFun, emit) { - // for temp_views one can use emit(doc, emit), see #38 - if (typeof mapFun === "function" && mapFun.length === 2) { - var origMap = mapFun; - return function (doc) { - return origMap(doc, emit); - }; - } else { - return evalFunctionWithEval(mapFun.toString(), emit); - } +function evalFilter(input) { + return scopeEval('"use strict";\nreturn ' + input + ';', {}); } -function reducer(reduceFun) { - var reduceFunString = reduceFun.toString(); - var builtIn = getBuiltIn(reduceFunString); - if (builtIn) { - return builtIn; - } else { - return evalFunctionWithEval(reduceFunString); +function evalView(input) { + var code = [ + 'return function(doc) {', + ' "use strict";', + ' var emitted = false;', + ' var emit = function (a, b) {', + ' emitted = true;', + ' };', + ' var view = ' + input + ';', + ' view(doc);', + ' if (emitted) {', + ' return true;', + ' }', + '};' + ].join('\n'); + + return scopeEval(code, {}); +} + +function validate(opts, callback) { + if (opts.selector) { + if (opts.filter && opts.filter !== '_selector') { + var filterName = typeof opts.filter === 'string' ? + opts.filter : 'function'; + return callback(new Error('selector invalid for filter "' + filterName + '"')); + } } + callback(); } -function ddocValidator(ddoc, viewName) { - var fun = ddoc.views && ddoc.views[viewName]; - if (typeof fun.map !== 'string') { - throw new NotFoundError('ddoc ' + ddoc._id + ' has no string view named ' + - viewName + ', instead found object of type: ' + typeof fun.map); +function normalize(opts) { + if (opts.view && !opts.filter) { + opts.filter = '_view'; + } + + if (opts.selector && !opts.filter) { + opts.filter = '_selector'; + } + + if (opts.filter && typeof opts.filter === 'string') { + if (opts.filter === '_view') { + opts.view = normalizeDesignDocFunctionName(opts.view); + } else { + opts.filter = normalizeDesignDocFunctionName(opts.filter); + } } } -var localDocName = 'mrviews'; -var abstract = createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator); +function shouldFilter(changesHandler, opts) { + return opts.filter && typeof opts.filter === 'string' && + !opts.doc_ids && !isRemote(changesHandler.db); +} -function query(fun, opts, callback) { - return abstract.query.call(this, fun, opts, callback); +function filter(changesHandler, opts) { + var callback = opts.complete; + if (opts.filter === '_view') { + if (!opts.view || typeof opts.view !== 'string') { + var err = createError(BAD_REQUEST, + '`view` filter parameter not found or invalid.'); + return callback(err); + } + // fetch a view from a design doc, make it behave like a filter + var viewName = parseDesignDocFunctionName(opts.view); + changesHandler.db.get('_design/' + viewName[0], function (err, ddoc) { + /* istanbul ignore if */ + if (changesHandler.isCancelled) { + return callback(null, {status: 'cancelled'}); + } + /* istanbul ignore next */ + if (err) { + return callback(generateErrorFromResponse(err)); + } + var mapFun = ddoc && ddoc.views && ddoc.views[viewName[1]] && + ddoc.views[viewName[1]].map; + if (!mapFun) { + return callback(createError(MISSING_DOC, + (ddoc.views ? 'missing json key: ' + viewName[1] : + 'missing json key: views'))); + } + opts.filter = evalView(mapFun); + changesHandler.doChanges(opts); + }); + } else if (opts.selector) { + opts.filter = function (doc) { + return matchesSelector(doc, opts.selector); + }; + changesHandler.doChanges(opts); + } else { + // fetch a filter from a design doc + var filterName = parseDesignDocFunctionName(opts.filter); + changesHandler.db.get('_design/' + filterName[0], function (err, ddoc) { + /* istanbul ignore if */ + if (changesHandler.isCancelled) { + return callback(null, {status: 'cancelled'}); + } + /* istanbul ignore next */ + if (err) { + return callback(generateErrorFromResponse(err)); + } + var filterFun = ddoc && ddoc.filters && ddoc.filters[filterName[1]]; + if (!filterFun) { + return callback(createError(MISSING_DOC, + ((ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1] + : 'missing json key: filters'))); + } + opts.filter = evalFilter(filterFun); + changesHandler.doChanges(opts); + }); + } } -function viewCleanup(callback) { - return abstract.viewCleanup.call(this, callback); +function applyChangesFilterPlugin(PouchDB) { + PouchDB._changesFilterPlugin = { + validate: validate, + normalize: normalize, + shouldFilter: shouldFilter, + filter: filter + }; } -var mapreduce = { - query: query, - viewCleanup: viewCleanup -}; +// TODO: remove from pouchdb-core (breaking) +PouchDB.plugin(applyChangesFilterPlugin); -function isGenOne$1(rev) { - return /^1-/.test(rev); +PouchDB.version = version; + +function toObject(array) { + return array.reduce(function (obj, item) { + obj[item] = true; + return obj; + }, {}); } +// List of top level reserved words for doc +var reservedWords = toObject([ + '_id', + '_rev', + '_attachments', + '_deleted', + '_revisions', + '_revs_info', + '_conflicts', + '_deleted_conflicts', + '_local_seq', + '_rev_tree', + //replication documents + '_replication_id', + '_replication_state', + '_replication_state_time', + '_replication_state_reason', + '_replication_stats', + // Specific to Couchbase Sync Gateway + '_removed' +]); -function fileHasChanged(localDoc, remoteDoc, filename) { - return !localDoc._attachments || - !localDoc._attachments[filename] || - localDoc._attachments[filename].digest !== remoteDoc._attachments[filename].digest; +// List of reserved words that should end up the document +var dataWords = toObject([ + '_attachments', + //replication documents + '_replication_id', + '_replication_state', + '_replication_state_time', + '_replication_state_reason', + '_replication_stats' +]); + +function parseRevisionInfo(rev) { + if (!/^\d+-./.test(rev)) { + return createError(INVALID_REV); + } + var idx = rev.indexOf('-'); + var left = rev.substring(0, idx); + var right = rev.substring(idx + 1); + return { + prefix: parseInt(left, 10), + id: right + }; } -function getDocAttachments(db, doc) { - var filenames = Object.keys(doc._attachments); - return Promise.all(filenames.map(function (filename) { - return db.getAttachment(doc._id, filename, {rev: doc._rev}); - })); +function makeRevTreeFromRevisions(revisions, opts) { + var pos = revisions.start - revisions.ids.length + 1; + + var revisionIds = revisions.ids; + var ids = [revisionIds[0], opts, []]; + + for (var i = 1, len = revisionIds.length; i < len; i++) { + ids = [revisionIds[i], {status: 'missing'}, [ids]]; + } + + return [{ + pos: pos, + ids: ids + }]; } -function getDocAttachmentsFromTargetOrSource(target, src, doc) { - var doCheckForLocalAttachments = isRemote(src) && !isRemote(target); - var filenames = Object.keys(doc._attachments); +// Preprocess documents, parse their revisions, assign an id and a +// revision for new writes that are missing them, etc +function parseDoc(doc, newEdits, dbOpts) { + if (!dbOpts) { + dbOpts = { + deterministic_revs: true + }; + } - if (!doCheckForLocalAttachments) { - return getDocAttachments(src, doc); + var nRevNum; + var newRevId; + var revInfo; + var opts = {status: 'available'}; + if (doc._deleted) { + opts.deleted = true; } - return target.get(doc._id).then(function (localDoc) { - return Promise.all(filenames.map(function (filename) { - if (fileHasChanged(localDoc, doc, filename)) { - return src.getAttachment(doc._id, filename); + if (newEdits) { + if (!doc._id) { + doc._id = uuid(); + } + newRevId = rev$$1(doc, dbOpts.deterministic_revs); + if (doc._rev) { + revInfo = parseRevisionInfo(doc._rev); + if (revInfo.error) { + return revInfo; + } + doc._rev_tree = [{ + pos: revInfo.prefix, + ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]] + }]; + nRevNum = revInfo.prefix + 1; + } else { + doc._rev_tree = [{ + pos: 1, + ids : [newRevId, opts, []] + }]; + nRevNum = 1; + } + } else { + if (doc._revisions) { + doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts); + nRevNum = doc._revisions.start; + newRevId = doc._revisions.ids[0]; + } + if (!doc._rev_tree) { + revInfo = parseRevisionInfo(doc._rev); + if (revInfo.error) { + return revInfo; } + nRevNum = revInfo.prefix; + newRevId = revInfo.id; + doc._rev_tree = [{ + pos: nRevNum, + ids: [newRevId, opts, []] + }]; + } + } - return target.getAttachment(localDoc._id, filename); - })); - }).catch(function (error) { - /* istanbul ignore if */ - if (error.status !== 404) { - throw error; + invalidIdError(doc._id); + + doc._rev = nRevNum + '-' + newRevId; + + var result = {metadata : {}, data : {}}; + for (var key in doc) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(doc, key)) { + var specialKey = key[0] === '_'; + if (specialKey && !reservedWords[key]) { + var error = createError(DOC_VALIDATION, key); + error.message = DOC_VALIDATION.message + ': ' + key; + throw error; + } else if (specialKey && !dataWords[key]) { + result.metadata[key.slice(1)] = doc[key]; + } else { + result.data[key] = doc[key]; + } } + } + return result; +} - return getDocAttachments(src, doc); +function parseBase64(data) { + try { + return thisAtob(data); + } catch (e) { + var err = createError(BAD_ARG, + 'Attachment is not a valid base64 string'); + return {error: err}; + } +} + +function preprocessString(att, blobType, callback) { + var asBinary = parseBase64(att.data); + if (asBinary.error) { + return callback(asBinary.error); + } + + att.length = asBinary.length; + if (blobType === 'blob') { + att.data = binStringToBluffer(asBinary, att.content_type); + } else if (blobType === 'base64') { + att.data = thisBtoa(asBinary); + } else { // binary + att.data = asBinary; + } + binaryMd5(asBinary, function (result) { + att.digest = 'md5-' + result; + callback(); }); } -function createBulkGetOpts(diffs) { - var requests = []; - Object.keys(diffs).forEach(function (id) { - var missingRevs = diffs[id].missing; - missingRevs.forEach(function (missingRev) { - requests.push({ - id: id, - rev: missingRev +function preprocessBlob(att, blobType, callback) { + binaryMd5(att.data, function (md5) { + att.digest = 'md5-' + md5; + // size is for blobs (browser), length is for buffers (node) + att.length = att.data.size || att.data.length || 0; + if (blobType === 'binary') { + blobToBinaryString(att.data, function (binString) { + att.data = binString; + callback(); }); - }); + } else if (blobType === 'base64') { + blobToBase64(att.data, function (b64) { + att.data = b64; + callback(); + }); + } else { + callback(); + } }); +} - return { - docs: requests, - revs: true, - latest: true - }; +function preprocessAttachment(att, blobType, callback) { + if (att.stub) { + return callback(); + } + if (typeof att.data === 'string') { // input is a base64 string + preprocessString(att, blobType, callback); + } else { // input is a blob + preprocessBlob(att, blobType, callback); + } } -// -// Fetch all the documents from the src as described in the "diffs", -// which is a mapping of docs IDs to revisions. If the state ever -// changes to "cancelled", then the returned promise will be rejected. -// Else it will be resolved with a list of fetched documents. -// -function getDocs(src, target, diffs, state) { - diffs = clone(diffs); // we do not need to modify this +function preprocessAttachments(docInfos, blobType, callback) { - var resultDocs = [], - ok = true; + if (!docInfos.length) { + return callback(); + } - function getAllDocs() { + var docv = 0; + var overallErr; - var bulkGetOpts = createBulkGetOpts(diffs); + docInfos.forEach(function (docInfo) { + var attachments = docInfo.data && docInfo.data._attachments ? + Object.keys(docInfo.data._attachments) : []; + var recv = 0; - if (!bulkGetOpts.docs.length) { // optimization: skip empty requests - return; + if (!attachments.length) { + return done(); } - return src.bulkGet(bulkGetOpts).then(function (bulkGetResponse) { - /* istanbul ignore if */ - if (state.cancelled) { - throw new Error('cancelled'); + function processedAttachment(err) { + overallErr = err; + recv++; + if (recv === attachments.length) { + done(); } - return Promise.all(bulkGetResponse.results.map(function (bulkGetInfo) { - return Promise.all(bulkGetInfo.docs.map(function (doc) { - var remoteDoc = doc.ok; - - if (doc.error) { - // when AUTO_COMPACTION is set, docs can be returned which look - // like this: {"missing":"1-7c3ac256b693c462af8442f992b83696"} - ok = false; - } + } - if (!remoteDoc || !remoteDoc._attachments) { - return remoteDoc; - } + for (var key in docInfo.data._attachments) { + if (docInfo.data._attachments.hasOwnProperty(key)) { + preprocessAttachment(docInfo.data._attachments[key], + blobType, processedAttachment); + } + } + }); - return getDocAttachmentsFromTargetOrSource(target, src, remoteDoc) - .then(function (attachments) { - var filenames = Object.keys(remoteDoc._attachments); - attachments - .forEach(function (attachment, i) { - var att = remoteDoc._attachments[filenames[i]]; - delete att.stub; - delete att.length; - att.data = attachment; - }); + function done() { + docv++; + if (docInfos.length === docv) { + if (overallErr) { + callback(overallErr); + } else { + callback(); + } + } + } +} - return remoteDoc; - }); - })); - })) +function updateDoc(revLimit, prev, docInfo, results, + i, cb, writeDoc, newEdits) { - .then(function (results) { - resultDocs = resultDocs.concat(flatten(results).filter(Boolean)); - }); - }); + if (revExists(prev.rev_tree, docInfo.metadata.rev) && !newEdits) { + results[i] = docInfo; + return cb(); } - function hasAttachments(doc) { - return doc._attachments && Object.keys(doc._attachments).length > 0; - } + // sometimes this is pre-calculated. historically not always + var previousWinningRev = prev.winningRev || winningRev(prev); + var previouslyDeleted = 'deleted' in prev ? prev.deleted : + isDeleted(prev, previousWinningRev); + var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted : + isDeleted(docInfo.metadata); + var isRoot = /^1-/.test(docInfo.metadata.rev); - function hasConflicts(doc) { - return doc._conflicts && doc._conflicts.length > 0; + if (previouslyDeleted && !deleted && newEdits && isRoot) { + var newDoc = docInfo.data; + newDoc._rev = previousWinningRev; + newDoc._id = docInfo.metadata.id; + docInfo = parseDoc(newDoc, newEdits); } - function fetchRevisionOneDocs(ids) { - // Optimization: fetch gen-1 docs and attachments in - // a single request using _all_docs - return src.allDocs({ - keys: ids, - include_docs: true, - conflicts: true - }).then(function (res) { - if (state.cancelled) { - throw new Error('cancelled'); - } - res.rows.forEach(function (row) { - if (row.deleted || !row.doc || !isGenOne$1(row.value.rev) || - hasAttachments(row.doc) || hasConflicts(row.doc)) { - // if any of these conditions apply, we need to fetch using get() - return; - } + var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit); - // strip _conflicts array to appease CSG (#5793) - /* istanbul ignore if */ - if (row.doc._conflicts) { - delete row.doc._conflicts; - } + var inConflict = newEdits && (( + (previouslyDeleted && deleted && merged.conflicts !== 'new_leaf') || + (!previouslyDeleted && merged.conflicts !== 'new_leaf') || + (previouslyDeleted && !deleted && merged.conflicts === 'new_branch'))); - // the doc we got back from allDocs() is sufficient - resultDocs.push(row.doc); - delete diffs[row.id]; - }); - }); + if (inConflict) { + var err = createError(REV_CONFLICT); + results[i] = err; + return cb(); } - function getRevisionOneDocs() { - // filter out the generation 1 docs and get them - // leaving the non-generation one docs to be got otherwise - var ids = Object.keys(diffs).filter(function (id) { - var missing = diffs[id].missing; - return missing.length === 1 && isGenOne$1(missing[0]); - }); - if (ids.length > 0) { - return fetchRevisionOneDocs(ids); - } + var newRev = docInfo.metadata.rev; + docInfo.metadata.rev_tree = merged.tree; + docInfo.stemmedRevs = merged.stemmedRevs || []; + /* istanbul ignore else */ + if (prev.rev_map) { + docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb } - function returnResult() { - return { ok:ok, docs:resultDocs }; + // recalculate + var winningRev$$1 = winningRev(docInfo.metadata); + var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$1); + + // calculate the total number of documents that were added/removed, + // from the perspective of total_rows/doc_count + var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 : + previouslyDeleted < winningRevIsDeleted ? -1 : 1; + + var newRevIsDeleted; + if (newRev === winningRev$$1) { + // if the new rev is the same as the winning rev, we can reuse that value + newRevIsDeleted = winningRevIsDeleted; + } else { + // if they're not the same, then we need to recalculate + newRevIsDeleted = isDeleted(docInfo.metadata, newRev); } - return Promise.resolve() - .then(getRevisionOneDocs) - .then(getAllDocs) - .then(returnResult); + writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted, + true, delta, i, cb); } -var CHECKPOINT_VERSION = 1; -var REPLICATOR = "pouchdb"; -// This is an arbitrary number to limit the -// amount of replication history we save in the checkpoint. -// If we save too much, the checkpoing docs will become very big, -// if we save fewer, we'll run a greater risk of having to -// read all the changes from 0 when checkpoint PUTs fail -// CouchDB 2.0 has a more involved history pruning, -// but let's go for the simple version for now. -var CHECKPOINT_HISTORY_SIZE = 5; -var LOWEST_SEQ = 0; +function rootIsMissing(docInfo) { + return docInfo.metadata.rev_tree[0].ids[1].status === 'missing'; +} -function updateCheckpoint(db, id, checkpoint, session, returnValue) { - return db.get(id).catch(function (err) { - if (err.status === 404) { - if (db.adapter === 'http' || db.adapter === 'https') { - explainError( - 404, 'PouchDB is just checking if a remote checkpoint exists.' - ); - } - return { - session_id: session, - _id: id, - history: [], - replicator: REPLICATOR, - version: CHECKPOINT_VERSION - }; +function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results, + writeDoc, opts, overallCallback) { + + // Default to 1000 locally + revLimit = revLimit || 1000; + + function insertDoc(docInfo, resultsIdx, callback) { + // Cant insert new deleted documents + var winningRev$$1 = winningRev(docInfo.metadata); + var deleted = isDeleted(docInfo.metadata, winningRev$$1); + if ('was_delete' in opts && deleted) { + results[resultsIdx] = createError(MISSING_DOC, 'deleted'); + return callback(); } - throw err; - }).then(function (doc) { - if (returnValue.cancelled) { - return; + + // 4712 - detect whether a new document was inserted with a _rev + var inConflict = newEdits && rootIsMissing(docInfo); + + if (inConflict) { + var err = createError(REV_CONFLICT); + results[resultsIdx] = err; + return callback(); } - // if the checkpoint has not changed, do not update - if (doc.last_seq === checkpoint) { - return; + var delta = deleted ? 0 : 1; + + writeDoc(docInfo, winningRev$$1, deleted, deleted, false, + delta, resultsIdx, callback); + } + + var newEdits = opts.new_edits; + var idsToDocs = new ExportedMap(); + + var docsDone = 0; + var docsToDo = docInfos.length; + + function checkAllDocsDone() { + if (++docsDone === docsToDo && overallCallback) { + overallCallback(); } + } - // Filter out current entry for this replication - doc.history = (doc.history || []).filter(function (item) { - return item.session_id !== session; - }); + docInfos.forEach(function (currentDoc, resultsIdx) { - // Add the latest checkpoint to history - doc.history.unshift({ - last_seq: checkpoint, - session_id: session - }); + if (currentDoc._id && isLocalId(currentDoc._id)) { + var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal'; + api[fun](currentDoc, {ctx: tx}, function (err, res) { + results[resultsIdx] = err || res; + checkAllDocsDone(); + }); + return; + } - // Just take the last pieces in history, to - // avoid really big checkpoint docs. - // see comment on history size above - doc.history = doc.history.slice(0, CHECKPOINT_HISTORY_SIZE); + var id = currentDoc.metadata.id; + if (idsToDocs.has(id)) { + docsToDo--; // duplicate + idsToDocs.get(id).push([currentDoc, resultsIdx]); + } else { + idsToDocs.set(id, [[currentDoc, resultsIdx]]); + } + }); - doc.version = CHECKPOINT_VERSION; - doc.replicator = REPLICATOR; + // in the case of new_edits, the user can provide multiple docs + // with the same id. these need to be processed sequentially + idsToDocs.forEach(function (docs, id) { + var numDone = 0; - doc.session_id = session; - doc.last_seq = checkpoint; + function docWritten() { + if (++numDone < docs.length) { + nextDoc(); + } else { + checkAllDocsDone(); + } + } + function nextDoc() { + var value = docs[numDone]; + var currentDoc = value[0]; + var resultsIdx = value[1]; - return db.put(doc).catch(function (err) { - if (err.status === 409) { - // retry; someone is trying to write a checkpoint simultaneously - return updateCheckpoint(db, id, checkpoint, session, returnValue); + if (fetchedDocs.has(id)) { + updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results, + resultsIdx, docWritten, writeDoc, newEdits); + } else { + // Ensure stemming applies to new writes as well + var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit); + currentDoc.metadata.rev_tree = merged.tree; + currentDoc.stemmedRevs = merged.stemmedRevs || []; + insertDoc(currentDoc, resultsIdx, docWritten); } - throw err; - }); + } + nextDoc(); }); } -function Checkpointer(src, target, id, returnValue, opts) { - this.src = src; - this.target = target; - this.id = id; - this.returnValue = returnValue; - this.opts = opts || {}; -} +// IndexedDB requires a versioned database structure, so we use the +// version here to manage migrations. +var ADAPTER_VERSION = 5; -Checkpointer.prototype.writeCheckpoint = function (checkpoint, session) { - var self = this; - return this.updateTarget(checkpoint, session).then(function () { - return self.updateSource(checkpoint, session); - }); -}; +// The object stores created for each database +// DOC_STORE stores the document meta data, its revision history and state +// Keyed by document id +var DOC_STORE = 'document-store'; +// BY_SEQ_STORE stores a particular version of a document, keyed by its +// sequence id +var BY_SEQ_STORE = 'by-sequence'; +// Where we store attachments +var ATTACH_STORE = 'attach-store'; +// Where we store many-to-many relations +// between attachment digests and seqs +var ATTACH_AND_SEQ_STORE = 'attach-seq-store'; -Checkpointer.prototype.updateTarget = function (checkpoint, session) { - if (this.opts.writeTargetCheckpoint) { - return updateCheckpoint(this.target, this.id, checkpoint, - session, this.returnValue); - } else { - return Promise.resolve(true); +// Where we store database-wide meta data in a single record +// keyed by id: META_STORE +var META_STORE = 'meta-store'; +// Where we store local documents +var LOCAL_STORE = 'local-store'; +// Where we detect blob support +var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support'; + +function safeJsonParse(str) { + // This try/catch guards against stack overflow errors. + // JSON.parse() is faster than vuvuzela.parse() but vuvuzela + // cannot overflow. + try { + return JSON.parse(str); + } catch (e) { + /* istanbul ignore next */ + return vuvuzela__WEBPACK_IMPORTED_MODULE_6__.parse(str); } -}; +} -Checkpointer.prototype.updateSource = function (checkpoint, session) { - if (this.opts.writeSourceCheckpoint) { - var self = this; - return updateCheckpoint(this.src, this.id, checkpoint, - session, this.returnValue) - .catch(function (err) { - if (isForbiddenError(err)) { - self.opts.writeSourceCheckpoint = false; - return true; - } - throw err; - }); - } else { - return Promise.resolve(true); +function safeJsonStringify(json) { + try { + return JSON.stringify(json); + } catch (e) { + /* istanbul ignore next */ + return vuvuzela__WEBPACK_IMPORTED_MODULE_6__.stringify(json); } -}; +} -var comparisons = { - "undefined": function (targetDoc, sourceDoc) { - // This is the previous comparison function - if (collate(targetDoc.last_seq, sourceDoc.last_seq) === 0) { - return sourceDoc.last_seq; +function idbError(callback) { + return function (evt) { + var message = 'unknown_error'; + if (evt.target && evt.target.error) { + message = evt.target.error.name || evt.target.error.message; } - /* istanbul ignore next */ - return 0; - }, - "1": function (targetDoc, sourceDoc) { - // This is the comparison function ported from CouchDB - return compareReplicationLogs(sourceDoc, targetDoc).last_seq; + callback(createError(IDB_ERROR, message, evt.type)); + }; +} + +// Unfortunately, the metadata has to be stringified +// when it is put into the database, because otherwise +// IndexedDB can throw errors for deeply-nested objects. +// Originally we just used JSON.parse/JSON.stringify; now +// we use this custom vuvuzela library that avoids recursion. +// If we could do it all over again, we'd probably use a +// format for the revision trees other than JSON. +function encodeMetadata(metadata, winningRev, deleted) { + return { + data: safeJsonStringify(metadata), + winningRev: winningRev, + deletedOrLocal: deleted ? '1' : '0', + seq: metadata.seq, // highest seq for this doc + id: metadata.id + }; +} + +function decodeMetadata(storedObject) { + if (!storedObject) { + return null; } -}; + var metadata = safeJsonParse(storedObject.data); + metadata.winningRev = storedObject.winningRev; + metadata.deleted = storedObject.deletedOrLocal === '1'; + metadata.seq = storedObject.seq; + return metadata; +} -Checkpointer.prototype.getCheckpoint = function () { - var self = this; +// read the doc back out from the database. we don't store the +// _id or _rev because we already have _doc_id_rev. +function decodeDoc(doc) { + if (!doc) { + return doc; + } + var idx = doc._doc_id_rev.lastIndexOf(':'); + doc._id = doc._doc_id_rev.substring(0, idx - 1); + doc._rev = doc._doc_id_rev.substring(idx + 1); + delete doc._doc_id_rev; + return doc; +} - if (self.opts && self.opts.writeSourceCheckpoint && !self.opts.writeTargetCheckpoint) { - return self.src.get(self.id).then(function (sourceDoc) { - return sourceDoc.last_seq || LOWEST_SEQ; - }).catch(function (err) { - /* istanbul ignore if */ - if (err.status !== 404) { - throw err; - } - return LOWEST_SEQ; - }); +// Read a blob from the database, encoding as necessary +// and translating from base64 if the IDB doesn't support +// native Blobs +function readBlobData(body, type, asBlob, callback) { + if (asBlob) { + if (!body) { + callback(createBlob([''], {type: type})); + } else if (typeof body !== 'string') { // we have blob support + callback(body); + } else { // no blob support + callback(b64ToBluffer(body, type)); + } + } else { // as base64 string + if (!body) { + callback(''); + } else if (typeof body !== 'string') { // we have blob support + readAsBinaryString(body, function (binary) { + callback(thisBtoa(binary)); + }); + } else { // no blob support + callback(body); + } } +} - return self.target.get(self.id).then(function (targetDoc) { - if (self.opts && self.opts.writeTargetCheckpoint && !self.opts.writeSourceCheckpoint) { - return targetDoc.last_seq || LOWEST_SEQ; +function fetchAttachmentsIfNecessary(doc, opts, txn, cb) { + var attachments = Object.keys(doc._attachments || {}); + if (!attachments.length) { + return cb && cb(); + } + var numDone = 0; + + function checkDone() { + if (++numDone === attachments.length && cb) { + cb(); } + } - return self.src.get(self.id).then(function (sourceDoc) { - // Since we can't migrate an old version doc to a new one - // (no session id), we just go with the lowest seq in this case - /* istanbul ignore if */ - if (targetDoc.version !== sourceDoc.version) { - return LOWEST_SEQ; - } + function fetchAttachment(doc, att) { + var attObj = doc._attachments[att]; + var digest = attObj.digest; + var req = txn.objectStore(ATTACH_STORE).get(digest); + req.onsuccess = function (e) { + attObj.body = e.target.result.body; + checkDone(); + }; + } - var version; - if (targetDoc.version) { - version = targetDoc.version.toString(); - } else { - version = "undefined"; - } + attachments.forEach(function (att) { + if (opts.attachments && opts.include_docs) { + fetchAttachment(doc, att); + } else { + doc._attachments[att].stub = true; + checkDone(); + } + }); +} - if (version in comparisons) { - return comparisons[version](targetDoc, sourceDoc); - } - /* istanbul ignore next */ - return LOWEST_SEQ; - }, function (err) { - if (err.status === 404 && targetDoc.last_seq) { - return self.src.put({ - _id: self.id, - last_seq: LOWEST_SEQ - }).then(function () { - return LOWEST_SEQ; - }, function (err) { - if (isForbiddenError(err)) { - self.opts.writeSourceCheckpoint = false; - return targetDoc.last_seq; - } - /* istanbul ignore next */ - return LOWEST_SEQ; +// IDB-specific postprocessing necessary because +// we don't know whether we stored a true Blob or +// a base64-encoded string, and if it's a Blob it +// needs to be read outside of the transaction context +function postProcessAttachments(results, asBlob) { + return Promise.all(results.map(function (row) { + if (row.doc && row.doc._attachments) { + var attNames = Object.keys(row.doc._attachments); + return Promise.all(attNames.map(function (att) { + var attObj = row.doc._attachments[att]; + if (!('body' in attObj)) { // already processed + return; + } + var body = attObj.body; + var type = attObj.content_type; + return new Promise(function (resolve) { + readBlobData(body, type, asBlob, function (data) { + row.doc._attachments[att] = $inject_Object_assign( + pick(attObj, ['digest', 'content_type']), + {data: data} + ); + resolve(); + }); }); - } - throw err; - }); - }).catch(function (err) { - if (err.status !== 404) { - throw err; + })); + } + })); +} + +function compactRevs(revs, docId, txn) { + + var possiblyOrphanedDigests = []; + var seqStore = txn.objectStore(BY_SEQ_STORE); + var attStore = txn.objectStore(ATTACH_STORE); + var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE); + var count = revs.length; + + function checkDone() { + count--; + if (!count) { // done processing all revs + deleteOrphanedAttachments(); } - return LOWEST_SEQ; - }); -}; -// This checkpoint comparison is ported from CouchDBs source -// they come from here: -// https://github.com/apache/couchdb-couch-replicator/blob/master/src/couch_replicator.erl#L863-L906 + } -function compareReplicationLogs(srcDoc, tgtDoc) { - if (srcDoc.session_id === tgtDoc.session_id) { - return { - last_seq: srcDoc.last_seq, - history: srcDoc.history - }; + function deleteOrphanedAttachments() { + if (!possiblyOrphanedDigests.length) { + return; + } + possiblyOrphanedDigests.forEach(function (digest) { + var countReq = attAndSeqStore.index('digestSeq').count( + IDBKeyRange.bound( + digest + '::', digest + '::\uffff', false, false)); + countReq.onsuccess = function (e) { + var count = e.target.result; + if (!count) { + // orphaned + attStore.delete(digest); + } + }; + }); } - return compareReplicationHistory(srcDoc.history, tgtDoc.history); -} + revs.forEach(function (rev) { + var index = seqStore.index('_doc_id_rev'); + var key = docId + "::" + rev; + index.getKey(key).onsuccess = function (e) { + var seq = e.target.result; + if (typeof seq !== 'number') { + return checkDone(); + } + seqStore.delete(seq); -function compareReplicationHistory(sourceHistory, targetHistory) { - // the erlang loop via function arguments is not so easy to repeat in JS - // therefore, doing this as recursion - var S = sourceHistory[0]; - var sourceRest = sourceHistory.slice(1); - var T = targetHistory[0]; - var targetRest = targetHistory.slice(1); + var cursor = attAndSeqStore.index('seq') + .openCursor(IDBKeyRange.only(seq)); - if (!S || targetHistory.length === 0) { - return { - last_seq: LOWEST_SEQ, - history: [] + cursor.onsuccess = function (event) { + var cursor = event.target.result; + if (cursor) { + var digest = cursor.value.digestSeq.split('::')[0]; + possiblyOrphanedDigests.push(digest); + attAndSeqStore.delete(cursor.primaryKey); + cursor.continue(); + } else { // done + checkDone(); + } + }; }; - } + }); +} - var sourceId = S.session_id; - /* istanbul ignore if */ - if (hasSessionId(sourceId, targetHistory)) { +function openTransactionSafely(idb, stores, mode) { + try { return { - last_seq: S.last_seq, - history: sourceHistory + txn: idb.transaction(stores, mode) }; - } - - var targetId = T.session_id; - if (hasSessionId(targetId, sourceRest)) { + } catch (err) { return { - last_seq: T.last_seq, - history: targetRest + error: err }; } - - return compareReplicationHistory(sourceRest, targetRest); } -function hasSessionId(sessionId, history) { - var props = history[0]; - var rest = history.slice(1); +var changesHandler = new Changes(); - if (!sessionId || history.length === 0) { - return false; - } +function idbBulkDocs(dbOpts, req, opts, api, idb, callback) { + var docInfos = req.docs; + var txn; + var docStore; + var bySeqStore; + var attachStore; + var attachAndSeqStore; + var metaStore; + var docInfoError; + var metaDoc; - if (sessionId === props.session_id) { - return true; + for (var i = 0, len = docInfos.length; i < len; i++) { + var doc = docInfos[i]; + if (doc._id && isLocalId(doc._id)) { + continue; + } + doc = docInfos[i] = parseDoc(doc, opts.new_edits, dbOpts); + if (doc.error && !docInfoError) { + docInfoError = doc; + } } - return hasSessionId(sessionId, rest); -} - -function isForbiddenError(err) { - return typeof err.status === 'number' && Math.floor(err.status / 100) === 4; -} + if (docInfoError) { + return callback(docInfoError); + } -var STARTING_BACK_OFF = 0; + var allDocsProcessed = false; + var docCountDelta = 0; + var results = new Array(docInfos.length); + var fetchedDocs = new ExportedMap(); + var preconditionErrored = false; + var blobType = api._meta.blobSupport ? 'blob' : 'base64'; -function backOff(opts, returnValue, error, callback) { - if (opts.retry === false) { - returnValue.emit('error', error); - returnValue.removeAllListeners(); - return; - } - /* istanbul ignore if */ - if (typeof opts.back_off_function !== 'function') { - opts.back_off_function = defaultBackOff; - } - returnValue.emit('requestError', error); - if (returnValue.state === 'active' || returnValue.state === 'pending') { - returnValue.emit('paused', error); - returnValue.state = 'stopped'; - var backOffSet = function backoffTimeSet() { - opts.current_back_off = STARTING_BACK_OFF; - }; - var removeBackOffSetter = function removeBackOffTimeSet() { - returnValue.removeListener('active', backOffSet); - }; - returnValue.once('paused', removeBackOffSetter); - returnValue.once('active', backOffSet); - } + preprocessAttachments(docInfos, blobType, function (err) { + if (err) { + return callback(err); + } + startTransaction(); + }); - opts.current_back_off = opts.current_back_off || STARTING_BACK_OFF; - opts.current_back_off = opts.back_off_function(opts.current_back_off); - setTimeout(callback, opts.current_back_off); -} + function startTransaction() { -function sortObjectPropertiesByKey(queryParams) { - return Object.keys(queryParams).sort(collate).reduce(function (result, key) { - result[key] = queryParams[key]; - return result; - }, {}); -} + var stores = [ + DOC_STORE, BY_SEQ_STORE, + ATTACH_STORE, + LOCAL_STORE, ATTACH_AND_SEQ_STORE, + META_STORE + ]; + var txnResult = openTransactionSafely(idb, stores, 'readwrite'); + if (txnResult.error) { + return callback(txnResult.error); + } + txn = txnResult.txn; + txn.onabort = idbError(callback); + txn.ontimeout = idbError(callback); + txn.oncomplete = complete; + docStore = txn.objectStore(DOC_STORE); + bySeqStore = txn.objectStore(BY_SEQ_STORE); + attachStore = txn.objectStore(ATTACH_STORE); + attachAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE); + metaStore = txn.objectStore(META_STORE); -// Generate a unique id particular to this replication. -// Not guaranteed to align perfectly with CouchDB's rep ids. -function generateReplicationId(src, target, opts) { - var docIds = opts.doc_ids ? opts.doc_ids.sort(collate) : ''; - var filterFun = opts.filter ? opts.filter.toString() : ''; - var queryParams = ''; - var filterViewName = ''; - var selector = ''; + metaStore.get(META_STORE).onsuccess = function (e) { + metaDoc = e.target.result; + updateDocCountIfReady(); + }; - // possibility for checkpoints to be lost here as behaviour of - // JSON.stringify is not stable (see #6226) - /* istanbul ignore if */ - if (opts.selector) { - selector = JSON.stringify(opts.selector); + verifyAttachments(function (err) { + if (err) { + preconditionErrored = true; + return callback(err); + } + fetchExistingDocs(); + }); } - if (opts.filter && opts.query_params) { - queryParams = JSON.stringify(sortObjectPropertiesByKey(opts.query_params)); + function onAllDocsProcessed() { + allDocsProcessed = true; + updateDocCountIfReady(); } - if (opts.filter && opts.filter === '_view') { - filterViewName = opts.view.toString(); + function idbProcessDocs() { + processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs, + txn, results, writeDoc, opts, onAllDocsProcessed); } - return Promise.all([src.id(), target.id()]).then(function (res) { - var queryData = res[0] + res[1] + filterFun + filterViewName + - queryParams + docIds + selector; - return new Promise(function (resolve) { - binaryMd5(queryData, resolve); - }); - }).then(function (md5sum) { - // can't use straight-up md5 alphabet, because - // the char '/' is interpreted as being for attachments, - // and + is also not url-safe - md5sum = md5sum.replace(/\//g, '.').replace(/\+/g, '_'); - return '_local/' + md5sum; - }); -} + function updateDocCountIfReady() { + if (!metaDoc || !allDocsProcessed) { + return; + } + // caching the docCount saves a lot of time in allDocs() and + // info(), which is why we go to all the trouble of doing this + metaDoc.docCount += docCountDelta; + metaStore.put(metaDoc); + } -function replicate(src, target, opts, returnValue, result) { - var batches = []; // list of batches to be processed - var currentBatch; // the batch currently being processed - var pendingBatch = { - seq: 0, - changes: [], - docs: [] - }; // next batch, not yet ready to be processed - var writingCheckpoint = false; // true while checkpoint is being written - var changesCompleted = false; // true when all changes received - var replicationCompleted = false; // true when replication has completed - var last_seq = 0; - var continuous = opts.continuous || opts.live || false; - var batch_size = opts.batch_size || 100; - var batches_limit = opts.batches_limit || 10; - var changesPending = false; // true while src.changes is running - var doc_ids = opts.doc_ids; - var selector = opts.selector; - var repId; - var checkpointer; - var changedDocs = []; - // Like couchdb, every replication gets a unique session id - var session = uuid(); + function fetchExistingDocs() { - result = result || { - ok: true, - start_time: new Date().toISOString(), - docs_read: 0, - docs_written: 0, - doc_write_failures: 0, - errors: [] - }; + if (!docInfos.length) { + return; + } - var changesOpts = {}; - returnValue.ready(src, target); + var numFetched = 0; - function initCheckpointer() { - if (checkpointer) { - return Promise.resolve(); + function checkDone() { + if (++numFetched === docInfos.length) { + idbProcessDocs(); + } } - return generateReplicationId(src, target, opts).then(function (res) { - repId = res; - var checkpointOpts = {}; - if (opts.checkpoint === false) { - checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: false }; - } else if (opts.checkpoint === 'source') { - checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: false }; - } else if (opts.checkpoint === 'target') { - checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: true }; - } else { - checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: true }; + function readMetadata(event) { + var metadata = decodeMetadata(event.target.result); + + if (metadata) { + fetchedDocs.set(metadata.id, metadata); } + checkDone(); + } - checkpointer = new Checkpointer(src, target, repId, returnValue, checkpointOpts); - }); + for (var i = 0, len = docInfos.length; i < len; i++) { + var docInfo = docInfos[i]; + if (docInfo._id && isLocalId(docInfo._id)) { + checkDone(); // skip local docs + continue; + } + var req = docStore.get(docInfo.metadata.id); + req.onsuccess = readMetadata; + } } - function writeDocs() { - changedDocs = []; - - if (currentBatch.docs.length === 0) { + function complete() { + if (preconditionErrored) { return; } - var docs = currentBatch.docs; - var bulkOpts = {timeout: opts.timeout}; - return target.bulkDocs({docs: docs, new_edits: false}, bulkOpts).then(function (res) { - /* istanbul ignore if */ - if (returnValue.cancelled) { - completeReplication(); - throw new Error('cancelled'); - } - - // `res` doesn't include full documents (which live in `docs`), so we create a map of - // (id -> error), and check for errors while iterating over `docs` - var errorsById = Object.create(null); - res.forEach(function (res) { - if (res.error) { - errorsById[res.id] = res; - } - }); - var errorsNo = Object.keys(errorsById).length; - result.doc_write_failures += errorsNo; - result.docs_written += docs.length - errorsNo; + changesHandler.notify(api._meta.name); + callback(null, results); + } - docs.forEach(function (doc) { - var error = errorsById[doc._id]; - if (error) { - result.errors.push(error); - // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway) - var errorName = (error.name || '').toLowerCase(); - if (errorName === 'unauthorized' || errorName === 'forbidden') { - returnValue.emit('denied', clone(error)); - } else { - throw error; - } - } else { - changedDocs.push(doc); - } - }); + function verifyAttachment(digest, callback) { - }, function (err) { - result.doc_write_failures += docs.length; - throw err; - }); + var req = attachStore.get(digest); + req.onsuccess = function (e) { + if (!e.target.result) { + var err = createError(MISSING_STUB, + 'unknown stub attachment with digest ' + + digest); + err.status = 412; + callback(err); + } else { + callback(); + } + }; } - function finishBatch() { - if (currentBatch.error) { - throw new Error('There was a problem getting docs.'); - } - result.last_seq = last_seq = currentBatch.seq; - var outResult = clone(result); - if (changedDocs.length) { - outResult.docs = changedDocs; - // Attach 'pending' property if server supports it (CouchDB 2.0+) - /* istanbul ignore if */ - if (typeof currentBatch.pending === 'number') { - outResult.pending = currentBatch.pending; - delete currentBatch.pending; - } - returnValue.emit('change', outResult); - } - writingCheckpoint = true; - return checkpointer.writeCheckpoint(currentBatch.seq, - session).then(function () { - writingCheckpoint = false; - /* istanbul ignore if */ - if (returnValue.cancelled) { - completeReplication(); - throw new Error('cancelled'); + function verifyAttachments(finish) { + + + var digests = []; + docInfos.forEach(function (docInfo) { + if (docInfo.data && docInfo.data._attachments) { + Object.keys(docInfo.data._attachments).forEach(function (filename) { + var att = docInfo.data._attachments[filename]; + if (att.stub) { + digests.push(att.digest); + } + }); } - currentBatch = undefined; - getChanges(); - }).catch(function (err) { - onCheckpointError(err); - throw err; }); - } + if (!digests.length) { + return finish(); + } + var numDone = 0; + var err; - function getDiffs() { - var diff = {}; - currentBatch.changes.forEach(function (change) { - // Couchbase Sync Gateway emits these, but we can ignore them - /* istanbul ignore if */ - if (change.id === "_user/") { - return; + function checkDone() { + if (++numDone === digests.length) { + finish(err); } - diff[change.id] = change.changes.map(function (x) { - return x.rev; + } + digests.forEach(function (digest) { + verifyAttachment(digest, function (attErr) { + if (attErr && !err) { + err = attErr; + } + checkDone(); }); }); - return target.revsDiff(diff).then(function (diffs) { - /* istanbul ignore if */ - if (returnValue.cancelled) { - completeReplication(); - throw new Error('cancelled'); - } - // currentBatch.diffs elements are deleted as the documents are written - currentBatch.diffs = diffs; - }); } - function getBatchDocs() { - return getDocs(src, target, currentBatch.diffs, returnValue).then(function (got) { - currentBatch.error = !got.ok; - got.docs.forEach(function (doc) { - delete currentBatch.diffs[doc._id]; - result.docs_read++; - currentBatch.docs.push(doc); - }); - }); - } + function writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted, + isUpdate, delta, resultsIdx, callback) { - function startNextBatch() { - if (returnValue.cancelled || currentBatch) { - return; + docInfo.metadata.winningRev = winningRev$$1; + docInfo.metadata.deleted = winningRevIsDeleted; + + var doc = docInfo.data; + doc._id = docInfo.metadata.id; + doc._rev = docInfo.metadata.rev; + + if (newRevIsDeleted) { + doc._deleted = true; } - if (batches.length === 0) { - processPendingBatch(true); - return; + + var hasAttachments = doc._attachments && + Object.keys(doc._attachments).length; + if (hasAttachments) { + return writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted, + isUpdate, resultsIdx, callback); } - currentBatch = batches.shift(); - getDiffs() - .then(getBatchDocs) - .then(writeDocs) - .then(finishBatch) - .then(startNextBatch) - .catch(function (err) { - abortReplication('batch processing terminated with error', err); - }); + + docCountDelta += delta; + updateDocCountIfReady(); + + finishDoc(docInfo, winningRev$$1, winningRevIsDeleted, + isUpdate, resultsIdx, callback); } + function finishDoc(docInfo, winningRev$$1, winningRevIsDeleted, + isUpdate, resultsIdx, callback) { - function processPendingBatch(immediate) { - if (pendingBatch.changes.length === 0) { - if (batches.length === 0 && !currentBatch) { - if ((continuous && changesOpts.live) || changesCompleted) { - returnValue.state = 'pending'; - returnValue.emit('paused'); - } - if (changesCompleted) { - completeReplication(); - } + var doc = docInfo.data; + var metadata = docInfo.metadata; + + doc._doc_id_rev = metadata.id + '::' + metadata.rev; + delete doc._id; + delete doc._rev; + + function afterPutDoc(e) { + var revsToDelete = docInfo.stemmedRevs || []; + + if (isUpdate && api.auto_compaction) { + revsToDelete = revsToDelete.concat(compactTree(docInfo.metadata)); } - return; - } - if ( - immediate || - changesCompleted || - pendingBatch.changes.length >= batch_size - ) { - batches.push(pendingBatch); - pendingBatch = { - seq: 0, - changes: [], - docs: [] - }; - if (returnValue.state === 'pending' || returnValue.state === 'stopped') { - returnValue.state = 'active'; - returnValue.emit('active'); + + if (revsToDelete && revsToDelete.length) { + compactRevs(revsToDelete, docInfo.metadata.id, txn); } - startNextBatch(); - } - } + metadata.seq = e.target.result; + // Current _rev is calculated from _rev_tree on read + // delete metadata.rev; + var metadataToStore = encodeMetadata(metadata, winningRev$$1, + winningRevIsDeleted); + var metaDataReq = docStore.put(metadataToStore); + metaDataReq.onsuccess = afterPutMetadata; + } - function abortReplication(reason, err) { - if (replicationCompleted) { - return; + function afterPutDocError(e) { + // ConstraintError, need to update, not put (see #1638 for details) + e.preventDefault(); // avoid transaction abort + e.stopPropagation(); // avoid transaction onerror + var index = bySeqStore.index('_doc_id_rev'); + var getKeyReq = index.getKey(doc._doc_id_rev); + getKeyReq.onsuccess = function (e) { + var putReq = bySeqStore.put(doc, e.target.result); + putReq.onsuccess = afterPutDoc; + }; } - if (!err.message) { - err.message = reason; + + function afterPutMetadata() { + results[resultsIdx] = { + ok: true, + id: metadata.id, + rev: metadata.rev + }; + fetchedDocs.set(docInfo.metadata.id, docInfo.metadata); + insertAttachmentMappings(docInfo, metadata.seq, callback); } - result.ok = false; - result.status = 'aborting'; - batches = []; - pendingBatch = { - seq: 0, - changes: [], - docs: [] - }; - completeReplication(err); + + var putReq = bySeqStore.put(doc); + + putReq.onsuccess = afterPutDoc; + putReq.onerror = afterPutDocError; } + function writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted, + isUpdate, resultsIdx, callback) { + - function completeReplication(fatalError) { - if (replicationCompleted) { - return; - } - /* istanbul ignore if */ - if (returnValue.cancelled) { - result.status = 'cancelled'; - if (writingCheckpoint) { - return; + var doc = docInfo.data; + + var numDone = 0; + var attachments = Object.keys(doc._attachments); + + function collectResults() { + if (numDone === attachments.length) { + finishDoc(docInfo, winningRev$$1, winningRevIsDeleted, + isUpdate, resultsIdx, callback); } } - result.status = result.status || 'complete'; - result.end_time = new Date().toISOString(); - result.last_seq = last_seq; - replicationCompleted = true; - if (fatalError) { - // need to extend the error because Firefox considers ".result" read-only - fatalError = createError(fatalError); - fatalError.result = result; + function attachmentSaved() { + numDone++; + collectResults(); + } - // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway) - var errorName = (fatalError.name || '').toLowerCase(); - if (errorName === 'unauthorized' || errorName === 'forbidden') { - returnValue.emit('error', fatalError); - returnValue.removeAllListeners(); + attachments.forEach(function (key) { + var att = docInfo.data._attachments[key]; + if (!att.stub) { + var data = att.data; + delete att.data; + att.revpos = parseInt(winningRev$$1, 10); + var digest = att.digest; + saveAttachment(digest, data, attachmentSaved); } else { - backOff(opts, returnValue, fatalError, function () { - replicate(src, target, opts, returnValue); - }); + numDone++; + collectResults(); } - } else { - returnValue.emit('complete', result); - returnValue.removeAllListeners(); - } + }); } + // map seqs to attachment digests, which + // we will need later during compaction + function insertAttachmentMappings(docInfo, seq, callback) { - function onChange(change, pending, lastSeq) { - /* istanbul ignore if */ - if (returnValue.cancelled) { - return completeReplication(); - } - // Attach 'pending' property if server supports it (CouchDB 2.0+) - /* istanbul ignore if */ - if (typeof pending === 'number') { - pendingBatch.pending = pending; + var attsAdded = 0; + var attsToAdd = Object.keys(docInfo.data._attachments || {}); + + if (!attsToAdd.length) { + return callback(); } - var filter = filterChange(opts)(change); - if (!filter) { - return; + function checkDone() { + if (++attsAdded === attsToAdd.length) { + callback(); + } } - pendingBatch.seq = change.seq || lastSeq; - pendingBatch.changes.push(change); - immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { - processPendingBatch(batches.length === 0 && changesOpts.live); - }); - } + function add(att) { + var digest = docInfo.data._attachments[att].digest; + var req = attachAndSeqStore.put({ + seq: seq, + digestSeq: digest + '::' + seq + }); - function onChangesComplete(changes) { - changesPending = false; - /* istanbul ignore if */ - if (returnValue.cancelled) { - return completeReplication(); + req.onsuccess = checkDone; + req.onerror = function (e) { + // this callback is for a constaint error, which we ignore + // because this docid/rev has already been associated with + // the digest (e.g. when new_edits == false) + e.preventDefault(); // avoid transaction abort + e.stopPropagation(); // avoid transaction onerror + checkDone(); + }; } + for (var i = 0; i < attsToAdd.length; i++) { + add(attsToAdd[i]); // do in parallel + } + } - // if no results were returned then we're done, - // else fetch more - if (changes.results.length > 0) { - changesOpts.since = changes.results[changes.results.length - 1].seq; - getChanges(); - processPendingBatch(true); - } else { + function saveAttachment(digest, data, callback) { - var complete = function () { - if (continuous) { - changesOpts.live = true; - getChanges(); - } else { - changesCompleted = true; - } - processPendingBatch(true); - }; - // update the checkpoint so we start from the right seq next time - if (!currentBatch && changes.results.length === 0) { - writingCheckpoint = true; - checkpointer.writeCheckpoint(changes.last_seq, - session).then(function () { - writingCheckpoint = false; - result.last_seq = last_seq = changes.last_seq; - complete(); - }) - .catch(onCheckpointError); - } else { - complete(); + var getKeyReq = attachStore.count(digest); + getKeyReq.onsuccess = function (e) { + var count = e.target.result; + if (count) { + return callback(); // already exists } - } + var newAtt = { + digest: digest, + body: data + }; + var putReq = attachStore.put(newAtt); + putReq.onsuccess = callback; + }; } +} +// Abstraction over IDBCursor and getAll()/getAllKeys() that allows us to batch our operations +// while falling back to a normal IDBCursor operation on browsers that don't support getAll() or +// getAllKeys(). This allows for a much faster implementation than just straight-up cursors, because +// we're not processing each document one-at-a-time. +function runBatchedCursor(objectStore, keyRange, descending, batchSize, onBatch) { - function onChangesError(err) { - changesPending = false; - /* istanbul ignore if */ - if (returnValue.cancelled) { - return completeReplication(); - } - abortReplication('changes rejected', err); + if (batchSize === -1) { + batchSize = 1000; } + // Bail out of getAll()/getAllKeys() in the following cases: + // 1) either method is unsupported - we need both + // 2) batchSize is 1 (might as well use IDBCursor) + // 3) descending – no real way to do this via getAll()/getAllKeys() - function getChanges() { - if (!( - !changesPending && - !changesCompleted && - batches.length < batches_limit - )) { - return; - } - changesPending = true; - function abortChanges() { - changes.cancel(); - } - function removeListener() { - returnValue.removeListener('cancel', abortChanges); - } - - if (returnValue._changes) { // remove old changes() and listeners - returnValue.removeListener('cancel', returnValue._abortChanges); - returnValue._changes.cancel(); - } - returnValue.once('cancel', abortChanges); + var useGetAll = typeof objectStore.getAll === 'function' && + typeof objectStore.getAllKeys === 'function' && + batchSize > 1 && !descending; - var changes = src.changes(changesOpts) - .on('change', onChange); - changes.then(removeListener, removeListener); - changes.then(onChangesComplete) - .catch(onChangesError); + var keysBatch; + var valuesBatch; + var pseudoCursor; - if (opts.retry) { - // save for later so we can cancel if necessary - returnValue._changes = changes; - returnValue._abortChanges = abortChanges; + function onGetAll(e) { + valuesBatch = e.target.result; + if (keysBatch) { + onBatch(keysBatch, valuesBatch, pseudoCursor); } } + function onGetAllKeys(e) { + keysBatch = e.target.result; + if (valuesBatch) { + onBatch(keysBatch, valuesBatch, pseudoCursor); + } + } - function startChanges() { - initCheckpointer().then(function () { - /* istanbul ignore if */ - if (returnValue.cancelled) { - completeReplication(); - return; - } - return checkpointer.getCheckpoint().then(function (checkpoint) { - last_seq = checkpoint; - changesOpts = { - since: last_seq, - limit: batch_size, - batch_size: batch_size, - style: 'all_docs', - doc_ids: doc_ids, - selector: selector, - return_docs: true // required so we know when we're done - }; - if (opts.filter) { - if (typeof opts.filter !== 'string') { - // required for the client-side filter in onChange - changesOpts.include_docs = true; - } else { // ddoc filter - changesOpts.filter = opts.filter; - } - } - if ('heartbeat' in opts) { - changesOpts.heartbeat = opts.heartbeat; - } - if ('timeout' in opts) { - changesOpts.timeout = opts.timeout; - } - if (opts.query_params) { - changesOpts.query_params = opts.query_params; - } - if (opts.view) { - changesOpts.view = opts.view; + function continuePseudoCursor() { + if (!keysBatch.length) { // no more results + return onBatch(); + } + // fetch next batch, exclusive start + var lastKey = keysBatch[keysBatch.length - 1]; + var newKeyRange; + if (keyRange && keyRange.upper) { + try { + newKeyRange = IDBKeyRange.bound(lastKey, keyRange.upper, + true, keyRange.upperOpen); + } catch (e) { + if (e.name === "DataError" && e.code === 0) { + return onBatch(); // we're done, startkey and endkey are equal } - getChanges(); - }); - }).catch(function (err) { - abortReplication('getCheckpoint rejected with ', err); - }); + } + } else { + newKeyRange = IDBKeyRange.lowerBound(lastKey, true); + } + keyRange = newKeyRange; + keysBatch = null; + valuesBatch = null; + objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll; + objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys; } - /* istanbul ignore next */ - function onCheckpointError(err) { - writingCheckpoint = false; - abortReplication('writeCheckpoint completed with error', err); + function onCursor(e) { + var cursor = e.target.result; + if (!cursor) { // done + return onBatch(); + } + // regular IDBCursor acts like a batch where batch size is always 1 + onBatch([cursor.key], [cursor.value], cursor); } - /* istanbul ignore if */ - if (returnValue.cancelled) { // cancelled immediately - completeReplication(); - return; + if (useGetAll) { + pseudoCursor = {"continue": continuePseudoCursor}; + objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll; + objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys; + } else if (descending) { + objectStore.openCursor(keyRange, 'prev').onsuccess = onCursor; + } else { + objectStore.openCursor(keyRange).onsuccess = onCursor; } +} - if (!returnValue._addedListeners) { - returnValue.once('cancel', completeReplication); +// simple shim for objectStore.getAll(), falling back to IDBCursor +function getAll(objectStore, keyRange, onSuccess) { + if (typeof objectStore.getAll === 'function') { + // use native getAll + objectStore.getAll(keyRange).onsuccess = onSuccess; + return; + } + // fall back to cursors + var values = []; - if (typeof opts.complete === 'function') { - returnValue.once('error', opts.complete); - returnValue.once('complete', function (result) { - opts.complete(null, result); + function onCursor(e) { + var cursor = e.target.result; + if (cursor) { + values.push(cursor.value); + cursor.continue(); + } else { + onSuccess({ + target: { + result: values + } }); } - returnValue._addedListeners = true; } - if (typeof opts.since === 'undefined') { - startChanges(); - } else { - initCheckpointer().then(function () { - writingCheckpoint = true; - return checkpointer.writeCheckpoint(opts.since, session); - }).then(function () { - writingCheckpoint = false; - /* istanbul ignore if */ - if (returnValue.cancelled) { - completeReplication(); - return; - } - last_seq = opts.since; - startChanges(); - }).catch(onCheckpointError); - } + objectStore.openCursor(keyRange).onsuccess = onCursor; } -// We create a basic promise so the caller can cancel the replication possibly -// before we have actually started listening to changes etc -inherits__WEBPACK_IMPORTED_MODULE_3___default()(Replication, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); -function Replication() { - events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this); - this.cancelled = false; - this.state = 'pending'; - var self = this; - var promise = new Promise(function (fulfill, reject) { - self.once('complete', fulfill); - self.once('error', reject); +function allDocsKeys(keys, docStore, onBatch) { + // It's not guaranted to be returned in right order + var valuesBatch = new Array(keys.length); + var count = 0; + keys.forEach(function (key, index) { + docStore.get(key).onsuccess = function (event) { + if (event.target.result) { + valuesBatch[index] = event.target.result; + } else { + valuesBatch[index] = {key: key, error: 'not_found'}; + } + count++; + if (count === keys.length) { + onBatch(keys, valuesBatch, {}); + } + }; }); - self.then = function (resolve, reject) { - return promise.then(resolve, reject); - }; - self.catch = function (reject) { - return promise.catch(reject); - }; - // As we allow error handling via "error" event as well, - // put a stub in here so that rejecting never throws UnhandledError. - self.catch(function () {}); } -Replication.prototype.cancel = function () { - this.cancelled = true; - this.state = 'cancelled'; - this.emit('cancel'); -}; - -Replication.prototype.ready = function (src, target) { - var self = this; - if (self._readyCalled) { - return; - } - self._readyCalled = true; - - function onDestroy() { - self.cancel(); - } - src.once('destroyed', onDestroy); - target.once('destroyed', onDestroy); - function cleanup() { - src.removeListener('destroyed', onDestroy); - target.removeListener('destroyed', onDestroy); - } - self.once('complete', cleanup); -}; - -function toPouch(db, opts) { - var PouchConstructor = opts.PouchConstructor; - if (typeof db === 'string') { - return new PouchConstructor(db, opts); - } else { - return db; +function createKeyRange(start, end, inclusiveEnd, key, descending) { + try { + if (start && end) { + if (descending) { + return IDBKeyRange.bound(end, start, !inclusiveEnd, false); + } else { + return IDBKeyRange.bound(start, end, false, !inclusiveEnd); + } + } else if (start) { + if (descending) { + return IDBKeyRange.upperBound(start); + } else { + return IDBKeyRange.lowerBound(start); + } + } else if (end) { + if (descending) { + return IDBKeyRange.lowerBound(end, !inclusiveEnd); + } else { + return IDBKeyRange.upperBound(end, !inclusiveEnd); + } + } else if (key) { + return IDBKeyRange.only(key); + } + } catch (e) { + return {error: e}; } + return null; } -function replicateWrapper(src, target, opts, callback) { - - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - if (typeof opts === 'undefined') { - opts = {}; - } +function idbAllDocs(opts, idb, callback) { + var start = 'startkey' in opts ? opts.startkey : false; + var end = 'endkey' in opts ? opts.endkey : false; + var key = 'key' in opts ? opts.key : false; + var keys = 'keys' in opts ? opts.keys : false; + var skip = opts.skip || 0; + var limit = typeof opts.limit === 'number' ? opts.limit : -1; + var inclusiveEnd = opts.inclusive_end !== false; - if (opts.doc_ids && !Array.isArray(opts.doc_ids)) { - throw createError(BAD_REQUEST, - "`doc_ids` filter parameter is not a list."); + var keyRange ; + var keyRangeError; + if (!keys) { + keyRange = createKeyRange(start, end, inclusiveEnd, key, opts.descending); + keyRangeError = keyRange && keyRange.error; + if (keyRangeError && + !(keyRangeError.name === "DataError" && keyRangeError.code === 0)) { + // DataError with error code 0 indicates start is less than end, so + // can just do an empty query. Else need to throw + return callback(createError(IDB_ERROR, + keyRangeError.name, keyRangeError.message)); + } } - opts.complete = callback; - opts = clone(opts); - opts.continuous = opts.continuous || opts.live; - opts.retry = ('retry' in opts) ? opts.retry : false; - /*jshint validthis:true */ - opts.PouchConstructor = opts.PouchConstructor || this; - var replicateRet = new Replication(opts); - var srcPouch = toPouch(src, opts); - var targetPouch = toPouch(target, opts); - replicate(srcPouch, targetPouch, opts, replicateRet); - return replicateRet; -} + var stores = [DOC_STORE, BY_SEQ_STORE, META_STORE]; -inherits__WEBPACK_IMPORTED_MODULE_3___default()(Sync, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); -function sync(src, target, opts, callback) { - if (typeof opts === 'function') { - callback = opts; - opts = {}; + if (opts.attachments) { + stores.push(ATTACH_STORE); } - if (typeof opts === 'undefined') { - opts = {}; + var txnResult = openTransactionSafely(idb, stores, 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); } - opts = clone(opts); - /*jshint validthis:true */ - opts.PouchConstructor = opts.PouchConstructor || this; - src = toPouch(src, opts); - target = toPouch(target, opts); - return new Sync(src, target, opts, callback); -} - -function Sync(src, target, opts, callback) { - var self = this; - this.canceled = false; - - var optsPush = opts.push ? $inject_Object_assign({}, opts, opts.push) : opts; - var optsPull = opts.pull ? $inject_Object_assign({}, opts, opts.pull) : opts; - - this.push = replicateWrapper(src, target, optsPush); - this.pull = replicateWrapper(target, src, optsPull); + var txn = txnResult.txn; + txn.oncomplete = onTxnComplete; + txn.onabort = idbError(callback); + var docStore = txn.objectStore(DOC_STORE); + var seqStore = txn.objectStore(BY_SEQ_STORE); + var metaStore = txn.objectStore(META_STORE); + var docIdRevIndex = seqStore.index('_doc_id_rev'); + var results = []; + var docCount; + var updateSeq; - this.pushPaused = true; - this.pullPaused = true; + metaStore.get(META_STORE).onsuccess = function (e) { + docCount = e.target.result.docCount; + }; - function pullChange(change) { - self.emit('change', { - direction: 'pull', - change: change - }); - } - function pushChange(change) { - self.emit('change', { - direction: 'push', - change: change - }); - } - function pushDenied(doc) { - self.emit('denied', { - direction: 'push', - doc: doc - }); - } - function pullDenied(doc) { - self.emit('denied', { - direction: 'pull', - doc: doc + /* istanbul ignore if */ + if (opts.update_seq) { + getMaxUpdateSeq(seqStore, function (e) { + if (e.target.result && e.target.result.length > 0) { + updateSeq = e.target.result[0]; + } }); } - function pushPaused() { - self.pushPaused = true; - /* istanbul ignore if */ - if (self.pullPaused) { - self.emit('paused'); - } - } - function pullPaused() { - self.pullPaused = true; - /* istanbul ignore if */ - if (self.pushPaused) { - self.emit('paused'); - } - } - function pushActive() { - self.pushPaused = false; - /* istanbul ignore if */ - if (self.pullPaused) { - self.emit('active', { - direction: 'push' - }); - } - } - function pullActive() { - self.pullPaused = false; - /* istanbul ignore if */ - if (self.pushPaused) { - self.emit('active', { - direction: 'pull' + + function getMaxUpdateSeq(objectStore, onSuccess) { + function onCursor(e) { + var cursor = e.target.result; + var maxKey = undefined; + if (cursor && cursor.key) { + maxKey = cursor.key; + } + return onSuccess({ + target: { + result: [maxKey] + } }); } + objectStore.openCursor(null, 'prev').onsuccess = onCursor; } - var removed = {}; - - function removeAll(type) { // type is 'push' or 'pull' - return function (event, func) { - var isChange = event === 'change' && - (func === pullChange || func === pushChange); - var isDenied = event === 'denied' && - (func === pullDenied || func === pushDenied); - var isPaused = event === 'paused' && - (func === pullPaused || func === pushPaused); - var isActive = event === 'active' && - (func === pullActive || func === pushActive); - - if (isChange || isDenied || isPaused || isActive) { - if (!(event in removed)) { - removed[event] = {}; - } - removed[event][type] = true; - if (Object.keys(removed[event]).length === 2) { - // both push and pull have asked to be removed - self.removeAllListeners(event); + // if the user specifies include_docs=true, then we don't + // want to block the main cursor while we're fetching the doc + function fetchDocAsynchronously(metadata, row, winningRev$$1) { + var key = metadata.id + "::" + winningRev$$1; + docIdRevIndex.get(key).onsuccess = function onGetDoc(e) { + row.doc = decodeDoc(e.target.result) || {}; + if (opts.conflicts) { + var conflicts = collectConflicts(metadata); + if (conflicts.length) { + row.doc._conflicts = conflicts; } } + fetchAttachmentsIfNecessary(row.doc, opts, txn); }; } - if (opts.live) { - this.push.on('complete', self.pull.cancel.bind(self.pull)); - this.pull.on('complete', self.push.cancel.bind(self.push)); + function allDocsInner(winningRev$$1, metadata) { + var row = { + id: metadata.id, + key: metadata.id, + value: { + rev: winningRev$$1 + } + }; + var deleted = metadata.deleted; + if (deleted) { + if (keys) { + results.push(row); + // deleted docs are okay with "keys" requests + row.value.deleted = true; + row.doc = null; + } + } else if (skip-- <= 0) { + results.push(row); + if (opts.include_docs) { + fetchDocAsynchronously(metadata, row, winningRev$$1); + } + } } - function addOneListener(ee, event, listener) { - if (ee.listeners(event).indexOf(listener) == -1) { - ee.on(event, listener); + function processBatch(batchValues) { + for (var i = 0, len = batchValues.length; i < len; i++) { + if (results.length === limit) { + break; + } + var batchValue = batchValues[i]; + if (batchValue.error && keys) { + // key was not found with "keys" requests + results.push(batchValue); + continue; + } + var metadata = decodeMetadata(batchValue); + var winningRev$$1 = metadata.winningRev; + allDocsInner(winningRev$$1, metadata); } } - this.on('newListener', function (event) { - if (event === 'change') { - addOneListener(self.pull, 'change', pullChange); - addOneListener(self.push, 'change', pushChange); - } else if (event === 'denied') { - addOneListener(self.pull, 'denied', pullDenied); - addOneListener(self.push, 'denied', pushDenied); - } else if (event === 'active') { - addOneListener(self.pull, 'active', pullActive); - addOneListener(self.push, 'active', pushActive); - } else if (event === 'paused') { - addOneListener(self.pull, 'paused', pullPaused); - addOneListener(self.push, 'paused', pushPaused); + function onBatch(batchKeys, batchValues, cursor) { + if (!cursor) { + return; } - }); - - this.on('removeListener', function (event) { - if (event === 'change') { - self.pull.removeListener('change', pullChange); - self.push.removeListener('change', pushChange); - } else if (event === 'denied') { - self.pull.removeListener('denied', pullDenied); - self.push.removeListener('denied', pushDenied); - } else if (event === 'active') { - self.pull.removeListener('active', pullActive); - self.push.removeListener('active', pushActive); - } else if (event === 'paused') { - self.pull.removeListener('paused', pullPaused); - self.push.removeListener('paused', pushPaused); + processBatch(batchValues); + if (results.length < limit) { + cursor.continue(); } - }); + } - this.pull.on('removeListener', removeAll('pull')); - this.push.on('removeListener', removeAll('push')); + function onGetAll(e) { + var values = e.target.result; + if (opts.descending) { + values = values.reverse(); + } + processBatch(values); + } - var promise = Promise.all([ - this.push, - this.pull - ]).then(function (resp) { - var out = { - push: resp[0], - pull: resp[1] + function onResultsReady() { + var returnVal = { + total_rows: docCount, + offset: opts.skip, + rows: results }; - self.emit('complete', out); - if (callback) { - callback(null, out); + + /* istanbul ignore if */ + if (opts.update_seq && updateSeq !== undefined) { + returnVal.update_seq = updateSeq; } - self.removeAllListeners(); - return out; - }, function (err) { - self.cancel(); - if (callback) { - // if there's a callback, then the callback can receive - // the error event - callback(err); + callback(null, returnVal); + } + + function onTxnComplete() { + if (opts.attachments) { + postProcessAttachments(results, opts.binary).then(onResultsReady); } else { - // if there's no callback, then we're safe to emit an error - // event, which would otherwise throw an unhandled error - // due to 'error' being a special event in EventEmitters - self.emit('error', err); - } - self.removeAllListeners(); - if (callback) { - // no sense throwing if we're already emitting an 'error' event - throw err; + onResultsReady(); } + } + + // don't bother doing any requests if start > end or limit === 0 + if (keyRangeError || limit === 0) { + return; + } + if (keys) { + return allDocsKeys(opts.keys, docStore, onBatch); + } + if (limit === -1) { // just fetch everything + return getAll(docStore, keyRange, onGetAll); + } + // else do a cursor + // choose a batch size based on the skip, since we'll need to skip that many + runBatchedCursor(docStore, keyRange, opts.descending, limit + skip, onBatch); +} + +// +// Blobs are not supported in all versions of IndexedDB, notably +// Chrome <37 and Android <5. In those versions, storing a blob will throw. +// +// Various other blob bugs exist in Chrome v37-42 (inclusive). +// Detecting them is expensive and confusing to users, and Chrome 37-42 +// is at very low usage worldwide, so we do a hacky userAgent check instead. +// +// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120 +// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916 +// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836 +// +function checkBlobSupport(txn) { + return new Promise(function (resolve) { + var blob$$1 = createBlob(['']); + var req = txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob$$1, 'key'); + + req.onsuccess = function () { + var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/); + var matchedEdge = navigator.userAgent.match(/Edge\//); + // MS Edge pretends to be Chrome 42: + // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx + resolve(matchedEdge || !matchedChrome || + parseInt(matchedChrome[1], 10) >= 43); + }; + + req.onerror = txn.onabort = function (e) { + // If the transaction aborts now its due to not being able to + // write to the database, likely due to the disk being full + e.preventDefault(); + e.stopPropagation(); + resolve(false); + }; + }).catch(function () { + return false; // error, so assume unsupported }); +} - this.then = function (success, err) { - return promise.then(success, err); +function countDocs(txn, cb) { + var index = txn.objectStore(DOC_STORE).index('deletedOrLocal'); + index.count(IDBKeyRange.only('0')).onsuccess = function (e) { + cb(e.target.result); }; +} - this.catch = function (err) { - return promise.catch(err); - }; +// This task queue ensures that IDB open calls are done in their own tick + +var running = false; +var queue = []; + +function tryCode(fun, err, res, PouchDB) { + try { + fun(err, res); + } catch (err) { + // Shouldn't happen, but in some odd cases + // IndexedDB implementations might throw a sync + // error, in which case this will at least log it. + PouchDB.emit('error', err); + } } -Sync.prototype.cancel = function () { - if (!this.canceled) { - this.canceled = true; - this.push.cancel(); - this.pull.cancel(); +function applyNext() { + if (running || !queue.length) { + return; } -}; + running = true; + queue.shift()(); +} -function replication(PouchDB) { - PouchDB.replicate = replicateWrapper; - PouchDB.sync = sync; +function enqueueTask(action, callback, PouchDB) { + queue.push(function runAction() { + action(function runCallback(err, res) { + tryCode(callback, err, res, PouchDB); + running = false; + immediate__WEBPACK_IMPORTED_MODULE_1___default()(function runNext() { + applyNext(PouchDB); + }); + }); + }); + applyNext(); +} - Object.defineProperty(PouchDB.prototype, 'replicate', { - get: function () { - var self = this; - if (typeof this.replicateMethods === 'undefined') { - this.replicateMethods = { - from: function (other, opts, callback) { - return self.constructor.replicate(other, self, opts, callback); - }, - to: function (other, opts, callback) { - return self.constructor.replicate(self, other, opts, callback); - } - }; +function changes(opts, api, dbName, idb) { + opts = clone(opts); + + if (opts.continuous) { + var id = dbName + ':' + uuid(); + changesHandler.addListener(dbName, id, api, opts); + changesHandler.notify(dbName); + return { + cancel: function () { + changesHandler.removeListener(dbName, id); } - return this.replicateMethods; - } - }); + }; + } - PouchDB.prototype.sync = function (dbName, opts, callback) { - return this.constructor.sync(this, dbName, opts, callback); - }; -} + var docIds = opts.doc_ids && new ExportedSet(opts.doc_ids); -PouchDB.plugin(IDBPouch) - .plugin(HttpPouch$1) - .plugin(mapreduce) - .plugin(replication); + opts.since = opts.since || 0; + var lastSeq = opts.since; -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PouchDB); + var limit = 'limit' in opts ? opts.limit : -1; + if (limit === 0) { + limit = 1; // per CouchDB _changes spec + } + var results = []; + var numResults = 0; + var filter = filterChange(opts); + var docIdsToMetadata = new ExportedMap(); -/***/ }), -/* 483 */ -/***/ ((module) => { + var txn; + var bySeqStore; + var docStore; + var docIdRevIndex; -"use strict"; + function onBatch(batchKeys, batchValues, cursor) { + if (!cursor || !batchKeys.length) { // done + return; + } + var winningDocs = new Array(batchKeys.length); + var metadatas = new Array(batchKeys.length); -module.exports = argsArray; + function processMetadataAndWinningDoc(metadata, winningDoc) { + var change = opts.processChange(winningDoc, metadata, opts); + lastSeq = change.seq = metadata.seq; -function argsArray(fun) { - return function () { - var len = arguments.length; - if (len) { - var args = []; - var i = -1; - while (++i < len) { - args[i] = arguments[i]; + var filtered = filter(change); + if (typeof filtered === 'object') { // anything but true/false indicates error + return Promise.reject(filtered); } - return fun.call(this, args); - } else { - return fun.call(this, []); - } - }; -} -/***/ }), -/* 484 */ -/***/ ((module) => { + if (!filtered) { + return Promise.resolve(); + } + numResults++; + if (opts.return_docs) { + results.push(change); + } + // process the attachment immediately + // for the benefit of live listeners + if (opts.attachments && opts.include_docs) { + return new Promise(function (resolve) { + fetchAttachmentsIfNecessary(winningDoc, opts, txn, function () { + postProcessAttachments([change], opts.binary).then(function () { + resolve(change); + }); + }); + }); + } else { + return Promise.resolve(change); + } + } -"use strict"; + function onBatchDone() { + var promises = []; + for (var i = 0, len = winningDocs.length; i < len; i++) { + if (numResults === limit) { + break; + } + var winningDoc = winningDocs[i]; + if (!winningDoc) { + continue; + } + var metadata = metadatas[i]; + promises.push(processMetadataAndWinningDoc(metadata, winningDoc)); + } -var Mutation = global.MutationObserver || global.WebKitMutationObserver; + Promise.all(promises).then(function (changes) { + for (var i = 0, len = changes.length; i < len; i++) { + if (changes[i]) { + opts.onChange(changes[i]); + } + } + }).catch(opts.complete); -var scheduleDrain; + if (numResults !== limit) { + cursor.continue(); + } + } -if (process.browser) { - if (Mutation) { - var called = 0; - var observer = new Mutation(nextTick); - var element = global.document.createTextNode(''); - observer.observe(element, { - characterData: true + // Fetch all metadatas/winningdocs from this batch in parallel, then process + // them all only once all data has been collected. This is done in parallel + // because it's faster than doing it one-at-a-time. + var numDone = 0; + batchValues.forEach(function (value, i) { + var doc = decodeDoc(value); + var seq = batchKeys[i]; + fetchWinningDocAndMetadata(doc, seq, function (metadata, winningDoc) { + metadatas[i] = metadata; + winningDocs[i] = winningDoc; + if (++numDone === batchKeys.length) { + onBatchDone(); + } + }); }); - scheduleDrain = function () { - element.data = (called = ++called % 2); - }; - } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') { - var channel = new global.MessageChannel(); - channel.port1.onmessage = nextTick; - scheduleDrain = function () { - channel.port2.postMessage(0); - }; - } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) { - scheduleDrain = function () { + } - // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted - // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. - var scriptEl = global.document.createElement('script'); - scriptEl.onreadystatechange = function () { - nextTick(); + function onGetMetadata(doc, seq, metadata, cb) { + if (metadata.seq !== seq) { + // some other seq is later + return cb(); + } - scriptEl.onreadystatechange = null; - scriptEl.parentNode.removeChild(scriptEl); - scriptEl = null; - }; - global.document.documentElement.appendChild(scriptEl); + if (metadata.winningRev === doc._rev) { + // this is the winning doc + return cb(metadata, doc); + } + + // fetch winning doc in separate request + var docIdRev = doc._id + '::' + metadata.winningRev; + var req = docIdRevIndex.get(docIdRev); + req.onsuccess = function (e) { + cb(metadata, decodeDoc(e.target.result)); }; - } else { - scheduleDrain = function () { - setTimeout(nextTick, 0); + } + + function fetchWinningDocAndMetadata(doc, seq, cb) { + if (docIds && !docIds.has(doc._id)) { + return cb(); + } + + var metadata = docIdsToMetadata.get(doc._id); + if (metadata) { // cached + return onGetMetadata(doc, seq, metadata, cb); + } + // metadata not cached, have to go fetch it + docStore.get(doc._id).onsuccess = function (e) { + metadata = decodeMetadata(e.target.result); + docIdsToMetadata.set(doc._id, metadata); + onGetMetadata(doc, seq, metadata, cb); }; } -} else { - scheduleDrain = function () { - process.nextTick(nextTick); - }; -} -var draining; -var queue = []; -//named nextTick for less confusing stack traces -function nextTick() { - draining = true; - var i, oldQueue; - var len = queue.length; - while (len) { - oldQueue = queue; - queue = []; - i = -1; - while (++i < len) { - oldQueue[i](); + function finish() { + opts.complete(null, { + results: results, + last_seq: lastSeq + }); + } + + function onTxnComplete() { + if (!opts.continuous && opts.attachments) { + // cannot guarantee that postProcessing was already done, + // so do it again + postProcessAttachments(results).then(finish); + } else { + finish(); } - len = queue.length; } - draining = false; -} -module.exports = immediate; -function immediate(task) { - if (queue.push(task) === 1 && !draining) { - scheduleDrain(); + var objectStores = [DOC_STORE, BY_SEQ_STORE]; + if (opts.attachments) { + objectStores.push(ATTACH_STORE); } -} + var txnResult = openTransactionSafely(idb, objectStores, 'readonly'); + if (txnResult.error) { + return opts.complete(txnResult.error); + } + txn = txnResult.txn; + txn.onabort = idbError(opts.complete); + txn.oncomplete = onTxnComplete; + bySeqStore = txn.objectStore(BY_SEQ_STORE); + docStore = txn.objectStore(DOC_STORE); + docIdRevIndex = bySeqStore.index('_doc_id_rev'); -/***/ }), -/* 485 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var keyRange = (opts.since && !opts.descending) ? + IDBKeyRange.lowerBound(opts.since, true) : null; -try { - var util = __webpack_require__(64); - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - module.exports = __webpack_require__(486); + runBatchedCursor(bySeqStore, keyRange, opts.descending, limit, onBatch); } +var cachedDBs = new ExportedMap(); +var blobSupportPromise; +var openReqList = new ExportedMap(); -/***/ }), -/* 486 */ -/***/ ((module) => { +function IdbPouch(opts, callback) { + var api = this; -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } + enqueueTask(function (thisCallback) { + init(api, opts, thisCallback); + }, callback, api.constructor); } +function init(api, opts, callback) { -/***/ }), -/* 487 */ -/***/ ((module) => { - -(function (factory) { - if (true) { - // Node/CommonJS - module.exports = factory(); - } else { var glob; } -}(function (undefined) { + var dbName = opts.name; - 'use strict'; + var idb = null; + api._meta = null; - /* - * Fastest md5 implementation around (JKM md5). - * Credits: Joseph Myers - * - * @see http://www.myersdaily.org/joseph/javascript/md5-text.html - * @see http://jsperf.com/md5-shootout/7 - */ + // called when creating a fresh new database + function createSchema(db) { + var docStore = db.createObjectStore(DOC_STORE, {keyPath : 'id'}); + db.createObjectStore(BY_SEQ_STORE, {autoIncrement: true}) + .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true}); + db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'}); + db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false}); + db.createObjectStore(DETECT_BLOB_SUPPORT_STORE); - /* this function is much faster, - so if possible we use it. Some IEs - are the only ones I know of that - need the idiotic second function, - generated by an if clause. */ - var add32 = function (a, b) { - return (a + b) & 0xFFFFFFFF; - }, - hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; + // added in v2 + docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false}); + // added in v3 + db.createObjectStore(LOCAL_STORE, {keyPath: '_id'}); - function cmn(q, a, b, x, s, t) { - a = add32(add32(a, q), add32(x, t)); - return add32((a << s) | (a >>> (32 - s)), b); - } + // added in v4 + var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE, + {autoIncrement: true}); + attAndSeqStore.createIndex('seq', 'seq'); + attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true}); + } - function md5cycle(x, k) { - var a = x[0], - b = x[1], - c = x[2], - d = x[3]; + // migration to version 2 + // unfortunately "deletedOrLocal" is a misnomer now that we no longer + // store local docs in the main doc-store, but whaddyagonnado + function addDeletedOrLocalIndex(txn, callback) { + var docStore = txn.objectStore(DOC_STORE); + docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false}); - a += (b & c | ~b & d) + k[0] - 680876936 | 0; - a = (a << 7 | a >>> 25) + b | 0; - d += (a & b | ~a & c) + k[1] - 389564586 | 0; - d = (d << 12 | d >>> 20) + a | 0; - c += (d & a | ~d & b) + k[2] + 606105819 | 0; - c = (c << 17 | c >>> 15) + d | 0; - b += (c & d | ~c & a) + k[3] - 1044525330 | 0; - b = (b << 22 | b >>> 10) + c | 0; - a += (b & c | ~b & d) + k[4] - 176418897 | 0; - a = (a << 7 | a >>> 25) + b | 0; - d += (a & b | ~a & c) + k[5] + 1200080426 | 0; - d = (d << 12 | d >>> 20) + a | 0; - c += (d & a | ~d & b) + k[6] - 1473231341 | 0; - c = (c << 17 | c >>> 15) + d | 0; - b += (c & d | ~c & a) + k[7] - 45705983 | 0; - b = (b << 22 | b >>> 10) + c | 0; - a += (b & c | ~b & d) + k[8] + 1770035416 | 0; - a = (a << 7 | a >>> 25) + b | 0; - d += (a & b | ~a & c) + k[9] - 1958414417 | 0; - d = (d << 12 | d >>> 20) + a | 0; - c += (d & a | ~d & b) + k[10] - 42063 | 0; - c = (c << 17 | c >>> 15) + d | 0; - b += (c & d | ~c & a) + k[11] - 1990404162 | 0; - b = (b << 22 | b >>> 10) + c | 0; - a += (b & c | ~b & d) + k[12] + 1804603682 | 0; - a = (a << 7 | a >>> 25) + b | 0; - d += (a & b | ~a & c) + k[13] - 40341101 | 0; - d = (d << 12 | d >>> 20) + a | 0; - c += (d & a | ~d & b) + k[14] - 1502002290 | 0; - c = (c << 17 | c >>> 15) + d | 0; - b += (c & d | ~c & a) + k[15] + 1236535329 | 0; - b = (b << 22 | b >>> 10) + c | 0; + docStore.openCursor().onsuccess = function (event) { + var cursor = event.target.result; + if (cursor) { + var metadata = cursor.value; + var deleted = isDeleted(metadata); + metadata.deletedOrLocal = deleted ? "1" : "0"; + docStore.put(metadata); + cursor.continue(); + } else { + callback(); + } + }; + } - a += (b & d | c & ~d) + k[1] - 165796510 | 0; - a = (a << 5 | a >>> 27) + b | 0; - d += (a & c | b & ~c) + k[6] - 1069501632 | 0; - d = (d << 9 | d >>> 23) + a | 0; - c += (d & b | a & ~b) + k[11] + 643717713 | 0; - c = (c << 14 | c >>> 18) + d | 0; - b += (c & a | d & ~a) + k[0] - 373897302 | 0; - b = (b << 20 | b >>> 12) + c | 0; - a += (b & d | c & ~d) + k[5] - 701558691 | 0; - a = (a << 5 | a >>> 27) + b | 0; - d += (a & c | b & ~c) + k[10] + 38016083 | 0; - d = (d << 9 | d >>> 23) + a | 0; - c += (d & b | a & ~b) + k[15] - 660478335 | 0; - c = (c << 14 | c >>> 18) + d | 0; - b += (c & a | d & ~a) + k[4] - 405537848 | 0; - b = (b << 20 | b >>> 12) + c | 0; - a += (b & d | c & ~d) + k[9] + 568446438 | 0; - a = (a << 5 | a >>> 27) + b | 0; - d += (a & c | b & ~c) + k[14] - 1019803690 | 0; - d = (d << 9 | d >>> 23) + a | 0; - c += (d & b | a & ~b) + k[3] - 187363961 | 0; - c = (c << 14 | c >>> 18) + d | 0; - b += (c & a | d & ~a) + k[8] + 1163531501 | 0; - b = (b << 20 | b >>> 12) + c | 0; - a += (b & d | c & ~d) + k[13] - 1444681467 | 0; - a = (a << 5 | a >>> 27) + b | 0; - d += (a & c | b & ~c) + k[2] - 51403784 | 0; - d = (d << 9 | d >>> 23) + a | 0; - c += (d & b | a & ~b) + k[7] + 1735328473 | 0; - c = (c << 14 | c >>> 18) + d | 0; - b += (c & a | d & ~a) + k[12] - 1926607734 | 0; - b = (b << 20 | b >>> 12) + c | 0; + // migration to version 3 (part 1) + function createLocalStoreSchema(db) { + db.createObjectStore(LOCAL_STORE, {keyPath: '_id'}) + .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true}); + } - a += (b ^ c ^ d) + k[5] - 378558 | 0; - a = (a << 4 | a >>> 28) + b | 0; - d += (a ^ b ^ c) + k[8] - 2022574463 | 0; - d = (d << 11 | d >>> 21) + a | 0; - c += (d ^ a ^ b) + k[11] + 1839030562 | 0; - c = (c << 16 | c >>> 16) + d | 0; - b += (c ^ d ^ a) + k[14] - 35309556 | 0; - b = (b << 23 | b >>> 9) + c | 0; - a += (b ^ c ^ d) + k[1] - 1530992060 | 0; - a = (a << 4 | a >>> 28) + b | 0; - d += (a ^ b ^ c) + k[4] + 1272893353 | 0; - d = (d << 11 | d >>> 21) + a | 0; - c += (d ^ a ^ b) + k[7] - 155497632 | 0; - c = (c << 16 | c >>> 16) + d | 0; - b += (c ^ d ^ a) + k[10] - 1094730640 | 0; - b = (b << 23 | b >>> 9) + c | 0; - a += (b ^ c ^ d) + k[13] + 681279174 | 0; - a = (a << 4 | a >>> 28) + b | 0; - d += (a ^ b ^ c) + k[0] - 358537222 | 0; - d = (d << 11 | d >>> 21) + a | 0; - c += (d ^ a ^ b) + k[3] - 722521979 | 0; - c = (c << 16 | c >>> 16) + d | 0; - b += (c ^ d ^ a) + k[6] + 76029189 | 0; - b = (b << 23 | b >>> 9) + c | 0; - a += (b ^ c ^ d) + k[9] - 640364487 | 0; - a = (a << 4 | a >>> 28) + b | 0; - d += (a ^ b ^ c) + k[12] - 421815835 | 0; - d = (d << 11 | d >>> 21) + a | 0; - c += (d ^ a ^ b) + k[15] + 530742520 | 0; - c = (c << 16 | c >>> 16) + d | 0; - b += (c ^ d ^ a) + k[2] - 995338651 | 0; - b = (b << 23 | b >>> 9) + c | 0; + // migration to version 3 (part 2) + function migrateLocalStore(txn, cb) { + var localStore = txn.objectStore(LOCAL_STORE); + var docStore = txn.objectStore(DOC_STORE); + var seqStore = txn.objectStore(BY_SEQ_STORE); - a += (c ^ (b | ~d)) + k[0] - 198630844 | 0; - a = (a << 6 | a >>> 26) + b | 0; - d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0; - d = (d << 10 | d >>> 22) + a | 0; - c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0; - c = (c << 15 | c >>> 17) + d | 0; - b += (d ^ (c | ~a)) + k[5] - 57434055 | 0; - b = (b << 21 |b >>> 11) + c | 0; - a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0; - a = (a << 6 | a >>> 26) + b | 0; - d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0; - d = (d << 10 | d >>> 22) + a | 0; - c += (a ^ (d | ~b)) + k[10] - 1051523 | 0; - c = (c << 15 | c >>> 17) + d | 0; - b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0; - b = (b << 21 |b >>> 11) + c | 0; - a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0; - a = (a << 6 | a >>> 26) + b | 0; - d += (b ^ (a | ~c)) + k[15] - 30611744 | 0; - d = (d << 10 | d >>> 22) + a | 0; - c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0; - c = (c << 15 | c >>> 17) + d | 0; - b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0; - b = (b << 21 |b >>> 11) + c | 0; - a += (c ^ (b | ~d)) + k[4] - 145523070 | 0; - a = (a << 6 | a >>> 26) + b | 0; - d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0; - d = (d << 10 | d >>> 22) + a | 0; - c += (a ^ (d | ~b)) + k[2] + 718787259 | 0; - c = (c << 15 | c >>> 17) + d | 0; - b += (d ^ (c | ~a)) + k[9] - 343485551 | 0; - b = (b << 21 | b >>> 11) + c | 0; + var cursor = docStore.openCursor(); + cursor.onsuccess = function (event) { + var cursor = event.target.result; + if (cursor) { + var metadata = cursor.value; + var docId = metadata.id; + var local = isLocalId(docId); + var rev = winningRev(metadata); + if (local) { + var docIdRev = docId + "::" + rev; + // remove all seq entries + // associated with this docId + var start = docId + "::"; + var end = docId + "::~"; + var index = seqStore.index('_doc_id_rev'); + var range = IDBKeyRange.bound(start, end, false, false); + var seqCursor = index.openCursor(range); + seqCursor.onsuccess = function (e) { + seqCursor = e.target.result; + if (!seqCursor) { + // done + docStore.delete(cursor.primaryKey); + cursor.continue(); + } else { + var data = seqCursor.value; + if (data._doc_id_rev === docIdRev) { + localStore.put(data); + } + seqStore.delete(seqCursor.primaryKey); + seqCursor.continue(); + } + }; + } else { + cursor.continue(); + } + } else if (cb) { + cb(); + } + }; + } - x[0] = a + x[0] | 0; - x[1] = b + x[1] | 0; - x[2] = c + x[2] | 0; - x[3] = d + x[3] | 0; - } + // migration to version 4 (part 1) + function addAttachAndSeqStore(db) { + var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE, + {autoIncrement: true}); + attAndSeqStore.createIndex('seq', 'seq'); + attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true}); + } - function md5blk(s) { - var md5blks = [], - i; /* Andy King said do it this way. */ + // migration to version 4 (part 2) + function migrateAttsAndSeqs(txn, callback) { + var seqStore = txn.objectStore(BY_SEQ_STORE); + var attStore = txn.objectStore(ATTACH_STORE); + var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE); - for (i = 0; i < 64; i += 4) { - md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24); + // need to actually populate the table. this is the expensive part, + // so as an optimization, check first that this database even + // contains attachments + var req = attStore.count(); + req.onsuccess = function (e) { + var count = e.target.result; + if (!count) { + return callback(); // done + } + + seqStore.openCursor().onsuccess = function (e) { + var cursor = e.target.result; + if (!cursor) { + return callback(); // done } - return md5blks; - } + var doc = cursor.value; + var seq = cursor.primaryKey; + var atts = Object.keys(doc._attachments || {}); + var digestMap = {}; + for (var j = 0; j < atts.length; j++) { + var att = doc._attachments[atts[j]]; + digestMap[att.digest] = true; // uniq digests, just in case + } + var digests = Object.keys(digestMap); + for (j = 0; j < digests.length; j++) { + var digest = digests[j]; + attAndSeqStore.put({ + seq: seq, + digestSeq: digest + '::' + seq + }); + } + cursor.continue(); + }; + }; + } - function md5blk_array(a) { - var md5blks = [], - i; /* Andy King said do it this way. */ + // migration to version 5 + // Instead of relying on on-the-fly migration of metadata, + // this brings the doc-store to its modern form: + // - metadata.winningrev + // - metadata.seq + // - stringify the metadata when storing it + function migrateMetadata(txn) { - for (i = 0; i < 64; i += 4) { - md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24); - } - return md5blks; + function decodeMetadataCompat(storedObject) { + if (!storedObject.data) { + // old format, when we didn't store it stringified + storedObject.deleted = storedObject.deletedOrLocal === '1'; + return storedObject; + } + return decodeMetadata(storedObject); } - function md51(s) { - var n = s.length, - state = [1732584193, -271733879, -1732584194, 271733878], - i, - length, - tail, - tmp, - lo, - hi; + // ensure that every metadata has a winningRev and seq, + // which was previously created on-the-fly but better to migrate + var bySeqStore = txn.objectStore(BY_SEQ_STORE); + var docStore = txn.objectStore(DOC_STORE); + var cursor = docStore.openCursor(); + cursor.onsuccess = function (e) { + var cursor = e.target.result; + if (!cursor) { + return; // done + } + var metadata = decodeMetadataCompat(cursor.value); - for (i = 64; i <= n; i += 64) { - md5cycle(state, md5blk(s.substring(i - 64, i))); - } - s = s.substring(i - 64); - length = s.length; - tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - for (i = 0; i < length; i += 1) { - tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3); - } - tail[i >> 2] |= 0x80 << ((i % 4) << 3); - if (i > 55) { - md5cycle(state, tail); - for (i = 0; i < 16; i += 1) { - tail[i] = 0; - } - } + metadata.winningRev = metadata.winningRev || + winningRev(metadata); - // Beware that the final length might not fit in 32 bits so we take care of that - tmp = n * 8; - tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); - lo = parseInt(tmp[2], 16); - hi = parseInt(tmp[1], 16) || 0; + function fetchMetadataSeq() { + // metadata.seq was added post-3.2.0, so if it's missing, + // we need to fetch it manually + var start = metadata.id + '::'; + var end = metadata.id + '::\uffff'; + var req = bySeqStore.index('_doc_id_rev').openCursor( + IDBKeyRange.bound(start, end)); - tail[14] = lo; - tail[15] = hi; + var metadataSeq = 0; + req.onsuccess = function (e) { + var cursor = e.target.result; + if (!cursor) { + metadata.seq = metadataSeq; + return onGetMetadataSeq(); + } + var seq = cursor.primaryKey; + if (seq > metadataSeq) { + metadataSeq = seq; + } + cursor.continue(); + }; + } - md5cycle(state, tail); - return state; - } + function onGetMetadataSeq() { + var metadataToStore = encodeMetadata(metadata, + metadata.winningRev, metadata.deleted); - function md51_array(a) { - var n = a.length, - state = [1732584193, -271733879, -1732584194, 271733878], - i, - length, - tail, - tmp, - lo, - hi; + var req = docStore.put(metadataToStore); + req.onsuccess = function () { + cursor.continue(); + }; + } - for (i = 64; i <= n; i += 64) { - md5cycle(state, md5blk_array(a.subarray(i - 64, i))); - } + if (metadata.seq) { + return onGetMetadataSeq(); + } - // Not sure if it is a bug, however IE10 will always produce a sub array of length 1 - // containing the last element of the parent array if the sub array specified starts - // beyond the length of the parent array - weird. - // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue - a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0); + fetchMetadataSeq(); + }; - length = a.length; - tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - for (i = 0; i < length; i += 1) { - tail[i >> 2] |= a[i] << ((i % 4) << 3); - } + } - tail[i >> 2] |= 0x80 << ((i % 4) << 3); - if (i > 55) { - md5cycle(state, tail); - for (i = 0; i < 16; i += 1) { - tail[i] = 0; - } - } + api._remote = false; + api.type = function () { + return 'idb'; + }; - // Beware that the final length might not fit in 32 bits so we take care of that - tmp = n * 8; - tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); - lo = parseInt(tmp[2], 16); - hi = parseInt(tmp[1], 16) || 0; + api._id = toPromise(function (callback) { + callback(null, api._meta.instanceId); + }); - tail[14] = lo; - tail[15] = hi; + api._bulkDocs = function idb_bulkDocs(req, reqOpts, callback) { + idbBulkDocs(opts, req, reqOpts, api, idb, callback); + }; - md5cycle(state, tail); + // First we look up the metadata in the ids database, then we fetch the + // current revision(s) from the by sequence store + api._get = function idb_get(id, opts, callback) { + var doc; + var metadata; + var err; + var txn = opts.ctx; + if (!txn) { + var txnResult = openTransactionSafely(idb, + [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + txn = txnResult.txn; + } - return state; + function finish() { + callback(err, {doc: doc, metadata: metadata, ctx: txn}); } - function rhex(n) { - var s = '', - j; - for (j = 0; j < 4; j += 1) { - s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; + txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) { + metadata = decodeMetadata(e.target.result); + // we can determine the result here if: + // 1. there is no such document + // 2. the document is deleted and we don't ask about specific rev + // When we ask with opts.rev we expect the answer to be either + // doc (possibly with _deleted=true) or missing error + if (!metadata) { + err = createError(MISSING_DOC, 'missing'); + return finish(); + } + + var rev; + if (!opts.rev) { + rev = metadata.winningRev; + var deleted = isDeleted(metadata); + if (deleted) { + err = createError(MISSING_DOC, "deleted"); + return finish(); } - return s; - } + } else { + rev = opts.latest ? latest(opts.rev, metadata) : opts.rev; + } - function hex(x) { - var i; - for (i = 0; i < x.length; i += 1) { - x[i] = rhex(x[i]); + var objectStore = txn.objectStore(BY_SEQ_STORE); + var key = metadata.id + '::' + rev; + + objectStore.index('_doc_id_rev').get(key).onsuccess = function (e) { + doc = e.target.result; + if (doc) { + doc = decodeDoc(doc); } - return x.join(''); - } + if (!doc) { + err = createError(MISSING_DOC, 'missing'); + return finish(); + } + finish(); + }; + }; + }; - // In some cases the fast add32 function cannot be used.. - if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') { - add32 = function (x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF), - msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); - }; + api._getAttachment = function (docId, attachId, attachment, opts, callback) { + var txn; + if (opts.ctx) { + txn = opts.ctx; + } else { + var txnResult = openTransactionSafely(idb, + [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + txn = txnResult.txn; } + var digest = attachment.digest; + var type = attachment.content_type; - // --------------------------------------------------- + txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) { + var body = e.target.result.body; + readBlobData(body, type, opts.binary, function (blobData) { + callback(null, blobData); + }); + }; + }; - /** - * ArrayBuffer slice polyfill. - * - * @see https://github.com/ttaubert/node-arraybuffer-slice - */ + api._info = function idb_info(callback) { + var updateSeq; + var docCount; - if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) { - (function () { - function clamp(val, length) { - val = (val | 0) || 0; + var txnResult = openTransactionSafely(idb, [META_STORE, BY_SEQ_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + var txn = txnResult.txn; + txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) { + docCount = e.target.result.docCount; + }; + txn.objectStore(BY_SEQ_STORE).openCursor(null, 'prev').onsuccess = function (e) { + var cursor = e.target.result; + updateSeq = cursor ? cursor.key : 0; + }; - if (val < 0) { - return Math.max(val + length, 0); - } + txn.oncomplete = function () { + callback(null, { + doc_count: docCount, + update_seq: updateSeq, + // for debugging + idb_attachment_format: (api._meta.blobSupport ? 'binary' : 'base64') + }); + }; + }; - return Math.min(val, length); - } + api._allDocs = function idb_allDocs(opts, callback) { + idbAllDocs(opts, idb, callback); + }; - ArrayBuffer.prototype.slice = function (from, to) { - var length = this.byteLength, - begin = clamp(from, length), - end = length, - num, - target, - targetArray, - sourceArray; + api._changes = function idbChanges(opts) { + return changes(opts, api, dbName, idb); + }; - if (to !== undefined) { - end = clamp(to, length); - } + api._close = function (callback) { + // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close + // "Returns immediately and closes the connection in a separate thread..." + idb.close(); + cachedDBs.delete(dbName); + callback(); + }; - if (begin > end) { - return new ArrayBuffer(0); - } + api._getRevisionTree = function (docId, callback) { + var txnResult = openTransactionSafely(idb, [DOC_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); + } + var txn = txnResult.txn; + var req = txn.objectStore(DOC_STORE).get(docId); + req.onsuccess = function (event) { + var doc = decodeMetadata(event.target.result); + if (!doc) { + callback(createError(MISSING_DOC)); + } else { + callback(null, doc.rev_tree); + } + }; + }; - num = end - begin; - target = new ArrayBuffer(num); - targetArray = new Uint8Array(target); + // This function removes revisions of document docId + // which are listed in revs and sets this document + // revision to to rev_tree + api._doCompaction = function (docId, revs, callback) { + var stores = [ + DOC_STORE, + BY_SEQ_STORE, + ATTACH_STORE, + ATTACH_AND_SEQ_STORE + ]; + var txnResult = openTransactionSafely(idb, stores, 'readwrite'); + if (txnResult.error) { + return callback(txnResult.error); + } + var txn = txnResult.txn; - sourceArray = new Uint8Array(this, begin, num); - targetArray.set(sourceArray); + var docStore = txn.objectStore(DOC_STORE); - return target; - }; - })(); + docStore.get(docId).onsuccess = function (event) { + var metadata = decodeMetadata(event.target.result); + traverseRevTree(metadata.rev_tree, function (isLeaf, pos, + revHash, ctx, opts) { + var rev = pos + '-' + revHash; + if (revs.indexOf(rev) !== -1) { + opts.status = 'missing'; + } + }); + compactRevs(revs, docId, txn); + var winningRev$$1 = metadata.winningRev; + var deleted = metadata.deleted; + txn.objectStore(DOC_STORE).put( + encodeMetadata(metadata, winningRev$$1, deleted)); + }; + txn.onabort = idbError(callback); + txn.oncomplete = function () { + callback(); + }; + }; + + + api._getLocal = function (id, callback) { + var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readonly'); + if (txnResult.error) { + return callback(txnResult.error); } + var tx = txnResult.txn; + var req = tx.objectStore(LOCAL_STORE).get(id); - // --------------------------------------------------- + req.onerror = idbError(callback); + req.onsuccess = function (e) { + var doc = e.target.result; + if (!doc) { + callback(createError(MISSING_DOC)); + } else { + delete doc['_doc_id_rev']; // for backwards compat + callback(null, doc); + } + }; + }; - /** - * Helpers. - */ + api._putLocal = function (doc, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + delete doc._revisions; // ignore this, trust the rev + var oldRev = doc._rev; + var id = doc._id; + if (!oldRev) { + doc._rev = '0-1'; + } else { + doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1); + } - function toUtf8(str) { - if (/[\u0080-\uFFFF]/.test(str)) { - str = unescape(encodeURIComponent(str)); + var tx = opts.ctx; + var ret; + if (!tx) { + var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite'); + if (txnResult.error) { + return callback(txnResult.error); + } + tx = txnResult.txn; + tx.onerror = idbError(callback); + tx.oncomplete = function () { + if (ret) { + callback(null, ret); } + }; + } - return str; + var oStore = tx.objectStore(LOCAL_STORE); + var req; + if (oldRev) { + req = oStore.get(id); + req.onsuccess = function (e) { + var oldDoc = e.target.result; + if (!oldDoc || oldDoc._rev !== oldRev) { + callback(createError(REV_CONFLICT)); + } else { // update + var req = oStore.put(doc); + req.onsuccess = function () { + ret = {ok: true, id: doc._id, rev: doc._rev}; + if (opts.ctx) { // return immediately + callback(null, ret); + } + }; + } + }; + } else { // new doc + req = oStore.add(doc); + req.onerror = function (e) { + // constraint error, already exists + callback(createError(REV_CONFLICT)); + e.preventDefault(); // avoid transaction abort + e.stopPropagation(); // avoid transaction onerror + }; + req.onsuccess = function () { + ret = {ok: true, id: doc._id, rev: doc._rev}; + if (opts.ctx) { // return immediately + callback(null, ret); + } + }; } + }; - function utf8Str2ArrayBuffer(str, returnUInt8Array) { - var length = str.length, - buff = new ArrayBuffer(length), - arr = new Uint8Array(buff), - i; + api._removeLocal = function (doc, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + var tx = opts.ctx; + if (!tx) { + var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite'); + if (txnResult.error) { + return callback(txnResult.error); + } + tx = txnResult.txn; + tx.oncomplete = function () { + if (ret) { + callback(null, ret); + } + }; + } + var ret; + var id = doc._id; + var oStore = tx.objectStore(LOCAL_STORE); + var req = oStore.get(id); - for (i = 0; i < length; i += 1) { - arr[i] = str.charCodeAt(i); + req.onerror = idbError(callback); + req.onsuccess = function (e) { + var oldDoc = e.target.result; + if (!oldDoc || oldDoc._rev !== doc._rev) { + callback(createError(MISSING_DOC)); + } else { + oStore.delete(id); + ret = {ok: true, id: id, rev: '0-0'}; + if (opts.ctx) { // return immediately + callback(null, ret); } + } + }; + }; - return returnUInt8Array ? arr : buff; - } + api._destroy = function (opts, callback) { + changesHandler.removeAllListeners(dbName); - function arrayBuffer2Utf8Str(buff) { - return String.fromCharCode.apply(null, new Uint8Array(buff)); + //Close open request for "dbName" database to fix ie delay. + var openReq = openReqList.get(dbName); + if (openReq && openReq.result) { + openReq.result.close(); + cachedDBs.delete(dbName); } + var req = indexedDB.deleteDatabase(dbName); - function concatenateArrayBuffers(first, second, returnUInt8Array) { - var result = new Uint8Array(first.byteLength + second.byteLength); + req.onsuccess = function () { + //Remove open request from the list. + openReqList.delete(dbName); + if (hasLocalStorage() && (dbName in localStorage)) { + delete localStorage[dbName]; + } + callback(null, { 'ok': true }); + }; - result.set(new Uint8Array(first)); - result.set(new Uint8Array(second), first.byteLength); + req.onerror = idbError(callback); + }; - return returnUInt8Array ? result : result.buffer; - } + var cached = cachedDBs.get(dbName); - function hexToBinaryString(hex) { - var bytes = [], - length = hex.length, - x; + if (cached) { + idb = cached.idb; + api._meta = cached.global; + return immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { + callback(null, api); + }); + } - for (x = 0; x < length - 1; x += 2) { - bytes.push(parseInt(hex.substr(x, 2), 16)); - } + var req = indexedDB.open(dbName, ADAPTER_VERSION); + openReqList.set(dbName, req); - return String.fromCharCode.apply(String, bytes); + req.onupgradeneeded = function (e) { + var db = e.target.result; + if (e.oldVersion < 1) { + return createSchema(db); // new db, initial schema } + // do migrations - // --------------------------------------------------- - - /** - * SparkMD5 OOP implementation. - * - * Use this class to perform an incremental md5, otherwise use the - * static methods instead. - */ + var txn = e.currentTarget.transaction; + // these migrations have to be done in this function, before + // control is returned to the event loop, because IndexedDB - function SparkMD5() { - // call reset to init the instance - this.reset(); + if (e.oldVersion < 3) { + createLocalStoreSchema(db); // v2 -> v3 + } + if (e.oldVersion < 4) { + addAttachAndSeqStore(db); // v3 -> v4 } - /** - * Appends a string. - * A conversion will be applied if an utf8 string is detected. - * - * @param {String} str The string to be appended - * - * @return {SparkMD5} The instance itself - */ - SparkMD5.prototype.append = function (str) { - // Converts the string to utf8 bytes if necessary - // Then append as binary - this.appendBinary(toUtf8(str)); + var migrations = [ + addDeletedOrLocalIndex, // v1 -> v2 + migrateLocalStore, // v2 -> v3 + migrateAttsAndSeqs, // v3 -> v4 + migrateMetadata // v4 -> v5 + ]; - return this; - }; + var i = e.oldVersion; - /** - * Appends a binary string. - * - * @param {String} contents The binary string to be appended - * - * @return {SparkMD5} The instance itself - */ - SparkMD5.prototype.appendBinary = function (contents) { - this._buff += contents; - this._length += contents.length; + function next() { + var migration = migrations[i - 1]; + i++; + if (migration) { + migration(txn, next); + } + } - var length = this._buff.length, - i; + next(); + }; - for (i = 64; i <= length; i += 64) { - md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i))); - } + req.onsuccess = function (e) { - this._buff = this._buff.substring(i - 64); + idb = e.target.result; - return this; + idb.onversionchange = function () { + idb.close(); + cachedDBs.delete(dbName); }; - /** - * Finishes the incremental computation, reseting the internal state and - * returning the result. - * - * @param {Boolean} raw True to get the raw string, false to get the hex string - * - * @return {String} The result - */ - SparkMD5.prototype.end = function (raw) { - var buff = this._buff, - length = buff.length, - i, - tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - ret; + idb.onabort = function (e) { + guardedConsole('error', 'Database has a global failure', e.target.error); + idb.close(); + cachedDBs.delete(dbName); + }; - for (i = 0; i < length; i += 1) { - tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3); - } + // Do a few setup operations (in parallel as much as possible): + // 1. Fetch meta doc + // 2. Check blob support + // 3. Calculate docCount + // 4. Generate an instanceId if necessary + // 5. Store docCount and instanceId on meta doc - this._finish(tail, length); - ret = hex(this._hash); + var txn = idb.transaction([ + META_STORE, + DETECT_BLOB_SUPPORT_STORE, + DOC_STORE + ], 'readwrite'); - if (raw) { - ret = hexToBinaryString(ret); - } + var storedMetaDoc = false; + var metaDoc; + var docCount; + var blobSupport; + var instanceId; - this.reset(); + function completeSetup() { + if (typeof blobSupport === 'undefined' || !storedMetaDoc) { + return; + } + api._meta = { + name: dbName, + instanceId: instanceId, + blobSupport: blobSupport + }; - return ret; - }; + cachedDBs.set(dbName, { + idb: idb, + global: api._meta + }); + callback(null, api); + } - /** - * Resets the internal state of the computation. - * - * @return {SparkMD5} The instance itself - */ - SparkMD5.prototype.reset = function () { - this._buff = ''; - this._length = 0; - this._hash = [1732584193, -271733879, -1732584194, 271733878]; + function storeMetaDocIfReady() { + if (typeof docCount === 'undefined' || typeof metaDoc === 'undefined') { + return; + } + var instanceKey = dbName + '_id'; + if (instanceKey in metaDoc) { + instanceId = metaDoc[instanceKey]; + } else { + metaDoc[instanceKey] = instanceId = uuid(); + } + metaDoc.docCount = docCount; + txn.objectStore(META_STORE).put(metaDoc); + } - return this; + // + // fetch or generate the instanceId + // + txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) { + metaDoc = e.target.result || { id: META_STORE }; + storeMetaDocIfReady(); }; - /** - * Gets the internal state of the computation. - * - * @return {Object} The state - */ - SparkMD5.prototype.getState = function () { - return { - buff: this._buff, - length: this._length, - hash: this._hash - }; - }; + // + // countDocs + // + countDocs(txn, function (count) { + docCount = count; + storeMetaDocIfReady(); + }); - /** - * Gets the internal state of the computation. - * - * @param {Object} state The state - * - * @return {SparkMD5} The instance itself - */ - SparkMD5.prototype.setState = function (state) { - this._buff = state.buff; - this._length = state.length; - this._hash = state.hash; + // + // check blob support + // + if (!blobSupportPromise) { + // make sure blob support is only checked once + blobSupportPromise = checkBlobSupport(txn); + } - return this; - }; + blobSupportPromise.then(function (val) { + blobSupport = val; + completeSetup(); + }); - /** - * Releases memory used by the incremental buffer and other additional - * resources. If you plan to use the instance again, use reset instead. - */ - SparkMD5.prototype.destroy = function () { - delete this._hash; - delete this._buff; - delete this._length; + // only when the metadata put transaction has completed, + // consider the setup done + txn.oncomplete = function () { + storedMetaDoc = true; + completeSetup(); }; + txn.onabort = idbError(callback); + }; - /** - * Finish the final calculation based on the tail. - * - * @param {Array} tail The tail (will be modified) - * @param {Number} length The length of the remaining buffer - */ - SparkMD5.prototype._finish = function (tail, length) { - var i = length, - tmp, - lo, - hi; + req.onerror = function () { + var msg = 'Failed to open indexedDB, are you in private browsing mode?'; + guardedConsole('error', msg); + callback(createError(IDB_ERROR, msg)); + }; +} - tail[i >> 2] |= 0x80 << ((i % 4) << 3); - if (i > 55) { - md5cycle(this._hash, tail); - for (i = 0; i < 16; i += 1) { - tail[i] = 0; - } - } +IdbPouch.valid = function () { + // Following #7085 buggy idb versions (typically Safari < 10.1) are + // considered valid. - // Do the final computation based on the tail and length - // Beware that the final length may not fit in 32 bits so we take care of that - tmp = this._length * 8; - tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); - lo = parseInt(tmp[2], 16); - hi = parseInt(tmp[1], 16) || 0; + // On Firefox SecurityError is thrown while referencing indexedDB if cookies + // are not allowed. `typeof indexedDB` also triggers the error. + try { + // some outdated implementations of IDB that appear on Samsung + // and HTC Android devices <4.4 are missing IDBKeyRange + return typeof indexedDB !== 'undefined' && typeof IDBKeyRange !== 'undefined'; + } catch (e) { + return false; + } +}; - tail[14] = lo; - tail[15] = hi; - md5cycle(this._hash, tail); - }; +function IDBPouch (PouchDB) { + PouchDB.adapter('idb', IdbPouch, true); +} - /** - * Performs the md5 hash on a string. - * A conversion will be applied if utf8 string is detected. - * - * @param {String} str The string - * @param {Boolean} raw True to get the raw string, false to get the hex string - * - * @return {String} The result - */ - SparkMD5.hash = function (str, raw) { - // Converts the string to utf8 bytes if necessary - // Then compute it using the binary function - return SparkMD5.hashBinary(toUtf8(str), raw); - }; +// dead simple promise pool, inspired by https://github.com/timdp/es6-promise-pool +// but much smaller in code size. limits the number of concurrent promises that are executed - /** - * Performs the md5 hash on a binary string. - * - * @param {String} content The binary string - * @param {Boolean} raw True to get the raw string, false to get the hex string - * - * @return {String} The result - */ - SparkMD5.hashBinary = function (content, raw) { - var hash = md51(content), - ret = hex(hash); - return raw ? hexToBinaryString(ret) : ret; - }; +function pool(promiseFactories, limit) { + return new Promise(function (resolve, reject) { + var running = 0; + var current = 0; + var done = 0; + var len = promiseFactories.length; + var err; - // --------------------------------------------------- + function runNext() { + running++; + promiseFactories[current++]().then(onSuccess, onError); + } - /** - * SparkMD5 OOP implementation for array buffers. - * - * Use this class to perform an incremental md5 ONLY for array buffers. - */ - SparkMD5.ArrayBuffer = function () { - // call reset to init the instance - this.reset(); - }; + function doNext() { + if (++done === len) { + /* istanbul ignore if */ + if (err) { + reject(err); + } else { + resolve(); + } + } else { + runNextBatch(); + } + } - /** - * Appends an array buffer. - * - * @param {ArrayBuffer} arr The array to be appended - * - * @return {SparkMD5.ArrayBuffer} The instance itself - */ - SparkMD5.ArrayBuffer.prototype.append = function (arr) { - var buff = concatenateArrayBuffers(this._buff.buffer, arr, true), - length = buff.length, - i; + function onSuccess() { + running--; + doNext(); + } - this._length += arr.byteLength; + /* istanbul ignore next */ + function onError(thisErr) { + running--; + err = err || thisErr; + doNext(); + } - for (i = 64; i <= length; i += 64) { - md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i))); - } + function runNextBatch() { + while (running < limit && current < len) { + runNext(); + } + } - this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0); + runNextBatch(); + }); +} - return this; - }; +var CHANGES_BATCH_SIZE = 25; +var MAX_SIMULTANEOUS_REVS = 50; +var CHANGES_TIMEOUT_BUFFER = 5000; +var DEFAULT_HEARTBEAT = 10000; - /** - * Finishes the incremental computation, reseting the internal state and - * returning the result. - * - * @param {Boolean} raw True to get the raw string, false to get the hex string - * - * @return {String} The result - */ - SparkMD5.ArrayBuffer.prototype.end = function (raw) { - var buff = this._buff, - length = buff.length, - tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - i, - ret; +var supportsBulkGetMap = {}; - for (i = 0; i < length; i += 1) { - tail[i >> 2] |= buff[i] << ((i % 4) << 3); - } +function readAttachmentsAsBlobOrBuffer(row) { + var doc = row.doc || row.ok; + var atts = doc._attachments; + if (!atts) { + return; + } + Object.keys(atts).forEach(function (filename) { + var att = atts[filename]; + att.data = b64ToBluffer(att.data, att.content_type); + }); +} - this._finish(tail, length); - ret = hex(this._hash); +function encodeDocId(id) { + if (/^_design/.test(id)) { + return '_design/' + encodeURIComponent(id.slice(8)); + } + if (/^_local/.test(id)) { + return '_local/' + encodeURIComponent(id.slice(7)); + } + return encodeURIComponent(id); +} - if (raw) { - ret = hexToBinaryString(ret); - } +function preprocessAttachments$1(doc) { + if (!doc._attachments || !Object.keys(doc._attachments)) { + return Promise.resolve(); + } - this.reset(); + return Promise.all(Object.keys(doc._attachments).map(function (key) { + var attachment = doc._attachments[key]; + if (attachment.data && typeof attachment.data !== 'string') { + return new Promise(function (resolve) { + blobToBase64(attachment.data, resolve); + }).then(function (b64) { + attachment.data = b64; + }); + } + })); +} - return ret; - }; +function hasUrlPrefix(opts) { + if (!opts.prefix) { + return false; + } + var protocol = parseUri(opts.prefix).protocol; + return protocol === 'http' || protocol === 'https'; +} - /** - * Resets the internal state of the computation. - * - * @return {SparkMD5.ArrayBuffer} The instance itself - */ - SparkMD5.ArrayBuffer.prototype.reset = function () { - this._buff = new Uint8Array(0); - this._length = 0; - this._hash = [1732584193, -271733879, -1732584194, 271733878]; +// Get all the information you possibly can about the URI given by name and +// return it as a suitable object. +function getHost(name, opts) { + // encode db name if opts.prefix is a url (#5574) + if (hasUrlPrefix(opts)) { + var dbName = opts.name.substr(opts.prefix.length); + // Ensure prefix has a trailing slash + var prefix = opts.prefix.replace(/\/?$/, '/'); + name = prefix + encodeURIComponent(dbName); + } - return this; - }; + var uri = parseUri(name); + if (uri.user || uri.password) { + uri.auth = {username: uri.user, password: uri.password}; + } - /** - * Gets the internal state of the computation. - * - * @return {Object} The state - */ - SparkMD5.ArrayBuffer.prototype.getState = function () { - var state = SparkMD5.prototype.getState.call(this); + // Split the path part of the URI into parts using '/' as the delimiter + // after removing any leading '/' and any trailing '/' + var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/'); - // Convert buffer to a string - state.buff = arrayBuffer2Utf8Str(state.buff); + uri.db = parts.pop(); + // Prevent double encoding of URI component + if (uri.db.indexOf('%') === -1) { + uri.db = encodeURIComponent(uri.db); + } - return state; - }; + uri.path = parts.join('/'); - /** - * Gets the internal state of the computation. - * - * @param {Object} state The state - * - * @return {SparkMD5.ArrayBuffer} The instance itself - */ - SparkMD5.ArrayBuffer.prototype.setState = function (state) { - // Convert string to buffer - state.buff = utf8Str2ArrayBuffer(state.buff, true); + return uri; +} - return SparkMD5.prototype.setState.call(this, state); - }; +// Generate a URL with the host data given by opts and the given path +function genDBUrl(opts, path) { + return genUrl(opts, opts.db + '/' + path); +} - SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy; +// Generate a URL with the host data given by opts and the given path +function genUrl(opts, path) { + // If the host already has a path, then we need to have a path delimiter + // Otherwise, the path delimiter is the empty string + var pathDel = !opts.path ? '' : '/'; - SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish; + // If the host already has a path, then we need to have a path delimiter + // Otherwise, the path delimiter is the empty string + return opts.protocol + '://' + opts.host + + (opts.port ? (':' + opts.port) : '') + + '/' + opts.path + pathDel + path; +} - /** - * Performs the md5 hash on an array buffer. - * - * @param {ArrayBuffer} arr The array buffer - * @param {Boolean} raw True to get the raw string, false to get the hex one - * - * @return {String} The result - */ - SparkMD5.ArrayBuffer.hash = function (arr, raw) { - var hash = md51_array(new Uint8Array(arr)), - ret = hex(hash); +function paramsToStr(params) { + return '?' + Object.keys(params).map(function (k) { + return k + '=' + encodeURIComponent(params[k]); + }).join('&'); +} - return raw ? hexToBinaryString(ret) : ret; - }; +function shouldCacheBust(opts) { + var ua = (typeof navigator !== 'undefined' && navigator.userAgent) ? + navigator.userAgent.toLowerCase() : ''; + var isIE = ua.indexOf('msie') !== -1; + var isTrident = ua.indexOf('trident') !== -1; + var isEdge = ua.indexOf('edge') !== -1; + var isGET = !('method' in opts) || opts.method === 'GET'; + return (isIE || isTrident || isEdge) && isGET; +} - return SparkMD5; -})); +// Implements the PouchDB API for dealing with CouchDB instances over HTTP +function HttpPouch(opts, callback) { + // The functions that will be publicly available for HttpPouch + var api = this; -/***/ }), -/* 488 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var host = getHost(opts.name, opts); + var dbUrl = genDBUrl(host, ''); -var v1 = __webpack_require__(489); -var v4 = __webpack_require__(492); + opts = clone(opts); -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; + var ourFetch = function (url, options) { -module.exports = uuid; + options = options || {}; + options.headers = options.headers || new h(); + if (opts.auth || host.auth) { + var nAuth = opts.auth || host.auth; + var str = nAuth.username + ':' + nAuth.password; + var token = thisBtoa(unescape(encodeURIComponent(str))); + options.headers.set('Authorization', 'Basic ' + token); + } -/***/ }), -/* 489 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var headers = opts.headers || {}; + Object.keys(headers).forEach(function (key) { + options.headers.append(key, headers[key]); + }); -var rng = __webpack_require__(490); -var bytesToUuid = __webpack_require__(491); + /* istanbul ignore if */ + if (shouldCacheBust(options)) { + url += (url.indexOf('?') === -1 ? '?' : '&') + '_nonce=' + Date.now(); + } -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html + var fetchFun = opts.fetch || f$1; + return fetchFun(url, options); + }; -var _nodeId; -var _clockseq; + function adapterFun$$1(name, fun) { + return adapterFun(name, argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { + setup().then(function () { + return fun.apply(this, args); + }).catch(function (e) { + var callback = args.pop(); + callback(e); + }); + })).bind(api); + } -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; + function fetchJSON(url, options, callback) { -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; + var result = {}; - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + options = options || {}; + options.headers = options.headers || new h(); - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; + if (!options.headers.get('Content-Type')) { + options.headers.set('Content-Type', 'application/json'); } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + if (!options.headers.get('Accept')) { + options.headers.set('Accept', 'application/json'); } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + return ourFetch(url, options).then(function (response) { + result.ok = response.ok; + result.status = response.status; + return response.json(); + }).then(function (json) { + result.data = json; + if (!result.ok) { + result.data.status = result.status; + var err = generateErrorFromResponse(result.data); + if (callback) { + return callback(err); + } else { + throw err; + } + } - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + if (Array.isArray(result.data)) { + result.data = result.data.map(function (v) { + if (v.error || v.missing) { + return generateErrorFromResponse(v); + } else { + return v; + } + }); + } - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; + if (callback) { + callback(null, result.data); + } else { + return result; + } + }); } - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } + var setupPromise; - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } + function setup() { + if (opts.skip_setup) { + return Promise.resolve(); + } - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; + // If there is a setup in process or previous successful setup + // done then we will use that + // If previous setups have been rejected we will try again + if (setupPromise) { + return setupPromise; + } - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; + setupPromise = fetchJSON(dbUrl).catch(function (err) { + if (err && err.status && err.status === 404) { + // Doesnt exist, create it + explainError(404, 'PouchDB is just detecting if the remote exists.'); + return fetchJSON(dbUrl, {method: 'PUT'}); + } else { + return Promise.reject(err); + } + }).catch(function (err) { + // If we try to create a database that already exists, skipped in + // istanbul since its catching a race condition. + /* istanbul ignore if */ + if (err && err.status && err.status === 412) { + return true; + } + return Promise.reject(err); + }); - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; + setupPromise.catch(function () { + setupPromise = null; + }); - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; + return setupPromise; + } - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; + immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { + callback(null, api); + }); - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; + api._remote = true; - // `clock_seq_low` - b[i++] = clockseq & 0xff; + /* istanbul ignore next */ + api.type = function () { + return 'http'; + }; - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } + api.id = adapterFun$$1('id', function (callback) { + ourFetch(genUrl(host, '')).then(function (response) { + return response.json(); + }).then(function (result) { + var uuid$$1 = (result && result.uuid) ? + (result.uuid + host.db) : genDBUrl(host, ''); + callback(null, uuid$$1); + }).catch(function (err) { + callback(err); + }); + }); - return buf ? buf : bytesToUuid(b); -} + // Sends a POST request to the host calling the couchdb _compact function + // version: The version of CouchDB it is running + api.compact = adapterFun$$1('compact', function (opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + opts = clone(opts); -module.exports = v1; + fetchJSON(genDBUrl(host, '_compact'), {method: 'POST'}).then(function () { + function ping() { + api.info(function (err, res) { + // CouchDB may send a "compact_running:true" if it's + // already compacting. PouchDB Server doesn't. + /* istanbul ignore else */ + if (res && !res.compact_running) { + callback(null, {ok: true}); + } else { + setTimeout(ping, opts.interval || 200); + } + }); + } + // Ping the http if it's finished compaction + ping(); + }); + }); + api.bulkGet = adapterFun('bulkGet', function (opts, callback) { + var self = this; -/***/ }), -/* 490 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + function doBulkGet(cb) { + var params = {}; + if (opts.revs) { + params.revs = true; + } + if (opts.attachments) { + /* istanbul ignore next */ + params.attachments = true; + } + if (opts.latest) { + params.latest = true; + } + fetchJSON(genDBUrl(host, '_bulk_get' + paramsToStr(params)), { + method: 'POST', + body: JSON.stringify({ docs: opts.docs}) + }).then(function (result) { + if (opts.attachments && opts.binary) { + result.data.results.forEach(function (res) { + res.docs.forEach(readAttachmentsAsBlobOrBuffer); + }); + } + cb(null, result.data); + }).catch(cb); + } -// Unique ID creation requires a high quality random # generator. In node.js -// this is pretty straight-forward - we use the crypto API. + /* istanbul ignore next */ + function doBulkGetShim() { + // avoid "url too long error" by splitting up into multiple requests + var batchSize = MAX_SIMULTANEOUS_REVS; + var numBatches = Math.ceil(opts.docs.length / batchSize); + var numDone = 0; + var results = new Array(numBatches); -var crypto = __webpack_require__(76); + function onResult(batchNum) { + return function (err, res) { + // err is impossible because shim returns a list of errs in that case + results[batchNum] = res.results; + if (++numDone === numBatches) { + callback(null, {results: flatten(results)}); + } + }; + } -module.exports = function nodeRNG() { - return crypto.randomBytes(16); -}; + for (var i = 0; i < numBatches; i++) { + var subOpts = pick(opts, ['revs', 'attachments', 'binary', 'latest']); + subOpts.docs = opts.docs.slice(i * batchSize, + Math.min(opts.docs.length, (i + 1) * batchSize)); + bulkGet(self, subOpts, onResult(i)); + } + } + // mark the whole database as either supporting or not supporting _bulk_get + var dbUrl = genUrl(host, ''); + var supportsBulkGet = supportsBulkGetMap[dbUrl]; -/***/ }), -/* 491 */ -/***/ ((module) => { + /* istanbul ignore next */ + if (typeof supportsBulkGet !== 'boolean') { + // check if this database supports _bulk_get + doBulkGet(function (err, res) { + if (err) { + supportsBulkGetMap[dbUrl] = false; + explainError( + err.status, + 'PouchDB is just detecting if the remote ' + + 'supports the _bulk_get API.' + ); + doBulkGetShim(); + } else { + supportsBulkGetMap[dbUrl] = true; + callback(null, res); + } + }); + } else if (supportsBulkGet) { + doBulkGet(callback); + } else { + doBulkGetShim(); + } + }); -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} + // Calls GET on the host, which gets back a JSON string containing + // couchdb: A welcome string + // version: The version of CouchDB it is running + api._info = function (callback) { + setup().then(function () { + return ourFetch(genDBUrl(host, '')); + }).then(function (response) { + return response.json(); + }).then(function (info) { + info.host = genDBUrl(host, ''); + callback(null, info); + }).catch(callback); + }; -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - return bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]]; -} + api.fetch = function (path, options) { + return setup().then(function () { + return ourFetch(genDBUrl(host, path), options); + }); + }; -module.exports = bytesToUuid; + // Get the document with the given id from the database given by host. + // The id could be solely the _id in the database, or it may be a + // _design/ID or _local/ID path + api.get = adapterFun$$1('get', function (id, opts, callback) { + // If no options were given, set the callback to the second parameter + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + opts = clone(opts); + // List of parameters to add to the GET request + var params = {}; -/***/ }), -/* 492 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (opts.revs) { + params.revs = true; + } -var rng = __webpack_require__(490); -var bytesToUuid = __webpack_require__(491); + if (opts.revs_info) { + params.revs_info = true; + } -function v4(options, buf, offset) { - var i = buf && offset || 0; + if (opts.latest) { + params.latest = true; + } - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; + if (opts.open_revs) { + if (opts.open_revs !== "all") { + opts.open_revs = JSON.stringify(opts.open_revs); + } + params.open_revs = opts.open_revs; + } - var rnds = options.random || (options.rng || rng)(); + if (opts.rev) { + params.rev = opts.rev; + } - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; + if (opts.conflicts) { + params.conflicts = opts.conflicts; + } - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; + /* istanbul ignore if */ + if (opts.update_seq) { + params.update_seq = opts.update_seq; } - } - return buf || bytesToUuid(rnds); -} + id = encodeDocId(id); -module.exports = v4; + function fetchAttachments(doc) { + var atts = doc._attachments; + var filenames = atts && Object.keys(atts); + if (!atts || !filenames.length) { + return; + } + // we fetch these manually in separate XHRs, because + // Sync Gateway would normally send it back as multipart/mixed, + // which we cannot parse. Also, this is more efficient than + // receiving attachments as base64-encoded strings. + function fetchData(filename) { + var att = atts[filename]; + var path = encodeDocId(doc._id) + '/' + encodeAttachmentId(filename) + + '?rev=' + doc._rev; + return ourFetch(genDBUrl(host, path)).then(function (response) { + if (typeof process !== 'undefined' && !process.browser) { + return response.buffer(); + } else { + /* istanbul ignore next */ + return response.blob(); + } + }).then(function (blob) { + if (opts.binary) { + // TODO: Can we remove this? + if (typeof process !== 'undefined' && !process.browser) { + blob.type = att.content_type; + } + return blob; + } + return new Promise(function (resolve) { + blobToBase64(blob, resolve); + }); + }).then(function (data) { + delete att.stub; + delete att.length; + att.data = data; + }); + } + var promiseFactories = filenames.map(function (filename) { + return function () { + return fetchData(filename); + }; + }); -/***/ }), -/* 493 */ -/***/ ((__unused_webpack_module, exports) => { + // This limits the number of parallel xhr requests to 5 any time + // to avoid issues with maximum browser request limits + return pool(promiseFactories, 5); + } -"use strict"; + function fetchAllAttachments(docOrDocs) { + if (Array.isArray(docOrDocs)) { + return Promise.all(docOrDocs.map(function (doc) { + if (doc.ok) { + return fetchAttachments(doc.ok); + } + })); + } + return fetchAttachments(docOrDocs); + } + var url = genDBUrl(host, id + paramsToStr(params)); + fetchJSON(url).then(function (res) { + return Promise.resolve().then(function () { + if (opts.attachments) { + return fetchAllAttachments(res.data); + } + }).then(function () { + callback(null, res.data); + }); + }).catch(function (e) { + e.docId = id; + callback(e); + }); + }); -/** - * Stringify/parse functions that don't operate - * recursively, so they avoid call stack exceeded - * errors. - */ -exports.stringify = function stringify(input) { - var queue = []; - queue.push({obj: input}); - var res = ''; - var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix; - while ((next = queue.pop())) { - obj = next.obj; - prefix = next.prefix || ''; - val = next.val || ''; - res += prefix; - if (val) { - res += val; - } else if (typeof obj !== 'object') { - res += typeof obj === 'undefined' ? null : JSON.stringify(obj); - } else if (obj === null) { - res += 'null'; - } else if (Array.isArray(obj)) { - queue.push({val: ']'}); - for (i = obj.length - 1; i >= 0; i--) { - arrayPrefix = i === 0 ? '' : ','; - queue.push({obj: obj[i], prefix: arrayPrefix}); - } - queue.push({val: '['}); - } else { // object - keys = []; - for (k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } + // Delete the document given by doc from the database given by host. + api.remove = adapterFun$$1('remove', function (docOrId, optsOrRev, opts, cb) { + var doc; + if (typeof optsOrRev === 'string') { + // id, rev, opts, callback style + doc = { + _id: docOrId, + _rev: optsOrRev + }; + if (typeof opts === 'function') { + cb = opts; + opts = {}; } - queue.push({val: '}'}); - for (i = keys.length - 1; i >= 0; i--) { - key = keys[i]; - value = obj[key]; - objPrefix = (i > 0 ? ',' : ''); - objPrefix += JSON.stringify(key) + ':'; - queue.push({obj: value, prefix: objPrefix}); + } else { + // doc, opts, callback style + doc = docOrId; + if (typeof optsOrRev === 'function') { + cb = optsOrRev; + opts = {}; + } else { + cb = opts; + opts = optsOrRev; } - queue.push({val: '{'}); } - } - return res; -}; -// Convenience function for the parse function. -// This pop function is basically copied from -// pouchCollate.parseIndexableString -function pop(obj, stack, metaStack) { - var lastMetaElement = metaStack[metaStack.length - 1]; - if (obj === lastMetaElement.element) { - // popping a meta-element, e.g. an object whose value is another object - metaStack.pop(); - lastMetaElement = metaStack[metaStack.length - 1]; - } - var element = lastMetaElement.element; - var lastElementIndex = lastMetaElement.index; - if (Array.isArray(element)) { - element.push(obj); - } else if (lastElementIndex === stack.length - 2) { // obj with key+value - var key = stack.pop(); - element[key] = obj; - } else { - stack.push(obj); // obj with key only + var rev = (doc._rev || opts.rev); + var url = genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev; + + fetchJSON(url, {method: 'DELETE'}, cb).catch(cb); + }); + + function encodeAttachmentId(attachmentId) { + return attachmentId.split("/").map(encodeURIComponent).join("/"); } -} -exports.parse = function (str) { - var stack = []; - var metaStack = []; // stack for arrays and objects - var i = 0; - var collationIndex,parsedNum,numChar; - var parsedString,lastCh,numConsecutiveSlashes,ch; - var arrayElement, objElement; - while (true) { - collationIndex = str[i++]; - if (collationIndex === '}' || - collationIndex === ']' || - typeof collationIndex === 'undefined') { - if (stack.length === 1) { - return stack.pop(); - } else { - pop(stack.pop(), stack, metaStack); - continue; - } + // Get the attachment + api.getAttachment = adapterFun$$1('getAttachment', function (docId, attachmentId, + opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; } - switch (collationIndex) { - case ' ': - case '\t': - case '\n': - case ':': - case ',': - break; - case 'n': - i += 3; // 'ull' - pop(null, stack, metaStack); - break; - case 't': - i += 3; // 'rue' - pop(true, stack, metaStack); - break; - case 'f': - i += 4; // 'alse' - pop(false, stack, metaStack); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - parsedNum = ''; - i--; - while (true) { - numChar = str[i++]; - if (/[\d\.\-e\+]/.test(numChar)) { - parsedNum += numChar; - } else { - i--; - break; - } - } - pop(parseFloat(parsedNum), stack, metaStack); - break; - case '"': - parsedString = ''; - lastCh = void 0; - numConsecutiveSlashes = 0; - while (true) { - ch = str[i++]; - if (ch !== '"' || (lastCh === '\\' && - numConsecutiveSlashes % 2 === 1)) { - parsedString += ch; - lastCh = ch; - if (lastCh === '\\') { - numConsecutiveSlashes++; - } else { - numConsecutiveSlashes = 0; - } - } else { - break; - } + var params = opts.rev ? ('?rev=' + opts.rev) : ''; + var url = genDBUrl(host, encodeDocId(docId)) + '/' + + encodeAttachmentId(attachmentId) + params; + var contentType; + ourFetch(url, {method: 'GET'}).then(function (response) { + contentType = response.headers.get('content-type'); + if (!response.ok) { + throw response; + } else { + if (typeof process !== 'undefined' && !process.browser) { + return response.buffer(); + } else { + /* istanbul ignore next */ + return response.blob(); } - pop(JSON.parse('"' + parsedString + '"'), stack, metaStack); - break; - case '[': - arrayElement = { element: [], index: stack.length }; - stack.push(arrayElement.element); - metaStack.push(arrayElement); - break; - case '{': - objElement = { element: {}, index: stack.length }; - stack.push(objElement.element); - metaStack.push(objElement); - break; - default: - throw new Error( - 'unexpectedly reached end of input: ' + collationIndex); - } - } -}; - - -/***/ }), -/* 494 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(495); -/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(498); -/* harmony import */ var pouchdb_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(500); -/* harmony import */ var pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(503); -/* harmony import */ var pouchdb_abstract_mapreduce__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(505); -/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(504); -/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(499); + } + }).then(function (blob) { + // TODO: also remove + if (typeof process !== 'undefined' && !process.browser) { + blob.type = contentType; + } + callback(null, blob); + }).catch(function (err) { + callback(err); + }); + }); + // Remove the attachment given by the id and rev + api.removeAttachment = adapterFun$$1('removeAttachment', function (docId, + attachmentId, + rev, + callback) { + var url = genDBUrl(host, encodeDocId(docId) + '/' + + encodeAttachmentId(attachmentId)) + '?rev=' + rev; + fetchJSON(url, {method: 'DELETE'}, callback).catch(callback); + }); + // Add the attachment given by blob and its contentType property + // to the document with the given id, the revision given by rev, and + // add it to the database given by host. + api.putAttachment = adapterFun$$1('putAttachment', function (docId, attachmentId, + rev, blob, + type, callback) { + if (typeof type === 'function') { + callback = type; + type = blob; + blob = rev; + rev = null; + } + var id = encodeDocId(docId) + '/' + encodeAttachmentId(attachmentId); + var url = genDBUrl(host, id); + if (rev) { + url += '?rev=' + rev; + } + if (typeof blob === 'string') { + // input is assumed to be a base64 string + var binary; + try { + binary = thisAtob(blob); + } catch (err) { + return callback(createError(BAD_ARG, + 'Attachment is not a valid base64 string')); + } + blob = binary ? binStringToBluffer(binary, type) : ''; + } + // Add the attachment + fetchJSON(url, { + headers: new h({'Content-Type': type}), + method: 'PUT', + body: blob + }, callback).catch(callback); + }); + // Update/create multiple documents given by req in the database + // given by host. + api._bulkDocs = function (req, opts, callback) { + // If new_edits=false then it prevents the database from creating + // new revision numbers for the documents. Instead it just uses + // the old ones. This is used in database replication. + req.new_edits = opts.new_edits; + setup().then(function () { + return Promise.all(req.docs.map(preprocessAttachments$1)); + }).then(function () { + // Update/create the documents + return fetchJSON(genDBUrl(host, '_bulk_docs'), { + method: 'POST', + body: JSON.stringify(req) + }, callback); + }).catch(callback); + }; -// we restucture the supplied JSON considerably, because the official -// Mango API is very particular about a lot of this stuff, but we like -// to be liberal with what we accept in order to prevent mental -// breakdowns in our users -function massageCreateIndexRequest(requestDef) { - requestDef = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(requestDef); + // Update/create document + api._put = function (doc, opts, callback) { + setup().then(function () { + return preprocessAttachments$1(doc); + }).then(function () { + return fetchJSON(genDBUrl(host, encodeDocId(doc._id)), { + method: 'PUT', + body: JSON.stringify(doc) + }); + }).then(function (result) { + callback(null, result.data); + }).catch(function (err) { + err.docId = doc && doc._id; + callback(err); + }); + }; - if (!requestDef.index) { - requestDef.index = {}; - } - ['type', 'name', 'ddoc'].forEach(function (key) { - if (requestDef.index[key]) { - requestDef[key] = requestDef.index[key]; - delete requestDef.index[key]; + // Get a listing of the documents in the database given + // by host and ordered by increasing id. + api.allDocs = adapterFun$$1('allDocs', function (opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; } - }); + opts = clone(opts); - if (requestDef.fields) { - requestDef.index.fields = requestDef.fields; - delete requestDef.fields; - } + // List of parameters to add to the GET request + var params = {}; + var body; + var method = 'GET'; - if (!requestDef.type) { - requestDef.type = 'json'; - } - return requestDef; -} + if (opts.conflicts) { + params.conflicts = true; + } -function dbFetch(db, path, opts, callback) { - var status, ok; - opts.headers = new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_2__.Headers({'Content-type': 'application/json'}); - db.fetch(path, opts).then(function (response) { - status = response.status; - ok = response.ok; - return response.json(); - }).then(function (json) { - if (!ok) { - json.status = status; - var err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_1__.generateErrorFromResponse)(json); - callback(err); - } else { - callback(null, json); + /* istanbul ignore if */ + if (opts.update_seq) { + params.update_seq = true; } - }).catch(callback); -} -function createIndex(db, requestDef, callback) { - requestDef = massageCreateIndexRequest(requestDef); - dbFetch(db, '_index', { - method: 'POST', - body: JSON.stringify(requestDef) - }, callback); -} + if (opts.descending) { + params.descending = true; + } -function find(db, requestDef, callback) { - dbFetch(db, '_find', { - method: 'POST', - body: JSON.stringify(requestDef) - }, callback); -} + if (opts.include_docs) { + params.include_docs = true; + } -function explain(db, requestDef, callback) { - dbFetch(db, '_explain', { - method: 'POST', - body: JSON.stringify(requestDef) - }, callback); -} + // added in CouchDB 1.6.0 + if (opts.attachments) { + params.attachments = true; + } -function getIndexes(db, callback) { - dbFetch(db, '_index', { - method: 'GET' - }, callback); -} + if (opts.key) { + params.key = JSON.stringify(opts.key); + } -function deleteIndex(db, indexDef, callback) { + if (opts.start_key) { + opts.startkey = opts.start_key; + } + if (opts.startkey) { + params.startkey = JSON.stringify(opts.startkey); + } - var ddoc = indexDef.ddoc; - var type = indexDef.type || 'json'; - var name = indexDef.name; + if (opts.end_key) { + opts.endkey = opts.end_key; + } - if (!ddoc) { - return callback(new Error('you must provide an index\'s ddoc')); - } + if (opts.endkey) { + params.endkey = JSON.stringify(opts.endkey); + } - if (!name) { - return callback(new Error('you must provide an index\'s name')); - } + if (typeof opts.inclusive_end !== 'undefined') { + params.inclusive_end = !!opts.inclusive_end; + } - var url = '_index/' + [ddoc, type, name].map(encodeURIComponent).join('/'); + if (typeof opts.limit !== 'undefined') { + params.limit = opts.limit; + } - dbFetch(db, url, {method: 'DELETE'}, callback); -} + if (typeof opts.skip !== 'undefined') { + params.skip = opts.skip; + } -function getArguments(fun) { - return function () { - var len = arguments.length; - var args = new Array(len); - var i = -1; - while (++i < len) { - args[i] = arguments[i]; + var paramStr = paramsToStr(params); + + if (typeof opts.keys !== 'undefined') { + method = 'POST'; + body = {keys: opts.keys}; } - return fun.call(this, args); - }; -} -function callbackify(fun) { - return getArguments(function (args) { - var cb = args.pop(); - var promise = fun.apply(this, args); - promisedCallback(promise, cb); - return promise; + fetchJSON(genDBUrl(host, '_all_docs' + paramStr), { + method: method, + body: JSON.stringify(body) + }).then(function (result) { + if (opts.include_docs && opts.attachments && opts.binary) { + result.data.rows.forEach(readAttachmentsAsBlobOrBuffer); + } + callback(null, result.data); + }).catch(callback); }); -} -function promisedCallback(promise, callback) { - promise.then(function (res) { - (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () { - callback(null, res); - }); - }, function (reason) { - (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () { - callback(reason); - }); - }); - return promise; -} + // Get a list of changes made to documents in the database given by host. + // TODO According to the README, there should be two other methods here, + // api.changes.addListener and api.changes.removeListener. + api._changes = function (opts) { -var flatten = getArguments(function (args) { - var res = []; - for (var i = 0, len = args.length; i < len; i++) { - var subArr = args[i]; - if (Array.isArray(subArr)) { - res = res.concat(flatten.apply(null, subArr)); - } else { - res.push(subArr); - } - } - return res; -}); + // We internally page the results of a changes request, this means + // if there is a large set of changes to be returned we can start + // processing them quicker instead of waiting on the entire + // set of changes to return and attempting to process them at once + var batchSize = 'batch_size' in opts ? opts.batch_size : CHANGES_BATCH_SIZE; -function mergeObjects(arr) { - var res = {}; - for (var i = 0, len = arr.length; i < len; i++) { - res = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.assign)(res, arr[i]); - } - return res; -} + opts = clone(opts); -// Selects a list of fields defined in dot notation from one doc -// and copies them to a new doc. Like underscore _.pick but supports nesting. -function pick(obj, arr) { - var res = {}; - for (var i = 0, len = arr.length; i < len; i++) { - var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(arr[i]); - var value = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getFieldFromDoc)(obj, parsedField); - if (typeof value !== 'undefined') { - (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.setFieldInDoc)(res, parsedField, value); + if (opts.continuous && !('heartbeat' in opts)) { + opts.heartbeat = DEFAULT_HEARTBEAT; } - } - return res; -} -// e.g. ['a'], ['a', 'b'] is true, but ['b'], ['a', 'b'] is false -function oneArrayIsSubArrayOfOther(left, right) { + var requestTimeout = ('timeout' in opts) ? opts.timeout : 30 * 1000; - for (var i = 0, len = Math.min(left.length, right.length); i < len; i++) { - if (left[i] !== right[i]) { - return false; + // ensure CHANGES_TIMEOUT_BUFFER applies + if ('timeout' in opts && opts.timeout && + (requestTimeout - opts.timeout) < CHANGES_TIMEOUT_BUFFER) { + requestTimeout = opts.timeout + CHANGES_TIMEOUT_BUFFER; } - } - return true; -} -// e.g.['a', 'b', 'c'], ['a', 'b'] is false -function oneArrayIsStrictSubArrayOfOther(left, right) { + /* istanbul ignore if */ + if ('heartbeat' in opts && opts.heartbeat && + (requestTimeout - opts.heartbeat) < CHANGES_TIMEOUT_BUFFER) { + requestTimeout = opts.heartbeat + CHANGES_TIMEOUT_BUFFER; + } - if (left.length > right.length) { - return false; - } + var params = {}; + if ('timeout' in opts && opts.timeout) { + params.timeout = opts.timeout; + } - return oneArrayIsSubArrayOfOther(left, right); -} + var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false; + var leftToFetch = limit; -// same as above, but treat the left array as an unordered set -// e.g. ['b', 'a'], ['a', 'b', 'c'] is true, but ['c'], ['a', 'b', 'c'] is false -function oneSetIsSubArrayOfOther(left, right) { - left = left.slice(); - for (var i = 0, len = right.length; i < len; i++) { - var field = right[i]; - if (!left.length) { - break; - } - var leftIdx = left.indexOf(field); - if (leftIdx === -1) { - return false; - } else { - left.splice(leftIdx, 1); + if (opts.style) { + params.style = opts.style; } - } - return true; -} - -function arrayToObject(arr) { - var res = {}; - for (var i = 0, len = arr.length; i < len; i++) { - res[arr[i]] = true; - } - return res; -} -function max(arr, fun) { - var max = null; - var maxScore = -1; - for (var i = 0, len = arr.length; i < len; i++) { - var element = arr[i]; - var score = fun(element); - if (score > maxScore) { - maxScore = score; - max = element; + if (opts.include_docs || opts.filter && typeof opts.filter === 'function') { + params.include_docs = true; } - } - return max; -} -function arrayEquals(arr1, arr2) { - if (arr1.length !== arr2.length) { - return false; - } - for (var i = 0, len = arr1.length; i < len; i++) { - if (arr1[i] !== arr2[i]) { - return false; + if (opts.attachments) { + params.attachments = true; } - } - return true; -} -function uniq(arr) { - var obj = {}; - for (var i = 0; i < arr.length; i++) { - obj['$' + arr[i]] = true; - } - return Object.keys(obj).map(function (key) { - return key.substring(1); - }); -} + if (opts.continuous) { + params.feed = 'longpoll'; + } -// -// One thing about these mappers: -// -// Per the advice of John-David Dalton (http://youtu.be/NthmeLEhDDM), -// what you want to do in this case is optimize for the smallest possible -// function, since that's the thing that gets run over and over again. -// -// This code would be a lot simpler if all the if/elses were inside -// the function, but it would also be a lot less performant. -// + if (opts.seq_interval) { + params.seq_interval = opts.seq_interval; + } + if (opts.conflicts) { + params.conflicts = true; + } -function createDeepMultiMapper(fields, emit) { - return function (doc) { - var toEmit = []; - for (var i = 0, iLen = fields.length; i < iLen; i++) { - var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(fields[i]); - var value = doc; - for (var j = 0, jLen = parsedField.length; j < jLen; j++) { - var key = parsedField[j]; - value = value[key]; - if (typeof value === 'undefined') { - return; // don't emit - } - } - toEmit.push(value); + if (opts.descending) { + params.descending = true; + } + + /* istanbul ignore if */ + if (opts.update_seq) { + params.update_seq = true; } - emit(toEmit); - }; -} -function createDeepSingleMapper(field, emit) { - var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(field); - return function (doc) { - var value = doc; - for (var i = 0, len = parsedField.length; i < len; i++) { - var key = parsedField[i]; - value = value[key]; - if (typeof value === 'undefined') { - return; // do nothing + if ('heartbeat' in opts) { + // If the heartbeat value is false, it disables the default heartbeat + if (opts.heartbeat) { + params.heartbeat = opts.heartbeat; } } - emit(value); - }; -} -function createShallowSingleMapper(field, emit) { - return function (doc) { - emit(doc[field]); - }; -} + if (opts.filter && typeof opts.filter === 'string') { + params.filter = opts.filter; + } -function createShallowMultiMapper(fields, emit) { - return function (doc) { - var toEmit = []; - for (var i = 0, len = fields.length; i < len; i++) { - toEmit.push(doc[fields[i]]); + if (opts.view && typeof opts.view === 'string') { + params.filter = '_view'; + params.view = opts.view; } - emit(toEmit); - }; -} -function checkShallow(fields) { - for (var i = 0, len = fields.length; i < len; i++) { - var field = fields[i]; - if (field.indexOf('.') !== -1) { - return false; + // If opts.query_params exists, pass it through to the changes request. + // These parameters may be used by the filter on the source database. + if (opts.query_params && typeof opts.query_params === 'object') { + for (var param_name in opts.query_params) { + /* istanbul ignore else */ + if (opts.query_params.hasOwnProperty(param_name)) { + params[param_name] = opts.query_params[param_name]; + } + } } - } - return true; -} -function createMapper(fields, emit) { - var isShallow = checkShallow(fields); - var isSingle = fields.length === 1; + var method = 'GET'; + var body; - // notice we try to optimize for the most common case, - // i.e. single shallow indexes - if (isShallow) { - if (isSingle) { - return createShallowSingleMapper(fields[0], emit); - } else { // multi - return createShallowMultiMapper(fields, emit); + if (opts.doc_ids) { + // set this automagically for the user; it's annoying that couchdb + // requires both a "filter" and a "doc_ids" param. + params.filter = '_doc_ids'; + method = 'POST'; + body = {doc_ids: opts.doc_ids }; } - } else { // deep - if (isSingle) { - return createDeepSingleMapper(fields[0], emit); - } else { // multi - return createDeepMultiMapper(fields, emit); + /* istanbul ignore next */ + else if (opts.selector) { + // set this automagically for the user, similar to above + params.filter = '_selector'; + method = 'POST'; + body = {selector: opts.selector }; } - } -} -function mapper(mapFunDef, emit) { - // mapFunDef is a list of fields + var controller = new a(); + var lastFetchedSeq; - var fields = Object.keys(mapFunDef.fields); + // Get all the changes starting wtih the one immediately after the + // sequence number given by since. + var fetchData = function (since, callback) { + if (opts.aborted) { + return; + } + params.since = since; + // "since" can be any kind of json object in Cloudant/CouchDB 2.x + /* istanbul ignore next */ + if (typeof params.since === "object") { + params.since = JSON.stringify(params.since); + } - return createMapper(fields, emit); -} + if (opts.descending) { + if (limit) { + params.limit = leftToFetch; + } + } else { + params.limit = (!limit || leftToFetch > batchSize) ? + batchSize : leftToFetch; + } -/* istanbul ignore next */ -function reducer(/*reduceFunDef*/) { - throw new Error('reduce not supported'); -} + // Set the options for the ajax call + var url = genDBUrl(host, '_changes' + paramsToStr(params)); + var fetchOpts = { + signal: controller.signal, + method: method, + body: JSON.stringify(body) + }; + lastFetchedSeq = since; -function ddocValidator(ddoc, viewName) { - var view = ddoc.views[viewName]; - // This doesn't actually need to be here apparently, but - // I feel safer keeping it. - /* istanbul ignore if */ - if (!view.map || !view.map.fields) { - throw new Error('ddoc ' + ddoc._id +' with view ' + viewName + - ' doesn\'t have map.fields defined. ' + - 'maybe it wasn\'t created by this plugin?'); - } -} + /* istanbul ignore if */ + if (opts.aborted) { + return; + } -var abstractMapper = (0,pouchdb_abstract_mapreduce__WEBPACK_IMPORTED_MODULE_4__["default"])( - /* localDocName */ 'indexes', - mapper, - reducer, - ddocValidator -); + // Get the changes + setup().then(function () { + return fetchJSON(url, fetchOpts, callback); + }).catch(callback); + }; -// normalize the "sort" value -function massageSort(sort) { - if (!Array.isArray(sort)) { - throw new Error('invalid sort json - should be an array'); - } - return sort.map(function (sorting) { - if (typeof sorting === 'string') { - var obj = {}; - obj[sorting] = 'asc'; - return obj; - } else { - return sorting; + // If opts.since exists, get all the changes from the sequence + // number given by opts.since. Otherwise, get all the changes + // from the sequence number 0. + var results = {results: []}; + + var fetched = function (err, res) { + if (opts.aborted) { + return; + } + var raw_results_length = 0; + // If the result of the ajax call (res) contains changes (res.results) + if (res && res.results) { + raw_results_length = res.results.length; + results.last_seq = res.last_seq; + var pending = null; + var lastSeq = null; + // Attach 'pending' property if server supports it (CouchDB 2.0+) + /* istanbul ignore if */ + if (typeof res.pending === 'number') { + pending = res.pending; + } + if (typeof results.last_seq === 'string' || typeof results.last_seq === 'number') { + lastSeq = results.last_seq; + } + // For each change + var req = {}; + req.query = opts.query_params; + res.results = res.results.filter(function (c) { + leftToFetch--; + var ret = filterChange(opts)(c); + if (ret) { + if (opts.include_docs && opts.attachments && opts.binary) { + readAttachmentsAsBlobOrBuffer(c); + } + if (opts.return_docs) { + results.results.push(c); + } + opts.onChange(c, pending, lastSeq); + } + return ret; + }); + } else if (err) { + // In case of an error, stop listening for changes and call + // opts.complete + opts.aborted = true; + opts.complete(err); + return; + } + + // The changes feed may have timed out with no results + // if so reuse last update sequence + if (res && res.last_seq) { + lastFetchedSeq = res.last_seq; + } + + var finished = (limit && leftToFetch <= 0) || + (res && raw_results_length < batchSize) || + (opts.descending); + + if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) { + // Queue a call to fetch again with the newest sequence number + immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { fetchData(lastFetchedSeq, fetched); }); + } else { + // We're done, call the callback + opts.complete(null, results); + } + }; + + fetchData(opts.since || 0, fetched); + + // Return a method to cancel this method from processing any more + return { + cancel: function () { + opts.aborted = true; + controller.abort(); + } + }; + }; + + // Given a set of document/revision IDs (given by req), tets the subset of + // those that do NOT correspond to revisions stored in the database. + // See http://wiki.apache.org/couchdb/HttpPostRevsDiff + api.revsDiff = adapterFun$$1('revsDiff', function (req, opts, callback) { + // If no options were given, set the callback to be the second parameter + if (typeof opts === 'function') { + callback = opts; + opts = {}; } + + // Get the missing document/revision IDs + fetchJSON(genDBUrl(host, '_revs_diff'), { + method: 'POST', + body: JSON.stringify(req) + }, callback).catch(callback); }); -} -function massageUseIndex(useIndex) { - var cleanedUseIndex = []; - if (typeof useIndex === 'string') { - cleanedUseIndex.push(useIndex); - } else { - cleanedUseIndex = useIndex; - } + api._close = function (callback) { + callback(); + }; - return cleanedUseIndex.map(function (name) { - return name.replace('_design/', ''); - }); + api._destroy = function (options, callback) { + fetchJSON(genDBUrl(host, ''), {method: 'DELETE'}).then(function (json) { + callback(null, json); + }).catch(function (err) { + /* istanbul ignore if */ + if (err.status === 404) { + callback(null, {ok: true}); + } else { + callback(err); + } + }); + }; } -function massageIndexDef(indexDef) { - indexDef.fields = indexDef.fields.map(function (field) { - if (typeof field === 'string') { - var obj = {}; - obj[field] = 'asc'; - return obj; - } - return field; - }); - return indexDef; +// HttpPouch is a valid adapter. +HttpPouch.valid = function () { + return true; +}; + +function HttpPouch$1 (PouchDB) { + PouchDB.adapter('http', HttpPouch, false); + PouchDB.adapter('https', HttpPouch, false); } -function getKeyFromDoc(doc, index) { - var res = []; - for (var i = 0; i < index.def.fields.length; i++) { - var field = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(index.def.fields[i]); - res.push(doc[field]); - } - return res; +function QueryParseError(message) { + this.status = 400; + this.name = 'query_parse_error'; + this.message = message; + this.error = true; + try { + Error.captureStackTrace(this, QueryParseError); + } catch (e) {} } -// have to do this manually because REASONS. I don't know why -// CouchDB didn't implement inclusive_start -function filterInclusiveStart(rows, targetValue, index) { - var indexFields = index.def.fields; - for (var i = 0, len = rows.length; i < len; i++) { - var row = rows[i]; +inherits__WEBPACK_IMPORTED_MODULE_3___default()(QueryParseError, Error); - // shave off any docs at the beginning that are <= the - // target value +function NotFoundError(message) { + this.status = 404; + this.name = 'not_found'; + this.message = message; + this.error = true; + try { + Error.captureStackTrace(this, NotFoundError); + } catch (e) {} +} - var docKey = getKeyFromDoc(row.doc, index); - if (indexFields.length === 1) { - docKey = docKey[0]; // only one field, not multi-field - } else { // more than one field in index - // in the case where e.g. the user is searching {$gt: {a: 1}} - // but the index is [a, b], then we need to shorten the doc key - while (docKey.length > targetValue.length) { - docKey.pop(); - } - } - //ABS as we just looking for values that don't match - if (Math.abs((0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__.collate)(docKey, targetValue)) > 0) { - // no need to filter any further; we're past the key - break; - } - } - return i > 0 ? rows.slice(i) : rows; +inherits__WEBPACK_IMPORTED_MODULE_3___default()(NotFoundError, Error); + +function BuiltInError(message) { + this.status = 500; + this.name = 'invalid_value'; + this.message = message; + this.error = true; + try { + Error.captureStackTrace(this, BuiltInError); + } catch (e) {} } -function reverseOptions(opts) { - var newOpts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(opts); - delete newOpts.startkey; - delete newOpts.endkey; - delete newOpts.inclusive_start; - delete newOpts.inclusive_end; +inherits__WEBPACK_IMPORTED_MODULE_3___default()(BuiltInError, Error); - if ('endkey' in opts) { - newOpts.startkey = opts.endkey; - } - if ('startkey' in opts) { - newOpts.endkey = opts.startkey; - } - if ('inclusive_start' in opts) { - newOpts.inclusive_end = opts.inclusive_start; - } - if ('inclusive_end' in opts) { - newOpts.inclusive_start = opts.inclusive_end; +function promisedCallback(promise, callback) { + if (callback) { + promise.then(function (res) { + immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { + callback(null, res); + }); + }, function (reason) { + immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { + callback(reason); + }); + }); } - return newOpts; + return promise; } -function validateIndex(index) { - var ascFields = index.fields.filter(function (field) { - return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getValue)(field) === 'asc'; +function callbackify(fun) { + return argsarray__WEBPACK_IMPORTED_MODULE_0___default()(function (args) { + var cb = args.pop(); + var promise = fun.apply(this, args); + if (typeof cb === 'function') { + promisedCallback(promise, cb); + } + return promise; }); - if (ascFields.length !== 0 && ascFields.length !== index.fields.length) { - throw new Error('unsupported mixed sorting'); - } } -function validateSort(requestDef, index) { - if (index.defaultUsed && requestDef.sort) { - var noneIdSorts = requestDef.sort.filter(function (sortItem) { - return Object.keys(sortItem)[0] !== '_id'; - }).map(function (sortItem) { - return Object.keys(sortItem)[0]; +// Promise finally util similar to Q.finally +function fin(promise, finalPromiseFactory) { + return promise.then(function (res) { + return finalPromiseFactory().then(function () { + return res; + }); + }, function (reason) { + return finalPromiseFactory().then(function () { + throw reason; }); + }); +} - if (noneIdSorts.length > 0) { - throw new Error('Cannot sort on field(s) "' + noneIdSorts.join(',') + - '" when using the default index'); - } - } +function sequentialize(queue, promiseFactory) { + return function () { + var args = arguments; + var that = this; + return queue.add(function () { + return promiseFactory.apply(that, args); + }); + }; +} - if (index.defaultUsed) { - return; - } +// uniq an array of strings, order not guaranteed +// similar to underscore/lodash _.uniq +function uniq(arr) { + var theSet = new ExportedSet(arr); + var result = new Array(theSet.size); + var index = -1; + theSet.forEach(function (value) { + result[++index] = value; + }); + return result; } -function validateFindRequest(requestDef) { - if (typeof requestDef.selector !== 'object') { - throw new Error('you must provide a selector when you find()'); - } +function mapToKeysArray(map) { + var result = new Array(map.size); + var index = -1; + map.forEach(function (value, key) { + result[++index] = key; + }); + return result; +} - /*var selectors = requestDef.selector['$and'] || [requestDef.selector]; - for (var i = 0; i < selectors.length; i++) { - var selector = selectors[i]; - var keys = Object.keys(selector); - if (keys.length === 0) { - throw new Error('invalid empty selector'); - } - //var selection = selector[keys[0]]; - /*if (Object.keys(selection).length !== 1) { - throw new Error('invalid selector: ' + JSON.stringify(selection) + - ' - it must have exactly one key/value'); - } - }*/ +function createBuiltInError(name) { + var message = 'builtin ' + name + + ' function requires map values to be numbers' + + ' or number arrays'; + return new BuiltInError(message); } -// determine the maximum number of fields -// we're going to need to query, e.g. if the user -// has selection ['a'] and sorting ['a', 'b'], then we -// need to use the longer of the two: ['a', 'b'] -function getUserFields(selector, sort) { - var selectorFields = Object.keys(selector); - var sortFields = sort? sort.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey) : []; - var userFields; - if (selectorFields.length >= sortFields.length) { - userFields = selectorFields; - } else { - userFields = sortFields; +function sum(values) { + var result = 0; + for (var i = 0, len = values.length; i < len; i++) { + var num = values[i]; + if (typeof num !== 'number') { + if (Array.isArray(num)) { + // lists of numbers are also allowed, sum them separately + result = typeof result === 'number' ? [result] : result; + for (var j = 0, jLen = num.length; j < jLen; j++) { + var jNum = num[j]; + if (typeof jNum !== 'number') { + throw createBuiltInError('_sum'); + } else if (typeof result[j] === 'undefined') { + result.push(jNum); + } else { + result[j] += jNum; + } + } + } else { // not array/number + throw createBuiltInError('_sum'); + } + } else if (typeof result === 'number') { + result += num; + } else { // add number to array + result[0] += num; + } } + return result; +} - if (sortFields.length === 0) { - return { - fields: userFields - }; - } +var log = guardedConsole.bind(null, 'log'); +var isArray = Array.isArray; +var toJSON = JSON.parse; - // sort according to the user's preferred sorting - userFields = userFields.sort(function (left, right) { - var leftIdx = sortFields.indexOf(left); - if (leftIdx === -1) { - leftIdx = Number.MAX_VALUE; - } - var rightIdx = sortFields.indexOf(right); - if (rightIdx === -1) { - rightIdx = Number.MAX_VALUE; +function evalFunctionWithEval(func, emit) { + return scopeEval( + "return (" + func.replace(/;\s*$/, "") + ");", + { + emit: emit, + sum: sum, + log: log, + isArray: isArray, + toJSON: toJSON } - return leftIdx < rightIdx ? -1 : leftIdx > rightIdx ? 1 : 0; - }); - - return { - fields: userFields, - sortOrder: sort.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey) - }; + ); } -function createIndex$1(db, requestDef) { - requestDef = massageCreateIndexRequest(requestDef); - var originalIndexDef = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(requestDef.index); - requestDef.index = massageIndexDef(requestDef.index); +/* + * Simple task queue to sequentialize actions. Assumes + * callbacks will eventually fire (once). + */ - validateIndex(requestDef.index); - // calculating md5 is expensive - memoize and only - // run if required - var md5; - function getMd5() { - return md5 || (md5 = (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_6__.stringMd5)(JSON.stringify(requestDef))); - } +function TaskQueue$1() { + this.promise = new Promise(function (fulfill) {fulfill(); }); +} +TaskQueue$1.prototype.add = function (promiseFactory) { + this.promise = this.promise.catch(function () { + // just recover + }).then(function () { + return promiseFactory(); + }); + return this.promise; +}; +TaskQueue$1.prototype.finish = function () { + return this.promise; +}; - var viewName = requestDef.name || ('idx-' + getMd5()); +function stringify(input) { + if (!input) { + return 'undefined'; // backwards compat for empty reduce + } + // for backwards compat with mapreduce, functions/strings are stringified + // as-is. everything else is JSON-stringified. + switch (typeof input) { + case 'function': + // e.g. a mapreduce map + return input.toString(); + case 'string': + // e.g. a mapreduce built-in _reduce function + return input.toString(); + default: + // e.g. a JSON object in the case of mango queries + return JSON.stringify(input); + } +} - var ddocName = requestDef.ddoc || ('idx-' + getMd5()); - var ddocId = '_design/' + ddocName; +/* create a string signature for a view so we can cache it and uniq it */ +function createViewSignature(mapFun, reduceFun) { + // the "undefined" part is for backwards compatibility + return stringify(mapFun) + stringify(reduceFun) + 'undefined'; +} - var hasInvalidLanguage = false; - var viewExists = false; +function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) { + var viewSignature = createViewSignature(mapFun, reduceFun); - function updateDdoc(doc) { - if (doc._rev && doc.language !== 'query') { - hasInvalidLanguage = true; + var cachedViews; + if (!temporary) { + // cache this to ensure we don't try to update the same view twice + cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {}; + if (cachedViews[viewSignature]) { + return cachedViews[viewSignature]; } - doc.language = 'query'; - doc.views = doc.views || {}; + } - viewExists = !!doc.views[viewName]; + var promiseForView = sourceDB.info().then(function (info) { - if (viewExists) { - return false; - } + var depDbName = info.db_name + '-mrview-' + + (temporary ? 'temp' : stringMd5(viewSignature)); - doc.views[viewName] = { - map: { - fields: mergeObjects(requestDef.index.fields) - }, - reduce: '_count', - options: { - def: originalIndexDef + // save the view name in the source db so it can be cleaned up if necessary + // (e.g. when the _design doc is deleted, remove all associated view data) + function diffFunction(doc) { + doc.views = doc.views || {}; + var fullViewName = viewName; + if (fullViewName.indexOf('/') === -1) { + fullViewName = viewName + '/' + viewName; } - }; - - return doc; - } - - db.constructor.emit('debug', ['find', 'creating index', ddocId]); - - return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(db, ddocId, updateDdoc).then(function () { - if (hasInvalidLanguage) { - throw new Error('invalid language for ddoc with id "' + - ddocId + - '" (should be "query")'); + var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {}; + /* istanbul ignore if */ + if (depDbs[depDbName]) { + return; // no update necessary + } + depDbs[depDbName] = true; + return doc; } - }).then(function () { - // kick off a build - // TODO: abstract-pouchdb-mapreduce should support auto-updating - // TODO: should also use update_after, but pouchdb/pouchdb#3415 blocks me - var signature = ddocName + '/' + viewName; - return abstractMapper.query.call(db, signature, { - limit: 0, - reduce: false - }).then(function () { - return { - id: ddocId, - name: viewName, - result: viewExists ? 'exists' : 'created' - }; + return upsert(sourceDB, '_local/' + localDocName, diffFunction).then(function () { + return sourceDB.registerDependentDatabase(depDbName).then(function (res) { + var db = res.db; + db.auto_compaction = true; + var view = { + name: depDbName, + db: db, + sourceDB: sourceDB, + adapter: sourceDB.adapter, + mapFun: mapFun, + reduceFun: reduceFun + }; + return view.db.get('_local/lastSeq').catch(function (err) { + /* istanbul ignore if */ + if (err.status !== 404) { + throw err; + } + }).then(function (lastSeqDoc) { + view.seq = lastSeqDoc ? lastSeqDoc.seq : 0; + if (cachedViews) { + view.db.once('destroyed', function () { + delete cachedViews[viewSignature]; + }); + } + return view; + }); + }); }); }); + + if (cachedViews) { + cachedViews[viewSignature] = promiseForView; + } + return promiseForView; } -function getIndexes$1(db) { - // just search through all the design docs and filter in-memory. - // hopefully there aren't that many ddocs. - return db.allDocs({ - startkey: '_design/', - endkey: '_design/\uffff', - include_docs: true - }).then(function (allDocsRes) { - var res = { - indexes: [{ - ddoc: null, - name: '_all_docs', - type: 'special', - def: { - fields: [{_id: 'asc'}] - } - }] - }; +var persistentQueues = {}; +var tempViewQueue = new TaskQueue$1(); +var CHANGES_BATCH_SIZE$1 = 50; - res.indexes = flatten(res.indexes, allDocsRes.rows.filter(function (row) { - return row.doc.language === 'query'; - }).map(function (row) { - var viewNames = row.doc.views !== undefined ? Object.keys(row.doc.views) : []; +function parseViewName(name) { + // can be either 'ddocname/viewname' or just 'viewname' + // (where the ddoc name is the same) + return name.indexOf('/') === -1 ? [name, name] : name.split('/'); +} - return viewNames.map(function (viewName) { - var view = row.doc.views[viewName]; - return { - ddoc: row.id, - name: viewName, - type: 'json', - def: massageIndexDef(view.options.def) - }; - }); - })); +function isGenOne(changes) { + // only return true if the current change is 1- + // and there are no other leafs + return changes.length === 1 && /^1-/.test(changes[0].rev); +} - // these are sorted by view name for some reason - res.indexes.sort(function (left, right) { - return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.compare)(left.name, right.name); - }); - res.total_rows = res.indexes.length; - return res; - }); +function emitError(db, e) { + try { + db.emit('error', e); + } catch (err) { + guardedConsole('error', + 'The user\'s map/reduce function threw an uncaught error.\n' + + 'You can debug this error by doing:\n' + + 'myDatabase.on(\'error\', function (err) { debugger; });\n' + + 'Please double-check your map/reduce function.'); + guardedConsole('error', e); + } } -// couchdb lowest collation value -var COLLATE_LO = null; +/** + * Returns an "abstract" mapreduce object of the form: + * + * { + * query: queryFun, + * viewCleanup: viewCleanupFun + * } + * + * Arguments are: + * + * localDoc: string + * This is for the local doc that gets saved in order to track the + * "dependent" DBs and clean them up for viewCleanup. It should be + * unique, so that indexer plugins don't collide with each other. + * mapper: function (mapFunDef, emit) + * Returns a map function based on the mapFunDef, which in the case of + * normal map/reduce is just the de-stringified function, but may be + * something else, such as an object in the case of pouchdb-find. + * reducer: function (reduceFunDef) + * Ditto, but for reducing. Modules don't have to support reducing + * (e.g. pouchdb-find). + * ddocValidator: function (ddoc, viewName) + * Throws an error if the ddoc or viewName is not valid. + * This could be a way to communicate to the user that the configuration for the + * indexer is invalid. + */ +function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) { -// couchdb highest collation value (TODO: well not really, but close enough amirite) -var COLLATE_HI = {"\uffff": {}}; + function tryMap(db, fun, doc) { + // emit an event if there was an error thrown by a map function. + // putting try/catches in a single function also avoids deoptimizations. + try { + fun(doc); + } catch (e) { + emitError(db, e); + } + } -// couchdb second-lowest collation value + function tryReduce(db, fun, keys, values, rereduce) { + // same as above, but returning the result or an error. there are two separate + // functions to avoid extra memory allocations since the tryCode() case is used + // for custom map functions (common) vs this function, which is only used for + // custom reduce functions (rare) + try { + return {output : fun(keys, values, rereduce)}; + } catch (e) { + emitError(db, e); + return {error: e}; + } + } -function checkFieldInIndex(index, field) { - var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); - for (var i = 0, len = indexFields.length; i < len; i++) { - var indexField = indexFields[i]; - if (field === indexField) { - return true; + function sortByKeyThenValue(x, y) { + var keyCompare = collate(x.key, y.key); + return keyCompare !== 0 ? keyCompare : collate(x.value, y.value); + } + + function sliceResults(results, limit, skip) { + skip = skip || 0; + if (typeof limit === 'number') { + return results.slice(skip, limit + skip); + } else if (skip > 0) { + return results.slice(skip); } + return results; } - return false; -} -// so when you do e.g. $eq/$eq, we can do it entirely in the database. -// but when you do e.g. $gt/$eq, the first part can be done -// in the database, but the second part has to be done in-memory, -// because $gt has forced us to lose precision. -// so that's what this determines -function userOperatorLosesPrecision(selector, field) { - var matcher = selector[field]; - var userOperator = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(matcher); + function rowToDocId(row) { + var val = row.value; + // Users can explicitly specify a joined doc _id, or it + // defaults to the doc _id that emitted the key/value. + var docId = (val && typeof val === 'object' && val._id) || row.id; + return docId; + } - return userOperator !== '$eq'; -} + function readAttachmentsAsBlobOrBuffer(res) { + res.rows.forEach(function (row) { + var atts = row.doc && row.doc._attachments; + if (!atts) { + return; + } + Object.keys(atts).forEach(function (filename) { + var att = atts[filename]; + atts[filename].data = b64ToBluffer(att.data, att.content_type); + }); + }); + } -// sort the user fields by their position in the index, -// if they're in the index -function sortFieldsByIndex(userFields, index) { - var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); + function postprocessAttachments(opts) { + return function (res) { + if (opts.include_docs && opts.attachments && opts.binary) { + readAttachmentsAsBlobOrBuffer(res); + } + return res; + }; + } - return userFields.slice().sort(function (a, b) { - var aIdx = indexFields.indexOf(a); - var bIdx = indexFields.indexOf(b); - if (aIdx === -1) { - aIdx = Number.MAX_VALUE; - } - if (bIdx === -1) { - bIdx = Number.MAX_VALUE; + function addHttpParam(paramName, opts, params, asJson) { + // add an http param from opts to params, optionally json-encoded + var val = opts[paramName]; + if (typeof val !== 'undefined') { + if (asJson) { + val = encodeURIComponent(JSON.stringify(val)); + } + params.push(paramName + '=' + val); } - return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.compare)(aIdx, bIdx); - }); -} + } -// first pass to try to find fields that will need to be sorted in-memory -function getBasicInMemoryFields(index, selector, userFields) { + function coerceInteger(integerCandidate) { + if (typeof integerCandidate !== 'undefined') { + var asNumber = Number(integerCandidate); + // prevents e.g. '1foo' or '1.1' being coerced to 1 + if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) { + return asNumber; + } else { + return integerCandidate; + } + } + } - userFields = sortFieldsByIndex(userFields, index); + function coerceOptions(opts) { + opts.group_level = coerceInteger(opts.group_level); + opts.limit = coerceInteger(opts.limit); + opts.skip = coerceInteger(opts.skip); + return opts; + } - // check if any of the user selectors lose precision - var needToFilterInMemory = false; - for (var i = 0, len = userFields.length; i < len; i++) { - var field = userFields[i]; - if (needToFilterInMemory || !checkFieldInIndex(index, field)) { - return userFields.slice(i); - } - if (i < len - 1 && userOperatorLosesPrecision(selector, field)) { - needToFilterInMemory = true; + function checkPositiveInteger(number) { + if (number) { + if (typeof number !== 'number') { + return new QueryParseError('Invalid value for integer: "' + + number + '"'); + } + if (number < 0) { + return new QueryParseError('Invalid value for positive integer: ' + + '"' + number + '"'); + } } } - return []; -} -function getInMemoryFieldsFromNe(selector) { - var fields = []; - Object.keys(selector).forEach(function (field) { - var matcher = selector[field]; - Object.keys(matcher).forEach(function (operator) { - if (operator === '$ne') { - fields.push(field); + function checkQueryParseError(options, fun) { + var startkeyName = options.descending ? 'endkey' : 'startkey'; + var endkeyName = options.descending ? 'startkey' : 'endkey'; + + if (typeof options[startkeyName] !== 'undefined' && + typeof options[endkeyName] !== 'undefined' && + collate(options[startkeyName], options[endkeyName]) > 0) { + throw new QueryParseError('No rows can match your key range, ' + + 'reverse your start_key and end_key or set {descending : true}'); + } else if (fun.reduce && options.reduce !== false) { + if (options.include_docs) { + throw new QueryParseError('{include_docs:true} is invalid for reduce'); + } else if (options.keys && options.keys.length > 1 && + !options.group && !options.group_level) { + throw new QueryParseError('Multi-key fetches for reduce views must use ' + + '{group: true}'); + } + } + ['group_level', 'limit', 'skip'].forEach(function (optionName) { + var error = checkPositiveInteger(options[optionName]); + if (error) { + throw error; } }); - }); - return fields; -} + } -function getInMemoryFields(coreInMemoryFields, index, selector, userFields) { - var result = flatten( - // in-memory fields reported as necessary by the query planner - coreInMemoryFields, - // combine with another pass that checks for any we may have missed - getBasicInMemoryFields(index, selector, userFields), - // combine with another pass that checks for $ne's - getInMemoryFieldsFromNe(selector) - ); + function httpQuery(db, fun, opts) { + // List of parameters to add to the PUT request + var params = []; + var body; + var method = 'GET'; + var ok, status; - return sortFieldsByIndex(uniq(result), index); -} + // If opts.reduce exists and is defined, then add it to the list + // of parameters. + // If reduce=false then the results are that of only the map function + // not the final result of map and reduce. + addHttpParam('reduce', opts, params); + addHttpParam('include_docs', opts, params); + addHttpParam('attachments', opts, params); + addHttpParam('limit', opts, params); + addHttpParam('descending', opts, params); + addHttpParam('group', opts, params); + addHttpParam('group_level', opts, params); + addHttpParam('skip', opts, params); + addHttpParam('stale', opts, params); + addHttpParam('conflicts', opts, params); + addHttpParam('startkey', opts, params, true); + addHttpParam('start_key', opts, params, true); + addHttpParam('endkey', opts, params, true); + addHttpParam('end_key', opts, params, true); + addHttpParam('inclusive_end', opts, params); + addHttpParam('key', opts, params, true); + addHttpParam('update_seq', opts, params); -// check that at least one field in the user's query is represented -// in the index. order matters in the case of sorts -function checkIndexFieldsMatch(indexFields, sortOrder, fields) { - if (sortOrder) { - // array has to be a strict subarray of index array. furthermore, - // the sortOrder fields need to all be represented in the index - var sortMatches = oneArrayIsStrictSubArrayOfOther(sortOrder, indexFields); - var selectorMatches = oneArrayIsSubArrayOfOther(fields, indexFields); + // Format the list of parameters into a valid URI query string + params = params.join('&'); + params = params === '' ? '' : '?' + params; - return sortMatches && selectorMatches; - } + // If keys are supplied, issue a POST to circumvent GET query string limits + // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options + if (typeof opts.keys !== 'undefined') { + var MAX_URL_LENGTH = 2000; + // according to http://stackoverflow.com/a/417184/680742, + // the de facto URL length limit is 2000 characters - // all of the user's specified fields still need to be - // on the left side of the index array, although the order - // doesn't matter - return oneSetIsSubArrayOfOther(fields, indexFields); -} + var keysAsString = + 'keys=' + encodeURIComponent(JSON.stringify(opts.keys)); + if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) { + // If the keys are short enough, do a GET. we do this to work around + // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239) + params += (params[0] === '?' ? '&' : '?') + keysAsString; + } else { + method = 'POST'; + if (typeof fun === 'string') { + body = {keys: opts.keys}; + } else { // fun is {map : mapfun}, so append to this + fun.keys = opts.keys; + } + } + } -var logicalMatchers = ['$eq', '$gt', '$gte', '$lt', '$lte']; -function isNonLogicalMatcher(matcher) { - return logicalMatchers.indexOf(matcher) === -1; -} + // We are referencing a query defined in the design doc + if (typeof fun === 'string') { + var parts = parseViewName(fun); + return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, { + headers: new h({'Content-Type': 'application/json'}), + method: method, + body: JSON.stringify(body) + }).then(function (response) { + ok = response.ok; + status = response.status; + return response.json(); + }).then(function (result) { + if (!ok) { + result.status = status; + throw generateErrorFromResponse(result); + } + // fail the entire request if the result contains an error + result.rows.forEach(function (row) { + /* istanbul ignore if */ + if (row.value && row.value.error && row.value.error === "builtin_reduce_error") { + throw new Error(row.reason); + } + }); + return result; + }).then(postprocessAttachments(opts)); + } -// check all the index fields for usages of '$ne' -// e.g. if the user queries {foo: {$ne: 'foo'}, bar: {$eq: 'bar'}}, -// then we can neither use an index on ['foo'] nor an index on -// ['foo', 'bar'], but we can use an index on ['bar'] or ['bar', 'foo'] -function checkFieldsLogicallySound(indexFields, selector) { - var firstField = indexFields[0]; - var matcher = selector[firstField]; + // We are using a temporary view, terrible for performance, good for testing + body = body || {}; + Object.keys(fun).forEach(function (key) { + if (Array.isArray(fun[key])) { + body[key] = fun[key]; + } else { + body[key] = fun[key].toString(); + } + }); - if (typeof matcher === 'undefined') { - /* istanbul ignore next */ - return true; + return db.fetch('_temp_view' + params, { + headers: new h({'Content-Type': 'application/json'}), + method: 'POST', + body: JSON.stringify(body) + }).then(function (response) { + ok = response.ok; + status = response.status; + return response.json(); + }).then(function (result) { + if (!ok) { + result.status = status; + throw generateErrorFromResponse(result); + } + return result; + }).then(postprocessAttachments(opts)); } - var hasLogicalOperator = Object.keys(matcher).some(function (matcherKey) { - return !(isNonLogicalMatcher(matcherKey)); - }); - - if (!hasLogicalOperator) { - return false; + // custom adapters can define their own api._query + // and override the default behavior + /* istanbul ignore next */ + function customQuery(db, fun, opts) { + return new Promise(function (resolve, reject) { + db._query(fun, opts, function (err, res) { + if (err) { + return reject(err); + } + resolve(res); + }); + }); } - var isInvalidNe = Object.keys(matcher).length === 1 && - (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(matcher) === '$ne'; - - return !isInvalidNe; -} + // custom adapters can define their own api._viewCleanup + // and override the default behavior + /* istanbul ignore next */ + function customViewCleanup(db) { + return new Promise(function (resolve, reject) { + db._viewCleanup(function (err, res) { + if (err) { + return reject(err); + } + resolve(res); + }); + }); + } -function checkIndexMatches(index, sortOrder, fields, selector) { + function defaultsTo(value) { + return function (reason) { + /* istanbul ignore else */ + if (reason.status === 404) { + return value; + } else { + throw reason; + } + }; + } - var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); + // returns a promise for a list of docs to update, based on the input docId. + // the order doesn't matter, because post-3.2.0, bulkDocs + // is an atomic operation in all three adapters. + function getDocsToPersist(docId, view, docIdsToChangesAndEmits) { + var metaDocId = '_local/doc_' + docId; + var defaultMetaDoc = {_id: metaDocId, keys: []}; + var docData = docIdsToChangesAndEmits.get(docId); + var indexableKeysToKeyValues = docData[0]; + var changes = docData[1]; - var fieldsMatch = checkIndexFieldsMatch(indexFields, sortOrder, fields); + function getMetaDoc() { + if (isGenOne(changes)) { + // generation 1, so we can safely assume initial state + // for performance reasons (avoids unnecessary GETs) + return Promise.resolve(defaultMetaDoc); + } + return view.db.get(metaDocId).catch(defaultsTo(defaultMetaDoc)); + } - if (!fieldsMatch) { - return false; - } + function getKeyValueDocs(metaDoc) { + if (!metaDoc.keys.length) { + // no keys, no need for a lookup + return Promise.resolve({rows: []}); + } + return view.db.allDocs({ + keys: metaDoc.keys, + include_docs: true + }); + } - return checkFieldsLogicallySound(indexFields, selector); -} + function processKeyValueDocs(metaDoc, kvDocsRes) { + var kvDocs = []; + var oldKeys = new ExportedSet(); -// -// the algorithm is very simple: -// take all the fields the user supplies, and if those fields -// are a strict subset of the fields in some index, -// then use that index -// -// -function findMatchingIndexes(selector, userFields, sortOrder, indexes) { + for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) { + var row = kvDocsRes.rows[i]; + var doc = row.doc; + if (!doc) { // deleted + continue; + } + kvDocs.push(doc); + oldKeys.add(doc._id); + doc._deleted = !indexableKeysToKeyValues.has(doc._id); + if (!doc._deleted) { + var keyValue = indexableKeysToKeyValues.get(doc._id); + if ('value' in keyValue) { + doc.value = keyValue.value; + } + } + } + var newKeys = mapToKeysArray(indexableKeysToKeyValues); + newKeys.forEach(function (key) { + if (!oldKeys.has(key)) { + // new doc + var kvDoc = { + _id: key + }; + var keyValue = indexableKeysToKeyValues.get(key); + if ('value' in keyValue) { + kvDoc.value = keyValue.value; + } + kvDocs.push(kvDoc); + } + }); + metaDoc.keys = uniq(newKeys.concat(metaDoc.keys)); + kvDocs.push(metaDoc); - return indexes.reduce(function (res, index) { - var indexMatches = checkIndexMatches(index, sortOrder, userFields, selector); - if (indexMatches) { - res.push(index); + return kvDocs; } - return res; - }, []); -} -// find the best index, i.e. the one that matches the most fields -// in the user's query -function findBestMatchingIndex(selector, userFields, sortOrder, indexes, useIndex) { + return getMetaDoc().then(function (metaDoc) { + return getKeyValueDocs(metaDoc).then(function (kvDocsRes) { + return processKeyValueDocs(metaDoc, kvDocsRes); + }); + }); + } - var matchingIndexes = findMatchingIndexes(selector, userFields, sortOrder, indexes); + // updates all emitted key/value docs and metaDocs in the mrview database + // for the given batch of documents from the source database + function saveKeyValues(view, docIdsToChangesAndEmits, seq) { + var seqDocId = '_local/lastSeq'; + return view.db.get(seqDocId) + .catch(defaultsTo({_id: seqDocId, seq: 0})) + .then(function (lastSeqDoc) { + var docIds = mapToKeysArray(docIdsToChangesAndEmits); + return Promise.all(docIds.map(function (docId) { + return getDocsToPersist(docId, view, docIdsToChangesAndEmits); + })).then(function (listOfDocsToPersist) { + var docsToPersist = flatten(listOfDocsToPersist); + lastSeqDoc.seq = seq; + docsToPersist.push(lastSeqDoc); + // write all docs in a single operation, update the seq once + return view.db.bulkDocs({docs : docsToPersist}); + }); + }); + } - if (matchingIndexes.length === 0) { - if (useIndex) { - throw { - error: "no_usable_index", - message: "There is no index available for this selector." - }; + function getQueue(view) { + var viewName = typeof view === 'string' ? view : view.name; + var queue = persistentQueues[viewName]; + if (!queue) { + queue = persistentQueues[viewName] = new TaskQueue$1(); } - //return `all_docs` as a default index; - //I'm assuming that _all_docs is always first - var defaultIndex = indexes[0]; - defaultIndex.defaultUsed = true; - return defaultIndex; + return queue; } - if (matchingIndexes.length === 1 && !useIndex) { - return matchingIndexes[0]; + + function updateView(view) { + return sequentialize(getQueue(view), function () { + return updateViewInQueue(view); + })(); } - var userFieldsMap = arrayToObject(userFields); + function updateViewInQueue(view) { + // bind the emit function once + var mapResults; + var doc; - function scoreIndex(index) { - var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); - var score = 0; - for (var i = 0, len = indexFields.length; i < len; i++) { - var indexField = indexFields[i]; - if (userFieldsMap[indexField]) { - score++; + function emit(key, value) { + var output = {id: doc._id, key: normalizeKey(key)}; + // Don't explicitly store the value unless it's defined and non-null. + // This saves on storage space, because often people don't use it. + if (typeof value !== 'undefined' && value !== null) { + output.value = normalizeKey(value); } + mapResults.push(output); } - return score; - } - - if (useIndex) { - var useIndexDdoc = '_design/' + useIndex[0]; - var useIndexName = useIndex.length === 2 ? useIndex[1] : false; - var index = matchingIndexes.find(function (index) { - if (useIndexName && index.ddoc === useIndexDdoc && useIndexName === index.name) { - return true; - } - if (index.ddoc === useIndexDdoc) { - /* istanbul ignore next */ - return true; - } + var mapFun = mapper(view.mapFun, emit); - return false; - }); + var currentSeq = view.seq || 0; - if (!index) { - throw { - error: "unknown_error", - message: "Could not find that index or could not use that index for the query" + function processChange(docIdsToChangesAndEmits, seq) { + return function () { + return saveKeyValues(view, docIdsToChangesAndEmits, seq); }; } - return index; - } - - return max(matchingIndexes, scoreIndex); -} - -function getSingleFieldQueryOptsFor(userOperator, userValue) { - switch (userOperator) { - case '$eq': - return {key: userValue}; - case '$lte': - return {endkey: userValue}; - case '$gte': - return {startkey: userValue}; - case '$lt': - return { - endkey: userValue, - inclusive_end: false - }; - case '$gt': - return { - startkey: userValue, - inclusive_start: false - }; - } -} -function getSingleFieldCoreQueryPlan(selector, index) { - var field = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(index.def.fields[0]); - //ignoring this because the test to exercise the branch is skipped at the moment - /* istanbul ignore next */ - var matcher = selector[field] || {}; - var inMemoryFields = []; - - var userOperators = Object.keys(matcher); - - var combinedOpts; + var queue = new TaskQueue$1(); - userOperators.forEach(function (userOperator) { + function processNextBatch() { + return view.sourceDB.changes({ + return_docs: true, + conflicts: true, + include_docs: true, + style: 'all_docs', + since: currentSeq, + limit: CHANGES_BATCH_SIZE$1 + }).then(processBatch); + } - if (isNonLogicalMatcher(userOperator)) { - inMemoryFields.push(field); - return; + function processBatch(response) { + var results = response.results; + if (!results.length) { + return; + } + var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results); + queue.add(processChange(docIdsToChangesAndEmits, currentSeq)); + if (results.length < CHANGES_BATCH_SIZE$1) { + return; + } + return processNextBatch(); } - var userValue = matcher[userOperator]; + function createDocIdsToChangesAndEmits(results) { + var docIdsToChangesAndEmits = new ExportedMap(); + for (var i = 0, len = results.length; i < len; i++) { + var change = results[i]; + if (change.doc._id[0] !== '_') { + mapResults = []; + doc = change.doc; - var newQueryOpts = getSingleFieldQueryOptsFor(userOperator, userValue); + if (!doc._deleted) { + tryMap(view.sourceDB, mapFun, doc); + } + mapResults.sort(sortByKeyThenValue); - if (combinedOpts) { - combinedOpts = mergeObjects([combinedOpts, newQueryOpts]); - } else { - combinedOpts = newQueryOpts; + var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults); + docIdsToChangesAndEmits.set(change.doc._id, [ + indexableKeysToKeyValues, + change.changes + ]); + } + currentSeq = change.seq; + } + return docIdsToChangesAndEmits; } - }); - return { - queryOpts: combinedOpts, - inMemoryFields: inMemoryFields - }; -} + function createIndexableKeysToKeyValues(mapResults) { + var indexableKeysToKeyValues = new ExportedMap(); + var lastKey; + for (var i = 0, len = mapResults.length; i < len; i++) { + var emittedKeyValue = mapResults[i]; + var complexKey = [emittedKeyValue.key, emittedKeyValue.id]; + if (i > 0 && collate(emittedKeyValue.key, lastKey) === 0) { + complexKey.push(i); // dup key+id, so make it unique + } + indexableKeysToKeyValues.set(toIndexableString(complexKey), emittedKeyValue); + lastKey = emittedKeyValue.key; + } + return indexableKeysToKeyValues; + } -function getMultiFieldCoreQueryPlan(userOperator, userValue) { - switch (userOperator) { - case '$eq': - return { - startkey: userValue, - endkey: userValue - }; - case '$lte': - return { - endkey: userValue - }; - case '$gte': - return { - startkey: userValue - }; - case '$lt': - return { - endkey: userValue, - inclusive_end: false - }; - case '$gt': - return { - startkey: userValue, - inclusive_start: false - }; + return processNextBatch().then(function () { + return queue.finish(); + }).then(function () { + view.seq = currentSeq; + }); } -} -function getMultiFieldQueryOpts(selector, index) { + function reduceView(view, results, options) { + if (options.group_level === 0) { + delete options.group_level; + } - var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); + var shouldGroup = options.group || options.group_level; - var inMemoryFields = []; - var startkey = []; - var endkey = []; - var inclusiveStart; - var inclusiveEnd; + var reduceFun = reducer(view.reduceFun); + var groups = []; + var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY : + options.group_level; + results.forEach(function (e) { + var last = groups[groups.length - 1]; + var groupKey = shouldGroup ? e.key : null; - function finish(i) { + // only set group_level for array keys + if (shouldGroup && Array.isArray(groupKey)) { + groupKey = groupKey.slice(0, lvl); + } - if (inclusiveStart !== false) { - startkey.push(COLLATE_LO); - } - if (inclusiveEnd !== false) { - endkey.push(COLLATE_HI); + if (last && collate(last.groupKey, groupKey) === 0) { + last.keys.push([e.key, e.id]); + last.values.push(e.value); + return; + } + groups.push({ + keys: [[e.key, e.id]], + values: [e.value], + groupKey: groupKey + }); + }); + results = []; + for (var i = 0, len = groups.length; i < len; i++) { + var e = groups[i]; + var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false); + if (reduceTry.error && reduceTry.error instanceof BuiltInError) { + // CouchDB returns an error if a built-in errors out + throw reduceTry.error; + } + results.push({ + // CouchDB just sets the value to null if a non-built-in errors out + value: reduceTry.error ? null : reduceTry.output, + key: e.groupKey + }); } - // keep track of the fields where we lost specificity, - // and therefore need to filter in-memory - inMemoryFields = indexFields.slice(i); + // no total_rows/offset when reducing + return {rows: sliceResults(results, options.limit, options.skip)}; } - for (var i = 0, len = indexFields.length; i < len; i++) { - var indexField = indexFields[i]; - - var matcher = selector[indexField]; + function queryView(view, opts) { + return sequentialize(getQueue(view), function () { + return queryViewInQueue(view, opts); + })(); + } - if (!matcher || !Object.keys(matcher).length) { // fewer fields in user query than in index - finish(i); - break; - } else if (i > 0) { - if (Object.keys(matcher).some(isNonLogicalMatcher)) { // non-logical are ignored - finish(i); - break; - } - var usingGtlt = ( - '$gt' in matcher || '$gte' in matcher || - '$lt' in matcher || '$lte' in matcher); - var previousKeys = Object.keys(selector[indexFields[i - 1]]); - var previousWasEq = arrayEquals(previousKeys, ['$eq']); - var previousWasSame = arrayEquals(previousKeys, Object.keys(matcher)); - var gtltLostSpecificity = usingGtlt && !previousWasEq && !previousWasSame; - if (gtltLostSpecificity) { - finish(i); - break; - } + function queryViewInQueue(view, opts) { + var totalRows; + var shouldReduce = view.reduceFun && opts.reduce !== false; + var skip = opts.skip || 0; + if (typeof opts.keys !== 'undefined' && !opts.keys.length) { + // equivalent query + opts.limit = 0; + delete opts.keys; } - var userOperators = Object.keys(matcher); + function fetchFromView(viewOpts) { + viewOpts.include_docs = true; + return view.db.allDocs(viewOpts).then(function (res) { + totalRows = res.total_rows; + return res.rows.map(function (result) { - var combinedOpts = null; + // implicit migration - in older versions of PouchDB, + // we explicitly stored the doc as {id: ..., key: ..., value: ...} + // this is tested in a migration test + /* istanbul ignore next */ + if ('value' in result.doc && typeof result.doc.value === 'object' && + result.doc.value !== null) { + var keys = Object.keys(result.doc.value).sort(); + // this detection method is not perfect, but it's unlikely the user + // emitted a value which was an object with these 3 exact keys + var expectedKeys = ['id', 'key', 'value']; + if (!(keys < expectedKeys || keys > expectedKeys)) { + return result.doc.value; + } + } - for (var j = 0; j < userOperators.length; j++) { - var userOperator = userOperators[j]; - var userValue = matcher[userOperator]; + var parsedKeyAndDocId = parseIndexableString(result.doc._id); + return { + key: parsedKeyAndDocId[0], + id: parsedKeyAndDocId[1], + value: ('value' in result.doc ? result.doc.value : null) + }; + }); + }); + } - var newOpts = getMultiFieldCoreQueryPlan(userOperator, userValue); + function onMapResultsReady(rows) { + var finalResults; + if (shouldReduce) { + finalResults = reduceView(view, rows, opts); + } else { + finalResults = { + total_rows: totalRows, + offset: skip, + rows: rows + }; + } + /* istanbul ignore if */ + if (opts.update_seq) { + finalResults.update_seq = view.seq; + } + if (opts.include_docs) { + var docIds = uniq(rows.map(rowToDocId)); - if (combinedOpts) { - combinedOpts = mergeObjects([combinedOpts, newOpts]); + return view.sourceDB.allDocs({ + keys: docIds, + include_docs: true, + conflicts: opts.conflicts, + attachments: opts.attachments, + binary: opts.binary + }).then(function (allDocsRes) { + var docIdsToDocs = new ExportedMap(); + allDocsRes.rows.forEach(function (row) { + docIdsToDocs.set(row.id, row.doc); + }); + rows.forEach(function (row) { + var docId = rowToDocId(row); + var doc = docIdsToDocs.get(docId); + if (doc) { + row.doc = doc; + } + }); + return finalResults; + }); } else { - combinedOpts = newOpts; + return finalResults; } } - startkey.push('startkey' in combinedOpts ? combinedOpts.startkey : COLLATE_LO); - endkey.push('endkey' in combinedOpts ? combinedOpts.endkey : COLLATE_HI); - if ('inclusive_start' in combinedOpts) { - inclusiveStart = combinedOpts.inclusive_start; - } - if ('inclusive_end' in combinedOpts) { - inclusiveEnd = combinedOpts.inclusive_end; + if (typeof opts.keys !== 'undefined') { + var keys = opts.keys; + var fetchPromises = keys.map(function (key) { + var viewOpts = { + startkey : toIndexableString([key]), + endkey : toIndexableString([key, {}]) + }; + /* istanbul ignore if */ + if (opts.update_seq) { + viewOpts.update_seq = true; + } + return fetchFromView(viewOpts); + }); + return Promise.all(fetchPromises).then(flatten).then(onMapResultsReady); + } else { // normal query, no 'keys' + var viewOpts = { + descending : opts.descending + }; + /* istanbul ignore if */ + if (opts.update_seq) { + viewOpts.update_seq = true; + } + var startkey; + var endkey; + if ('start_key' in opts) { + startkey = opts.start_key; + } + if ('startkey' in opts) { + startkey = opts.startkey; + } + if ('end_key' in opts) { + endkey = opts.end_key; + } + if ('endkey' in opts) { + endkey = opts.endkey; + } + if (typeof startkey !== 'undefined') { + viewOpts.startkey = opts.descending ? + toIndexableString([startkey, {}]) : + toIndexableString([startkey]); + } + if (typeof endkey !== 'undefined') { + var inclusiveEnd = opts.inclusive_end !== false; + if (opts.descending) { + inclusiveEnd = !inclusiveEnd; + } + + viewOpts.endkey = toIndexableString( + inclusiveEnd ? [endkey, {}] : [endkey]); + } + if (typeof opts.key !== 'undefined') { + var keyStart = toIndexableString([opts.key]); + var keyEnd = toIndexableString([opts.key, {}]); + if (viewOpts.descending) { + viewOpts.endkey = keyStart; + viewOpts.startkey = keyEnd; + } else { + viewOpts.startkey = keyStart; + viewOpts.endkey = keyEnd; + } + } + if (!shouldReduce) { + if (typeof opts.limit === 'number') { + viewOpts.limit = opts.limit; + } + viewOpts.skip = skip; + } + return fetchFromView(viewOpts).then(onMapResultsReady); } } - var res = { - startkey: startkey, - endkey: endkey - }; + function httpViewCleanup(db) { + return db.fetch('_view_cleanup', { + headers: new h({'Content-Type': 'application/json'}), + method: 'POST' + }).then(function (response) { + return response.json(); + }); + } + + function localViewCleanup(db) { + return db.get('_local/' + localDocName).then(function (metaDoc) { + var docsToViews = new ExportedMap(); + Object.keys(metaDoc.views).forEach(function (fullViewName) { + var parts = parseViewName(fullViewName); + var designDocName = '_design/' + parts[0]; + var viewName = parts[1]; + var views = docsToViews.get(designDocName); + if (!views) { + views = new ExportedSet(); + docsToViews.set(designDocName, views); + } + views.add(viewName); + }); + var opts = { + keys : mapToKeysArray(docsToViews), + include_docs : true + }; + return db.allDocs(opts).then(function (res) { + var viewsToStatus = {}; + res.rows.forEach(function (row) { + var ddocName = row.key.substring(8); // cuts off '_design/' + docsToViews.get(row.key).forEach(function (viewName) { + var fullViewName = ddocName + '/' + viewName; + /* istanbul ignore if */ + if (!metaDoc.views[fullViewName]) { + // new format, without slashes, to support PouchDB 2.2.0 + // migration test in pouchdb's browser.migration.js verifies this + fullViewName = viewName; + } + var viewDBNames = Object.keys(metaDoc.views[fullViewName]); + // design doc deleted, or view function nonexistent + var statusIsGood = row.doc && row.doc.views && + row.doc.views[viewName]; + viewDBNames.forEach(function (viewDBName) { + viewsToStatus[viewDBName] = + viewsToStatus[viewDBName] || statusIsGood; + }); + }); + }); + var dbsToDelete = Object.keys(viewsToStatus).filter( + function (viewDBName) { return !viewsToStatus[viewDBName]; }); + var destroyPromises = dbsToDelete.map(function (viewDBName) { + return sequentialize(getQueue(viewDBName), function () { + return new db.constructor(viewDBName, db.__opts).destroy(); + })(); + }); + return Promise.all(destroyPromises).then(function () { + return {ok: true}; + }); + }); + }, defaultsTo({ok: true})); + } + + function queryPromised(db, fun, opts) { + /* istanbul ignore next */ + if (typeof db._query === 'function') { + return customQuery(db, fun, opts); + } + if (isRemote(db)) { + return httpQuery(db, fun, opts); + } - if (typeof inclusiveStart !== 'undefined') { - res.inclusive_start = inclusiveStart; - } - if (typeof inclusiveEnd !== 'undefined') { - res.inclusive_end = inclusiveEnd; - } + if (typeof fun !== 'string') { + // temp_view + checkQueryParseError(opts, fun); - return { - queryOpts: res, - inMemoryFields: inMemoryFields - }; -} + tempViewQueue.add(function () { + var createViewPromise = createView( + /* sourceDB */ db, + /* viewName */ 'temp_view/temp_view', + /* mapFun */ fun.map, + /* reduceFun */ fun.reduce, + /* temporary */ true, + /* localDocName */ localDocName); + return createViewPromise.then(function (view) { + return fin(updateView(view).then(function () { + return queryView(view, opts); + }), function () { + return view.db.destroy(); + }); + }); + }); + return tempViewQueue.finish(); + } else { + // persistent view + var fullViewName = fun; + var parts = parseViewName(fullViewName); + var designDocName = parts[0]; + var viewName = parts[1]; + return db.get('_design/' + designDocName).then(function (doc) { + var fun = doc.views && doc.views[viewName]; -function getDefaultQueryPlan(selector) { - //using default index, so all fields need to be done in memory - return { - queryOpts: {startkey: null}, - inMemoryFields: [Object.keys(selector)] - }; -} + if (!fun) { + // basic validator; it's assumed that every subclass would want this + throw new NotFoundError('ddoc ' + doc._id + ' has no view named ' + + viewName); + } -function getCoreQueryPlan(selector, index) { - if (index.defaultUsed) { - return getDefaultQueryPlan(selector, index); - } + ddocValidator(doc, viewName); + checkQueryParseError(opts, fun); - if (index.def.fields.length === 1) { - // one field in index, so the value was indexed as a singleton - return getSingleFieldCoreQueryPlan(selector, index); + var createViewPromise = createView( + /* sourceDB */ db, + /* viewName */ fullViewName, + /* mapFun */ fun.map, + /* reduceFun */ fun.reduce, + /* temporary */ false, + /* localDocName */ localDocName); + return createViewPromise.then(function (view) { + if (opts.stale === 'ok' || opts.stale === 'update_after') { + if (opts.stale === 'update_after') { + immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { + updateView(view); + }); + } + return queryView(view, opts); + } else { // stale not ok + return updateView(view).then(function () { + return queryView(view, opts); + }); + } + }); + }); + } } - // else index has multiple fields, so the value was indexed as an array - return getMultiFieldQueryOpts(selector, index); -} - -function planQuery(request, indexes) { - var selector = request.selector; - var sort = request.sort; - - var userFieldsRes = getUserFields(selector, sort); + function abstractQuery(fun, opts, callback) { + var db = this; + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + opts = opts ? coerceOptions(opts) : {}; - var userFields = userFieldsRes.fields; - var sortOrder = userFieldsRes.sortOrder; - var index = findBestMatchingIndex(selector, userFields, sortOrder, indexes, request.use_index); + if (typeof fun === 'function') { + fun = {map : fun}; + } - var coreQueryPlan = getCoreQueryPlan(selector, index); - var queryOpts = coreQueryPlan.queryOpts; - var coreInMemoryFields = coreQueryPlan.inMemoryFields; + var promise = Promise.resolve().then(function () { + return queryPromised(db, fun, opts); + }); + promisedCallback(promise, callback); + return promise; + } - var inMemoryFields = getInMemoryFields(coreInMemoryFields, index, selector, userFields); + var abstractViewCleanup = callbackify(function () { + var db = this; + /* istanbul ignore next */ + if (typeof db._viewCleanup === 'function') { + return customViewCleanup(db); + } + if (isRemote(db)) { + return httpViewCleanup(db); + } + return localViewCleanup(db); + }); - var res = { - queryOpts: queryOpts, - index: index, - inMemoryFields: inMemoryFields + return { + query: abstractQuery, + viewCleanup: abstractViewCleanup }; - return res; -} - -function indexToSignature(index) { - // remove '_design/' - return index.ddoc.substring(8) + '/' + index.name; } -function doAllDocs(db, originalOpts) { - var opts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(originalOpts); +var builtInReduce = { + _sum: function (keys, values) { + return sum(values); + }, - // CouchDB responds in weird ways when you provide a non-string to _id; - // we mimic the behavior for consistency. See issue66 tests for details. + _count: function (keys, values) { + return values.length; + }, - if (opts.descending) { - if ('endkey' in opts && typeof opts.endkey !== 'string') { - opts.endkey = ''; - } - if ('startkey' in opts && typeof opts.startkey !== 'string') { - opts.limit = 0; - } - } else { - if ('startkey' in opts && typeof opts.startkey !== 'string') { - opts.startkey = ''; - } - if ('endkey' in opts && typeof opts.endkey !== 'string') { - opts.limit = 0; + _stats: function (keys, values) { + // no need to implement rereduce=true, because Pouch + // will never call it + function sumsqr(values) { + var _sumsqr = 0; + for (var i = 0, len = values.length; i < len; i++) { + var num = values[i]; + _sumsqr += (num * num); + } + return _sumsqr; } + return { + sum : sum(values), + min : Math.min.apply(null, values), + max : Math.max.apply(null, values), + count : values.length, + sumsqr : sumsqr(values) + }; } - if ('key' in opts && typeof opts.key !== 'string') { - opts.limit = 0; - } +}; - return db.allDocs(opts) - .then(function (res) { - // filter out any design docs that _all_docs might return - res.rows = res.rows.filter(function (row) { - return !/^_design\//.test(row.id); - }); - return res; - }); +function getBuiltIn(reduceFunString) { + if (/^_sum/.test(reduceFunString)) { + return builtInReduce._sum; + } else if (/^_count/.test(reduceFunString)) { + return builtInReduce._count; + } else if (/^_stats/.test(reduceFunString)) { + return builtInReduce._stats; + } else if (/^_/.test(reduceFunString)) { + throw new Error(reduceFunString + ' is not a supported reduce function.'); + } } -function find$1(db, requestDef, explain) { - if (requestDef.selector) { - requestDef.selector = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.massageSelector)(requestDef.selector); +function mapper(mapFun, emit) { + // for temp_views one can use emit(doc, emit), see #38 + if (typeof mapFun === "function" && mapFun.length === 2) { + var origMap = mapFun; + return function (doc) { + return origMap(doc, emit); + }; + } else { + return evalFunctionWithEval(mapFun.toString(), emit); } +} - if (requestDef.sort) { - requestDef.sort = massageSort(requestDef.sort); +function reducer(reduceFun) { + var reduceFunString = reduceFun.toString(); + var builtIn = getBuiltIn(reduceFunString); + if (builtIn) { + return builtIn; + } else { + return evalFunctionWithEval(reduceFunString); } +} - if (requestDef.use_index) { - requestDef.use_index = massageUseIndex(requestDef.use_index); +function ddocValidator(ddoc, viewName) { + var fun = ddoc.views && ddoc.views[viewName]; + if (typeof fun.map !== 'string') { + throw new NotFoundError('ddoc ' + ddoc._id + ' has no string view named ' + + viewName + ', instead found object of type: ' + typeof fun.map); } +} - validateFindRequest(requestDef); +var localDocName = 'mrviews'; +var abstract = createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator); - return getIndexes$1(db).then(function (getIndexesRes) { +function query(fun, opts, callback) { + return abstract.query.call(this, fun, opts, callback); +} - db.constructor.emit('debug', ['find', 'planning query', requestDef]); - var queryPlan = planQuery(requestDef, getIndexesRes.indexes); - db.constructor.emit('debug', ['find', 'query plan', queryPlan]); +function viewCleanup(callback) { + return abstract.viewCleanup.call(this, callback); +} - var indexToUse = queryPlan.index; +var mapreduce = { + query: query, + viewCleanup: viewCleanup +}; - validateSort(requestDef, indexToUse); +function isGenOne$1(rev) { + return /^1-/.test(rev); +} - var opts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.assign)({ - include_docs: true, - reduce: false - }, queryPlan.queryOpts); +function fileHasChanged(localDoc, remoteDoc, filename) { + return !localDoc._attachments || + !localDoc._attachments[filename] || + localDoc._attachments[filename].digest !== remoteDoc._attachments[filename].digest; +} - if ('startkey' in opts && 'endkey' in opts && - (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__.collate)(opts.startkey, opts.endkey) > 0) { - // can't possibly return any results, startkey > endkey - /* istanbul ignore next */ - return {docs: []}; - } +function getDocAttachments(db, doc) { + var filenames = Object.keys(doc._attachments); + return Promise.all(filenames.map(function (filename) { + return db.getAttachment(doc._id, filename, {rev: doc._rev}); + })); +} - var isDescending = requestDef.sort && - typeof requestDef.sort[0] !== 'string' && - (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getValue)(requestDef.sort[0]) === 'desc'; +function getDocAttachmentsFromTargetOrSource(target, src, doc) { + var doCheckForLocalAttachments = isRemote(src) && !isRemote(target); + var filenames = Object.keys(doc._attachments); - if (isDescending) { - // either all descending or all ascending - opts.descending = true; - opts = reverseOptions(opts); - } + if (!doCheckForLocalAttachments) { + return getDocAttachments(src, doc); + } - if (!queryPlan.inMemoryFields.length) { - // no in-memory filtering necessary, so we can let the - // database do the limit/skip for us - if ('limit' in requestDef) { - opts.limit = requestDef.limit; - } - if ('skip' in requestDef) { - opts.skip = requestDef.skip; + return target.get(doc._id).then(function (localDoc) { + return Promise.all(filenames.map(function (filename) { + if (fileHasChanged(localDoc, doc, filename)) { + return src.getAttachment(doc._id, filename); } - } - if (explain) { - return Promise.resolve(queryPlan, opts); + return target.getAttachment(localDoc._id, filename); + })); + }).catch(function (error) { + /* istanbul ignore if */ + if (error.status !== 404) { + throw error; } - return Promise.resolve().then(function () { - if (indexToUse.name === '_all_docs') { - return doAllDocs(db, opts); - } else { - var signature = indexToSignature(indexToUse); - return abstractMapper.query.call(db, signature, opts); - } - }).then(function (res) { - if (opts.inclusive_start === false) { - // may have to manually filter the first one, - // since couchdb has no true inclusive_start option - res.rows = filterInclusiveStart(res.rows, opts.startkey, indexToUse); - } - - if (queryPlan.inMemoryFields.length) { - // need to filter some stuff in-memory - res.rows = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.filterInMemoryFields)(res.rows, requestDef, queryPlan.inMemoryFields); - } - - var resp = { - docs: res.rows.map(function (row) { - var doc = row.doc; - if (requestDef.fields) { - return pick(doc, requestDef.fields); - } - return doc; - }) - }; - - if (indexToUse.defaultUsed) { - resp.warning = 'no matching index found, create an index to optimize query time'; - } - - return resp; - }); + return getDocAttachments(src, doc); }); } -function explain$1(db, requestDef) { - return find$1(db, requestDef, true) - .then(function (queryPlan) { - return { - dbname: db.name, - index: queryPlan.index, - selector: requestDef.selector, - range: { - start_key: queryPlan.queryOpts.startkey, - end_key: queryPlan.queryOpts.endkey, - }, - opts: { - use_index: requestDef.use_index || [], - bookmark: "nil", //hardcoded to match CouchDB since its not supported, - limit: requestDef.limit, - skip: requestDef.skip, - sort: requestDef.sort || {}, - fields: requestDef.fields, - conflicts: false, //hardcoded to match CouchDB since its not supported, - r: [49], // hardcoded to match CouchDB since its not support - }, - limit: requestDef.limit, - skip: requestDef.skip || 0, - fields: requestDef.fields, - }; +function createBulkGetOpts(diffs) { + var requests = []; + Object.keys(diffs).forEach(function (id) { + var missingRevs = diffs[id].missing; + missingRevs.forEach(function (missingRev) { + requests.push({ + id: id, + rev: missingRev + }); + }); }); + + return { + docs: requests, + revs: true, + latest: true + }; } -function deleteIndex$1(db, index) { +// +// Fetch all the documents from the src as described in the "diffs", +// which is a mapping of docs IDs to revisions. If the state ever +// changes to "cancelled", then the returned promise will be rejected. +// Else it will be resolved with a list of fetched documents. +// +function getDocs(src, target, diffs, state) { + diffs = clone(diffs); // we do not need to modify this - if (!index.ddoc) { - throw new Error('you must supply an index.ddoc when deleting'); - } + var resultDocs = [], + ok = true; - if (!index.name) { - throw new Error('you must supply an index.name when deleting'); - } + function getAllDocs() { - var docId = index.ddoc; - var viewName = index.name; + var bulkGetOpts = createBulkGetOpts(diffs); - function deltaFun(doc) { - if (Object.keys(doc.views).length === 1 && doc.views[viewName]) { - // only one view in this ddoc, delete the whole ddoc - return {_id: docId, _deleted: true}; + if (!bulkGetOpts.docs.length) { // optimization: skip empty requests + return; } - // more than one view here, just remove the view - delete doc.views[viewName]; - return doc; - } - return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(db, docId, deltaFun).then(function () { - return abstractMapper.viewCleanup.apply(db); - }).then(function () { - return {ok: true}; - }); -} + return src.bulkGet(bulkGetOpts).then(function (bulkGetResponse) { + /* istanbul ignore if */ + if (state.cancelled) { + throw new Error('cancelled'); + } + return Promise.all(bulkGetResponse.results.map(function (bulkGetInfo) { + return Promise.all(bulkGetInfo.docs.map(function (doc) { + var remoteDoc = doc.ok; -var createIndexAsCallback = callbackify(createIndex$1); -var findAsCallback = callbackify(find$1); -var explainAsCallback = callbackify(explain$1); -var getIndexesAsCallback = callbackify(getIndexes$1); -var deleteIndexAsCallback = callbackify(deleteIndex$1); + if (doc.error) { + // when AUTO_COMPACTION is set, docs can be returned which look + // like this: {"missing":"1-7c3ac256b693c462af8442f992b83696"} + ok = false; + } -var plugin = {}; -plugin.createIndex = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) { + if (!remoteDoc || !remoteDoc._attachments) { + return remoteDoc; + } - if (typeof requestDef !== 'object') { - return callback(new Error('you must provide an index to create')); - } + return getDocAttachmentsFromTargetOrSource(target, src, remoteDoc) + .then(function (attachments) { + var filenames = Object.keys(remoteDoc._attachments); + attachments + .forEach(function (attachment, i) { + var att = remoteDoc._attachments[filenames[i]]; + delete att.stub; + delete att.length; + att.data = attachment; + }); - var createIndex$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? - createIndex : createIndexAsCallback; - createIndex$$1(this, requestDef, callback); -}); + return remoteDoc; + }); + })); + })) -plugin.find = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) { + .then(function (results) { + resultDocs = resultDocs.concat(flatten(results).filter(Boolean)); + }); + }); + } - if (typeof callback === 'undefined') { - callback = requestDef; - requestDef = undefined; + function hasAttachments(doc) { + return doc._attachments && Object.keys(doc._attachments).length > 0; } - if (typeof requestDef !== 'object') { - return callback(new Error('you must provide search parameters to find()')); + function hasConflicts(doc) { + return doc._conflicts && doc._conflicts.length > 0; } - var find$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? find : findAsCallback; - find$$1(this, requestDef, callback); -}); + function fetchRevisionOneDocs(ids) { + // Optimization: fetch gen-1 docs and attachments in + // a single request using _all_docs + return src.allDocs({ + keys: ids, + include_docs: true, + conflicts: true + }).then(function (res) { + if (state.cancelled) { + throw new Error('cancelled'); + } + res.rows.forEach(function (row) { + if (row.deleted || !row.doc || !isGenOne$1(row.value.rev) || + hasAttachments(row.doc) || hasConflicts(row.doc)) { + // if any of these conditions apply, we need to fetch using get() + return; + } -plugin.explain = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) { + // strip _conflicts array to appease CSG (#5793) + /* istanbul ignore if */ + if (row.doc._conflicts) { + delete row.doc._conflicts; + } - if (typeof callback === 'undefined') { - callback = requestDef; - requestDef = undefined; + // the doc we got back from allDocs() is sufficient + resultDocs.push(row.doc); + delete diffs[row.id]; + }); + }); } - if (typeof requestDef !== 'object') { - return callback(new Error('you must provide search parameters to explain()')); + function getRevisionOneDocs() { + // filter out the generation 1 docs and get them + // leaving the non-generation one docs to be got otherwise + var ids = Object.keys(diffs).filter(function (id) { + var missing = diffs[id].missing; + return missing.length === 1 && isGenOne$1(missing[0]); + }); + if (ids.length > 0) { + return fetchRevisionOneDocs(ids); + } } - var find$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? explain : explainAsCallback; - find$$1(this, requestDef, callback); -}); - -plugin.getIndexes = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (callback) { - - var getIndexes$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? getIndexes : getIndexesAsCallback; - getIndexes$$1(this, callback); -}); - -plugin.deleteIndex = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (indexDef, callback) { - - if (typeof indexDef !== 'object') { - return callback(new Error('you must provide an index to delete')); + function returnResult() { + return { ok:ok, docs:resultDocs }; } - var deleteIndex$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? - deleteIndex : deleteIndexAsCallback; - deleteIndex$$1(this, indexDef, callback); -}); - -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (plugin); - - -/***/ }), -/* 495 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "adapterFun": () => (/* binding */ adapterFun), -/* harmony export */ "assign": () => (/* binding */ assign$1), -/* harmony export */ "bulkGetShim": () => (/* binding */ bulkGet), -/* harmony export */ "changesHandler": () => (/* binding */ Changes), -/* harmony export */ "clone": () => (/* binding */ clone$1), -/* harmony export */ "defaultBackOff": () => (/* binding */ defaultBackOff), -/* harmony export */ "explainError": () => (/* binding */ res), -/* harmony export */ "filterChange": () => (/* binding */ filterChange), -/* harmony export */ "flatten": () => (/* binding */ flatten), -/* harmony export */ "functionName": () => (/* binding */ res$2), -/* harmony export */ "guardedConsole": () => (/* binding */ guardedConsole), -/* harmony export */ "hasLocalStorage": () => (/* binding */ hasLocalStorage), -/* harmony export */ "invalidIdError": () => (/* binding */ invalidIdError), -/* harmony export */ "isRemote": () => (/* binding */ isRemote), -/* harmony export */ "listenerCount": () => (/* binding */ listenerCount), -/* harmony export */ "nextTick": () => (/* binding */ nextTick), -/* harmony export */ "normalizeDdocFunctionName": () => (/* binding */ normalizeDesignDocFunctionName), -/* harmony export */ "once": () => (/* binding */ once), -/* harmony export */ "parseDdocFunctionName": () => (/* binding */ parseDesignDocFunctionName), -/* harmony export */ "parseUri": () => (/* binding */ parseUri), -/* harmony export */ "pick": () => (/* binding */ pick), -/* harmony export */ "rev": () => (/* binding */ rev), -/* harmony export */ "scopeEval": () => (/* binding */ scopeEval), -/* harmony export */ "toPromise": () => (/* binding */ toPromise), -/* harmony export */ "upsert": () => (/* binding */ upsert), -/* harmony export */ "uuid": () => (/* binding */ uuid) -/* harmony export */ }); -/* harmony import */ var clone_buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(496); -/* harmony import */ var clone_buffer__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(clone_buffer__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(483); -/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(497); -/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(250); -/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(485); -/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_4__); -/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(498); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(488); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_6__); -/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(499); -/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(495); - + return Promise.resolve() + .then(getRevisionOneDocs) + .then(getAllDocs) + .then(returnResult); +} +var CHECKPOINT_VERSION = 1; +var REPLICATOR = "pouchdb"; +// This is an arbitrary number to limit the +// amount of replication history we save in the checkpoint. +// If we save too much, the checkpoing docs will become very big, +// if we save fewer, we'll run a greater risk of having to +// read all the changes from 0 when checkpoint PUTs fail +// CouchDB 2.0 has a more involved history pruning, +// but let's go for the simple version for now. +var CHECKPOINT_HISTORY_SIZE = 5; +var LOWEST_SEQ = 0; +function updateCheckpoint(db, id, checkpoint, session, returnValue) { + return db.get(id).catch(function (err) { + if (err.status === 404) { + if (db.adapter === 'http' || db.adapter === 'https') { + explainError( + 404, 'PouchDB is just checking if a remote checkpoint exists.' + ); + } + return { + session_id: session, + _id: id, + history: [], + replicator: REPLICATOR, + version: CHECKPOINT_VERSION + }; + } + throw err; + }).then(function (doc) { + if (returnValue.cancelled) { + return; + } + // if the checkpoint has not changed, do not update + if (doc.last_seq === checkpoint) { + return; + } + // Filter out current entry for this replication + doc.history = (doc.history || []).filter(function (item) { + return item.session_id !== session; + }); + // Add the latest checkpoint to history + doc.history.unshift({ + last_seq: checkpoint, + session_id: session + }); + // Just take the last pieces in history, to + // avoid really big checkpoint docs. + // see comment on history size above + doc.history = doc.history.slice(0, CHECKPOINT_HISTORY_SIZE); + doc.version = CHECKPOINT_VERSION; + doc.replicator = REPLICATOR; + doc.session_id = session; + doc.last_seq = checkpoint; -function isBinaryObject(object) { - return object instanceof Buffer; + return db.put(doc).catch(function (err) { + if (err.status === 409) { + // retry; someone is trying to write a checkpoint simultaneously + return updateCheckpoint(db, id, checkpoint, session, returnValue); + } + throw err; + }); + }); } -// most of this is borrowed from lodash.isPlainObject: -// https://github.com/fis-components/lodash.isplainobject/ -// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js +function Checkpointer(src, target, id, returnValue, opts) { + this.src = src; + this.target = target; + this.id = id; + this.returnValue = returnValue; + this.opts = opts || {}; +} -var funcToString = Function.prototype.toString; -var objectCtorString = funcToString.call(Object); +Checkpointer.prototype.writeCheckpoint = function (checkpoint, session) { + var self = this; + return this.updateTarget(checkpoint, session).then(function () { + return self.updateSource(checkpoint, session); + }); +}; -function isPlainObject(value) { - var proto = Object.getPrototypeOf(value); - /* istanbul ignore if */ - if (proto === null) { // not sure when this happens, but I guess it can - return true; +Checkpointer.prototype.updateTarget = function (checkpoint, session) { + if (this.opts.writeTargetCheckpoint) { + return updateCheckpoint(this.target, this.id, checkpoint, + session, this.returnValue); + } else { + return Promise.resolve(true); } - var Ctor = proto.constructor; - return (typeof Ctor == 'function' && - Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); -} - -function clone$1(object) { - var newObject; - var i; - var len; +}; - if (!object || typeof object !== 'object') { - return object; +Checkpointer.prototype.updateSource = function (checkpoint, session) { + if (this.opts.writeSourceCheckpoint) { + var self = this; + return updateCheckpoint(this.src, this.id, checkpoint, + session, this.returnValue) + .catch(function (err) { + if (isForbiddenError(err)) { + self.opts.writeSourceCheckpoint = false; + return true; + } + throw err; + }); + } else { + return Promise.resolve(true); } +}; - if (Array.isArray(object)) { - newObject = []; - for (i = 0, len = object.length; i < len; i++) { - newObject[i] = clone$1(object[i]); +var comparisons = { + "undefined": function (targetDoc, sourceDoc) { + // This is the previous comparison function + if (collate(targetDoc.last_seq, sourceDoc.last_seq) === 0) { + return sourceDoc.last_seq; } - return newObject; + /* istanbul ignore next */ + return 0; + }, + "1": function (targetDoc, sourceDoc) { + // This is the comparison function ported from CouchDB + return compareReplicationLogs(sourceDoc, targetDoc).last_seq; } +}; - // special case: to avoid inconsistencies between IndexedDB - // and other backends, we automatically stringify Dates - if (object instanceof Date) { - return object.toISOString(); - } +Checkpointer.prototype.getCheckpoint = function () { + var self = this; - if (isBinaryObject(object)) { - return clone_buffer__WEBPACK_IMPORTED_MODULE_0___default()(object); + if (self.opts && self.opts.writeSourceCheckpoint && !self.opts.writeTargetCheckpoint) { + return self.src.get(self.id).then(function (sourceDoc) { + return sourceDoc.last_seq || LOWEST_SEQ; + }).catch(function (err) { + /* istanbul ignore if */ + if (err.status !== 404) { + throw err; + } + return LOWEST_SEQ; + }); } - if (!isPlainObject(object)) { - return object; // don't clone objects like Workers - } + return self.target.get(self.id).then(function (targetDoc) { + if (self.opts && self.opts.writeTargetCheckpoint && !self.opts.writeSourceCheckpoint) { + return targetDoc.last_seq || LOWEST_SEQ; + } - newObject = {}; - for (i in object) { - /* istanbul ignore else */ - if (Object.prototype.hasOwnProperty.call(object, i)) { - var value = clone$1(object[i]); - if (typeof value !== 'undefined') { - newObject[i] = value; + return self.src.get(self.id).then(function (sourceDoc) { + // Since we can't migrate an old version doc to a new one + // (no session id), we just go with the lowest seq in this case + /* istanbul ignore if */ + if (targetDoc.version !== sourceDoc.version) { + return LOWEST_SEQ; } - } - } - return newObject; -} -function once(fun) { - var called = false; - return argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) { - /* istanbul ignore if */ - if (called) { - // this is a smoke test and should never actually happen - throw new Error('once called more than once'); - } else { - called = true; - fun.apply(this, args); - } - }); -} + var version; + if (targetDoc.version) { + version = targetDoc.version.toString(); + } else { + version = "undefined"; + } -function toPromise(func) { - //create the function we will be returning - return argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) { - // Clone arguments - args = clone$1(args); - var self = this; - // if the last argument is a function, assume its a callback - var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false; - var promise = new Promise(function (fulfill, reject) { - var resp; - try { - var callback = once(function (err, mesg) { - if (err) { - reject(err); - } else { - fulfill(mesg); + if (version in comparisons) { + return comparisons[version](targetDoc, sourceDoc); + } + /* istanbul ignore next */ + return LOWEST_SEQ; + }, function (err) { + if (err.status === 404 && targetDoc.last_seq) { + return self.src.put({ + _id: self.id, + last_seq: LOWEST_SEQ + }).then(function () { + return LOWEST_SEQ; + }, function (err) { + if (isForbiddenError(err)) { + self.opts.writeSourceCheckpoint = false; + return targetDoc.last_seq; } + /* istanbul ignore next */ + return LOWEST_SEQ; }); - // create a callback for this invocation - // apply the function in the orig context - args.push(callback); - resp = func.apply(self, args); - if (resp && typeof resp.then === 'function') { - fulfill(resp); - } - } catch (e) { - reject(e); } + throw err; }); - // if there is a callback, call it back - if (usedCB) { - promise.then(function (result) { - usedCB(null, result); - }, usedCB); + }).catch(function (err) { + if (err.status !== 404) { + throw err; } - return promise; + return LOWEST_SEQ; }); +}; +// This checkpoint comparison is ported from CouchDBs source +// they come from here: +// https://github.com/apache/couchdb-couch-replicator/blob/master/src/couch_replicator.erl#L863-L906 + +function compareReplicationLogs(srcDoc, tgtDoc) { + if (srcDoc.session_id === tgtDoc.session_id) { + return { + last_seq: srcDoc.last_seq, + history: srcDoc.history + }; + } + + return compareReplicationHistory(srcDoc.history, tgtDoc.history); } -function logApiCall(self, name, args) { +function compareReplicationHistory(sourceHistory, targetHistory) { + // the erlang loop via function arguments is not so easy to repeat in JS + // therefore, doing this as recursion + var S = sourceHistory[0]; + var sourceRest = sourceHistory.slice(1); + var T = targetHistory[0]; + var targetRest = targetHistory.slice(1); + + if (!S || targetHistory.length === 0) { + return { + last_seq: LOWEST_SEQ, + history: [] + }; + } + + var sourceId = S.session_id; /* istanbul ignore if */ - if (self.constructor.listeners('debug').length) { - var logArgs = ['api', self.name, name]; - for (var i = 0; i < args.length - 1; i++) { - logArgs.push(args[i]); - } - self.constructor.emit('debug', logArgs); + if (hasSessionId(sourceId, targetHistory)) { + return { + last_seq: S.last_seq, + history: sourceHistory + }; + } - // override the callback itself to log the response - var origCallback = args[args.length - 1]; - args[args.length - 1] = function (err, res) { - var responseArgs = ['api', self.name, name]; - responseArgs = responseArgs.concat( - err ? ['error', err] : ['success', res] - ); - self.constructor.emit('debug', responseArgs); - origCallback(err, res); + var targetId = T.session_id; + if (hasSessionId(targetId, sourceRest)) { + return { + last_seq: T.last_seq, + history: targetRest }; } -} -function adapterFun(name, callback) { - return toPromise(argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) { - if (this._closed) { - return Promise.reject(new Error('database is closed')); - } - if (this._destroyed) { - return Promise.reject(new Error('database is destroyed')); - } - var self = this; - logApiCall(self, name, args); - if (!this.taskqueue.isReady) { - return new Promise(function (fulfill, reject) { - self.taskqueue.addTask(function (failed) { - if (failed) { - reject(failed); - } else { - fulfill(self[name].apply(self, args)); - } - }); - }); - } - return callback.apply(this, args); - })); + return compareReplicationHistory(sourceRest, targetRest); } -// like underscore/lodash _.pick() -function pick(obj, arr) { - var res = {}; - for (var i = 0, len = arr.length; i < len; i++) { - var prop = arr[i]; - if (prop in obj) { - res[prop] = obj[prop]; - } +function hasSessionId(sessionId, history) { + var props = history[0]; + var rest = history.slice(1); + + if (!sessionId || history.length === 0) { + return false; } - return res; -} -// Most browsers throttle concurrent requests at 6, so it's silly -// to shim _bulk_get by trying to launch potentially hundreds of requests -// and then letting the majority time out. We can handle this ourselves. -var MAX_NUM_CONCURRENT_REQUESTS = 6; + if (sessionId === props.session_id) { + return true; + } -function identityFunction(x) { - return x; + return hasSessionId(sessionId, rest); } -function formatResultForOpenRevsGet(result) { - return [{ - ok: result - }]; +function isForbiddenError(err) { + return typeof err.status === 'number' && Math.floor(err.status / 100) === 4; } -// shim for P/CouchDB adapters that don't directly implement _bulk_get -function bulkGet(db, opts, callback) { - var requests = opts.docs; +var STARTING_BACK_OFF = 0; - // consolidate into one request per doc if possible - var requestsById = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); - requests.forEach(function (request) { - if (requestsById.has(request.id)) { - requestsById.get(request.id).push(request); - } else { - requestsById.set(request.id, [request]); - } - }); +function backOff(opts, returnValue, error, callback) { + if (opts.retry === false) { + returnValue.emit('error', error); + returnValue.removeAllListeners(); + return; + } + /* istanbul ignore if */ + if (typeof opts.back_off_function !== 'function') { + opts.back_off_function = defaultBackOff; + } + returnValue.emit('requestError', error); + if (returnValue.state === 'active' || returnValue.state === 'pending') { + returnValue.emit('paused', error); + returnValue.state = 'stopped'; + var backOffSet = function backoffTimeSet() { + opts.current_back_off = STARTING_BACK_OFF; + }; + var removeBackOffSetter = function removeBackOffTimeSet() { + returnValue.removeListener('active', backOffSet); + }; + returnValue.once('paused', removeBackOffSetter); + returnValue.once('active', backOffSet); + } + + opts.current_back_off = opts.current_back_off || STARTING_BACK_OFF; + opts.current_back_off = opts.back_off_function(opts.current_back_off); + setTimeout(callback, opts.current_back_off); +} + +function sortObjectPropertiesByKey(queryParams) { + return Object.keys(queryParams).sort(collate).reduce(function (result, key) { + result[key] = queryParams[key]; + return result; + }, {}); +} - var numDocs = requestsById.size; - var numDone = 0; - var perDocResults = new Array(numDocs); +// Generate a unique id particular to this replication. +// Not guaranteed to align perfectly with CouchDB's rep ids. +function generateReplicationId(src, target, opts) { + var docIds = opts.doc_ids ? opts.doc_ids.sort(collate) : ''; + var filterFun = opts.filter ? opts.filter.toString() : ''; + var queryParams = ''; + var filterViewName = ''; + var selector = ''; - function collapseResultsAndFinish() { - var results = []; - perDocResults.forEach(function (res) { - res.docs.forEach(function (info) { - results.push({ - id: res.id, - docs: [info] - }); - }); - }); - callback(null, {results: results}); + // possibility for checkpoints to be lost here as behaviour of + // JSON.stringify is not stable (see #6226) + /* istanbul ignore if */ + if (opts.selector) { + selector = JSON.stringify(opts.selector); } - function checkDone() { - if (++numDone === numDocs) { - collapseResultsAndFinish(); - } + if (opts.filter && opts.query_params) { + queryParams = JSON.stringify(sortObjectPropertiesByKey(opts.query_params)); } - function gotResult(docIndex, id, docs) { - perDocResults[docIndex] = {id: id, docs: docs}; - checkDone(); + if (opts.filter && opts.filter === '_view') { + filterViewName = opts.view.toString(); } - var allRequests = []; - requestsById.forEach(function (value, key) { - allRequests.push(key); + return Promise.all([src.id(), target.id()]).then(function (res) { + var queryData = res[0] + res[1] + filterFun + filterViewName + + queryParams + docIds + selector; + return new Promise(function (resolve) { + binaryMd5(queryData, resolve); + }); + }).then(function (md5sum) { + // can't use straight-up md5 alphabet, because + // the char '/' is interpreted as being for attachments, + // and + is also not url-safe + md5sum = md5sum.replace(/\//g, '.').replace(/\+/g, '_'); + return '_local/' + md5sum; }); +} - var i = 0; - - function nextBatch() { - - if (i >= allRequests.length) { - return; - } +function replicate(src, target, opts, returnValue, result) { + var batches = []; // list of batches to be processed + var currentBatch; // the batch currently being processed + var pendingBatch = { + seq: 0, + changes: [], + docs: [] + }; // next batch, not yet ready to be processed + var writingCheckpoint = false; // true while checkpoint is being written + var changesCompleted = false; // true when all changes received + var replicationCompleted = false; // true when replication has completed + var last_seq = 0; + var continuous = opts.continuous || opts.live || false; + var batch_size = opts.batch_size || 100; + var batches_limit = opts.batches_limit || 10; + var changesPending = false; // true while src.changes is running + var doc_ids = opts.doc_ids; + var selector = opts.selector; + var repId; + var checkpointer; + var changedDocs = []; + // Like couchdb, every replication gets a unique session id + var session = uuid(); - var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length); - var batch = allRequests.slice(i, upTo); - processBatch(batch, i); - i += batch.length; - } + result = result || { + ok: true, + start_time: new Date().toISOString(), + docs_read: 0, + docs_written: 0, + doc_write_failures: 0, + errors: [] + }; - function processBatch(batch, offset) { - batch.forEach(function (docId, j) { - var docIdx = offset + j; - var docRequests = requestsById.get(docId); + var changesOpts = {}; + returnValue.ready(src, target); - // just use the first request as the "template" - // TODO: The _bulk_get API allows for more subtle use cases than this, - // but for now it is unlikely that there will be a mix of different - // "atts_since" or "attachments" in the same request, since it's just - // replicate.js that is using this for the moment. - // Also, atts_since is aspirational, since we don't support it yet. - var docOpts = pick(docRequests[0], ['atts_since', 'attachments']); - docOpts.open_revs = docRequests.map(function (request) { - // rev is optional, open_revs disallowed - return request.rev; - }); + function initCheckpointer() { + if (checkpointer) { + return Promise.resolve(); + } + return generateReplicationId(src, target, opts).then(function (res) { + repId = res; - // remove falsey / undefined revisions - docOpts.open_revs = docOpts.open_revs.filter(identityFunction); + var checkpointOpts = {}; + if (opts.checkpoint === false) { + checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: false }; + } else if (opts.checkpoint === 'source') { + checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: false }; + } else if (opts.checkpoint === 'target') { + checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: true }; + } else { + checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: true }; + } - var formatResult = identityFunction; + checkpointer = new Checkpointer(src, target, repId, returnValue, checkpointOpts); + }); + } - if (docOpts.open_revs.length === 0) { - delete docOpts.open_revs; + function writeDocs() { + changedDocs = []; - // when fetching only the "winning" leaf, - // transform the result so it looks like an open_revs - // request - formatResult = formatResultForOpenRevsGet; + if (currentBatch.docs.length === 0) { + return; + } + var docs = currentBatch.docs; + var bulkOpts = {timeout: opts.timeout}; + return target.bulkDocs({docs: docs, new_edits: false}, bulkOpts).then(function (res) { + /* istanbul ignore if */ + if (returnValue.cancelled) { + completeReplication(); + throw new Error('cancelled'); } - // globally-supplied options - ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) { - if (param in opts) { - docOpts[param] = opts[param]; + // `res` doesn't include full documents (which live in `docs`), so we create a map of + // (id -> error), and check for errors while iterating over `docs` + var errorsById = Object.create(null); + res.forEach(function (res) { + if (res.error) { + errorsById[res.id] = res; } }); - db.get(docId, docOpts, function (err, res) { - var result; - /* istanbul ignore if */ - if (err) { - result = [{error: err}]; + + var errorsNo = Object.keys(errorsById).length; + result.doc_write_failures += errorsNo; + result.docs_written += docs.length - errorsNo; + + docs.forEach(function (doc) { + var error = errorsById[doc._id]; + if (error) { + result.errors.push(error); + // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway) + var errorName = (error.name || '').toLowerCase(); + if (errorName === 'unauthorized' || errorName === 'forbidden') { + returnValue.emit('denied', clone(error)); + } else { + throw error; + } } else { - result = formatResult(res); + changedDocs.push(doc); } - gotResult(docIdx, docId, result); - nextBatch(); }); + + }, function (err) { + result.doc_write_failures += docs.length; + throw err; }); } - nextBatch(); - -} - -// in Node of course this is false -function hasLocalStorage() { - return false; -} - -function nextTick(fn) { - process.nextTick(fn); -} - -inherits__WEBPACK_IMPORTED_MODULE_4___default()(Changes, events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter); - -/* istanbul ignore next */ -function attachBrowserEvents(self) { - if (hasLocalStorage()) { - addEventListener("storage", function (e) { - self.emit(e.key); + function finishBatch() { + if (currentBatch.error) { + throw new Error('There was a problem getting docs.'); + } + result.last_seq = last_seq = currentBatch.seq; + var outResult = clone(result); + if (changedDocs.length) { + outResult.docs = changedDocs; + // Attach 'pending' property if server supports it (CouchDB 2.0+) + /* istanbul ignore if */ + if (typeof currentBatch.pending === 'number') { + outResult.pending = currentBatch.pending; + delete currentBatch.pending; + } + returnValue.emit('change', outResult); + } + writingCheckpoint = true; + return checkpointer.writeCheckpoint(currentBatch.seq, + session).then(function () { + writingCheckpoint = false; + /* istanbul ignore if */ + if (returnValue.cancelled) { + completeReplication(); + throw new Error('cancelled'); + } + currentBatch = undefined; + getChanges(); + }).catch(function (err) { + onCheckpointError(err); + throw err; }); } -} -function Changes() { - events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.call(this); - this._listeners = {}; + function getDiffs() { + var diff = {}; + currentBatch.changes.forEach(function (change) { + // Couchbase Sync Gateway emits these, but we can ignore them + /* istanbul ignore if */ + if (change.id === "_user/") { + return; + } + diff[change.id] = change.changes.map(function (x) { + return x.rev; + }); + }); + return target.revsDiff(diff).then(function (diffs) { + /* istanbul ignore if */ + if (returnValue.cancelled) { + completeReplication(); + throw new Error('cancelled'); + } + // currentBatch.diffs elements are deleted as the documents are written + currentBatch.diffs = diffs; + }); + } - attachBrowserEvents(this); -} -Changes.prototype.addListener = function (dbName, id, db, opts) { - /* istanbul ignore if */ - if (this._listeners[id]) { - return; + function getBatchDocs() { + return getDocs(src, target, currentBatch.diffs, returnValue).then(function (got) { + currentBatch.error = !got.ok; + got.docs.forEach(function (doc) { + delete currentBatch.diffs[doc._id]; + result.docs_read++; + currentBatch.docs.push(doc); + }); + }); } - var self = this; - var inprogress = false; - function eventFunction() { - /* istanbul ignore if */ - if (!self._listeners[id]) { + + function startNextBatch() { + if (returnValue.cancelled || currentBatch) { return; } - if (inprogress) { - inprogress = 'waiting'; + if (batches.length === 0) { + processPendingBatch(true); return; } - inprogress = true; - var changesOpts = pick(opts, [ - 'style', 'include_docs', 'attachments', 'conflicts', 'filter', - 'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs' - ]); + currentBatch = batches.shift(); + getDiffs() + .then(getBatchDocs) + .then(writeDocs) + .then(finishBatch) + .then(startNextBatch) + .catch(function (err) { + abortReplication('batch processing terminated with error', err); + }); + } - /* istanbul ignore next */ - function onError() { - inprogress = false; - } - db.changes(changesOpts).on('change', function (c) { - if (c.seq > opts.since && !opts.cancelled) { - opts.since = c.seq; - opts.onChange(c); + function processPendingBatch(immediate) { + if (pendingBatch.changes.length === 0) { + if (batches.length === 0 && !currentBatch) { + if ((continuous && changesOpts.live) || changesCompleted) { + returnValue.state = 'pending'; + returnValue.emit('paused'); + } + if (changesCompleted) { + completeReplication(); + } } - }).on('complete', function () { - if (inprogress === 'waiting') { - nextTick(eventFunction); + return; + } + if ( + immediate || + changesCompleted || + pendingBatch.changes.length >= batch_size + ) { + batches.push(pendingBatch); + pendingBatch = { + seq: 0, + changes: [], + docs: [] + }; + if (returnValue.state === 'pending' || returnValue.state === 'stopped') { + returnValue.state = 'active'; + returnValue.emit('active'); } - inprogress = false; - }).on('error', onError); + startNextBatch(); + } } - this._listeners[id] = eventFunction; - this.on(dbName, eventFunction); -}; -Changes.prototype.removeListener = function (dbName, id) { - /* istanbul ignore if */ - if (!(id in this._listeners)) { - return; + + function abortReplication(reason, err) { + if (replicationCompleted) { + return; + } + if (!err.message) { + err.message = reason; + } + result.ok = false; + result.status = 'aborting'; + batches = []; + pendingBatch = { + seq: 0, + changes: [], + docs: [] + }; + completeReplication(err); } - events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.prototype.removeListener.call(this, dbName, - this._listeners[id]); - delete this._listeners[id]; -}; -/* istanbul ignore next */ -Changes.prototype.notifyLocalWindows = function (dbName) { - //do a useless change on a storage thing - //in order to get other windows's listeners to activate - if (hasLocalStorage()) { - localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a"; - } -}; + function completeReplication(fatalError) { + if (replicationCompleted) { + return; + } + /* istanbul ignore if */ + if (returnValue.cancelled) { + result.status = 'cancelled'; + if (writingCheckpoint) { + return; + } + } + result.status = result.status || 'complete'; + result.end_time = new Date().toISOString(); + result.last_seq = last_seq; + replicationCompleted = true; -Changes.prototype.notify = function (dbName) { - this.emit(dbName); - this.notifyLocalWindows(dbName); -}; + if (fatalError) { + // need to extend the error because Firefox considers ".result" read-only + fatalError = createError(fatalError); + fatalError.result = result; -function guardedConsole(method) { - /* istanbul ignore else */ - if (typeof console !== 'undefined' && typeof console[method] === 'function') { - var args = Array.prototype.slice.call(arguments, 1); - console[method].apply(console, args); + // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway) + var errorName = (fatalError.name || '').toLowerCase(); + if (errorName === 'unauthorized' || errorName === 'forbidden') { + returnValue.emit('error', fatalError); + returnValue.removeAllListeners(); + } else { + backOff(opts, returnValue, fatalError, function () { + replicate(src, target, opts, returnValue); + }); + } + } else { + returnValue.emit('complete', result); + returnValue.removeAllListeners(); + } } -} -function randomNumber(min, max) { - var maxTimeout = 600000; // Hard-coded default of 10 minutes - min = parseInt(min, 10) || 0; - max = parseInt(max, 10); - if (max !== max || max <= min) { - max = (min || 1) << 1; //doubling - } else { - max = max + 1; - } - // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout - if (max > maxTimeout) { - min = maxTimeout >> 1; // divide by two - max = maxTimeout; - } - var ratio = Math.random(); - var range = max - min; - return ~~(range * ratio + min); // ~~ coerces to an int, but fast. -} + function onChange(change, pending, lastSeq) { + /* istanbul ignore if */ + if (returnValue.cancelled) { + return completeReplication(); + } + // Attach 'pending' property if server supports it (CouchDB 2.0+) + /* istanbul ignore if */ + if (typeof pending === 'number') { + pendingBatch.pending = pending; + } -function defaultBackOff(min) { - var max = 0; - if (!min) { - max = 2000; + var filter = filterChange(opts)(change); + if (!filter) { + return; + } + pendingBatch.seq = change.seq || lastSeq; + pendingBatch.changes.push(change); + immediate__WEBPACK_IMPORTED_MODULE_1___default()(function () { + processPendingBatch(batches.length === 0 && changesOpts.live); + }); } - return randomNumber(min, max); -} -// We assume Node users don't need to see this warning -var res = function () {}; -var assign; -{ - if (typeof Object.assign === 'function') { - assign = Object.assign; - } else { - // lite Object.assign polyfill based on - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - assign = function (target) { - var to = Object(target); + function onChangesComplete(changes) { + changesPending = false; + /* istanbul ignore if */ + if (returnValue.cancelled) { + return completeReplication(); + } - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; + // if no results were returned then we're done, + // else fetch more + if (changes.results.length > 0) { + changesOpts.since = changes.results[changes.results.length - 1].seq; + getChanges(); + processPendingBatch(true); + } else { - if (nextSource != null) { // Skip over if undefined or null - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } + var complete = function () { + if (continuous) { + changesOpts.live = true; + getChanges(); + } else { + changesCompleted = true; } + processPendingBatch(true); + }; + + // update the checkpoint so we start from the right seq next time + if (!currentBatch && changes.results.length === 0) { + writingCheckpoint = true; + checkpointer.writeCheckpoint(changes.last_seq, + session).then(function () { + writingCheckpoint = false; + result.last_seq = last_seq = changes.last_seq; + complete(); + }) + .catch(onCheckpointError); + } else { + complete(); } - return to; - }; + } } -} -var assign$1 = assign; -function tryFilter(filter, doc, req) { - try { - return !filter(doc, req); - } catch (err) { - var msg = 'Filter function threw: ' + err.toString(); - return (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.BAD_REQUEST, msg); + function onChangesError(err) { + changesPending = false; + /* istanbul ignore if */ + if (returnValue.cancelled) { + return completeReplication(); + } + abortReplication('changes rejected', err); } -} -function filterChange(opts) { - var req = {}; - var hasFilter = opts.filter && typeof opts.filter === 'function'; - req.query = opts.query_params; - return function filter(change) { - if (!change.doc) { - // CSG sends events on the changes feed that don't have documents, - // this hack makes a whole lot of existing code robust. - change.doc = {}; + function getChanges() { + if (!( + !changesPending && + !changesCompleted && + batches.length < batches_limit + )) { + return; + } + changesPending = true; + function abortChanges() { + changes.cancel(); + } + function removeListener() { + returnValue.removeListener('cancel', abortChanges); } - var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req); - - if (typeof filterReturn === 'object') { - return filterReturn; + if (returnValue._changes) { // remove old changes() and listeners + returnValue.removeListener('cancel', returnValue._abortChanges); + returnValue._changes.cancel(); } + returnValue.once('cancel', abortChanges); - if (filterReturn) { - return false; + var changes = src.changes(changesOpts) + .on('change', onChange); + changes.then(removeListener, removeListener); + changes.then(onChangesComplete) + .catch(onChangesError); + + if (opts.retry) { + // save for later so we can cancel if necessary + returnValue._changes = changes; + returnValue._abortChanges = abortChanges; } + } - if (!opts.include_docs) { - delete change.doc; - } else if (!opts.attachments) { - for (var att in change.doc._attachments) { - /* istanbul ignore else */ - if (change.doc._attachments.hasOwnProperty(att)) { - change.doc._attachments[att].stub = true; - } + + function startChanges() { + initCheckpointer().then(function () { + /* istanbul ignore if */ + if (returnValue.cancelled) { + completeReplication(); + return; } - } - return true; - }; -} + return checkpointer.getCheckpoint().then(function (checkpoint) { + last_seq = checkpoint; + changesOpts = { + since: last_seq, + limit: batch_size, + batch_size: batch_size, + style: 'all_docs', + doc_ids: doc_ids, + selector: selector, + return_docs: true // required so we know when we're done + }; + if (opts.filter) { + if (typeof opts.filter !== 'string') { + // required for the client-side filter in onChange + changesOpts.include_docs = true; + } else { // ddoc filter + changesOpts.filter = opts.filter; + } + } + if ('heartbeat' in opts) { + changesOpts.heartbeat = opts.heartbeat; + } + if ('timeout' in opts) { + changesOpts.timeout = opts.timeout; + } + if (opts.query_params) { + changesOpts.query_params = opts.query_params; + } + if (opts.view) { + changesOpts.view = opts.view; + } + getChanges(); + }); + }).catch(function (err) { + abortReplication('getCheckpoint rejected with ', err); + }); + } -function flatten(arrs) { - var res = []; - for (var i = 0, len = arrs.length; i < len; i++) { - res = res.concat(arrs[i]); + /* istanbul ignore next */ + function onCheckpointError(err) { + writingCheckpoint = false; + abortReplication('writeCheckpoint completed with error', err); } - return res; -} -// shim for Function.prototype.name, -// for browsers that don't support it like IE + /* istanbul ignore if */ + if (returnValue.cancelled) { // cancelled immediately + completeReplication(); + return; + } -/* istanbul ignore next */ -function f() {} + if (!returnValue._addedListeners) { + returnValue.once('cancel', completeReplication); -var hasName = f.name; -var res$1; + if (typeof opts.complete === 'function') { + returnValue.once('error', opts.complete); + returnValue.once('complete', function (result) { + opts.complete(null, result); + }); + } + returnValue._addedListeners = true; + } -// We dont run coverage in IE -/* istanbul ignore else */ -if (hasName) { - res$1 = function (fun) { - return fun.name; + if (typeof opts.since === 'undefined') { + startChanges(); + } else { + initCheckpointer().then(function () { + writingCheckpoint = true; + return checkpointer.writeCheckpoint(opts.since, session); + }).then(function () { + writingCheckpoint = false; + /* istanbul ignore if */ + if (returnValue.cancelled) { + completeReplication(); + return; + } + last_seq = opts.since; + startChanges(); + }).catch(onCheckpointError); + } +} + +// We create a basic promise so the caller can cancel the replication possibly +// before we have actually started listening to changes etc +inherits__WEBPACK_IMPORTED_MODULE_3___default()(Replication, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); +function Replication() { + events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter.call(this); + this.cancelled = false; + this.state = 'pending'; + var self = this; + var promise = new Promise(function (fulfill, reject) { + self.once('complete', fulfill); + self.once('error', reject); + }); + self.then = function (resolve, reject) { + return promise.then(resolve, reject); }; -} else { - res$1 = function (fun) { - var match = fun.toString().match(/^\s*function\s*(?:(\S+)\s*)?\(/); - if (match && match[1]) { - return match[1]; - } - else { - return ''; - } + self.catch = function (reject) { + return promise.catch(reject); }; + // As we allow error handling via "error" event as well, + // put a stub in here so that rejecting never throws UnhandledError. + self.catch(function () {}); } -var res$2 = res$1; +Replication.prototype.cancel = function () { + this.cancelled = true; + this.state = 'cancelled'; + this.emit('cancel'); +}; -// Determine id an ID is valid -// - invalid IDs begin with an underescore that does not begin '_design' or -// '_local' -// - any other string value is a valid id -// Returns the specific error object for each case -function invalidIdError(id) { - var err; - if (!id) { - err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.MISSING_ID); - } else if (typeof id !== 'string') { - err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.INVALID_ID); - } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) { - err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.RESERVED_ID); +Replication.prototype.ready = function (src, target) { + var self = this; + if (self._readyCalled) { + return; } - if (err) { - throw err; + self._readyCalled = true; + + function onDestroy() { + self.cancel(); + } + src.once('destroyed', onDestroy); + target.once('destroyed', onDestroy); + function cleanup() { + src.removeListener('destroyed', onDestroy); + target.removeListener('destroyed', onDestroy); + } + self.once('complete', cleanup); +}; + +function toPouch(db, opts) { + var PouchConstructor = opts.PouchConstructor; + if (typeof db === 'string') { + return new PouchConstructor(db, opts); + } else { + return db; } } -// Checks if a PouchDB object is "remote" or not. This is +function replicateWrapper(src, target, opts, callback) { -function isRemote(db) { - if (typeof db._remote === 'boolean') { - return db._remote; + if (typeof opts === 'function') { + callback = opts; + opts = {}; } - /* istanbul ignore next */ - if (typeof db.type === 'function') { - guardedConsole('warn', - 'db.type() is deprecated and will be removed in ' + - 'a future version of PouchDB'); - return db.type() === 'http'; + if (typeof opts === 'undefined') { + opts = {}; } - /* istanbul ignore next */ - return false; -} -function listenerCount(ee, type) { - return 'listenerCount' in ee ? ee.listenerCount(type) : - events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.listenerCount(ee, type); + if (opts.doc_ids && !Array.isArray(opts.doc_ids)) { + throw createError(BAD_REQUEST, + "`doc_ids` filter parameter is not a list."); + } + + opts.complete = callback; + opts = clone(opts); + opts.continuous = opts.continuous || opts.live; + opts.retry = ('retry' in opts) ? opts.retry : false; + /*jshint validthis:true */ + opts.PouchConstructor = opts.PouchConstructor || this; + var replicateRet = new Replication(opts); + var srcPouch = toPouch(src, opts); + var targetPouch = toPouch(target, opts); + replicate(srcPouch, targetPouch, opts, replicateRet); + return replicateRet; } -function parseDesignDocFunctionName(s) { - if (!s) { - return null; - } - var parts = s.split('/'); - if (parts.length === 2) { - return parts; +inherits__WEBPACK_IMPORTED_MODULE_3___default()(Sync, events__WEBPACK_IMPORTED_MODULE_2__.EventEmitter); +function sync(src, target, opts, callback) { + if (typeof opts === 'function') { + callback = opts; + opts = {}; } - if (parts.length === 1) { - return [s, s]; + if (typeof opts === 'undefined') { + opts = {}; } - return null; + opts = clone(opts); + /*jshint validthis:true */ + opts.PouchConstructor = opts.PouchConstructor || this; + src = toPouch(src, opts); + target = toPouch(target, opts); + return new Sync(src, target, opts, callback); } -function normalizeDesignDocFunctionName(s) { - var normalized = parseDesignDocFunctionName(s); - return normalized ? normalized.join('/') : null; -} +function Sync(src, target, opts, callback) { + var self = this; + this.canceled = false; -// originally parseUri 1.2.2, now patched by us -// (c) Steven Levithan <stevenlevithan.com> -// MIT License -var keys = ["source", "protocol", "authority", "userInfo", "user", "password", - "host", "port", "relative", "path", "directory", "file", "query", "anchor"]; -var qName ="queryKey"; -var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g; + var optsPush = opts.push ? $inject_Object_assign({}, opts, opts.push) : opts; + var optsPull = opts.pull ? $inject_Object_assign({}, opts, opts.pull) : opts; -// use the "loose" parser -/* eslint maxlen: 0, no-useless-escape: 0 */ -var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; + this.push = replicateWrapper(src, target, optsPush); + this.pull = replicateWrapper(target, src, optsPull); -function parseUri(str) { - var m = parser.exec(str); - var uri = {}; - var i = 14; + this.pushPaused = true; + this.pullPaused = true; - while (i--) { - var key = keys[i]; - var value = m[i] || ""; - var encoded = ['user', 'password'].indexOf(key) !== -1; - uri[key] = encoded ? decodeURIComponent(value) : value; + function pullChange(change) { + self.emit('change', { + direction: 'pull', + change: change + }); } - - uri[qName] = {}; - uri[keys[12]].replace(qParser, function ($0, $1, $2) { - if ($1) { - uri[qName][$1] = $2; + function pushChange(change) { + self.emit('change', { + direction: 'push', + change: change + }); + } + function pushDenied(doc) { + self.emit('denied', { + direction: 'push', + doc: doc + }); + } + function pullDenied(doc) { + self.emit('denied', { + direction: 'pull', + doc: doc + }); + } + function pushPaused() { + self.pushPaused = true; + /* istanbul ignore if */ + if (self.pullPaused) { + self.emit('paused'); } - }); - - return uri; -} - -// Based on https://github.com/alexdavid/scope-eval v0.0.3 -// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js) -// This is basically just a wrapper around new Function() - -function scopeEval(source, scope) { - var keys = []; - var values = []; - for (var key in scope) { - if (scope.hasOwnProperty(key)) { - keys.push(key); - values.push(scope[key]); + } + function pullPaused() { + self.pullPaused = true; + /* istanbul ignore if */ + if (self.pushPaused) { + self.emit('paused'); + } + } + function pushActive() { + self.pushPaused = false; + /* istanbul ignore if */ + if (self.pullPaused) { + self.emit('active', { + direction: 'push' + }); + } + } + function pullActive() { + self.pullPaused = false; + /* istanbul ignore if */ + if (self.pushPaused) { + self.emit('active', { + direction: 'pull' + }); } } - keys.push(source); - return Function.apply(null, keys).apply(null, values); -} -// this is essentially the "update sugar" function from daleharvey/pouchdb#1388 -// the diffFun tells us what delta to apply to the doc. it either returns -// the doc, or false if it doesn't need to do an update after all -function upsert(db, docId, diffFun) { - return new Promise(function (fulfill, reject) { - db.get(docId, function (err, doc) { - if (err) { - /* istanbul ignore next */ - if (err.status !== 404) { - return reject(err); + var removed = {}; + + function removeAll(type) { // type is 'push' or 'pull' + return function (event, func) { + var isChange = event === 'change' && + (func === pullChange || func === pushChange); + var isDenied = event === 'denied' && + (func === pullDenied || func === pushDenied); + var isPaused = event === 'paused' && + (func === pullPaused || func === pushPaused); + var isActive = event === 'active' && + (func === pullActive || func === pushActive); + + if (isChange || isDenied || isPaused || isActive) { + if (!(event in removed)) { + removed[event] = {}; + } + removed[event][type] = true; + if (Object.keys(removed[event]).length === 2) { + // both push and pull have asked to be removed + self.removeAllListeners(event); } - doc = {}; } + }; + } - // the user might change the _rev, so save it for posterity - var docRev = doc._rev; - var newDoc = diffFun(doc); + if (opts.live) { + this.push.on('complete', self.pull.cancel.bind(self.pull)); + this.pull.on('complete', self.push.cancel.bind(self.push)); + } - if (!newDoc) { - // if the diffFun returns falsy, we short-circuit as - // an optimization - return fulfill({updated: false, rev: docRev}); - } + function addOneListener(ee, event, listener) { + if (ee.listeners(event).indexOf(listener) == -1) { + ee.on(event, listener); + } + } - // users aren't allowed to modify these values, - // so reset them here - newDoc._id = docId; - newDoc._rev = docRev; - fulfill(tryAndPut(db, newDoc, diffFun)); - }); + this.on('newListener', function (event) { + if (event === 'change') { + addOneListener(self.pull, 'change', pullChange); + addOneListener(self.push, 'change', pushChange); + } else if (event === 'denied') { + addOneListener(self.pull, 'denied', pullDenied); + addOneListener(self.push, 'denied', pushDenied); + } else if (event === 'active') { + addOneListener(self.pull, 'active', pullActive); + addOneListener(self.push, 'active', pushActive); + } else if (event === 'paused') { + addOneListener(self.pull, 'paused', pullPaused); + addOneListener(self.push, 'paused', pushPaused); + } + }); + + this.on('removeListener', function (event) { + if (event === 'change') { + self.pull.removeListener('change', pullChange); + self.push.removeListener('change', pushChange); + } else if (event === 'denied') { + self.pull.removeListener('denied', pullDenied); + self.push.removeListener('denied', pushDenied); + } else if (event === 'active') { + self.pull.removeListener('active', pullActive); + self.push.removeListener('active', pushActive); + } else if (event === 'paused') { + self.pull.removeListener('paused', pullPaused); + self.push.removeListener('paused', pushPaused); + } }); -} -function tryAndPut(db, doc, diffFun) { - return db.put(doc).then(function (res) { - return { - updated: true, - rev: res.rev + this.pull.on('removeListener', removeAll('pull')); + this.push.on('removeListener', removeAll('push')); + + var promise = Promise.all([ + this.push, + this.pull + ]).then(function (resp) { + var out = { + push: resp[0], + pull: resp[1] }; + self.emit('complete', out); + if (callback) { + callback(null, out); + } + self.removeAllListeners(); + return out; }, function (err) { - /* istanbul ignore next */ - if (err.status !== 409) { + self.cancel(); + if (callback) { + // if there's a callback, then the callback can receive + // the error event + callback(err); + } else { + // if there's no callback, then we're safe to emit an error + // event, which would otherwise throw an unhandled error + // due to 'error' being a special event in EventEmitters + self.emit('error', err); + } + self.removeAllListeners(); + if (callback) { + // no sense throwing if we're already emitting an 'error' event throw err; } - return upsert(db, doc._id, diffFun); }); + + this.then = function (success, err) { + return promise.then(success, err); + }; + + this.catch = function (err) { + return promise.catch(err); + }; } -function rev(doc, deterministic_revs) { - var clonedDoc = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_8__.clone)(doc); - if (!deterministic_revs) { - return uuid__WEBPACK_IMPORTED_MODULE_6___default().v4().replace(/-/g, '').toLowerCase(); +Sync.prototype.cancel = function () { + if (!this.canceled) { + this.canceled = true; + this.push.cancel(); + this.pull.cancel(); } +}; - delete clonedDoc._rev_tree; - return (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_7__.stringMd5)(JSON.stringify(clonedDoc)); +function replication(PouchDB) { + PouchDB.replicate = replicateWrapper; + PouchDB.sync = sync; + + Object.defineProperty(PouchDB.prototype, 'replicate', { + get: function () { + var self = this; + if (typeof this.replicateMethods === 'undefined') { + this.replicateMethods = { + from: function (other, opts, callback) { + return self.constructor.replicate(other, self, opts, callback); + }, + to: function (other, opts, callback) { + return self.constructor.replicate(self, other, opts, callback); + } + }; + } + return this.replicateMethods; + } + }); + + PouchDB.prototype.sync = function (dbName, opts, callback) { + return this.constructor.sync(this, dbName, opts, callback); + }; } -var uuid = (uuid__WEBPACK_IMPORTED_MODULE_6___default().v4); +PouchDB.plugin(IDBPouch) + .plugin(HttpPouch$1) + .plugin(mapreduce) + .plugin(replication); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PouchDB); + + +/***/ }), +/* 495 */ +/***/ ((module) => { + +"use strict"; +module.exports = argsArray; +function argsArray(fun) { + return function () { + var len = arguments.length; + if (len) { + var args = []; + var i = -1; + while (++i < len) { + args[i] = arguments[i]; + } + return fun.call(this, args); + } else { + return fun.call(this, []); + } + }; +} /***/ }), /* 496 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/***/ ((module) => { "use strict"; +var Mutation = global.MutationObserver || global.WebKitMutationObserver; -var Buffer = (__webpack_require__(78).Buffer); +var scheduleDrain; -function hasFrom() { - // Node versions 5.x below 5.10 seem to have a `from` method - // However, it doesn't clone Buffers - // Luckily, it reports as `false` to hasOwnProperty - return (Buffer.hasOwnProperty('from') && typeof Buffer.from === 'function'); -} +if (process.browser) { + if (Mutation) { + var called = 0; + var observer = new Mutation(nextTick); + var element = global.document.createTextNode(''); + observer.observe(element, { + characterData: true + }); + scheduleDrain = function () { + element.data = (called = ++called % 2); + }; + } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') { + var channel = new global.MessageChannel(); + channel.port1.onmessage = nextTick; + scheduleDrain = function () { + channel.port2.postMessage(0); + }; + } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) { + scheduleDrain = function () { -function cloneBuffer(buf) { - if (!Buffer.isBuffer(buf)) { - throw new Error('Can only clone Buffer.'); - } + // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted + // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. + var scriptEl = global.document.createElement('script'); + scriptEl.onreadystatechange = function () { + nextTick(); - if (hasFrom()) { - return Buffer.from(buf); + scriptEl.onreadystatechange = null; + scriptEl.parentNode.removeChild(scriptEl); + scriptEl = null; + }; + global.document.documentElement.appendChild(scriptEl); + }; + } else { + scheduleDrain = function () { + setTimeout(nextTick, 0); + }; } - - var copy = new Buffer(buf.length); - buf.copy(copy); - return copy; +} else { + scheduleDrain = function () { + process.nextTick(nextTick); + }; } -cloneBuffer.hasFrom = hasFrom; +var draining; +var queue = []; +//named nextTick for less confusing stack traces +function nextTick() { + draining = true; + var i, oldQueue; + var len = queue.length; + while (len) { + oldQueue = queue; + queue = []; + i = -1; + while (++i < len) { + oldQueue[i](); + } + len = queue.length; + } + draining = false; +} -module.exports = cloneBuffer; +module.exports = immediate; +function immediate(task) { + if (queue.push(task) === 1 && !draining) { + scheduleDrain(); + } +} /***/ }), /* 497 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Set": () => (/* binding */ ExportedSet), -/* harmony export */ "Map": () => (/* binding */ ExportedMap) -/* harmony export */ }); -function mangle(key) { - return '$' + key; -} -function unmangle(key) { - return key.substring(1); -} -function Map$1() { - this._store = {}; +try { + var util = __webpack_require__(64); + if (typeof util.inherits !== 'function') throw ''; + module.exports = util.inherits; +} catch (e) { + module.exports = __webpack_require__(498); } -Map$1.prototype.get = function (key) { - var mangled = mangle(key); - return this._store[mangled]; -}; -Map$1.prototype.set = function (key, value) { - var mangled = mangle(key); - this._store[mangled] = value; - return true; -}; -Map$1.prototype.has = function (key) { - var mangled = mangle(key); - return mangled in this._store; -}; -Map$1.prototype.delete = function (key) { - var mangled = mangle(key); - var res = mangled in this._store; - delete this._store[mangled]; - return res; -}; -Map$1.prototype.forEach = function (cb) { - var keys = Object.keys(this._store); - for (var i = 0, len = keys.length; i < len; i++) { - var key = keys[i]; - var value = this._store[key]; - key = unmangle(key); - cb(value, key); - } -}; -Object.defineProperty(Map$1.prototype, 'size', { - get: function () { - return Object.keys(this._store).length; - } -}); -function Set$1(array) { - this._store = new Map$1(); - // init with an array - if (array && Array.isArray(array)) { - for (var i = 0, len = array.length; i < len; i++) { - this.add(array[i]); - } - } -} -Set$1.prototype.add = function (key) { - return this._store.set(key, true); -}; -Set$1.prototype.has = function (key) { - return this._store.has(key); -}; -Set$1.prototype.forEach = function (cb) { - this._store.forEach(function (value, key) { - cb(key); - }); -}; -Object.defineProperty(Set$1.prototype, 'size', { - get: function () { - return this._store.size; - } -}); +/***/ }), +/* 498 */ +/***/ ((module) => { -/* global Map,Set,Symbol */ -// Based on https://kangax.github.io/compat-table/es6/ we can sniff out -// incomplete Map/Set implementations which would otherwise cause our tests to fail. -// Notably they fail in IE11 and iOS 8.4, which this prevents. -function supportsMapAndSet() { - if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') { - return false; +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor } - var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species); - return prop && 'get' in prop && Map[Symbol.species] === Map; } -// based on https://github.com/montagejs/collections -var ExportedSet; -var ExportedMap; +/***/ }), +/* 499 */ +/***/ ((module) => { -{ - if (supportsMapAndSet()) { // prefer built-in Map/Set - ExportedSet = Set; - ExportedMap = Map; - } else { // fall back to our polyfill - ExportedSet = Set$1; - ExportedMap = Map$1; - } -} +(function (factory) { + if (true) { + // Node/CommonJS + module.exports = factory(); + } else { var glob; } +}(function (undefined) { + 'use strict'; + /* + * Fastest md5 implementation around (JKM md5). + * Credits: Joseph Myers + * + * @see http://www.myersdaily.org/joseph/javascript/md5-text.html + * @see http://jsperf.com/md5-shootout/7 + */ + /* this function is much faster, + so if possible we use it. Some IEs + are the only ones I know of that + need the idiotic second function, + generated by an if clause. */ + var add32 = function (a, b) { + return (a + b) & 0xFFFFFFFF; + }, + hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; -/***/ }), -/* 498 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "UNAUTHORIZED": () => (/* binding */ UNAUTHORIZED), -/* harmony export */ "MISSING_BULK_DOCS": () => (/* binding */ MISSING_BULK_DOCS), -/* harmony export */ "MISSING_DOC": () => (/* binding */ MISSING_DOC), -/* harmony export */ "REV_CONFLICT": () => (/* binding */ REV_CONFLICT), -/* harmony export */ "INVALID_ID": () => (/* binding */ INVALID_ID), -/* harmony export */ "MISSING_ID": () => (/* binding */ MISSING_ID), -/* harmony export */ "RESERVED_ID": () => (/* binding */ RESERVED_ID), -/* harmony export */ "NOT_OPEN": () => (/* binding */ NOT_OPEN), -/* harmony export */ "UNKNOWN_ERROR": () => (/* binding */ UNKNOWN_ERROR), -/* harmony export */ "BAD_ARG": () => (/* binding */ BAD_ARG), -/* harmony export */ "INVALID_REQUEST": () => (/* binding */ INVALID_REQUEST), -/* harmony export */ "QUERY_PARSE_ERROR": () => (/* binding */ QUERY_PARSE_ERROR), -/* harmony export */ "DOC_VALIDATION": () => (/* binding */ DOC_VALIDATION), -/* harmony export */ "BAD_REQUEST": () => (/* binding */ BAD_REQUEST), -/* harmony export */ "NOT_AN_OBJECT": () => (/* binding */ NOT_AN_OBJECT), -/* harmony export */ "DB_MISSING": () => (/* binding */ DB_MISSING), -/* harmony export */ "WSQ_ERROR": () => (/* binding */ WSQ_ERROR), -/* harmony export */ "LDB_ERROR": () => (/* binding */ LDB_ERROR), -/* harmony export */ "FORBIDDEN": () => (/* binding */ FORBIDDEN), -/* harmony export */ "INVALID_REV": () => (/* binding */ INVALID_REV), -/* harmony export */ "FILE_EXISTS": () => (/* binding */ FILE_EXISTS), -/* harmony export */ "MISSING_STUB": () => (/* binding */ MISSING_STUB), -/* harmony export */ "IDB_ERROR": () => (/* binding */ IDB_ERROR), -/* harmony export */ "INVALID_URL": () => (/* binding */ INVALID_URL), -/* harmony export */ "createError": () => (/* binding */ createError), -/* harmony export */ "generateErrorFromResponse": () => (/* binding */ generateErrorFromResponse) -/* harmony export */ }); -/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(485); -/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_0__); + function cmn(q, a, b, x, s, t) { + a = add32(add32(a, q), add32(x, t)); + return add32((a << s) | (a >>> (32 - s)), b); + } + function md5cycle(x, k) { + var a = x[0], + b = x[1], + c = x[2], + d = x[3]; -inherits__WEBPACK_IMPORTED_MODULE_0___default()(PouchError, Error); + a += (b & c | ~b & d) + k[0] - 680876936 | 0; + a = (a << 7 | a >>> 25) + b | 0; + d += (a & b | ~a & c) + k[1] - 389564586 | 0; + d = (d << 12 | d >>> 20) + a | 0; + c += (d & a | ~d & b) + k[2] + 606105819 | 0; + c = (c << 17 | c >>> 15) + d | 0; + b += (c & d | ~c & a) + k[3] - 1044525330 | 0; + b = (b << 22 | b >>> 10) + c | 0; + a += (b & c | ~b & d) + k[4] - 176418897 | 0; + a = (a << 7 | a >>> 25) + b | 0; + d += (a & b | ~a & c) + k[5] + 1200080426 | 0; + d = (d << 12 | d >>> 20) + a | 0; + c += (d & a | ~d & b) + k[6] - 1473231341 | 0; + c = (c << 17 | c >>> 15) + d | 0; + b += (c & d | ~c & a) + k[7] - 45705983 | 0; + b = (b << 22 | b >>> 10) + c | 0; + a += (b & c | ~b & d) + k[8] + 1770035416 | 0; + a = (a << 7 | a >>> 25) + b | 0; + d += (a & b | ~a & c) + k[9] - 1958414417 | 0; + d = (d << 12 | d >>> 20) + a | 0; + c += (d & a | ~d & b) + k[10] - 42063 | 0; + c = (c << 17 | c >>> 15) + d | 0; + b += (c & d | ~c & a) + k[11] - 1990404162 | 0; + b = (b << 22 | b >>> 10) + c | 0; + a += (b & c | ~b & d) + k[12] + 1804603682 | 0; + a = (a << 7 | a >>> 25) + b | 0; + d += (a & b | ~a & c) + k[13] - 40341101 | 0; + d = (d << 12 | d >>> 20) + a | 0; + c += (d & a | ~d & b) + k[14] - 1502002290 | 0; + c = (c << 17 | c >>> 15) + d | 0; + b += (c & d | ~c & a) + k[15] + 1236535329 | 0; + b = (b << 22 | b >>> 10) + c | 0; -function PouchError(status, error, reason) { - Error.call(this, reason); - this.status = status; - this.name = error; - this.message = reason; - this.error = true; -} + a += (b & d | c & ~d) + k[1] - 165796510 | 0; + a = (a << 5 | a >>> 27) + b | 0; + d += (a & c | b & ~c) + k[6] - 1069501632 | 0; + d = (d << 9 | d >>> 23) + a | 0; + c += (d & b | a & ~b) + k[11] + 643717713 | 0; + c = (c << 14 | c >>> 18) + d | 0; + b += (c & a | d & ~a) + k[0] - 373897302 | 0; + b = (b << 20 | b >>> 12) + c | 0; + a += (b & d | c & ~d) + k[5] - 701558691 | 0; + a = (a << 5 | a >>> 27) + b | 0; + d += (a & c | b & ~c) + k[10] + 38016083 | 0; + d = (d << 9 | d >>> 23) + a | 0; + c += (d & b | a & ~b) + k[15] - 660478335 | 0; + c = (c << 14 | c >>> 18) + d | 0; + b += (c & a | d & ~a) + k[4] - 405537848 | 0; + b = (b << 20 | b >>> 12) + c | 0; + a += (b & d | c & ~d) + k[9] + 568446438 | 0; + a = (a << 5 | a >>> 27) + b | 0; + d += (a & c | b & ~c) + k[14] - 1019803690 | 0; + d = (d << 9 | d >>> 23) + a | 0; + c += (d & b | a & ~b) + k[3] - 187363961 | 0; + c = (c << 14 | c >>> 18) + d | 0; + b += (c & a | d & ~a) + k[8] + 1163531501 | 0; + b = (b << 20 | b >>> 12) + c | 0; + a += (b & d | c & ~d) + k[13] - 1444681467 | 0; + a = (a << 5 | a >>> 27) + b | 0; + d += (a & c | b & ~c) + k[2] - 51403784 | 0; + d = (d << 9 | d >>> 23) + a | 0; + c += (d & b | a & ~b) + k[7] + 1735328473 | 0; + c = (c << 14 | c >>> 18) + d | 0; + b += (c & a | d & ~a) + k[12] - 1926607734 | 0; + b = (b << 20 | b >>> 12) + c | 0; -PouchError.prototype.toString = function () { - return JSON.stringify({ - status: this.status, - name: this.name, - message: this.message, - reason: this.reason - }); -}; + a += (b ^ c ^ d) + k[5] - 378558 | 0; + a = (a << 4 | a >>> 28) + b | 0; + d += (a ^ b ^ c) + k[8] - 2022574463 | 0; + d = (d << 11 | d >>> 21) + a | 0; + c += (d ^ a ^ b) + k[11] + 1839030562 | 0; + c = (c << 16 | c >>> 16) + d | 0; + b += (c ^ d ^ a) + k[14] - 35309556 | 0; + b = (b << 23 | b >>> 9) + c | 0; + a += (b ^ c ^ d) + k[1] - 1530992060 | 0; + a = (a << 4 | a >>> 28) + b | 0; + d += (a ^ b ^ c) + k[4] + 1272893353 | 0; + d = (d << 11 | d >>> 21) + a | 0; + c += (d ^ a ^ b) + k[7] - 155497632 | 0; + c = (c << 16 | c >>> 16) + d | 0; + b += (c ^ d ^ a) + k[10] - 1094730640 | 0; + b = (b << 23 | b >>> 9) + c | 0; + a += (b ^ c ^ d) + k[13] + 681279174 | 0; + a = (a << 4 | a >>> 28) + b | 0; + d += (a ^ b ^ c) + k[0] - 358537222 | 0; + d = (d << 11 | d >>> 21) + a | 0; + c += (d ^ a ^ b) + k[3] - 722521979 | 0; + c = (c << 16 | c >>> 16) + d | 0; + b += (c ^ d ^ a) + k[6] + 76029189 | 0; + b = (b << 23 | b >>> 9) + c | 0; + a += (b ^ c ^ d) + k[9] - 640364487 | 0; + a = (a << 4 | a >>> 28) + b | 0; + d += (a ^ b ^ c) + k[12] - 421815835 | 0; + d = (d << 11 | d >>> 21) + a | 0; + c += (d ^ a ^ b) + k[15] + 530742520 | 0; + c = (c << 16 | c >>> 16) + d | 0; + b += (c ^ d ^ a) + k[2] - 995338651 | 0; + b = (b << 23 | b >>> 9) + c | 0; -var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect."); -var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'"); -var MISSING_DOC = new PouchError(404, 'not_found', 'missing'); -var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict'); -var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string'); -var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts'); -var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.'); -var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open'); -var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error'); -var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid'); -var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid'); -var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid'); -var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member'); -var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request'); -var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object'); -var DB_MISSING = new PouchError(404, 'not_found', 'Database not found'); -var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown'); -var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown'); -var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown'); -var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function'); -var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format'); -var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.'); -var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found'); -var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid'); + a += (c ^ (b | ~d)) + k[0] - 198630844 | 0; + a = (a << 6 | a >>> 26) + b | 0; + d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0; + d = (d << 10 | d >>> 22) + a | 0; + c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0; + c = (c << 15 | c >>> 17) + d | 0; + b += (d ^ (c | ~a)) + k[5] - 57434055 | 0; + b = (b << 21 |b >>> 11) + c | 0; + a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0; + a = (a << 6 | a >>> 26) + b | 0; + d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0; + d = (d << 10 | d >>> 22) + a | 0; + c += (a ^ (d | ~b)) + k[10] - 1051523 | 0; + c = (c << 15 | c >>> 17) + d | 0; + b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0; + b = (b << 21 |b >>> 11) + c | 0; + a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0; + a = (a << 6 | a >>> 26) + b | 0; + d += (b ^ (a | ~c)) + k[15] - 30611744 | 0; + d = (d << 10 | d >>> 22) + a | 0; + c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0; + c = (c << 15 | c >>> 17) + d | 0; + b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0; + b = (b << 21 |b >>> 11) + c | 0; + a += (c ^ (b | ~d)) + k[4] - 145523070 | 0; + a = (a << 6 | a >>> 26) + b | 0; + d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0; + d = (d << 10 | d >>> 22) + a | 0; + c += (a ^ (d | ~b)) + k[2] + 718787259 | 0; + c = (c << 15 | c >>> 17) + d | 0; + b += (d ^ (c | ~a)) + k[9] - 343485551 | 0; + b = (b << 21 | b >>> 11) + c | 0; -function createError(error, reason) { - function CustomPouchError(reason) { - // inherit error properties from our parent error manually - // so as to allow proper JSON parsing. - /* jshint ignore:start */ - for (var p in error) { - if (typeof error[p] !== 'function') { - this[p] = error[p]; - } - } - /* jshint ignore:end */ - if (reason !== undefined) { - this.reason = reason; + x[0] = a + x[0] | 0; + x[1] = b + x[1] | 0; + x[2] = c + x[2] | 0; + x[3] = d + x[3] | 0; } - } - CustomPouchError.prototype = PouchError.prototype; - return new CustomPouchError(reason); -} -function generateErrorFromResponse(err) { + function md5blk(s) { + var md5blks = [], + i; /* Andy King said do it this way. */ - if (typeof err !== 'object') { - var data = err; - err = UNKNOWN_ERROR; - err.data = data; - } + for (i = 0; i < 64; i += 4) { + md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24); + } + return md5blks; + } - if ('error' in err && err.error === 'conflict') { - err.name = 'conflict'; - err.status = 409; - } + function md5blk_array(a) { + var md5blks = [], + i; /* Andy King said do it this way. */ - if (!('name' in err)) { - err.name = err.error || 'unknown'; - } + for (i = 0; i < 64; i += 4) { + md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24); + } + return md5blks; + } - if (!('status' in err)) { - err.status = 500; - } + function md51(s) { + var n = s.length, + state = [1732584193, -271733879, -1732584194, 271733878], + i, + length, + tail, + tmp, + lo, + hi; - if (!('message' in err)) { - err.message = err.message || err.reason; - } + for (i = 64; i <= n; i += 64) { + md5cycle(state, md5blk(s.substring(i - 64, i))); + } + s = s.substring(i - 64); + length = s.length; + tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (i = 0; i < length; i += 1) { + tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3); + } + tail[i >> 2] |= 0x80 << ((i % 4) << 3); + if (i > 55) { + md5cycle(state, tail); + for (i = 0; i < 16; i += 1) { + tail[i] = 0; + } + } - return err; -} + // Beware that the final length might not fit in 32 bits so we take care of that + tmp = n * 8; + tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); + lo = parseInt(tmp[2], 16); + hi = parseInt(tmp[1], 16) || 0; + tail[14] = lo; + tail[15] = hi; + md5cycle(state, tail); + return state; + } + function md51_array(a) { + var n = a.length, + state = [1732584193, -271733879, -1732584194, 271733878], + i, + length, + tail, + tmp, + lo, + hi; -/***/ }), -/* 499 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + for (i = 64; i <= n; i += 64) { + md5cycle(state, md5blk_array(a.subarray(i - 64, i))); + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "binaryMd5": () => (/* binding */ binaryMd5), -/* harmony export */ "stringMd5": () => (/* binding */ stringMd5) -/* harmony export */ }); -/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(76); -/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_0__); + // Not sure if it is a bug, however IE10 will always produce a sub array of length 1 + // containing the last element of the parent array if the sub array specified starts + // beyond the length of the parent array - weird. + // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue + a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0); + length = a.length; + tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (i = 0; i < length; i += 1) { + tail[i >> 2] |= a[i] << ((i % 4) << 3); + } -function binaryMd5(data, callback) { - var base64 = crypto__WEBPACK_IMPORTED_MODULE_0___default().createHash('md5').update(data, 'binary').digest('base64'); - callback(base64); -} + tail[i >> 2] |= 0x80 << ((i % 4) << 3); + if (i > 55) { + md5cycle(state, tail); + for (i = 0; i < 16; i += 1) { + tail[i] = 0; + } + } -function stringMd5(string) { - return crypto__WEBPACK_IMPORTED_MODULE_0___default().createHash('md5').update(string, 'binary').digest('hex'); -} + // Beware that the final length might not fit in 32 bits so we take care of that + tmp = n * 8; + tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); + lo = parseInt(tmp[2], 16); + hi = parseInt(tmp[1], 16) || 0; + tail[14] = lo; + tail[15] = hi; + md5cycle(state, tail); + return state; + } -/***/ }), -/* 500 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + function rhex(n) { + var s = '', + j; + for (j = 0; j < 4; j += 1) { + s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; + } + return s; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "fetch": () => (/* binding */ fetch), -/* harmony export */ "Headers": () => (/* binding */ Headers), -/* harmony export */ "AbortController": () => (/* binding */ AbortController) -/* harmony export */ }); -/* harmony import */ var node_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(481); -/* harmony import */ var fetch_cookie__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(501); -/* harmony import */ var fetch_cookie__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fetch_cookie__WEBPACK_IMPORTED_MODULE_1__); + function hex(x) { + var i; + for (i = 0; i < x.length; i += 1) { + x[i] = rhex(x[i]); + } + return x.join(''); + } + // In some cases the fast add32 function cannot be used.. + if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') { + add32 = function (x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF), + msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + }; + } + // --------------------------------------------------- -var fetch = fetch_cookie__WEBPACK_IMPORTED_MODULE_1___default()(node_fetch__WEBPACK_IMPORTED_MODULE_0__["default"]); + /** + * ArrayBuffer slice polyfill. + * + * @see https://github.com/ttaubert/node-arraybuffer-slice + */ -/* We can fake the abort, the http adapter keeps track - of ignoring the result */ -function AbortController() { - return {abort: function () {}}; -} + if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) { + (function () { + function clamp(val, length) { + val = (val | 0) || 0; -var Headers = node_fetch__WEBPACK_IMPORTED_MODULE_0__["default"].Headers; + if (val < 0) { + return Math.max(val + length, 0); + } + return Math.min(val, length); + } + ArrayBuffer.prototype.slice = function (from, to) { + var length = this.byteLength, + begin = clamp(from, length), + end = length, + num, + target, + targetArray, + sourceArray; + if (to !== undefined) { + end = clamp(to, length); + } -/***/ }), -/* 501 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (begin > end) { + return new ArrayBuffer(0); + } -var denodeify = __webpack_require__(502)(Promise) -var tough = __webpack_require__(61) + num = end - begin; + target = new ArrayBuffer(num); + targetArray = new Uint8Array(target); -module.exports = function fetchCookieDecorator (fetch, jar) { - fetch = fetch || window.fetch - jar = jar || new tough.CookieJar() + sourceArray = new Uint8Array(this, begin, num); + targetArray.set(sourceArray); - var getCookieString = denodeify(jar.getCookieString.bind(jar)) - var setCookie = denodeify(jar.setCookie.bind(jar)) + return target; + }; + })(); + } - return function fetchCookie (url, opts) { - opts = opts || {} + // --------------------------------------------------- - return getCookieString(url) - .then(function (cookie) { - return fetch(url, Object.assign(opts, { - headers: Object.assign(opts.headers || {}, (cookie ? { cookie: cookie } : {})) - })) - }) - .then(function (res) { - var cookies + /** + * Helpers. + */ - if (res.headers.getAll) { - // node-fetch v1 - cookies = res.headers.getAll('set-cookie') - } else { - // node-fetch v2 - var cookie = res.headers.get('set-cookie') - cookies = cookie && cookie.split(',') || [] + function toUtf8(str) { + if (/[\u0080-\uFFFF]/.test(str)) { + str = unescape(encodeURIComponent(str)); } - if (!cookies.length) { - return res - } + return str; + } - return Promise.all(cookies.map(function (cookie) { - return setCookie(cookie, res.url) - })).then(function () { - return res - }) - }) - } -} + function utf8Str2ArrayBuffer(str, returnUInt8Array) { + var length = str.length, + buff = new ArrayBuffer(length), + arr = new Uint8Array(buff), + i; + for (i = 0; i < length; i += 1) { + arr[i] = str.charCodeAt(i); + } -/***/ }), -/* 502 */ -/***/ ((module, exports) => { + return returnUInt8Array ? arr : buff; + } -"use strict"; + function arrayBuffer2Utf8Str(buff) { + return String.fromCharCode.apply(null, new Uint8Array(buff)); + } + function concatenateArrayBuffers(first, second, returnUInt8Array) { + var result = new Uint8Array(first.byteLength + second.byteLength); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); + result.set(new Uint8Array(first)); + result.set(new Uint8Array(second), first.byteLength); -exports["default"] = function () { - var PromiseArg = arguments[0] === undefined ? Promise : arguments[0]; - return function (f) { - return function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } + return returnUInt8Array ? result : result.buffer; + } - return new PromiseArg(function (resolve, reject) { - return f.apply(undefined, args.concat([function (err, val) { - return err ? reject(err) : resolve(val); - }])); - }); - }; - }; -}; + function hexToBinaryString(hex) { + var bytes = [], + length = hex.length, + x; -module.exports = exports["default"]; + for (x = 0; x < length - 1; x += 2) { + bytes.push(parseInt(hex.substr(x, 2), 16)); + } + return String.fromCharCode.apply(String, bytes); + } + // --------------------------------------------------- -/***/ }), -/* 503 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + /** + * SparkMD5 OOP implementation. + * + * Use this class to perform an incremental md5, otherwise use the + * static methods instead. + */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "massageSelector": () => (/* binding */ massageSelector), -/* harmony export */ "matchesSelector": () => (/* binding */ matchesSelector), -/* harmony export */ "filterInMemoryFields": () => (/* binding */ filterInMemoryFields), -/* harmony export */ "createFieldSorter": () => (/* binding */ createFieldSorter), -/* harmony export */ "rowFilter": () => (/* binding */ rowFilter), -/* harmony export */ "isCombinationalField": () => (/* binding */ isCombinationalField), -/* harmony export */ "getKey": () => (/* binding */ getKey), -/* harmony export */ "getValue": () => (/* binding */ getValue), -/* harmony export */ "getFieldFromDoc": () => (/* binding */ getFieldFromDoc), -/* harmony export */ "setFieldInDoc": () => (/* binding */ setFieldInDoc), -/* harmony export */ "compare": () => (/* binding */ compare), -/* harmony export */ "parseField": () => (/* binding */ parseField) -/* harmony export */ }); -/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(495); -/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(504); + function SparkMD5() { + // call reset to init the instance + this.reset(); + } + /** + * Appends a string. + * A conversion will be applied if an utf8 string is detected. + * + * @param {String} str The string to be appended + * + * @return {SparkMD5} The instance itself + */ + SparkMD5.prototype.append = function (str) { + // Converts the string to utf8 bytes if necessary + // Then append as binary + this.appendBinary(toUtf8(str)); + return this; + }; -// this would just be "return doc[field]", but fields -// can be "deep" due to dot notation -function getFieldFromDoc(doc, parsedField) { - var value = doc; - for (var i = 0, len = parsedField.length; i < len; i++) { - var key = parsedField[i]; - value = value[key]; - if (!value) { - break; - } - } - return value; -} + /** + * Appends a binary string. + * + * @param {String} contents The binary string to be appended + * + * @return {SparkMD5} The instance itself + */ + SparkMD5.prototype.appendBinary = function (contents) { + this._buff += contents; + this._length += contents.length; -function setFieldInDoc(doc, parsedField, value) { - for (var i = 0, len = parsedField.length; i < len-1; i++) { - var elem = parsedField[i]; - doc = doc[elem] = {}; - } - doc[parsedField[len-1]] = value; -} + var length = this._buff.length, + i; -function compare(left, right) { - return left < right ? -1 : left > right ? 1 : 0; -} + for (i = 64; i <= length; i += 64) { + md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i))); + } -// Converts a string in dot notation to an array of its components, with backslash escaping -function parseField(fieldName) { - // fields may be deep (e.g. "foo.bar.baz"), so parse - var fields = []; - var current = ''; - for (var i = 0, len = fieldName.length; i < len; i++) { - var ch = fieldName[i]; - if (ch === '.') { - if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter - current = current.substring(0, current.length - 1) + '.'; - } else { // not escaped, so delimiter - fields.push(current); - current = ''; - } - } else { // normal character - current += ch; - } - } - fields.push(current); - return fields; -} + this._buff = this._buff.substring(i - 64); -var combinationFields = ['$or', '$nor', '$not']; -function isCombinationalField(field) { - return combinationFields.indexOf(field) > -1; -} + return this; + }; -function getKey(obj) { - return Object.keys(obj)[0]; -} + /** + * Finishes the incremental computation, reseting the internal state and + * returning the result. + * + * @param {Boolean} raw True to get the raw string, false to get the hex string + * + * @return {String} The result + */ + SparkMD5.prototype.end = function (raw) { + var buff = this._buff, + length = buff.length, + i, + tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ret; -function getValue(obj) { - return obj[getKey(obj)]; -} + for (i = 0; i < length; i += 1) { + tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3); + } + this._finish(tail, length); + ret = hex(this._hash); -// flatten an array of selectors joined by an $and operator -function mergeAndedSelectors(selectors) { + if (raw) { + ret = hexToBinaryString(ret); + } - // sort to ensure that e.g. if the user specified - // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into - // just {$gt: 'b'} - var res = {}; + this.reset(); - selectors.forEach(function (selector) { - Object.keys(selector).forEach(function (field) { - var matcher = selector[field]; - if (typeof matcher !== 'object') { - matcher = {$eq: matcher}; - } + return ret; + }; - if (isCombinationalField(field)) { - if (matcher instanceof Array) { - res[field] = matcher.map(function (m) { - return mergeAndedSelectors([m]); - }); - } else { - res[field] = mergeAndedSelectors([matcher]); - } - } else { - var fieldMatchers = res[field] = res[field] || {}; - Object.keys(matcher).forEach(function (operator) { - var value = matcher[operator]; + /** + * Resets the internal state of the computation. + * + * @return {SparkMD5} The instance itself + */ + SparkMD5.prototype.reset = function () { + this._buff = ''; + this._length = 0; + this._hash = [1732584193, -271733879, -1732584194, 271733878]; - if (operator === '$gt' || operator === '$gte') { - return mergeGtGte(operator, value, fieldMatchers); - } else if (operator === '$lt' || operator === '$lte') { - return mergeLtLte(operator, value, fieldMatchers); - } else if (operator === '$ne') { - return mergeNe(value, fieldMatchers); - } else if (operator === '$eq') { - return mergeEq(value, fieldMatchers); - } - fieldMatchers[operator] = value; - }); - } - }); - }); + return this; + }; - return res; -} + /** + * Gets the internal state of the computation. + * + * @return {Object} The state + */ + SparkMD5.prototype.getState = function () { + return { + buff: this._buff, + length: this._length, + hash: this._hash + }; + }; + /** + * Gets the internal state of the computation. + * + * @param {Object} state The state + * + * @return {SparkMD5} The instance itself + */ + SparkMD5.prototype.setState = function (state) { + this._buff = state.buff; + this._length = state.length; + this._hash = state.hash; + return this; + }; -// collapse logically equivalent gt/gte values -function mergeGtGte(operator, value, fieldMatchers) { - if (typeof fieldMatchers.$eq !== 'undefined') { - return; // do nothing - } - if (typeof fieldMatchers.$gte !== 'undefined') { - if (operator === '$gte') { - if (value > fieldMatchers.$gte) { // more specificity - fieldMatchers.$gte = value; - } - } else { // operator === '$gt' - if (value >= fieldMatchers.$gte) { // more specificity - delete fieldMatchers.$gte; - fieldMatchers.$gt = value; - } - } - } else if (typeof fieldMatchers.$gt !== 'undefined') { - if (operator === '$gte') { - if (value > fieldMatchers.$gt) { // more specificity - delete fieldMatchers.$gt; - fieldMatchers.$gte = value; - } - } else { // operator === '$gt' - if (value > fieldMatchers.$gt) { // more specificity - fieldMatchers.$gt = value; - } - } - } else { - fieldMatchers[operator] = value; - } -} + /** + * Releases memory used by the incremental buffer and other additional + * resources. If you plan to use the instance again, use reset instead. + */ + SparkMD5.prototype.destroy = function () { + delete this._hash; + delete this._buff; + delete this._length; + }; -// collapse logically equivalent lt/lte values -function mergeLtLte(operator, value, fieldMatchers) { - if (typeof fieldMatchers.$eq !== 'undefined') { - return; // do nothing - } - if (typeof fieldMatchers.$lte !== 'undefined') { - if (operator === '$lte') { - if (value < fieldMatchers.$lte) { // more specificity - fieldMatchers.$lte = value; - } - } else { // operator === '$gt' - if (value <= fieldMatchers.$lte) { // more specificity - delete fieldMatchers.$lte; - fieldMatchers.$lt = value; - } - } - } else if (typeof fieldMatchers.$lt !== 'undefined') { - if (operator === '$lte') { - if (value < fieldMatchers.$lt) { // more specificity - delete fieldMatchers.$lt; - fieldMatchers.$lte = value; - } - } else { // operator === '$gt' - if (value < fieldMatchers.$lt) { // more specificity - fieldMatchers.$lt = value; - } - } - } else { - fieldMatchers[operator] = value; - } -} + /** + * Finish the final calculation based on the tail. + * + * @param {Array} tail The tail (will be modified) + * @param {Number} length The length of the remaining buffer + */ + SparkMD5.prototype._finish = function (tail, length) { + var i = length, + tmp, + lo, + hi; -// combine $ne values into one array -function mergeNe(value, fieldMatchers) { - if ('$ne' in fieldMatchers) { - // there are many things this could "not" be - fieldMatchers.$ne.push(value); - } else { // doesn't exist yet - fieldMatchers.$ne = [value]; - } -} + tail[i >> 2] |= 0x80 << ((i % 4) << 3); + if (i > 55) { + md5cycle(this._hash, tail); + for (i = 0; i < 16; i += 1) { + tail[i] = 0; + } + } -// add $eq into the mix -function mergeEq(value, fieldMatchers) { - // these all have less specificity than the $eq - // TODO: check for user errors here - delete fieldMatchers.$gt; - delete fieldMatchers.$gte; - delete fieldMatchers.$lt; - delete fieldMatchers.$lte; - delete fieldMatchers.$ne; - fieldMatchers.$eq = value; -} + // Do the final computation based on the tail and length + // Beware that the final length may not fit in 32 bits so we take care of that + tmp = this._length * 8; + tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); + lo = parseInt(tmp[2], 16); + hi = parseInt(tmp[1], 16) || 0; + tail[14] = lo; + tail[15] = hi; + md5cycle(this._hash, tail); + }; -// -// normalize the selector -// -function massageSelector(input) { - var result = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(input); - var wasAnded = false; - if ('$and' in result) { - result = mergeAndedSelectors(result['$and']); - wasAnded = true; - } + /** + * Performs the md5 hash on a string. + * A conversion will be applied if utf8 string is detected. + * + * @param {String} str The string + * @param {Boolean} raw True to get the raw string, false to get the hex string + * + * @return {String} The result + */ + SparkMD5.hash = function (str, raw) { + // Converts the string to utf8 bytes if necessary + // Then compute it using the binary function + return SparkMD5.hashBinary(toUtf8(str), raw); + }; - ['$or', '$nor'].forEach(function (orOrNor) { - if (orOrNor in result) { - // message each individual selector - // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}} - result[orOrNor].forEach(function (subSelector) { - var fields = Object.keys(subSelector); - for (var i = 0; i < fields.length; i++) { - var field = fields[i]; - var matcher = subSelector[field]; - if (typeof matcher !== 'object' || matcher === null) { - subSelector[field] = {$eq: matcher}; - } - } - }); - } - }); + /** + * Performs the md5 hash on a binary string. + * + * @param {String} content The binary string + * @param {Boolean} raw True to get the raw string, false to get the hex string + * + * @return {String} The result + */ + SparkMD5.hashBinary = function (content, raw) { + var hash = md51(content), + ret = hex(hash); - if ('$not' in result) { - //This feels a little like forcing, but it will work for now, - //I would like to come back to this and make the merging of selectors a little more generic - result['$not'] = mergeAndedSelectors([result['$not']]); - } + return raw ? hexToBinaryString(ret) : ret; + }; - var fields = Object.keys(result); + // --------------------------------------------------- - for (var i = 0; i < fields.length; i++) { - var field = fields[i]; - var matcher = result[field]; + /** + * SparkMD5 OOP implementation for array buffers. + * + * Use this class to perform an incremental md5 ONLY for array buffers. + */ + SparkMD5.ArrayBuffer = function () { + // call reset to init the instance + this.reset(); + }; - if (typeof matcher !== 'object' || matcher === null) { - matcher = {$eq: matcher}; - } else if ('$ne' in matcher && !wasAnded) { - // I put these in an array, since there may be more than one - // but in the "mergeAnded" operation, I already take care of that - matcher.$ne = [matcher.$ne]; - } - result[field] = matcher; - } + /** + * Appends an array buffer. + * + * @param {ArrayBuffer} arr The array to be appended + * + * @return {SparkMD5.ArrayBuffer} The instance itself + */ + SparkMD5.ArrayBuffer.prototype.append = function (arr) { + var buff = concatenateArrayBuffers(this._buff.buffer, arr, true), + length = buff.length, + i; - return result; -} + this._length += arr.byteLength; -// create a comparator based on the sort object -function createFieldSorter(sort) { + for (i = 64; i <= length; i += 64) { + md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i))); + } - function getFieldValuesAsArray(doc) { - return sort.map(function (sorting) { - var fieldName = getKey(sorting); - var parsedField = parseField(fieldName); - var docFieldValue = getFieldFromDoc(doc, parsedField); - return docFieldValue; - }); - } + this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0); - return function (aRow, bRow) { - var aFieldValues = getFieldValuesAsArray(aRow.doc); - var bFieldValues = getFieldValuesAsArray(bRow.doc); - var collation = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(aFieldValues, bFieldValues); - if (collation !== 0) { - return collation; - } - // this is what mango seems to do - return compare(aRow.doc._id, bRow.doc._id); - }; -} + return this; + }; -function filterInMemoryFields(rows, requestDef, inMemoryFields) { - rows = rows.filter(function (row) { - return rowFilter(row.doc, requestDef.selector, inMemoryFields); - }); + /** + * Finishes the incremental computation, reseting the internal state and + * returning the result. + * + * @param {Boolean} raw True to get the raw string, false to get the hex string + * + * @return {String} The result + */ + SparkMD5.ArrayBuffer.prototype.end = function (raw) { + var buff = this._buff, + length = buff.length, + tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + i, + ret; - if (requestDef.sort) { - // in-memory sort - var fieldSorter = createFieldSorter(requestDef.sort); - rows = rows.sort(fieldSorter); - if (typeof requestDef.sort[0] !== 'string' && - getValue(requestDef.sort[0]) === 'desc') { - rows = rows.reverse(); - } - } + for (i = 0; i < length; i += 1) { + tail[i >> 2] |= buff[i] << ((i % 4) << 3); + } - if ('limit' in requestDef || 'skip' in requestDef) { - // have to do the limit in-memory - var skip = requestDef.skip || 0; - var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip; - rows = rows.slice(skip, limit); - } - return rows; -} + this._finish(tail, length); + ret = hex(this._hash); -function rowFilter(doc, selector, inMemoryFields) { - return inMemoryFields.every(function (field) { - var matcher = selector[field]; - var parsedField = parseField(field); - var docFieldValue = getFieldFromDoc(doc, parsedField); - if (isCombinationalField(field)) { - return matchCominationalSelector(field, matcher, doc); - } + if (raw) { + ret = hexToBinaryString(ret); + } - return matchSelector(matcher, doc, parsedField, docFieldValue); - }); -} + this.reset(); -function matchSelector(matcher, doc, parsedField, docFieldValue) { - if (!matcher) { - // no filtering necessary; this field is just needed for sorting - return true; - } + return ret; + }; - return Object.keys(matcher).every(function (userOperator) { - var userValue = matcher[userOperator]; - return match(userOperator, doc, userValue, parsedField, docFieldValue); - }); -} + /** + * Resets the internal state of the computation. + * + * @return {SparkMD5.ArrayBuffer} The instance itself + */ + SparkMD5.ArrayBuffer.prototype.reset = function () { + this._buff = new Uint8Array(0); + this._length = 0; + this._hash = [1732584193, -271733879, -1732584194, 271733878]; -function matchCominationalSelector(field, matcher, doc) { + return this; + }; - if (field === '$or') { - return matcher.some(function (orMatchers) { - return rowFilter(doc, orMatchers, Object.keys(orMatchers)); - }); - } + /** + * Gets the internal state of the computation. + * + * @return {Object} The state + */ + SparkMD5.ArrayBuffer.prototype.getState = function () { + var state = SparkMD5.prototype.getState.call(this); - if (field === '$not') { - return !rowFilter(doc, matcher, Object.keys(matcher)); - } + // Convert buffer to a string + state.buff = arrayBuffer2Utf8Str(state.buff); - //`$nor` - return !matcher.find(function (orMatchers) { - return rowFilter(doc, orMatchers, Object.keys(orMatchers)); - }); + return state; + }; -} + /** + * Gets the internal state of the computation. + * + * @param {Object} state The state + * + * @return {SparkMD5.ArrayBuffer} The instance itself + */ + SparkMD5.ArrayBuffer.prototype.setState = function (state) { + // Convert string to buffer + state.buff = utf8Str2ArrayBuffer(state.buff, true); -function match(userOperator, doc, userValue, parsedField, docFieldValue) { - if (!matchers[userOperator]) { - throw new Error('unknown operator "' + userOperator + - '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' + - '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all'); - } - return matchers[userOperator](doc, userValue, parsedField, docFieldValue); -} + return SparkMD5.prototype.setState.call(this, state); + }; -function fieldExists(docFieldValue) { - return typeof docFieldValue !== 'undefined' && docFieldValue !== null; -} + SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy; -function fieldIsNotUndefined(docFieldValue) { - return typeof docFieldValue !== 'undefined'; -} + SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish; -function modField(docFieldValue, userValue) { - var divisor = userValue[0]; - var mod = userValue[1]; - if (divisor === 0) { - throw new Error('Bad divisor, cannot divide by zero'); - } + /** + * Performs the md5 hash on an array buffer. + * + * @param {ArrayBuffer} arr The array buffer + * @param {Boolean} raw True to get the raw string, false to get the hex one + * + * @return {String} The result + */ + SparkMD5.ArrayBuffer.hash = function (arr, raw) { + var hash = md51_array(new Uint8Array(arr)), + ret = hex(hash); - if (parseInt(divisor, 10) !== divisor ) { - throw new Error('Divisor is not an integer'); - } + return raw ? hexToBinaryString(ret) : ret; + }; - if (parseInt(mod, 10) !== mod ) { - throw new Error('Modulus is not an integer'); - } + return SparkMD5; +})); - if (parseInt(docFieldValue, 10) !== docFieldValue) { - return false; - } - return docFieldValue % divisor === mod; -} +/***/ }), +/* 500 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function arrayContainsValue(docFieldValue, userValue) { - return userValue.some(function (val) { - if (docFieldValue instanceof Array) { - return docFieldValue.indexOf(val) > -1; - } +var v1 = __webpack_require__(501); +var v4 = __webpack_require__(504); - return docFieldValue === val; - }); -} +var uuid = v4; +uuid.v1 = v1; +uuid.v4 = v4; -function arrayContainsAllValues(docFieldValue, userValue) { - return userValue.every(function (val) { - return docFieldValue.indexOf(val) > -1; - }); -} +module.exports = uuid; -function arraySize(docFieldValue, userValue) { - return docFieldValue.length === userValue; -} -function regexMatch(docFieldValue, userValue) { - var re = new RegExp(userValue); +/***/ }), +/* 501 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return re.test(docFieldValue); -} +var rng = __webpack_require__(502); +var bytesToUuid = __webpack_require__(503); -function typeMatch(docFieldValue, userValue) { +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html - switch (userValue) { - case 'null': - return docFieldValue === null; - case 'boolean': - return typeof (docFieldValue) === 'boolean'; - case 'number': - return typeof (docFieldValue) === 'number'; - case 'string': - return typeof (docFieldValue) === 'string'; - case 'array': - return docFieldValue instanceof Array; - case 'object': - return ({}).toString.call(docFieldValue) === '[object Object]'; - } +var _nodeId; +var _clockseq; - throw new Error(userValue + ' not supported as a type.' + - 'Please use one of object, string, array, number, boolean or null.'); +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; -} +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; -var matchers = { + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - '$elemMatch': function (doc, userValue, parsedField, docFieldValue) { - if (!Array.isArray(docFieldValue)) { - return false; + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; } - - if (docFieldValue.length === 0) { - return false; + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; } + } - if (typeof docFieldValue[0] === 'object') { - return docFieldValue.some(function (val) { - return rowFilter(val, userValue, Object.keys(userValue)); - }); - } + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - return docFieldValue.some(function (val) { - return matchSelector(userValue, doc, parsedField, val); - }); - }, + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - '$allMatch': function (doc, userValue, parsedField, docFieldValue) { - if (!Array.isArray(docFieldValue)) { - return false; - } + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - /* istanbul ignore next */ - if (docFieldValue.length === 0) { - return false; - } + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } - if (typeof docFieldValue[0] === 'object') { - return docFieldValue.every(function (val) { - return rowFilter(val, userValue, Object.keys(userValue)); - }); - } + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } - return docFieldValue.every(function (val) { - return matchSelector(userValue, doc, parsedField, val); - }); - }, + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } - '$eq': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) === 0; - }, + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; - '$gte': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) >= 0; - }, + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; - '$gt': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) > 0; - }, + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; - '$lte': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) <= 0; - }, + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; - '$lt': function (doc, userValue, parsedField, docFieldValue) { - return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) < 0; - }, + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; - '$exists': function (doc, userValue, parsedField, docFieldValue) { - //a field that is null is still considered to exist - if (userValue) { - return fieldIsNotUndefined(docFieldValue); - } + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; - return !fieldIsNotUndefined(docFieldValue); - }, + // `clock_seq_low` + b[i++] = clockseq & 0xff; - '$mod': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && modField(docFieldValue, userValue); - }, + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } - '$ne': function (doc, userValue, parsedField, docFieldValue) { - return userValue.every(function (neValue) { - return (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, neValue) !== 0; - }); - }, - '$in': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue); - }, + return buf ? buf : bytesToUuid(b); +} - '$nin': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue); - }, +module.exports = v1; - '$size': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue); - }, - '$all': function (doc, userValue, parsedField, docFieldValue) { - return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue); - }, +/***/ }), +/* 502 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - '$regex': function (doc, userValue, parsedField, docFieldValue) { - return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue); - }, +// Unique ID creation requires a high quality random # generator. In node.js +// this is pretty straight-forward - we use the crypto API. - '$type': function (doc, userValue, parsedField, docFieldValue) { - return typeMatch(docFieldValue, userValue); - } +var crypto = __webpack_require__(76); + +module.exports = function nodeRNG() { + return crypto.randomBytes(16); }; -// return true if the given doc matches the supplied selector -function matchesSelector(doc, selector) { - /* istanbul ignore if */ - if (typeof selector !== 'object') { - // match the CouchDB error message - throw new Error('Selector error: expected a JSON object'); - } - selector = massageSelector(selector); - var row = { - 'doc': doc - }; +/***/ }), +/* 503 */ +/***/ ((module) => { - var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector)); - return rowsMatched && rowsMatched.length === 1; +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); } +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + return bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + '-' + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]] + + bth[buf[i++]] + bth[buf[i++]]; +} +module.exports = bytesToUuid; /***/ }), /* 504 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "collate": () => (/* binding */ collate), -/* harmony export */ "normalizeKey": () => (/* binding */ normalizeKey), -/* harmony export */ "toIndexableString": () => (/* binding */ toIndexableString), -/* harmony export */ "parseIndexableString": () => (/* binding */ parseIndexableString) -/* harmony export */ }); -function pad(str, padWith, upToLength) { - var padding = ''; - var targetLength = upToLength - str.length; - /* istanbul ignore next */ - while (padding.length < targetLength) { - padding += padWith; +var rng = __webpack_require__(502); +var bytesToUuid = __webpack_require__(503); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; } - return padding; -} + options = options || {}; -function padLeft(str, padWith, upToLength) { - var padding = pad(str, padWith, upToLength); - return padding + str; + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); } -var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE -var MAGNITUDE_DIGITS = 3; // ditto -var SEP = ''; // set to '_' for easier debugging +module.exports = v4; -function collate(a, b) { - if (a === b) { - return 0; - } +/***/ }), +/* 505 */ +/***/ ((__unused_webpack_module, exports) => { - a = normalizeKey(a); - b = normalizeKey(b); +"use strict"; - var ai = collationIndex(a); - var bi = collationIndex(b); - if ((ai - bi) !== 0) { - return ai - bi; - } - switch (typeof a) { - case 'number': - return a - b; - case 'boolean': - return a < b ? -1 : 1; - case 'string': - return stringCollate(a, b); - } - return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b); -} -// couch considers null/NaN/Infinity/-Infinity === undefined, -// for the purposes of mapreduce indexes. also, dates get stringified. -function normalizeKey(key) { - switch (typeof key) { - case 'undefined': - return null; - case 'number': - if (key === Infinity || key === -Infinity || isNaN(key)) { - return null; +/** + * Stringify/parse functions that don't operate + * recursively, so they avoid call stack exceeded + * errors. + */ +exports.stringify = function stringify(input) { + var queue = []; + queue.push({obj: input}); + + var res = ''; + var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix; + while ((next = queue.pop())) { + obj = next.obj; + prefix = next.prefix || ''; + val = next.val || ''; + res += prefix; + if (val) { + res += val; + } else if (typeof obj !== 'object') { + res += typeof obj === 'undefined' ? null : JSON.stringify(obj); + } else if (obj === null) { + res += 'null'; + } else if (Array.isArray(obj)) { + queue.push({val: ']'}); + for (i = obj.length - 1; i >= 0; i--) { + arrayPrefix = i === 0 ? '' : ','; + queue.push({obj: obj[i], prefix: arrayPrefix}); } - return key; - case 'object': - var origKey = key; - if (Array.isArray(key)) { - var len = key.length; - key = new Array(len); - for (var i = 0; i < len; i++) { - key[i] = normalizeKey(origKey[i]); - } - /* istanbul ignore next */ - } else if (key instanceof Date) { - return key.toJSON(); - } else if (key !== null) { // generic object - key = {}; - for (var k in origKey) { - if (origKey.hasOwnProperty(k)) { - var val = origKey[k]; - if (typeof val !== 'undefined') { - key[k] = normalizeKey(val); - } - } + queue.push({val: '['}); + } else { // object + keys = []; + for (k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); } } - } - return key; -} - -function indexify(key) { - if (key !== null) { - switch (typeof key) { - case 'boolean': - return key ? 1 : 0; - case 'number': - return numToIndexableString(key); - case 'string': - // We've to be sure that key does not contain \u0000 - // Do order-preserving replacements: - // 0 -> 1, 1 - // 1 -> 1, 2 - // 2 -> 2, 2 - /* eslint-disable no-control-regex */ - return key - .replace(/\u0002/g, '\u0002\u0002') - .replace(/\u0001/g, '\u0001\u0002') - .replace(/\u0000/g, '\u0001\u0001'); - /* eslint-enable no-control-regex */ - case 'object': - var isArray = Array.isArray(key); - var arr = isArray ? key : Object.keys(key); - var i = -1; - var len = arr.length; - var result = ''; - if (isArray) { - while (++i < len) { - result += toIndexableString(arr[i]); - } - } else { - while (++i < len) { - var objKey = arr[i]; - result += toIndexableString(objKey) + - toIndexableString(key[objKey]); - } - } - return result; - } - } - return ''; -} - -// convert the given key to a string that would be appropriate -// for lexical sorting, e.g. within a database, where the -// sorting is the same given by the collate() function. -function toIndexableString(key) { - var zero = '\u0000'; - key = normalizeKey(key); - return collationIndex(key) + SEP + indexify(key) + zero; -} - -function parseNumber(str, i) { - var originalIdx = i; - var num; - var zero = str[i] === '1'; - if (zero) { - num = 0; - i++; - } else { - var neg = str[i] === '0'; - i++; - var numAsString = ''; - var magAsString = str.substring(i, i + MAGNITUDE_DIGITS); - var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE; - /* istanbul ignore next */ - if (neg) { - magnitude = -magnitude; - } - i += MAGNITUDE_DIGITS; - while (true) { - var ch = str[i]; - if (ch === '\u0000') { - break; - } else { - numAsString += ch; + queue.push({val: '}'}); + for (i = keys.length - 1; i >= 0; i--) { + key = keys[i]; + value = obj[key]; + objPrefix = (i > 0 ? ',' : ''); + objPrefix += JSON.stringify(key) + ':'; + queue.push({obj: value, prefix: objPrefix}); } - i++; - } - numAsString = numAsString.split('.'); - if (numAsString.length === 1) { - num = parseInt(numAsString, 10); - } else { - /* istanbul ignore next */ - num = parseFloat(numAsString[0] + '.' + numAsString[1]); - } - /* istanbul ignore next */ - if (neg) { - num = num - 10; - } - /* istanbul ignore next */ - if (magnitude !== 0) { - // parseFloat is more reliable than pow due to rounding errors - // e.g. Number.MAX_VALUE would return Infinity if we did - // num * Math.pow(10, magnitude); - num = parseFloat(num + 'e' + magnitude); + queue.push({val: '{'}); } } - return {num: num, length : i - originalIdx}; -} - -// move up the stack while parsing -// this function moved outside of parseIndexableString for performance -function pop(stack, metaStack) { - var obj = stack.pop(); + return res; +}; - if (metaStack.length) { - var lastMetaElement = metaStack[metaStack.length - 1]; - if (obj === lastMetaElement.element) { - // popping a meta-element, e.g. an object whose value is another object - metaStack.pop(); - lastMetaElement = metaStack[metaStack.length - 1]; - } - var element = lastMetaElement.element; - var lastElementIndex = lastMetaElement.index; - if (Array.isArray(element)) { - element.push(obj); - } else if (lastElementIndex === stack.length - 2) { // obj with key+value - var key = stack.pop(); - element[key] = obj; - } else { - stack.push(obj); // obj with key only - } +// Convenience function for the parse function. +// This pop function is basically copied from +// pouchCollate.parseIndexableString +function pop(obj, stack, metaStack) { + var lastMetaElement = metaStack[metaStack.length - 1]; + if (obj === lastMetaElement.element) { + // popping a meta-element, e.g. an object whose value is another object + metaStack.pop(); + lastMetaElement = metaStack[metaStack.length - 1]; + } + var element = lastMetaElement.element; + var lastElementIndex = lastMetaElement.index; + if (Array.isArray(element)) { + element.push(obj); + } else if (lastElementIndex === stack.length - 2) { // obj with key+value + var key = stack.pop(); + element[key] = obj; + } else { + stack.push(obj); // obj with key only } } -function parseIndexableString(str) { +exports.parse = function (str) { var stack = []; var metaStack = []; // stack for arrays and objects var i = 0; - - /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/ + var collationIndex,parsedNum,numChar; + var parsedString,lastCh,numConsecutiveSlashes,ch; + var arrayElement, objElement; while (true) { - var collationIndex = str[i++]; - if (collationIndex === '\u0000') { + collationIndex = str[i++]; + if (collationIndex === '}' || + collationIndex === ']' || + typeof collationIndex === 'undefined') { if (stack.length === 1) { return stack.pop(); } else { - pop(stack, metaStack); + pop(stack.pop(), stack, metaStack); continue; } } switch (collationIndex) { - case '1': - stack.push(null); + case ' ': + case '\t': + case '\n': + case ':': + case ',': break; - case '2': - stack.push(str[i] === '1'); - i++; + case 'n': + i += 3; // 'ull' + pop(null, stack, metaStack); break; - case '3': - var parsedNum = parseNumber(str, i); - stack.push(parsedNum.num); - i += parsedNum.length; + case 't': + i += 3; // 'rue' + pop(true, stack, metaStack); + break; + case 'f': + i += 4; // 'alse' + pop(false, stack, metaStack); break; + case '0': + case '1': + case '2': + case '3': case '4': - var parsedStr = ''; - /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/ + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + parsedNum = ''; + i--; while (true) { - var ch = str[i]; - if (ch === '\u0000') { + numChar = str[i++]; + if (/[\d\.\-e\+]/.test(numChar)) { + parsedNum += numChar; + } else { + i--; break; } - parsedStr += ch; - i++; } - // perform the reverse of the order-preserving replacement - // algorithm (see above) - /* eslint-disable no-control-regex */ - parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000') - .replace(/\u0001\u0002/g, '\u0001') - .replace(/\u0002\u0002/g, '\u0002'); - /* eslint-enable no-control-regex */ - stack.push(parsedStr); + pop(parseFloat(parsedNum), stack, metaStack); break; - case '5': - var arrayElement = { element: [], index: stack.length }; + case '"': + parsedString = ''; + lastCh = void 0; + numConsecutiveSlashes = 0; + while (true) { + ch = str[i++]; + if (ch !== '"' || (lastCh === '\\' && + numConsecutiveSlashes % 2 === 1)) { + parsedString += ch; + lastCh = ch; + if (lastCh === '\\') { + numConsecutiveSlashes++; + } else { + numConsecutiveSlashes = 0; + } + } else { + break; + } + } + pop(JSON.parse('"' + parsedString + '"'), stack, metaStack); + break; + case '[': + arrayElement = { element: [], index: stack.length }; stack.push(arrayElement.element); metaStack.push(arrayElement); break; - case '6': - var objElement = { element: {}, index: stack.length }; + case '{': + objElement = { element: {}, index: stack.length }; stack.push(objElement.element); metaStack.push(objElement); break; - /* istanbul ignore next */ default: throw new Error( - 'bad collationIndex or unexpectedly reached end of input: ' + - collationIndex); + 'unexpectedly reached end of input: ' + collationIndex); } } -} +}; -function arrayCollate(a, b) { - var len = Math.min(a.length, b.length); - for (var i = 0; i < len; i++) { - var sort = collate(a[i], b[i]); - if (sort !== 0) { - return sort; - } + +/***/ }), +/* 506 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507); +/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(510); +/* harmony import */ var pouchdb_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(512); +/* harmony import */ var pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(515); +/* harmony import */ var pouchdb_abstract_mapreduce__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(517); +/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(516); +/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(511); + + + + + + + + +// we restucture the supplied JSON considerably, because the official +// Mango API is very particular about a lot of this stuff, but we like +// to be liberal with what we accept in order to prevent mental +// breakdowns in our users +function massageCreateIndexRequest(requestDef) { + requestDef = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(requestDef); + + if (!requestDef.index) { + requestDef.index = {}; } - return (a.length === b.length) ? 0 : - (a.length > b.length) ? 1 : -1; -} -function stringCollate(a, b) { - // See: https://github.com/daleharvey/pouchdb/issues/40 - // This is incompatible with the CouchDB implementation, but its the - // best we can do for now - return (a === b) ? 0 : ((a > b) ? 1 : -1); -} -function objectCollate(a, b) { - var ak = Object.keys(a), bk = Object.keys(b); - var len = Math.min(ak.length, bk.length); - for (var i = 0; i < len; i++) { - // First sort the keys - var sort = collate(ak[i], bk[i]); - if (sort !== 0) { - return sort; - } - // if the keys are equal sort the values - sort = collate(a[ak[i]], b[bk[i]]); - if (sort !== 0) { - return sort; + + ['type', 'name', 'ddoc'].forEach(function (key) { + if (requestDef.index[key]) { + requestDef[key] = requestDef.index[key]; + delete requestDef.index[key]; } + }); + + if (requestDef.fields) { + requestDef.index.fields = requestDef.fields; + delete requestDef.fields; + } + if (!requestDef.type) { + requestDef.type = 'json'; } - return (ak.length === bk.length) ? 0 : - (ak.length > bk.length) ? 1 : -1; + return requestDef; } -// The collation is defined by erlangs ordered terms -// the atoms null, true, false come first, then numbers, strings, -// arrays, then objects -// null/undefined/NaN/Infinity/-Infinity are all considered null -function collationIndex(x) { - var id = ['boolean', 'number', 'string', 'object']; - var idx = id.indexOf(typeof x); - //false if -1 otherwise true, but fast!!!!1 - if (~idx) { - if (x === null) { - return 1; - } - if (Array.isArray(x)) { - return 5; + +function dbFetch(db, path, opts, callback) { + var status, ok; + opts.headers = new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_2__.Headers({'Content-type': 'application/json'}); + db.fetch(path, opts).then(function (response) { + status = response.status; + ok = response.ok; + return response.json(); + }).then(function (json) { + if (!ok) { + json.status = status; + var err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_1__.generateErrorFromResponse)(json); + callback(err); + } else { + callback(null, json); } - return idx < 3 ? (idx + 2) : (idx + 3); - } - /* istanbul ignore next */ - if (Array.isArray(x)) { - return 5; - } + }).catch(callback); } -// conversion: -// x yyy zz...zz -// x = 0 for negative, 1 for 0, 2 for positive -// y = exponent (for negative numbers negated) moved so that it's >= 0 -// z = mantisse -function numToIndexableString(num) { +function createIndex(db, requestDef, callback) { + requestDef = massageCreateIndexRequest(requestDef); + dbFetch(db, '_index', { + method: 'POST', + body: JSON.stringify(requestDef) + }, callback); +} - if (num === 0) { - return '1'; - } +function find(db, requestDef, callback) { + dbFetch(db, '_find', { + method: 'POST', + body: JSON.stringify(requestDef) + }, callback); +} - // convert number to exponential format for easier and - // more succinct string sorting - var expFormat = num.toExponential().split(/e\+?/); - var magnitude = parseInt(expFormat[1], 10); +function explain(db, requestDef, callback) { + dbFetch(db, '_explain', { + method: 'POST', + body: JSON.stringify(requestDef) + }, callback); +} - var neg = num < 0; +function getIndexes(db, callback) { + dbFetch(db, '_index', { + method: 'GET' + }, callback); +} - var result = neg ? '0' : '2'; +function deleteIndex(db, indexDef, callback) { - // first sort by magnitude - // it's easier if all magnitudes are positive - var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE); - var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS); - result += SEP + magString; + var ddoc = indexDef.ddoc; + var type = indexDef.type || 'json'; + var name = indexDef.name; - // then sort by the factor - var factor = Math.abs(parseFloat(expFormat[0])); // [1..10) - /* istanbul ignore next */ - if (neg) { // for negative reverse ordering - factor = 10 - factor; + if (!ddoc) { + return callback(new Error('you must provide an index\'s ddoc')); } - var factorStr = factor.toFixed(20); + if (!name) { + return callback(new Error('you must provide an index\'s name')); + } - // strip zeros from the end - factorStr = factorStr.replace(/\.?0+$/, ''); + var url = '_index/' + [ddoc, type, name].map(encodeURIComponent).join('/'); - result += SEP + factorStr; + dbFetch(db, url, {method: 'DELETE'}, callback); +} - return result; +function getArguments(fun) { + return function () { + var len = arguments.length; + var args = new Array(len); + var i = -1; + while (++i < len) { + args[i] = arguments[i]; + } + return fun.call(this, args); + }; +} + +function callbackify(fun) { + return getArguments(function (args) { + var cb = args.pop(); + var promise = fun.apply(this, args); + promisedCallback(promise, cb); + return promise; + }); +} + +function promisedCallback(promise, callback) { + promise.then(function (res) { + (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () { + callback(null, res); + }); + }, function (reason) { + (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () { + callback(reason); + }); + }); + return promise; +} + +var flatten = getArguments(function (args) { + var res = []; + for (var i = 0, len = args.length; i < len; i++) { + var subArr = args[i]; + if (Array.isArray(subArr)) { + res = res.concat(flatten.apply(null, subArr)); + } else { + res.push(subArr); + } + } + return res; +}); + +function mergeObjects(arr) { + var res = {}; + for (var i = 0, len = arr.length; i < len; i++) { + res = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.assign)(res, arr[i]); + } + return res; } +// Selects a list of fields defined in dot notation from one doc +// and copies them to a new doc. Like underscore _.pick but supports nesting. +function pick(obj, arr) { + var res = {}; + for (var i = 0, len = arr.length; i < len; i++) { + var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(arr[i]); + var value = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getFieldFromDoc)(obj, parsedField); + if (typeof value !== 'undefined') { + (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.setFieldInDoc)(res, parsedField, value); + } + } + return res; +} +// e.g. ['a'], ['a', 'b'] is true, but ['b'], ['a', 'b'] is false +function oneArrayIsSubArrayOfOther(left, right) { + for (var i = 0, len = Math.min(left.length, right.length); i < len; i++) { + if (left[i] !== right[i]) { + return false; + } + } + return true; +} -/***/ }), -/* 505 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +// e.g.['a', 'b', 'c'], ['a', 'b'] is false +function oneArrayIsStrictSubArrayOfOther(left, right) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(495); -/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(499); -/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(497); -/* harmony import */ var pouchdb_binary_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(506); -/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(504); -/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(498); -/* harmony import */ var pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(500); -/* harmony import */ var pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(508); + if (left.length > right.length) { + return false; + } + return oneArrayIsSubArrayOfOther(left, right); +} +// same as above, but treat the left array as an unordered set +// e.g. ['b', 'a'], ['a', 'b', 'c'] is true, but ['c'], ['a', 'b', 'c'] is false +function oneSetIsSubArrayOfOther(left, right) { + left = left.slice(); + for (var i = 0, len = right.length; i < len; i++) { + var field = right[i]; + if (!left.length) { + break; + } + var leftIdx = left.indexOf(field); + if (leftIdx === -1) { + return false; + } else { + left.splice(leftIdx, 1); + } + } + return true; +} +function arrayToObject(arr) { + var res = {}; + for (var i = 0, len = arr.length; i < len; i++) { + res[arr[i]] = true; + } + return res; +} +function max(arr, fun) { + var max = null; + var maxScore = -1; + for (var i = 0, len = arr.length; i < len; i++) { + var element = arr[i]; + var score = fun(element); + if (score > maxScore) { + maxScore = score; + max = element; + } + } + return max; +} +function arrayEquals(arr1, arr2) { + if (arr1.length !== arr2.length) { + return false; + } + for (var i = 0, len = arr1.length; i < len; i++) { + if (arr1[i] !== arr2[i]) { + return false; + } + } + return true; +} +function uniq(arr) { + var obj = {}; + for (var i = 0; i < arr.length; i++) { + obj['$' + arr[i]] = true; + } + return Object.keys(obj).map(function (key) { + return key.substring(1); + }); +} +// +// One thing about these mappers: +// +// Per the advice of John-David Dalton (http://youtu.be/NthmeLEhDDM), +// what you want to do in this case is optimize for the smallest possible +// function, since that's the thing that gets run over and over again. +// +// This code would be a lot simpler if all the if/elses were inside +// the function, but it would also be a lot less performant. +// -/* - * Simple task queue to sequentialize actions. Assumes - * callbacks will eventually fire (once). - */ +function createDeepMultiMapper(fields, emit) { + return function (doc) { + var toEmit = []; + for (var i = 0, iLen = fields.length; i < iLen; i++) { + var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(fields[i]); + var value = doc; + for (var j = 0, jLen = parsedField.length; j < jLen; j++) { + var key = parsedField[j]; + value = value[key]; + if (typeof value === 'undefined') { + return; // don't emit + } + } + toEmit.push(value); + } + emit(toEmit); + }; +} +function createDeepSingleMapper(field, emit) { + var parsedField = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.parseField)(field); + return function (doc) { + var value = doc; + for (var i = 0, len = parsedField.length; i < len; i++) { + var key = parsedField[i]; + value = value[key]; + if (typeof value === 'undefined') { + return; // do nothing + } + } + emit(value); + }; +} -function TaskQueue() { - this.promise = new Promise(function (fulfill) {fulfill(); }); +function createShallowSingleMapper(field, emit) { + return function (doc) { + emit(doc[field]); + }; } -TaskQueue.prototype.add = function (promiseFactory) { - this.promise = this.promise.catch(function () { - // just recover - }).then(function () { - return promiseFactory(); - }); - return this.promise; -}; -TaskQueue.prototype.finish = function () { - return this.promise; -}; -function stringify(input) { - if (!input) { - return 'undefined'; // backwards compat for empty reduce +function createShallowMultiMapper(fields, emit) { + return function (doc) { + var toEmit = []; + for (var i = 0, len = fields.length; i < len; i++) { + toEmit.push(doc[fields[i]]); + } + emit(toEmit); + }; +} + +function checkShallow(fields) { + for (var i = 0, len = fields.length; i < len; i++) { + var field = fields[i]; + if (field.indexOf('.') !== -1) { + return false; + } } - // for backwards compat with mapreduce, functions/strings are stringified - // as-is. everything else is JSON-stringified. - switch (typeof input) { - case 'function': - // e.g. a mapreduce map - return input.toString(); - case 'string': - // e.g. a mapreduce built-in _reduce function - return input.toString(); - default: - // e.g. a JSON object in the case of mango queries - return JSON.stringify(input); + return true; +} + +function createMapper(fields, emit) { + var isShallow = checkShallow(fields); + var isSingle = fields.length === 1; + + // notice we try to optimize for the most common case, + // i.e. single shallow indexes + if (isShallow) { + if (isSingle) { + return createShallowSingleMapper(fields[0], emit); + } else { // multi + return createShallowMultiMapper(fields, emit); + } + } else { // deep + if (isSingle) { + return createDeepSingleMapper(fields[0], emit); + } else { // multi + return createDeepMultiMapper(fields, emit); + } } } -/* create a string signature for a view so we can cache it and uniq it */ -function createViewSignature(mapFun, reduceFun) { - // the "undefined" part is for backwards compatibility - return stringify(mapFun) + stringify(reduceFun) + 'undefined'; +function mapper(mapFunDef, emit) { + // mapFunDef is a list of fields + + var fields = Object.keys(mapFunDef.fields); + + return createMapper(fields, emit); } -function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) { - var viewSignature = createViewSignature(mapFun, reduceFun); +/* istanbul ignore next */ +function reducer(/*reduceFunDef*/) { + throw new Error('reduce not supported'); +} - var cachedViews; - if (!temporary) { - // cache this to ensure we don't try to update the same view twice - cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {}; - if (cachedViews[viewSignature]) { - return cachedViews[viewSignature]; - } +function ddocValidator(ddoc, viewName) { + var view = ddoc.views[viewName]; + // This doesn't actually need to be here apparently, but + // I feel safer keeping it. + /* istanbul ignore if */ + if (!view.map || !view.map.fields) { + throw new Error('ddoc ' + ddoc._id +' with view ' + viewName + + ' doesn\'t have map.fields defined. ' + + 'maybe it wasn\'t created by this plugin?'); } +} - var promiseForView = sourceDB.info().then(function (info) { +var abstractMapper = (0,pouchdb_abstract_mapreduce__WEBPACK_IMPORTED_MODULE_4__["default"])( + /* localDocName */ 'indexes', + mapper, + reducer, + ddocValidator +); - var depDbName = info.db_name + '-mrview-' + - (temporary ? 'temp' : (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_1__.stringMd5)(viewSignature)); +// normalize the "sort" value +function massageSort(sort) { + if (!Array.isArray(sort)) { + throw new Error('invalid sort json - should be an array'); + } + return sort.map(function (sorting) { + if (typeof sorting === 'string') { + var obj = {}; + obj[sorting] = 'asc'; + return obj; + } else { + return sorting; + } + }); +} - // save the view name in the source db so it can be cleaned up if necessary - // (e.g. when the _design doc is deleted, remove all associated view data) - function diffFunction(doc) { - doc.views = doc.views || {}; - var fullViewName = viewName; - if (fullViewName.indexOf('/') === -1) { - fullViewName = viewName + '/' + viewName; - } - var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {}; - /* istanbul ignore if */ - if (depDbs[depDbName]) { - return; // no update necessary - } - depDbs[depDbName] = true; - return doc; +function massageUseIndex(useIndex) { + var cleanedUseIndex = []; + if (typeof useIndex === 'string') { + cleanedUseIndex.push(useIndex); + } else { + cleanedUseIndex = useIndex; + } + + return cleanedUseIndex.map(function (name) { + return name.replace('_design/', ''); + }); +} + +function massageIndexDef(indexDef) { + indexDef.fields = indexDef.fields.map(function (field) { + if (typeof field === 'string') { + var obj = {}; + obj[field] = 'asc'; + return obj; } - return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(sourceDB, '_local/' + localDocName, diffFunction).then(function () { - return sourceDB.registerDependentDatabase(depDbName).then(function (res) { - var db = res.db; - db.auto_compaction = true; - var view = { - name: depDbName, - db: db, - sourceDB: sourceDB, - adapter: sourceDB.adapter, - mapFun: mapFun, - reduceFun: reduceFun - }; - return view.db.get('_local/lastSeq').catch(function (err) { - /* istanbul ignore if */ - if (err.status !== 404) { - throw err; - } - }).then(function (lastSeqDoc) { - view.seq = lastSeqDoc ? lastSeqDoc.seq : 0; - if (cachedViews) { - view.db.once('destroyed', function () { - delete cachedViews[viewSignature]; - }); - } - return view; - }); - }); - }); + return field; }); + return indexDef; +} - if (cachedViews) { - cachedViews[viewSignature] = promiseForView; +function getKeyFromDoc(doc, index) { + var res = []; + for (var i = 0; i < index.def.fields.length; i++) { + var field = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(index.def.fields[i]); + res.push(doc[field]); } - return promiseForView; + return res; } -var persistentQueues = {}; -var tempViewQueue = new TaskQueue(); -var CHANGES_BATCH_SIZE = 50; +// have to do this manually because REASONS. I don't know why +// CouchDB didn't implement inclusive_start +function filterInclusiveStart(rows, targetValue, index) { + var indexFields = index.def.fields; + for (var i = 0, len = rows.length; i < len; i++) { + var row = rows[i]; -function parseViewName(name) { - // can be either 'ddocname/viewname' or just 'viewname' - // (where the ddoc name is the same) - return name.indexOf('/') === -1 ? [name, name] : name.split('/'); + // shave off any docs at the beginning that are <= the + // target value + + var docKey = getKeyFromDoc(row.doc, index); + if (indexFields.length === 1) { + docKey = docKey[0]; // only one field, not multi-field + } else { // more than one field in index + // in the case where e.g. the user is searching {$gt: {a: 1}} + // but the index is [a, b], then we need to shorten the doc key + while (docKey.length > targetValue.length) { + docKey.pop(); + } + } + //ABS as we just looking for values that don't match + if (Math.abs((0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__.collate)(docKey, targetValue)) > 0) { + // no need to filter any further; we're past the key + break; + } + } + return i > 0 ? rows.slice(i) : rows; } -function isGenOne(changes) { - // only return true if the current change is 1- - // and there are no other leafs - return changes.length === 1 && /^1-/.test(changes[0].rev); +function reverseOptions(opts) { + var newOpts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(opts); + delete newOpts.startkey; + delete newOpts.endkey; + delete newOpts.inclusive_start; + delete newOpts.inclusive_end; + + if ('endkey' in opts) { + newOpts.startkey = opts.endkey; + } + if ('startkey' in opts) { + newOpts.endkey = opts.startkey; + } + if ('inclusive_start' in opts) { + newOpts.inclusive_end = opts.inclusive_start; + } + if ('inclusive_end' in opts) { + newOpts.inclusive_start = opts.inclusive_end; + } + return newOpts; } -function emitError(db, e) { - try { - db.emit('error', e); - } catch (err) { - (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.guardedConsole)('error', - 'The user\'s map/reduce function threw an uncaught error.\n' + - 'You can debug this error by doing:\n' + - 'myDatabase.on(\'error\', function (err) { debugger; });\n' + - 'Please double-check your map/reduce function.'); - (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.guardedConsole)('error', e); +function validateIndex(index) { + var ascFields = index.fields.filter(function (field) { + return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getValue)(field) === 'asc'; + }); + if (ascFields.length !== 0 && ascFields.length !== index.fields.length) { + throw new Error('unsupported mixed sorting'); } } -/** - * Returns an "abstract" mapreduce object of the form: - * - * { - * query: queryFun, - * viewCleanup: viewCleanupFun - * } - * - * Arguments are: - * - * localDoc: string - * This is for the local doc that gets saved in order to track the - * "dependent" DBs and clean them up for viewCleanup. It should be - * unique, so that indexer plugins don't collide with each other. - * mapper: function (mapFunDef, emit) - * Returns a map function based on the mapFunDef, which in the case of - * normal map/reduce is just the de-stringified function, but may be - * something else, such as an object in the case of pouchdb-find. - * reducer: function (reduceFunDef) - * Ditto, but for reducing. Modules don't have to support reducing - * (e.g. pouchdb-find). - * ddocValidator: function (ddoc, viewName) - * Throws an error if the ddoc or viewName is not valid. - * This could be a way to communicate to the user that the configuration for the - * indexer is invalid. - */ -function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) { +function validateSort(requestDef, index) { + if (index.defaultUsed && requestDef.sort) { + var noneIdSorts = requestDef.sort.filter(function (sortItem) { + return Object.keys(sortItem)[0] !== '_id'; + }).map(function (sortItem) { + return Object.keys(sortItem)[0]; + }); - function tryMap(db, fun, doc) { - // emit an event if there was an error thrown by a map function. - // putting try/catches in a single function also avoids deoptimizations. - try { - fun(doc); - } catch (e) { - emitError(db, e); + if (noneIdSorts.length > 0) { + throw new Error('Cannot sort on field(s) "' + noneIdSorts.join(',') + + '" when using the default index'); } } - function tryReduce(db, fun, keys, values, rereduce) { - // same as above, but returning the result or an error. there are two separate - // functions to avoid extra memory allocations since the tryCode() case is used - // for custom map functions (common) vs this function, which is only used for - // custom reduce functions (rare) - try { - return {output : fun(keys, values, rereduce)}; - } catch (e) { - emitError(db, e); - return {error: e}; - } + if (index.defaultUsed) { + return; } +} - function sortByKeyThenValue(x, y) { - var keyCompare = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(x.key, y.key); - return keyCompare !== 0 ? keyCompare : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(x.value, y.value); +function validateFindRequest(requestDef) { + if (typeof requestDef.selector !== 'object') { + throw new Error('you must provide a selector when you find()'); } - function sliceResults(results, limit, skip) { - skip = skip || 0; - if (typeof limit === 'number') { - return results.slice(skip, limit + skip); - } else if (skip > 0) { - return results.slice(skip); + /*var selectors = requestDef.selector['$and'] || [requestDef.selector]; + for (var i = 0; i < selectors.length; i++) { + var selector = selectors[i]; + var keys = Object.keys(selector); + if (keys.length === 0) { + throw new Error('invalid empty selector'); } - return results; + //var selection = selector[keys[0]]; + /*if (Object.keys(selection).length !== 1) { + throw new Error('invalid selector: ' + JSON.stringify(selection) + + ' - it must have exactly one key/value'); + } + }*/ +} + +// determine the maximum number of fields +// we're going to need to query, e.g. if the user +// has selection ['a'] and sorting ['a', 'b'], then we +// need to use the longer of the two: ['a', 'b'] +function getUserFields(selector, sort) { + var selectorFields = Object.keys(selector); + var sortFields = sort? sort.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey) : []; + var userFields; + if (selectorFields.length >= sortFields.length) { + userFields = selectorFields; + } else { + userFields = sortFields; } - function rowToDocId(row) { - var val = row.value; - // Users can explicitly specify a joined doc _id, or it - // defaults to the doc _id that emitted the key/value. - var docId = (val && typeof val === 'object' && val._id) || row.id; - return docId; + if (sortFields.length === 0) { + return { + fields: userFields + }; } - function readAttachmentsAsBlobOrBuffer(res) { - res.rows.forEach(function (row) { - var atts = row.doc && row.doc._attachments; - if (!atts) { - return; - } - Object.keys(atts).forEach(function (filename) { - var att = atts[filename]; - atts[filename].data = (0,pouchdb_binary_utils__WEBPACK_IMPORTED_MODULE_3__.base64StringToBlobOrBuffer)(att.data, att.content_type); - }); - }); + // sort according to the user's preferred sorting + userFields = userFields.sort(function (left, right) { + var leftIdx = sortFields.indexOf(left); + if (leftIdx === -1) { + leftIdx = Number.MAX_VALUE; + } + var rightIdx = sortFields.indexOf(right); + if (rightIdx === -1) { + rightIdx = Number.MAX_VALUE; + } + return leftIdx < rightIdx ? -1 : leftIdx > rightIdx ? 1 : 0; + }); + + return { + fields: userFields, + sortOrder: sort.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey) + }; +} + +function createIndex$1(db, requestDef) { + requestDef = massageCreateIndexRequest(requestDef); + var originalIndexDef = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(requestDef.index); + requestDef.index = massageIndexDef(requestDef.index); + + validateIndex(requestDef.index); + + // calculating md5 is expensive - memoize and only + // run if required + var md5; + function getMd5() { + return md5 || (md5 = (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_6__.stringMd5)(JSON.stringify(requestDef))); } - function postprocessAttachments(opts) { - return function (res) { - if (opts.include_docs && opts.attachments && opts.binary) { - readAttachmentsAsBlobOrBuffer(res); + var viewName = requestDef.name || ('idx-' + getMd5()); + + var ddocName = requestDef.ddoc || ('idx-' + getMd5()); + var ddocId = '_design/' + ddocName; + + var hasInvalidLanguage = false; + var viewExists = false; + + function updateDdoc(doc) { + if (doc._rev && doc.language !== 'query') { + hasInvalidLanguage = true; + } + doc.language = 'query'; + doc.views = doc.views || {}; + + viewExists = !!doc.views[viewName]; + + if (viewExists) { + return false; + } + + doc.views[viewName] = { + map: { + fields: mergeObjects(requestDef.index.fields) + }, + reduce: '_count', + options: { + def: originalIndexDef } - return res; }; + + return doc; } - function addHttpParam(paramName, opts, params, asJson) { - // add an http param from opts to params, optionally json-encoded - var val = opts[paramName]; - if (typeof val !== 'undefined') { - if (asJson) { - val = encodeURIComponent(JSON.stringify(val)); - } - params.push(paramName + '=' + val); + db.constructor.emit('debug', ['find', 'creating index', ddocId]); + + return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(db, ddocId, updateDdoc).then(function () { + if (hasInvalidLanguage) { + throw new Error('invalid language for ddoc with id "' + + ddocId + + '" (should be "query")'); } - } + }).then(function () { + // kick off a build + // TODO: abstract-pouchdb-mapreduce should support auto-updating + // TODO: should also use update_after, but pouchdb/pouchdb#3415 blocks me + var signature = ddocName + '/' + viewName; + return abstractMapper.query.call(db, signature, { + limit: 0, + reduce: false + }).then(function () { + return { + id: ddocId, + name: viewName, + result: viewExists ? 'exists' : 'created' + }; + }); + }); +} + +function getIndexes$1(db) { + // just search through all the design docs and filter in-memory. + // hopefully there aren't that many ddocs. + return db.allDocs({ + startkey: '_design/', + endkey: '_design/\uffff', + include_docs: true + }).then(function (allDocsRes) { + var res = { + indexes: [{ + ddoc: null, + name: '_all_docs', + type: 'special', + def: { + fields: [{_id: 'asc'}] + } + }] + }; + + res.indexes = flatten(res.indexes, allDocsRes.rows.filter(function (row) { + return row.doc.language === 'query'; + }).map(function (row) { + var viewNames = row.doc.views !== undefined ? Object.keys(row.doc.views) : []; + + return viewNames.map(function (viewName) { + var view = row.doc.views[viewName]; + return { + ddoc: row.id, + name: viewName, + type: 'json', + def: massageIndexDef(view.options.def) + }; + }); + })); + + // these are sorted by view name for some reason + res.indexes.sort(function (left, right) { + return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.compare)(left.name, right.name); + }); + res.total_rows = res.indexes.length; + return res; + }); +} + +// couchdb lowest collation value +var COLLATE_LO = null; - function coerceInteger(integerCandidate) { - if (typeof integerCandidate !== 'undefined') { - var asNumber = Number(integerCandidate); - // prevents e.g. '1foo' or '1.1' being coerced to 1 - if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) { - return asNumber; - } else { - return integerCandidate; - } - } - } +// couchdb highest collation value (TODO: well not really, but close enough amirite) +var COLLATE_HI = {"\uffff": {}}; - function coerceOptions(opts) { - opts.group_level = coerceInteger(opts.group_level); - opts.limit = coerceInteger(opts.limit); - opts.skip = coerceInteger(opts.skip); - return opts; - } +// couchdb second-lowest collation value - function checkPositiveInteger(number) { - if (number) { - if (typeof number !== 'number') { - return new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Invalid value for integer: "' + - number + '"'); - } - if (number < 0) { - return new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Invalid value for positive integer: ' + - '"' + number + '"'); - } +function checkFieldInIndex(index, field) { + var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); + for (var i = 0, len = indexFields.length; i < len; i++) { + var indexField = indexFields[i]; + if (field === indexField) { + return true; } } + return false; +} - function checkQueryParseError(options, fun) { - var startkeyName = options.descending ? 'endkey' : 'startkey'; - var endkeyName = options.descending ? 'startkey' : 'endkey'; +// so when you do e.g. $eq/$eq, we can do it entirely in the database. +// but when you do e.g. $gt/$eq, the first part can be done +// in the database, but the second part has to be done in-memory, +// because $gt has forced us to lose precision. +// so that's what this determines +function userOperatorLosesPrecision(selector, field) { + var matcher = selector[field]; + var userOperator = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(matcher); - if (typeof options[startkeyName] !== 'undefined' && - typeof options[endkeyName] !== 'undefined' && - (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(options[startkeyName], options[endkeyName]) > 0) { - throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('No rows can match your key range, ' + - 'reverse your start_key and end_key or set {descending : true}'); - } else if (fun.reduce && options.reduce !== false) { - if (options.include_docs) { - throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('{include_docs:true} is invalid for reduce'); - } else if (options.keys && options.keys.length > 1 && - !options.group && !options.group_level) { - throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Multi-key fetches for reduce views must use ' + - '{group: true}'); - } - } - ['group_level', 'limit', 'skip'].forEach(function (optionName) { - var error = checkPositiveInteger(options[optionName]); - if (error) { - throw error; - } - }); - } + return userOperator !== '$eq'; +} - function httpQuery(db, fun, opts) { - // List of parameters to add to the PUT request - var params = []; - var body; - var method = 'GET'; - var ok, status; +// sort the user fields by their position in the index, +// if they're in the index +function sortFieldsByIndex(userFields, index) { + var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); - // If opts.reduce exists and is defined, then add it to the list - // of parameters. - // If reduce=false then the results are that of only the map function - // not the final result of map and reduce. - addHttpParam('reduce', opts, params); - addHttpParam('include_docs', opts, params); - addHttpParam('attachments', opts, params); - addHttpParam('limit', opts, params); - addHttpParam('descending', opts, params); - addHttpParam('group', opts, params); - addHttpParam('group_level', opts, params); - addHttpParam('skip', opts, params); - addHttpParam('stale', opts, params); - addHttpParam('conflicts', opts, params); - addHttpParam('startkey', opts, params, true); - addHttpParam('start_key', opts, params, true); - addHttpParam('endkey', opts, params, true); - addHttpParam('end_key', opts, params, true); - addHttpParam('inclusive_end', opts, params); - addHttpParam('key', opts, params, true); - addHttpParam('update_seq', opts, params); + return userFields.slice().sort(function (a, b) { + var aIdx = indexFields.indexOf(a); + var bIdx = indexFields.indexOf(b); + if (aIdx === -1) { + aIdx = Number.MAX_VALUE; + } + if (bIdx === -1) { + bIdx = Number.MAX_VALUE; + } + return (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.compare)(aIdx, bIdx); + }); +} - // Format the list of parameters into a valid URI query string - params = params.join('&'); - params = params === '' ? '' : '?' + params; +// first pass to try to find fields that will need to be sorted in-memory +function getBasicInMemoryFields(index, selector, userFields) { - // If keys are supplied, issue a POST to circumvent GET query string limits - // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options - if (typeof opts.keys !== 'undefined') { - var MAX_URL_LENGTH = 2000; - // according to http://stackoverflow.com/a/417184/680742, - // the de facto URL length limit is 2000 characters + userFields = sortFieldsByIndex(userFields, index); - var keysAsString = - 'keys=' + encodeURIComponent(JSON.stringify(opts.keys)); - if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) { - // If the keys are short enough, do a GET. we do this to work around - // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239) - params += (params[0] === '?' ? '&' : '?') + keysAsString; - } else { - method = 'POST'; - if (typeof fun === 'string') { - body = {keys: opts.keys}; - } else { // fun is {map : mapfun}, so append to this - fun.keys = opts.keys; - } - } + // check if any of the user selectors lose precision + var needToFilterInMemory = false; + for (var i = 0, len = userFields.length; i < len; i++) { + var field = userFields[i]; + if (needToFilterInMemory || !checkFieldInIndex(index, field)) { + return userFields.slice(i); } - - // We are referencing a query defined in the design doc - if (typeof fun === 'string') { - var parts = parseViewName(fun); - return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, { - headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}), - method: method, - body: JSON.stringify(body) - }).then(function (response) { - ok = response.ok; - status = response.status; - return response.json(); - }).then(function (result) { - if (!ok) { - result.status = status; - throw (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.generateErrorFromResponse)(result); - } - // fail the entire request if the result contains an error - result.rows.forEach(function (row) { - /* istanbul ignore if */ - if (row.value && row.value.error && row.value.error === "builtin_reduce_error") { - throw new Error(row.reason); - } - }); - return result; - }).then(postprocessAttachments(opts)); + if (i < len - 1 && userOperatorLosesPrecision(selector, field)) { + needToFilterInMemory = true; } + } + return []; +} - // We are using a temporary view, terrible for performance, good for testing - body = body || {}; - Object.keys(fun).forEach(function (key) { - if (Array.isArray(fun[key])) { - body[key] = fun[key]; - } else { - body[key] = fun[key].toString(); +function getInMemoryFieldsFromNe(selector) { + var fields = []; + Object.keys(selector).forEach(function (field) { + var matcher = selector[field]; + Object.keys(matcher).forEach(function (operator) { + if (operator === '$ne') { + fields.push(field); } }); + }); + return fields; +} - return db.fetch('_temp_view' + params, { - headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}), - method: 'POST', - body: JSON.stringify(body) - }).then(function (response) { - ok = response.ok; - status = response.status; - return response.json(); - }).then(function (result) { - if (!ok) { - result.status = status; - throw (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.generateErrorFromResponse)(result); - } - return result; - }).then(postprocessAttachments(opts)); - } +function getInMemoryFields(coreInMemoryFields, index, selector, userFields) { + var result = flatten( + // in-memory fields reported as necessary by the query planner + coreInMemoryFields, + // combine with another pass that checks for any we may have missed + getBasicInMemoryFields(index, selector, userFields), + // combine with another pass that checks for $ne's + getInMemoryFieldsFromNe(selector) + ); - // custom adapters can define their own api._query - // and override the default behavior - /* istanbul ignore next */ - function customQuery(db, fun, opts) { - return new Promise(function (resolve, reject) { - db._query(fun, opts, function (err, res) { - if (err) { - return reject(err); - } - resolve(res); - }); - }); + return sortFieldsByIndex(uniq(result), index); +} + +// check that at least one field in the user's query is represented +// in the index. order matters in the case of sorts +function checkIndexFieldsMatch(indexFields, sortOrder, fields) { + if (sortOrder) { + // array has to be a strict subarray of index array. furthermore, + // the sortOrder fields need to all be represented in the index + var sortMatches = oneArrayIsStrictSubArrayOfOther(sortOrder, indexFields); + var selectorMatches = oneArrayIsSubArrayOfOther(fields, indexFields); + + return sortMatches && selectorMatches; } - // custom adapters can define their own api._viewCleanup - // and override the default behavior - /* istanbul ignore next */ - function customViewCleanup(db) { - return new Promise(function (resolve, reject) { - db._viewCleanup(function (err, res) { - if (err) { - return reject(err); - } - resolve(res); - }); - }); + // all of the user's specified fields still need to be + // on the left side of the index array, although the order + // doesn't matter + return oneSetIsSubArrayOfOther(fields, indexFields); +} + +var logicalMatchers = ['$eq', '$gt', '$gte', '$lt', '$lte']; +function isNonLogicalMatcher(matcher) { + return logicalMatchers.indexOf(matcher) === -1; +} + +// check all the index fields for usages of '$ne' +// e.g. if the user queries {foo: {$ne: 'foo'}, bar: {$eq: 'bar'}}, +// then we can neither use an index on ['foo'] nor an index on +// ['foo', 'bar'], but we can use an index on ['bar'] or ['bar', 'foo'] +function checkFieldsLogicallySound(indexFields, selector) { + var firstField = indexFields[0]; + var matcher = selector[firstField]; + + if (typeof matcher === 'undefined') { + /* istanbul ignore next */ + return true; } - function defaultsTo(value) { - return function (reason) { - /* istanbul ignore else */ - if (reason.status === 404) { - return value; - } else { - throw reason; - } - }; + var hasLogicalOperator = Object.keys(matcher).some(function (matcherKey) { + return !(isNonLogicalMatcher(matcherKey)); + }); + + if (!hasLogicalOperator) { + return false; } - // returns a promise for a list of docs to update, based on the input docId. - // the order doesn't matter, because post-3.2.0, bulkDocs - // is an atomic operation in all three adapters. - function getDocsToPersist(docId, view, docIdsToChangesAndEmits) { - var metaDocId = '_local/doc_' + docId; - var defaultMetaDoc = {_id: metaDocId, keys: []}; - var docData = docIdsToChangesAndEmits.get(docId); - var indexableKeysToKeyValues = docData[0]; - var changes = docData[1]; + var isInvalidNe = Object.keys(matcher).length === 1 && + (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(matcher) === '$ne'; - function getMetaDoc() { - if (isGenOne(changes)) { - // generation 1, so we can safely assume initial state - // for performance reasons (avoids unnecessary GETs) - return Promise.resolve(defaultMetaDoc); - } - return view.db.get(metaDocId).catch(defaultsTo(defaultMetaDoc)); - } + return !isInvalidNe; +} - function getKeyValueDocs(metaDoc) { - if (!metaDoc.keys.length) { - // no keys, no need for a lookup - return Promise.resolve({rows: []}); - } - return view.db.allDocs({ - keys: metaDoc.keys, - include_docs: true - }); - } +function checkIndexMatches(index, sortOrder, fields, selector) { - function processKeyValueDocs(metaDoc, kvDocsRes) { - var kvDocs = []; - var oldKeys = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Set(); + var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); - for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) { - var row = kvDocsRes.rows[i]; - var doc = row.doc; - if (!doc) { // deleted - continue; - } - kvDocs.push(doc); - oldKeys.add(doc._id); - doc._deleted = !indexableKeysToKeyValues.has(doc._id); - if (!doc._deleted) { - var keyValue = indexableKeysToKeyValues.get(doc._id); - if ('value' in keyValue) { - doc.value = keyValue.value; - } - } - } - var newKeys = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(indexableKeysToKeyValues); - newKeys.forEach(function (key) { - if (!oldKeys.has(key)) { - // new doc - var kvDoc = { - _id: key - }; - var keyValue = indexableKeysToKeyValues.get(key); - if ('value' in keyValue) { - kvDoc.value = keyValue.value; - } - kvDocs.push(kvDoc); - } - }); - metaDoc.keys = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.uniq)(newKeys.concat(metaDoc.keys)); - kvDocs.push(metaDoc); + var fieldsMatch = checkIndexFieldsMatch(indexFields, sortOrder, fields); - return kvDocs; + if (!fieldsMatch) { + return false; + } + + return checkFieldsLogicallySound(indexFields, selector); +} + +// +// the algorithm is very simple: +// take all the fields the user supplies, and if those fields +// are a strict subset of the fields in some index, +// then use that index +// +// +function findMatchingIndexes(selector, userFields, sortOrder, indexes) { + + return indexes.reduce(function (res, index) { + var indexMatches = checkIndexMatches(index, sortOrder, userFields, selector); + if (indexMatches) { + res.push(index); } + return res; + }, []); +} - return getMetaDoc().then(function (metaDoc) { - return getKeyValueDocs(metaDoc).then(function (kvDocsRes) { - return processKeyValueDocs(metaDoc, kvDocsRes); - }); - }); - } +// find the best index, i.e. the one that matches the most fields +// in the user's query +function findBestMatchingIndex(selector, userFields, sortOrder, indexes, useIndex) { - // updates all emitted key/value docs and metaDocs in the mrview database - // for the given batch of documents from the source database - function saveKeyValues(view, docIdsToChangesAndEmits, seq) { - var seqDocId = '_local/lastSeq'; - return view.db.get(seqDocId) - .catch(defaultsTo({_id: seqDocId, seq: 0})) - .then(function (lastSeqDoc) { - var docIds = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(docIdsToChangesAndEmits); - return Promise.all(docIds.map(function (docId) { - return getDocsToPersist(docId, view, docIdsToChangesAndEmits); - })).then(function (listOfDocsToPersist) { - var docsToPersist = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.flatten)(listOfDocsToPersist); - lastSeqDoc.seq = seq; - docsToPersist.push(lastSeqDoc); - // write all docs in a single operation, update the seq once - return view.db.bulkDocs({docs : docsToPersist}); - }); - }); - } + var matchingIndexes = findMatchingIndexes(selector, userFields, sortOrder, indexes); - function getQueue(view) { - var viewName = typeof view === 'string' ? view : view.name; - var queue = persistentQueues[viewName]; - if (!queue) { - queue = persistentQueues[viewName] = new TaskQueue(); + if (matchingIndexes.length === 0) { + if (useIndex) { + throw { + error: "no_usable_index", + message: "There is no index available for this selector." + }; } - return queue; + //return `all_docs` as a default index; + //I'm assuming that _all_docs is always first + var defaultIndex = indexes[0]; + defaultIndex.defaultUsed = true; + return defaultIndex; } - - function updateView(view) { - return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(view), function () { - return updateViewInQueue(view); - })(); + if (matchingIndexes.length === 1 && !useIndex) { + return matchingIndexes[0]; } - function updateViewInQueue(view) { - // bind the emit function once - var mapResults; - var doc; + var userFieldsMap = arrayToObject(userFields); - function emit(key, value) { - var output = {id: doc._id, key: (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.normalizeKey)(key)}; - // Don't explicitly store the value unless it's defined and non-null. - // This saves on storage space, because often people don't use it. - if (typeof value !== 'undefined' && value !== null) { - output.value = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.normalizeKey)(value); + function scoreIndex(index) { + var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); + var score = 0; + for (var i = 0, len = indexFields.length; i < len; i++) { + var indexField = indexFields[i]; + if (userFieldsMap[indexField]) { + score++; } - mapResults.push(output); } + return score; + } - var mapFun = mapper(view.mapFun, emit); + if (useIndex) { + var useIndexDdoc = '_design/' + useIndex[0]; + var useIndexName = useIndex.length === 2 ? useIndex[1] : false; + var index = matchingIndexes.find(function (index) { + if (useIndexName && index.ddoc === useIndexDdoc && useIndexName === index.name) { + return true; + } - var currentSeq = view.seq || 0; + if (index.ddoc === useIndexDdoc) { + /* istanbul ignore next */ + return true; + } - function processChange(docIdsToChangesAndEmits, seq) { - return function () { - return saveKeyValues(view, docIdsToChangesAndEmits, seq); + return false; + }); + + if (!index) { + throw { + error: "unknown_error", + message: "Could not find that index or could not use that index for the query" }; } + return index; + } - var queue = new TaskQueue(); + return max(matchingIndexes, scoreIndex); +} - function processNextBatch() { - return view.sourceDB.changes({ - return_docs: true, - conflicts: true, - include_docs: true, - style: 'all_docs', - since: currentSeq, - limit: CHANGES_BATCH_SIZE - }).then(processBatch); - } +function getSingleFieldQueryOptsFor(userOperator, userValue) { + switch (userOperator) { + case '$eq': + return {key: userValue}; + case '$lte': + return {endkey: userValue}; + case '$gte': + return {startkey: userValue}; + case '$lt': + return { + endkey: userValue, + inclusive_end: false + }; + case '$gt': + return { + startkey: userValue, + inclusive_start: false + }; + } +} - function processBatch(response) { - var results = response.results; - if (!results.length) { - return; - } - var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results); - queue.add(processChange(docIdsToChangesAndEmits, currentSeq)); - if (results.length < CHANGES_BATCH_SIZE) { - return; - } - return processNextBatch(); - } +function getSingleFieldCoreQueryPlan(selector, index) { + var field = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey)(index.def.fields[0]); + //ignoring this because the test to exercise the branch is skipped at the moment + /* istanbul ignore next */ + var matcher = selector[field] || {}; + var inMemoryFields = []; - function createDocIdsToChangesAndEmits(results) { - var docIdsToChangesAndEmits = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); - for (var i = 0, len = results.length; i < len; i++) { - var change = results[i]; - if (change.doc._id[0] !== '_') { - mapResults = []; - doc = change.doc; + var userOperators = Object.keys(matcher); - if (!doc._deleted) { - tryMap(view.sourceDB, mapFun, doc); - } - mapResults.sort(sortByKeyThenValue); + var combinedOpts; - var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults); - docIdsToChangesAndEmits.set(change.doc._id, [ - indexableKeysToKeyValues, - change.changes - ]); - } - currentSeq = change.seq; - } - return docIdsToChangesAndEmits; + userOperators.forEach(function (userOperator) { + + if (isNonLogicalMatcher(userOperator)) { + inMemoryFields.push(field); + return; } - function createIndexableKeysToKeyValues(mapResults) { - var indexableKeysToKeyValues = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); - var lastKey; - for (var i = 0, len = mapResults.length; i < len; i++) { - var emittedKeyValue = mapResults[i]; - var complexKey = [emittedKeyValue.key, emittedKeyValue.id]; - if (i > 0 && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(emittedKeyValue.key, lastKey) === 0) { - complexKey.push(i); // dup key+id, so make it unique - } - indexableKeysToKeyValues.set((0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)(complexKey), emittedKeyValue); - lastKey = emittedKeyValue.key; - } - return indexableKeysToKeyValues; + var userValue = matcher[userOperator]; + + var newQueryOpts = getSingleFieldQueryOptsFor(userOperator, userValue); + + if (combinedOpts) { + combinedOpts = mergeObjects([combinedOpts, newQueryOpts]); + } else { + combinedOpts = newQueryOpts; } + }); - return processNextBatch().then(function () { - return queue.finish(); - }).then(function () { - view.seq = currentSeq; - }); + return { + queryOpts: combinedOpts, + inMemoryFields: inMemoryFields + }; +} + +function getMultiFieldCoreQueryPlan(userOperator, userValue) { + switch (userOperator) { + case '$eq': + return { + startkey: userValue, + endkey: userValue + }; + case '$lte': + return { + endkey: userValue + }; + case '$gte': + return { + startkey: userValue + }; + case '$lt': + return { + endkey: userValue, + inclusive_end: false + }; + case '$gt': + return { + startkey: userValue, + inclusive_start: false + }; } +} - function reduceView(view, results, options) { - if (options.group_level === 0) { - delete options.group_level; - } +function getMultiFieldQueryOpts(selector, index) { - var shouldGroup = options.group || options.group_level; + var indexFields = index.def.fields.map(pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getKey); - var reduceFun = reducer(view.reduceFun); + var inMemoryFields = []; + var startkey = []; + var endkey = []; + var inclusiveStart; + var inclusiveEnd; - var groups = []; - var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY : - options.group_level; - results.forEach(function (e) { - var last = groups[groups.length - 1]; - var groupKey = shouldGroup ? e.key : null; - // only set group_level for array keys - if (shouldGroup && Array.isArray(groupKey)) { - groupKey = groupKey.slice(0, lvl); - } + function finish(i) { - if (last && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(last.groupKey, groupKey) === 0) { - last.keys.push([e.key, e.id]); - last.values.push(e.value); - return; - } - groups.push({ - keys: [[e.key, e.id]], - values: [e.value], - groupKey: groupKey - }); - }); - results = []; - for (var i = 0, len = groups.length; i < len; i++) { - var e = groups[i]; - var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false); - if (reduceTry.error && reduceTry.error instanceof pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.BuiltInError) { - // CouchDB returns an error if a built-in errors out - throw reduceTry.error; - } - results.push({ - // CouchDB just sets the value to null if a non-built-in errors out - value: reduceTry.error ? null : reduceTry.output, - key: e.groupKey - }); + if (inclusiveStart !== false) { + startkey.push(COLLATE_LO); } - // no total_rows/offset when reducing - return {rows: sliceResults(results, options.limit, options.skip)}; + if (inclusiveEnd !== false) { + endkey.push(COLLATE_HI); + } + // keep track of the fields where we lost specificity, + // and therefore need to filter in-memory + inMemoryFields = indexFields.slice(i); } - function queryView(view, opts) { - return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(view), function () { - return queryViewInQueue(view, opts); - })(); - } + for (var i = 0, len = indexFields.length; i < len; i++) { + var indexField = indexFields[i]; - function queryViewInQueue(view, opts) { - var totalRows; - var shouldReduce = view.reduceFun && opts.reduce !== false; - var skip = opts.skip || 0; - if (typeof opts.keys !== 'undefined' && !opts.keys.length) { - // equivalent query - opts.limit = 0; - delete opts.keys; + var matcher = selector[indexField]; + + if (!matcher || !Object.keys(matcher).length) { // fewer fields in user query than in index + finish(i); + break; + } else if (i > 0) { + if (Object.keys(matcher).some(isNonLogicalMatcher)) { // non-logical are ignored + finish(i); + break; + } + var usingGtlt = ( + '$gt' in matcher || '$gte' in matcher || + '$lt' in matcher || '$lte' in matcher); + var previousKeys = Object.keys(selector[indexFields[i - 1]]); + var previousWasEq = arrayEquals(previousKeys, ['$eq']); + var previousWasSame = arrayEquals(previousKeys, Object.keys(matcher)); + var gtltLostSpecificity = usingGtlt && !previousWasEq && !previousWasSame; + if (gtltLostSpecificity) { + finish(i); + break; + } } - function fetchFromView(viewOpts) { - viewOpts.include_docs = true; - return view.db.allDocs(viewOpts).then(function (res) { - totalRows = res.total_rows; - return res.rows.map(function (result) { + var userOperators = Object.keys(matcher); - // implicit migration - in older versions of PouchDB, - // we explicitly stored the doc as {id: ..., key: ..., value: ...} - // this is tested in a migration test - /* istanbul ignore next */ - if ('value' in result.doc && typeof result.doc.value === 'object' && - result.doc.value !== null) { - var keys = Object.keys(result.doc.value).sort(); - // this detection method is not perfect, but it's unlikely the user - // emitted a value which was an object with these 3 exact keys - var expectedKeys = ['id', 'key', 'value']; - if (!(keys < expectedKeys || keys > expectedKeys)) { - return result.doc.value; - } - } + var combinedOpts = null; - var parsedKeyAndDocId = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.parseIndexableString)(result.doc._id); - return { - key: parsedKeyAndDocId[0], - id: parsedKeyAndDocId[1], - value: ('value' in result.doc ? result.doc.value : null) - }; - }); - }); - } + for (var j = 0; j < userOperators.length; j++) { + var userOperator = userOperators[j]; + var userValue = matcher[userOperator]; - function onMapResultsReady(rows) { - var finalResults; - if (shouldReduce) { - finalResults = reduceView(view, rows, opts); - } else { - finalResults = { - total_rows: totalRows, - offset: skip, - rows: rows - }; - } - /* istanbul ignore if */ - if (opts.update_seq) { - finalResults.update_seq = view.seq; - } - if (opts.include_docs) { - var docIds = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.uniq)(rows.map(rowToDocId)); + var newOpts = getMultiFieldCoreQueryPlan(userOperator, userValue); - return view.sourceDB.allDocs({ - keys: docIds, - include_docs: true, - conflicts: opts.conflicts, - attachments: opts.attachments, - binary: opts.binary - }).then(function (allDocsRes) { - var docIdsToDocs = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); - allDocsRes.rows.forEach(function (row) { - docIdsToDocs.set(row.id, row.doc); - }); - rows.forEach(function (row) { - var docId = rowToDocId(row); - var doc = docIdsToDocs.get(docId); - if (doc) { - row.doc = doc; - } - }); - return finalResults; - }); + if (combinedOpts) { + combinedOpts = mergeObjects([combinedOpts, newOpts]); } else { - return finalResults; + combinedOpts = newOpts; } } - if (typeof opts.keys !== 'undefined') { - var keys = opts.keys; - var fetchPromises = keys.map(function (key) { - var viewOpts = { - startkey : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([key]), - endkey : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([key, {}]) - }; - /* istanbul ignore if */ - if (opts.update_seq) { - viewOpts.update_seq = true; - } - return fetchFromView(viewOpts); - }); - return Promise.all(fetchPromises).then(pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.flatten).then(onMapResultsReady); - } else { // normal query, no 'keys' - var viewOpts = { - descending : opts.descending - }; - /* istanbul ignore if */ - if (opts.update_seq) { - viewOpts.update_seq = true; - } - var startkey; - var endkey; - if ('start_key' in opts) { - startkey = opts.start_key; - } - if ('startkey' in opts) { - startkey = opts.startkey; - } - if ('end_key' in opts) { - endkey = opts.end_key; - } - if ('endkey' in opts) { - endkey = opts.endkey; - } - if (typeof startkey !== 'undefined') { - viewOpts.startkey = opts.descending ? - (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([startkey, {}]) : - (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([startkey]); - } - if (typeof endkey !== 'undefined') { - var inclusiveEnd = opts.inclusive_end !== false; - if (opts.descending) { - inclusiveEnd = !inclusiveEnd; - } - - viewOpts.endkey = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)( - inclusiveEnd ? [endkey, {}] : [endkey]); - } - if (typeof opts.key !== 'undefined') { - var keyStart = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([opts.key]); - var keyEnd = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([opts.key, {}]); - if (viewOpts.descending) { - viewOpts.endkey = keyStart; - viewOpts.startkey = keyEnd; - } else { - viewOpts.startkey = keyStart; - viewOpts.endkey = keyEnd; - } - } - if (!shouldReduce) { - if (typeof opts.limit === 'number') { - viewOpts.limit = opts.limit; - } - viewOpts.skip = skip; - } - return fetchFromView(viewOpts).then(onMapResultsReady); + startkey.push('startkey' in combinedOpts ? combinedOpts.startkey : COLLATE_LO); + endkey.push('endkey' in combinedOpts ? combinedOpts.endkey : COLLATE_HI); + if ('inclusive_start' in combinedOpts) { + inclusiveStart = combinedOpts.inclusive_start; + } + if ('inclusive_end' in combinedOpts) { + inclusiveEnd = combinedOpts.inclusive_end; } } - function httpViewCleanup(db) { - return db.fetch('_view_cleanup', { - headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}), - method: 'POST' - }).then(function (response) { - return response.json(); - }); - } + var res = { + startkey: startkey, + endkey: endkey + }; - function localViewCleanup(db) { - return db.get('_local/' + localDocName).then(function (metaDoc) { - var docsToViews = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); - Object.keys(metaDoc.views).forEach(function (fullViewName) { - var parts = parseViewName(fullViewName); - var designDocName = '_design/' + parts[0]; - var viewName = parts[1]; - var views = docsToViews.get(designDocName); - if (!views) { - views = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Set(); - docsToViews.set(designDocName, views); - } - views.add(viewName); - }); - var opts = { - keys : (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(docsToViews), - include_docs : true - }; - return db.allDocs(opts).then(function (res) { - var viewsToStatus = {}; - res.rows.forEach(function (row) { - var ddocName = row.key.substring(8); // cuts off '_design/' - docsToViews.get(row.key).forEach(function (viewName) { - var fullViewName = ddocName + '/' + viewName; - /* istanbul ignore if */ - if (!metaDoc.views[fullViewName]) { - // new format, without slashes, to support PouchDB 2.2.0 - // migration test in pouchdb's browser.migration.js verifies this - fullViewName = viewName; - } - var viewDBNames = Object.keys(metaDoc.views[fullViewName]); - // design doc deleted, or view function nonexistent - var statusIsGood = row.doc && row.doc.views && - row.doc.views[viewName]; - viewDBNames.forEach(function (viewDBName) { - viewsToStatus[viewDBName] = - viewsToStatus[viewDBName] || statusIsGood; - }); - }); - }); - var dbsToDelete = Object.keys(viewsToStatus).filter( - function (viewDBName) { return !viewsToStatus[viewDBName]; }); - var destroyPromises = dbsToDelete.map(function (viewDBName) { - return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(viewDBName), function () { - return new db.constructor(viewDBName, db.__opts).destroy(); - })(); - }); - return Promise.all(destroyPromises).then(function () { - return {ok: true}; - }); - }); - }, defaultsTo({ok: true})); + if (typeof inclusiveStart !== 'undefined') { + res.inclusive_start = inclusiveStart; + } + if (typeof inclusiveEnd !== 'undefined') { + res.inclusive_end = inclusiveEnd; } - function queryPromised(db, fun, opts) { - /* istanbul ignore next */ - if (typeof db._query === 'function') { - return customQuery(db, fun, opts); - } - if ((0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(db)) { - return httpQuery(db, fun, opts); - } - - if (typeof fun !== 'string') { - // temp_view - checkQueryParseError(opts, fun); - - tempViewQueue.add(function () { - var createViewPromise = createView( - /* sourceDB */ db, - /* viewName */ 'temp_view/temp_view', - /* mapFun */ fun.map, - /* reduceFun */ fun.reduce, - /* temporary */ true, - /* localDocName */ localDocName); - return createViewPromise.then(function (view) { - return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.fin)(updateView(view).then(function () { - return queryView(view, opts); - }), function () { - return view.db.destroy(); - }); - }); - }); - return tempViewQueue.finish(); - } else { - // persistent view - var fullViewName = fun; - var parts = parseViewName(fullViewName); - var designDocName = parts[0]; - var viewName = parts[1]; - return db.get('_design/' + designDocName).then(function (doc) { - var fun = doc.views && doc.views[viewName]; + return { + queryOpts: res, + inMemoryFields: inMemoryFields + }; +} - if (!fun) { - // basic validator; it's assumed that every subclass would want this - throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.NotFoundError('ddoc ' + doc._id + ' has no view named ' + - viewName); - } +function getDefaultQueryPlan(selector) { + //using default index, so all fields need to be done in memory + return { + queryOpts: {startkey: null}, + inMemoryFields: [Object.keys(selector)] + }; +} - ddocValidator(doc, viewName); - checkQueryParseError(opts, fun); +function getCoreQueryPlan(selector, index) { + if (index.defaultUsed) { + return getDefaultQueryPlan(selector, index); + } - var createViewPromise = createView( - /* sourceDB */ db, - /* viewName */ fullViewName, - /* mapFun */ fun.map, - /* reduceFun */ fun.reduce, - /* temporary */ false, - /* localDocName */ localDocName); - return createViewPromise.then(function (view) { - if (opts.stale === 'ok' || opts.stale === 'update_after') { - if (opts.stale === 'update_after') { - (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () { - updateView(view); - }); - } - return queryView(view, opts); - } else { // stale not ok - return updateView(view).then(function () { - return queryView(view, opts); - }); - } - }); - }); - } + if (index.def.fields.length === 1) { + // one field in index, so the value was indexed as a singleton + return getSingleFieldCoreQueryPlan(selector, index); } + // else index has multiple fields, so the value was indexed as an array + return getMultiFieldQueryOpts(selector, index); +} - function abstractQuery(fun, opts, callback) { - var db = this; - if (typeof opts === 'function') { - callback = opts; - opts = {}; - } - opts = opts ? coerceOptions(opts) : {}; +function planQuery(request, indexes) { - if (typeof fun === 'function') { - fun = {map : fun}; - } + var selector = request.selector; + var sort = request.sort; - var promise = Promise.resolve().then(function () { - return queryPromised(db, fun, opts); - }); - (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.promisedCallback)(promise, callback); - return promise; - } + var userFieldsRes = getUserFields(selector, sort); - var abstractViewCleanup = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.callbackify)(function () { - var db = this; - /* istanbul ignore next */ - if (typeof db._viewCleanup === 'function') { - return customViewCleanup(db); - } - if ((0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(db)) { - return httpViewCleanup(db); - } - return localViewCleanup(db); - }); + var userFields = userFieldsRes.fields; + var sortOrder = userFieldsRes.sortOrder; + var index = findBestMatchingIndex(selector, userFields, sortOrder, indexes, request.use_index); - return { - query: abstractQuery, - viewCleanup: abstractViewCleanup - }; -} + var coreQueryPlan = getCoreQueryPlan(selector, index); + var queryOpts = coreQueryPlan.queryOpts; + var coreInMemoryFields = coreQueryPlan.inMemoryFields; -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createAbstractMapReduce); + var inMemoryFields = getInMemoryFields(coreInMemoryFields, index, selector, userFields); + var res = { + queryOpts: queryOpts, + index: index, + inMemoryFields: inMemoryFields + }; + return res; +} -/***/ }), -/* 506 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +function indexToSignature(index) { + // remove '_design/' + return index.ddoc.substring(8) + '/' + index.name; +} -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "atob": () => (/* binding */ thisAtob), -/* harmony export */ "btoa": () => (/* binding */ thisBtoa), -/* harmony export */ "base64StringToBlobOrBuffer": () => (/* binding */ b64ToBluffer), -/* harmony export */ "binaryStringToArrayBuffer": () => (/* binding */ binaryStringToArrayBuffer), -/* harmony export */ "binaryStringToBlobOrBuffer": () => (/* binding */ binStringToBluffer), -/* harmony export */ "blob": () => (/* binding */ createBlob), -/* harmony export */ "blobOrBufferToBase64": () => (/* binding */ blobToBase64), -/* harmony export */ "blobOrBufferToBinaryString": () => (/* binding */ blobToBase64$1), -/* harmony export */ "readAsArrayBuffer": () => (/* binding */ readAsArrayBuffer), -/* harmony export */ "readAsBinaryString": () => (/* binding */ readAsBinaryString), -/* harmony export */ "typedBuffer": () => (/* binding */ typedBuffer) -/* harmony export */ }); -/* harmony import */ var buffer_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507); -/* harmony import */ var buffer_from__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(buffer_from__WEBPACK_IMPORTED_MODULE_0__); +function doAllDocs(db, originalOpts) { + var opts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(originalOpts); + // CouchDB responds in weird ways when you provide a non-string to _id; + // we mimic the behavior for consistency. See issue66 tests for details. -function thisAtob(str) { - var base64 = new Buffer(str, 'base64'); - // Node.js will just skip the characters it can't decode instead of - // throwing an exception - if (base64.toString('base64') !== str) { - throw new Error("attachment is not a valid base64 string"); + if (opts.descending) { + if ('endkey' in opts && typeof opts.endkey !== 'string') { + opts.endkey = ''; + } + if ('startkey' in opts && typeof opts.startkey !== 'string') { + opts.limit = 0; + } + } else { + if ('startkey' in opts && typeof opts.startkey !== 'string') { + opts.startkey = ''; + } + if ('endkey' in opts && typeof opts.endkey !== 'string') { + opts.limit = 0; + } + } + if ('key' in opts && typeof opts.key !== 'string') { + opts.limit = 0; } - return base64.toString('binary'); -} -function thisBtoa(str) { - return buffer_from__WEBPACK_IMPORTED_MODULE_0___default()(str, 'binary').toString('base64'); + return db.allDocs(opts) + .then(function (res) { + // filter out any design docs that _all_docs might return + res.rows = res.rows.filter(function (row) { + return !/^_design\//.test(row.id); + }); + return res; + }); } -function typedBuffer(binString, buffType, type) { - // buffType is either 'binary' or 'base64' - var buff = buffer_from__WEBPACK_IMPORTED_MODULE_0___default()(binString, buffType); - buff.type = type; // non-standard, but used for consistency with the browser - return buff; -} +function find$1(db, requestDef, explain) { + if (requestDef.selector) { + requestDef.selector = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.massageSelector)(requestDef.selector); + } -function b64ToBluffer(b64, type) { - return typedBuffer(b64, 'base64', type); -} + if (requestDef.sort) { + requestDef.sort = massageSort(requestDef.sort); + } -// From http://stackoverflow.com/questions/14967647/ (continues on next line) -// encode-decode-image-with-base64-breaks-image (2013-04-21) -function binaryStringToArrayBuffer(bin) { - var length = bin.length; - var buf = new ArrayBuffer(length); - var arr = new Uint8Array(buf); - for (var i = 0; i < length; i++) { - arr[i] = bin.charCodeAt(i); + if (requestDef.use_index) { + requestDef.use_index = massageUseIndex(requestDef.use_index); } - return buf; -} -function binStringToBluffer(binString, type) { - return typedBuffer(binString, 'binary', type); -} + validateFindRequest(requestDef); -// This function is unused in Node -/* istanbul ignore next */ -function createBlob() { -} + return getIndexes$1(db).then(function (getIndexesRes) { -function blobToBase64(blobOrBuffer, callback) { - callback(blobOrBuffer.toString('base64')); -} + db.constructor.emit('debug', ['find', 'planning query', requestDef]); + var queryPlan = planQuery(requestDef, getIndexesRes.indexes); + db.constructor.emit('debug', ['find', 'query plan', queryPlan]); -// not used in Node, but here for completeness -function blobToBase64$1(blobOrBuffer, callback) { - callback(blobOrBuffer.toString('binary')); -} + var indexToUse = queryPlan.index; -// simplified API. universal browser support is assumed -function readAsArrayBuffer(blob, callback) { - var reader = new FileReader(); - reader.onloadend = function (e) { - var result = e.target.result || new ArrayBuffer(0); - callback(result); - }; - reader.readAsArrayBuffer(blob); -} + validateSort(requestDef, indexToUse); -//Can't find original post, but this is close -//http://stackoverflow.com/questions/6965107/ (continues on next line) -//converting-between-strings-and-arraybuffers -function arrayBufferToBinaryString(buffer) { - var binary = ''; - var bytes = new Uint8Array(buffer); - var length = bytes.byteLength; - for (var i = 0; i < length; i++) { - binary += String.fromCharCode(bytes[i]); - } - return binary; -} + var opts = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.assign)({ + include_docs: true, + reduce: false + }, queryPlan.queryOpts); -// shim for browsers that don't support it -function readAsBinaryString(blob, callback) { - var reader = new FileReader(); - var hasBinaryString = typeof reader.readAsBinaryString === 'function'; - reader.onloadend = function (e) { - var result = e.target.result || ''; - if (hasBinaryString) { - return callback(result); + if ('startkey' in opts && 'endkey' in opts && + (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_5__.collate)(opts.startkey, opts.endkey) > 0) { + // can't possibly return any results, startkey > endkey + /* istanbul ignore next */ + return {docs: []}; } - callback(arrayBufferToBinaryString(result)); - }; - if (hasBinaryString) { - reader.readAsBinaryString(blob); - } else { - reader.readAsArrayBuffer(blob); - } -} + var isDescending = requestDef.sort && + typeof requestDef.sort[0] !== 'string' && + (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.getValue)(requestDef.sort[0]) === 'desc'; + if (isDescending) { + // either all descending or all ascending + opts.descending = true; + opts = reverseOptions(opts); + } + if (!queryPlan.inMemoryFields.length) { + // no in-memory filtering necessary, so we can let the + // database do the limit/skip for us + if ('limit' in requestDef) { + opts.limit = requestDef.limit; + } + if ('skip' in requestDef) { + opts.skip = requestDef.skip; + } + } -/***/ }), -/* 507 */ -/***/ ((module) => { + if (explain) { + return Promise.resolve(queryPlan, opts); + } -var toString = Object.prototype.toString + return Promise.resolve().then(function () { + if (indexToUse.name === '_all_docs') { + return doAllDocs(db, opts); + } else { + var signature = indexToSignature(indexToUse); + return abstractMapper.query.call(db, signature, opts); + } + }).then(function (res) { + if (opts.inclusive_start === false) { + // may have to manually filter the first one, + // since couchdb has no true inclusive_start option + res.rows = filterInclusiveStart(res.rows, opts.startkey, indexToUse); + } -var isModern = ( - typeof Buffer.alloc === 'function' && - typeof Buffer.allocUnsafe === 'function' && - typeof Buffer.from === 'function' -) + if (queryPlan.inMemoryFields.length) { + // need to filter some stuff in-memory + res.rows = (0,pouchdb_selector_core__WEBPACK_IMPORTED_MODULE_3__.filterInMemoryFields)(res.rows, requestDef, queryPlan.inMemoryFields); + } -function isArrayBuffer (input) { - return toString.call(input).slice(8, -1) === 'ArrayBuffer' + var resp = { + docs: res.rows.map(function (row) { + var doc = row.doc; + if (requestDef.fields) { + return pick(doc, requestDef.fields); + } + return doc; + }) + }; + + if (indexToUse.defaultUsed) { + resp.warning = 'no matching index found, create an index to optimize query time'; + } + + return resp; + }); + }); } -function fromArrayBuffer (obj, byteOffset, length) { - byteOffset >>>= 0 +function explain$1(db, requestDef) { + return find$1(db, requestDef, true) + .then(function (queryPlan) { + return { + dbname: db.name, + index: queryPlan.index, + selector: requestDef.selector, + range: { + start_key: queryPlan.queryOpts.startkey, + end_key: queryPlan.queryOpts.endkey, + }, + opts: { + use_index: requestDef.use_index || [], + bookmark: "nil", //hardcoded to match CouchDB since its not supported, + limit: requestDef.limit, + skip: requestDef.skip, + sort: requestDef.sort || {}, + fields: requestDef.fields, + conflicts: false, //hardcoded to match CouchDB since its not supported, + r: [49], // hardcoded to match CouchDB since its not support + }, + limit: requestDef.limit, + skip: requestDef.skip || 0, + fields: requestDef.fields, + }; + }); +} - var maxLength = obj.byteLength - byteOffset +function deleteIndex$1(db, index) { - if (maxLength < 0) { - throw new RangeError("'offset' is out of bounds") + if (!index.ddoc) { + throw new Error('you must supply an index.ddoc when deleting'); } - if (length === undefined) { - length = maxLength - } else { - length >>>= 0 + if (!index.name) { + throw new Error('you must supply an index.name when deleting'); + } - if (length > maxLength) { - throw new RangeError("'length' is out of bounds") + var docId = index.ddoc; + var viewName = index.name; + + function deltaFun(doc) { + if (Object.keys(doc.views).length === 1 && doc.views[viewName]) { + // only one view in this ddoc, delete the whole ddoc + return {_id: docId, _deleted: true}; } + // more than one view here, just remove the view + delete doc.views[viewName]; + return doc; } - return isModern - ? Buffer.from(obj.slice(byteOffset, byteOffset + length)) - : new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length))) + return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(db, docId, deltaFun).then(function () { + return abstractMapper.viewCleanup.apply(db); + }).then(function () { + return {ok: true}; + }); } -function fromString (string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8' +var createIndexAsCallback = callbackify(createIndex$1); +var findAsCallback = callbackify(find$1); +var explainAsCallback = callbackify(explain$1); +var getIndexesAsCallback = callbackify(getIndexes$1); +var deleteIndexAsCallback = callbackify(deleteIndex$1); + +var plugin = {}; +plugin.createIndex = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) { + + if (typeof requestDef !== 'object') { + return callback(new Error('you must provide an index to create')); } - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') + var createIndex$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? + createIndex : createIndexAsCallback; + createIndex$$1(this, requestDef, callback); +}); + +plugin.find = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) { + + if (typeof callback === 'undefined') { + callback = requestDef; + requestDef = undefined; } - return isModern - ? Buffer.from(string, encoding) - : new Buffer(string, encoding) -} + if (typeof requestDef !== 'object') { + return callback(new Error('you must provide search parameters to find()')); + } -function bufferFrom (value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') + var find$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? find : findAsCallback; + find$$1(this, requestDef, callback); +}); + +plugin.explain = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (requestDef, callback) { + + if (typeof callback === 'undefined') { + callback = requestDef; + requestDef = undefined; } - if (isArrayBuffer(value)) { - return fromArrayBuffer(value, encodingOrOffset, length) + if (typeof requestDef !== 'object') { + return callback(new Error('you must provide search parameters to explain()')); } - if (typeof value === 'string') { - return fromString(value, encodingOrOffset) + var find$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? explain : explainAsCallback; + find$$1(this, requestDef, callback); +}); + +plugin.getIndexes = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (callback) { + + var getIndexes$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? getIndexes : getIndexesAsCallback; + getIndexes$$1(this, callback); +}); + +plugin.deleteIndex = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.toPromise)(function (indexDef, callback) { + + if (typeof indexDef !== 'object') { + return callback(new Error('you must provide an index to delete')); } - return isModern - ? Buffer.from(value) - : new Buffer(value) -} + var deleteIndex$$1 = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(this) ? + deleteIndex : deleteIndexAsCallback; + deleteIndex$$1(this, indexDef, callback); +}); -module.exports = bufferFrom +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (plugin); /***/ }), -/* 508 */ +/* 507 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "uniq": () => (/* binding */ uniq), -/* harmony export */ "sequentialize": () => (/* binding */ sequentialize), -/* harmony export */ "fin": () => (/* binding */ fin), -/* harmony export */ "callbackify": () => (/* binding */ callbackify), -/* harmony export */ "promisedCallback": () => (/* binding */ promisedCallback), -/* harmony export */ "mapToKeysArray": () => (/* binding */ mapToKeysArray), -/* harmony export */ "QueryParseError": () => (/* binding */ QueryParseError), -/* harmony export */ "NotFoundError": () => (/* binding */ NotFoundError), -/* harmony export */ "BuiltInError": () => (/* binding */ BuiltInError) +/* harmony export */ "adapterFun": () => (/* binding */ adapterFun), +/* harmony export */ "assign": () => (/* binding */ assign$1), +/* harmony export */ "bulkGetShim": () => (/* binding */ bulkGet), +/* harmony export */ "changesHandler": () => (/* binding */ Changes), +/* harmony export */ "clone": () => (/* binding */ clone$1), +/* harmony export */ "defaultBackOff": () => (/* binding */ defaultBackOff), +/* harmony export */ "explainError": () => (/* binding */ res), +/* harmony export */ "filterChange": () => (/* binding */ filterChange), +/* harmony export */ "flatten": () => (/* binding */ flatten), +/* harmony export */ "functionName": () => (/* binding */ res$2), +/* harmony export */ "guardedConsole": () => (/* binding */ guardedConsole), +/* harmony export */ "hasLocalStorage": () => (/* binding */ hasLocalStorage), +/* harmony export */ "invalidIdError": () => (/* binding */ invalidIdError), +/* harmony export */ "isRemote": () => (/* binding */ isRemote), +/* harmony export */ "listenerCount": () => (/* binding */ listenerCount), +/* harmony export */ "nextTick": () => (/* binding */ nextTick), +/* harmony export */ "normalizeDdocFunctionName": () => (/* binding */ normalizeDesignDocFunctionName), +/* harmony export */ "once": () => (/* binding */ once), +/* harmony export */ "parseDdocFunctionName": () => (/* binding */ parseDesignDocFunctionName), +/* harmony export */ "parseUri": () => (/* binding */ parseUri), +/* harmony export */ "pick": () => (/* binding */ pick), +/* harmony export */ "rev": () => (/* binding */ rev), +/* harmony export */ "scopeEval": () => (/* binding */ scopeEval), +/* harmony export */ "toPromise": () => (/* binding */ toPromise), +/* harmony export */ "upsert": () => (/* binding */ upsert), +/* harmony export */ "uuid": () => (/* binding */ uuid) /* harmony export */ }); -/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(485); -/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(497); -/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(483); -/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(495); +/* harmony import */ var clone_buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(508); +/* harmony import */ var clone_buffer__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(clone_buffer__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(495); +/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(509); +/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(250); +/* harmony import */ var events__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(events__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(497); +/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_4__); +/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(510); +/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(500); +/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(511); +/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(507); -function QueryParseError(message) { - this.status = 400; - this.name = 'query_parse_error'; - this.message = message; - this.error = true; - try { - Error.captureStackTrace(this, QueryParseError); - } catch (e) {} -} -inherits__WEBPACK_IMPORTED_MODULE_0___default()(QueryParseError, Error); -function NotFoundError(message) { - this.status = 404; - this.name = 'not_found'; - this.message = message; - this.error = true; - try { - Error.captureStackTrace(this, NotFoundError); - } catch (e) {} + + + +function isBinaryObject(object) { + return object instanceof Buffer; } -inherits__WEBPACK_IMPORTED_MODULE_0___default()(NotFoundError, Error); +// most of this is borrowed from lodash.isPlainObject: +// https://github.com/fis-components/lodash.isplainobject/ +// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js -function BuiltInError(message) { - this.status = 500; - this.name = 'invalid_value'; - this.message = message; - this.error = true; - try { - Error.captureStackTrace(this, BuiltInError); - } catch (e) {} +var funcToString = Function.prototype.toString; +var objectCtorString = funcToString.call(Object); + +function isPlainObject(value) { + var proto = Object.getPrototypeOf(value); + /* istanbul ignore if */ + if (proto === null) { // not sure when this happens, but I guess it can + return true; + } + var Ctor = proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); } -inherits__WEBPACK_IMPORTED_MODULE_0___default()(BuiltInError, Error); +function clone$1(object) { + var newObject; + var i; + var len; -function promisedCallback(promise, callback) { - if (callback) { - promise.then(function (res) { - (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__.nextTick)(function () { - callback(null, res); - }); - }, function (reason) { - (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__.nextTick)(function () { - callback(reason); - }); - }); + if (!object || typeof object !== 'object') { + return object; } - return promise; + + if (Array.isArray(object)) { + newObject = []; + for (i = 0, len = object.length; i < len; i++) { + newObject[i] = clone$1(object[i]); + } + return newObject; + } + + // special case: to avoid inconsistencies between IndexedDB + // and other backends, we automatically stringify Dates + if (object instanceof Date) { + return object.toISOString(); + } + + if (isBinaryObject(object)) { + return clone_buffer__WEBPACK_IMPORTED_MODULE_0___default()(object); + } + + if (!isPlainObject(object)) { + return object; // don't clone objects like Workers + } + + newObject = {}; + for (i in object) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(object, i)) { + var value = clone$1(object[i]); + if (typeof value !== 'undefined') { + newObject[i] = value; + } + } + } + return newObject; } -function callbackify(fun) { - return argsarray__WEBPACK_IMPORTED_MODULE_2___default()(function (args) { - var cb = args.pop(); - var promise = fun.apply(this, args); - if (typeof cb === 'function') { - promisedCallback(promise, cb); +function once(fun) { + var called = false; + return argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) { + /* istanbul ignore if */ + if (called) { + // this is a smoke test and should never actually happen + throw new Error('once called more than once'); + } else { + called = true; + fun.apply(this, args); } - return promise; }); } -// Promise finally util similar to Q.finally -function fin(promise, finalPromiseFactory) { - return promise.then(function (res) { - return finalPromiseFactory().then(function () { - return res; - }); - }, function (reason) { - return finalPromiseFactory().then(function () { - throw reason; +function toPromise(func) { + //create the function we will be returning + return argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) { + // Clone arguments + args = clone$1(args); + var self = this; + // if the last argument is a function, assume its a callback + var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false; + var promise = new Promise(function (fulfill, reject) { + var resp; + try { + var callback = once(function (err, mesg) { + if (err) { + reject(err); + } else { + fulfill(mesg); + } + }); + // create a callback for this invocation + // apply the function in the orig context + args.push(callback); + resp = func.apply(self, args); + if (resp && typeof resp.then === 'function') { + fulfill(resp); + } + } catch (e) { + reject(e); + } }); + // if there is a callback, call it back + if (usedCB) { + promise.then(function (result) { + usedCB(null, result); + }, usedCB); + } + return promise; }); } -function sequentialize(queue, promiseFactory) { - return function () { - var args = arguments; - var that = this; - return queue.add(function () { - return promiseFactory.apply(that, args); - }); - }; -} +function logApiCall(self, name, args) { + /* istanbul ignore if */ + if (self.constructor.listeners('debug').length) { + var logArgs = ['api', self.name, name]; + for (var i = 0; i < args.length - 1; i++) { + logArgs.push(args[i]); + } + self.constructor.emit('debug', logArgs); -// uniq an array of strings, order not guaranteed -// similar to underscore/lodash _.uniq -function uniq(arr) { - var theSet = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_1__.Set(arr); - var result = new Array(theSet.size); - var index = -1; - theSet.forEach(function (value) { - result[++index] = value; - }); - return result; + // override the callback itself to log the response + var origCallback = args[args.length - 1]; + args[args.length - 1] = function (err, res) { + var responseArgs = ['api', self.name, name]; + responseArgs = responseArgs.concat( + err ? ['error', err] : ['success', res] + ); + self.constructor.emit('debug', responseArgs); + origCallback(err, res); + }; + } } -function mapToKeysArray(map) { - var result = new Array(map.size); - var index = -1; - map.forEach(function (value, key) { - result[++index] = key; - }); - return result; +function adapterFun(name, callback) { + return toPromise(argsarray__WEBPACK_IMPORTED_MODULE_1___default()(function (args) { + if (this._closed) { + return Promise.reject(new Error('database is closed')); + } + if (this._destroyed) { + return Promise.reject(new Error('database is destroyed')); + } + var self = this; + logApiCall(self, name, args); + if (!this.taskqueue.isReady) { + return new Promise(function (fulfill, reject) { + self.taskqueue.addTask(function (failed) { + if (failed) { + reject(failed); + } else { + fulfill(self[name].apply(self, args)); + } + }); + }); + } + return callback.apply(this, args); + })); } +// like underscore/lodash _.pick() +function pick(obj, arr) { + var res = {}; + for (var i = 0, len = arr.length; i < len; i++) { + var prop = arr[i]; + if (prop in obj) { + res[prop] = obj[prop]; + } + } + return res; +} +// Most browsers throttle concurrent requests at 6, so it's silly +// to shim _bulk_get by trying to launch potentially hundreds of requests +// and then letting the majority time out. We can handle this ourselves. +var MAX_NUM_CONCURRENT_REQUESTS = 6; +function identityFunction(x) { + return x; +} -/***/ }), -/* 509 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; +function formatResultForOpenRevsGet(result) { + return [{ + ok: result + }]; +} +// shim for P/CouchDB adapters that don't directly implement _bulk_get +function bulkGet(db, opts, callback) { + var requests = opts.docs; -var _interopRequireWildcard = __webpack_require__(510); + // consolidate into one request per doc if possible + var requestsById = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); + requests.forEach(function (request) { + if (requestsById.has(request.id)) { + requestsById.get(request.id).push(request); + } else { + requestsById.set(request.id, [request]); + } + }); -var _interopRequireDefault = __webpack_require__(512); + var numDocs = requestsById.size; + var numDone = 0; + var perDocResults = new Array(numDocs); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var _exportNames = { - CozyLink: true, - StackLink: true, - compose: true, - QueryDefinition: true, - Mutations: true, - MutationTypes: true, - getDoctypeFromOperation: true, - Q: true, - Association: true, - HasMany: true, - HasOne: true, - HasOneInPlace: true, - HasManyInPlace: true, - HasManyTriggers: true, - dehydrate: true, - generateWebLink: true, - rootCozyUrl: true, - InvalidCozyUrlError: true, - InvalidProtocolError: true, - cancelable: true, - getQueryFromState: true, - Registry: true, - manifest: true, - BulkEditError: true, - models: true -}; -Object.defineProperty(exports, "default", ({ - enumerable: true, - get: function get() { - return _CozyClient.default; - } -})); -Object.defineProperty(exports, "CozyLink", ({ - enumerable: true, - get: function get() { - return _CozyLink.default; - } -})); -Object.defineProperty(exports, "StackLink", ({ - enumerable: true, - get: function get() { - return _StackLink.default; - } -})); -Object.defineProperty(exports, "compose", ({ - enumerable: true, - get: function get() { - return _flow.default; - } -})); -Object.defineProperty(exports, "QueryDefinition", ({ - enumerable: true, - get: function get() { - return _dsl.QueryDefinition; - } -})); -Object.defineProperty(exports, "Mutations", ({ - enumerable: true, - get: function get() { - return _dsl.Mutations; - } -})); -Object.defineProperty(exports, "MutationTypes", ({ - enumerable: true, - get: function get() { - return _dsl.MutationTypes; - } -})); -Object.defineProperty(exports, "getDoctypeFromOperation", ({ - enumerable: true, - get: function get() { - return _dsl.getDoctypeFromOperation; - } -})); -Object.defineProperty(exports, "Q", ({ - enumerable: true, - get: function get() { - return _dsl.Q; - } -})); -Object.defineProperty(exports, "Association", ({ - enumerable: true, - get: function get() { - return _associations.Association; - } -})); -Object.defineProperty(exports, "HasMany", ({ - enumerable: true, - get: function get() { - return _associations.HasMany; - } -})); -Object.defineProperty(exports, "HasOne", ({ - enumerable: true, - get: function get() { - return _associations.HasOne; - } -})); -Object.defineProperty(exports, "HasOneInPlace", ({ - enumerable: true, - get: function get() { - return _associations.HasOneInPlace; - } -})); -Object.defineProperty(exports, "HasManyInPlace", ({ - enumerable: true, - get: function get() { - return _associations.HasManyInPlace; - } -})); -Object.defineProperty(exports, "HasManyTriggers", ({ - enumerable: true, - get: function get() { - return _associations.HasManyTriggers; - } -})); -Object.defineProperty(exports, "dehydrate", ({ - enumerable: true, - get: function get() { - return _helpers.dehydrate; - } -})); -Object.defineProperty(exports, "generateWebLink", ({ - enumerable: true, - get: function get() { - return _helpers.generateWebLink; - } -})); -Object.defineProperty(exports, "rootCozyUrl", ({ - enumerable: true, - get: function get() { - return _helpers.rootCozyUrl; + function collapseResultsAndFinish() { + var results = []; + perDocResults.forEach(function (res) { + res.docs.forEach(function (info) { + results.push({ + id: res.id, + docs: [info] + }); + }); + }); + callback(null, {results: results}); } -})); -Object.defineProperty(exports, "InvalidCozyUrlError", ({ - enumerable: true, - get: function get() { - return _helpers.InvalidCozyUrlError; + + function checkDone() { + if (++numDone === numDocs) { + collapseResultsAndFinish(); + } } -})); -Object.defineProperty(exports, "InvalidProtocolError", ({ - enumerable: true, - get: function get() { - return _helpers.InvalidProtocolError; + + function gotResult(docIndex, id, docs) { + perDocResults[docIndex] = {id: id, docs: docs}; + checkDone(); } -})); -Object.defineProperty(exports, "cancelable", ({ - enumerable: true, - get: function get() { - return _utils.cancelable; + + var allRequests = []; + requestsById.forEach(function (value, key) { + allRequests.push(key); + }); + + var i = 0; + + function nextBatch() { + + if (i >= allRequests.length) { + return; + } + + var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length); + var batch = allRequests.slice(i, upTo); + processBatch(batch, i); + i += batch.length; } -})); -Object.defineProperty(exports, "getQueryFromState", ({ - enumerable: true, - get: function get() { - return _store.getQueryFromState; + + function processBatch(batch, offset) { + batch.forEach(function (docId, j) { + var docIdx = offset + j; + var docRequests = requestsById.get(docId); + + // just use the first request as the "template" + // TODO: The _bulk_get API allows for more subtle use cases than this, + // but for now it is unlikely that there will be a mix of different + // "atts_since" or "attachments" in the same request, since it's just + // replicate.js that is using this for the moment. + // Also, atts_since is aspirational, since we don't support it yet. + var docOpts = pick(docRequests[0], ['atts_since', 'attachments']); + docOpts.open_revs = docRequests.map(function (request) { + // rev is optional, open_revs disallowed + return request.rev; + }); + + // remove falsey / undefined revisions + docOpts.open_revs = docOpts.open_revs.filter(identityFunction); + + var formatResult = identityFunction; + + if (docOpts.open_revs.length === 0) { + delete docOpts.open_revs; + + // when fetching only the "winning" leaf, + // transform the result so it looks like an open_revs + // request + formatResult = formatResultForOpenRevsGet; + } + + // globally-supplied options + ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) { + if (param in opts) { + docOpts[param] = opts[param]; + } + }); + db.get(docId, docOpts, function (err, res) { + var result; + /* istanbul ignore if */ + if (err) { + result = [{error: err}]; + } else { + result = formatResult(res); + } + gotResult(docIdx, docId, result); + nextBatch(); + }); + }); } -})); -Object.defineProperty(exports, "Registry", ({ - enumerable: true, - get: function get() { - return _registry.default; + + nextBatch(); + +} + +// in Node of course this is false +function hasLocalStorage() { + return false; +} + +function nextTick(fn) { + process.nextTick(fn); +} + +inherits__WEBPACK_IMPORTED_MODULE_4___default()(Changes, events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter); + +/* istanbul ignore next */ +function attachBrowserEvents(self) { + if (hasLocalStorage()) { + addEventListener("storage", function (e) { + self.emit(e.key); + }); } -})); -Object.defineProperty(exports, "BulkEditError", ({ - enumerable: true, - get: function get() { - return _errors.BulkEditError; +} + +function Changes() { + events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.call(this); + this._listeners = {}; + + attachBrowserEvents(this); +} +Changes.prototype.addListener = function (dbName, id, db, opts) { + /* istanbul ignore if */ + if (this._listeners[id]) { + return; } -})); -exports.models = exports.manifest = void 0; + var self = this; + var inprogress = false; + function eventFunction() { + /* istanbul ignore if */ + if (!self._listeners[id]) { + return; + } + if (inprogress) { + inprogress = 'waiting'; + return; + } + inprogress = true; + var changesOpts = pick(opts, [ + 'style', 'include_docs', 'attachments', 'conflicts', 'filter', + 'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs' + ]); + + /* istanbul ignore next */ + function onError() { + inprogress = false; + } -var _CozyClient = _interopRequireDefault(__webpack_require__(513)); + db.changes(changesOpts).on('change', function (c) { + if (c.seq > opts.since && !opts.cancelled) { + opts.since = c.seq; + opts.onChange(c); + } + }).on('complete', function () { + if (inprogress === 'waiting') { + nextTick(eventFunction); + } + inprogress = false; + }).on('error', onError); + } + this._listeners[id] = eventFunction; + this.on(dbName, eventFunction); +}; -var _CozyLink = _interopRequireDefault(__webpack_require__(687)); +Changes.prototype.removeListener = function (dbName, id) { + /* istanbul ignore if */ + if (!(id in this._listeners)) { + return; + } + events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.prototype.removeListener.call(this, dbName, + this._listeners[id]); + delete this._listeners[id]; +}; -var _StackLink = _interopRequireDefault(__webpack_require__(686)); -var _flow = _interopRequireDefault(__webpack_require__(792)); +/* istanbul ignore next */ +Changes.prototype.notifyLocalWindows = function (dbName) { + //do a useless change on a storage thing + //in order to get other windows's listeners to activate + if (hasLocalStorage()) { + localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a"; + } +}; -var _dsl = __webpack_require__(607); +Changes.prototype.notify = function (dbName) { + this.emit(dbName); + this.notifyLocalWindows(dbName); +}; -var _associations = __webpack_require__(691); +function guardedConsole(method) { + /* istanbul ignore else */ + if (typeof console !== 'undefined' && typeof console[method] === 'function') { + var args = Array.prototype.slice.call(arguments, 1); + console[method].apply(console, args); + } +} -var _helpers = __webpack_require__(756); +function randomNumber(min, max) { + var maxTimeout = 600000; // Hard-coded default of 10 minutes + min = parseInt(min, 10) || 0; + max = parseInt(max, 10); + if (max !== max || max <= min) { + max = (min || 1) << 1; //doubling + } else { + max = max + 1; + } + // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout + if (max > maxTimeout) { + min = maxTimeout >> 1; // divide by two + max = maxTimeout; + } + var ratio = Math.random(); + var range = max - min; -var _utils = __webpack_require__(804); + return ~~(range * ratio + min); // ~~ coerces to an int, but fast. +} -var _store = __webpack_require__(693); +function defaultBackOff(min) { + var max = 0; + if (!min) { + max = 2000; + } + return randomNumber(min, max); +} -var _registry = _interopRequireDefault(__webpack_require__(596)); +// We assume Node users don't need to see this warning +var res = function () {}; -var manifest = _interopRequireWildcard(__webpack_require__(805)); +var assign; +{ + if (typeof Object.assign === 'function') { + assign = Object.assign; + } else { + // lite Object.assign polyfill based on + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + assign = function (target) { + var to = Object(target); -exports.manifest = manifest; + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; -var _mock = __webpack_require__(806); + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + }; + } +} -Object.keys(_mock).forEach(function (key) { - if (key === "default" || key === "__esModule") return; - if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; - if (key in exports && exports[key] === _mock[key]) return; - Object.defineProperty(exports, key, { - enumerable: true, - get: function get() { - return _mock[key]; - } - }); -}); +var assign$1 = assign; -var _errors = __webpack_require__(688); +function tryFilter(filter, doc, req) { + try { + return !filter(doc, req); + } catch (err) { + var msg = 'Filter function threw: ' + err.toString(); + return (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.BAD_REQUEST, msg); + } +} -var _cli = __webpack_require__(807); +function filterChange(opts) { + var req = {}; + var hasFilter = opts.filter && typeof opts.filter === 'function'; + req.query = opts.query_params; -Object.keys(_cli).forEach(function (key) { - if (key === "default" || key === "__esModule") return; - if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; - if (key in exports && exports[key] === _cli[key]) return; - Object.defineProperty(exports, key, { - enumerable: true, - get: function get() { - return _cli[key]; + return function filter(change) { + if (!change.doc) { + // CSG sends events on the changes feed that don't have documents, + // this hack makes a whole lot of existing code robust. + change.doc = {}; } - }); -}); -var models = _interopRequireWildcard(__webpack_require__(828)); - -exports.models = models; + var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req); -/***/ }), -/* 510 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (typeof filterReturn === 'object') { + return filterReturn; + } -var _typeof = (__webpack_require__(511)["default"]); + if (filterReturn) { + return false; + } -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== "function") return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); + if (!opts.include_docs) { + delete change.doc; + } else if (!opts.attachments) { + for (var att in change.doc._attachments) { + /* istanbul ignore else */ + if (change.doc._attachments.hasOwnProperty(att)) { + change.doc._attachments[att].stub = true; + } + } + } + return true; + }; } -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - - if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { - return { - "default": obj - }; +function flatten(arrs) { + var res = []; + for (var i = 0, len = arrs.length; i < len; i++) { + res = res.concat(arrs[i]); } + return res; +} - var cache = _getRequireWildcardCache(nodeInterop); - - if (cache && cache.has(obj)) { - return cache.get(obj); - } +// shim for Function.prototype.name, +// for browsers that don't support it like IE - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; +/* istanbul ignore next */ +function f() {} - for (var key in obj) { - if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; +var hasName = f.name; +var res$1; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } +// We dont run coverage in IE +/* istanbul ignore else */ +if (hasName) { + res$1 = function (fun) { + return fun.name; + }; +} else { + res$1 = function (fun) { + var match = fun.toString().match(/^\s*function\s*(?:(\S+)\s*)?\(/); + if (match && match[1]) { + return match[1]; } - } + else { + return ''; + } + }; +} - newObj["default"] = obj; +var res$2 = res$1; - if (cache) { - cache.set(obj, newObj); +// Determine id an ID is valid +// - invalid IDs begin with an underescore that does not begin '_design' or +// '_local' +// - any other string value is a valid id +// Returns the specific error object for each case +function invalidIdError(id) { + var err; + if (!id) { + err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.MISSING_ID); + } else if (typeof id !== 'string') { + err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.INVALID_ID); + } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) { + err = (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.createError)(pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.RESERVED_ID); + } + if (err) { + throw err; } - - return newObj; } -module.exports = _interopRequireWildcard; -module.exports["default"] = module.exports, module.exports.__esModule = true; - -/***/ }), -/* 511 */ -/***/ ((module) => { - -function _typeof(obj) { - "@babel/helpers - typeof"; - - if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { - module.exports = _typeof = function _typeof(obj) { - return typeof obj; - }; - - module.exports["default"] = module.exports, module.exports.__esModule = true; - } else { - module.exports = _typeof = function _typeof(obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; +// Checks if a PouchDB object is "remote" or not. This is - module.exports["default"] = module.exports, module.exports.__esModule = true; +function isRemote(db) { + if (typeof db._remote === 'boolean') { + return db._remote; } - - return _typeof(obj); + /* istanbul ignore next */ + if (typeof db.type === 'function') { + guardedConsole('warn', + 'db.type() is deprecated and will be removed in ' + + 'a future version of PouchDB'); + return db.type() === 'http'; + } + /* istanbul ignore next */ + return false; } -module.exports = _typeof; -module.exports["default"] = module.exports, module.exports.__esModule = true; +function listenerCount(ee, type) { + return 'listenerCount' in ee ? ee.listenerCount(type) : + events__WEBPACK_IMPORTED_MODULE_3__.EventEmitter.listenerCount(ee, type); +} -/***/ }), -/* 512 */ -/***/ ((module) => { +function parseDesignDocFunctionName(s) { + if (!s) { + return null; + } + var parts = s.split('/'); + if (parts.length === 2) { + return parts; + } + if (parts.length === 1) { + return [s, s]; + } + return null; +} -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - "default": obj - }; +function normalizeDesignDocFunctionName(s) { + var normalized = parseDesignDocFunctionName(s); + return normalized ? normalized.join('/') : null; } -module.exports = _interopRequireDefault; -module.exports["default"] = module.exports, module.exports.__esModule = true; +// originally parseUri 1.2.2, now patched by us +// (c) Steven Levithan <stevenlevithan.com> +// MIT License +var keys = ["source", "protocol", "authority", "userInfo", "user", "password", + "host", "port", "relative", "path", "directory", "file", "query", "anchor"]; +var qName ="queryKey"; +var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g; -/***/ }), -/* 513 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +// use the "loose" parser +/* eslint maxlen: 0, no-useless-escape: 0 */ +var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; -"use strict"; +function parseUri(str) { + var m = parser.exec(str); + var uri = {}; + var i = 14; + while (i--) { + var key = keys[i]; + var value = m[i] || ""; + var encoded = ['user', 'password'].indexOf(key) !== -1; + uri[key] = encoded ? decodeURIComponent(value) : value; + } -var _interopRequireWildcard = __webpack_require__(510); + uri[qName] = {}; + uri[keys[12]].replace(qParser, function ($0, $1, $2) { + if ($1) { + uri[qName][$1] = $2; + } + }); -var _interopRequireDefault = __webpack_require__(512); + return uri; +} -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +// Based on https://github.com/alexdavid/scope-eval v0.0.3 +// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js) +// This is basically just a wrapper around new Function() -var _toArray2 = _interopRequireDefault(__webpack_require__(514)); +function scopeEval(source, scope) { + var keys = []; + var values = []; + for (var key in scope) { + if (scope.hasOwnProperty(key)) { + keys.push(key); + values.push(scope[key]); + } + } + keys.push(source); + return Function.apply(null, keys).apply(null, values); +} -var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520)); +// this is essentially the "update sugar" function from daleharvey/pouchdb#1388 +// the diffFun tells us what delta to apply to the doc. it either returns +// the doc, or false if it doesn't need to do an update after all +function upsert(db, docId, diffFun) { + return new Promise(function (fulfill, reject) { + db.get(docId, function (err, doc) { + if (err) { + /* istanbul ignore next */ + if (err.status !== 404) { + return reject(err); + } + doc = {}; + } -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); + // the user might change the _rev, so save it for posterity + var docRev = doc._rev; + var newDoc = diffFun(doc); -var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525)); + if (!newDoc) { + // if the diffFun returns falsy, we short-circuit as + // an optimization + return fulfill({updated: false, rev: docRev}); + } -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + // users aren't allowed to modify these values, + // so reset them here + newDoc._id = docId; + newDoc._rev = docRev; + fulfill(tryAndPut(db, newDoc, diffFun)); + }); + }); +} -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +function tryAndPut(db, doc, diffFun) { + return db.put(doc).then(function (res) { + return { + updated: true, + rev: res.rev + }; + }, function (err) { + /* istanbul ignore next */ + if (err.status !== 409) { + throw err; + } + return upsert(db, doc._id, diffFun); + }); +} -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +function rev(doc, deterministic_revs) { + var clonedDoc = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_8__.clone)(doc); + if (!deterministic_revs) { + return uuid__WEBPACK_IMPORTED_MODULE_6___default().v4().replace(/-/g, '').toLowerCase(); + } -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + delete clonedDoc._rev_tree; + return (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_7__.stringMd5)(JSON.stringify(clonedDoc)); +} -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var uuid = (uuid__WEBPACK_IMPORTED_MODULE_6___default().v4); -var _mapValues = _interopRequireDefault(__webpack_require__(533)); -var _fromPairs = _interopRequireDefault(__webpack_require__(539)); -var _flatten = _interopRequireDefault(__webpack_require__(540)); -var _uniqBy = _interopRequireDefault(__webpack_require__(400)); +/***/ }), +/* 508 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _zip = _interopRequireDefault(__webpack_require__(543)); +"use strict"; -var _forEach = _interopRequireDefault(__webpack_require__(553)); -var _get = _interopRequireDefault(__webpack_require__(358)); +var Buffer = (__webpack_require__(78).Buffer); -var _microee = _interopRequireDefault(__webpack_require__(558)); +function hasFrom() { + // Node versions 5.x below 5.10 seem to have a `from` method + // However, it doesn't clone Buffers + // Luckily, it reports as `false` to hasOwnProperty + return (Buffer.hasOwnProperty('from') && typeof Buffer.from === 'function'); +} -var _cozyStackClient = _interopRequireWildcard(__webpack_require__(559)); +function cloneBuffer(buf) { + if (!Buffer.isBuffer(buf)) { + throw new Error('Can only clone Buffer.'); + } -var _const = __webpack_require__(685); + if (hasFrom()) { + return Buffer.from(buf); + } -var _StackLink = _interopRequireDefault(__webpack_require__(686)); + var copy = new Buffer(buf.length); + buf.copy(copy); + return copy; +} -var _associations = __webpack_require__(691); +cloneBuffer.hasFrom = hasFrom; -var _helpers = __webpack_require__(755); +module.exports = cloneBuffer; -var _helpers2 = __webpack_require__(756); -var _dsl = __webpack_require__(607); +/***/ }), +/* 509 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -var _mobile = __webpack_require__(757); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Set": () => (/* binding */ ExportedSet), +/* harmony export */ "Map": () => (/* binding */ ExportedMap) +/* harmony export */ }); +function mangle(key) { + return '$' + key; +} +function unmangle(key) { + return key.substring(1); +} +function Map$1() { + this._store = {}; +} +Map$1.prototype.get = function (key) { + var mangled = mangle(key); + return this._store[mangled]; +}; +Map$1.prototype.set = function (key, value) { + var mangled = mangle(key); + this._store[mangled] = value; + return true; +}; +Map$1.prototype.has = function (key) { + var mangled = mangle(key); + return mangled in this._store; +}; +Map$1.prototype.delete = function (key) { + var mangled = mangle(key); + var res = mangled in this._store; + delete this._store[mangled]; + return res; +}; +Map$1.prototype.forEach = function (cb) { + var keys = Object.keys(this._store); + for (var i = 0, len = keys.length; i < len; i++) { + var key = keys[i]; + var value = this._store[key]; + key = unmangle(key); + cb(value, key); + } +}; +Object.defineProperty(Map$1.prototype, 'size', { + get: function () { + return Object.keys(this._store).length; + } +}); -var _optimize = _interopRequireDefault(__webpack_require__(774)); +function Set$1(array) { + this._store = new Map$1(); -var _store = _interopRequireWildcard(__webpack_require__(693)); + // init with an array + if (array && Array.isArray(array)) { + for (var i = 0, len = array.length; i < len; i++) { + this.add(array[i]); + } + } +} +Set$1.prototype.add = function (key) { + return this._store.set(key, true); +}; +Set$1.prototype.has = function (key) { + return this._store.has(key); +}; +Set$1.prototype.forEach = function (cb) { + this._store.forEach(function (value, key) { + cb(key); + }); +}; +Object.defineProperty(Set$1.prototype, 'size', { + get: function () { + return this._store.size; + } +}); -var _policies = _interopRequireDefault(__webpack_require__(776)); +/* global Map,Set,Symbol */ +// Based on https://kangax.github.io/compat-table/es6/ we can sniff out +// incomplete Map/Set implementations which would otherwise cause our tests to fail. +// Notably they fail in IE11 and iOS 8.4, which this prevents. +function supportsMapAndSet() { + if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') { + return false; + } + var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species); + return prop && 'get' in prop && Map[Symbol.species] === Map; +} -var _Schema = _interopRequireDefault(__webpack_require__(777)); +// based on https://github.com/montagejs/collections -var _CozyLink = __webpack_require__(687); +var ExportedSet; +var ExportedMap; -var _ObservableQuery = _interopRequireDefault(__webpack_require__(783)); +{ + if (supportsMapAndSet()) { // prefer built-in Map/Set + ExportedSet = Set; + ExportedMap = Map; + } else { // fall back to our polyfill + ExportedSet = Set$1; + ExportedMap = Map$1; + } +} -var _snapshots = __webpack_require__(784); -var _logger = _interopRequireDefault(__webpack_require__(703)); -var _types = __webpack_require__(610); -var _queries = __webpack_require__(723); +/***/ }), +/* 510 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -var _jsonStableStringify = _interopRequireDefault(__webpack_require__(785)); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "UNAUTHORIZED": () => (/* binding */ UNAUTHORIZED), +/* harmony export */ "MISSING_BULK_DOCS": () => (/* binding */ MISSING_BULK_DOCS), +/* harmony export */ "MISSING_DOC": () => (/* binding */ MISSING_DOC), +/* harmony export */ "REV_CONFLICT": () => (/* binding */ REV_CONFLICT), +/* harmony export */ "INVALID_ID": () => (/* binding */ INVALID_ID), +/* harmony export */ "MISSING_ID": () => (/* binding */ MISSING_ID), +/* harmony export */ "RESERVED_ID": () => (/* binding */ RESERVED_ID), +/* harmony export */ "NOT_OPEN": () => (/* binding */ NOT_OPEN), +/* harmony export */ "UNKNOWN_ERROR": () => (/* binding */ UNKNOWN_ERROR), +/* harmony export */ "BAD_ARG": () => (/* binding */ BAD_ARG), +/* harmony export */ "INVALID_REQUEST": () => (/* binding */ INVALID_REQUEST), +/* harmony export */ "QUERY_PARSE_ERROR": () => (/* binding */ QUERY_PARSE_ERROR), +/* harmony export */ "DOC_VALIDATION": () => (/* binding */ DOC_VALIDATION), +/* harmony export */ "BAD_REQUEST": () => (/* binding */ BAD_REQUEST), +/* harmony export */ "NOT_AN_OBJECT": () => (/* binding */ NOT_AN_OBJECT), +/* harmony export */ "DB_MISSING": () => (/* binding */ DB_MISSING), +/* harmony export */ "WSQ_ERROR": () => (/* binding */ WSQ_ERROR), +/* harmony export */ "LDB_ERROR": () => (/* binding */ LDB_ERROR), +/* harmony export */ "FORBIDDEN": () => (/* binding */ FORBIDDEN), +/* harmony export */ "INVALID_REV": () => (/* binding */ INVALID_REV), +/* harmony export */ "FILE_EXISTS": () => (/* binding */ FILE_EXISTS), +/* harmony export */ "MISSING_STUB": () => (/* binding */ MISSING_STUB), +/* harmony export */ "IDB_ERROR": () => (/* binding */ IDB_ERROR), +/* harmony export */ "INVALID_URL": () => (/* binding */ INVALID_URL), +/* harmony export */ "createError": () => (/* binding */ createError), +/* harmony export */ "generateErrorFromResponse": () => (/* binding */ generateErrorFromResponse) +/* harmony export */ }); +/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(497); +/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_0__); -var _promiseCache = _interopRequireDefault(__webpack_require__(789)); -var _flagshipCertification = __webpack_require__(790); +inherits__WEBPACK_IMPORTED_MODULE_0___default()(PouchError, Error); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +function PouchError(status, error, reason) { + Error.call(this, reason); + this.status = status; + this.name = error; + this.message = reason; + this.error = true; +} -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +PouchError.prototype.toString = function () { + return JSON.stringify({ + status: this.status, + name: this.name, + message: this.message, + reason: this.reason + }); +}; -function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } +var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect."); +var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'"); +var MISSING_DOC = new PouchError(404, 'not_found', 'missing'); +var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict'); +var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string'); +var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts'); +var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.'); +var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open'); +var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error'); +var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid'); +var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid'); +var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid'); +var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member'); +var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request'); +var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object'); +var DB_MISSING = new PouchError(404, 'not_found', 'Database not found'); +var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown'); +var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown'); +var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown'); +var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function'); +var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format'); +var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.'); +var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found'); +var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid'); -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function createError(error, reason) { + function CustomPouchError(reason) { + // inherit error properties from our parent error manually + // so as to allow proper JSON parsing. + /* jshint ignore:start */ + for (var p in error) { + if (typeof error[p] !== 'function') { + this[p] = error[p]; + } + } + /* jshint ignore:end */ + if (reason !== undefined) { + this.reason = reason; + } + } + CustomPouchError.prototype = PouchError.prototype; + return new CustomPouchError(reason); +} -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } +function generateErrorFromResponse(err) { -var ensureArray = function ensureArray(arr) { - return Array.isArray(arr) ? arr : [arr]; -}; + if (typeof err !== 'object') { + var data = err; + err = UNKNOWN_ERROR; + err.data = data; + } -var deprecatedHandler = function deprecatedHandler(msg) { - return { - get: function get(target, prop) { - console.warn(msg); - return target[prop]; - } - }; -}; + if ('error' in err && err.error === 'conflict') { + err.name = 'conflict'; + err.status = 409; + } -var supportsReferences = function supportsReferences(relationshipClass) { - return relationshipClass.prototype.addReferences && relationshipClass.prototype.removeReferences; -}; + if (!('name' in err)) { + err.name = err.error || 'unknown'; + } -var referencesUnsupportedError = function referencesUnsupportedError(relationshipClassName) { - return new Error("The \"".concat(relationshipClassName, "\" relationship does not support references. If you need to add references to a document, its relationship class must have the methods {add,remove}References")); -}; + if (!('status' in err)) { + err.status = 500; + } -var DOC_CREATION = 'creation'; -var DOC_UPDATE = 'update'; -/** - * @typedef {object} ClientOptions - * @property {object} [client] - * @property {object} [link] - * @property {object} [links] - * @property {Token} [token] - * @property {string} [uri] - * @property {object} [stackClient] - * @property {boolean} [warningForCustomHandlers] - * @property {boolean} [autoHydrate] - * @property {object} [oauth] - * @property {Function} [onTokenRefresh] - * @property {Function} [onError] - Default callback if a query is errored - * @property {Link} [link] - Backward compatibility - * @property {Array<Link>} [links] - List of links - * @property {object} [schema] - Schema description for each doctypes - * @property {AppMetadata} [appMetadata] - Metadata about the application that will be used in ensureCozyMetadata - * @property {ClientCapabilities} [capabilities] - Capabilities sent by the stack - * @property {boolean} [store] - If set to false, the client will not instantiate a Redux store automatically. Use this if you want to merge cozy-client's store with your own redux store. See [here](https://docs.cozy.io/en/cozy-client/react-integration/#1b-use-your-own-redux-store) for more information. - */ + if (!('message' in err)) { + err.message = err.message || err.reason; + } -/** - * Responsible for - * - * - Creating observable queries - * - Hydration - * - Creating plan for saving documents - * - Associations - */ + return err; +} -var CozyClient = /*#__PURE__*/function () { - /** - * @param {ClientOptions} rawOptions - Options - * - * @example - * ```js - * const client = new CozyClient({ - * schema: { - * todos: { - * doctype: 'io.cozy.todos', - * relationships: { - * authors: { - * type: 'has-many', - * doctype: 'io.cozy.persons' - * } - * } - * } - * } - * }) - * ``` - * - * Cozy-Client will automatically call `this.login()` if provided with a token and an uri - */ - function CozyClient() { - var _this = this; - var rawOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - (0, _classCallCheck2.default)(this, CozyClient); - (0, _defineProperty2.default)(this, "fetchQueryAndGetFromState", /*#__PURE__*/function () { - var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(query) { - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.prev = 0; - _context.next = 3; - return _this.query(query.definition, query.options); - case 3: - return _context.abrupt("return", _this.getQueryFromState(query.options.as)); - case 6: - _context.prev = 6; - _context.t0 = _context["catch"](0); - throw _context.t0; +/***/ }), +/* 511 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - case 9: - case "end": - return _context.stop(); - } - } - }, _callee, null, [[0, 6]]); - })); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "binaryMd5": () => (/* binding */ binaryMd5), +/* harmony export */ "stringMd5": () => (/* binding */ stringMd5) +/* harmony export */ }); +/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(76); +/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_0__); - return function (_x) { - return _ref.apply(this, arguments); - }; - }()); - var link = rawOptions.link, - links = rawOptions.links, - _rawOptions$schema = rawOptions.schema, - schema = _rawOptions$schema === void 0 ? {} : _rawOptions$schema, - _rawOptions$appMetada = rawOptions.appMetadata, - appMetadata = _rawOptions$appMetada === void 0 ? {} : _rawOptions$appMetada, - capabilities = rawOptions.capabilities, - options = (0, _objectWithoutProperties2.default)(rawOptions, ["link", "links", "schema", "appMetadata", "capabilities"]); - if (link) { - console.warn('`link` is deprecated, use `links`'); - } +function binaryMd5(data, callback) { + var base64 = crypto__WEBPACK_IMPORTED_MODULE_0___default().createHash('md5').update(data, 'binary').digest('base64'); + callback(base64); +} - this.appMetadata = appMetadata; - this.options = options; - this.queryIdGenerator = new _queries.QueryIDGenerator(); - this.isLogged = false; - this.instanceOptions = {}; // Bind handlers +function stringMd5(string) { + return crypto__WEBPACK_IMPORTED_MODULE_0___default().createHash('md5').update(string, 'binary').digest('hex'); +} - this.handleRevocationChange = this.handleRevocationChange.bind(this); - this.handleTokenRefresh = this.handleTokenRefresh.bind(this); - this.createClient(); - var stackClient = this.getStackClient(); - stackClient.on('error', function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - return _this.emit.apply(_this, ['error'].concat(args)); - }); - this.links = ensureArray(link || links || new _StackLink.default()); - this.registerClientOnLinks(); - this.chain = (0, _CozyLink.chain)(this.links); - this.schema = new _Schema.default(schema, stackClient); - /** - * @type {ClientCapabilities} - */ - this.capabilities = capabilities || null; // Instances of plugins registered with registerPlugin - this.plugins = {}; +/***/ }), +/* 512 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - try { - this.loadInstanceOptionsFromDOM(); - } catch (err) {// not a critical error, we may be in node or the instance options are not on the default HTML element - } +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "fetch": () => (/* binding */ fetch), +/* harmony export */ "Headers": () => (/* binding */ Headers), +/* harmony export */ "AbortController": () => (/* binding */ AbortController) +/* harmony export */ }); +/* harmony import */ var node_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(493); +/* harmony import */ var fetch_cookie__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(513); +/* harmony import */ var fetch_cookie__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fetch_cookie__WEBPACK_IMPORTED_MODULE_1__); - if (options.uri && options.token) { - this.login(); - } - /** - * @type {object} - */ - this.storeAccesors = null; +var fetch = fetch_cookie__WEBPACK_IMPORTED_MODULE_1___default()(node_fetch__WEBPACK_IMPORTED_MODULE_0__["default"]); - if (options.store !== false) { - this.ensureStore(); - } - /** - * Holds in-flight promises for deduplication purpose - * - * @private - * @type {PromiseCache} - */ +/* We can fake the abort, the http adapter keeps track + of ignoring the result */ +function AbortController() { + return {abort: function () {}}; +} +var Headers = node_fetch__WEBPACK_IMPORTED_MODULE_0__["default"].Headers; - this._promiseCache = new _promiseCache.default(); - } - /** - * Gets overrided by MicroEE.mixin - * This is here just so typescript does not scream - * - * TODO Find a better way to make TS understand that emit is - * a method from cozy-client - */ - (0, _createClass2.default)(CozyClient, [{ - key: "emit", - value: function emit() {} - }, { - key: "on", - value: function on() {} - }, { - key: "removeListener", - value: function removeListener() {} - /** - * A plugin is a class whose constructor receives the client as first argument. - * The main mean of interaction with the client should be with events - * like "login"/"logout". - * - * The plugin system is meant to encourage separation of concerns, modularity - * and testability : instead of registering events at module level, please - * create a plugin that subscribes to events. - * - * Plugin instances are stored internally in the `plugins` attribute of the client - * and can be accessed via this mean. A plugin class must have the attribute - * `pluginName` that will be use as the key in the `plugins` object. - * - * Two plugins with the same `pluginName` cannot co-exist. - * - * @example - * ```js - * class AlertPlugin { - * constructor(client, options) { - * this.client = client - * this.options = options - * this.handleLogin = this.handleLogin.bind(this) - * this.handleLogout = this.handleLogout.bind(this) - * this.client.on("login", this.handleLogin) - * this.client.on("logout", this.handleLogout) - * } - * - * handleLogin() { - * alert(this.options.onLoginAlert) - * } - * - * handleLogout() { - * alert(this.options.onLogoutAlert) - * } - * } - * - * AlertPlugin.pluginName = 'alerts' - * - * client.registerPlugin(AlertPlugin, { - * onLoginAlert: 'client has logged in !', - * onLogoutAlert: 'client has logged out !' - * }) - * - * // the instance of the plugin is accessible via - * client.plugins.alerts - * ``` - */ - }, { - key: "registerPlugin", - value: function registerPlugin(Plugin, options) { - if (!Plugin.pluginName) { - throw new Error('Cannot register a plugin whose class does not have `pluginName` attribute.'); - } +/***/ }), +/* 513 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (this.plugins[Plugin.pluginName]) { - throw new Error("Cannot register plugin ".concat(Plugin.pluginName, ". A plugin with the same name has already been registered.")); - } +var denodeify = __webpack_require__(514)(Promise) +var tough = __webpack_require__(61) - var instance = new Plugin(this, options); - this.plugins[Plugin.pluginName] = instance; - return instance; - } - /** - * To help with the transition from cozy-client-js to cozy-client, it is possible to instantiate - * a client with a cookie-based instance of cozy-client-js. - * - * @param {OldCozyClient} oldClient - An instance of the deprecated cozy-client - * @param {object} options - CozyStackClient options - * @returns {CozyClient} - */ +module.exports = function fetchCookieDecorator (fetch, jar) { + fetch = fetch || window.fetch + jar = jar || new tough.CookieJar() - }, { - key: "addSchema", - value: function addSchema(schemaDefinition) { - this.schema.add(schemaDefinition); - } - }, { - key: "registerClientOnLinks", - value: function registerClientOnLinks() { - var _iterator = _createForOfIteratorHelper(this.links), - _step; + var getCookieString = denodeify(jar.getCookieString.bind(jar)) + var setCookie = denodeify(jar.setCookie.bind(jar)) - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - var link = _step.value; + return function fetchCookie (url, opts) { + opts = opts || {} - if (link.registerClient) { - try { - link.registerClient(this); - } catch (e) { - console.warn(e); - } - } - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } - } - /** - * Notify the links that they can start and set isLogged to true. - * - * On mobile, where url/token are set after instantiation, use this method - * to set the token and uri via options. - * - * Emits - * - * - "beforeLogin" at the beginning, before links have been set up - * - "login" when the client is fully logged in and links have been set up - * - * @param {object} [options] - Options - * @param {string} options.token - If passed, the token is set on the client - * @param {string} options.uri - If passed, the uri is set on the client - * @returns {Promise} - Resolves when all links have been setup and client is fully logged in - * - */ + return getCookieString(url) + .then(function (cookie) { + return fetch(url, Object.assign(opts, { + headers: Object.assign(opts.headers || {}, (cookie ? { cookie: cookie } : {})) + })) + }) + .then(function (res) { + var cookies - }, { - key: "login", - value: function login(options) { - // Keep the promise to be able to return it in future calls. - // This allows us to autoLogin in constructor without breaking any compatibility - // with codes that uses an explicit login. - if (this.isLogged && !this.isRevoked) { - console.warn("CozyClient is already logged."); - return this.loginPromise; - } + if (res.headers.getAll) { + // node-fetch v1 + cookies = res.headers.getAll('set-cookie') + } else { + // node-fetch v2 + var cookie = res.headers.get('set-cookie') + cookies = cookie && cookie.split(',') || [] + } - return this.loginPromise = this._login(options); - } - }, { - key: "_login", - value: function () { - var _login2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(options) { - var _iterator2, _step2, link; + if (!cookies.length) { + return res + } - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - this.emit('beforeLogin'); - this.registerClientOnLinks(); + return Promise.all(cookies.map(function (cookie) { + return setCookie(cookie, res.url) + })).then(function () { + return res + }) + }) + } +} - if (options) { - if (options.uri) { - this.stackClient.setUri(options.uri); - } - if (options.token) { - this.stackClient.setToken(options.token); - } - } +/***/ }), +/* 514 */ +/***/ ((module, exports) => { - _iterator2 = _createForOfIteratorHelper(this.links); - _context2.prev = 4; +"use strict"; - _iterator2.s(); - case 6: - if ((_step2 = _iterator2.n()).done) { - _context2.next = 13; - break; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); - link = _step2.value; +exports["default"] = function () { + var PromiseArg = arguments[0] === undefined ? Promise : arguments[0]; + return function (f) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } - if (!link.onLogin) { - _context2.next = 11; - break; - } + return new PromiseArg(function (resolve, reject) { + return f.apply(undefined, args.concat([function (err, val) { + return err ? reject(err) : resolve(val); + }])); + }); + }; + }; +}; - _context2.next = 11; - return link.onLogin(); +module.exports = exports["default"]; - case 11: - _context2.next = 6; - break; - case 13: - _context2.next = 18; - break; - case 15: - _context2.prev = 15; - _context2.t0 = _context2["catch"](4); +/***/ }), +/* 515 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - _iterator2.e(_context2.t0); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "massageSelector": () => (/* binding */ massageSelector), +/* harmony export */ "matchesSelector": () => (/* binding */ matchesSelector), +/* harmony export */ "filterInMemoryFields": () => (/* binding */ filterInMemoryFields), +/* harmony export */ "createFieldSorter": () => (/* binding */ createFieldSorter), +/* harmony export */ "rowFilter": () => (/* binding */ rowFilter), +/* harmony export */ "isCombinationalField": () => (/* binding */ isCombinationalField), +/* harmony export */ "getKey": () => (/* binding */ getKey), +/* harmony export */ "getValue": () => (/* binding */ getValue), +/* harmony export */ "getFieldFromDoc": () => (/* binding */ getFieldFromDoc), +/* harmony export */ "setFieldInDoc": () => (/* binding */ setFieldInDoc), +/* harmony export */ "compare": () => (/* binding */ compare), +/* harmony export */ "parseField": () => (/* binding */ parseField) +/* harmony export */ }); +/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507); +/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(516); - case 18: - _context2.prev = 18; - _iterator2.f(); - return _context2.finish(18); +// this would just be "return doc[field]", but fields +// can be "deep" due to dot notation +function getFieldFromDoc(doc, parsedField) { + var value = doc; + for (var i = 0, len = parsedField.length; i < len; i++) { + var key = parsedField[i]; + value = value[key]; + if (!value) { + break; + } + } + return value; +} - case 21: - this.isLogged = true; - this.isRevoked = false; - this.emit('login'); +function setFieldInDoc(doc, parsedField, value) { + for (var i = 0, len = parsedField.length; i < len-1; i++) { + var elem = parsedField[i]; + doc = doc[elem] = {}; + } + doc[parsedField[len-1]] = value; +} - case 24: - case "end": - return _context2.stop(); - } - } - }, _callee2, this, [[4, 15, 18, 21]]); - })); +function compare(left, right) { + return left < right ? -1 : left > right ? 1 : 0; +} - function _login(_x2) { - return _login2.apply(this, arguments); +// Converts a string in dot notation to an array of its components, with backslash escaping +function parseField(fieldName) { + // fields may be deep (e.g. "foo.bar.baz"), so parse + var fields = []; + var current = ''; + for (var i = 0, len = fieldName.length; i < len; i++) { + var ch = fieldName[i]; + if (ch === '.') { + if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter + current = current.substring(0, current.length - 1) + '.'; + } else { // not escaped, so delimiter + fields.push(current); + current = ''; } + } else { // normal character + current += ch; + } + } + fields.push(current); + return fields; +} - return _login; - }() - /** - * Logs out the client and reset all the links - * - * Emits - * - * - "beforeLogout" at the beginning, before links have been reset - * - "login" when the client is fully logged out and links have been reset - * - * @returns {Promise} - Resolves when all links have been reset and client is fully logged out - */ - - }, { - key: "logout", - value: function () { - var _logout = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { - var _iterator3, _step3, link; +var combinationFields = ['$or', '$nor', '$not']; +function isCombinationalField(field) { + return combinationFields.indexOf(field) > -1; +} - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - if (this.isLogged) { - _context3.next = 3; - break; - } +function getKey(obj) { + return Object.keys(obj)[0]; +} - _logger.default.warn("CozyClient isn't logged."); +function getValue(obj) { + return obj[getKey(obj)]; +} - return _context3.abrupt("return"); - case 3: - this.emit('beforeLogout'); - this.isLogged = false; +// flatten an array of selectors joined by an $and operator +function mergeAndedSelectors(selectors) { - if (!(this.stackClient instanceof _cozyStackClient.OAuthClient)) { - _context3.next = 17; - break; - } + // sort to ensure that e.g. if the user specified + // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into + // just {$gt: 'b'} + var res = {}; - _context3.prev = 6; + selectors.forEach(function (selector) { + Object.keys(selector).forEach(function (field) { + var matcher = selector[field]; + if (typeof matcher !== 'object') { + matcher = {$eq: matcher}; + } - if (!(this.stackClient.unregister && (!this.stackClient.isRegistered || this.stackClient.isRegistered()))) { - _context3.next = 10; - break; - } + if (isCombinationalField(field)) { + if (matcher instanceof Array) { + res[field] = matcher.map(function (m) { + return mergeAndedSelectors([m]); + }); + } else { + res[field] = mergeAndedSelectors([matcher]); + } + } else { + var fieldMatchers = res[field] = res[field] || {}; + Object.keys(matcher).forEach(function (operator) { + var value = matcher[operator]; - _context3.next = 10; - return this.stackClient.unregister(); + if (operator === '$gt' || operator === '$gte') { + return mergeGtGte(operator, value, fieldMatchers); + } else if (operator === '$lt' || operator === '$lte') { + return mergeLtLte(operator, value, fieldMatchers); + } else if (operator === '$ne') { + return mergeNe(value, fieldMatchers); + } else if (operator === '$eq') { + return mergeEq(value, fieldMatchers); + } + fieldMatchers[operator] = value; + }); + } + }); + }); - case 10: - _context3.next = 15; - break; + return res; +} - case 12: - _context3.prev = 12; - _context3.t0 = _context3["catch"](6); - _logger.default.warn("Impossible to unregister client on stack: ".concat(_context3.t0)); - case 15: - _context3.next = 25; - break; +// collapse logically equivalent gt/gte values +function mergeGtGte(operator, value, fieldMatchers) { + if (typeof fieldMatchers.$eq !== 'undefined') { + return; // do nothing + } + if (typeof fieldMatchers.$gte !== 'undefined') { + if (operator === '$gte') { + if (value > fieldMatchers.$gte) { // more specificity + fieldMatchers.$gte = value; + } + } else { // operator === '$gt' + if (value >= fieldMatchers.$gte) { // more specificity + delete fieldMatchers.$gte; + fieldMatchers.$gt = value; + } + } + } else if (typeof fieldMatchers.$gt !== 'undefined') { + if (operator === '$gte') { + if (value > fieldMatchers.$gt) { // more specificity + delete fieldMatchers.$gt; + fieldMatchers.$gte = value; + } + } else { // operator === '$gt' + if (value > fieldMatchers.$gt) { // more specificity + fieldMatchers.$gt = value; + } + } + } else { + fieldMatchers[operator] = value; + } +} - case 17: - _context3.prev = 17; - _context3.next = 20; - return this.stackClient.fetch('DELETE', '/auth/login'); +// collapse logically equivalent lt/lte values +function mergeLtLte(operator, value, fieldMatchers) { + if (typeof fieldMatchers.$eq !== 'undefined') { + return; // do nothing + } + if (typeof fieldMatchers.$lte !== 'undefined') { + if (operator === '$lte') { + if (value < fieldMatchers.$lte) { // more specificity + fieldMatchers.$lte = value; + } + } else { // operator === '$gt' + if (value <= fieldMatchers.$lte) { // more specificity + delete fieldMatchers.$lte; + fieldMatchers.$lt = value; + } + } + } else if (typeof fieldMatchers.$lt !== 'undefined') { + if (operator === '$lte') { + if (value < fieldMatchers.$lt) { // more specificity + delete fieldMatchers.$lt; + fieldMatchers.$lte = value; + } + } else { // operator === '$gt' + if (value < fieldMatchers.$lt) { // more specificity + fieldMatchers.$lt = value; + } + } + } else { + fieldMatchers[operator] = value; + } +} - case 20: - _context3.next = 25; - break; +// combine $ne values into one array +function mergeNe(value, fieldMatchers) { + if ('$ne' in fieldMatchers) { + // there are many things this could "not" be + fieldMatchers.$ne.push(value); + } else { // doesn't exist yet + fieldMatchers.$ne = [value]; + } +} - case 22: - _context3.prev = 22; - _context3.t1 = _context3["catch"](17); +// add $eq into the mix +function mergeEq(value, fieldMatchers) { + // these all have less specificity than the $eq + // TODO: check for user errors here + delete fieldMatchers.$gt; + delete fieldMatchers.$gte; + delete fieldMatchers.$lt; + delete fieldMatchers.$lte; + delete fieldMatchers.$ne; + fieldMatchers.$eq = value; +} - _logger.default.warn("Impossible to log out: ".concat(_context3.t1)); - case 25: - // clean information on links - _iterator3 = _createForOfIteratorHelper(this.links); - _context3.prev = 26; +// +// normalize the selector +// +function massageSelector(input) { + var result = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.clone)(input); + var wasAnded = false; + if ('$and' in result) { + result = mergeAndedSelectors(result['$and']); + wasAnded = true; + } - _iterator3.s(); + ['$or', '$nor'].forEach(function (orOrNor) { + if (orOrNor in result) { + // message each individual selector + // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}} + result[orOrNor].forEach(function (subSelector) { + var fields = Object.keys(subSelector); + for (var i = 0; i < fields.length; i++) { + var field = fields[i]; + var matcher = subSelector[field]; + if (typeof matcher !== 'object' || matcher === null) { + subSelector[field] = {$eq: matcher}; + } + } + }); + } + }); - case 28: - if ((_step3 = _iterator3.n()).done) { - _context3.next = 41; - break; - } + if ('$not' in result) { + //This feels a little like forcing, but it will work for now, + //I would like to come back to this and make the merging of selectors a little more generic + result['$not'] = mergeAndedSelectors([result['$not']]); + } - link = _step3.value; + var fields = Object.keys(result); - if (!link.reset) { - _context3.next = 39; - break; - } + for (var i = 0; i < fields.length; i++) { + var field = fields[i]; + var matcher = result[field]; - _context3.prev = 31; - _context3.next = 34; - return link.reset(); + if (typeof matcher !== 'object' || matcher === null) { + matcher = {$eq: matcher}; + } else if ('$ne' in matcher && !wasAnded) { + // I put these in an array, since there may be more than one + // but in the "mergeAnded" operation, I already take care of that + matcher.$ne = [matcher.$ne]; + } + result[field] = matcher; + } - case 34: - _context3.next = 39; - break; + return result; +} - case 36: - _context3.prev = 36; - _context3.t2 = _context3["catch"](31); - console.warn(_context3.t2); +// create a comparator based on the sort object +function createFieldSorter(sort) { - case 39: - _context3.next = 28; - break; + function getFieldValuesAsArray(doc) { + return sort.map(function (sorting) { + var fieldName = getKey(sorting); + var parsedField = parseField(fieldName); + var docFieldValue = getFieldFromDoc(doc, parsedField); + return docFieldValue; + }); + } - case 41: - _context3.next = 46; - break; + return function (aRow, bRow) { + var aFieldValues = getFieldValuesAsArray(aRow.doc); + var bFieldValues = getFieldValuesAsArray(bRow.doc); + var collation = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(aFieldValues, bFieldValues); + if (collation !== 0) { + return collation; + } + // this is what mango seems to do + return compare(aRow.doc._id, bRow.doc._id); + }; +} - case 43: - _context3.prev = 43; - _context3.t3 = _context3["catch"](26); +function filterInMemoryFields(rows, requestDef, inMemoryFields) { + rows = rows.filter(function (row) { + return rowFilter(row.doc, requestDef.selector, inMemoryFields); + }); - _iterator3.e(_context3.t3); + if (requestDef.sort) { + // in-memory sort + var fieldSorter = createFieldSorter(requestDef.sort); + rows = rows.sort(fieldSorter); + if (typeof requestDef.sort[0] !== 'string' && + getValue(requestDef.sort[0]) === 'desc') { + rows = rows.reverse(); + } + } - case 46: - _context3.prev = 46; + if ('limit' in requestDef || 'skip' in requestDef) { + // have to do the limit in-memory + var skip = requestDef.skip || 0; + var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip; + rows = rows.slice(skip, limit); + } + return rows; +} - _iterator3.f(); +function rowFilter(doc, selector, inMemoryFields) { + return inMemoryFields.every(function (field) { + var matcher = selector[field]; + var parsedField = parseField(field); + var docFieldValue = getFieldFromDoc(doc, parsedField); + if (isCombinationalField(field)) { + return matchCominationalSelector(field, matcher, doc); + } - return _context3.finish(46); + return matchSelector(matcher, doc, parsedField, docFieldValue); + }); +} - case 49: - if (this.store) { - this.dispatch((0, _store.resetState)()); - } +function matchSelector(matcher, doc, parsedField, docFieldValue) { + if (!matcher) { + // no filtering necessary; this field is just needed for sorting + return true; + } - this.emit('logout'); + return Object.keys(matcher).every(function (userOperator) { + var userValue = matcher[userOperator]; + return match(userOperator, doc, userValue, parsedField, docFieldValue); + }); +} - case 51: - case "end": - return _context3.stop(); - } - } - }, _callee3, this, [[6, 12], [17, 22], [26, 43, 46, 49], [31, 36]]); - })); +function matchCominationalSelector(field, matcher, doc) { - function logout() { - return _logout.apply(this, arguments); - } + if (field === '$or') { + return matcher.some(function (orMatchers) { + return rowFilter(doc, orMatchers, Object.keys(orMatchers)); + }); + } - return logout; - }() - /** - * Forwards to a stack client instance and returns - * a [DocumentCollection]{@link https://docs.cozy.io/en/cozy-client/api/cozy-stack-client/#DocumentCollection} instance. - * - * @param {string} doctype The collection doctype. - * @returns {DocumentCollection} Collection corresponding to the doctype - */ + if (field === '$not') { + return !rowFilter(doc, matcher, Object.keys(matcher)); + } - }, { - key: "collection", - value: function collection(doctype) { - return this.getStackClient().collection(doctype); - } - }, { - key: "fetch", - value: function fetch(method, path, body) { - var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; - return this.getStackClient().fetch(method, path, body, options); - } - }, { - key: "all", - value: function all(doctype) { - _logger.default.warn("\nclient.all is deprecated, prefer to use the Q helper to build a new QueryDefinition.\n\nimport { Q } from 'cozy-client'\nclient.query(Q('io.cozy.bills'))"); + //`$nor` + return !matcher.find(function (orMatchers) { + return rowFilter(doc, orMatchers, Object.keys(orMatchers)); + }); - return (0, _dsl.Q)(doctype); - } - }, { - key: "find", - value: function find(doctype) { - var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; - console.warn('client.find(doctype, selector) is deprecated, please use Q(doctype).where(selector) to build the same query.'); - return new _dsl.QueryDefinition({ - doctype: doctype, - selector: selector - }); - } - }, { - key: "get", - value: function get(doctype, id) { - console.warn("client.get(".concat(doctype, ", id) is deprecated, please use Q(").concat(doctype, ").getById(id) to build the same query.")); - return new _dsl.QueryDefinition({ - doctype: doctype, - id: id - }); - } - /** - * Creates a document and saves it on the server - * - * @param {string} type - Doctype of the document - * @param {object} doc - Document to save - * @param {ReferenceMap} [references] - References are a special kind of relationship - * that is not stored inside the referencer document, they are used for example between a photo - * and its album. You should not need to use it normally. - * @param {object} options - Mutation options - * - * @example - * ```js - * await client.create('io.cozy.todos', { - * label: 'My todo', - * relationships: { - * authors: { - * data: [{_id: 1, _type: 'io.cozy.persons'}] - * } - * } - * }) - * ``` - * - * @returns {Promise} - */ +} - }, { - key: "create", - value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(type, doc, references) { - var options, - _type, - attributes, - normalizedDoc, - ret, - _args4 = arguments; +function match(userOperator, doc, userValue, parsedField, docFieldValue) { + if (!matchers[userOperator]) { + throw new Error('unknown operator "' + userOperator + + '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' + + '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all'); + } + return matchers[userOperator](doc, userValue, parsedField, docFieldValue); +} - return _regenerator.default.wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - options = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {}; - _type = doc._type, attributes = (0, _objectWithoutProperties2.default)(doc, ["_type"]); - normalizedDoc = _objectSpread({ - _type: type - }, attributes); - _context4.next = 5; - return this.schema.validate(normalizedDoc); +function fieldExists(docFieldValue) { + return typeof docFieldValue !== 'undefined' && docFieldValue !== null; +} - case 5: - ret = _context4.sent; +function fieldIsNotUndefined(docFieldValue) { + return typeof docFieldValue !== 'undefined'; +} - if (!(ret !== true)) { - _context4.next = 8; - break; - } +function modField(docFieldValue, userValue) { + var divisor = userValue[0]; + var mod = userValue[1]; + if (divisor === 0) { + throw new Error('Bad divisor, cannot divide by zero'); + } - throw new Error('Validation failed'); + if (parseInt(divisor, 10) !== divisor ) { + throw new Error('Divisor is not an integer'); + } - case 8: - return _context4.abrupt("return", this.mutate(this.getDocumentSavePlan(normalizedDoc, references), options)); + if (parseInt(mod, 10) !== mod ) { + throw new Error('Modulus is not an integer'); + } - case 9: - case "end": - return _context4.stop(); - } - } - }, _callee4, this); - })); + if (parseInt(docFieldValue, 10) !== docFieldValue) { + return false; + } - function create(_x3, _x4, _x5) { - return _create.apply(this, arguments); - } + return docFieldValue % divisor === mod; +} - return create; - }() - }, { - key: "validate", - value: function validate(document) { - return this.schema.validate(document); +function arrayContainsValue(docFieldValue, userValue) { + return userValue.some(function (val) { + if (docFieldValue instanceof Array) { + return docFieldValue.indexOf(val) > -1; } - /** - * Create or update a document on the server - * - * @param {object} doc - Document to save - * @param {object} mutationOptions - Mutation options - * @returns {Promise} - */ - }, { - key: "save", - value: function () { - var _save = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(doc) { - var mutationOptions, - _type, - attributes, - normalizedDoc, - ret, - _args5 = arguments; + return docFieldValue === val; + }); +} - return _regenerator.default.wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - mutationOptions = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {}; - _type = doc._type, attributes = (0, _objectWithoutProperties2.default)(doc, ["_type"]); +function arrayContainsAllValues(docFieldValue, userValue) { + return userValue.every(function (val) { + return docFieldValue.indexOf(val) > -1; + }); +} - if (_type) { - _context5.next = 4; - break; - } +function arraySize(docFieldValue, userValue) { + return docFieldValue.length === userValue; +} - throw new Error('The document must have a `_type` property'); +function regexMatch(docFieldValue, userValue) { + var re = new RegExp(userValue); - case 4: - normalizedDoc = _objectSpread({ - _type: _type - }, attributes); - _context5.next = 7; - return this.schema.validate(normalizedDoc); + return re.test(docFieldValue); +} - case 7: - ret = _context5.sent; +function typeMatch(docFieldValue, userValue) { - if (!(ret !== true)) { - _context5.next = 10; - break; - } + switch (userValue) { + case 'null': + return docFieldValue === null; + case 'boolean': + return typeof (docFieldValue) === 'boolean'; + case 'number': + return typeof (docFieldValue) === 'number'; + case 'string': + return typeof (docFieldValue) === 'string'; + case 'array': + return docFieldValue instanceof Array; + case 'object': + return ({}).toString.call(docFieldValue) === '[object Object]'; + } - throw new Error('Validation failed'); + throw new Error(userValue + ' not supported as a type.' + + 'Please use one of object, string, array, number, boolean or null.'); - case 10: - return _context5.abrupt("return", this.mutate(this.getDocumentSavePlan(normalizedDoc), mutationOptions)); +} - case 11: - case "end": - return _context5.stop(); - } - } - }, _callee5, this); - })); +var matchers = { - function save(_x6) { - return _save.apply(this, arguments); - } + '$elemMatch': function (doc, userValue, parsedField, docFieldValue) { + if (!Array.isArray(docFieldValue)) { + return false; + } - return save; - }() - /** - * Saves multiple documents in one batch - * - Can only be called with documents from the same doctype - * - Does not support automatic creation of references - * - * @param {CozyClientDocument[]} docs - * @param {Object} mutationOptions - * @returns {Promise<void>} - */ + if (docFieldValue.length === 0) { + return false; + } - }, { - key: "saveAll", - value: function () { - var _saveAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(docs) { - var _this2 = this; + if (typeof docFieldValue[0] === 'object') { + return docFieldValue.some(function (val) { + return rowFilter(val, userValue, Object.keys(userValue)); + }); + } - var mutationOptions, - doctypes, - validations, - errors, - toSaveDocs, - mutation, - _args6 = arguments; - return _regenerator.default.wrap(function _callee6$(_context6) { - while (1) { - switch (_context6.prev = _context6.next) { - case 0: - mutationOptions = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {}; - doctypes = Array.from(new Set(docs.map(function (x) { - return x._type; - }))); + return docFieldValue.some(function (val) { + return matchSelector(userValue, doc, parsedField, val); + }); + }, - if (!(doctypes.length !== 1)) { - _context6.next = 4; - break; - } + '$allMatch': function (doc, userValue, parsedField, docFieldValue) { + if (!Array.isArray(docFieldValue)) { + return false; + } - throw new Error('saveAll can only save documents with the same doctype'); + /* istanbul ignore next */ + if (docFieldValue.length === 0) { + return false; + } - case 4: - _context6.next = 6; - return Promise.all(docs.map(function (d) { - return _this2.schema.validate(d); - })); + if (typeof docFieldValue[0] === 'object') { + return docFieldValue.every(function (val) { + return rowFilter(val, userValue, Object.keys(userValue)); + }); + } - case 6: - validations = _context6.sent; - errors = validations.filter(function (validation) { - return validation !== true; - }); + return docFieldValue.every(function (val) { + return matchSelector(userValue, doc, parsedField, val); + }); + }, - if (!(errors.length > 0)) { - _context6.next = 11; - break; - } + '$eq': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) === 0; + }, - console.warn('There has been some validation errors while bulk saving', errors); - throw new Error('Validation failed for at least one doc'); + '$gte': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) >= 0; + }, - case 11: - toSaveDocs = docs.map(function (d) { - return _this2.prepareDocumentForSave(d); - }); - mutation = _dsl.Mutations.updateDocuments(toSaveDocs); - return _context6.abrupt("return", this.mutate(mutation, mutationOptions)); + '$gt': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) > 0; + }, - case 14: - case "end": - return _context6.stop(); - } - } - }, _callee6, this); - })); + '$lte': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) <= 0; + }, - function saveAll(_x7) { - return _saveAll.apply(this, arguments); - } + '$lt': function (doc, userValue, parsedField, docFieldValue) { + return fieldIsNotUndefined(docFieldValue) && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, userValue) < 0; + }, - return saveAll; - }() - }, { - key: "ensureCozyMetadata", - value: function ensureCozyMetadata(document) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { - event: DOC_CREATION - }; - var METADATA_VERSION = 1; - if (this.appMetadata === undefined) return document; - var doctypeVersion; + '$exists': function (doc, userValue, parsedField, docFieldValue) { + //a field that is null is still considered to exist + if (userValue) { + return fieldIsNotUndefined(docFieldValue); + } - if (document._type) { - var schema = this.schema.getDoctypeSchema(document._type); - doctypeVersion = (0, _get.default)(schema, 'doctypeVersion'); - } + return !fieldIsNotUndefined(docFieldValue); + }, - var _this$appMetadata = this.appMetadata, - slug = _this$appMetadata.slug, - sourceAccount = _this$appMetadata.sourceAccount, - version = _this$appMetadata.version; - var now = new Date().toISOString(); - var cozyMetadata = (0, _get.default)(document, 'cozyMetadata', {}); + '$mod': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && modField(docFieldValue, userValue); + }, - if (options.event === DOC_CREATION) { - cozyMetadata = _objectSpread({ - metadataVersion: METADATA_VERSION, - doctypeVersion: doctypeVersion, - createdByApp: slug, - sourceAccount: sourceAccount, - createdAt: now, - createdByAppVersion: version, - updatedAt: now, - updatedByApps: slug ? [{ - date: now, - slug: slug, - version: version - }] : [] - }, cozyMetadata); - } else if (options.event === DOC_UPDATE) { - cozyMetadata = _objectSpread(_objectSpread({}, cozyMetadata), {}, { - updatedAt: now, - updatedByApps: [{ - date: now, - slug: slug, - version: version - }].concat((0, _toConsumableArray2.default)((0, _get.default)(document, 'cozyMetadata.updatedByApps', []).filter(function (info) { - return info.slug !== slug; - }))) - }); - } + '$ne': function (doc, userValue, parsedField, docFieldValue) { + return userValue.every(function (neValue) { + return (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_1__.collate)(docFieldValue, neValue) !== 0; + }); + }, + '$in': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue); + }, - return _objectSpread(_objectSpread({}, document), {}, { - cozyMetadata: cozyMetadata - }); - } - /** - * Dehydrates and adds metadata before saving a document - * - * @param {CozyClientDocument} doc - Document that will be saved - * @returns {CozyClientDocument} - */ + '$nin': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue); + }, - }, { - key: "prepareDocumentForSave", - value: function prepareDocumentForSave(doc) { - var isNewDoc = !doc._rev; - var dehydratedDoc = this.ensureCozyMetadata((0, _helpers2.dehydrate)(doc), { - event: isNewDoc ? DOC_CREATION : DOC_UPDATE - }); - return dehydratedDoc; - } - /** - * Creates a list of mutations to execute to create a document and its relationships. - * - * ```js - * const baseDoc = { _type: 'io.cozy.todo', label: 'Go hiking' } - * // relations can be arrays or single objects - * const relationships = { - * attachments: [{ _id: 12345, _type: 'io.cozy.files' }, { _id: 6789, _type: 'io.cozy.files' }], - * bills: { _id: 9999, _type: 'io.cozy.bills' } - * } - * client.getDocumentSavePlan(baseDoc, relationships) - * ``` - * - * - * @param {object} document - Document to create - * @param {ReferenceMap} [referencesByName] - References to the created document. The - * relationship class associated to each reference list should support references, otherwise this - * method will throw. - * - * @returns {Mutation[]|Mutation} One or more mutation to execute - */ + '$size': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue); + }, - }, { - key: "getDocumentSavePlan", - value: function getDocumentSavePlan(document, referencesByName) { - var _this3 = this; + '$all': function (doc, userValue, parsedField, docFieldValue) { + return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue); + }, - var isNewDoc = !document._rev; - var docToSave = this.prepareDocumentForSave(document); - var saveMutation = isNewDoc ? _dsl.Mutations.createDocument(docToSave) : _dsl.Mutations.updateDocument(docToSave); - var hasReferences = referencesByName && Object.values(referencesByName).filter(function (references) { - return Array.isArray(references) ? references.length > 0 : references; - }).length > 0; + '$regex': function (doc, userValue, parsedField, docFieldValue) { + return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue); + }, + + '$type': function (doc, userValue, parsedField, docFieldValue) { + return typeMatch(docFieldValue, userValue); + } +}; + +// return true if the given doc matches the supplied selector +function matchesSelector(doc, selector) { + /* istanbul ignore if */ + if (typeof selector !== 'object') { + // match the CouchDB error message + throw new Error('Selector error: expected a JSON object'); + } - if (!hasReferences) { - return saveMutation; - } else { - for (var _i = 0, _Object$keys = Object.keys(referencesByName); _i < _Object$keys.length; _i++) { - var relName = _Object$keys[_i]; - var doctype = document._type; - var doctypeRelationship = this.schema.getRelationship(doctype, relName); - var relationshipClass = doctypeRelationship.type; + selector = massageSelector(selector); + var row = { + 'doc': doc + }; - if (!supportsReferences(relationshipClass)) { - throw referencesUnsupportedError(doctypeRelationship.name); - } - } - } + var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector)); + return rowsMatched && rowsMatched.length === 1; +} - if (referencesByName && !isNewDoc) { - throw new Error('Unable to save external relationships on a not-new document'); - } - return [saveMutation, function (response) { - var doc = _this3.hydrateDocument(response.data); - return Object.entries(referencesByName).map(function (_ref2) { - var _ref3 = (0, _slicedToArray2.default)(_ref2, 2), - relName = _ref3[0], - references = _ref3[1]; - var relationship = doc[relName]; - return relationship.addReferences(references); - }); - }]; - } - /** - * Hooks are an observable system for events on documents. - * There are at the moment only 2 hooks available. - * - * - before:destroy, called just before a document is destroyed via CozyClient::destroy - * - after:destroy, called after a document is destroyed via CozyClient::destroy - * - * @example - * ``` - * CozyClient.registerHook('io.cozy.bank.accounts', 'before:destroy', () => { - * console.log('A io.cozy.bank.accounts is being destroyed') - * }) - * ``` - * - * @param {string} doctype - Doctype on which the hook will be registered - * @param {string} name - Name of the hook - * @param {Function} fn - Callback to be executed - */ +/***/ }), +/* 516 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - }, { - key: "triggerHook", - value: function triggerHook(name, document) { - if (!CozyClient.hooks) return; - var allHooks = CozyClient.hooks[document._type] || {}; - var hooks = allHooks[name] || []; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "collate": () => (/* binding */ collate), +/* harmony export */ "normalizeKey": () => (/* binding */ normalizeKey), +/* harmony export */ "toIndexableString": () => (/* binding */ toIndexableString), +/* harmony export */ "parseIndexableString": () => (/* binding */ parseIndexableString) +/* harmony export */ }); +function pad(str, padWith, upToLength) { + var padding = ''; + var targetLength = upToLength - str.length; + /* istanbul ignore next */ + while (padding.length < targetLength) { + padding += padWith; + } + return padding; +} - var _iterator4 = _createForOfIteratorHelper(hooks), - _step4; +function padLeft(str, padWith, upToLength) { + var padding = pad(str, padWith, upToLength); + return padding + str; +} - try { - for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { - var h = _step4.value; - h(this, document); - } - } catch (err) { - _iterator4.e(err); - } finally { - _iterator4.f(); - } - } - /** - * Destroys a document. {before,after}:destroy hooks will be fired. - * - * @param {CozyClientDocument} document - Document to be deleted - * @returns {Promise<CozyClientDocument>} The document that has been deleted - */ +var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE +var MAGNITUDE_DIGITS = 3; // ditto +var SEP = ''; // set to '_' for easier debugging - }, { - key: "destroy", - value: function () { - var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(document) { - var mutationOptions, - res, - _args7 = arguments; - return _regenerator.default.wrap(function _callee7$(_context7) { - while (1) { - switch (_context7.prev = _context7.next) { - case 0: - mutationOptions = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {}; - _context7.next = 3; - return this.triggerHook('before:destroy', document); +function collate(a, b) { - case 3: - _context7.next = 5; - return this.mutate(_dsl.Mutations.deleteDocument(document), mutationOptions); + if (a === b) { + return 0; + } - case 5: - res = _context7.sent; - _context7.next = 8; - return this.triggerHook('after:destroy', document); + a = normalizeKey(a); + b = normalizeKey(b); - case 8: - return _context7.abrupt("return", res); + var ai = collationIndex(a); + var bi = collationIndex(b); + if ((ai - bi) !== 0) { + return ai - bi; + } + switch (typeof a) { + case 'number': + return a - b; + case 'boolean': + return a < b ? -1 : 1; + case 'string': + return stringCollate(a, b); + } + return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b); +} - case 9: - case "end": - return _context7.stop(); +// couch considers null/NaN/Infinity/-Infinity === undefined, +// for the purposes of mapreduce indexes. also, dates get stringified. +function normalizeKey(key) { + switch (typeof key) { + case 'undefined': + return null; + case 'number': + if (key === Infinity || key === -Infinity || isNaN(key)) { + return null; + } + return key; + case 'object': + var origKey = key; + if (Array.isArray(key)) { + var len = key.length; + key = new Array(len); + for (var i = 0; i < len; i++) { + key[i] = normalizeKey(origKey[i]); + } + /* istanbul ignore next */ + } else if (key instanceof Date) { + return key.toJSON(); + } else if (key !== null) { // generic object + key = {}; + for (var k in origKey) { + if (origKey.hasOwnProperty(k)) { + var val = origKey[k]; + if (typeof val !== 'undefined') { + key[k] = normalizeKey(val); } } - }, _callee7, this); - })); - - function destroy(_x8) { - return _destroy.apply(this, arguments); + } } + } + return key; +} - return destroy; - }() - }, { - key: "upload", - value: function upload(file, dirPath) { - var mutationOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - return this.mutate(_dsl.Mutations.uploadFile(file, dirPath), mutationOptions); +function indexify(key) { + if (key !== null) { + switch (typeof key) { + case 'boolean': + return key ? 1 : 0; + case 'number': + return numToIndexableString(key); + case 'string': + // We've to be sure that key does not contain \u0000 + // Do order-preserving replacements: + // 0 -> 1, 1 + // 1 -> 1, 2 + // 2 -> 2, 2 + /* eslint-disable no-control-regex */ + return key + .replace(/\u0002/g, '\u0002\u0002') + .replace(/\u0001/g, '\u0001\u0002') + .replace(/\u0000/g, '\u0001\u0001'); + /* eslint-enable no-control-regex */ + case 'object': + var isArray = Array.isArray(key); + var arr = isArray ? key : Object.keys(key); + var i = -1; + var len = arr.length; + var result = ''; + if (isArray) { + while (++i < len) { + result += toIndexableString(arr[i]); + } + } else { + while (++i < len) { + var objKey = arr[i]; + result += toIndexableString(objKey) + + toIndexableString(key[objKey]); + } + } + return result; } - /** - * Makes sure that the query exists in the store - * - * @param {string} queryId - Id of the query - * @param {QueryDefinition} queryDefinition - Definition of the query - * @param {QueryOptions} [options] - Additional options - */ + } + return ''; +} - }, { - key: "ensureQueryExists", - value: function ensureQueryExists(queryId, queryDefinition, options) { - this.ensureStore(); - var existingQuery = (0, _store.getQueryFromState)(this.store.getState(), queryId); // Don't trigger the INIT_QUERY for fetchMore() calls +// convert the given key to a string that would be appropriate +// for lexical sorting, e.g. within a database, where the +// sorting is the same given by the collate() function. +function toIndexableString(key) { + var zero = '\u0000'; + key = normalizeKey(key); + return collationIndex(key) + SEP + indexify(key) + zero; +} - if (existingQuery.fetchStatus !== 'loaded' || !queryDefinition.skip && !queryDefinition.bookmark) { - this.dispatch((0, _store.initQuery)(queryId, queryDefinition, options)); +function parseNumber(str, i) { + var originalIdx = i; + var num; + var zero = str[i] === '1'; + if (zero) { + num = 0; + i++; + } else { + var neg = str[i] === '0'; + i++; + var numAsString = ''; + var magAsString = str.substring(i, i + MAGNITUDE_DIGITS); + var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE; + /* istanbul ignore next */ + if (neg) { + magnitude = -magnitude; + } + i += MAGNITUDE_DIGITS; + while (true) { + var ch = str[i]; + if (ch === '\u0000') { + break; + } else { + numAsString += ch; } + i++; } - /** - * Executes a query and returns its results. - * - * Results from the query will be saved internally and can be retrieved via - * `getQueryFromState` or directly using `<Query />`. `<Query />` automatically - * executes its query when mounted if no fetch policy has been indicated. - * - * @param {QueryDefinition} queryDefinition - Definition that will be executed - * @param {QueryOptions} [options] - Options - * @returns {Promise<QueryResult>} - */ - - }, { - key: "query", - value: function () { - var _query = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(queryDefinition) { - var _this4 = this; - - var _ref4, - update, - options, - queryId, - existingQuery, - shouldFetch, - response, - _args8 = arguments; + numAsString = numAsString.split('.'); + if (numAsString.length === 1) { + num = parseInt(numAsString, 10); + } else { + /* istanbul ignore next */ + num = parseFloat(numAsString[0] + '.' + numAsString[1]); + } + /* istanbul ignore next */ + if (neg) { + num = num - 10; + } + /* istanbul ignore next */ + if (magnitude !== 0) { + // parseFloat is more reliable than pow due to rounding errors + // e.g. Number.MAX_VALUE would return Infinity if we did + // num * Math.pow(10, magnitude); + num = parseFloat(num + 'e' + magnitude); + } + } + return {num: num, length : i - originalIdx}; +} - return _regenerator.default.wrap(function _callee8$(_context8) { - while (1) { - switch (_context8.prev = _context8.next) { - case 0: - _ref4 = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {}; - update = _ref4.update, options = (0, _objectWithoutProperties2.default)(_ref4, ["update"]); - this.ensureStore(); - queryId = options.as || this.queryIdGenerator.generateId(queryDefinition); - existingQuery = this.getQueryFromState(queryId); +// move up the stack while parsing +// this function moved outside of parseIndexableString for performance +function pop(stack, metaStack) { + var obj = stack.pop(); - if (!options.fetchPolicy) { - _context8.next = 11; - break; - } + if (metaStack.length) { + var lastMetaElement = metaStack[metaStack.length - 1]; + if (obj === lastMetaElement.element) { + // popping a meta-element, e.g. an object whose value is another object + metaStack.pop(); + lastMetaElement = metaStack[metaStack.length - 1]; + } + var element = lastMetaElement.element; + var lastElementIndex = lastMetaElement.index; + if (Array.isArray(element)) { + element.push(obj); + } else if (lastElementIndex === stack.length - 2) { // obj with key+value + var key = stack.pop(); + element[key] = obj; + } else { + stack.push(obj); // obj with key only + } + } +} - if (options.as) { - _context8.next = 8; - break; - } +function parseIndexableString(str) { + var stack = []; + var metaStack = []; // stack for arrays and objects + var i = 0; - throw new Error('Cannot use `fetchPolicy` without naming the query, please use `as` to name the query'); + /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/ + while (true) { + var collationIndex = str[i++]; + if (collationIndex === '\u0000') { + if (stack.length === 1) { + return stack.pop(); + } else { + pop(stack, metaStack); + continue; + } + } + switch (collationIndex) { + case '1': + stack.push(null); + break; + case '2': + stack.push(str[i] === '1'); + i++; + break; + case '3': + var parsedNum = parseNumber(str, i); + stack.push(parsedNum.num); + i += parsedNum.length; + break; + case '4': + var parsedStr = ''; + /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/ + while (true) { + var ch = str[i]; + if (ch === '\u0000') { + break; + } + parsedStr += ch; + i++; + } + // perform the reverse of the order-preserving replacement + // algorithm (see above) + /* eslint-disable no-control-regex */ + parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000') + .replace(/\u0001\u0002/g, '\u0001') + .replace(/\u0002\u0002/g, '\u0002'); + /* eslint-enable no-control-regex */ + stack.push(parsedStr); + break; + case '5': + var arrayElement = { element: [], index: stack.length }; + stack.push(arrayElement.element); + metaStack.push(arrayElement); + break; + case '6': + var objElement = { element: {}, index: stack.length }; + stack.push(objElement.element); + metaStack.push(objElement); + break; + /* istanbul ignore next */ + default: + throw new Error( + 'bad collationIndex or unexpectedly reached end of input: ' + + collationIndex); + } + } +} - case 8: - shouldFetch = options.fetchPolicy(existingQuery); +function arrayCollate(a, b) { + var len = Math.min(a.length, b.length); + for (var i = 0; i < len; i++) { + var sort = collate(a[i], b[i]); + if (sort !== 0) { + return sort; + } + } + return (a.length === b.length) ? 0 : + (a.length > b.length) ? 1 : -1; +} +function stringCollate(a, b) { + // See: https://github.com/daleharvey/pouchdb/issues/40 + // This is incompatible with the CouchDB implementation, but its the + // best we can do for now + return (a === b) ? 0 : ((a > b) ? 1 : -1); +} +function objectCollate(a, b) { + var ak = Object.keys(a), bk = Object.keys(b); + var len = Math.min(ak.length, bk.length); + for (var i = 0; i < len; i++) { + // First sort the keys + var sort = collate(ak[i], bk[i]); + if (sort !== 0) { + return sort; + } + // if the keys are equal sort the values + sort = collate(a[ak[i]], b[bk[i]]); + if (sort !== 0) { + return sort; + } - if (shouldFetch) { - _context8.next = 11; - break; - } + } + return (ak.length === bk.length) ? 0 : + (ak.length > bk.length) ? 1 : -1; +} +// The collation is defined by erlangs ordered terms +// the atoms null, true, false come first, then numbers, strings, +// arrays, then objects +// null/undefined/NaN/Infinity/-Infinity are all considered null +function collationIndex(x) { + var id = ['boolean', 'number', 'string', 'object']; + var idx = id.indexOf(typeof x); + //false if -1 otherwise true, but fast!!!!1 + if (~idx) { + if (x === null) { + return 1; + } + if (Array.isArray(x)) { + return 5; + } + return idx < 3 ? (idx + 2) : (idx + 3); + } + /* istanbul ignore next */ + if (Array.isArray(x)) { + return 5; + } +} - return _context8.abrupt("return"); +// conversion: +// x yyy zz...zz +// x = 0 for negative, 1 for 0, 2 for positive +// y = exponent (for negative numbers negated) moved so that it's >= 0 +// z = mantisse +function numToIndexableString(num) { - case 11: - if (!(existingQuery && Object.keys(existingQuery).length > 0)) { - _context8.next = 14; - break; - } + if (num === 0) { + return '1'; + } - if (!(existingQuery.fetchStatus === 'loading')) { - _context8.next = 14; - break; - } + // convert number to exponential format for easier and + // more succinct string sorting + var expFormat = num.toExponential().split(/e\+?/); + var magnitude = parseInt(expFormat[1], 10); - return _context8.abrupt("return", this._promiseCache.get(function () { - return (0, _jsonStableStringify.default)(queryDefinition); - })); + var neg = num < 0; - case 14: - this.ensureQueryExists(queryId, queryDefinition, options); - _context8.prev = 15; - this.dispatch((0, _store.loadQuery)(queryId)); - _context8.next = 19; - return this._promiseCache.exec(function () { - return _this4.requestQuery(queryDefinition); - }, function () { - return (0, _jsonStableStringify.default)(queryDefinition); - }); + var result = neg ? '0' : '2'; - case 19: - response = _context8.sent; - this.dispatch((0, _store.receiveQueryResult)(queryId, response, { - update: update - })); - return _context8.abrupt("return", response); + // first sort by magnitude + // it's easier if all magnitudes are positive + var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE); + var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS); - case 24: - _context8.prev = 24; - _context8.t0 = _context8["catch"](15); - this.dispatch((0, _store.receiveQueryError)(queryId, _context8.t0)); // specific onError + result += SEP + magString; - if (!options.onError) { - _context8.next = 31; - break; - } + // then sort by the factor + var factor = Math.abs(parseFloat(expFormat[0])); // [1..10) + /* istanbul ignore next */ + if (neg) { // for negative reverse ordering + factor = 10 - factor; + } - options.onError(_context8.t0); // defaulted onError + var factorStr = factor.toFixed(20); - _context8.next = 36; - break; + // strip zeros from the end + factorStr = factorStr.replace(/\.?0+$/, ''); - case 31: - if (!this.options.onError) { - _context8.next = 35; - break; - } + result += SEP + factorStr; - this.options.onError(_context8.t0); - _context8.next = 36; - break; + return result; +} - case 35: - throw _context8.t0; - case 36: - case "end": - return _context8.stop(); - } - } - }, _callee8, this, [[15, 24]]); - })); - function query(_x9) { - return _query.apply(this, arguments); - } - return query; - }() - /** - * Will fetch all documents for a `queryDefinition`, automatically fetching more - * documents if the total of documents is superior to the pagination limit. Can - * result in a lot of network requests. - * - * @param {QueryDefinition} queryDefinition - Definition to be executed - * @param {QueryOptions} [options] - Options - * @returns {Promise<QueryResult>} All documents matching the query - */ +/***/ }), +/* 517 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - }, { - key: "queryAll", - value: function () { - var _queryAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(queryDefinition) { - var options, - queryId, - mergedOptions, - resp, - documents, - currentResult, - _args9 = arguments; - return _regenerator.default.wrap(function _callee9$(_context9) { - while (1) { - switch (_context9.prev = _context9.next) { - case 0: - options = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : {}; - queryId = options.as || this.queryIdGenerator.generateId(queryDefinition); - mergedOptions = _objectSpread(_objectSpread({}, options), {}, { - as: queryId - }); - _context9.next = 5; - return this.query(queryDefinition, mergedOptions); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(507); +/* harmony import */ var pouchdb_md5__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(511); +/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(509); +/* harmony import */ var pouchdb_binary_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(518); +/* harmony import */ var pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(516); +/* harmony import */ var pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(510); +/* harmony import */ var pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(512); +/* harmony import */ var pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(520); - case 5: - resp = _context9.sent; - documents = resp.data; - case 7: - if (!(resp && resp.next)) { - _context9.next = 21; - break; - } - if (!resp.bookmark) { - _context9.next = 14; - break; - } - _context9.next = 11; - return this.query(queryDefinition.offsetBookmark(resp.bookmark), mergedOptions); - case 11: - resp = _context9.sent; - _context9.next = 18; - break; - case 14: - currentResult = (0, _store.getRawQueryFromState)(this.store.getState(), queryId); - _context9.next = 17; - return this.query(queryDefinition.offset(currentResult.data.length), mergedOptions); - case 17: - resp = _context9.sent; - case 18: - documents.push.apply(documents, (0, _toConsumableArray2.default)(resp.data)); - _context9.next = 7; - break; - case 21: - return _context9.abrupt("return", documents); +/* + * Simple task queue to sequentialize actions. Assumes + * callbacks will eventually fire (once). + */ - case 22: - case "end": - return _context9.stop(); - } - } - }, _callee9, this); - })); - function queryAll(_x10) { - return _queryAll.apply(this, arguments); - } +function TaskQueue() { + this.promise = new Promise(function (fulfill) {fulfill(); }); +} +TaskQueue.prototype.add = function (promiseFactory) { + this.promise = this.promise.catch(function () { + // just recover + }).then(function () { + return promiseFactory(); + }); + return this.promise; +}; +TaskQueue.prototype.finish = function () { + return this.promise; +}; - return queryAll; - }() - }, { - key: "watchQuery", - value: function watchQuery() { - console.warn('client.watchQuery is deprecated, please use client.makeObservableQuery.'); - return this.makeObservableQuery.apply(this, arguments); - } - }, { - key: "makeObservableQuery", - value: function makeObservableQuery(queryDefinition) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - this.ensureStore(); - var queryId = options.as || this.queryIdGenerator.generateId(queryDefinition); - this.ensureQueryExists(queryId, queryDefinition); - return new _ObservableQuery.default(queryId, queryDefinition, this, options); - } - /** - * Mutate a document - * - * @param {object} mutationDefinition - Describe the mutation - * @param {object} [options] - Options - * @param {string} [options.as] - Mutation id - * @param {Function} [options.update] - Function to update the document - * @param {Function} [options.updateQueries] - Function to update queries - * @returns {Promise} - */ +function stringify(input) { + if (!input) { + return 'undefined'; // backwards compat for empty reduce + } + // for backwards compat with mapreduce, functions/strings are stringified + // as-is. everything else is JSON-stringified. + switch (typeof input) { + case 'function': + // e.g. a mapreduce map + return input.toString(); + case 'string': + // e.g. a mapreduce built-in _reduce function + return input.toString(); + default: + // e.g. a JSON object in the case of mango queries + return JSON.stringify(input); + } +} - }, { - key: "mutate", - value: function () { - var _mutate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(mutationDefinition) { - var _ref5, - update, - updateQueries, - options, - mutationId, - response, - _args10 = arguments; +/* create a string signature for a view so we can cache it and uniq it */ +function createViewSignature(mapFun, reduceFun) { + // the "undefined" part is for backwards compatibility + return stringify(mapFun) + stringify(reduceFun) + 'undefined'; +} - return _regenerator.default.wrap(function _callee10$(_context10) { - while (1) { - switch (_context10.prev = _context10.next) { - case 0: - _ref5 = _args10.length > 1 && _args10[1] !== undefined ? _args10[1] : {}; - update = _ref5.update, updateQueries = _ref5.updateQueries, options = (0, _objectWithoutProperties2.default)(_ref5, ["update", "updateQueries"]); - this.ensureStore(); - mutationId = options.as || this.queryIdGenerator.generateId(mutationDefinition); - this.dispatch((0, _store.initMutation)(mutationId, mutationDefinition)); - _context10.prev = 5; - _context10.next = 8; - return this.requestMutation(mutationDefinition); +function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) { + var viewSignature = createViewSignature(mapFun, reduceFun); - case 8: - response = _context10.sent; - this.dispatch((0, _store.receiveMutationResult)(mutationId, response, { - update: update, - updateQueries: updateQueries - }, mutationDefinition)); - return _context10.abrupt("return", response); + var cachedViews; + if (!temporary) { + // cache this to ensure we don't try to update the same view twice + cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {}; + if (cachedViews[viewSignature]) { + return cachedViews[viewSignature]; + } + } - case 13: - _context10.prev = 13; - _context10.t0 = _context10["catch"](5); - this.dispatch((0, _store.receiveMutationError)(mutationId, _context10.t0, mutationDefinition)); - throw _context10.t0; + var promiseForView = sourceDB.info().then(function (info) { - case 17: - case "end": - return _context10.stop(); - } - } - }, _callee10, this, [[5, 13]]); - })); + var depDbName = info.db_name + '-mrview-' + + (temporary ? 'temp' : (0,pouchdb_md5__WEBPACK_IMPORTED_MODULE_1__.stringMd5)(viewSignature)); - function mutate(_x11) { - return _mutate.apply(this, arguments); + // save the view name in the source db so it can be cleaned up if necessary + // (e.g. when the _design doc is deleted, remove all associated view data) + function diffFunction(doc) { + doc.views = doc.views || {}; + var fullViewName = viewName; + if (fullViewName.indexOf('/') === -1) { + fullViewName = viewName + '/' + viewName; } - - return mutate; - }() - /** - * Executes a query through links and fetches relationships - * - * @private - * @param {QueryDefinition} definition QueryDefinition to be executed - * @returns {Promise<ClientResponse>} - */ - - }, { - key: "requestQuery", - value: function () { - var _requestQuery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(definition) { - var mainResponse, withIncluded; - return _regenerator.default.wrap(function _callee11$(_context11) { - while (1) { - switch (_context11.prev = _context11.next) { - case 0: - _context11.next = 2; - return this.chain.request(definition); - - case 2: - mainResponse = _context11.sent; - - if (definition.includes) { - _context11.next = 5; - break; - } - - return _context11.abrupt("return", mainResponse); - - case 5: - _context11.next = 7; - return this.fetchRelationships(mainResponse, this.getIncludesRelationships(definition)); - - case 7: - withIncluded = _context11.sent; - return _context11.abrupt("return", withIncluded); - - case 9: - case "end": - return _context11.stop(); - } - } - }, _callee11, this); - })); - - function requestQuery(_x12) { - return _requestQuery.apply(this, arguments); + var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {}; + /* istanbul ignore if */ + if (depDbs[depDbName]) { + return; // no update necessary } + depDbs[depDbName] = true; + return doc; + } + return (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.upsert)(sourceDB, '_local/' + localDocName, diffFunction).then(function () { + return sourceDB.registerDependentDatabase(depDbName).then(function (res) { + var db = res.db; + db.auto_compaction = true; + var view = { + name: depDbName, + db: db, + sourceDB: sourceDB, + adapter: sourceDB.adapter, + mapFun: mapFun, + reduceFun: reduceFun + }; + return view.db.get('_local/lastSeq').catch(function (err) { + /* istanbul ignore if */ + if (err.status !== 404) { + throw err; + } + }).then(function (lastSeqDoc) { + view.seq = lastSeqDoc ? lastSeqDoc.seq : 0; + if (cachedViews) { + view.db.once('destroyed', function () { + delete cachedViews[viewSignature]; + }); + } + return view; + }); + }); + }); + }); - return requestQuery; - }() - /** - * Fetch relationships for a response (can be several docs). - * Fills the `relationships` attribute of each documents. - * - * Can potentially result in several fetch requests. - * Queries are optimized before being sent (multiple single documents queries can be packed into - * one multiple document query) for example. - * - * @private - */ - - }, { - key: "fetchRelationships", - value: function () { - var _fetchRelationships = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(response, relationshipsByName) { - var _this5 = this; + if (cachedViews) { + cachedViews[viewSignature] = promiseForView; + } + return promiseForView; +} - var isSingleDoc, responseDocs, queryDefToDocIdAndRel, documents, definitions, optimizedDefinitions, responses, uniqueDocuments, included, relationshipsByDocId, _iterator5, _step5, _step5$value, def, resp, docIdAndRel, _docIdAndRel, docId, relName; +var persistentQueues = {}; +var tempViewQueue = new TaskQueue(); +var CHANGES_BATCH_SIZE = 50; - return _regenerator.default.wrap(function _callee12$(_context12) { - while (1) { - switch (_context12.prev = _context12.next) { - case 0: - isSingleDoc = !Array.isArray(response.data); +function parseViewName(name) { + // can be either 'ddocname/viewname' or just 'viewname' + // (where the ddoc name is the same) + return name.indexOf('/') === -1 ? [name, name] : name.split('/'); +} - if (!(!isSingleDoc && response.data.length === 0)) { - _context12.next = 3; - break; - } +function isGenOne(changes) { + // only return true if the current change is 1- + // and there are no other leafs + return changes.length === 1 && /^1-/.test(changes[0].rev); +} - return _context12.abrupt("return", response); +function emitError(db, e) { + try { + db.emit('error', e); + } catch (err) { + (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.guardedConsole)('error', + 'The user\'s map/reduce function threw an uncaught error.\n' + + 'You can debug this error by doing:\n' + + 'myDatabase.on(\'error\', function (err) { debugger; });\n' + + 'Please double-check your map/reduce function.'); + (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.guardedConsole)('error', e); + } +} - case 3: - responseDocs = isSingleDoc ? [response.data] : response.data; - queryDefToDocIdAndRel = new Map(); - documents = []; - definitions = []; - responseDocs.forEach(function (doc) { - return (0, _forEach.default)(relationshipsByName, function (relationship, relName) { - try { - var queryDef = relationship.type.query(doc, _this5, relationship); - var docId = doc._id; // Used to reattach responses into the relationships attribute of - // each document +/** + * Returns an "abstract" mapreduce object of the form: + * + * { + * query: queryFun, + * viewCleanup: viewCleanupFun + * } + * + * Arguments are: + * + * localDoc: string + * This is for the local doc that gets saved in order to track the + * "dependent" DBs and clean them up for viewCleanup. It should be + * unique, so that indexer plugins don't collide with each other. + * mapper: function (mapFunDef, emit) + * Returns a map function based on the mapFunDef, which in the case of + * normal map/reduce is just the de-stringified function, but may be + * something else, such as an object in the case of pouchdb-find. + * reducer: function (reduceFunDef) + * Ditto, but for reducing. Modules don't have to support reducing + * (e.g. pouchdb-find). + * ddocValidator: function (ddoc, viewName) + * Throws an error if the ddoc or viewName is not valid. + * This could be a way to communicate to the user that the configuration for the + * indexer is invalid. + */ +function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) { - queryDefToDocIdAndRel.set(queryDef, [docId, relName]); // Relationships can yield "queries" that are already resolved documents. - // These do not need to go through the usual link request mechanism. + function tryMap(db, fun, doc) { + // emit an event if there was an error thrown by a map function. + // putting try/catches in a single function also avoids deoptimizations. + try { + fun(doc); + } catch (e) { + emitError(db, e); + } + } - if (queryDef instanceof _dsl.QueryDefinition) { - definitions.push(queryDef); - } else { - documents.push(queryDef); - } - } catch (_unused) {// eslint-disable-next-line - // We do not crash completely if one the relationship behaves badly and - // throws - } - }); - }); // Definitions can be in optimized/regrouped in case of HasMany relationships. + function tryReduce(db, fun, keys, values, rereduce) { + // same as above, but returning the result or an error. there are two separate + // functions to avoid extra memory allocations since the tryCode() case is used + // for custom map functions (common) vs this function, which is only used for + // custom reduce functions (rare) + try { + return {output : fun(keys, values, rereduce)}; + } catch (e) { + emitError(db, e); + return {error: e}; + } + } - optimizedDefinitions = (0, _optimize.default)(definitions); - _context12.next = 11; - return Promise.all(optimizedDefinitions.map(function (req) { - return _this5.chain.request(req); - })); + function sortByKeyThenValue(x, y) { + var keyCompare = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(x.key, y.key); + return keyCompare !== 0 ? keyCompare : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(x.value, y.value); + } - case 11: - responses = _context12.sent; - // "Included" documents will be stored in the `documents` store - uniqueDocuments = (0, _uniqBy.default)((0, _flatten.default)(documents), '_id'); - included = (0, _flatten.default)(responses.map(function (r) { - return r.included || r.data; - })).concat(uniqueDocuments).filter(Boolean); // Some relationships have the relationship data on the other side of the - // relationship (ex: io.cozy.photos.albums do not have photo inclusion information, - // it is on the io.cozy.files side). - // Here we take the data received from the relationship queries, and group - // it so that we can fill the `relationships` attribute of each doc before - // storing the document. This makes the data easier to manipulate for the front-end. + function sliceResults(results, limit, skip) { + skip = skip || 0; + if (typeof limit === 'number') { + return results.slice(skip, limit + skip); + } else if (skip > 0) { + return results.slice(skip); + } + return results; + } - relationshipsByDocId = {}; - _iterator5 = _createForOfIteratorHelper((0, _zip.default)(optimizedDefinitions, responses)); + function rowToDocId(row) { + var val = row.value; + // Users can explicitly specify a joined doc _id, or it + // defaults to the doc _id that emitted the key/value. + var docId = (val && typeof val === 'object' && val._id) || row.id; + return docId; + } - try { - for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { - _step5$value = (0, _slicedToArray2.default)(_step5.value, 2), def = _step5$value[0], resp = _step5$value[1]; - docIdAndRel = queryDefToDocIdAndRel.get(def); + function readAttachmentsAsBlobOrBuffer(res) { + res.rows.forEach(function (row) { + var atts = row.doc && row.doc._attachments; + if (!atts) { + return; + } + Object.keys(atts).forEach(function (filename) { + var att = atts[filename]; + atts[filename].data = (0,pouchdb_binary_utils__WEBPACK_IMPORTED_MODULE_3__.base64StringToBlobOrBuffer)(att.data, att.content_type); + }); + }); + } - if (docIdAndRel) { - _docIdAndRel = (0, _slicedToArray2.default)(docIdAndRel, 2), docId = _docIdAndRel[0], relName = _docIdAndRel[1]; - relationshipsByDocId[docId] = relationshipsByDocId[docId] || {}; - relationshipsByDocId[docId][relName] = (0, _helpers.responseToRelationship)(resp); - } - } - } catch (err) { - _iterator5.e(err); - } finally { - _iterator5.f(); - } + function postprocessAttachments(opts) { + return function (res) { + if (opts.include_docs && opts.attachments && opts.binary) { + readAttachmentsAsBlobOrBuffer(res); + } + return res; + }; + } - return _context12.abrupt("return", _objectSpread(_objectSpread({}, (0, _helpers.attachRelationships)(response, relationshipsByDocId)), {}, { - included: included - })); + function addHttpParam(paramName, opts, params, asJson) { + // add an http param from opts to params, optionally json-encoded + var val = opts[paramName]; + if (typeof val !== 'undefined') { + if (asJson) { + val = encodeURIComponent(JSON.stringify(val)); + } + params.push(paramName + '=' + val); + } + } - case 18: - case "end": - return _context12.stop(); - } - } - }, _callee12); - })); + function coerceInteger(integerCandidate) { + if (typeof integerCandidate !== 'undefined') { + var asNumber = Number(integerCandidate); + // prevents e.g. '1foo' or '1.1' being coerced to 1 + if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) { + return asNumber; + } else { + return integerCandidate; + } + } + } - function fetchRelationships(_x13, _x14) { - return _fetchRelationships.apply(this, arguments); + function coerceOptions(opts) { + opts.group_level = coerceInteger(opts.group_level); + opts.limit = coerceInteger(opts.limit); + opts.skip = coerceInteger(opts.skip); + return opts; + } + + function checkPositiveInteger(number) { + if (number) { + if (typeof number !== 'number') { + return new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Invalid value for integer: "' + + number + '"'); + } + if (number < 0) { + return new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Invalid value for positive integer: ' + + '"' + number + '"'); } + } + } - return fetchRelationships; - }() - }, { - key: "requestMutation", - value: function () { - var _requestMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(definition) { - var _this6 = this; + function checkQueryParseError(options, fun) { + var startkeyName = options.descending ? 'endkey' : 'startkey'; + var endkeyName = options.descending ? 'startkey' : 'endkey'; - var _definition, first, rest, firstResponse; + if (typeof options[startkeyName] !== 'undefined' && + typeof options[endkeyName] !== 'undefined' && + (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(options[startkeyName], options[endkeyName]) > 0) { + throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('No rows can match your key range, ' + + 'reverse your start_key and end_key or set {descending : true}'); + } else if (fun.reduce && options.reduce !== false) { + if (options.include_docs) { + throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('{include_docs:true} is invalid for reduce'); + } else if (options.keys && options.keys.length > 1 && + !options.group && !options.group_level) { + throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.QueryParseError('Multi-key fetches for reduce views must use ' + + '{group: true}'); + } + } + ['group_level', 'limit', 'skip'].forEach(function (optionName) { + var error = checkPositiveInteger(options[optionName]); + if (error) { + throw error; + } + }); + } - return _regenerator.default.wrap(function _callee13$(_context13) { - while (1) { - switch (_context13.prev = _context13.next) { - case 0: - if (!Array.isArray(definition)) { - _context13.next = 8; - break; - } + function httpQuery(db, fun, opts) { + // List of parameters to add to the PUT request + var params = []; + var body; + var method = 'GET'; + var ok, status; - _definition = (0, _toArray2.default)(definition), first = _definition[0], rest = _definition.slice(1); - _context13.next = 4; - return this.requestMutation(first); + // If opts.reduce exists and is defined, then add it to the list + // of parameters. + // If reduce=false then the results are that of only the map function + // not the final result of map and reduce. + addHttpParam('reduce', opts, params); + addHttpParam('include_docs', opts, params); + addHttpParam('attachments', opts, params); + addHttpParam('limit', opts, params); + addHttpParam('descending', opts, params); + addHttpParam('group', opts, params); + addHttpParam('group_level', opts, params); + addHttpParam('skip', opts, params); + addHttpParam('stale', opts, params); + addHttpParam('conflicts', opts, params); + addHttpParam('startkey', opts, params, true); + addHttpParam('start_key', opts, params, true); + addHttpParam('endkey', opts, params, true); + addHttpParam('end_key', opts, params, true); + addHttpParam('inclusive_end', opts, params); + addHttpParam('key', opts, params, true); + addHttpParam('update_seq', opts, params); - case 4: - firstResponse = _context13.sent; - _context13.next = 7; - return Promise.all(rest.map(function (def) { - var mutationDef = typeof def === 'function' ? def(firstResponse) : def; - return _this6.requestMutation(mutationDef); - })); + // Format the list of parameters into a valid URI query string + params = params.join('&'); + params = params === '' ? '' : '?' + params; - case 7: - return _context13.abrupt("return", firstResponse); + // If keys are supplied, issue a POST to circumvent GET query string limits + // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options + if (typeof opts.keys !== 'undefined') { + var MAX_URL_LENGTH = 2000; + // according to http://stackoverflow.com/a/417184/680742, + // the de facto URL length limit is 2000 characters - case 8: - return _context13.abrupt("return", this.chain.request(definition)); + var keysAsString = + 'keys=' + encodeURIComponent(JSON.stringify(opts.keys)); + if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) { + // If the keys are short enough, do a GET. we do this to work around + // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239) + params += (params[0] === '?' ? '&' : '?') + keysAsString; + } else { + method = 'POST'; + if (typeof fun === 'string') { + body = {keys: opts.keys}; + } else { // fun is {map : mapfun}, so append to this + fun.keys = opts.keys; + } + } + } - case 9: - case "end": - return _context13.stop(); - } + // We are referencing a query defined in the design doc + if (typeof fun === 'string') { + var parts = parseViewName(fun); + return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, { + headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}), + method: method, + body: JSON.stringify(body) + }).then(function (response) { + ok = response.ok; + status = response.status; + return response.json(); + }).then(function (result) { + if (!ok) { + result.status = status; + throw (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.generateErrorFromResponse)(result); + } + // fail the entire request if the result contains an error + result.rows.forEach(function (row) { + /* istanbul ignore if */ + if (row.value && row.value.error && row.value.error === "builtin_reduce_error") { + throw new Error(row.reason); } - }, _callee13, this); - })); + }); + return result; + }).then(postprocessAttachments(opts)); + } - function requestMutation(_x15) { - return _requestMutation.apply(this, arguments); + // We are using a temporary view, terrible for performance, good for testing + body = body || {}; + Object.keys(fun).forEach(function (key) { + if (Array.isArray(fun[key])) { + body[key] = fun[key]; + } else { + body[key] = fun[key].toString(); } + }); - return requestMutation; - }() - }, { - key: "getIncludesRelationships", - value: function getIncludesRelationships(queryDefinition) { - var _this7 = this; + return db.fetch('_temp_view' + params, { + headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}), + method: 'POST', + body: JSON.stringify(body) + }).then(function (response) { + ok = response.ok; + status = response.status; + return response.json(); + }).then(function (result) { + if (!ok) { + result.status = status; + throw (0,pouchdb_errors__WEBPACK_IMPORTED_MODULE_5__.generateErrorFromResponse)(result); + } + return result; + }).then(postprocessAttachments(opts)); + } - var includes = queryDefinition.includes, - doctype = queryDefinition.doctype; - if (!includes) return {}; - return (0, _fromPairs.default)(includes.map(function (relName) { - return [relName, _this7.schema.getRelationship(doctype, relName)]; - })); - } - /** - * Returns documents with their relationships resolved according to their schema. - * If related documents are not in the store, they will not be fetched automatically. - * Instead, the relationships will have null documents. - * - * @param {string} doctype - Doctype of the documents being hydrated - * @param {Array<CozyClientDocument>} documents - Documents to be hydrated - * @returns {Array<HydratedDocument>} - */ + // custom adapters can define their own api._query + // and override the default behavior + /* istanbul ignore next */ + function customQuery(db, fun, opts) { + return new Promise(function (resolve, reject) { + db._query(fun, opts, function (err, res) { + if (err) { + return reject(err); + } + resolve(res); + }); + }); + } - }, { - key: "hydrateDocuments", - value: function hydrateDocuments(doctype, documents) { - var _this8 = this; + // custom adapters can define their own api._viewCleanup + // and override the default behavior + /* istanbul ignore next */ + function customViewCleanup(db) { + return new Promise(function (resolve, reject) { + db._viewCleanup(function (err, res) { + if (err) { + return reject(err); + } + resolve(res); + }); + }); + } - if (this.options.autoHydrate === false) { - return documents; + function defaultsTo(value) { + return function (reason) { + /* istanbul ignore else */ + if (reason.status === 404) { + return value; + } else { + throw reason; } + }; + } - var schema = this.schema.getDoctypeSchema(doctype); - var relationships = schema.relationships; + // returns a promise for a list of docs to update, based on the input docId. + // the order doesn't matter, because post-3.2.0, bulkDocs + // is an atomic operation in all three adapters. + function getDocsToPersist(docId, view, docIdsToChangesAndEmits) { + var metaDocId = '_local/doc_' + docId; + var defaultMetaDoc = {_id: metaDocId, keys: []}; + var docData = docIdsToChangesAndEmits.get(docId); + var indexableKeysToKeyValues = docData[0]; + var changes = docData[1]; - if (relationships) { - return documents.map(function (doc) { - return _this8.hydrateDocument(doc, schema); - }); - } else { - return documents; + function getMetaDoc() { + if (isGenOne(changes)) { + // generation 1, so we can safely assume initial state + // for performance reasons (avoids unnecessary GETs) + return Promise.resolve(defaultMetaDoc); } + return view.db.get(metaDocId).catch(defaultsTo(defaultMetaDoc)); } - /** - * Resolves relationships on a document. - * - * The original document is kept in the target attribute of - * the relationship - * - * @param {CozyClientDocument} document - for which relationships must be resolved - * @param {Schema} [schemaArg] - Optional - * @returns {HydratedDocument} - */ - }, { - key: "hydrateDocument", - value: function hydrateDocument(document, schemaArg) { - if (!document) { - return document; + function getKeyValueDocs(metaDoc) { + if (!metaDoc.keys.length) { + // no keys, no need for a lookup + return Promise.resolve({rows: []}); } - - var schema = schemaArg || this.schema.getDoctypeSchema(document._type); - return _objectSpread(_objectSpread({}, document), this.hydrateRelationships(document, schema.relationships)); - } - }, { - key: "hydrateRelationships", - value: function hydrateRelationships(document, schemaRelationships) { - var methods = this.getRelationshipStoreAccessors(); - return (0, _mapValues.default)(schemaRelationships, function (assoc, name) { - return (0, _associations.create)(document, assoc, methods); + return view.db.allDocs({ + keys: metaDoc.keys, + include_docs: true }); } - /** - * Creates (locally) a new document for the given doctype. - * This document is hydrated : its relationships are there - * and working. - */ - }, { - key: "makeNewDocument", - value: function makeNewDocument(doctype) { - var obj = { - _type: doctype - }; - return this.hydrateDocument(obj); - } - }, { - key: "generateRandomId", - value: function generateRandomId() { - return this.queryIdGenerator.generateRandomId(); - } - /** - * Creates an association that is linked to the store. - */ + function processKeyValueDocs(metaDoc, kvDocsRes) { + var kvDocs = []; + var oldKeys = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Set(); - }, { - key: "getAssociation", - value: function getAssociation(document, associationName) { - return (0, _associations.create)(document, this.schema.getRelationship(document._type, associationName), this.getRelationshipStoreAccessors()); + for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) { + var row = kvDocsRes.rows[i]; + var doc = row.doc; + if (!doc) { // deleted + continue; + } + kvDocs.push(doc); + oldKeys.add(doc._id); + doc._deleted = !indexableKeysToKeyValues.has(doc._id); + if (!doc._deleted) { + var keyValue = indexableKeysToKeyValues.get(doc._id); + if ('value' in keyValue) { + doc.value = keyValue.value; + } + } + } + var newKeys = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(indexableKeysToKeyValues); + newKeys.forEach(function (key) { + if (!oldKeys.has(key)) { + // new doc + var kvDoc = { + _id: key + }; + var keyValue = indexableKeysToKeyValues.get(key); + if ('value' in keyValue) { + kvDoc.value = keyValue.value; + } + kvDocs.push(kvDoc); + } + }); + metaDoc.keys = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.uniq)(newKeys.concat(metaDoc.keys)); + kvDocs.push(metaDoc); + + return kvDocs; } - /** - * Returns the accessors that are given to the relationships for them - * to deal with the stores. - * - * Relationships need to have access to the store to ping it when - * a modification (addById/removeById etc...) has been done. This wakes - * the store up, which in turn will update the `<Query>`s and re-render the data. - */ - }, { - key: "getRelationshipStoreAccessors", - value: function getRelationshipStoreAccessors() { - var _this9 = this; + return getMetaDoc().then(function (metaDoc) { + return getKeyValueDocs(metaDoc).then(function (kvDocsRes) { + return processKeyValueDocs(metaDoc, kvDocsRes); + }); + }); + } - if (!this.storeAccesors) { - this.storeAccessors = { - get: this.getDocumentFromState.bind(this), - save: function save(document, opts) { - return _this9.save.call(_this9, document, opts); - }, - dispatch: this.dispatch.bind(this), - query: function query(def, opts) { - return _this9.query.call(_this9, def, opts); - }, - mutate: function mutate(def, opts) { - return _this9.mutate.call(_this9, def, opts); - } - }; - } + // updates all emitted key/value docs and metaDocs in the mrview database + // for the given batch of documents from the source database + function saveKeyValues(view, docIdsToChangesAndEmits, seq) { + var seqDocId = '_local/lastSeq'; + return view.db.get(seqDocId) + .catch(defaultsTo({_id: seqDocId, seq: 0})) + .then(function (lastSeqDoc) { + var docIds = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(docIdsToChangesAndEmits); + return Promise.all(docIds.map(function (docId) { + return getDocsToPersist(docId, view, docIdsToChangesAndEmits); + })).then(function (listOfDocsToPersist) { + var docsToPersist = (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.flatten)(listOfDocsToPersist); + lastSeqDoc.seq = seq; + docsToPersist.push(lastSeqDoc); + // write all docs in a single operation, update the seq once + return view.db.bulkDocs({docs : docsToPersist}); + }); + }); + } - return this.storeAccessors; + function getQueue(view) { + var viewName = typeof view === 'string' ? view : view.name; + var queue = persistentQueues[viewName]; + if (!queue) { + queue = persistentQueues[viewName] = new TaskQueue(); } - /** - * Get a collection of documents from the internal store. - * - * @param {string} type - Doctype of the collection - * - * @returns {CozyClientDocument[]} Array of documents or null if the collection does not exist. - */ + return queue; + } - }, { - key: "getCollectionFromState", - value: function getCollectionFromState(type) { - try { - return (0, _store.getCollectionFromState)(this.store.getState(), type); - } catch (e) { - _logger.default.warn('Could not getCollectionFromState', type, e.message); + function updateView(view) { + return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(view), function () { + return updateViewInQueue(view); + })(); + } - return null; + function updateViewInQueue(view) { + // bind the emit function once + var mapResults; + var doc; + + function emit(key, value) { + var output = {id: doc._id, key: (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.normalizeKey)(key)}; + // Don't explicitly store the value unless it's defined and non-null. + // This saves on storage space, because often people don't use it. + if (typeof value !== 'undefined' && value !== null) { + output.value = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.normalizeKey)(value); } + mapResults.push(output); } - /** - * Get a document from the internal store. - * - * @param {string} type - Doctype of the document - * @param {string} id - Id of the document - * - * @returns {CozyClientDocument} Document or null if the object does not exist. - */ - }, { - key: "getDocumentFromState", - value: function getDocumentFromState(type, id) { - try { - return (0, _store.getDocumentFromState)(this.store.getState(), type, id); - } catch (e) { - _logger.default.warn('Could not getDocumentFromState', type, id, e.message); + var mapFun = mapper(view.mapFun, emit); - return null; + var currentSeq = view.seq || 0; + + function processChange(docIdsToChangesAndEmits, seq) { + return function () { + return saveKeyValues(view, docIdsToChangesAndEmits, seq); + }; + } + + var queue = new TaskQueue(); + + function processNextBatch() { + return view.sourceDB.changes({ + return_docs: true, + conflicts: true, + include_docs: true, + style: 'all_docs', + since: currentSeq, + limit: CHANGES_BATCH_SIZE + }).then(processBatch); + } + + function processBatch(response) { + var results = response.results; + if (!results.length) { + return; + } + var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results); + queue.add(processChange(docIdsToChangesAndEmits, currentSeq)); + if (results.length < CHANGES_BATCH_SIZE) { + return; } + return processNextBatch(); } - /** - * Get a query from the internal store. - * - * @param {string} id - Id of the query (set via Query.props.as) - * @param {object} options - Options - * @param {boolean} [options.hydrated] - Whether documents should be returned already hydrated (default: false) - * @param {object} [options.singleDocData] - If true, the "data" returned will be - * a single doc instead of an array for single doc queries. Defaults to false for backward - * compatibility but will be set to true in the future. - * - * @returns {QueryState} - Query state or null if it does not exist. - */ - }, { - key: "getQueryFromState", - value: function getQueryFromState(id) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var hydrated = options.hydrated || false; - var singleDocData = options.singleDocData || false; + function createDocIdsToChangesAndEmits(results) { + var docIdsToChangesAndEmits = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); + for (var i = 0, len = results.length; i < len; i++) { + var change = results[i]; + if (change.doc._id[0] !== '_') { + mapResults = []; + doc = change.doc; - try { - var queryResults = (0, _store.getQueryFromState)(this.store.getState(), id); - var doctype = queryResults.definition && queryResults.definition.doctype; - var isSingleDocQuery = queryResults.definition && queryResults.definition.id; + if (!doc._deleted) { + tryMap(view.sourceDB, mapFun, doc); + } + mapResults.sort(sortByKeyThenValue); - if (!hydrated && !singleDocData) { - // Early return let's us preserve reference equality in the simple case - return queryResults; + var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults); + docIdsToChangesAndEmits.set(change.doc._id, [ + indexableKeysToKeyValues, + change.changes + ]); } + currentSeq = change.seq; + } + return docIdsToChangesAndEmits; + } - var data = hydrated && doctype ? this.hydrateDocuments(doctype, queryResults.data) : queryResults.data; - return _objectSpread(_objectSpread({}, queryResults), {}, { - data: isSingleDocQuery && singleDocData ? data[0] : data - }); - } catch (e) { - console.warn("Could not get query from state. queryId: ".concat(id, ", error: ").concat(e.message)); - return null; + function createIndexableKeysToKeyValues(mapResults) { + var indexableKeysToKeyValues = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); + var lastKey; + for (var i = 0, len = mapResults.length; i < len; i++) { + var emittedKeyValue = mapResults[i]; + var complexKey = [emittedKeyValue.key, emittedKeyValue.id]; + if (i > 0 && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(emittedKeyValue.key, lastKey) === 0) { + complexKey.push(i); // dup key+id, so make it unique + } + indexableKeysToKeyValues.set((0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)(complexKey), emittedKeyValue); + lastKey = emittedKeyValue.key; } + return indexableKeysToKeyValues; } - /** - * Executes a query and returns the results from internal store. - * - * Can be useful in pure JS context (without React) - * Has a behavior close to <Query /> or useQuery - * - * @param {object} query - Query with definition and options - * @returns {Promise<QueryState>} Query state - */ - }, { - key: "register", + return processNextBatch().then(function () { + return queue.finish(); + }).then(function () { + view.seq = currentSeq; + }); + } - /** - * Performs a complete OAuth flow using a Cordova webview - * or React Native WebView for auth. - * The `register` method's name has been chosen for compat reasons with the Authentication compo. - * - * @param {string} cozyURL Receives the URL of the cozy instance. - * @returns {object} Contains the fetched token and the client information. - */ - value: function register(cozyURL) { - var stackClient = this.getStackClient(); - stackClient.setUri(cozyURL); - return this.startOAuthFlow(_mobile.authFunction); - } - }, { - key: "isReactNative", - value: function isReactNative() { - return typeof navigator != 'undefined' && navigator.product == 'ReactNative'; + function reduceView(view, results, options) { + if (options.group_level === 0) { + delete options.group_level; } - /** - * Performs a complete OAuth flow, including updating the internal token at the end. - * - * @param {OpenURLCallback} openURLCallback Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions. - * @returns {Promise<object>} Contains the fetched token and the client information. These should be stored and used to restore the client. - */ - - }, { - key: "startOAuthFlow", - value: function () { - var _startOAuthFlow = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(openURLCallback) { - var stackClient; - return _regenerator.default.wrap(function _callee14$(_context14) { - while (1) { - switch (_context14.prev = _context14.next) { - case 0: - stackClient = this.getStackClient(); - _context14.next = 3; - return stackClient.register(); - case 3: - _context14.next = 5; - return this.certifyFlagship(); + var shouldGroup = options.group || options.group_level; - case 5: - return _context14.abrupt("return", this.authorize({ - openURLCallback: openURLCallback - })); + var reduceFun = reducer(view.reduceFun); - case 6: - case "end": - return _context14.stop(); - } - } - }, _callee14, this); - })); + var groups = []; + var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY : + options.group_level; + results.forEach(function (e) { + var last = groups[groups.length - 1]; + var groupKey = shouldGroup ? e.key : null; - function startOAuthFlow(_x16) { - return _startOAuthFlow.apply(this, arguments); + // only set group_level for array keys + if (shouldGroup && Array.isArray(groupKey)) { + groupKey = groupKey.slice(0, lvl); } - return startOAuthFlow; - }() - /** - * Perform the Flagship certification process for verifying that the current running app is a genuine Cozy application - * - * This mechanism is described in https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/flagship-certification/README.md - */ + if (last && (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.collate)(last.groupKey, groupKey) === 0) { + last.keys.push([e.key, e.id]); + last.values.push(e.value); + return; + } + groups.push({ + keys: [[e.key, e.id]], + values: [e.value], + groupKey: groupKey + }); + }); + results = []; + for (var i = 0, len = groups.length; i < len; i++) { + var e = groups[i]; + var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false); + if (reduceTry.error && reduceTry.error instanceof pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.BuiltInError) { + // CouchDB returns an error if a built-in errors out + throw reduceTry.error; + } + results.push({ + // CouchDB just sets the value to null if a non-built-in errors out + value: reduceTry.error ? null : reduceTry.output, + key: e.groupKey + }); + } + // no total_rows/offset when reducing + return {rows: sliceResults(results, options.limit, options.skip)}; + } - }, { - key: "certifyFlagship", - value: function () { - var _certifyFlagship2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15() { - var stackClient; - return _regenerator.default.wrap(function _callee15$(_context15) { - while (1) { - switch (_context15.prev = _context15.next) { - case 0: - stackClient = this.getStackClient(); + function queryView(view, opts) { + return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(view), function () { + return queryViewInQueue(view, opts); + })(); + } - if (!stackClient.oauthOptions.shouldRequireFlagshipPermissions) { - _context15.next = 4; - break; - } + function queryViewInQueue(view, opts) { + var totalRows; + var shouldReduce = view.reduceFun && opts.reduce !== false; + var skip = opts.skip || 0; + if (typeof opts.keys !== 'undefined' && !opts.keys.length) { + // equivalent query + opts.limit = 0; + delete opts.keys; + } - _context15.next = 4; - return (0, _flagshipCertification.certifyFlagship)(stackClient.oauthOptions.certificationConfig, this); + function fetchFromView(viewOpts) { + viewOpts.include_docs = true; + return view.db.allDocs(viewOpts).then(function (res) { + totalRows = res.total_rows; + return res.rows.map(function (result) { - case 4: - case "end": - return _context15.stop(); + // implicit migration - in older versions of PouchDB, + // we explicitly stored the doc as {id: ..., key: ..., value: ...} + // this is tested in a migration test + /* istanbul ignore next */ + if ('value' in result.doc && typeof result.doc.value === 'object' && + result.doc.value !== null) { + var keys = Object.keys(result.doc.value).sort(); + // this detection method is not perfect, but it's unlikely the user + // emitted a value which was an object with these 3 exact keys + var expectedKeys = ['id', 'key', 'value']; + if (!(keys < expectedKeys || keys > expectedKeys)) { + return result.doc.value; } } - }, _callee15, this); - })); - function certifyFlagship() { - return _certifyFlagship2.apply(this, arguments); + var parsedKeyAndDocId = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.parseIndexableString)(result.doc._id); + return { + key: parsedKeyAndDocId[0], + id: parsedKeyAndDocId[1], + value: ('value' in result.doc ? result.doc.value : null) + }; + }); + }); + } + + function onMapResultsReady(rows) { + var finalResults; + if (shouldReduce) { + finalResults = reduceView(view, rows, opts); + } else { + finalResults = { + total_rows: totalRows, + offset: skip, + rows: rows + }; + } + /* istanbul ignore if */ + if (opts.update_seq) { + finalResults.update_seq = view.seq; } + if (opts.include_docs) { + var docIds = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.uniq)(rows.map(rowToDocId)); - return certifyFlagship; - }() - /** - * Creates an OAuth token with needed permissions for the current client. - * The authorization page URL generation can be overriding by passing a function pointer as `openURLCallback` parameter - * It is possible to skip the session creation process (when using an in-app browser) by passing a sessionCode (see https://docs.cozy.io/en/cozy-stack/auth/#post-authsession_code) - * - * @param {object} [options] - Authorization options - * @param {OpenURLCallback} [options.openURLCallback] - Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions. - * @param {SessionCode} [options.sessionCode] - session code than can be added to the authorization URL to automatically create the session. - * @param {PKCECodes} [options.pkceCodes] - code verifier and a code challenge that should be used in the PKCE verification process. - * @returns {Promise<object>} Contains the fetched token and the client information. These should be stored and used to restore the client. - */ + return view.sourceDB.allDocs({ + keys: docIds, + include_docs: true, + conflicts: opts.conflicts, + attachments: opts.attachments, + binary: opts.binary + }).then(function (allDocsRes) { + var docIdsToDocs = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); + allDocsRes.rows.forEach(function (row) { + docIdsToDocs.set(row.id, row.doc); + }); + rows.forEach(function (row) { + var docId = rowToDocId(row); + var doc = docIdsToDocs.get(docId); + if (doc) { + row.doc = doc; + } + }); + return finalResults; + }); + } else { + return finalResults; + } + } - }, { - key: "authorize", - value: function () { - var _authorize = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16() { - var _ref6, - _ref6$openURLCallback, - openURLCallback, - _ref6$sessionCode, - sessionCode, - _ref6$pkceCodes, - pkceCodes, - codeVerifier, - codeChallenge, - stackClient, - stateCode, - url, - redirectedURL, - code, - token, - _stackClient, - _args16 = arguments; + if (typeof opts.keys !== 'undefined') { + var keys = opts.keys; + var fetchPromises = keys.map(function (key) { + var viewOpts = { + startkey : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([key]), + endkey : (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([key, {}]) + }; + /* istanbul ignore if */ + if (opts.update_seq) { + viewOpts.update_seq = true; + } + return fetchFromView(viewOpts); + }); + return Promise.all(fetchPromises).then(pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.flatten).then(onMapResultsReady); + } else { // normal query, no 'keys' + var viewOpts = { + descending : opts.descending + }; + /* istanbul ignore if */ + if (opts.update_seq) { + viewOpts.update_seq = true; + } + var startkey; + var endkey; + if ('start_key' in opts) { + startkey = opts.start_key; + } + if ('startkey' in opts) { + startkey = opts.startkey; + } + if ('end_key' in opts) { + endkey = opts.end_key; + } + if ('endkey' in opts) { + endkey = opts.endkey; + } + if (typeof startkey !== 'undefined') { + viewOpts.startkey = opts.descending ? + (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([startkey, {}]) : + (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([startkey]); + } + if (typeof endkey !== 'undefined') { + var inclusiveEnd = opts.inclusive_end !== false; + if (opts.descending) { + inclusiveEnd = !inclusiveEnd; + } - return _regenerator.default.wrap(function _callee16$(_context16) { - while (1) { - switch (_context16.prev = _context16.next) { - case 0: - _ref6 = _args16.length > 0 && _args16[0] !== undefined ? _args16[0] : {}, _ref6$openURLCallback = _ref6.openURLCallback, openURLCallback = _ref6$openURLCallback === void 0 ? _mobile.authFunction : _ref6$openURLCallback, _ref6$sessionCode = _ref6.sessionCode, sessionCode = _ref6$sessionCode === void 0 ? undefined : _ref6$sessionCode, _ref6$pkceCodes = _ref6.pkceCodes, pkceCodes = _ref6$pkceCodes === void 0 ? {} : _ref6$pkceCodes; - _context16.prev = 1; - codeVerifier = pkceCodes.codeVerifier, codeChallenge = pkceCodes.codeChallenge; - stackClient = this.getStackClient(); - stateCode = stackClient.generateStateCode(); - url = stackClient.getAuthCodeURL({ - stateCode: stateCode, - scopes: undefined, - sessionCode: sessionCode, - codeChallenge: codeChallenge - }); - _context16.next = 8; - return openURLCallback(url); + viewOpts.endkey = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)( + inclusiveEnd ? [endkey, {}] : [endkey]); + } + if (typeof opts.key !== 'undefined') { + var keyStart = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([opts.key]); + var keyEnd = (0,pouchdb_collate__WEBPACK_IMPORTED_MODULE_4__.toIndexableString)([opts.key, {}]); + if (viewOpts.descending) { + viewOpts.endkey = keyStart; + viewOpts.startkey = keyEnd; + } else { + viewOpts.startkey = keyStart; + viewOpts.endkey = keyEnd; + } + } + if (!shouldReduce) { + if (typeof opts.limit === 'number') { + viewOpts.limit = opts.limit; + } + viewOpts.skip = skip; + } + return fetchFromView(viewOpts).then(onMapResultsReady); + } + } - case 8: - redirectedURL = _context16.sent; - code = stackClient.getAccessCodeFromURL(redirectedURL, stateCode); - _context16.next = 12; - return stackClient.fetchAccessToken(code, undefined, undefined, codeVerifier); + function httpViewCleanup(db) { + return db.fetch('_view_cleanup', { + headers: new pouchdb_fetch__WEBPACK_IMPORTED_MODULE_6__.Headers({'Content-Type': 'application/json'}), + method: 'POST' + }).then(function (response) { + return response.json(); + }); + } - case 12: - token = _context16.sent; - stackClient.setToken(token); - return _context16.abrupt("return", { - token: token, - infos: stackClient.oauthOptions, - client: stackClient.oauthOptions // for compat with Authentication comp reasons + function localViewCleanup(db) { + return db.get('_local/' + localDocName).then(function (metaDoc) { + var docsToViews = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Map(); + Object.keys(metaDoc.views).forEach(function (fullViewName) { + var parts = parseViewName(fullViewName); + var designDocName = '_design/' + parts[0]; + var viewName = parts[1]; + var views = docsToViews.get(designDocName); + if (!views) { + views = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_2__.Set(); + docsToViews.set(designDocName, views); + } + views.add(viewName); + }); + var opts = { + keys : (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.mapToKeysArray)(docsToViews), + include_docs : true + }; + return db.allDocs(opts).then(function (res) { + var viewsToStatus = {}; + res.rows.forEach(function (row) { + var ddocName = row.key.substring(8); // cuts off '_design/' + docsToViews.get(row.key).forEach(function (viewName) { + var fullViewName = ddocName + '/' + viewName; + /* istanbul ignore if */ + if (!metaDoc.views[fullViewName]) { + // new format, without slashes, to support PouchDB 2.2.0 + // migration test in pouchdb's browser.migration.js verifies this + fullViewName = viewName; + } + var viewDBNames = Object.keys(metaDoc.views[fullViewName]); + // design doc deleted, or view function nonexistent + var statusIsGood = row.doc && row.doc.views && + row.doc.views[viewName]; + viewDBNames.forEach(function (viewDBName) { + viewsToStatus[viewDBName] = + viewsToStatus[viewDBName] || statusIsGood; + }); + }); + }); + var dbsToDelete = Object.keys(viewsToStatus).filter( + function (viewDBName) { return !viewsToStatus[viewDBName]; }); + var destroyPromises = dbsToDelete.map(function (viewDBName) { + return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.sequentialize)(getQueue(viewDBName), function () { + return new db.constructor(viewDBName, db.__opts).destroy(); + })(); + }); + return Promise.all(destroyPromises).then(function () { + return {ok: true}; + }); + }); + }, defaultsTo({ok: true})); + } - }); + function queryPromised(db, fun, opts) { + /* istanbul ignore next */ + if (typeof db._query === 'function') { + return customQuery(db, fun, opts); + } + if ((0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(db)) { + return httpQuery(db, fun, opts); + } - case 17: - _context16.prev = 17; - _context16.t0 = _context16["catch"](1); + if (typeof fun !== 'string') { + // temp_view + checkQueryParseError(opts, fun); - /* if REGISTRATION_ABORT is emited, we have to unregister the client. */ - if (_context16.t0.message === _const.REGISTRATION_ABORT) { - _stackClient = this.getStackClient(); + tempViewQueue.add(function () { + var createViewPromise = createView( + /* sourceDB */ db, + /* viewName */ 'temp_view/temp_view', + /* mapFun */ fun.map, + /* reduceFun */ fun.reduce, + /* temporary */ true, + /* localDocName */ localDocName); + return createViewPromise.then(function (view) { + return (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.fin)(updateView(view).then(function () { + return queryView(view, opts); + }), function () { + return view.db.destroy(); + }); + }); + }); + return tempViewQueue.finish(); + } else { + // persistent view + var fullViewName = fun; + var parts = parseViewName(fullViewName); + var designDocName = parts[0]; + var viewName = parts[1]; + return db.get('_design/' + designDocName).then(function (doc) { + var fun = doc.views && doc.views[viewName]; - _stackClient.unregister(); - } + if (!fun) { + // basic validator; it's assumed that every subclass would want this + throw new pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.NotFoundError('ddoc ' + doc._id + ' has no view named ' + + viewName); + } - throw _context16.t0; + ddocValidator(doc, viewName); + checkQueryParseError(opts, fun); - case 21: - case "end": - return _context16.stop(); + var createViewPromise = createView( + /* sourceDB */ db, + /* viewName */ fullViewName, + /* mapFun */ fun.map, + /* reduceFun */ fun.reduce, + /* temporary */ false, + /* localDocName */ localDocName); + return createViewPromise.then(function (view) { + if (opts.stale === 'ok' || opts.stale === 'update_after') { + if (opts.stale === 'update_after') { + (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.nextTick)(function () { + updateView(view); + }); } + return queryView(view, opts); + } else { // stale not ok + return updateView(view).then(function () { + return queryView(view, opts); + }); } - }, _callee16, this, [[1, 17]]); - })); - - function authorize() { - return _authorize.apply(this, arguments); - } - - return authorize; - }() - /** - * Renews the token if, for instance, new permissions are required or token - * has expired. - * - * @returns {object} Contains the fetched token and the client information. - */ - - }, { - key: "renewAuthorization", - value: function renewAuthorization() { - return this.authorize({ - openURLCallback: _mobile.authFunction + }); }); } - /** - * Sets the internal store of the client. Use this when you want to have cozy-client's - * internal store colocated with your existing Redux store. - * - * Typically, you would need to do this only once in your application, this is why - * setStore throws if you do it twice. If you really need to set the store again, - * use options.force = true. - * - * @example - * ``` - * const client = new CozyClient() - * const store = createStore(combineReducers({ - * todos: todoReducer, - * cozy: client.reducer() - * }) - * client.setStore(store) - * ``` - * - * @param {ReduxStore} store - A redux store - * @param {object} [options] - Options - * @param {boolean} [options.force] - Will deactivate throwing when client's store already exists - */ + } - }, { - key: "setStore", - value: function setStore(store) { - var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, - _ref7$force = _ref7.force, - force = _ref7$force === void 0 ? false : _ref7$force; + function abstractQuery(fun, opts, callback) { + var db = this; + if (typeof opts === 'function') { + callback = opts; + opts = {}; + } + opts = opts ? coerceOptions(opts) : {}; - if (store === undefined) { - throw new Error('Store is undefined'); - } else if (this.store && !force) { - throw new Error("Client already has a store, it is forbidden to change store.\nsetStore must be called before any query is executed. Try to\ncall setStore earlier in your code, preferably just after the\ninstantiation of the client."); - } + if (typeof fun === 'function') { + fun = {map : fun}; + } - this.store = store; + var promise = Promise.resolve().then(function () { + return queryPromised(db, fun, opts); + }); + (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.promisedCallback)(promise, callback); + return promise; + } + + var abstractViewCleanup = (0,pouchdb_mapreduce_utils__WEBPACK_IMPORTED_MODULE_7__.callbackify)(function () { + var db = this; + /* istanbul ignore next */ + if (typeof db._viewCleanup === 'function') { + return customViewCleanup(db); } - }, { - key: "ensureStore", - value: function ensureStore() { - if (!this.store) { - this.setStore((0, _store.createStore)()); - } + if ((0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_0__.isRemote)(db)) { + return httpViewCleanup(db); } - /** - * Returns whether the client has been revoked on the server - */ + return localViewCleanup(db); + }); - }, { - key: "checkForRevocation", - value: function () { - var _checkForRevocation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17() { - return _regenerator.default.wrap(function _callee17$(_context17) { - while (1) { - switch (_context17.prev = _context17.next) { - case 0: - return _context17.abrupt("return", this.stackClient.checkForRevocation()); + return { + query: abstractQuery, + viewCleanup: abstractViewCleanup + }; +} - case 1: - case "end": - return _context17.stop(); - } - } - }, _callee17, this); - })); +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createAbstractMapReduce); - function checkForRevocation() { - return _checkForRevocation.apply(this, arguments); - } - return checkForRevocation; - }() - /** Sets public attribute and emits event related to revocation */ +/***/ }), +/* 518 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - }, { - key: "handleRevocationChange", - value: function handleRevocationChange(state) { - if (state) { - this.isRevoked = true; - this.emit('revoked'); - } else { - this.isRevoked = false; - this.emit('unrevoked'); - } - } - /** Emits event when token is refreshed */ +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "atob": () => (/* binding */ thisAtob), +/* harmony export */ "btoa": () => (/* binding */ thisBtoa), +/* harmony export */ "base64StringToBlobOrBuffer": () => (/* binding */ b64ToBluffer), +/* harmony export */ "binaryStringToArrayBuffer": () => (/* binding */ binaryStringToArrayBuffer), +/* harmony export */ "binaryStringToBlobOrBuffer": () => (/* binding */ binStringToBluffer), +/* harmony export */ "blob": () => (/* binding */ createBlob), +/* harmony export */ "blobOrBufferToBase64": () => (/* binding */ blobToBase64), +/* harmony export */ "blobOrBufferToBinaryString": () => (/* binding */ blobToBase64$1), +/* harmony export */ "readAsArrayBuffer": () => (/* binding */ readAsArrayBuffer), +/* harmony export */ "readAsBinaryString": () => (/* binding */ readAsBinaryString), +/* harmony export */ "typedBuffer": () => (/* binding */ typedBuffer) +/* harmony export */ }); +/* harmony import */ var buffer_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(519); +/* harmony import */ var buffer_from__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(buffer_from__WEBPACK_IMPORTED_MODULE_0__); - }, { - key: "handleTokenRefresh", - value: function handleTokenRefresh(token) { - this.emit('tokenRefreshed'); - if (this.options.onTokenRefresh) { - deprecatedHandler("Using onTokenRefresh is deprecated, please use events like this: cozyClient.on('tokenRefreshed', token => console.log('Token has been refreshed', token)). https://git.io/fj3M3"); - this.options.onTokenRefresh(token); - } - } - /** - * If no stack client has been passed in options, creates a default stack - * client and attaches handlers for revocation and token refresh. - * If a stackClient has been passed in options, ensure it has handlers for - * revocation and token refresh. - * - * If `oauth` options are passed, stackClient is an OAuthStackClient. - */ +function thisAtob(str) { + var base64 = new Buffer(str, 'base64'); + // Node.js will just skip the characters it can't decode instead of + // throwing an exception + if (base64.toString('base64') !== str) { + throw new Error("attachment is not a valid base64 string"); + } + return base64.toString('binary'); +} - }, { - key: "createClient", - value: function createClient() { - if (this.options.client) { - console.warn('CozyClient: Using options.client is deprecated, please use options.stackClient.'); - } +function thisBtoa(str) { + return buffer_from__WEBPACK_IMPORTED_MODULE_0___default()(str, 'binary').toString('base64'); +} - var warningForCustomHandlers = this.options.warningForCustomHandlers !== undefined ? this.options.warningForCustomHandlers : true; - var stackClient = this.options.client || this.options.stackClient; - var handlers = { - onRevocationChange: this.handleRevocationChange, - onTokenRefresh: this.handleTokenRefresh - }; +function typedBuffer(binString, buffType, type) { + // buffType is either 'binary' or 'base64' + var buff = buffer_from__WEBPACK_IMPORTED_MODULE_0___default()(binString, buffType); + buff.type = type; // non-standard, but used for consistency with the browser + return buff; +} - if (stackClient) { - this.stackClient = stackClient; +function b64ToBluffer(b64, type) { + return typedBuffer(b64, 'base64', type); +} - if (!stackClient.options) { - stackClient.options = {}; - } +// From http://stackoverflow.com/questions/14967647/ (continues on next line) +// encode-decode-image-with-base64-breaks-image (2013-04-21) +function binaryStringToArrayBuffer(bin) { + var length = bin.length; + var buf = new ArrayBuffer(length); + var arr = new Uint8Array(buf); + for (var i = 0; i < length; i++) { + arr[i] = bin.charCodeAt(i); + } + return buf; +} - for (var _i2 = 0, _Object$keys2 = Object.keys(handlers); _i2 < _Object$keys2.length; _i2++) { - var handlerName = _Object$keys2[_i2]; +function binStringToBluffer(binString, type) { + return typedBuffer(binString, 'binary', type); +} - if (!stackClient.options[handlerName]) { - stackClient.options[handlerName] = handlers[handlerName]; - } else { - if (warningForCustomHandlers) { - console.warn("You passed a stackClient with its own ".concat(handlerName, ". It is not supported, unexpected things might happen.")); - } - } - } - } else { - var options = _objectSpread(_objectSpread({}, this.options), handlers); +// This function is unused in Node +/* istanbul ignore next */ +function createBlob() { +} - this.stackClient = this.options.oauth ? new _cozyStackClient.OAuthClient(options) : new _cozyStackClient.default(options); - } +function blobToBase64(blobOrBuffer, callback) { + callback(blobOrBuffer.toString('base64')); +} - this.client = new Proxy(this.stackClient, deprecatedHandler('Using cozyClient.client is deprecated, please use cozyClient.stackClient.')); - } - }, { - key: "getClient", - value: function getClient() { - console.warn('CozyClient: getClient() is deprecated, please use getStackClient().'); - return this.getStackClient(); - } - }, { - key: "getStackClient", - value: function getStackClient() { - if (!this.stackClient) { - this.createClient(); - } +// not used in Node, but here for completeness +function blobToBase64$1(blobOrBuffer, callback) { + callback(blobOrBuffer.toString('binary')); +} - return this.stackClient; - } - }, { - key: "reducer", - value: function reducer() { - return _store.default; - } - }, { - key: "dispatch", - value: function dispatch(action) { - return this.store.dispatch(action); - } - /** - * getInstanceOptions - Returns current instance options, such as domain or app slug - * - * @returns {object} - */ +// simplified API. universal browser support is assumed +function readAsArrayBuffer(blob, callback) { + var reader = new FileReader(); + reader.onloadend = function (e) { + var result = e.target.result || new ArrayBuffer(0); + callback(result); + }; + reader.readAsArrayBuffer(blob); +} - }, { - key: "getInstanceOptions", - value: function getInstanceOptions() { - return this.instanceOptions; +//Can't find original post, but this is close +//http://stackoverflow.com/questions/6965107/ (continues on next line) +//converting-between-strings-and-arraybuffers +function arrayBufferToBinaryString(buffer) { + var binary = ''; + var bytes = new Uint8Array(buffer); + var length = bytes.byteLength; + for (var i = 0; i < length; i++) { + binary += String.fromCharCode(bytes[i]); + } + return binary; +} + +// shim for browsers that don't support it +function readAsBinaryString(blob, callback) { + var reader = new FileReader(); + var hasBinaryString = typeof reader.readAsBinaryString === 'function'; + reader.onloadend = function (e) { + var result = e.target.result || ''; + if (hasBinaryString) { + return callback(result); } - /** - * loadInstanceOptionsFromDOM - Loads the dataset injected by the Stack in web pages and exposes it through getInstanceOptions - * - * @param {string} [selector=[role=application]] A selector for the node that holds the dataset to load - * - * @returns {void} - */ + callback(arrayBufferToBinaryString(result)); + }; + if (hasBinaryString) { + reader.readAsBinaryString(blob); + } else { + reader.readAsArrayBuffer(blob); + } +} - }, { - key: "loadInstanceOptionsFromDOM", - value: function loadInstanceOptionsFromDOM() { - var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '[role=application]'; - var root = document.querySelector(selector); - if (!(root instanceof HTMLElement)) { - throw new Error('The selector that is passed does not return an HTMLElement'); - } - var _root$dataset = root.dataset, - _root$dataset$cozy = _root$dataset.cozy, - cozy = _root$dataset$cozy === void 0 ? '{}' : _root$dataset$cozy, - dataset = (0, _objectWithoutProperties2.default)(_root$dataset, ["cozy"]); - this.instanceOptions = _objectSpread(_objectSpread({}, JSON.parse(cozy)), dataset); - this.capabilities = this.instanceOptions.capabilities || null; - } - /** - * Directly set the data in the store, without using a query - * This is useful for cases like Pouch replication, which wants to - * set some data in the store. - * - * @param {object} data - Data that is inserted in the store. Shape: { doctype: [data] } - */ - }, { - key: "setData", - value: function setData(data) { - var _this10 = this; +/***/ }), +/* 519 */ +/***/ ((module) => { - this.ensureStore(); - Object.entries(data).forEach(function (_ref8) { - var _ref9 = (0, _slicedToArray2.default)(_ref8, 2), - doctype = _ref9[0], - data = _ref9[1]; +var toString = Object.prototype.toString - _this10.dispatch((0, _store.receiveQueryResult)(null, { - data: data - })); - }); - } - /** - * At any time put an error function - * - * @param {Function} [onError] - Set a callback for queries which are errored - * @throws {Error} onError should not have been defined yet - */ +var isModern = ( + typeof Buffer.alloc === 'function' && + typeof Buffer.allocUnsafe === 'function' && + typeof Buffer.from === 'function' +) - }, { - key: "setOnError", - value: function setOnError(onError) { - if (this.options && this.options.onError) { - throw new Error('On Error is already defined'); - } +function isArrayBuffer (input) { + return toString.call(input).slice(8, -1) === 'ArrayBuffer' +} - this.options.onError = onError; - } - }, { - key: "toJSON", - value: function toJSON() { - return new _snapshots.CozyClient({ - uri: this.options.uri - }); - } - }], [{ - key: "fromOldClient", - value: function fromOldClient(oldClient, options) { - return new CozyClient(_objectSpread({ - uri: oldClient._url, - token: oldClient._token.token - }, options)); - } - /** - * To help with the transition from cozy-client-js to cozy-client, it is possible to instantiate - * a client with an OAuth-based instance of cozy-client-js. - * - * Warning: unlike other instantiators, this one needs to be awaited. - * - * @param {OldCozyClient} oldClient - An OAuth instance of the deprecated cozy-client - * @param {object} options - CozyStackClient options - * @returns {Promise<CozyClient>} An instance of a client, configured from the old client - */ +function fromArrayBuffer (obj, byteOffset, length) { + byteOffset >>>= 0 - }, { - key: "fromOldOAuthClient", - value: function () { - var _fromOldOAuthClient = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(oldClient, options) { - var credentials, oauthOptions; - return _regenerator.default.wrap(function _callee18$(_context18) { - while (1) { - switch (_context18.prev = _context18.next) { - case 0: - if (!oldClient._oauth) { - _context18.next = 8; - break; - } + var maxLength = obj.byteLength - byteOffset - _context18.next = 3; - return oldClient.authorize(); + if (maxLength < 0) { + throw new RangeError("'offset' is out of bounds") + } - case 3: - credentials = _context18.sent; - oauthOptions = { - oauth: credentials.client, - token: credentials.token, - scope: credentials.token.scope - }; - return _context18.abrupt("return", new CozyClient(_objectSpread(_objectSpread({ - uri: oldClient._url - }, oauthOptions), options))); + if (length === undefined) { + length = maxLength + } else { + length >>>= 0 - case 8: - throw new Error('Cannot instantiate a new client: old client is not an OAuth client. CozyClient.fromOldClient might be more suitable.'); + if (length > maxLength) { + throw new RangeError("'length' is out of bounds") + } + } - case 9: - case "end": - return _context18.stop(); - } - } - }, _callee18); - })); + return isModern + ? Buffer.from(obj.slice(byteOffset, byteOffset + length)) + : new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length))) +} - function fromOldOAuthClient(_x17, _x18) { - return _fromOldOAuthClient.apply(this, arguments); - } +function fromString (string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8' + } - return fromOldOAuthClient; - }() - /** - * In konnector/service context, CozyClient can be instantiated from - * environment variables - * - * @param {NodeEnvironment} [envArg] - The environment - * @param {object} options - Options - * @returns {CozyClient} - */ + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') + } - }, { - key: "fromEnv", - value: function fromEnv(envArg) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var env = envArg || (typeof process !== 'undefined' ? process.env : {}); - var COZY_URL = env.COZY_URL, - COZY_CREDENTIALS = env.COZY_CREDENTIALS, - NODE_ENV = env.NODE_ENV; + return isModern + ? Buffer.from(string, encoding) + : new Buffer(string, encoding) +} - if (!COZY_URL || !COZY_CREDENTIALS) { - throw new Error('Env used to instantiate CozyClient must have COZY_URL and COZY_CREDENTIALS'); - } +function bufferFrom (value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } - if (NODE_ENV === 'development') { - options.oauth = JSON.parse(COZY_CREDENTIALS); - } else { - options.token = COZY_CREDENTIALS.trim(); - } + if (isArrayBuffer(value)) { + return fromArrayBuffer(value, encodingOrOffset, length) + } - options.uri = COZY_URL.trim(); - return new CozyClient(_objectSpread({}, options)); - } - /** - * When used from an app, CozyClient can be instantiated from the data injected by the stack in - * the DOM. - * - * @param {object} options - CozyClient constructor options - * @param {string} selector - Options - * @returns {CozyClient} - CozyClient instance - */ + if (typeof value === 'string') { + return fromString(value, encodingOrOffset) + } - }, { - key: "fromDOM", - value: function fromDOM() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '[role=application]'; - var root = document.querySelector(selector); + return isModern + ? Buffer.from(value) + : new Buffer(value) +} - if (!(root instanceof HTMLElement)) { - throw new Error("Cannot find an HTMLElement corresponding to ".concat(selector)); - } +module.exports = bufferFrom - if (!root || !root.dataset) { - throw new Error("Found no data in ".concat(selector, " to instantiate cozyClient")); - } - var data = root.dataset.cozy ? JSON.parse(root.dataset.cozy) : _objectSpread({}, root.dataset); - var domain = data.domain, - token = data.token; +/***/ }), +/* 520 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - if (!domain || !token) { - domain = domain || data.cozyDomain; - token = token || data.cozyToken; - } +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "uniq": () => (/* binding */ uniq), +/* harmony export */ "sequentialize": () => (/* binding */ sequentialize), +/* harmony export */ "fin": () => (/* binding */ fin), +/* harmony export */ "callbackify": () => (/* binding */ callbackify), +/* harmony export */ "promisedCallback": () => (/* binding */ promisedCallback), +/* harmony export */ "mapToKeysArray": () => (/* binding */ mapToKeysArray), +/* harmony export */ "QueryParseError": () => (/* binding */ QueryParseError), +/* harmony export */ "NotFoundError": () => (/* binding */ NotFoundError), +/* harmony export */ "BuiltInError": () => (/* binding */ BuiltInError) +/* harmony export */ }); +/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(497); +/* harmony import */ var inherits__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(inherits__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var pouchdb_collections__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(509); +/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(495); +/* harmony import */ var argsarray__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(argsarray__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(507); - if (!domain || !token) { - throw new Error("Found no data in ".concat(root.dataset, " to instantiate cozyClient")); - } - return new CozyClient(_objectSpread({ - uri: "".concat(window.location.protocol, "//").concat(domain), - token: token, - capabilities: data.capabilities - }, options)); - } - }, { - key: "registerHook", - value: function registerHook(doctype, name, fn) { - var hooks = CozyClient.hooks[doctype] = CozyClient.hooks[doctype] || {}; - hooks[name] = hooks[name] || []; - hooks[name].push(fn); - } - }]); - return CozyClient; -}(); -CozyClient.hooks = CozyClient.hooks || {}; -CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config -CozyClient.version = "27.26.4"; -_microee.default.mixin(CozyClient); +function QueryParseError(message) { + this.status = 400; + this.name = 'query_parse_error'; + this.message = message; + this.error = true; + try { + Error.captureStackTrace(this, QueryParseError); + } catch (e) {} +} -var _default = CozyClient; -exports["default"] = _default; +inherits__WEBPACK_IMPORTED_MODULE_0___default()(QueryParseError, Error); -/***/ }), -/* 514 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function NotFoundError(message) { + this.status = 404; + this.name = 'not_found'; + this.message = message; + this.error = true; + try { + Error.captureStackTrace(this, NotFoundError); + } catch (e) {} +} -var arrayWithHoles = __webpack_require__(515); +inherits__WEBPACK_IMPORTED_MODULE_0___default()(NotFoundError, Error); + +function BuiltInError(message) { + this.status = 500; + this.name = 'invalid_value'; + this.message = message; + this.error = true; + try { + Error.captureStackTrace(this, BuiltInError); + } catch (e) {} +} -var iterableToArray = __webpack_require__(516); +inherits__WEBPACK_IMPORTED_MODULE_0___default()(BuiltInError, Error); -var unsupportedIterableToArray = __webpack_require__(517); +function promisedCallback(promise, callback) { + if (callback) { + promise.then(function (res) { + (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__.nextTick)(function () { + callback(null, res); + }); + }, function (reason) { + (0,pouchdb_utils__WEBPACK_IMPORTED_MODULE_3__.nextTick)(function () { + callback(reason); + }); + }); + } + return promise; +} -var nonIterableRest = __webpack_require__(519); +function callbackify(fun) { + return argsarray__WEBPACK_IMPORTED_MODULE_2___default()(function (args) { + var cb = args.pop(); + var promise = fun.apply(this, args); + if (typeof cb === 'function') { + promisedCallback(promise, cb); + } + return promise; + }); +} -function _toArray(arr) { - return arrayWithHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableRest(); +// Promise finally util similar to Q.finally +function fin(promise, finalPromiseFactory) { + return promise.then(function (res) { + return finalPromiseFactory().then(function () { + return res; + }); + }, function (reason) { + return finalPromiseFactory().then(function () { + throw reason; + }); + }); } -module.exports = _toArray; -module.exports["default"] = module.exports, module.exports.__esModule = true; +function sequentialize(queue, promiseFactory) { + return function () { + var args = arguments; + var that = this; + return queue.add(function () { + return promiseFactory.apply(that, args); + }); + }; +} -/***/ }), -/* 515 */ -/***/ ((module) => { +// uniq an array of strings, order not guaranteed +// similar to underscore/lodash _.uniq +function uniq(arr) { + var theSet = new pouchdb_collections__WEBPACK_IMPORTED_MODULE_1__.Set(arr); + var result = new Array(theSet.size); + var index = -1; + theSet.forEach(function (value) { + result[++index] = value; + }); + return result; +} -function _arrayWithHoles(arr) { - if (Array.isArray(arr)) return arr; +function mapToKeysArray(map) { + var result = new Array(map.size); + var index = -1; + map.forEach(function (value, key) { + result[++index] = key; + }); + return result; } -module.exports = _arrayWithHoles; -module.exports["default"] = module.exports, module.exports.__esModule = true; + + /***/ }), -/* 516 */ -/***/ ((module) => { +/* 521 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -function _iterableToArray(iter) { - if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); -} +"use strict"; -module.exports = _iterableToArray; -module.exports["default"] = module.exports, module.exports.__esModule = true; -/***/ }), -/* 517 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _interopRequireWildcard = __webpack_require__(522); + +var _interopRequireDefault = __webpack_require__(524); + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +var _exportNames = { + CozyLink: true, + StackLink: true, + compose: true, + QueryDefinition: true, + Mutations: true, + MutationTypes: true, + getDoctypeFromOperation: true, + Q: true, + Association: true, + HasMany: true, + HasOne: true, + HasOneInPlace: true, + HasManyInPlace: true, + HasManyTriggers: true, + dehydrate: true, + generateWebLink: true, + rootCozyUrl: true, + InvalidCozyUrlError: true, + InvalidProtocolError: true, + cancelable: true, + getQueryFromState: true, + Registry: true, + manifest: true, + BulkEditError: true, + models: true +}; +Object.defineProperty(exports, "default", ({ + enumerable: true, + get: function get() { + return _CozyClient.default; + } +})); +Object.defineProperty(exports, "CozyLink", ({ + enumerable: true, + get: function get() { + return _CozyLink.default; + } +})); +Object.defineProperty(exports, "StackLink", ({ + enumerable: true, + get: function get() { + return _StackLink.default; + } +})); +Object.defineProperty(exports, "compose", ({ + enumerable: true, + get: function get() { + return _flow.default; + } +})); +Object.defineProperty(exports, "QueryDefinition", ({ + enumerable: true, + get: function get() { + return _dsl.QueryDefinition; + } +})); +Object.defineProperty(exports, "Mutations", ({ + enumerable: true, + get: function get() { + return _dsl.Mutations; + } +})); +Object.defineProperty(exports, "MutationTypes", ({ + enumerable: true, + get: function get() { + return _dsl.MutationTypes; + } +})); +Object.defineProperty(exports, "getDoctypeFromOperation", ({ + enumerable: true, + get: function get() { + return _dsl.getDoctypeFromOperation; + } +})); +Object.defineProperty(exports, "Q", ({ + enumerable: true, + get: function get() { + return _dsl.Q; + } +})); +Object.defineProperty(exports, "Association", ({ + enumerable: true, + get: function get() { + return _associations.Association; + } +})); +Object.defineProperty(exports, "HasMany", ({ + enumerable: true, + get: function get() { + return _associations.HasMany; + } +})); +Object.defineProperty(exports, "HasOne", ({ + enumerable: true, + get: function get() { + return _associations.HasOne; + } +})); +Object.defineProperty(exports, "HasOneInPlace", ({ + enumerable: true, + get: function get() { + return _associations.HasOneInPlace; + } +})); +Object.defineProperty(exports, "HasManyInPlace", ({ + enumerable: true, + get: function get() { + return _associations.HasManyInPlace; + } +})); +Object.defineProperty(exports, "HasManyTriggers", ({ + enumerable: true, + get: function get() { + return _associations.HasManyTriggers; + } +})); +Object.defineProperty(exports, "dehydrate", ({ + enumerable: true, + get: function get() { + return _helpers.dehydrate; + } +})); +Object.defineProperty(exports, "generateWebLink", ({ + enumerable: true, + get: function get() { + return _helpers.generateWebLink; + } +})); +Object.defineProperty(exports, "rootCozyUrl", ({ + enumerable: true, + get: function get() { + return _helpers.rootCozyUrl; + } +})); +Object.defineProperty(exports, "InvalidCozyUrlError", ({ + enumerable: true, + get: function get() { + return _helpers.InvalidCozyUrlError; + } +})); +Object.defineProperty(exports, "InvalidProtocolError", ({ + enumerable: true, + get: function get() { + return _helpers.InvalidProtocolError; + } +})); +Object.defineProperty(exports, "cancelable", ({ + enumerable: true, + get: function get() { + return _utils.cancelable; + } +})); +Object.defineProperty(exports, "getQueryFromState", ({ + enumerable: true, + get: function get() { + return _store.getQueryFromState; + } +})); +Object.defineProperty(exports, "Registry", ({ + enumerable: true, + get: function get() { + return _registry.default; + } +})); +Object.defineProperty(exports, "BulkEditError", ({ + enumerable: true, + get: function get() { + return _errors.BulkEditError; + } +})); +exports.models = exports.manifest = void 0; + +var _CozyClient = _interopRequireDefault(__webpack_require__(525)); -var arrayLikeToArray = __webpack_require__(518); +var _CozyLink = _interopRequireDefault(__webpack_require__(699)); -function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen); -} +var _StackLink = _interopRequireDefault(__webpack_require__(698)); -module.exports = _unsupportedIterableToArray; -module.exports["default"] = module.exports, module.exports.__esModule = true; +var _flow = _interopRequireDefault(__webpack_require__(805)); -/***/ }), -/* 518 */ -/***/ ((module) => { +var _dsl = __webpack_require__(619); -function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; +var _associations = __webpack_require__(703); - for (var i = 0, arr2 = new Array(len); i < len; i++) { - arr2[i] = arr[i]; - } +var _helpers = __webpack_require__(768); - return arr2; -} +var _utils = __webpack_require__(817); -module.exports = _arrayLikeToArray; -module.exports["default"] = module.exports, module.exports.__esModule = true; +var _store = __webpack_require__(705); -/***/ }), -/* 519 */ -/***/ ((module) => { +var _registry = _interopRequireDefault(__webpack_require__(608)); -function _nonIterableRest() { - throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); -} +var manifest = _interopRequireWildcard(__webpack_require__(818)); -module.exports = _nonIterableRest; -module.exports["default"] = module.exports, module.exports.__esModule = true; +exports.manifest = manifest; -/***/ }), -/* 520 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _mock = __webpack_require__(819); -var arrayWithHoles = __webpack_require__(515); +Object.keys(_mock).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _mock[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function get() { + return _mock[key]; + } + }); +}); -var iterableToArrayLimit = __webpack_require__(521); +var _errors = __webpack_require__(700); -var unsupportedIterableToArray = __webpack_require__(517); +var _cli = __webpack_require__(820); -var nonIterableRest = __webpack_require__(519); +Object.keys(_cli).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _cli[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function get() { + return _cli[key]; + } + }); +}); -function _slicedToArray(arr, i) { - return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest(); -} +var models = _interopRequireWildcard(__webpack_require__(826)); -module.exports = _slicedToArray; -module.exports["default"] = module.exports, module.exports.__esModule = true; +exports.models = models; /***/ }), -/* 521 */ -/***/ ((module) => { - -function _iterableToArrayLimit(arr, i) { - var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; +/* 522 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (_i == null) return; - var _arr = []; - var _n = true; - var _d = false; +var _typeof = (__webpack_require__(523)["default"]); - var _s, _e; +function _getRequireWildcardCache(nodeInterop) { + if (typeof WeakMap !== "function") return null; + var cacheBabelInterop = new WeakMap(); + var cacheNodeInterop = new WeakMap(); + return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { + return nodeInterop ? cacheNodeInterop : cacheBabelInterop; + })(nodeInterop); +} - try { - for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); +function _interopRequireWildcard(obj, nodeInterop) { + if (!nodeInterop && obj && obj.__esModule) { + return obj; + } - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"] != null) _i["return"](); - } finally { - if (_d) throw _e; - } + if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { + return { + "default": obj + }; } - return _arr; -} + var cache = _getRequireWildcardCache(nodeInterop); -module.exports = _iterableToArrayLimit; -module.exports["default"] = module.exports, module.exports.__esModule = true; + if (cache && cache.has(obj)) { + return cache.get(obj); + } -/***/ }), -/* 522 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var newObj = {}; + var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; -var arrayWithoutHoles = __webpack_require__(523); + for (var key in obj) { + if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { + var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; -var iterableToArray = __webpack_require__(516); + if (desc && (desc.get || desc.set)) { + Object.defineProperty(newObj, key, desc); + } else { + newObj[key] = obj[key]; + } + } + } -var unsupportedIterableToArray = __webpack_require__(517); + newObj["default"] = obj; -var nonIterableSpread = __webpack_require__(524); + if (cache) { + cache.set(obj, newObj); + } -function _toConsumableArray(arr) { - return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread(); + return newObj; } -module.exports = _toConsumableArray; +module.exports = _interopRequireWildcard; module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), /* 523 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/***/ ((module) => { -var arrayLikeToArray = __webpack_require__(518); +function _typeof(obj) { + "@babel/helpers - typeof"; -function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) return arrayLikeToArray(arr); + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + module.exports = _typeof = function _typeof(obj) { + return typeof obj; + }; + + module.exports["default"] = module.exports, module.exports.__esModule = true; + } else { + module.exports = _typeof = function _typeof(obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + + module.exports["default"] = module.exports, module.exports.__esModule = true; + } + + return _typeof(obj); } -module.exports = _arrayWithoutHoles; +module.exports = _typeof; module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), /* 524 */ /***/ ((module) => { -function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + "default": obj + }; } -module.exports = _nonIterableSpread; +module.exports = _interopRequireDefault; module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), /* 525 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var objectWithoutPropertiesLoose = __webpack_require__(526); - -function _objectWithoutProperties(source, excluded) { - if (source == null) return {}; - var target = objectWithoutPropertiesLoose(source, excluded); - var key, i; - - if (Object.getOwnPropertySymbols) { - var sourceSymbolKeys = Object.getOwnPropertySymbols(source); - - for (i = 0; i < sourceSymbolKeys.length; i++) { - key = sourceSymbolKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; - target[key] = source[key]; - } - } +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - return target; -} +"use strict"; -module.exports = _objectWithoutProperties; -module.exports["default"] = module.exports, module.exports.__esModule = true; -/***/ }), -/* 526 */ -/***/ ((module) => { +var _interopRequireWildcard = __webpack_require__(522); -function _objectWithoutPropertiesLoose(source, excluded) { - if (source == null) return {}; - var target = {}; - var sourceKeys = Object.keys(source); - var key, i; +var _interopRequireDefault = __webpack_require__(524); - for (i = 0; i < sourceKeys.length; i++) { - key = sourceKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - target[key] = source[key]; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - return target; -} +var _toArray2 = _interopRequireDefault(__webpack_require__(526)); -module.exports = _objectWithoutPropertiesLoose; -module.exports["default"] = module.exports, module.exports.__esModule = true; +var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532)); -/***/ }), -/* 527 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); -module.exports = __webpack_require__(528); +var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -/***/ }), -/* 528 */ -/***/ ((module) => { +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var runtime = (function (exports) { - "use strict"; +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - var Op = Object.prototype; - var hasOwn = Op.hasOwnProperty; - var undefined; // More compressible than void 0. - var $Symbol = typeof Symbol === "function" ? Symbol : {}; - var iteratorSymbol = $Symbol.iterator || "@@iterator"; - var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; - var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); - function define(obj, key, value) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - return obj[key]; - } - try { - // IE 8 has a broken Object.defineProperty that only works on DOM objects. - define({}, ""); - } catch (err) { - define = function(obj, key, value) { - return obj[key] = value; - }; - } +var _mapValues = _interopRequireDefault(__webpack_require__(545)); - function wrap(innerFn, outerFn, self, tryLocsList) { - // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. - var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; - var generator = Object.create(protoGenerator.prototype); - var context = new Context(tryLocsList || []); +var _fromPairs = _interopRequireDefault(__webpack_require__(551)); - // The ._invoke method unifies the implementations of the .next, - // .throw, and .return methods. - generator._invoke = makeInvokeMethod(innerFn, self, context); +var _flatten = _interopRequireDefault(__webpack_require__(552)); - return generator; - } - exports.wrap = wrap; +var _uniqBy = _interopRequireDefault(__webpack_require__(412)); - // Try/catch helper to minimize deoptimizations. Returns a completion - // record like context.tryEntries[i].completion. This interface could - // have been (and was previously) designed to take a closure to be - // invoked without arguments, but in all the cases we care about we - // already have an existing method we want to call, so there's no need - // to create a new function object. We can even get away with assuming - // the method takes exactly one argument, since that happens to be true - // in every case, so we don't have to touch the arguments object. The - // only additional allocation required is the completion record, which - // has a stable shape and so hopefully should be cheap to allocate. - function tryCatch(fn, obj, arg) { - try { - return { type: "normal", arg: fn.call(obj, arg) }; - } catch (err) { - return { type: "throw", arg: err }; - } - } +var _zip = _interopRequireDefault(__webpack_require__(555)); - var GenStateSuspendedStart = "suspendedStart"; - var GenStateSuspendedYield = "suspendedYield"; - var GenStateExecuting = "executing"; - var GenStateCompleted = "completed"; +var _forEach = _interopRequireDefault(__webpack_require__(565)); - // Returning this object from the innerFn has the same effect as - // breaking out of the dispatch switch statement. - var ContinueSentinel = {}; +var _get = _interopRequireDefault(__webpack_require__(370)); - // Dummy constructor functions that we use as the .constructor and - // .constructor.prototype properties for functions that return Generator - // objects. For full spec compliance, you may wish to configure your - // minifier not to mangle the names of these two functions. - function Generator() {} - function GeneratorFunction() {} - function GeneratorFunctionPrototype() {} +var _microee = _interopRequireDefault(__webpack_require__(570)); - // This is a polyfill for %IteratorPrototype% for environments that - // don't natively support it. - var IteratorPrototype = {}; - define(IteratorPrototype, iteratorSymbol, function () { - return this; - }); +var _cozyStackClient = _interopRequireWildcard(__webpack_require__(571)); - var getProto = Object.getPrototypeOf; - var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); - if (NativeIteratorPrototype && - NativeIteratorPrototype !== Op && - hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { - // This environment has a native %IteratorPrototype%; use it instead - // of the polyfill. - IteratorPrototype = NativeIteratorPrototype; - } +var _const = __webpack_require__(697); - var Gp = GeneratorFunctionPrototype.prototype = - Generator.prototype = Object.create(IteratorPrototype); - GeneratorFunction.prototype = GeneratorFunctionPrototype; - define(Gp, "constructor", GeneratorFunctionPrototype); - define(GeneratorFunctionPrototype, "constructor", GeneratorFunction); - GeneratorFunction.displayName = define( - GeneratorFunctionPrototype, - toStringTagSymbol, - "GeneratorFunction" - ); +var _StackLink = _interopRequireDefault(__webpack_require__(698)); - // Helper for defining the .next, .throw, and .return methods of the - // Iterator interface in terms of a single ._invoke method. - function defineIteratorMethods(prototype) { - ["next", "throw", "return"].forEach(function(method) { - define(prototype, method, function(arg) { - return this._invoke(method, arg); - }); - }); - } +var _associations = __webpack_require__(703); - exports.isGeneratorFunction = function(genFun) { - var ctor = typeof genFun === "function" && genFun.constructor; - return ctor - ? ctor === GeneratorFunction || - // For the native GeneratorFunction constructor, the best we can - // do is to check its .name property. - (ctor.displayName || ctor.name) === "GeneratorFunction" - : false; - }; +var _helpers = __webpack_require__(767); - exports.mark = function(genFun) { - if (Object.setPrototypeOf) { - Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); - } else { - genFun.__proto__ = GeneratorFunctionPrototype; - define(genFun, toStringTagSymbol, "GeneratorFunction"); - } - genFun.prototype = Object.create(Gp); - return genFun; - }; +var _helpers2 = __webpack_require__(768); - // Within the body of any async function, `await x` is transformed to - // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test - // `hasOwn.call(value, "__await")` to determine if the yielded value is - // meant to be awaited. - exports.awrap = function(arg) { - return { __await: arg }; - }; +var _dsl = __webpack_require__(619); - function AsyncIterator(generator, PromiseImpl) { - function invoke(method, arg, resolve, reject) { - var record = tryCatch(generator[method], generator, arg); - if (record.type === "throw") { - reject(record.arg); - } else { - var result = record.arg; - var value = result.value; - if (value && - typeof value === "object" && - hasOwn.call(value, "__await")) { - return PromiseImpl.resolve(value.__await).then(function(value) { - invoke("next", value, resolve, reject); - }, function(err) { - invoke("throw", err, resolve, reject); - }); - } +var _mobile = __webpack_require__(769); - return PromiseImpl.resolve(value).then(function(unwrapped) { - // When a yielded Promise is resolved, its final value becomes - // the .value of the Promise<{value,done}> result for the - // current iteration. - result.value = unwrapped; - resolve(result); - }, function(error) { - // If a rejected Promise was yielded, throw the rejection back - // into the async generator function so it can be handled there. - return invoke("throw", error, resolve, reject); - }); - } - } +var _optimize = _interopRequireDefault(__webpack_require__(787)); - var previousPromise; +var _store = _interopRequireWildcard(__webpack_require__(705)); - function enqueue(method, arg) { - function callInvokeWithMethodAndArg() { - return new PromiseImpl(function(resolve, reject) { - invoke(method, arg, resolve, reject); - }); - } +var _policies = _interopRequireDefault(__webpack_require__(789)); - return previousPromise = - // If enqueue has been called before, then we want to wait until - // all previous Promises have been resolved before calling invoke, - // so that results are always delivered in the correct order. If - // enqueue has not been called before, then it is important to - // call invoke immediately, without waiting on a callback to fire, - // so that the async generator function has the opportunity to do - // any necessary setup in a predictable way. This predictability - // is why the Promise constructor synchronously invokes its - // executor callback, and why async functions synchronously - // execute code before the first await. Since we implement simple - // async functions in terms of async generators, it is especially - // important to get this right, even though it requires care. - previousPromise ? previousPromise.then( - callInvokeWithMethodAndArg, - // Avoid propagating failures to Promises returned by later - // invocations of the iterator. - callInvokeWithMethodAndArg - ) : callInvokeWithMethodAndArg(); - } +var _Schema = _interopRequireDefault(__webpack_require__(790)); - // Define the unified helper method that is used to implement .next, - // .throw, and .return (see defineIteratorMethods). - this._invoke = enqueue; - } +var _CozyLink = __webpack_require__(699); - defineIteratorMethods(AsyncIterator.prototype); - define(AsyncIterator.prototype, asyncIteratorSymbol, function () { - return this; - }); - exports.AsyncIterator = AsyncIterator; +var _ObservableQuery = _interopRequireDefault(__webpack_require__(796)); - // Note that simple async functions are implemented on top of - // AsyncIterator objects; they just return a Promise for the value of - // the final result produced by the iterator. - exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) { - if (PromiseImpl === void 0) PromiseImpl = Promise; +var _snapshots = __webpack_require__(797); - var iter = new AsyncIterator( - wrap(innerFn, outerFn, self, tryLocsList), - PromiseImpl - ); +var _logger = _interopRequireDefault(__webpack_require__(715)); - return exports.isGeneratorFunction(outerFn) - ? iter // If outerFn is a generator, return the full iterator. - : iter.next().then(function(result) { - return result.done ? result.value : iter.next(); - }); - }; +var _types = __webpack_require__(622); - function makeInvokeMethod(innerFn, self, context) { - var state = GenStateSuspendedStart; +var _queries = __webpack_require__(735); - return function invoke(method, arg) { - if (state === GenStateExecuting) { - throw new Error("Generator is already running"); - } +var _jsonStableStringify = _interopRequireDefault(__webpack_require__(798)); - if (state === GenStateCompleted) { - if (method === "throw") { - throw arg; - } +var _promiseCache = _interopRequireDefault(__webpack_require__(802)); - // Be forgiving, per 25.3.3.3.3 of the spec: - // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume - return doneResult(); - } +var _flagshipCertification = __webpack_require__(803); - context.method = method; - context.arg = arg; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - while (true) { - var delegate = context.delegate; - if (delegate) { - var delegateResult = maybeInvokeDelegate(delegate, context); - if (delegateResult) { - if (delegateResult === ContinueSentinel) continue; - return delegateResult; - } - } +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - if (context.method === "next") { - // Setting context._sent for legacy support of Babel's - // function.sent implementation. - context.sent = context._sent = context.arg; +function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } - } else if (context.method === "throw") { - if (state === GenStateSuspendedStart) { - state = GenStateCompleted; - throw context.arg; - } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - context.dispatchException(context.arg); +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - } else if (context.method === "return") { - context.abrupt("return", context.arg); - } +var ensureArray = function ensureArray(arr) { + return Array.isArray(arr) ? arr : [arr]; +}; - state = GenStateExecuting; +var deprecatedHandler = function deprecatedHandler(msg) { + return { + get: function get(target, prop) { + console.warn(msg); + return target[prop]; + } + }; +}; - var record = tryCatch(innerFn, self, context); - if (record.type === "normal") { - // If an exception is thrown from innerFn, we leave state === - // GenStateExecuting and loop back for another invocation. - state = context.done - ? GenStateCompleted - : GenStateSuspendedYield; +var supportsReferences = function supportsReferences(relationshipClass) { + return relationshipClass.prototype.addReferences && relationshipClass.prototype.removeReferences; +}; - if (record.arg === ContinueSentinel) { - continue; - } +var referencesUnsupportedError = function referencesUnsupportedError(relationshipClassName) { + return new Error("The \"".concat(relationshipClassName, "\" relationship does not support references. If you need to add references to a document, its relationship class must have the methods {add,remove}References")); +}; - return { - value: record.arg, - done: context.done - }; +var securiseUri = function securiseUri(uri) { + var _window$cozy; - } else if (record.type === "throw") { - state = GenStateCompleted; - // Dispatch the exception by looping back around to the - // context.dispatchException(context.arg) call above. - context.method = "throw"; - context.arg = record.arg; - } - } - }; + if (uri && typeof window !== 'undefined' && (_window$cozy = window['cozy']) !== null && _window$cozy !== void 0 && _window$cozy.isSecureProtocol) { + var secureUrl = new URL(uri); + secureUrl.protocol = 'https:'; + return secureUrl.toString(); } - // Call delegate.iterator[context.method](context.arg) and handle the - // result, either by returning a { value, done } result from the - // delegate iterator, or by modifying context.method and context.arg, - // setting context.delegate to null, and returning the ContinueSentinel. - function maybeInvokeDelegate(delegate, context) { - var method = delegate.iterator[context.method]; - if (method === undefined) { - // A .throw or .return when the delegate iterator has no .throw - // method always terminates the yield* loop. - context.delegate = null; + return uri; +}; - if (context.method === "throw") { - // Note: ["return"] must be used for ES3 parsing compatibility. - if (delegate.iterator["return"]) { - // If the delegate iterator has a return method, give it a - // chance to clean up. - context.method = "return"; - context.arg = undefined; - maybeInvokeDelegate(delegate, context); +var DOC_CREATION = 'creation'; +var DOC_UPDATE = 'update'; +/** + * @typedef {object} ClientOptions + * @property {object} [client] + * @property {object} [link] + * @property {object} [links] + * @property {Token} [token] + * @property {string} [uri] + * @property {object} [stackClient] + * @property {boolean} [warningForCustomHandlers] + * @property {boolean} [autoHydrate] + * @property {object} [oauth] + * @property {Function} [onTokenRefresh] + * @property {Function} [onError] - Default callback if a query is errored + * @property {Link} [link] - Backward compatibility + * @property {Array<Link>} [links] - List of links + * @property {object} [schema] - Schema description for each doctypes + * @property {AppMetadata} [appMetadata] - Metadata about the application that will be used in ensureCozyMetadata + * @property {ClientCapabilities} [capabilities] - Capabilities sent by the stack + * @property {boolean} [store] - If set to false, the client will not instantiate a Redux store automatically. Use this if you want to merge cozy-client's store with your own redux store. See [here](https://docs.cozy.io/en/cozy-client/react-integration/#1b-use-your-own-redux-store) for more information. + */ - if (context.method === "throw") { - // If maybeInvokeDelegate(context) changed context.method from - // "return" to "throw", let that override the TypeError below. - return ContinueSentinel; - } - } +/** + * Responsible for + * + * - Creating observable queries + * - Hydration + * - Creating plan for saving documents + * - Associations + */ - context.method = "throw"; - context.arg = new TypeError( - "The iterator does not provide a 'throw' method"); - } +var CozyClient = /*#__PURE__*/function () { + /** + * @param {ClientOptions} rawOptions - Options + * + * @example + * ```js + * const client = new CozyClient({ + * schema: { + * todos: { + * doctype: 'io.cozy.todos', + * relationships: { + * authors: { + * type: 'has-many', + * doctype: 'io.cozy.persons' + * } + * } + * } + * } + * }) + * ``` + * + * Cozy-Client will automatically call `this.login()` if provided with a token and an uri + */ + function CozyClient() { + var _this = this; - return ContinueSentinel; - } + var rawOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + (0, _classCallCheck2.default)(this, CozyClient); + (0, _defineProperty2.default)(this, "fetchQueryAndGetFromState", /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(query) { + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.prev = 0; + _context.next = 3; + return _this.query(query.definition, query.options); - var record = tryCatch(method, delegate.iterator, context.arg); + case 3: + return _context.abrupt("return", _this.getQueryFromState(query.options.as)); - if (record.type === "throw") { - context.method = "throw"; - context.arg = record.arg; - context.delegate = null; - return ContinueSentinel; - } + case 6: + _context.prev = 6; + _context.t0 = _context["catch"](0); + throw _context.t0; - var info = record.arg; + case 9: + case "end": + return _context.stop(); + } + } + }, _callee, null, [[0, 6]]); + })); - if (! info) { - context.method = "throw"; - context.arg = new TypeError("iterator result is not an object"); - context.delegate = null; - return ContinueSentinel; - } + return function (_x) { + return _ref.apply(this, arguments); + }; + }()); + var link = rawOptions.link, + links = rawOptions.links, + _rawOptions$schema = rawOptions.schema, + schema = _rawOptions$schema === void 0 ? {} : _rawOptions$schema, + _rawOptions$appMetada = rawOptions.appMetadata, + appMetadata = _rawOptions$appMetada === void 0 ? {} : _rawOptions$appMetada, + capabilities = rawOptions.capabilities, + options = (0, _objectWithoutProperties2.default)(rawOptions, ["link", "links", "schema", "appMetadata", "capabilities"]); - if (info.done) { - // Assign the result of the finished delegate to the temporary - // variable specified by delegate.resultName (see delegateYield). - context[delegate.resultName] = info.value; + if (link) { + console.warn('`link` is deprecated, use `links`'); + } - // Resume execution at the desired location (see delegateYield). - context.next = delegate.nextLoc; + this.appMetadata = appMetadata; + options.uri = securiseUri(options.uri); + this.options = options; + this.queryIdGenerator = new _queries.QueryIDGenerator(); + this.isLogged = false; + this.instanceOptions = {}; // Bind handlers - // If context.method was "throw" but the delegate handled the - // exception, let the outer generator proceed normally. If - // context.method was "next", forget context.arg since it has been - // "consumed" by the delegate iterator. If context.method was - // "return", allow the original .return call to continue in the - // outer generator. - if (context.method !== "return") { - context.method = "next"; - context.arg = undefined; + this.handleRevocationChange = this.handleRevocationChange.bind(this); + this.handleTokenRefresh = this.handleTokenRefresh.bind(this); + this.createClient(); + var stackClient = this.getStackClient(); + stackClient.on('error', function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; } - } else { - // Re-yield the result returned by the delegate method. - return info; - } - - // The delegate iterator is finished, so forget it and continue with - // the outer generator. - context.delegate = null; - return ContinueSentinel; - } + return _this.emit.apply(_this, ['error'].concat(args)); + }); + this.links = ensureArray(link || links || new _StackLink.default()); + this.registerClientOnLinks(); + this.chain = (0, _CozyLink.chain)(this.links); + this.schema = new _Schema.default(schema, stackClient); + /** + * @type {ClientCapabilities} + */ - // Define Generator.prototype.{next,throw,return} in terms of the - // unified ._invoke helper method. - defineIteratorMethods(Gp); + this.capabilities = capabilities || null; // Instances of plugins registered with registerPlugin - define(Gp, toStringTagSymbol, "Generator"); + this.plugins = {}; - // A Generator should always return itself as the iterator object when the - // @@iterator function is called on it. Some browsers' implementations of the - // iterator prototype chain incorrectly implement this, causing the Generator - // object to not be returned from this call. This ensures that doesn't happen. - // See https://github.com/facebook/regenerator/issues/274 for more details. - define(Gp, iteratorSymbol, function() { - return this; - }); + try { + this.loadInstanceOptionsFromDOM(); + } catch (err) {// not a critical error, we may be in node or the instance options are not on the default HTML element + } - define(Gp, "toString", function() { - return "[object Generator]"; - }); + if (options.uri && options.token) { + this.login(); + } + /** + * @type {object} + */ - function pushTryEntry(locs) { - var entry = { tryLoc: locs[0] }; - if (1 in locs) { - entry.catchLoc = locs[1]; - } + this.storeAccesors = null; - if (2 in locs) { - entry.finallyLoc = locs[2]; - entry.afterLoc = locs[3]; + if (options.store !== false) { + this.ensureStore(); } + /** + * Holds in-flight promises for deduplication purpose + * + * @private + * @type {PromiseCache} + */ - this.tryEntries.push(entry); - } - - function resetTryEntry(entry) { - var record = entry.completion || {}; - record.type = "normal"; - delete record.arg; - entry.completion = record; - } - function Context(tryLocsList) { - // The root entry object (effectively a try statement without a catch - // or a finally block) gives us a place to store values thrown from - // locations where there is no enclosing try statement. - this.tryEntries = [{ tryLoc: "root" }]; - tryLocsList.forEach(pushTryEntry, this); - this.reset(true); + this._promiseCache = new _promiseCache.default(); } + /** + * Gets overrided by MicroEE.mixin + * This is here just so typescript does not scream + * + * TODO Find a better way to make TS understand that emit is + * a method from cozy-client + */ - exports.keys = function(object) { - var keys = []; - for (var key in object) { - keys.push(key); - } - keys.reverse(); - - // Rather than returning an object with a next method, we keep - // things simple and return the next function itself. - return function next() { - while (keys.length) { - var key = keys.pop(); - if (key in object) { - next.value = key; - next.done = false; - return next; - } - } - // To avoid creating an additional object, we just hang the .value - // and .done properties off the next function object itself. This - // also ensures that the minifier will not anonymize the function. - next.done = true; - return next; - }; - }; + (0, _createClass2.default)(CozyClient, [{ + key: "emit", + value: function emit() {} + }, { + key: "on", + value: function on() {} + }, { + key: "removeListener", + value: function removeListener() {} + /** + * A plugin is a class whose constructor receives the client as first argument. + * The main mean of interaction with the client should be with events + * like "login"/"logout". + * + * The plugin system is meant to encourage separation of concerns, modularity + * and testability : instead of registering events at module level, please + * create a plugin that subscribes to events. + * + * Plugin instances are stored internally in the `plugins` attribute of the client + * and can be accessed via this mean. A plugin class must have the attribute + * `pluginName` that will be use as the key in the `plugins` object. + * + * Two plugins with the same `pluginName` cannot co-exist. + * + * @example + * ```js + * class AlertPlugin { + * constructor(client, options) { + * this.client = client + * this.options = options + * this.handleLogin = this.handleLogin.bind(this) + * this.handleLogout = this.handleLogout.bind(this) + * this.client.on("login", this.handleLogin) + * this.client.on("logout", this.handleLogout) + * } + * + * handleLogin() { + * alert(this.options.onLoginAlert) + * } + * + * handleLogout() { + * alert(this.options.onLogoutAlert) + * } + * } + * + * AlertPlugin.pluginName = 'alerts' + * + * client.registerPlugin(AlertPlugin, { + * onLoginAlert: 'client has logged in !', + * onLogoutAlert: 'client has logged out !' + * }) + * + * // the instance of the plugin is accessible via + * client.plugins.alerts + * ``` + */ - function values(iterable) { - if (iterable) { - var iteratorMethod = iterable[iteratorSymbol]; - if (iteratorMethod) { - return iteratorMethod.call(iterable); + }, { + key: "registerPlugin", + value: function registerPlugin(Plugin, options) { + if (!Plugin.pluginName) { + throw new Error('Cannot register a plugin whose class does not have `pluginName` attribute.'); } - if (typeof iterable.next === "function") { - return iterable; + if (this.plugins[Plugin.pluginName]) { + throw new Error("Cannot register plugin ".concat(Plugin.pluginName, ". A plugin with the same name has already been registered.")); } - if (!isNaN(iterable.length)) { - var i = -1, next = function next() { - while (++i < iterable.length) { - if (hasOwn.call(iterable, i)) { - next.value = iterable[i]; - next.done = false; - return next; - } - } - - next.value = undefined; - next.done = true; - - return next; - }; - - return next.next = next; - } + var instance = new Plugin(this, options); + this.plugins[Plugin.pluginName] = instance; + return instance; } + /** + * To help with the transition from cozy-client-js to cozy-client, it is possible to instantiate + * a client with a cookie-based instance of cozy-client-js. + * + * @param {OldCozyClient} oldClient - An instance of the deprecated cozy-client + * @param {object} options - CozyStackClient options + * @returns {CozyClient} + */ - // Return an iterator with no values. - return { next: doneResult }; - } - exports.values = values; - - function doneResult() { - return { value: undefined, done: true }; - } - - Context.prototype = { - constructor: Context, - - reset: function(skipTempReset) { - this.prev = 0; - this.next = 0; - // Resetting context._sent for legacy support of Babel's - // function.sent implementation. - this.sent = this._sent = undefined; - this.done = false; - this.delegate = null; - - this.method = "next"; - this.arg = undefined; + }, { + key: "addSchema", + value: function addSchema(schemaDefinition) { + this.schema.add(schemaDefinition); + } + }, { + key: "registerClientOnLinks", + value: function registerClientOnLinks() { + var _iterator = _createForOfIteratorHelper(this.links), + _step; - this.tryEntries.forEach(resetTryEntry); + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var link = _step.value; - if (!skipTempReset) { - for (var name in this) { - // Not sure about the optimal order of these conditions: - if (name.charAt(0) === "t" && - hasOwn.call(this, name) && - !isNaN(+name.slice(1))) { - this[name] = undefined; + if (link.registerClient) { + try { + link.registerClient(this); + } catch (e) { + console.warn(e); + } } } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); } - }, - - stop: function() { - this.done = true; + } + /** + * Notify the links that they can start and set isLogged to true. + * + * On mobile, where url/token are set after instantiation, use this method + * to set the token and uri via options. + * + * Emits + * + * - "beforeLogin" at the beginning, before links have been set up + * - "login" when the client is fully logged in and links have been set up + * + * @param {object} [options] - Options + * @param {string} options.token - If passed, the token is set on the client + * @param {string} options.uri - If passed, the uri is set on the client + * @returns {Promise} - Resolves when all links have been setup and client is fully logged in + * + */ - var rootEntry = this.tryEntries[0]; - var rootRecord = rootEntry.completion; - if (rootRecord.type === "throw") { - throw rootRecord.arg; + }, { + key: "login", + value: function login(options) { + // Keep the promise to be able to return it in future calls. + // This allows us to autoLogin in constructor without breaking any compatibility + // with codes that uses an explicit login. + if (this.isLogged && !this.isRevoked) { + console.warn("CozyClient is already logged."); + return this.loginPromise; } - return this.rval; - }, - - dispatchException: function(exception) { - if (this.done) { - throw exception; - } + return this.loginPromise = this._login(options); + } + }, { + key: "_login", + value: function () { + var _login2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(options) { + var _iterator2, _step2, link; - var context = this; - function handle(loc, caught) { - record.type = "throw"; - record.arg = exception; - context.next = loc; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + this.emit('beforeLogin'); + this.registerClientOnLinks(); - if (caught) { - // If the dispatched exception was caught by a catch block, - // then let that catch block handle the exception normally. - context.method = "next"; - context.arg = undefined; - } + if (options) { + if (options.uri) { + this.stackClient.setUri(options.uri); + } - return !! caught; - } + if (options.token) { + this.stackClient.setToken(options.token); + } + } - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - var record = entry.completion; + _iterator2 = _createForOfIteratorHelper(this.links); + _context2.prev = 4; - if (entry.tryLoc === "root") { - // Exception thrown outside of any try block that could handle - // it, so set the completion value of the entire function to - // throw the exception. - return handle("end"); - } + _iterator2.s(); - if (entry.tryLoc <= this.prev) { - var hasCatch = hasOwn.call(entry, "catchLoc"); - var hasFinally = hasOwn.call(entry, "finallyLoc"); + case 6: + if ((_step2 = _iterator2.n()).done) { + _context2.next = 13; + break; + } - if (hasCatch && hasFinally) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } else if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } + link = _step2.value; - } else if (hasCatch) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } + if (!link.onLogin) { + _context2.next = 11; + break; + } - } else if (hasFinally) { - if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } + _context2.next = 11; + return link.onLogin(); - } else { - throw new Error("try statement without catch or finally"); - } - } - } - }, + case 11: + _context2.next = 6; + break; - abrupt: function(type, arg) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.tryLoc <= this.prev && - hasOwn.call(entry, "finallyLoc") && - this.prev < entry.finallyLoc) { - var finallyEntry = entry; - break; - } - } + case 13: + _context2.next = 18; + break; - if (finallyEntry && - (type === "break" || - type === "continue") && - finallyEntry.tryLoc <= arg && - arg <= finallyEntry.finallyLoc) { - // Ignore the finally entry if control is not jumping to a - // location outside the try/catch block. - finallyEntry = null; - } + case 15: + _context2.prev = 15; + _context2.t0 = _context2["catch"](4); - var record = finallyEntry ? finallyEntry.completion : {}; - record.type = type; - record.arg = arg; + _iterator2.e(_context2.t0); - if (finallyEntry) { - this.method = "next"; - this.next = finallyEntry.finallyLoc; - return ContinueSentinel; - } + case 18: + _context2.prev = 18; - return this.complete(record); - }, + _iterator2.f(); - complete: function(record, afterLoc) { - if (record.type === "throw") { - throw record.arg; - } + return _context2.finish(18); - if (record.type === "break" || - record.type === "continue") { - this.next = record.arg; - } else if (record.type === "return") { - this.rval = this.arg = record.arg; - this.method = "return"; - this.next = "end"; - } else if (record.type === "normal" && afterLoc) { - this.next = afterLoc; - } + case 21: + this.isLogged = true; + this.isRevoked = false; + this.emit('login'); - return ContinueSentinel; - }, + case 24: + case "end": + return _context2.stop(); + } + } + }, _callee2, this, [[4, 15, 18, 21]]); + })); - finish: function(finallyLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.finallyLoc === finallyLoc) { - this.complete(entry.completion, entry.afterLoc); - resetTryEntry(entry); - return ContinueSentinel; - } + function _login(_x2) { + return _login2.apply(this, arguments); } - }, - "catch": function(tryLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.tryLoc === tryLoc) { - var record = entry.completion; - if (record.type === "throw") { - var thrown = record.arg; - resetTryEntry(entry); - } - return thrown; - } - } + return _login; + }() + /** + * Logs out the client and reset all the links + * + * Emits + * + * - "beforeLogout" at the beginning, before links have been reset + * - "login" when the client is fully logged out and links have been reset + * + * @returns {Promise} - Resolves when all links have been reset and client is fully logged out + */ - // The context.catch method must only be called with a location - // argument that corresponds to a known catch block. - throw new Error("illegal catch attempt"); - }, + }, { + key: "logout", + value: function () { + var _logout = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { + var _iterator3, _step3, link; - delegateYield: function(iterable, resultName, nextLoc) { - this.delegate = { - iterator: values(iterable), - resultName: resultName, - nextLoc: nextLoc - }; + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (this.isLogged) { + _context3.next = 3; + break; + } - if (this.method === "next") { - // Deliberately forget the last sent value so that we don't - // accidentally pass it on to the delegate. - this.arg = undefined; - } + _logger.default.warn("CozyClient isn't logged."); - return ContinueSentinel; - } - }; + return _context3.abrupt("return"); - // Regardless of whether this script is executing as a CommonJS module - // or not, return the runtime object so that we can declare the variable - // regeneratorRuntime in the outer scope, which allows this module to be - // injected easily by `bin/regenerator --include-runtime script.js`. - return exports; + case 3: + this.emit('beforeLogout'); + this.isLogged = false; -}( - // If this script is executing as a CommonJS module, use module.exports - // as the regeneratorRuntime namespace. Otherwise create a new empty - // object. Either way, the resulting object will be used to initialize - // the regeneratorRuntime variable at the top of this file. - true ? module.exports : 0 -)); + if (!(this.stackClient instanceof _cozyStackClient.OAuthClient)) { + _context3.next = 17; + break; + } -try { - regeneratorRuntime = runtime; -} catch (accidentalStrictMode) { - // This module should not be running in strict mode, so the above - // assignment should always work unless something is misconfigured. Just - // in case runtime.js accidentally runs in strict mode, in modern engines - // we can explicitly access globalThis. In older engines we can escape - // strict mode using a global Function call. This could conceivably fail - // if a Content Security Policy forbids using Function, but in that case - // the proper solution is to fix the accidental strict mode problem. If - // you've misconfigured your bundler to force strict mode and applied a - // CSP to forbid Function, and you're not willing to fix either of those - // problems, please detail your unique predicament in a GitHub issue. - if (typeof globalThis === "object") { - globalThis.regeneratorRuntime = runtime; - } else { - Function("r", "regeneratorRuntime = r")(runtime); - } -} + _context3.prev = 6; + if (!(this.stackClient.unregister && (!this.stackClient.isRegistered || this.stackClient.isRegistered()))) { + _context3.next = 10; + break; + } -/***/ }), -/* 529 */ -/***/ ((module) => { + _context3.next = 10; + return this.stackClient.unregister(); -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { - try { - var info = gen[key](arg); - var value = info.value; - } catch (error) { - reject(error); - return; - } + case 10: + _context3.next = 15; + break; - if (info.done) { - resolve(value); - } else { - Promise.resolve(value).then(_next, _throw); - } -} + case 12: + _context3.prev = 12; + _context3.t0 = _context3["catch"](6); -function _asyncToGenerator(fn) { - return function () { - var self = this, - args = arguments; - return new Promise(function (resolve, reject) { - var gen = fn.apply(self, args); + _logger.default.warn("Impossible to unregister client on stack: ".concat(_context3.t0)); - function _next(value) { - asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); - } + case 15: + _context3.next = 25; + break; - function _throw(err) { - asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); - } + case 17: + _context3.prev = 17; + _context3.next = 20; + return this.stackClient.fetch('DELETE', '/auth/login'); - _next(undefined); - }); - }; -} + case 20: + _context3.next = 25; + break; -module.exports = _asyncToGenerator; -module.exports["default"] = module.exports, module.exports.__esModule = true; + case 22: + _context3.prev = 22; + _context3.t1 = _context3["catch"](17); -/***/ }), -/* 530 */ -/***/ ((module) => { + _logger.default.warn("Impossible to log out: ".concat(_context3.t1)); -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} + case 25: + // clean information on links + _iterator3 = _createForOfIteratorHelper(this.links); + _context3.prev = 26; -module.exports = _classCallCheck; -module.exports["default"] = module.exports, module.exports.__esModule = true; + _iterator3.s(); -/***/ }), -/* 531 */ -/***/ ((module) => { + case 28: + if ((_step3 = _iterator3.n()).done) { + _context3.next = 41; + break; + } -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); - } -} + link = _step3.value; -function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; -} + if (!link.reset) { + _context3.next = 39; + break; + } -module.exports = _createClass; -module.exports["default"] = module.exports, module.exports.__esModule = true; + _context3.prev = 31; + _context3.next = 34; + return link.reset(); -/***/ }), -/* 532 */ -/***/ ((module) => { + case 34: + _context3.next = 39; + break; -function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } + case 36: + _context3.prev = 36; + _context3.t2 = _context3["catch"](31); + console.warn(_context3.t2); - return obj; -} + case 39: + _context3.next = 28; + break; -module.exports = _defineProperty; -module.exports["default"] = module.exports, module.exports.__esModule = true; + case 41: + _context3.next = 46; + break; -/***/ }), -/* 533 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 43: + _context3.prev = 43; + _context3.t3 = _context3["catch"](26); -var baseAssignValue = __webpack_require__(534), - baseForOwn = __webpack_require__(536), - baseIteratee = __webpack_require__(401); + _iterator3.e(_context3.t3); -/** - * Creates an object with the same keys as `object` and values generated - * by running each own enumerable string keyed property of `object` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, key, object). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapKeys - * @example - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * _.mapValues(users, function(o) { return o.age; }); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - * - * // The `_.property` iteratee shorthand. - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ -function mapValues(object, iteratee) { - var result = {}; - iteratee = baseIteratee(iteratee, 3); + case 46: + _context3.prev = 46; - baseForOwn(object, function(value, key, object) { - baseAssignValue(result, key, iteratee(value, key, object)); - }); - return result; -} + _iterator3.f(); -module.exports = mapValues; + return _context3.finish(46); + case 49: + if (this.store) { + this.dispatch((0, _store.resetState)()); + } -/***/ }), -/* 534 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + this.emit('logout'); -var defineProperty = __webpack_require__(535); + case 51: + case "end": + return _context3.stop(); + } + } + }, _callee3, this, [[6, 12], [17, 22], [26, 43, 46, 49], [31, 36]]); + })); -/** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function baseAssignValue(object, key, value) { - if (key == '__proto__' && defineProperty) { - defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } -} + function logout() { + return _logout.apply(this, arguments); + } -module.exports = baseAssignValue; + return logout; + }() + /** + * Forwards to a stack client instance and returns + * a [DocumentCollection]{@link https://docs.cozy.io/en/cozy-client/api/cozy-stack-client/#DocumentCollection} instance. + * + * @param {string} doctype The collection doctype. + * @returns {DocumentCollection} Collection corresponding to the doctype + */ + }, { + key: "collection", + value: function collection(doctype) { + return this.getStackClient().collection(doctype); + } + }, { + key: "fetch", + value: function fetch(method, path, body) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + return this.getStackClient().fetch(method, path, body, options); + } + }, { + key: "all", + value: function all(doctype) { + _logger.default.warn("\nclient.all is deprecated, prefer to use the Q helper to build a new QueryDefinition.\n\nimport { Q } from 'cozy-client'\nclient.query(Q('io.cozy.bills'))"); -/***/ }), -/* 535 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return (0, _dsl.Q)(doctype); + } + }, { + key: "find", + value: function find(doctype) { + var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + console.warn('client.find(doctype, selector) is deprecated, please use Q(doctype).where(selector) to build the same query.'); + return new _dsl.QueryDefinition({ + doctype: doctype, + selector: selector + }); + } + }, { + key: "get", + value: function get(doctype, id) { + console.warn("client.get(".concat(doctype, ", id) is deprecated, please use Q(").concat(doctype, ").getById(id) to build the same query.")); + return new _dsl.QueryDefinition({ + doctype: doctype, + id: id + }); + } + /** + * Creates a document and saves it on the server + * + * @param {string} type - Doctype of the document + * @param {object} doc - Document to save + * @param {ReferenceMap} [references] - References are a special kind of relationship + * that is not stored inside the referencer document, they are used for example between a photo + * and its album. You should not need to use it normally. + * @param {object} options - Mutation options + * + * @example + * ```js + * await client.create('io.cozy.todos', { + * label: 'My todo', + * relationships: { + * authors: { + * data: [{_id: 1, _type: 'io.cozy.persons'}] + * } + * } + * }) + * ``` + * + * @returns {Promise} + */ -var getNative = __webpack_require__(371); + }, { + key: "create", + value: function () { + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(type, doc, references) { + var options, + _type, + attributes, + normalizedDoc, + ret, + _args4 = arguments; -var defineProperty = (function() { - try { - var func = getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} -}()); + return _regenerator.default.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + options = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {}; + _type = doc._type, attributes = (0, _objectWithoutProperties2.default)(doc, ["_type"]); + normalizedDoc = _objectSpread({ + _type: type + }, attributes); + _context4.next = 5; + return this.schema.validate(normalizedDoc); -module.exports = defineProperty; + case 5: + ret = _context4.sent; + if (!(ret !== true)) { + _context4.next = 8; + break; + } -/***/ }), -/* 536 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + throw new Error('Validation failed'); -var baseFor = __webpack_require__(537), - keys = __webpack_require__(429); + case 8: + return _context4.abrupt("return", this.mutate(this.getDocumentSavePlan(normalizedDoc, references), options)); -/** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ -function baseForOwn(object, iteratee) { - return object && baseFor(object, iteratee, keys); -} + case 9: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); -module.exports = baseForOwn; + function create(_x3, _x4, _x5) { + return _create.apply(this, arguments); + } + return create; + }() + }, { + key: "validate", + value: function validate(document) { + return this.schema.validate(document); + } + /** + * Create or update a document on the server + * + * @param {object} doc - Document to save + * @param {object} mutationOptions - Mutation options + * @returns {Promise} + */ -/***/ }), -/* 537 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + }, { + key: "save", + value: function () { + var _save = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(doc) { + var mutationOptions, + _type, + attributes, + normalizedDoc, + ret, + _args5 = arguments; -var createBaseFor = __webpack_require__(538); + return _regenerator.default.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + mutationOptions = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {}; + _type = doc._type, attributes = (0, _objectWithoutProperties2.default)(doc, ["_type"]); -/** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ -var baseFor = createBaseFor(); + if (_type) { + _context5.next = 4; + break; + } -module.exports = baseFor; + throw new Error('The document must have a `_type` property'); + case 4: + normalizedDoc = _objectSpread({ + _type: _type + }, attributes); + _context5.next = 7; + return this.schema.validate(normalizedDoc); -/***/ }), -/* 538 */ -/***/ ((module) => { + case 7: + ret = _context5.sent; -/** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ -function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; + if (!(ret !== true)) { + _context5.next = 10; + break; + } - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; -} + throw new Error('Validation failed'); -module.exports = createBaseFor; + case 10: + return _context5.abrupt("return", this.mutate(this.getDocumentSavePlan(normalizedDoc), mutationOptions)); + case 11: + case "end": + return _context5.stop(); + } + } + }, _callee5, this); + })); -/***/ }), -/* 539 */ -/***/ ((module) => { + function save(_x6) { + return _save.apply(this, arguments); + } -/** - * The inverse of `_.toPairs`; this method returns an object composed - * from key-value `pairs`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} pairs The key-value pairs. - * @returns {Object} Returns the new object. - * @example - * - * _.fromPairs([['a', 1], ['b', 2]]); - * // => { 'a': 1, 'b': 2 } - */ -function fromPairs(pairs) { - var index = -1, - length = pairs == null ? 0 : pairs.length, - result = {}; + return save; + }() + /** + * Saves multiple documents in one batch + * - Can only be called with documents from the same doctype + * - Does not support automatic creation of references + * + * @param {CozyClientDocument[]} docs + * @param {Object} mutationOptions + * @returns {Promise<void>} + */ - while (++index < length) { - var pair = pairs[index]; - result[pair[0]] = pair[1]; - } - return result; -} + }, { + key: "saveAll", + value: function () { + var _saveAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(docs) { + var _this2 = this; -module.exports = fromPairs; + var mutationOptions, + doctypes, + validations, + errors, + toSaveDocs, + mutation, + _args6 = arguments; + return _regenerator.default.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + mutationOptions = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {}; + doctypes = Array.from(new Set(docs.map(function (x) { + return x._type; + }))); + if (!(doctypes.length !== 1)) { + _context6.next = 4; + break; + } -/***/ }), -/* 540 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + throw new Error('saveAll can only save documents with the same doctype'); -var baseFlatten = __webpack_require__(541); + case 4: + _context6.next = 6; + return Promise.all(docs.map(function (d) { + return _this2.schema.validate(d); + })); -/** - * Flattens `array` a single level deep. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flatten([1, [2, [3, [4]], 5]]); - * // => [1, 2, [3, [4]], 5] - */ -function flatten(array) { - var length = array == null ? 0 : array.length; - return length ? baseFlatten(array, 1) : []; -} + case 6: + validations = _context6.sent; + errors = validations.filter(function (validation) { + return validation !== true; + }); -module.exports = flatten; + if (!(errors.length > 0)) { + _context6.next = 11; + break; + } + console.warn('There has been some validation errors while bulk saving', errors); + throw new Error('Validation failed for at least one doc'); -/***/ }), -/* 541 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 11: + toSaveDocs = docs.map(function (d) { + return _this2.prepareDocumentForSave(d); + }); + mutation = _dsl.Mutations.updateDocuments(toSaveDocs); + return _context6.abrupt("return", this.mutate(mutation, mutationOptions)); -var arrayPush = __webpack_require__(425), - isFlattenable = __webpack_require__(542); + case 14: + case "end": + return _context6.stop(); + } + } + }, _callee6, this); + })); -/** - * The base implementation of `_.flatten` with support for restricting flattening. - * - * @private - * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. - * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. - * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ -function baseFlatten(array, depth, predicate, isStrict, result) { - var index = -1, - length = array.length; + function saveAll(_x7) { + return _saveAll.apply(this, arguments); + } - predicate || (predicate = isFlattenable); - result || (result = []); + return saveAll; + }() + }, { + key: "ensureCozyMetadata", + value: function ensureCozyMetadata(document) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { + event: DOC_CREATION + }; + var METADATA_VERSION = 1; + if (this.appMetadata === undefined) return document; + var doctypeVersion; - while (++index < length) { - var value = array[index]; - if (depth > 0 && predicate(value)) { - if (depth > 1) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, depth - 1, predicate, isStrict, result); - } else { - arrayPush(result, value); + if (document._type) { + var schema = this.schema.getDoctypeSchema(document._type); + doctypeVersion = (0, _get.default)(schema, 'doctypeVersion'); } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; -} -module.exports = baseFlatten; + var _this$appMetadata = this.appMetadata, + slug = _this$appMetadata.slug, + sourceAccount = _this$appMetadata.sourceAccount, + version = _this$appMetadata.version; + var now = new Date().toISOString(); + var cozyMetadata = (0, _get.default)(document, 'cozyMetadata', {}); + + if (options.event === DOC_CREATION) { + cozyMetadata = _objectSpread({ + metadataVersion: METADATA_VERSION, + doctypeVersion: doctypeVersion, + createdByApp: slug, + sourceAccount: sourceAccount, + createdAt: now, + createdByAppVersion: version, + updatedAt: now, + updatedByApps: slug ? [{ + date: now, + slug: slug, + version: version + }] : [] + }, cozyMetadata); + } else if (options.event === DOC_UPDATE) { + cozyMetadata = _objectSpread(_objectSpread({}, cozyMetadata), {}, { + updatedAt: now, + updatedByApps: [{ + date: now, + slug: slug, + version: version + }].concat((0, _toConsumableArray2.default)((0, _get.default)(document, 'cozyMetadata.updatedByApps', []).filter(function (info) { + return info.slug !== slug; + }))) + }); + } + return _objectSpread(_objectSpread({}, document), {}, { + cozyMetadata: cozyMetadata + }); + } + /** + * Dehydrates and adds metadata before saving a document + * + * @param {CozyClientDocument} doc - Document that will be saved + * @returns {CozyClientDocument} + */ -/***/ }), -/* 542 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + }, { + key: "prepareDocumentForSave", + value: function prepareDocumentForSave(doc) { + var isNewDoc = !doc._rev; + var dehydratedDoc = this.ensureCozyMetadata((0, _helpers2.dehydrate)(doc), { + event: isNewDoc ? DOC_CREATION : DOC_UPDATE + }); + return dehydratedDoc; + } + /** + * Creates a list of mutations to execute to create a document and its relationships. + * + * ```js + * const baseDoc = { _type: 'io.cozy.todo', label: 'Go hiking' } + * // relations can be arrays or single objects + * const relationships = { + * attachments: [{ _id: 12345, _type: 'io.cozy.files' }, { _id: 6789, _type: 'io.cozy.files' }], + * bills: { _id: 9999, _type: 'io.cozy.bills' } + * } + * client.getDocumentSavePlan(baseDoc, relationships) + * ``` + * + * + * @param {object} document - Document to create + * @param {ReferenceMap} [referencesByName] - References to the created document. The + * relationship class associated to each reference list should support references, otherwise this + * method will throw. + * + * @returns {Mutation[]|Mutation} One or more mutation to execute + */ -var Symbol = __webpack_require__(47), - isArguments = __webpack_require__(432), - isArray = __webpack_require__(55); + }, { + key: "getDocumentSavePlan", + value: function getDocumentSavePlan(document, referencesByName) { + var _this3 = this; -/** Built-in value references. */ -var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; + var isNewDoc = !document._rev; + var docToSave = this.prepareDocumentForSave(document); + var saveMutation = isNewDoc ? _dsl.Mutations.createDocument(docToSave) : _dsl.Mutations.updateDocument(docToSave); + var hasReferences = referencesByName && Object.values(referencesByName).filter(function (references) { + return Array.isArray(references) ? references.length > 0 : references; + }).length > 0; -/** - * Checks if `value` is a flattenable `arguments` object or array. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. - */ -function isFlattenable(value) { - return isArray(value) || isArguments(value) || - !!(spreadableSymbol && value && value[spreadableSymbol]); -} + if (!hasReferences) { + return saveMutation; + } else { + for (var _i = 0, _Object$keys = Object.keys(referencesByName); _i < _Object$keys.length; _i++) { + var relName = _Object$keys[_i]; + var doctype = document._type; + var doctypeRelationship = this.schema.getRelationship(doctype, relName); + var relationshipClass = doctypeRelationship.type; -module.exports = isFlattenable; + if (!supportsReferences(relationshipClass)) { + throw referencesUnsupportedError(doctypeRelationship.name); + } + } + } + if (referencesByName && !isNewDoc) { + throw new Error('Unable to save external relationships on a not-new document'); + } -/***/ }), -/* 543 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return [saveMutation, function (response) { + var doc = _this3.hydrateDocument(response.data); -var baseRest = __webpack_require__(544), - unzip = __webpack_require__(551); + return Object.entries(referencesByName).map(function (_ref2) { + var _ref3 = (0, _slicedToArray2.default)(_ref2, 2), + relName = _ref3[0], + references = _ref3[1]; -/** - * Creates an array of grouped elements, the first of which contains the - * first elements of the given arrays, the second of which contains the - * second elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - */ -var zip = baseRest(unzip); + var relationship = doc[relName]; + return relationship.addReferences(references); + }); + }]; + } + /** + * Hooks are an observable system for events on documents. + * There are at the moment only 2 hooks available. + * + * - before:destroy, called just before a document is destroyed via CozyClient::destroy + * - after:destroy, called after a document is destroyed via CozyClient::destroy + * + * @example + * ``` + * CozyClient.registerHook('io.cozy.bank.accounts', 'before:destroy', () => { + * console.log('A io.cozy.bank.accounts is being destroyed') + * }) + * ``` + * + * @param {string} doctype - Doctype on which the hook will be registered + * @param {string} name - Name of the hook + * @param {Function} fn - Callback to be executed + */ -module.exports = zip; + }, { + key: "triggerHook", + value: function triggerHook(name, document) { + if (!CozyClient.hooks) return; + var allHooks = CozyClient.hooks[document._type] || {}; + var hooks = allHooks[name] || []; + var _iterator4 = _createForOfIteratorHelper(hooks), + _step4; -/***/ }), -/* 544 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + try { + for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { + var h = _step4.value; + h(this, document); + } + } catch (err) { + _iterator4.e(err); + } finally { + _iterator4.f(); + } + } + /** + * Destroys a document. {before,after}:destroy hooks will be fired. + * + * @param {CozyClientDocument} document - Document to be deleted + * @returns {Promise<CozyClientDocument>} The document that has been deleted + */ -var identity = __webpack_require__(459), - overRest = __webpack_require__(545), - setToString = __webpack_require__(547); + }, { + key: "destroy", + value: function () { + var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(document) { + var mutationOptions, + res, + _args7 = arguments; + return _regenerator.default.wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + mutationOptions = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {}; + _context7.next = 3; + return this.triggerHook('before:destroy', document); -/** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ -function baseRest(func, start) { - return setToString(overRest(func, start, identity), func + ''); -} + case 3: + _context7.next = 5; + return this.mutate(_dsl.Mutations.deleteDocument(document), mutationOptions); -module.exports = baseRest; + case 5: + res = _context7.sent; + _context7.next = 8; + return this.triggerHook('after:destroy', document); + case 8: + return _context7.abrupt("return", res); -/***/ }), -/* 545 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 9: + case "end": + return _context7.stop(); + } + } + }, _callee7, this); + })); -var apply = __webpack_require__(546); + function destroy(_x8) { + return _destroy.apply(this, arguments); + } -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMax = Math.max; + return destroy; + }() + }, { + key: "upload", + value: function upload(file, dirPath) { + var mutationOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return this.mutate(_dsl.Mutations.uploadFile(file, dirPath), mutationOptions); + } + /** + * Makes sure that the query exists in the store + * + * @param {string} queryId - Id of the query + * @param {QueryDefinition} queryDefinition - Definition of the query + * @param {QueryOptions} [options] - Additional options + */ -/** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ -function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); + }, { + key: "ensureQueryExists", + value: function ensureQueryExists(queryId, queryDefinition, options) { + this.ensureStore(); + var existingQuery = (0, _store.getQueryFromState)(this.store.getState(), queryId); // Don't trigger the INIT_QUERY for fetchMore() calls - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; + if (existingQuery.fetchStatus !== 'loaded' || !queryDefinition.skip && !queryDefinition.bookmark) { + this.dispatch((0, _store.initQuery)(queryId, queryDefinition, options)); + } } - otherArgs[start] = transform(array); - return apply(func, this, otherArgs); - }; -} + /** + * Executes a query and returns its results. + * + * Results from the query will be saved internally and can be retrieved via + * `getQueryFromState` or directly using `<Query />`. `<Query />` automatically + * executes its query when mounted if no fetch policy has been indicated. + * + * @param {QueryDefinition} queryDefinition - Definition that will be executed + * @param {QueryOptions} [options] - Options + * @returns {Promise<QueryResult>} + */ -module.exports = overRest; + }, { + key: "query", + value: function () { + var _query = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(queryDefinition) { + var _this4 = this; + var _ref4, + update, + options, + queryId, + existingQuery, + shouldFetch, + response, + _args8 = arguments; -/***/ }), -/* 546 */ -/***/ ((module) => { + return _regenerator.default.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + _ref4 = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {}; + update = _ref4.update, options = (0, _objectWithoutProperties2.default)(_ref4, ["update"]); + this.ensureStore(); + queryId = options.as || this.queryIdGenerator.generateId(queryDefinition); + existingQuery = this.getQueryFromState(queryId); -/** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ -function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); -} + if (!options.fetchPolicy) { + _context8.next = 11; + break; + } -module.exports = apply; + if (options.as) { + _context8.next = 8; + break; + } + throw new Error('Cannot use `fetchPolicy` without naming the query, please use `as` to name the query'); -/***/ }), -/* 547 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 8: + shouldFetch = options.fetchPolicy(existingQuery); -var baseSetToString = __webpack_require__(548), - shortOut = __webpack_require__(550); + if (shouldFetch) { + _context8.next = 11; + break; + } -/** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var setToString = shortOut(baseSetToString); + return _context8.abrupt("return"); -module.exports = setToString; + case 11: + if (!(existingQuery && Object.keys(existingQuery).length > 0)) { + _context8.next = 14; + break; + } + if (!(existingQuery.fetchStatus === 'loading')) { + _context8.next = 14; + break; + } -/***/ }), -/* 548 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return _context8.abrupt("return", this._promiseCache.get(function () { + return (0, _jsonStableStringify.default)(queryDefinition); + })); -var constant = __webpack_require__(549), - defineProperty = __webpack_require__(535), - identity = __webpack_require__(459); + case 14: + this.ensureQueryExists(queryId, queryDefinition, options); + _context8.prev = 15; + this.dispatch((0, _store.loadQuery)(queryId)); + _context8.next = 19; + return this._promiseCache.exec(function () { + return _this4.requestQuery(queryDefinition); + }, function () { + return (0, _jsonStableStringify.default)(queryDefinition); + }); -/** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var baseSetToString = !defineProperty ? identity : function(func, string) { - return defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(string), - 'writable': true - }); -}; + case 19: + response = _context8.sent; + this.dispatch((0, _store.receiveQueryResult)(queryId, response, { + update: update + })); + return _context8.abrupt("return", response); -module.exports = baseSetToString; + case 24: + _context8.prev = 24; + _context8.t0 = _context8["catch"](15); + this.dispatch((0, _store.receiveQueryError)(queryId, _context8.t0)); // specific onError + if (!options.onError) { + _context8.next = 31; + break; + } -/***/ }), -/* 549 */ -/***/ ((module) => { + options.onError(_context8.t0); // defaulted onError -/** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new constant function. - * @example - * - * var objects = _.times(2, _.constant({ 'a': 1 })); - * - * console.log(objects); - * // => [{ 'a': 1 }, { 'a': 1 }] - * - * console.log(objects[0] === objects[1]); - * // => true - */ -function constant(value) { - return function() { - return value; - }; -} + _context8.next = 36; + break; -module.exports = constant; + case 31: + if (!this.options.onError) { + _context8.next = 35; + break; + } + this.options.onError(_context8.t0); + _context8.next = 36; + break; -/***/ }), -/* 550 */ -/***/ ((module) => { + case 35: + throw _context8.t0; -/** Used to detect hot functions by number of calls within a span of milliseconds. */ -var HOT_COUNT = 800, - HOT_SPAN = 16; + case 36: + case "end": + return _context8.stop(); + } + } + }, _callee8, this, [[15, 24]]); + })); -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeNow = Date.now; + function query(_x9) { + return _query.apply(this, arguments); + } -/** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ -function shortOut(func) { - var count = 0, - lastCalled = 0; + return query; + }() + /** + * Will fetch all documents for a `queryDefinition`, automatically fetching more + * documents if the total of documents is superior to the pagination limit. Can + * result in a lot of network requests. + * + * @param {QueryDefinition} queryDefinition - Definition to be executed + * @param {QueryOptions} [options] - Options + * @returns {Promise<QueryResult>} All documents matching the query + */ - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); + }, { + key: "queryAll", + value: function () { + var _queryAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(queryDefinition) { + var options, + queryId, + mergedOptions, + resp, + documents, + currentResult, + _args9 = arguments; + return _regenerator.default.wrap(function _callee9$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + options = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : {}; + queryId = options.as || this.queryIdGenerator.generateId(queryDefinition); + mergedOptions = _objectSpread(_objectSpread({}, options), {}, { + as: queryId + }); + _context9.next = 5; + return this.query(queryDefinition, mergedOptions); - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; -} + case 5: + resp = _context9.sent; + documents = resp.data; -module.exports = shortOut; + case 7: + if (!(resp && resp.next)) { + _context9.next = 21; + break; + } + if (!resp.bookmark) { + _context9.next = 14; + break; + } -/***/ }), -/* 551 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + _context9.next = 11; + return this.query(queryDefinition.offsetBookmark(resp.bookmark), mergedOptions); -var arrayFilter = __webpack_require__(427), - arrayMap = __webpack_require__(398), - baseProperty = __webpack_require__(461), - baseTimes = __webpack_require__(431), - isArrayLikeObject = __webpack_require__(552); + case 11: + resp = _context9.sent; + _context9.next = 18; + break; -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMax = Math.max; + case 14: + currentResult = (0, _store.getRawQueryFromState)(this.store.getState(), queryId); + _context9.next = 17; + return this.query(queryDefinition.offset(currentResult.data.length), mergedOptions); -/** - * This method is like `_.zip` except that it accepts an array of grouped - * elements and creates an array regrouping the elements to their pre-zip - * configuration. - * - * @static - * @memberOf _ - * @since 1.2.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - * - * _.unzip(zipped); - * // => [['a', 'b'], [1, 2], [true, false]] - */ -function unzip(array) { - if (!(array && array.length)) { - return []; - } - var length = 0; - array = arrayFilter(array, function(group) { - if (isArrayLikeObject(group)) { - length = nativeMax(group.length, length); - return true; - } - }); - return baseTimes(length, function(index) { - return arrayMap(array, baseProperty(index)); - }); -} + case 17: + resp = _context9.sent; -module.exports = unzip; + case 18: + documents.push.apply(documents, (0, _toConsumableArray2.default)(resp.data)); + _context9.next = 7; + break; + case 21: + return _context9.abrupt("return", documents); -/***/ }), -/* 552 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 22: + case "end": + return _context9.stop(); + } + } + }, _callee9, this); + })); -var isArrayLike = __webpack_require__(446), - isObjectLike = __webpack_require__(53); + function queryAll(_x10) { + return _queryAll.apply(this, arguments); + } -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); -} + return queryAll; + }() + }, { + key: "watchQuery", + value: function watchQuery() { + console.warn('client.watchQuery is deprecated, please use client.makeObservableQuery.'); + return this.makeObservableQuery.apply(this, arguments); + } + }, { + key: "makeObservableQuery", + value: function makeObservableQuery(queryDefinition) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + this.ensureStore(); + var queryId = options.as || this.queryIdGenerator.generateId(queryDefinition); + this.ensureQueryExists(queryId, queryDefinition); + return new _ObservableQuery.default(queryId, queryDefinition, this, options); + } + /** + * Mutate a document + * + * @param {object} mutationDefinition - Describe the mutation + * @param {object} [options] - Options + * @param {string} [options.as] - Mutation id + * @param {Function} [options.update] - Function to update the document + * @param {Function} [options.updateQueries] - Function to update queries + * @returns {Promise} + */ -module.exports = isArrayLikeObject; + }, { + key: "mutate", + value: function () { + var _mutate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(mutationDefinition) { + var _ref5, + update, + updateQueries, + options, + mutationId, + response, + _args10 = arguments; + return _regenerator.default.wrap(function _callee10$(_context10) { + while (1) { + switch (_context10.prev = _context10.next) { + case 0: + _ref5 = _args10.length > 1 && _args10[1] !== undefined ? _args10[1] : {}; + update = _ref5.update, updateQueries = _ref5.updateQueries, options = (0, _objectWithoutProperties2.default)(_ref5, ["update", "updateQueries"]); + this.ensureStore(); + mutationId = options.as || this.queryIdGenerator.generateId(mutationDefinition); + this.dispatch((0, _store.initMutation)(mutationId, mutationDefinition)); + _context10.prev = 5; + _context10.next = 8; + return this.requestMutation(mutationDefinition); -/***/ }), -/* 553 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 8: + response = _context10.sent; + this.dispatch((0, _store.receiveMutationResult)(mutationId, response, { + update: update, + updateQueries: updateQueries + }, mutationDefinition)); + return _context10.abrupt("return", response); -var arrayEach = __webpack_require__(554), - baseEach = __webpack_require__(555), - castFunction = __webpack_require__(557), - isArray = __webpack_require__(55); + case 13: + _context10.prev = 13; + _context10.t0 = _context10["catch"](5); + this.dispatch((0, _store.receiveMutationError)(mutationId, _context10.t0, mutationDefinition)); + throw _context10.t0; -/** - * Iterates over elements of `collection` and invokes `iteratee` for each element. - * The iteratee is invoked with three arguments: (value, index|key, collection). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * **Note:** As with other "Collections" methods, objects with a "length" - * property are iterated like arrays. To avoid this behavior use `_.forIn` - * or `_.forOwn` for object iteration. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias each - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEachRight - * @example - * - * _.forEach([1, 2], function(value) { - * console.log(value); - * }); - * // => Logs `1` then `2`. - * - * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ -function forEach(collection, iteratee) { - var func = isArray(collection) ? arrayEach : baseEach; - return func(collection, castFunction(iteratee)); -} + case 17: + case "end": + return _context10.stop(); + } + } + }, _callee10, this, [[5, 13]]); + })); -module.exports = forEach; + function mutate(_x11) { + return _mutate.apply(this, arguments); + } + return mutate; + }() + /** + * Executes a query through links and fetches relationships + * + * @private + * @param {QueryDefinition} definition QueryDefinition to be executed + * @returns {Promise<ClientResponse>} + */ -/***/ }), -/* 554 */ -/***/ ((module) => { + }, { + key: "requestQuery", + value: function () { + var _requestQuery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(definition) { + var mainResponse, withIncluded; + return _regenerator.default.wrap(function _callee11$(_context11) { + while (1) { + switch (_context11.prev = _context11.next) { + case 0: + _context11.next = 2; + return this.chain.request(definition); -/** - * A specialized version of `_.forEach` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ -function arrayEach(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length; + case 2: + mainResponse = _context11.sent; - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; -} + if (definition.includes) { + _context11.next = 5; + break; + } -module.exports = arrayEach; + return _context11.abrupt("return", mainResponse); + case 5: + _context11.next = 7; + return this.fetchRelationships(mainResponse, this.getIncludesRelationships(definition)); -/***/ }), -/* 555 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 7: + withIncluded = _context11.sent; + return _context11.abrupt("return", withIncluded); -var baseForOwn = __webpack_require__(536), - createBaseEach = __webpack_require__(556); + case 9: + case "end": + return _context11.stop(); + } + } + }, _callee11, this); + })); -/** - * The base implementation of `_.forEach` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ -var baseEach = createBaseEach(baseForOwn); + function requestQuery(_x12) { + return _requestQuery.apply(this, arguments); + } -module.exports = baseEach; + return requestQuery; + }() + /** + * Fetch relationships for a response (can be several docs). + * Fills the `relationships` attribute of each documents. + * + * Can potentially result in several fetch requests. + * Queries are optimized before being sent (multiple single documents queries can be packed into + * one multiple document query) for example. + * + * @private + */ + }, { + key: "fetchRelationships", + value: function () { + var _fetchRelationships = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(response, relationshipsByName) { + var _this5 = this; -/***/ }), -/* 556 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var isSingleDoc, responseDocs, queryDefToDocIdAndRel, documents, definitions, optimizedDefinitions, responses, uniqueDocuments, included, relationshipsByDocId, _iterator5, _step5, _step5$value, def, resp, docIdAndRel, _docIdAndRel, docId, relName; -var isArrayLike = __webpack_require__(446); + return _regenerator.default.wrap(function _callee12$(_context12) { + while (1) { + switch (_context12.prev = _context12.next) { + case 0: + isSingleDoc = !Array.isArray(response.data); -/** - * Creates a `baseEach` or `baseEachRight` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ -function createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - if (collection == null) { - return collection; - } - if (!isArrayLike(collection)) { - return eachFunc(collection, iteratee); - } - var length = collection.length, - index = fromRight ? length : -1, - iterable = Object(collection); + if (!(!isSingleDoc && response.data.length === 0)) { + _context12.next = 3; + break; + } - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; -} + return _context12.abrupt("return", response); -module.exports = createBaseEach; + case 3: + responseDocs = isSingleDoc ? [response.data] : response.data; + queryDefToDocIdAndRel = new Map(); + documents = []; + definitions = []; + responseDocs.forEach(function (doc) { + return (0, _forEach.default)(relationshipsByName, function (relationship, relName) { + try { + var queryDef = relationship.type.query(doc, _this5, relationship); + var docId = doc._id; // Used to reattach responses into the relationships attribute of + // each document + queryDefToDocIdAndRel.set(queryDef, [docId, relName]); // Relationships can yield "queries" that are already resolved documents. + // These do not need to go through the usual link request mechanism. -/***/ }), -/* 557 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (queryDef instanceof _dsl.QueryDefinition) { + definitions.push(queryDef); + } else { + documents.push(queryDef); + } + } catch (_unused) {// eslint-disable-next-line + // We do not crash completely if one the relationship behaves badly and + // throws + } + }); + }); // Definitions can be in optimized/regrouped in case of HasMany relationships. -var identity = __webpack_require__(459); + optimizedDefinitions = (0, _optimize.default)(definitions); + _context12.next = 11; + return Promise.all(optimizedDefinitions.map(function (req) { + return _this5.chain.request(req); + })); -/** - * Casts `value` to `identity` if it's not a function. - * - * @private - * @param {*} value The value to inspect. - * @returns {Function} Returns cast function. - */ -function castFunction(value) { - return typeof value == 'function' ? value : identity; -} + case 11: + responses = _context12.sent; + // "Included" documents will be stored in the `documents` store + uniqueDocuments = (0, _uniqBy.default)((0, _flatten.default)(documents), '_id'); + included = (0, _flatten.default)(responses.map(function (r) { + return r.included || r.data; + })).concat(uniqueDocuments).filter(Boolean); // Some relationships have the relationship data on the other side of the + // relationship (ex: io.cozy.photos.albums do not have photo inclusion information, + // it is on the io.cozy.files side). + // Here we take the data received from the relationship queries, and group + // it so that we can fill the `relationships` attribute of each doc before + // storing the document. This makes the data easier to manipulate for the front-end. -module.exports = castFunction; + relationshipsByDocId = {}; + _iterator5 = _createForOfIteratorHelper((0, _zip.default)(optimizedDefinitions, responses)); + try { + for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { + _step5$value = (0, _slicedToArray2.default)(_step5.value, 2), def = _step5$value[0], resp = _step5$value[1]; + docIdAndRel = queryDefToDocIdAndRel.get(def); -/***/ }), -/* 558 */ -/***/ ((module) => { + if (docIdAndRel) { + _docIdAndRel = (0, _slicedToArray2.default)(docIdAndRel, 2), docId = _docIdAndRel[0], relName = _docIdAndRel[1]; + relationshipsByDocId[docId] = relationshipsByDocId[docId] || {}; + relationshipsByDocId[docId][relName] = (0, _helpers.responseToRelationship)(resp); + } + } + } catch (err) { + _iterator5.e(err); + } finally { + _iterator5.f(); + } -function M() { this._events = {}; } -M.prototype = { - on: function(ev, cb) { - this._events || (this._events = {}); - var e = this._events; - (e[ev] || (e[ev] = [])).push(cb); - return this; - }, - removeListener: function(ev, cb) { - var e = this._events[ev] || [], i; - for(i = e.length-1; i >= 0 && e[i]; i--){ - if(e[i] === cb || e[i].cb === cb) { e.splice(i, 1); } - } - }, - removeAllListeners: function(ev) { - if(!ev) { this._events = {}; } - else { this._events[ev] && (this._events[ev] = []); } - }, - listeners: function(ev) { - return (this._events ? this._events[ev] || [] : []); - }, - emit: function(ev) { - this._events || (this._events = {}); - var args = Array.prototype.slice.call(arguments, 1), i, e = this._events[ev] || []; - for(i = e.length-1; i >= 0 && e[i]; i--){ - e[i].apply(this, args); - } - return this; - }, - when: function(ev, cb) { - return this.once(ev, cb, true); - }, - once: function(ev, cb, when) { - if(!cb) return this; - function c() { - if(!when) this.removeListener(ev, c); - if(cb.apply(this, arguments) && when) this.removeListener(ev, c); - } - c.cb = cb; - this.on(ev, c); - return this; - } -}; -M.mixin = function(dest) { - var o = M.prototype, k; - for (k in o) { - o.hasOwnProperty(k) && (dest.prototype[k] = o[k]); - } -}; -module.exports = M; + return _context12.abrupt("return", _objectSpread(_objectSpread({}, (0, _helpers.attachRelationships)(response, relationshipsByDocId)), {}, { + included: included + })); + case 18: + case "end": + return _context12.stop(); + } + } + }, _callee12); + })); -/***/ }), -/* 559 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + function fetchRelationships(_x13, _x14) { + return _fetchRelationships.apply(this, arguments); + } -"use strict"; + return fetchRelationships; + }() + }, { + key: "requestMutation", + value: function () { + var _requestMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(definition) { + var _this6 = this; + var _definition, first, rest, firstResponse; -var _interopRequireWildcard = __webpack_require__(510); + return _regenerator.default.wrap(function _callee13$(_context13) { + while (1) { + switch (_context13.prev = _context13.next) { + case 0: + if (!Array.isArray(definition)) { + _context13.next = 8; + break; + } -var _interopRequireDefault = __webpack_require__(512); + _definition = (0, _toArray2.default)(definition), first = _definition[0], rest = _definition.slice(1); + _context13.next = 4; + return this.requestMutation(first); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -Object.defineProperty(exports, "default", ({ - enumerable: true, - get: function get() { - return _CozyStackClient.default; - } -})); -Object.defineProperty(exports, "OAuthClient", ({ - enumerable: true, - get: function get() { - return _OAuthClient.default; - } -})); -Object.defineProperty(exports, "errors", ({ - enumerable: true, - get: function get() { - return _errors.default; - } -})); -Object.defineProperty(exports, "FetchError", ({ - enumerable: true, - get: function get() { - return _errors.FetchError; - } -})); -Object.defineProperty(exports, "normalizeDoc", ({ - enumerable: true, - get: function get() { - return _DocumentCollection.normalizeDoc; - } -})); + case 4: + firstResponse = _context13.sent; + _context13.next = 7; + return Promise.all(rest.map(function (def) { + var mutationDef = typeof def === 'function' ? def(firstResponse) : def; + return _this6.requestMutation(mutationDef); + })); -var _CozyStackClient = _interopRequireDefault(__webpack_require__(560)); + case 7: + return _context13.abrupt("return", firstResponse); -var _OAuthClient = _interopRequireDefault(__webpack_require__(684)); + case 8: + return _context13.abrupt("return", this.chain.request(definition)); -var _errors = _interopRequireWildcard(__webpack_require__(651)); + case 9: + case "end": + return _context13.stop(); + } + } + }, _callee13, this); + })); -var _DocumentCollection = __webpack_require__(601); + function requestMutation(_x15) { + return _requestMutation.apply(this, arguments); + } -/***/ }), -/* 560 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + return requestMutation; + }() + }, { + key: "getIncludesRelationships", + value: function getIncludesRelationships(queryDefinition) { + var _this7 = this; -"use strict"; + var includes = queryDefinition.includes, + doctype = queryDefinition.doctype; + if (!includes) return {}; + return (0, _fromPairs.default)(includes.map(function (relName) { + return [relName, _this7.schema.getRelationship(doctype, relName)]; + })); + } + /** + * Returns documents with their relationships resolved according to their schema. + * If related documents are not in the store, they will not be fetched automatically. + * Instead, the relationships will have null documents. + * + * @param {string} doctype - Doctype of the documents being hydrated + * @param {Array<CozyClientDocument>} documents - Documents to be hydrated + * @returns {Array<HydratedDocument>} + */ + + }, { + key: "hydrateDocuments", + value: function hydrateDocuments(doctype, documents) { + var _this8 = this; + + if (this.options.autoHydrate === false) { + return documents; + } + var schema = this.schema.getDoctypeSchema(doctype); + var relationships = schema.relationships; -var _interopRequireWildcard = __webpack_require__(510); + if (relationships) { + return documents.map(function (doc) { + return _this8.hydrateDocument(doc, schema); + }); + } else { + return documents; + } + } + /** + * Resolves relationships on a document. + * + * The original document is kept in the target attribute of + * the relationship + * + * @param {CozyClientDocument} document - for which relationships must be resolved + * @param {Schema} [schemaArg] - Optional + * @returns {HydratedDocument} + */ -var _interopRequireDefault = __webpack_require__(512); + }, { + key: "hydrateDocument", + value: function hydrateDocument(document, schemaArg) { + if (!document) { + return document; + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + var schema = schemaArg || this.schema.getDoctypeSchema(document._type); + return _objectSpread(_objectSpread({}, document), this.hydrateRelationships(document, schema.relationships)); + } + }, { + key: "hydrateRelationships", + value: function hydrateRelationships(document, schemaRelationships) { + var methods = this.getRelationshipStoreAccessors(); + return (0, _mapValues.default)(schemaRelationships, function (assoc, name) { + return (0, _associations.create)(document, assoc, methods); + }); + } + /** + * Creates (locally) a new document for the given doctype. + * This document is hydrated : its relationships are there + * and working. + */ -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + }, { + key: "makeNewDocument", + value: function makeNewDocument(doctype) { + var obj = { + _type: doctype + }; + return this.hydrateDocument(obj); + } + }, { + key: "generateRandomId", + value: function generateRandomId() { + return this.queryIdGenerator.generateRandomId(); + } + /** + * Creates an association that is linked to the store. + */ -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); + }, { + key: "getAssociation", + value: function getAssociation(document, associationName) { + return (0, _associations.create)(document, this.schema.getRelationship(document._type, associationName), this.getRelationshipStoreAccessors()); + } + /** + * Returns the accessors that are given to the relationships for them + * to deal with the stores. + * + * Relationships need to have access to the store to ping it when + * a modification (addById/removeById etc...) has been done. This wakes + * the store up, which in turn will update the `<Query>`s and re-render the data. + */ -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); + }, { + key: "getRelationshipStoreAccessors", + value: function getRelationshipStoreAccessors() { + var _this9 = this; -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + if (!this.storeAccesors) { + this.storeAccessors = { + get: this.getDocumentFromState.bind(this), + save: function save(document, opts) { + return _this9.save.call(_this9, document, opts); + }, + dispatch: this.dispatch.bind(this), + query: function query(def, opts) { + return _this9.query.call(_this9, def, opts); + }, + mutate: function mutate(def, opts) { + return _this9.mutate.call(_this9, def, opts); + } + }; + } -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + return this.storeAccessors; + } + /** + * Get a collection of documents from the internal store. + * + * @param {string} type - Doctype of the collection + * + * @returns {CozyClientDocument[]} Array of documents or null if the collection does not exist. + */ -var _cloneDeep = _interopRequireDefault(__webpack_require__(561)); + }, { + key: "getCollectionFromState", + value: function getCollectionFromState(type) { + try { + return (0, _store.getCollectionFromState)(this.store.getState(), type); + } catch (e) { + _logger.default.warn('Could not getCollectionFromState', type, e.message); -var _AppCollection = _interopRequireWildcard(__webpack_require__(590)); + return null; + } + } + /** + * Get a document from the internal store. + * + * @param {string} type - Doctype of the document + * @param {string} id - Id of the document + * + * @returns {CozyClientDocument} Document or null if the object does not exist. + */ -var _AppToken = _interopRequireDefault(__webpack_require__(656)); + }, { + key: "getDocumentFromState", + value: function getDocumentFromState(type, id) { + try { + return (0, _store.getDocumentFromState)(this.store.getState(), type, id); + } catch (e) { + _logger.default.warn('Could not getDocumentFromState', type, id, e.message); -var _AccessToken = _interopRequireDefault(__webpack_require__(657)); + return null; + } + } + /** + * Get a query from the internal store. + * + * @param {string} id - Id of the query (set via Query.props.as) + * @param {object} options - Options + * @param {boolean} [options.hydrated] - Whether documents should be returned already hydrated (default: false) + * @param {object} [options.singleDocData] - If true, the "data" returned will be + * a single doc instead of an array for single doc queries. Defaults to false for backward + * compatibility but will be set to true in the future. + * + * @returns {QueryState} - Query state or null if it does not exist. + */ -var _DocumentCollection = _interopRequireDefault(__webpack_require__(601)); + }, { + key: "getQueryFromState", + value: function getQueryFromState(id) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var hydrated = options.hydrated || false; + var singleDocData = options.singleDocData || false; -var _FileCollection = _interopRequireDefault(__webpack_require__(658)); + try { + var queryResults = (0, _store.getQueryFromState)(this.store.getState(), id); + var doctype = queryResults.definition && queryResults.definition.doctype; + var isSingleDocQuery = queryResults.definition && queryResults.definition.id; -var _JobCollection = _interopRequireWildcard(__webpack_require__(667)); + if (!hydrated && !singleDocData) { + // Early return let's us preserve reference equality in the simple case + return queryResults; + } -var _KonnectorCollection = _interopRequireWildcard(__webpack_require__(668)); + var data = hydrated && doctype ? this.hydrateDocuments(doctype, queryResults.data) : queryResults.data; + return _objectSpread(_objectSpread({}, queryResults), {}, { + data: isSingleDocQuery && singleDocData ? data[0] : data + }); + } catch (e) { + console.warn("Could not get query from state. queryId: ".concat(id, ", error: ").concat(e.message)); + return null; + } + } + /** + * Executes a query and returns the results from internal store. + * + * Can be useful in pure JS context (without React) + * Has a behavior close to <Query /> or useQuery + * + * @param {object} query - Query with definition and options + * @returns {Promise<QueryState>} Query state + */ -var _SharingCollection = _interopRequireDefault(__webpack_require__(672)); + }, { + key: "register", -var _PermissionCollection = _interopRequireDefault(__webpack_require__(673)); + /** + * Performs a complete OAuth flow using a Cordova webview + * or React Native WebView for auth. + * The `register` method's name has been chosen for compat reasons with the Authentication compo. + * + * @param {string} cozyURL Receives the URL of the cozy instance. + * @returns {object} Contains the fetched token and the client information. + */ + value: function register(cozyURL) { + var stackClient = this.getStackClient(); + stackClient.setUri(cozyURL); + return this.startOAuthFlow(_mobile.authFunction); + } + }, { + key: "isReactNative", + value: function isReactNative() { + return typeof navigator != 'undefined' && navigator.product == 'ReactNative'; + } + /** + * Performs a complete OAuth flow, including updating the internal token at the end. + * + * @param {OpenURLCallback} openURLCallback Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions. + * @returns {Promise<object>} Contains the fetched token and the client information. These should be stored and used to restore the client. + */ -var _TriggerCollection = _interopRequireWildcard(__webpack_require__(669)); + }, { + key: "startOAuthFlow", + value: function () { + var _startOAuthFlow = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(openURLCallback) { + var stackClient; + return _regenerator.default.wrap(function _callee14$(_context14) { + while (1) { + switch (_context14.prev = _context14.next) { + case 0: + stackClient = this.getStackClient(); + _context14.next = 3; + return stackClient.register(); -var _SettingsCollection = _interopRequireWildcard(__webpack_require__(674)); + case 3: + _context14.next = 5; + return this.certifyFlagship(); -var _NotesCollection = _interopRequireWildcard(__webpack_require__(675)); + case 5: + return _context14.abrupt("return", this.authorize({ + openURLCallback: openURLCallback + })); -var _OAuthClientsCollection = _interopRequireWildcard(__webpack_require__(677)); + case 6: + case "end": + return _context14.stop(); + } + } + }, _callee14, this); + })); -var _ShortcutsCollection = _interopRequireWildcard(__webpack_require__(678)); + function startOAuthFlow(_x16) { + return _startOAuthFlow.apply(this, arguments); + } -var _ContactsCollection = _interopRequireWildcard(__webpack_require__(679)); + return startOAuthFlow; + }() + /** + * Perform the Flagship certification process for verifying that the current running app is a genuine Cozy application + * + * This mechanism is described in https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/flagship-certification/README.md + */ -var _getIconURL2 = _interopRequireDefault(__webpack_require__(680)); + }, { + key: "certifyFlagship", + value: function () { + var _certifyFlagship2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15() { + var stackClient; + return _regenerator.default.wrap(function _callee15$(_context15) { + while (1) { + switch (_context15.prev = _context15.next) { + case 0: + stackClient = this.getStackClient(); -var _logDeprecate = _interopRequireDefault(__webpack_require__(682)); + if (!stackClient.oauthOptions.shouldRequireFlagshipPermissions) { + _context15.next = 4; + break; + } -var _errors = _interopRequireWildcard(__webpack_require__(651)); + _context15.next = 4; + return (0, _flagshipCertification.certifyFlagship)(stackClient.oauthOptions.certificationConfig, this); -var _xhrFetch = __webpack_require__(683); + case 4: + case "end": + return _context15.stop(); + } + } + }, _callee15, this); + })); -var _microee = _interopRequireDefault(__webpack_require__(558)); + function certifyFlagship() { + return _certifyFlagship2.apply(this, arguments); + } -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + return certifyFlagship; + }() + /** + * Creates an OAuth token with needed permissions for the current client. + * The authorization page URL generation can be overriding by passing a function pointer as `openURLCallback` parameter + * It is possible to skip the session creation process (when using an in-app browser) by passing a sessionCode (see https://docs.cozy.io/en/cozy-stack/auth/#post-authsession_code) + * + * @param {object} [options] - Authorization options + * @param {OpenURLCallback} [options.openURLCallback] - Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions. + * @param {SessionCode} [options.sessionCode] - session code than can be added to the authorization URL to automatically create the session. + * @param {PKCECodes} [options.pkceCodes] - code verifier and a code challenge that should be used in the PKCE verification process. + * @returns {Promise<object>} Contains the fetched token and the client information. These should be stored and used to restore the client. + */ -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + }, { + key: "authorize", + value: function () { + var _authorize = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16() { + var _ref6, + _ref6$openURLCallback, + openURLCallback, + _ref6$sessionCode, + sessionCode, + _ref6$pkceCodes, + pkceCodes, + codeVerifier, + codeChallenge, + stackClient, + stateCode, + url, + redirectedURL, + code, + token, + _stackClient, + _args16 = arguments; -var normalizeUri = function normalizeUri(uriArg) { - var uri = uriArg; - if (uri === null) return null; + return _regenerator.default.wrap(function _callee16$(_context16) { + while (1) { + switch (_context16.prev = _context16.next) { + case 0: + _ref6 = _args16.length > 0 && _args16[0] !== undefined ? _args16[0] : {}, _ref6$openURLCallback = _ref6.openURLCallback, openURLCallback = _ref6$openURLCallback === void 0 ? _mobile.authFunction : _ref6$openURLCallback, _ref6$sessionCode = _ref6.sessionCode, sessionCode = _ref6$sessionCode === void 0 ? undefined : _ref6$sessionCode, _ref6$pkceCodes = _ref6.pkceCodes, pkceCodes = _ref6$pkceCodes === void 0 ? {} : _ref6$pkceCodes; + _context16.prev = 1; + codeVerifier = pkceCodes.codeVerifier, codeChallenge = pkceCodes.codeChallenge; + stackClient = this.getStackClient(); + stateCode = stackClient.generateStateCode(); + url = stackClient.getAuthCodeURL({ + stateCode: stateCode, + scopes: undefined, + sessionCode: sessionCode, + codeChallenge: codeChallenge + }); + _context16.next = 8; + return openURLCallback(url); - while (uri[uri.length - 1] === '/') { - uri = uri.slice(0, -1); - } + case 8: + redirectedURL = _context16.sent; + code = stackClient.getAccessCodeFromURL(redirectedURL, stateCode); + _context16.next = 12; + return stackClient.fetchAccessToken(code, undefined, undefined, codeVerifier); - return uri; -}; + case 12: + token = _context16.sent; + stackClient.setToken(token); + return _context16.abrupt("return", { + token: token, + infos: stackClient.oauthOptions, + client: stackClient.oauthOptions // for compat with Authentication comp reasons -var isRevocationError = function isRevocationError(err) { - return err.message && _errors.default.CLIENT_NOT_FOUND.test(err.message); -}; -/** - * Main API against the `cozy-stack` server. - */ + }); + case 17: + _context16.prev = 17; + _context16.t0 = _context16["catch"](1); -var CozyStackClient = /*#__PURE__*/function () { - function CozyStackClient(options) { - (0, _classCallCheck2.default)(this, CozyStackClient); + /* if REGISTRATION_ABORT is emited, we have to unregister the client. */ + if (_context16.t0.message === _const.REGISTRATION_ABORT) { + _stackClient = this.getStackClient(); - var opts = _objectSpread({}, options); + _stackClient.unregister(); + } - var token = opts.token, - _opts$uri = opts.uri, - uri = _opts$uri === void 0 ? '' : _opts$uri; - this.options = opts; - this.setUri(uri); - this.setToken(token); - this.konnectors = new _KonnectorCollection.default(this); - this.jobs = new _JobCollection.default(this); - } - /** - * Creates a {@link DocumentCollection} instance. - * - * @param {string} doctype The collection doctype. - * @returns {DocumentCollection} - */ + throw _context16.t0; + case 21: + case "end": + return _context16.stop(); + } + } + }, _callee16, this, [[1, 17]]); + })); - (0, _createClass2.default)(CozyStackClient, [{ - key: "collection", - value: function collection(doctype) { - if (!doctype) { - throw new Error('CozyStackClient.collection() called without a doctype'); + function authorize() { + return _authorize.apply(this, arguments); } - switch (doctype) { - case _AppCollection.APPS_DOCTYPE: - return new _AppCollection.default(this); - - case _KonnectorCollection.KONNECTORS_DOCTYPE: - return new _KonnectorCollection.default(this); + return authorize; + }() + /** + * Renews the token if, for instance, new permissions are required or token + * has expired. + * + * @returns {object} Contains the fetched token and the client information. + */ - case 'io.cozy.files': - return new _FileCollection.default(doctype, this); + }, { + key: "renewAuthorization", + value: function renewAuthorization() { + return this.authorize({ + openURLCallback: _mobile.authFunction + }); + } + /** + * Sets the internal store of the client. Use this when you want to have cozy-client's + * internal store colocated with your existing Redux store. + * + * Typically, you would need to do this only once in your application, this is why + * setStore throws if you do it twice. If you really need to set the store again, + * use options.force = true. + * + * @example + * ``` + * const client = new CozyClient() + * const store = createStore(combineReducers({ + * todos: todoReducer, + * cozy: client.reducer() + * }) + * client.setStore(store) + * ``` + * + * @param {ReduxStore} store - A redux store + * @param {object} [options] - Options + * @param {boolean} [options.force] - Will deactivate throwing when client's store already exists + */ - case 'io.cozy.sharings': - return new _SharingCollection.default(doctype, this); + }, { + key: "setStore", + value: function setStore(store) { + var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref7$force = _ref7.force, + force = _ref7$force === void 0 ? false : _ref7$force; - case 'io.cozy.permissions': - return new _PermissionCollection.default(doctype, this); + if (store === undefined) { + throw new Error('Store is undefined'); + } else if (this.store && !force) { + throw new Error("Client already has a store, it is forbidden to change store.\nsetStore must be called before any query is executed. Try to\ncall setStore earlier in your code, preferably just after the\ninstantiation of the client."); + } - case _ContactsCollection.CONTACTS_DOCTYPE: - return new _ContactsCollection.default(doctype, this); + this.store = store; + } + }, { + key: "ensureStore", + value: function ensureStore() { + if (!this.store) { + this.setStore((0, _store.createStore)()); + } + } + /** + * Returns whether the client has been revoked on the server + */ - case _TriggerCollection.TRIGGERS_DOCTYPE: - return new _TriggerCollection.default(this); + }, { + key: "checkForRevocation", + value: function () { + var _checkForRevocation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17() { + return _regenerator.default.wrap(function _callee17$(_context17) { + while (1) { + switch (_context17.prev = _context17.next) { + case 0: + return _context17.abrupt("return", this.stackClient.checkForRevocation()); - case _JobCollection.JOBS_DOCTYPE: - return new _JobCollection.default(this); + case 1: + case "end": + return _context17.stop(); + } + } + }, _callee17, this); + })); - case _SettingsCollection.SETTINGS_DOCTYPE: - return new _SettingsCollection.default(this); + function checkForRevocation() { + return _checkForRevocation.apply(this, arguments); + } - case _NotesCollection.NOTES_DOCTYPE: - return new _NotesCollection.default(this); + return checkForRevocation; + }() + /** Sets public attribute and emits event related to revocation */ - case _OAuthClientsCollection.OAUTH_CLIENTS_DOCTYPE: - return new _OAuthClientsCollection.default(this); + }, { + key: "handleRevocationChange", + value: function handleRevocationChange(state) { + if (state) { + this.isRevoked = true; + this.emit('revoked'); + } else { + this.isRevoked = false; + this.emit('unrevoked'); + } + } + /** Emits event when token is refreshed */ - case _ShortcutsCollection.SHORTCUTS_DOCTYPE: - return new _ShortcutsCollection.default(this); + }, { + key: "handleTokenRefresh", + value: function handleTokenRefresh(token) { + this.emit('tokenRefreshed'); - default: - return new _DocumentCollection.default(doctype, this); + if (this.options.onTokenRefresh) { + deprecatedHandler("Using onTokenRefresh is deprecated, please use events like this: cozyClient.on('tokenRefreshed', token => console.log('Token has been refreshed', token)). https://git.io/fj3M3"); + this.options.onTokenRefresh(token); } } /** - * Fetches an endpoint in an authorized way. + * If no stack client has been passed in options, creates a default stack + * client and attaches handlers for revocation and token refresh. + * If a stackClient has been passed in options, ensure it has handlers for + * revocation and token refresh. * - * @param {string} method The HTTP method. - * @param {string} path The URI. - * @param {object} [body] The payload. - * @param {object} [opts={}] Options for fetch - * @returns {object} - * @throws {FetchError} + * If `oauth` options are passed, stackClient is an OAuthStackClient. */ }, { - key: "fetch", - value: function (_fetch) { - function fetch(_x, _x2, _x3) { - return _fetch.apply(this, arguments); + key: "createClient", + value: function createClient() { + if (this.options.client) { + console.warn('CozyClient: Using options.client is deprecated, please use options.stackClient.'); } - fetch.toString = function () { - return _fetch.toString(); + var warningForCustomHandlers = this.options.warningForCustomHandlers !== undefined ? this.options.warningForCustomHandlers : true; + var stackClient = this.options.client || this.options.stackClient; + var handlers = { + onRevocationChange: this.handleRevocationChange, + onTokenRefresh: this.handleTokenRefresh }; - return fetch; - }( /*#__PURE__*/function () { - var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(method, path, body) { - var opts, - options, - headers, - fullPath, - fetcher, - response, - _args = arguments; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - opts = _args.length > 3 && _args[3] !== undefined ? _args[3] : {}; - options = _objectSpread({}, opts); - options.method = method; - headers = options.headers = _objectSpread({}, opts.headers); + if (stackClient) { + this.stackClient = stackClient; - if (method !== 'GET' && method !== 'HEAD' && body !== undefined) { - if (headers['Content-Type']) { - options.body = body; - } - } + if (!stackClient.options) { + stackClient.options = {}; + } - if (!headers.Authorization) { - headers.Authorization = this.getAuthorizationHeader(); - } // the option credentials:include tells fetch to include the cookies in the - // request even for cross-origin requests + for (var _i2 = 0, _Object$keys2 = Object.keys(handlers); _i2 < _Object$keys2.length; _i2++) { + var handlerName = _Object$keys2[_i2]; + if (!stackClient.options[handlerName]) { + stackClient.options[handlerName] = handlers[handlerName]; + } else { + if (warningForCustomHandlers) { + console.warn("You passed a stackClient with its own ".concat(handlerName, ". It is not supported, unexpected things might happen.")); + } + } + } + } else { + var options = _objectSpread(_objectSpread({}, this.options), handlers); - options.credentials = 'include'; - fullPath = this.fullpath(path); - fetcher = (0, _xhrFetch.shouldXMLHTTPRequestBeUsed)(method, path, options) ? _xhrFetch.fetchWithXMLHttpRequest : fetch; - _context.prev = 9; - _context.next = 12; - return fetcher(fullPath, options); + this.stackClient = this.options.oauth ? new _cozyStackClient.OAuthClient(options) : new _cozyStackClient.default(options); + } - case 12: - response = _context.sent; + this.client = new Proxy(this.stackClient, deprecatedHandler('Using cozyClient.client is deprecated, please use cozyClient.stackClient.')); + } + }, { + key: "getClient", + value: function getClient() { + console.warn('CozyClient: getClient() is deprecated, please use getStackClient().'); + return this.getStackClient(); + } + }, { + key: "getStackClient", + value: function getStackClient() { + if (!this.stackClient) { + this.createClient(); + } - if (!response.ok) { - this.emit('error', new _errors.FetchError(response, "".concat(response.status, " ").concat(response.statusText))); - } + return this.stackClient; + } + }, { + key: "reducer", + value: function reducer() { + return _store.default; + } + }, { + key: "dispatch", + value: function dispatch(action) { + return this.store.dispatch(action); + } + /** + * getInstanceOptions - Returns current instance options, such as domain or app slug + * + * @returns {object} + */ - return _context.abrupt("return", response); + }, { + key: "getInstanceOptions", + value: function getInstanceOptions() { + return this.instanceOptions; + } + /** + * loadInstanceOptionsFromDOM - Loads the dataset injected by the Stack in web pages and exposes it through getInstanceOptions + * + * @param {string} [selector=[role=application]] A selector for the node that holds the dataset to load + * + * @returns {void} + */ - case 17: - _context.prev = 17; - _context.t0 = _context["catch"](9); + }, { + key: "loadInstanceOptionsFromDOM", + value: function loadInstanceOptionsFromDOM() { + var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '[role=application]'; + var root = document.querySelector(selector); - if (isRevocationError(_context.t0)) { - this.onRevocationChange(true); - } + if (!(root instanceof HTMLElement)) { + throw new Error('The selector that is passed does not return an HTMLElement'); + } - throw _context.t0; + var _root$dataset = root.dataset, + _root$dataset$cozy = _root$dataset.cozy, + cozy = _root$dataset$cozy === void 0 ? '{}' : _root$dataset$cozy, + dataset = (0, _objectWithoutProperties2.default)(_root$dataset, ["cozy"]); + this.instanceOptions = _objectSpread(_objectSpread({}, JSON.parse(cozy)), dataset); + this.capabilities = this.instanceOptions.capabilities || null; + } + /** + * Directly set the data in the store, without using a query + * This is useful for cases like Pouch replication, which wants to + * set some data in the store. + * + * @param {object} data - Data that is inserted in the store. Shape: { doctype: [data] } + */ - case 21: - case "end": - return _context.stop(); - } - } - }, _callee, this, [[9, 17]]); - })); + }, { + key: "setData", + value: function setData(data) { + var _this10 = this; + + this.ensureStore(); + Object.entries(data).forEach(function (_ref8) { + var _ref9 = (0, _slicedToArray2.default)(_ref8, 2), + doctype = _ref9[0], + data = _ref9[1]; + + _this10.dispatch((0, _store.receiveQueryResult)(null, { + data: data + })); + }); + } + /** + * At any time put an error function + * + * @param {Function} [onError] - Set a callback for queries which are errored + * @throws {Error} onError should not have been defined yet + */ - return function (_x4, _x5, _x6) { - return _ref.apply(this, arguments); - }; - }()) }, { - key: "onTokenRefresh", - value: function onTokenRefresh(token) { - if (this.options && this.options.onTokenRefresh) { - this.options.onTokenRefresh(token); + key: "setOnError", + value: function setOnError(onError) { + if (this.options && this.options.onError) { + throw new Error('On Error is already defined'); } + + this.options.onError = onError; } }, { - key: "onRevocationChange", - value: function onRevocationChange(state) { - if (this.options && this.options.onRevocationChange) { - this.options.onRevocationChange(state); - } + key: "toJSON", + value: function toJSON() { + return new _snapshots.CozyClient({ + uri: this.options.uri + }); + } + }], [{ + key: "fromOldClient", + value: function fromOldClient(oldClient, options) { + return new CozyClient(_objectSpread({ + uri: oldClient._url, + token: oldClient._token.token + }, options)); } /** - * Returns whether the client has been revoked on the server + * To help with the transition from cozy-client-js to cozy-client, it is possible to instantiate + * a client with an OAuth-based instance of cozy-client-js. + * + * Warning: unlike other instantiators, this one needs to be awaited. + * + * @param {OldCozyClient} oldClient - An OAuth instance of the deprecated cozy-client + * @param {object} options - CozyStackClient options + * @returns {Promise<CozyClient>} An instance of a client, configured from the old client */ }, { - key: "checkForRevocation", + key: "fromOldOAuthClient", value: function () { - var _checkForRevocation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { - return _regenerator.default.wrap(function _callee2$(_context2) { + var _fromOldOAuthClient = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(oldClient, options) { + var credentials, oauthOptions; + return _regenerator.default.wrap(function _callee18$(_context18) { while (1) { - switch (_context2.prev = _context2.next) { + switch (_context18.prev = _context18.next) { case 0: - _context2.prev = 0; - _context2.next = 3; - return this.fetchInformation(); + if (!oldClient._oauth) { + _context18.next = 8; + break; + } + + _context18.next = 3; + return oldClient.authorize(); case 3: - return _context2.abrupt("return", false); + credentials = _context18.sent; + oauthOptions = { + oauth: credentials.client, + token: credentials.token, + scope: credentials.token.scope + }; + return _context18.abrupt("return", new CozyClient(_objectSpread(_objectSpread({ + uri: oldClient._url + }, oauthOptions), options))); - case 6: - _context2.prev = 6; - _context2.t0 = _context2["catch"](0); - return _context2.abrupt("return", isRevocationError(_context2.t0)); + case 8: + throw new Error('Cannot instantiate a new client: old client is not an OAuth client. CozyClient.fromOldClient might be more suitable.'); case 9: case "end": - return _context2.stop(); + return _context18.stop(); } } - }, _callee2, this, [[0, 6]]); + }, _callee18); })); - function checkForRevocation() { - return _checkForRevocation.apply(this, arguments); + function fromOldOAuthClient(_x17, _x18) { + return _fromOldOAuthClient.apply(this, arguments); } - return checkForRevocation; + return fromOldOAuthClient; }() /** - * Retrieves a new app token by refreshing the currently used token. + * In konnector/service context, CozyClient can be instantiated from + * environment variables * - * @throws {Error} The client should already have an access token to use this function - * @throws {Error} The client couldn't fetch a new token - * @returns {Promise} A promise that resolves with a new AccessToken object + * @param {NodeEnvironment} [envArg] - The environment + * @param {object} options - Options + * @returns {CozyClient} */ }, { - key: "refreshToken", - value: function () { - var _refreshToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { - var options, response, html, parser, doc, appNode, data, token, newToken; - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - if (this.token) { - _context3.next = 2; - break; - } + key: "fromEnv", + value: function fromEnv(envArg) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var env = envArg || (typeof process !== 'undefined' ? process.env : {}); + var COZY_URL = env.COZY_URL, + COZY_CREDENTIALS = env.COZY_CREDENTIALS, + NODE_ENV = env.NODE_ENV; - throw new Error('Cannot refresh an empty token'); + if (!COZY_URL || !COZY_CREDENTIALS) { + throw new Error('Env used to instantiate CozyClient must have COZY_URL and COZY_CREDENTIALS'); + } - case 2: - options = { - method: 'GET', - credentials: 'include' - }; + if (NODE_ENV === 'development') { + options.oauth = JSON.parse(COZY_CREDENTIALS); + } else { + options.token = COZY_CREDENTIALS.trim(); + } - if (global.document) { - _context3.next = 5; - break; - } + options.uri = COZY_URL.trim(); + return new CozyClient(_objectSpread({}, options)); + } + /** + * When used from an app, CozyClient can be instantiated from the data injected by the stack in + * the DOM. + * + * @param {object} options - CozyClient constructor options + * @param {string} selector - Options + * @returns {CozyClient} - CozyClient instance + */ - throw new Error('Not in a web context, cannot refresh token'); + }, { + key: "fromDOM", + value: function fromDOM() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '[role=application]'; + var root = document.querySelector(selector); - case 5: - _context3.next = 7; - return fetch('/?refreshToken', options); + if (!(root instanceof HTMLElement)) { + throw new Error("Cannot find an HTMLElement corresponding to ".concat(selector)); + } - case 7: - response = _context3.sent; + if (!root || !root.dataset) { + throw new Error("Found no data in ".concat(selector, " to instantiate cozyClient")); + } - if (response.ok) { - _context3.next = 10; - break; - } + var data = root.dataset.cozy ? JSON.parse(root.dataset.cozy) : _objectSpread({}, root.dataset); + var domain = data.domain, + token = data.token; - throw new Error("couldn't fetch a new token - response " + response.statusCode); + if (!domain || !token) { + domain = domain || data.cozyDomain; + token = token || data.cozyToken; + } - case 10: - _context3.next = 12; - return response.text(); + if (!domain || !token) { + throw new Error("Found no data in ".concat(root.dataset, " to instantiate cozyClient")); + } - case 12: - html = _context3.sent; - parser = new DOMParser(); - doc = parser.parseFromString(html, 'text/html'); + return new CozyClient(_objectSpread({ + uri: "".concat(window.location.protocol, "//").concat(domain), + token: token, + capabilities: data.capabilities + }, options)); + } + }, { + key: "registerHook", + value: function registerHook(doctype, name, fn) { + var hooks = CozyClient.hooks[doctype] = CozyClient.hooks[doctype] || {}; + hooks[name] = hooks[name] || []; + hooks[name].push(fn); + } + }]); + return CozyClient; +}(); - if (doc) { - _context3.next = 17; - break; - } +CozyClient.hooks = CozyClient.hooks || {}; +CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config - throw Error("couldn't fetch a new token - doc is not html"); +CozyClient.version = "29.2.0"; - case 17: - appNode = doc.querySelector('div[role="application"]'); +_microee.default.mixin(CozyClient); - if (appNode) { - _context3.next = 20; - break; - } +var _default = CozyClient; +exports["default"] = _default; - throw Error("couldn't fetch a new token - no div[role=application]"); +/***/ }), +/* 526 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 20: - data = appNode.dataset.cozy ? JSON.parse(appNode.dataset.cozy) : _objectSpread({}, appNode.dataset); - token = data.token; +var arrayWithHoles = __webpack_require__(527); - if (token) { - token = token || data.cozyToken; - } +var iterableToArray = __webpack_require__(528); - if (token) { - _context3.next = 25; - break; - } +var unsupportedIterableToArray = __webpack_require__(529); - throw Error("couldn't fetch a new token -- missing data-cozy or data-cozy-token attribute"); +var nonIterableRest = __webpack_require__(531); - case 25: - newToken = new _AppToken.default(token); - this.onTokenRefresh(newToken); - return _context3.abrupt("return", newToken); +function _toArray(arr) { + return arrayWithHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableRest(); +} - case 28: - case "end": - return _context3.stop(); - } - } - }, _callee3, this); - })); +module.exports = _toArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; - function refreshToken() { - return _refreshToken.apply(this, arguments); - } +/***/ }), +/* 527 */ +/***/ ((module) => { - return refreshToken; - }() - /** - * Fetches JSON in an authorized way. - * - * @param {string} method The HTTP method. - * @param {string} path The URI. - * @param {object} body The payload. - * @param {object} options Options - * @returns {object} - * @throws {FetchError} - */ +function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; +} - }, { - key: "fetchJSON", - value: function () { - var _fetchJSON = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(method, path, body) { - var options, - token, - _args4 = arguments; - return _regenerator.default.wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - options = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {}; - _context4.prev = 1; - _context4.next = 4; - return this.fetchJSONWithCurrentToken(method, path, body, options); +module.exports = _arrayWithHoles; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), +/* 528 */ +/***/ ((module) => { + +function _iterableToArray(iter) { + if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); +} + +module.exports = _iterableToArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), +/* 529 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var arrayLikeToArray = __webpack_require__(530); + +function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen); +} + +module.exports = _unsupportedIterableToArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), +/* 530 */ +/***/ ((module) => { + +function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) { + arr2[i] = arr[i]; + } + + return arr2; +} + +module.exports = _arrayLikeToArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), +/* 531 */ +/***/ ((module) => { + +function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} + +module.exports = _nonIterableRest; +module.exports["default"] = module.exports, module.exports.__esModule = true; - case 4: - return _context4.abrupt("return", _context4.sent); +/***/ }), +/* 532 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 7: - _context4.prev = 7; - _context4.t0 = _context4["catch"](1); +var arrayWithHoles = __webpack_require__(527); - if (!(_errors.default.EXPIRED_TOKEN.test(_context4.t0.message) || _errors.default.INVALID_TOKEN.test(_context4.t0.message))) { - _context4.next = 25; - break; - } +var iterableToArrayLimit = __webpack_require__(533); - _context4.prev = 10; - _context4.next = 13; - return this.refreshToken(); +var unsupportedIterableToArray = __webpack_require__(529); - case 13: - token = _context4.sent; - _context4.next = 19; - break; +var nonIterableRest = __webpack_require__(531); - case 16: - _context4.prev = 16; - _context4.t1 = _context4["catch"](10); - throw _context4.t0; +function _slicedToArray(arr, i) { + return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest(); +} - case 19: - this.setToken(token); - _context4.next = 22; - return this.fetchJSONWithCurrentToken(method, path, body, options); +module.exports = _slicedToArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; - case 22: - return _context4.abrupt("return", _context4.sent); +/***/ }), +/* 533 */ +/***/ ((module) => { - case 25: - throw _context4.t0; +function _iterableToArrayLimit(arr, i) { + var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; - case 26: - case "end": - return _context4.stop(); - } - } - }, _callee4, this, [[1, 7], [10, 16]]); - })); + if (_i == null) return; + var _arr = []; + var _n = true; + var _d = false; - function fetchJSON(_x7, _x8, _x9) { - return _fetchJSON.apply(this, arguments); - } + var _s, _e; - return fetchJSON; - }() - }, { - key: "fetchJSONWithCurrentToken", - value: function () { - var _fetchJSONWithCurrentToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(method, path, bodyArg) { - var options, - clonedOptions, - headers, - body, - resp, - contentType, - isJson, - data, - _args5 = arguments; - return _regenerator.default.wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - options = _args5.length > 3 && _args5[3] !== undefined ? _args5[3] : {}; - //Since we modify the object later by adding in some case a - //content-type, let's clone this object to scope the modification - clonedOptions = (0, _cloneDeep.default)(options); - headers = clonedOptions.headers = clonedOptions.headers || {}; - headers['Accept'] = 'application/json'; - body = bodyArg; + try { + for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); - if (method !== 'GET' && method !== 'HEAD' && body !== undefined) { - if (!headers['Content-Type']) { - headers['Content-Type'] = 'application/json'; - body = JSON.stringify(body); - } - } + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } - _context5.next = 8; - return this.fetch(method, path, body, clonedOptions); + return _arr; +} - case 8: - resp = _context5.sent; - contentType = resp.headers.get('content-type'); - isJson = contentType && contentType.indexOf('json') >= 0; - _context5.next = 13; - return isJson ? resp.json() : resp.text(); +module.exports = _iterableToArrayLimit; +module.exports["default"] = module.exports, module.exports.__esModule = true; - case 13: - data = _context5.sent; +/***/ }), +/* 534 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!resp.ok) { - _context5.next = 16; - break; - } +var arrayWithoutHoles = __webpack_require__(535); - return _context5.abrupt("return", data); +var iterableToArray = __webpack_require__(528); - case 16: - throw new _errors.FetchError(resp, data); +var unsupportedIterableToArray = __webpack_require__(529); - case 17: - case "end": - return _context5.stop(); - } - } - }, _callee5, this); - })); +var nonIterableSpread = __webpack_require__(536); - function fetchJSONWithCurrentToken(_x10, _x11, _x12) { - return _fetchJSONWithCurrentToken.apply(this, arguments); - } +function _toConsumableArray(arr) { + return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread(); +} - return fetchJSONWithCurrentToken; - }() - }, { - key: "fullpath", - value: function fullpath(path) { - if (path.startsWith('http')) { - return path; - } else { - return this.uri + path; - } - } - }, { - key: "getAuthorizationHeader", - value: function getAuthorizationHeader() { - return this.token ? this.token.toAuthHeader() : null; - } - }, { - key: "setCredentials", - value: function setCredentials(token) { - (0, _logDeprecate.default)('CozyStackClient::setCredentials is deprecated, use CozyStackClient::setToken'); - return this.setToken(token); - } - }, { - key: "getCredentials", - value: function getCredentials() { - (0, _logDeprecate.default)('CozyStackClient::getCredentials is deprecated, use CozyStackClient::getAuthorizationHeader'); - return this.getAuthorizationHeader(); - } - /** - * Change or set the API token - * - * @param {string|AppToken|AccessToken} token - Stack API token - */ +module.exports = _toConsumableArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; - }, { - key: "setToken", - value: function setToken(token) { - if (!token) { - this.token = null; - } else { - if (token.toAuthHeader) { - // AppToken or AccessToken - this.token = token; - } else if (typeof token === 'string') { - // jwt string - this.token = new _AppToken.default(token); - } else { - console.warn('Cozy-Client: Unknown token format', token); - throw new Error('Cozy-Client: Unknown token format'); - } +/***/ }), +/* 535 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.onRevocationChange(false); - } - } - /** - * Get the access token string, being an oauth token or an app token - * - * @returns {string} token - */ +var arrayLikeToArray = __webpack_require__(530); - }, { - key: "getAccessToken", - value: function getAccessToken() { - return this.token && this.token.getAccessToken(); - } - }, { - key: "setUri", - value: function setUri(uri) { - this.uri = normalizeUri(uri); - } - }, { - key: "getIconURL", - value: function getIconURL(opts) { - return (0, _getIconURL2.default)(this, opts); - } - }]); - return CozyStackClient; -}(); +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) return arrayLikeToArray(arr); +} -_microee.default.mixin(CozyStackClient); +module.exports = _arrayWithoutHoles; +module.exports["default"] = module.exports, module.exports.__esModule = true; -var _default = CozyStackClient; -exports["default"] = _default; +/***/ }), +/* 536 */ +/***/ ((module) => { + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} + +module.exports = _nonIterableSpread; +module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), -/* 561 */ +/* 537 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseClone = __webpack_require__(562); +var objectWithoutPropertiesLoose = __webpack_require__(538); -/** Used to compose bitmasks for cloning. */ -var CLONE_DEEP_FLAG = 1, - CLONE_SYMBOLS_FLAG = 4; +function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + var target = objectWithoutPropertiesLoose(source, excluded); + var key, i; -/** - * This method is like `_.clone` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @returns {*} Returns the deep cloned value. - * @see _.clone - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var deep = _.cloneDeep(objects); - * console.log(deep[0] === objects[0]); - * // => false - */ -function cloneDeep(value) { - return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); -} + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); -module.exports = cloneDeep; + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; +} +module.exports = _objectWithoutProperties; +module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), -/* 562 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 538 */ +/***/ ((module) => { -var Stack = __webpack_require__(404), - arrayEach = __webpack_require__(554), - assignValue = __webpack_require__(563), - baseAssign = __webpack_require__(564), - baseAssignIn = __webpack_require__(566), - cloneBuffer = __webpack_require__(570), - copyArray = __webpack_require__(571), - copySymbols = __webpack_require__(572), - copySymbolsIn = __webpack_require__(573), - getAllKeys = __webpack_require__(423), - getAllKeysIn = __webpack_require__(576), - getTag = __webpack_require__(447), - initCloneArray = __webpack_require__(577), - initCloneByTag = __webpack_require__(578), - initCloneObject = __webpack_require__(584), - isArray = __webpack_require__(55), - isBuffer = __webpack_require__(434), - isMap = __webpack_require__(586), - isObject = __webpack_require__(52), - isSet = __webpack_require__(588), - keys = __webpack_require__(429), - keysIn = __webpack_require__(567); +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; -/** Used to compose bitmasks for cloning. */ -var CLONE_DEEP_FLAG = 1, - CLONE_FLAT_FLAG = 2, - CLONE_SYMBOLS_FLAG = 4; + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]', - weakMapTag = '[object WeakMap]'; + return target; +} -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; +module.exports = _objectWithoutPropertiesLoose; +module.exports["default"] = module.exports, module.exports.__esModule = true; -/** Used to identify `toStringTag` values supported by `_.clone`. */ -var cloneableTags = {}; -cloneableTags[argsTag] = cloneableTags[arrayTag] = -cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = -cloneableTags[boolTag] = cloneableTags[dateTag] = -cloneableTags[float32Tag] = cloneableTags[float64Tag] = -cloneableTags[int8Tag] = cloneableTags[int16Tag] = -cloneableTags[int32Tag] = cloneableTags[mapTag] = -cloneableTags[numberTag] = cloneableTags[objectTag] = -cloneableTags[regexpTag] = cloneableTags[setTag] = -cloneableTags[stringTag] = cloneableTags[symbolTag] = -cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = -cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; -cloneableTags[errorTag] = cloneableTags[funcTag] = -cloneableTags[weakMapTag] = false; +/***/ }), +/* 539 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +module.exports = __webpack_require__(540); + + +/***/ }), +/* 540 */ +/***/ ((module) => { /** - * The base implementation of `_.clone` and `_.cloneDeep` which tracks - * traversed objects. + * Copyright (c) 2014-present, Facebook, Inc. * - * @private - * @param {*} value The value to clone. - * @param {boolean} bitmask The bitmask flags. - * 1 - Deep clone - * 2 - Flatten inherited properties - * 4 - Clone symbols - * @param {Function} [customizer] The function to customize cloning. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The parent object of `value`. - * @param {Object} [stack] Tracks traversed objects and their clone counterparts. - * @returns {*} Returns the cloned value. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ -function baseClone(value, bitmask, customizer, key, object, stack) { - var result, - isDeep = bitmask & CLONE_DEEP_FLAG, - isFlat = bitmask & CLONE_FLAT_FLAG, - isFull = bitmask & CLONE_SYMBOLS_FLAG; - if (customizer) { - result = object ? customizer(value, key, object, stack) : customizer(value); +var runtime = (function (exports) { + "use strict"; + + var Op = Object.prototype; + var hasOwn = Op.hasOwnProperty; + var undefined; // More compressible than void 0. + var $Symbol = typeof Symbol === "function" ? Symbol : {}; + var iteratorSymbol = $Symbol.iterator || "@@iterator"; + var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; + var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; + + function define(obj, key, value) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + return obj[key]; } - if (result !== undefined) { - return result; + try { + // IE 8 has a broken Object.defineProperty that only works on DOM objects. + define({}, ""); + } catch (err) { + define = function(obj, key, value) { + return obj[key] = value; + }; } - if (!isObject(value)) { - return value; + + function wrap(innerFn, outerFn, self, tryLocsList) { + // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. + var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; + var generator = Object.create(protoGenerator.prototype); + var context = new Context(tryLocsList || []); + + // The ._invoke method unifies the implementations of the .next, + // .throw, and .return methods. + generator._invoke = makeInvokeMethod(innerFn, self, context); + + return generator; } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return copyArray(value, result); - } - } else { - var tag = getTag(value), - isFunc = tag == funcTag || tag == genTag; + exports.wrap = wrap; - if (isBuffer(value)) { - return cloneBuffer(value, isDeep); - } - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - result = (isFlat || isFunc) ? {} : initCloneObject(value); - if (!isDeep) { - return isFlat - ? copySymbolsIn(value, baseAssignIn(result, value)) - : copySymbols(value, baseAssign(result, value)); - } - } else { - if (!cloneableTags[tag]) { - return object ? value : {}; - } - result = initCloneByTag(value, tag, isDeep); + // Try/catch helper to minimize deoptimizations. Returns a completion + // record like context.tryEntries[i].completion. This interface could + // have been (and was previously) designed to take a closure to be + // invoked without arguments, but in all the cases we care about we + // already have an existing method we want to call, so there's no need + // to create a new function object. We can even get away with assuming + // the method takes exactly one argument, since that happens to be true + // in every case, so we don't have to touch the arguments object. The + // only additional allocation required is the completion record, which + // has a stable shape and so hopefully should be cheap to allocate. + function tryCatch(fn, obj, arg) { + try { + return { type: "normal", arg: fn.call(obj, arg) }; + } catch (err) { + return { type: "throw", arg: err }; } } - // Check for circular references and return its corresponding clone. - stack || (stack = new Stack); - var stacked = stack.get(value); - if (stacked) { - return stacked; + + var GenStateSuspendedStart = "suspendedStart"; + var GenStateSuspendedYield = "suspendedYield"; + var GenStateExecuting = "executing"; + var GenStateCompleted = "completed"; + + // Returning this object from the innerFn has the same effect as + // breaking out of the dispatch switch statement. + var ContinueSentinel = {}; + + // Dummy constructor functions that we use as the .constructor and + // .constructor.prototype properties for functions that return Generator + // objects. For full spec compliance, you may wish to configure your + // minifier not to mangle the names of these two functions. + function Generator() {} + function GeneratorFunction() {} + function GeneratorFunctionPrototype() {} + + // This is a polyfill for %IteratorPrototype% for environments that + // don't natively support it. + var IteratorPrototype = {}; + define(IteratorPrototype, iteratorSymbol, function () { + return this; + }); + + var getProto = Object.getPrototypeOf; + var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); + if (NativeIteratorPrototype && + NativeIteratorPrototype !== Op && + hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { + // This environment has a native %IteratorPrototype%; use it instead + // of the polyfill. + IteratorPrototype = NativeIteratorPrototype; } - stack.set(value, result); - if (isSet(value)) { - value.forEach(function(subValue) { - result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); - }); - } else if (isMap(value)) { - value.forEach(function(subValue, key) { - result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + var Gp = GeneratorFunctionPrototype.prototype = + Generator.prototype = Object.create(IteratorPrototype); + GeneratorFunction.prototype = GeneratorFunctionPrototype; + define(Gp, "constructor", GeneratorFunctionPrototype); + define(GeneratorFunctionPrototype, "constructor", GeneratorFunction); + GeneratorFunction.displayName = define( + GeneratorFunctionPrototype, + toStringTagSymbol, + "GeneratorFunction" + ); + + // Helper for defining the .next, .throw, and .return methods of the + // Iterator interface in terms of a single ._invoke method. + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function(method) { + define(prototype, method, function(arg) { + return this._invoke(method, arg); + }); }); } - var keysFunc = isFull - ? (isFlat ? getAllKeysIn : getAllKeys) - : (isFlat ? keysIn : keys); + exports.isGeneratorFunction = function(genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor + ? ctor === GeneratorFunction || + // For the native GeneratorFunction constructor, the best we can + // do is to check its .name property. + (ctor.displayName || ctor.name) === "GeneratorFunction" + : false; + }; - var props = isArr ? undefined : keysFunc(value); - arrayEach(props || value, function(subValue, key) { - if (props) { - key = subValue; - subValue = value[key]; + exports.mark = function(genFun) { + if (Object.setPrototypeOf) { + Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); + } else { + genFun.__proto__ = GeneratorFunctionPrototype; + define(genFun, toStringTagSymbol, "GeneratorFunction"); } - // Recursively populate clone (susceptible to call stack limits). - assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); - }); - return result; -} + genFun.prototype = Object.create(Gp); + return genFun; + }; -module.exports = baseClone; + // Within the body of any async function, `await x` is transformed to + // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test + // `hasOwn.call(value, "__await")` to determine if the yielded value is + // meant to be awaited. + exports.awrap = function(arg) { + return { __await: arg }; + }; + function AsyncIterator(generator, PromiseImpl) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); + if (record.type === "throw") { + reject(record.arg); + } else { + var result = record.arg; + var value = result.value; + if (value && + typeof value === "object" && + hasOwn.call(value, "__await")) { + return PromiseImpl.resolve(value.__await).then(function(value) { + invoke("next", value, resolve, reject); + }, function(err) { + invoke("throw", err, resolve, reject); + }); + } -/***/ }), -/* 563 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return PromiseImpl.resolve(value).then(function(unwrapped) { + // When a yielded Promise is resolved, its final value becomes + // the .value of the Promise<{value,done}> result for the + // current iteration. + result.value = unwrapped; + resolve(result); + }, function(error) { + // If a rejected Promise was yielded, throw the rejection back + // into the async generator function so it can be handled there. + return invoke("throw", error, resolve, reject); + }); + } + } -var baseAssignValue = __webpack_require__(534), - eq = __webpack_require__(385); + var previousPromise; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + function enqueue(method, arg) { + function callInvokeWithMethodAndArg() { + return new PromiseImpl(function(resolve, reject) { + invoke(method, arg, resolve, reject); + }); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + return previousPromise = + // If enqueue has been called before, then we want to wait until + // all previous Promises have been resolved before calling invoke, + // so that results are always delivered in the correct order. If + // enqueue has not been called before, then it is important to + // call invoke immediately, without waiting on a callback to fire, + // so that the async generator function has the opportunity to do + // any necessary setup in a predictable way. This predictability + // is why the Promise constructor synchronously invokes its + // executor callback, and why async functions synchronously + // execute code before the first await. Since we implement simple + // async functions in terms of async generators, it is especially + // important to get this right, even though it requires care. + previousPromise ? previousPromise.then( + callInvokeWithMethodAndArg, + // Avoid propagating failures to Promises returned by later + // invocations of the iterator. + callInvokeWithMethodAndArg + ) : callInvokeWithMethodAndArg(); + } -/** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); + // Define the unified helper method that is used to implement .next, + // .throw, and .return (see defineIteratorMethods). + this._invoke = enqueue; } -} -module.exports = assignValue; + defineIteratorMethods(AsyncIterator.prototype); + define(AsyncIterator.prototype, asyncIteratorSymbol, function () { + return this; + }); + exports.AsyncIterator = AsyncIterator; + // Note that simple async functions are implemented on top of + // AsyncIterator objects; they just return a Promise for the value of + // the final result produced by the iterator. + exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) { + if (PromiseImpl === void 0) PromiseImpl = Promise; -/***/ }), -/* 564 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var iter = new AsyncIterator( + wrap(innerFn, outerFn, self, tryLocsList), + PromiseImpl + ); -var copyObject = __webpack_require__(565), - keys = __webpack_require__(429); + return exports.isGeneratorFunction(outerFn) + ? iter // If outerFn is a generator, return the full iterator. + : iter.next().then(function(result) { + return result.done ? result.value : iter.next(); + }); + }; -/** - * The base implementation of `_.assign` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ -function baseAssign(object, source) { - return object && copyObject(source, keys(source), object); -} + function makeInvokeMethod(innerFn, self, context) { + var state = GenStateSuspendedStart; -module.exports = baseAssign; + return function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } + if (state === GenStateCompleted) { + if (method === "throw") { + throw arg; + } -/***/ }), -/* 565 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + // Be forgiving, per 25.3.3.3.3 of the spec: + // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume + return doneResult(); + } -var assignValue = __webpack_require__(563), - baseAssignValue = __webpack_require__(534); + context.method = method; + context.arg = arg; -/** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ -function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); + while (true) { + var delegate = context.delegate; + if (delegate) { + var delegateResult = maybeInvokeDelegate(delegate, context); + if (delegateResult) { + if (delegateResult === ContinueSentinel) continue; + return delegateResult; + } + } - var index = -1, - length = props.length; + if (context.method === "next") { + // Setting context._sent for legacy support of Babel's + // function.sent implementation. + context.sent = context._sent = context.arg; - while (++index < length) { - var key = props[index]; + } else if (context.method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw context.arg; + } - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; + context.dispatchException(context.arg); - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - baseAssignValue(object, key, newValue); - } else { - assignValue(object, key, newValue); - } - } - return object; -} + } else if (context.method === "return") { + context.abrupt("return", context.arg); + } -module.exports = copyObject; + state = GenStateExecuting; + var record = tryCatch(innerFn, self, context); + if (record.type === "normal") { + // If an exception is thrown from innerFn, we leave state === + // GenStateExecuting and loop back for another invocation. + state = context.done + ? GenStateCompleted + : GenStateSuspendedYield; -/***/ }), -/* 566 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (record.arg === ContinueSentinel) { + continue; + } -var copyObject = __webpack_require__(565), - keysIn = __webpack_require__(567); + return { + value: record.arg, + done: context.done + }; -/** - * The base implementation of `_.assignIn` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ -function baseAssignIn(object, source) { - return object && copyObject(source, keysIn(source), object); -} + } else if (record.type === "throw") { + state = GenStateCompleted; + // Dispatch the exception by looping back around to the + // context.dispatchException(context.arg) call above. + context.method = "throw"; + context.arg = record.arg; + } + } + }; + } -module.exports = baseAssignIn; + // Call delegate.iterator[context.method](context.arg) and handle the + // result, either by returning a { value, done } result from the + // delegate iterator, or by modifying context.method and context.arg, + // setting context.delegate to null, and returning the ContinueSentinel. + function maybeInvokeDelegate(delegate, context) { + var method = delegate.iterator[context.method]; + if (method === undefined) { + // A .throw or .return when the delegate iterator has no .throw + // method always terminates the yield* loop. + context.delegate = null; + if (context.method === "throw") { + // Note: ["return"] must be used for ES3 parsing compatibility. + if (delegate.iterator["return"]) { + // If the delegate iterator has a return method, give it a + // chance to clean up. + context.method = "return"; + context.arg = undefined; + maybeInvokeDelegate(delegate, context); -/***/ }), -/* 567 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (context.method === "throw") { + // If maybeInvokeDelegate(context) changed context.method from + // "return" to "throw", let that override the TypeError below. + return ContinueSentinel; + } + } -var arrayLikeKeys = __webpack_require__(430), - baseKeysIn = __webpack_require__(568), - isArrayLike = __webpack_require__(446); + context.method = "throw"; + context.arg = new TypeError( + "The iterator does not provide a 'throw' method"); + } -/** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ -function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); -} + return ContinueSentinel; + } -module.exports = keysIn; + var record = tryCatch(method, delegate.iterator, context.arg); + if (record.type === "throw") { + context.method = "throw"; + context.arg = record.arg; + context.delegate = null; + return ContinueSentinel; + } -/***/ }), -/* 568 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var info = record.arg; -var isObject = __webpack_require__(52), - isPrototype = __webpack_require__(443), - nativeKeysIn = __webpack_require__(569); + if (! info) { + context.method = "throw"; + context.arg = new TypeError("iterator result is not an object"); + context.delegate = null; + return ContinueSentinel; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + if (info.done) { + // Assign the result of the finished delegate to the temporary + // variable specified by delegate.resultName (see delegateYield). + context[delegate.resultName] = info.value; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + // Resume execution at the desired location (see delegateYield). + context.next = delegate.nextLoc; -/** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeysIn(object) { - if (!isObject(object)) { - return nativeKeysIn(object); - } - var isProto = isPrototype(object), - result = []; + // If context.method was "throw" but the delegate handled the + // exception, let the outer generator proceed normally. If + // context.method was "next", forget context.arg since it has been + // "consumed" by the delegate iterator. If context.method was + // "return", allow the original .return call to continue in the + // outer generator. + if (context.method !== "return") { + context.method = "next"; + context.arg = undefined; + } - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); + } else { + // Re-yield the result returned by the delegate method. + return info; } + + // The delegate iterator is finished, so forget it and continue with + // the outer generator. + context.delegate = null; + return ContinueSentinel; } - return result; -} -module.exports = baseKeysIn; + // Define Generator.prototype.{next,throw,return} in terms of the + // unified ._invoke helper method. + defineIteratorMethods(Gp); + define(Gp, toStringTagSymbol, "Generator"); -/***/ }), -/* 569 */ -/***/ ((module) => { + // A Generator should always return itself as the iterator object when the + // @@iterator function is called on it. Some browsers' implementations of the + // iterator prototype chain incorrectly implement this, causing the Generator + // object to not be returned from this call. This ensures that doesn't happen. + // See https://github.com/facebook/regenerator/issues/274 for more details. + define(Gp, iteratorSymbol, function() { + return this; + }); -/** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); + define(Gp, "toString", function() { + return "[object Generator]"; + }); + + function pushTryEntry(locs) { + var entry = { tryLoc: locs[0] }; + + if (1 in locs) { + entry.catchLoc = locs[1]; + } + + if (2 in locs) { + entry.finallyLoc = locs[2]; + entry.afterLoc = locs[3]; } + + this.tryEntries.push(entry); } - return result; -} -module.exports = nativeKeysIn; + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal"; + delete record.arg; + entry.completion = record; + } + function Context(tryLocsList) { + // The root entry object (effectively a try statement without a catch + // or a finally block) gives us a place to store values thrown from + // locations where there is no enclosing try statement. + this.tryEntries = [{ tryLoc: "root" }]; + tryLocsList.forEach(pushTryEntry, this); + this.reset(true); + } -/***/ }), -/* 570 */ -/***/ ((module, exports, __webpack_require__) => { + exports.keys = function(object) { + var keys = []; + for (var key in object) { + keys.push(key); + } + keys.reverse(); + + // Rather than returning an object with a next method, we keep + // things simple and return the next function itself. + return function next() { + while (keys.length) { + var key = keys.pop(); + if (key in object) { + next.value = key; + next.done = false; + return next; + } + } + + // To avoid creating an additional object, we just hang the .value + // and .done properties off the next function object itself. This + // also ensures that the minifier will not anonymize the function. + next.done = true; + return next; + }; + }; + + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } -/* module decorator */ module = __webpack_require__.nmd(module); -var root = __webpack_require__(48); + if (typeof iterable.next === "function") { + return iterable; + } -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; + if (!isNaN(iterable.length)) { + var i = -1, next = function next() { + while (++i < iterable.length) { + if (hasOwn.call(iterable, i)) { + next.value = iterable[i]; + next.done = false; + return next; + } + } -/** Detect free variable `module`. */ -var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; + next.value = undefined; + next.done = true; -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; + return next; + }; -/** Built-in value references. */ -var Buffer = moduleExports ? root.Buffer : undefined, - allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; + return next.next = next; + } + } -/** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ -function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); + // Return an iterator with no values. + return { next: doneResult }; } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - - buffer.copy(result); - return result; -} - -module.exports = cloneBuffer; + exports.values = values; + function doneResult() { + return { value: undefined, done: true }; + } -/***/ }), -/* 571 */ -/***/ ((module) => { + Context.prototype = { + constructor: Context, -/** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ -function copyArray(source, array) { - var index = -1, - length = source.length; + reset: function(skipTempReset) { + this.prev = 0; + this.next = 0; + // Resetting context._sent for legacy support of Babel's + // function.sent implementation. + this.sent = this._sent = undefined; + this.done = false; + this.delegate = null; - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; -} + this.method = "next"; + this.arg = undefined; -module.exports = copyArray; + this.tryEntries.forEach(resetTryEntry); + if (!skipTempReset) { + for (var name in this) { + // Not sure about the optimal order of these conditions: + if (name.charAt(0) === "t" && + hasOwn.call(this, name) && + !isNaN(+name.slice(1))) { + this[name] = undefined; + } + } + } + }, -/***/ }), -/* 572 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + stop: function() { + this.done = true; -var copyObject = __webpack_require__(565), - getSymbols = __webpack_require__(426); + var rootEntry = this.tryEntries[0]; + var rootRecord = rootEntry.completion; + if (rootRecord.type === "throw") { + throw rootRecord.arg; + } -/** - * Copies own symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ -function copySymbols(source, object) { - return copyObject(source, getSymbols(source), object); -} + return this.rval; + }, -module.exports = copySymbols; + dispatchException: function(exception) { + if (this.done) { + throw exception; + } + var context = this; + function handle(loc, caught) { + record.type = "throw"; + record.arg = exception; + context.next = loc; -/***/ }), -/* 573 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (caught) { + // If the dispatched exception was caught by a catch block, + // then let that catch block handle the exception normally. + context.method = "next"; + context.arg = undefined; + } -var copyObject = __webpack_require__(565), - getSymbolsIn = __webpack_require__(574); + return !! caught; + } -/** - * Copies own and inherited symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ -function copySymbolsIn(source, object) { - return copyObject(source, getSymbolsIn(source), object); -} + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + var record = entry.completion; -module.exports = copySymbolsIn; + if (entry.tryLoc === "root") { + // Exception thrown outside of any try block that could handle + // it, so set the completion value of the entire function to + // throw the exception. + return handle("end"); + } + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"); + var hasFinally = hasOwn.call(entry, "finallyLoc"); -/***/ }), -/* 574 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } else if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } -var arrayPush = __webpack_require__(425), - getPrototype = __webpack_require__(575), - getSymbols = __webpack_require__(426), - stubArray = __webpack_require__(428); + } else if (hasCatch) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeGetSymbols = Object.getOwnPropertySymbols; + } else if (hasFinally) { + if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } -/** - * Creates an array of the own and inherited enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ -var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { - var result = []; - while (object) { - arrayPush(result, getSymbols(object)); - object = getPrototype(object); - } - return result; -}; + } else { + throw new Error("try statement without catch or finally"); + } + } + } + }, -module.exports = getSymbolsIn; + abrupt: function(type, arg) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && + hasOwn.call(entry, "finallyLoc") && + this.prev < entry.finallyLoc) { + var finallyEntry = entry; + break; + } + } + if (finallyEntry && + (type === "break" || + type === "continue") && + finallyEntry.tryLoc <= arg && + arg <= finallyEntry.finallyLoc) { + // Ignore the finally entry if control is not jumping to a + // location outside the try/catch block. + finallyEntry = null; + } -/***/ }), -/* 575 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var record = finallyEntry ? finallyEntry.completion : {}; + record.type = type; + record.arg = arg; -var overArg = __webpack_require__(445); + if (finallyEntry) { + this.method = "next"; + this.next = finallyEntry.finallyLoc; + return ContinueSentinel; + } -/** Built-in value references. */ -var getPrototype = overArg(Object.getPrototypeOf, Object); + return this.complete(record); + }, -module.exports = getPrototype; + complete: function(record, afterLoc) { + if (record.type === "throw") { + throw record.arg; + } + if (record.type === "break" || + record.type === "continue") { + this.next = record.arg; + } else if (record.type === "return") { + this.rval = this.arg = record.arg; + this.method = "return"; + this.next = "end"; + } else if (record.type === "normal" && afterLoc) { + this.next = afterLoc; + } -/***/ }), -/* 576 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return ContinueSentinel; + }, -var baseGetAllKeys = __webpack_require__(424), - getSymbolsIn = __webpack_require__(574), - keysIn = __webpack_require__(567); + finish: function(finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.finallyLoc === finallyLoc) { + this.complete(entry.completion, entry.afterLoc); + resetTryEntry(entry); + return ContinueSentinel; + } + } + }, -/** - * Creates an array of own and inherited enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ -function getAllKeysIn(object) { - return baseGetAllKeys(object, keysIn, getSymbolsIn); -} + "catch": function(tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if (record.type === "throw") { + var thrown = record.arg; + resetTryEntry(entry); + } + return thrown; + } + } -module.exports = getAllKeysIn; + // The context.catch method must only be called with a location + // argument that corresponds to a known catch block. + throw new Error("illegal catch attempt"); + }, + delegateYield: function(iterable, resultName, nextLoc) { + this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }; -/***/ }), -/* 577 */ -/***/ ((module) => { + if (this.method === "next") { + // Deliberately forget the last sent value so that we don't + // accidentally pass it on to the delegate. + this.arg = undefined; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + return ContinueSentinel; + } + }; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + // Regardless of whether this script is executing as a CommonJS module + // or not, return the runtime object so that we can declare the variable + // regeneratorRuntime in the outer scope, which allows this module to be + // injected easily by `bin/regenerator --include-runtime script.js`. + return exports; -/** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ -function initCloneArray(array) { - var length = array.length, - result = new array.constructor(length); +}( + // If this script is executing as a CommonJS module, use module.exports + // as the regeneratorRuntime namespace. Otherwise create a new empty + // object. Either way, the resulting object will be used to initialize + // the regeneratorRuntime variable at the top of this file. + true ? module.exports : 0 +)); - // Add properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; +try { + regeneratorRuntime = runtime; +} catch (accidentalStrictMode) { + // This module should not be running in strict mode, so the above + // assignment should always work unless something is misconfigured. Just + // in case runtime.js accidentally runs in strict mode, in modern engines + // we can explicitly access globalThis. In older engines we can escape + // strict mode using a global Function call. This could conceivably fail + // if a Content Security Policy forbids using Function, but in that case + // the proper solution is to fix the accidental strict mode problem. If + // you've misconfigured your bundler to force strict mode and applied a + // CSP to forbid Function, and you're not willing to fix either of those + // problems, please detail your unique predicament in a GitHub issue. + if (typeof globalThis === "object") { + globalThis.regeneratorRuntime = runtime; + } else { + Function("r", "regeneratorRuntime = r")(runtime); } - return result; } -module.exports = initCloneArray; - /***/ }), -/* 578 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 541 */ +/***/ ((module) => { -var cloneArrayBuffer = __webpack_require__(579), - cloneDataView = __webpack_require__(580), - cloneRegExp = __webpack_require__(581), - cloneSymbol = __webpack_require__(582), - cloneTypedArray = __webpack_require__(583); +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } -/** `Object#toString` result references. */ -var boolTag = '[object Boolean]', - dateTag = '[object Date]', - mapTag = '[object Map]', - numberTag = '[object Number]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]'; + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } +} -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; +function _asyncToGenerator(fn) { + return function () { + var self = this, + args = arguments; + return new Promise(function (resolve, reject) { + var gen = fn.apply(self, args); -/** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ -function initCloneByTag(object, tag, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return cloneArrayBuffer(object); + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } - case boolTag: - case dateTag: - return new Ctor(+object); + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); + } - case dataViewTag: - return cloneDataView(object, isDeep); + _next(undefined); + }); + }; +} - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - return cloneTypedArray(object, isDeep); +module.exports = _asyncToGenerator; +module.exports["default"] = module.exports, module.exports.__esModule = true; - case mapTag: - return new Ctor; +/***/ }), +/* 542 */ +/***/ ((module) => { - case numberTag: - case stringTag: - return new Ctor(object); +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +} - case regexpTag: - return cloneRegExp(object); +module.exports = _classCallCheck; +module.exports["default"] = module.exports, module.exports.__esModule = true; - case setTag: - return new Ctor; +/***/ }), +/* 543 */ +/***/ ((module) => { - case symbolTag: - return cloneSymbol(object); +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); } } -module.exports = initCloneByTag; +function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; +} +module.exports = _createClass; +module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), -/* 579 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 544 */ +/***/ ((module) => { -var Uint8Array = __webpack_require__(419); +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } -/** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ -function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array(result).set(new Uint8Array(arrayBuffer)); - return result; + return obj; } -module.exports = cloneArrayBuffer; - +module.exports = _defineProperty; +module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), -/* 580 */ +/* 545 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var cloneArrayBuffer = __webpack_require__(579); +var baseAssignValue = __webpack_require__(546), + baseForOwn = __webpack_require__(548), + baseIteratee = __webpack_require__(413); /** - * Creates a clone of `dataView`. + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). * - * @private - * @param {Object} dataView The data view to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned data view. + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) */ -function cloneDataView(dataView, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; - return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +function mapValues(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; } -module.exports = cloneDataView; +module.exports = mapValues; /***/ }), -/* 581 */ -/***/ ((module) => { +/* 546 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/** Used to match `RegExp` flags from their coerced string values. */ -var reFlags = /\w*$/; +var defineProperty = __webpack_require__(547); /** - * Creates a clone of `regexp`. + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. * * @private - * @param {Object} regexp The regexp to clone. - * @returns {Object} Returns the cloned regexp. + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. */ -function cloneRegExp(regexp) { - var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); - result.lastIndex = regexp.lastIndex; - return result; +function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } } -module.exports = cloneRegExp; +module.exports = baseAssignValue; /***/ }), -/* 582 */ +/* 547 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var Symbol = __webpack_require__(47); - -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; +var getNative = __webpack_require__(383); -/** - * Creates a clone of the `symbol` object. - * - * @private - * @param {Object} symbol The symbol object to clone. - * @returns {Object} Returns the cloned symbol object. - */ -function cloneSymbol(symbol) { - return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; -} +var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} +}()); -module.exports = cloneSymbol; +module.exports = defineProperty; /***/ }), -/* 583 */ +/* 548 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var cloneArrayBuffer = __webpack_require__(579); +var baseFor = __webpack_require__(549), + keys = __webpack_require__(441); /** - * Creates a clone of `typedArray`. + * The base implementation of `_.forOwn` without support for iteratee shorthands. * * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. */ -function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); } -module.exports = cloneTypedArray; +module.exports = baseForOwn; /***/ }), -/* 584 */ +/* 549 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseCreate = __webpack_require__(585), - getPrototype = __webpack_require__(575), - isPrototype = __webpack_require__(443); +var createBaseFor = __webpack_require__(550); /** - * Initializes an object clone. + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. * * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. */ -function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; -} +var baseFor = createBaseFor(); -module.exports = initCloneObject; +module.exports = baseFor; /***/ }), -/* 585 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var isObject = __webpack_require__(52); - -/** Built-in value references. */ -var objectCreate = Object.create; +/* 550 */ +/***/ ((module) => { /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. + * Creates a base function for methods like `_.forIn` and `_.forOwn`. * * @private - * @param {Object} proto The object to inherit from. - * @returns {Object} Returns the new object. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. */ -var baseCreate = (function() { - function object() {} - return function(proto) { - if (!isObject(proto)) { - return {}; - } - if (objectCreate) { - return objectCreate(proto); +function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; + return object; }; -}()); +} -module.exports = baseCreate; +module.exports = createBaseFor; /***/ }), -/* 586 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var baseIsMap = __webpack_require__(587), - baseUnary = __webpack_require__(440), - nodeUtil = __webpack_require__(441); - -/* Node.js helper references. */ -var nodeIsMap = nodeUtil && nodeUtil.isMap; +/* 551 */ +/***/ ((module) => { /** - * Checks if `value` is classified as a `Map` object. + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. * * @static * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @since 4.0.0 + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. * @example * - * _.isMap(new Map); - * // => true - * - * _.isMap(new WeakMap); - * // => false + * _.fromPairs([['a', 1], ['b', 2]]); + * // => { 'a': 1, 'b': 2 } */ -var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; - -module.exports = isMap; - - -/***/ }), -/* 587 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var getTag = __webpack_require__(447), - isObjectLike = __webpack_require__(53); - -/** `Object#toString` result references. */ -var mapTag = '[object Map]'; +function fromPairs(pairs) { + var index = -1, + length = pairs == null ? 0 : pairs.length, + result = {}; -/** - * The base implementation of `_.isMap` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - */ -function baseIsMap(value) { - return isObjectLike(value) && getTag(value) == mapTag; + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; } -module.exports = baseIsMap; +module.exports = fromPairs; /***/ }), -/* 588 */ +/* 552 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseIsSet = __webpack_require__(589), - baseUnary = __webpack_require__(440), - nodeUtil = __webpack_require__(441); - -/* Node.js helper references. */ -var nodeIsSet = nodeUtil && nodeUtil.isSet; +var baseFlatten = __webpack_require__(553); /** - * Checks if `value` is classified as a `Set` object. + * Flattens `array` a single level deep. * * @static * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. * @example * - * _.isSet(new Set); - * // => true - * - * _.isSet(new WeakSet); - * // => false - */ -var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; - -module.exports = isSet; - - -/***/ }), -/* 589 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var getTag = __webpack_require__(447), - isObjectLike = __webpack_require__(53); - -/** `Object#toString` result references. */ -var setTag = '[object Set]'; - -/** - * The base implementation of `_.isSet` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] */ -function baseIsSet(value) { - return isObjectLike(value) && getTag(value) == setTag; +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, 1) : []; } -module.exports = baseIsSet; - - -/***/ }), -/* 590 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireWildcard = __webpack_require__(510); - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.normalizeApp = exports.APPS_DOCTYPE = void 0; - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); - -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); - -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); - -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); - -var _get3 = _interopRequireDefault(__webpack_require__(358)); - -var _registry = __webpack_require__(596); - -var _Collection = _interopRequireDefault(__webpack_require__(600)); - -var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601)); - -var _errors = __webpack_require__(651); - -function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } - -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -var APPS_DOCTYPE = 'io.cozy.apps'; -exports.APPS_DOCTYPE = APPS_DOCTYPE; - -var normalizeApp = function normalizeApp(app, doctype) { - return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, app.attributes), app), (0, _DocumentCollection2.normalizeDoc)(app, doctype)), {}, { - id: app.id // ignores any 'id' attribute in the manifest - - }); -}; -/** - * Extends `DocumentCollection` API along with specific methods for `io.cozy.apps`. - */ - - -exports.normalizeApp = normalizeApp; - -var AppCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(AppCollection, _DocumentCollection); - - var _super = _createSuper(AppCollection); - - function AppCollection(stackClient) { - var _this; - - (0, _classCallCheck2.default)(this, AppCollection); - _this = _super.call(this, APPS_DOCTYPE, stackClient); - _this.endpoint = '/apps/'; - return _this; - } - - (0, _createClass2.default)(AppCollection, [{ - key: "get", - value: function () { - var _get2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(idArg, query) { - var _this2 = this; - - var id, sources, dataFetchers, _iterator, _step, source, res, data, normalizedDoc; - - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - if (idArg.indexOf('/') > -1) { - id = idArg.split('/')[1]; - } else { - console.warn("Deprecated: in next versions of cozy-client, it will not be possible to query apps/konnectors only with id, please use the form ".concat(this.doctype, "/").concat(idArg, "\n\n- Q('io.cozy.apps').getById('banks')\n+ Q('io.cozy.apps').getById('io.cozy.apps/banks')")); - id = idArg; - } - - if (!(query && query.sources && (!Array.isArray(query.sources) || query.sources.length === 0))) { - _context.next = 3; - break; - } - - throw new Error('Invalid "sources" attribute passed in query, please use an array with at least one element.'); - - case 3: - sources = (0, _get3.default)(query, 'sources', ['stack']); - dataFetchers = { - stack: function stack() { - return _Collection.default.get(_this2.stackClient, "".concat(_this2.endpoint).concat(encodeURIComponent(id)), { - normalize: _this2.constructor.normalizeDoctype(_this2.doctype) - }); - }, - registry: function registry() { - return _this2.stackClient.fetchJSON('GET', _registry.registryEndpoint + id); - } - }; - _iterator = _createForOfIteratorHelper(sources); - _context.prev = 6; - - _iterator.s(); - - case 8: - if ((_step = _iterator.n()).done) { - _context.next = 27; - break; - } - - source = _step.value; - _context.prev = 10; - _context.next = 13; - return dataFetchers[source](); - - case 13: - res = _context.sent; - - if (!(source !== 'registry')) { - _context.next = 16; - break; - } - - return _context.abrupt("return", res); - - case 16: - data = (0, _registry.transformRegistryFormatToStackFormat)(res); - normalizedDoc = (0, _DocumentCollection2.normalizeDoc)(data, this.doctype); - return _context.abrupt("return", { - data: normalizedDoc - }); - - case 21: - _context.prev = 21; - _context.t0 = _context["catch"](10); - - if (!(source === sources[sources.length - 1])) { - _context.next = 25; - break; - } - - throw _context.t0; - - case 25: - _context.next = 8; - break; - - case 27: - _context.next = 32; - break; - - case 29: - _context.prev = 29; - _context.t1 = _context["catch"](6); - - _iterator.e(_context.t1); - - case 32: - _context.prev = 32; - - _iterator.f(); - - return _context.finish(32); - - case 35: - case "end": - return _context.stop(); - } - } - }, _callee, this, [[6, 29, 32, 35], [10, 21]]); - })); - - function get(_x, _x2) { - return _get2.apply(this, arguments); - } - - return get; - }() - /** - * Lists all apps, without filters. - * - * The returned documents are not paginated by the stack. - * - * @returns {{data, meta, skip, next}} The JSON API conformant response. - * @throws {FetchError} - */ - - }, { - key: "all", - value: function () { - var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { - var _this3 = this; - - var resp; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _context2.next = 2; - return this.stackClient.fetchJSON('GET', this.endpoint); +module.exports = flatten; - case 2: - resp = _context2.sent; - return _context2.abrupt("return", { - data: resp.data.map(function (app) { - return normalizeApp(app, _this3.doctype); - }), - meta: { - count: resp.meta.count - }, - skip: 0, - next: false - }); - case 4: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); +/***/ }), +/* 553 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - function all() { - return _all.apply(this, arguments); - } +var arrayPush = __webpack_require__(437), + isFlattenable = __webpack_require__(554); - return all; - }() - }, { - key: "create", - value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - throw new Error('create() method is not available for applications'); +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; - case 1: - case "end": - return _context3.stop(); - } - } - }, _callee3); - })); + predicate || (predicate = isFlattenable); + result || (result = []); - function create() { - return _create.apply(this, arguments); + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + arrayPush(result, value); } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} - return create; - }() - }, { - key: "update", - value: function () { - var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() { - return _regenerator.default.wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - throw new Error('update() method is not available for applications'); +module.exports = baseFlatten; - case 1: - case "end": - return _context4.stop(); - } - } - }, _callee4); - })); - function update() { - return _update.apply(this, arguments); - } +/***/ }), +/* 554 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return update; - }() - }, { - key: "destroy", - value: function () { - var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() { - return _regenerator.default.wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - throw new Error('destroy() method is not available for applications'); +var Symbol = __webpack_require__(47), + isArguments = __webpack_require__(444), + isArray = __webpack_require__(55); - case 1: - case "end": - return _context5.stop(); - } - } - }, _callee5); - })); +/** Built-in value references. */ +var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; - function destroy() { - return _destroy.apply(this, arguments); - } +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return isArray(value) || isArguments(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} - return destroy; - }() - }]); - return AppCollection; -}(_DocumentCollection2.default); +module.exports = isFlattenable; -AppCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; -var _default = AppCollection; -exports["default"] = _default; /***/ }), -/* 591 */ +/* 555 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var setPrototypeOf = __webpack_require__(592); +var baseRest = __webpack_require__(556), + unzip = __webpack_require__(563); -function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function"); - } +/** + * Creates an array of grouped elements, the first of which contains the + * first elements of the given arrays, the second of which contains the + * second elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + */ +var zip = baseRest(unzip); - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); - if (superClass) setPrototypeOf(subClass, superClass); -} +module.exports = zip; -module.exports = _inherits; -module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), -/* 592 */ -/***/ ((module) => { +/* 556 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _setPrototypeOf(o, p) { - module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; +var identity = __webpack_require__(471), + overRest = __webpack_require__(557), + setToString = __webpack_require__(559); - module.exports["default"] = module.exports, module.exports.__esModule = true; - return _setPrototypeOf(o, p); +/** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ +function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); } -module.exports = _setPrototypeOf; -module.exports["default"] = module.exports, module.exports.__esModule = true; +module.exports = baseRest; + /***/ }), -/* 593 */ +/* 557 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _typeof = (__webpack_require__(511)["default"]); +var apply = __webpack_require__(558); -var assertThisInitialized = __webpack_require__(594); +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; -function _possibleConstructorReturn(self, call) { - if (call && (_typeof(call) === "object" || typeof call === "function")) { - return call; - } else if (call !== void 0) { - throw new TypeError("Derived constructors may only return object or undefined"); - } +/** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ +function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); - return assertThisInitialized(self); + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; } -module.exports = _possibleConstructorReturn; -module.exports["default"] = module.exports, module.exports.__esModule = true; +module.exports = overRest; + /***/ }), -/* 594 */ +/* 558 */ /***/ ((module) => { -function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); } - - return self; + return func.apply(thisArg, args); } -module.exports = _assertThisInitialized; -module.exports["default"] = module.exports, module.exports.__esModule = true; +module.exports = apply; + /***/ }), -/* 595 */ -/***/ ((module) => { +/* 559 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _getPrototypeOf(o) { - module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - module.exports["default"] = module.exports, module.exports.__esModule = true; - return _getPrototypeOf(o); -} +var baseSetToString = __webpack_require__(560), + shortOut = __webpack_require__(562); -module.exports = _getPrototypeOf; -module.exports["default"] = module.exports, module.exports.__esModule = true; +/** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ +var setToString = shortOut(baseSetToString); -/***/ }), -/* 596 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +module.exports = setToString; -"use strict"; +/***/ }), +/* 560 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _interopRequireDefault = __webpack_require__(512); +var constant = __webpack_require__(561), + defineProperty = __webpack_require__(547), + identity = __webpack_require__(471); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.registryEndpoint = exports.transformRegistryFormatToStackFormat = void 0; +/** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ +var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); +}; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +module.exports = baseSetToString; -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +/***/ }), +/* 561 */ +/***/ ((module) => { -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +/** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new constant function. + * @example + * + * var objects = _.times(2, _.constant({ 'a': 1 })); + * + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); + * // => true + */ +function constant(value) { + return function() { + return value; + }; +} -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +module.exports = constant; -var _get = _interopRequireDefault(__webpack_require__(358)); -__webpack_require__(597); +/***/ }), +/* 562 */ +/***/ ((module) => { -var _terms = _interopRequireDefault(__webpack_require__(598)); +/** Used to detect hot functions by number of calls within a span of milliseconds. */ +var HOT_COUNT = 800, + HOT_SPAN = 16; -var _constants = __webpack_require__(599); +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeNow = Date.now; -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +/** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ +function shortOut(func) { + var count = 0, + lastCalled = 0; -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); -var transformRegistryFormatToStackFormat = function transformRegistryFormatToStackFormat(doc) { - return _objectSpread({ - id: (0, _get.default)(doc, 'latest_version.manifest.source'), - attributes: (0, _get.default)(doc, 'latest_version.manifest') - }, doc); -}; + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; +} -exports.transformRegistryFormatToStackFormat = transformRegistryFormatToStackFormat; -var registryEndpoint = '/registry/'; -exports.registryEndpoint = registryEndpoint; +module.exports = shortOut; -var queryPartFromOptions = function queryPartFromOptions(options) { - var query = new URLSearchParams(options).toString(); - return query ? "?".concat(query) : ''; -}; -var getBaseRoute = function getBaseRoute(app) { - var type = app.type; // TODO node is an historic type, it should be `konnector`, check with the back +/***/ }), +/* 563 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var route = type === _constants.APP_TYPE.KONNECTOR || type === 'node' ? 'konnectors' : 'apps'; - return "/".concat(route); -}; -/** - * @typedef {object} RegistryApp - * @property {string} slug - * @property {object} terms - * @property {boolean} installed - */ +var arrayFilter = __webpack_require__(439), + arrayMap = __webpack_require__(410), + baseProperty = __webpack_require__(473), + baseTimes = __webpack_require__(443), + isArrayLikeObject = __webpack_require__(564); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; /** - * @typedef {"dev"|"beta"|"stable"} RegistryAppChannel + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @since 1.2.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + * + * _.unzip(zipped); + * // => [['a', 'b'], [1, 2], [true, false]] */ +function unzip(array) { + if (!(array && array.length)) { + return []; + } + var length = 0; + array = arrayFilter(array, function(group) { + if (isArrayLikeObject(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + return baseTimes(length, function(index) { + return arrayMap(array, baseProperty(index)); + }); +} +module.exports = unzip; -var Registry = /*#__PURE__*/function () { - function Registry(options) { - (0, _classCallCheck2.default)(this, Registry); - if (!options.client) { - throw new Error('Need to pass a client to instantiate a Registry API.'); - } +/***/ }), +/* 564 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.client = options.client; - } - /** - * Installs or updates an app from a source. - * - * Accepts the terms if the app has them. - * - * @param {RegistryApp} app - App to be installed - * @param {string} source - String (ex: registry://drive/stable) - * @returns {Promise} - */ +var isArrayLike = __webpack_require__(458), + isObjectLike = __webpack_require__(53); +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} - (0, _createClass2.default)(Registry, [{ - key: "installApp", - value: function () { - var _installApp = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(app, source) { - var slug, terms, searchParams, isUpdate, querypart, verb, baseRoute; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - slug = app.slug, terms = app.terms; - searchParams = {}; - isUpdate = app.installed; - if (isUpdate) searchParams.PermissionsAcked = isUpdate; - if (source) searchParams.Source = source; - querypart = queryPartFromOptions(searchParams); +module.exports = isArrayLikeObject; - if (!terms) { - _context.next = 9; - break; - } - _context.next = 9; - return _terms.default.save(this.client, terms); +/***/ }), +/* 565 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 9: - verb = app.installed ? 'PUT' : 'POST'; - baseRoute = getBaseRoute(app); - return _context.abrupt("return", this.client.stackClient.fetchJSON(verb, "".concat(baseRoute, "/").concat(slug).concat(querypart))); +var arrayEach = __webpack_require__(566), + baseEach = __webpack_require__(567), + castFunction = __webpack_require__(569), + isArray = __webpack_require__(55); - case 12: - case "end": - return _context.stop(); - } - } - }, _callee, this); - })); +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = isArray(collection) ? arrayEach : baseEach; + return func(collection, castFunction(iteratee)); +} - function installApp(_x, _x2) { - return _installApp.apply(this, arguments); - } +module.exports = forEach; - return installApp; - }() - /** - * Uninstalls an app. - */ - }, { - key: "uninstallApp", - value: function () { - var _uninstallApp = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(app) { - var slug, baseRoute; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - slug = app.slug; - baseRoute = getBaseRoute(app); - return _context2.abrupt("return", this.client.stackClient.fetchJSON('DELETE', "".concat(baseRoute, "/").concat(slug))); +/***/ }), +/* 566 */ +/***/ ((module) => { - case 3: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; - function uninstallApp(_x3) { - return _uninstallApp.apply(this, arguments); - } + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} - return uninstallApp; - }() - /** - * Fetch at most 200 apps from the channel - * - * @param {object} params - Fetching parameters - * @param {string} params.type - "webapp" or "konnector" - * @param {RegistryAppChannel} params.channel - The channel of the apps to fetch - * @param {string} params.limit - maximum number of fetched apps - defaults to 200 - * - * @returns {Promise<Array<RegistryApp>>} - */ +module.exports = arrayEach; - }, { - key: "fetchApps", - value: function () { - var _fetchApps = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(params) { - var channel, type, _params$limit, limit, searchParams, querypart, _yield$this$client$st, apps; - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - channel = params.channel, type = params.type, _params$limit = params.limit, limit = _params$limit === void 0 ? '200' : _params$limit; - searchParams = { - limit: limit, - versionsChannel: channel, - latestChannelVersion: channel - }; - querypart = new URLSearchParams(searchParams).toString(); +/***/ }), +/* 567 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (type) { - // Unfortunately, URLSearchParams encodes brackets so we have to do - // the querypart handling manually - querypart = querypart + "&filter[type]=".concat(type); - } +var baseForOwn = __webpack_require__(548), + createBaseEach = __webpack_require__(568); - _context3.next = 6; - return this.client.stackClient.fetchJSON('GET', "/registry?".concat(querypart)); +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = createBaseEach(baseForOwn); - case 6: - _yield$this$client$st = _context3.sent; - apps = _yield$this$client$st.data; - return _context3.abrupt("return", apps); +module.exports = baseEach; - case 9: - case "end": - return _context3.stop(); - } - } - }, _callee3, this); - })); - function fetchApps(_x4) { - return _fetchApps.apply(this, arguments); - } +/***/ }), +/* 568 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return fetchApps; - }() - /** - * Fetch the list of apps that are in maintenance mode - * - * @returns {Array<RegistryApp>} - */ +var isArrayLike = __webpack_require__(458); - }, { - key: "fetchAppsInMaintenance", - value: function fetchAppsInMaintenance() { - return this.client.stackClient.fetchJSON('GET', '/registry/maintenance'); +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; } - /** - * Fetch the status of a single app on the registry - * - * @param {string} slug - The slug of the app to fetch - * - * @returns {RegistryApp} - */ - - }, { - key: "fetchApp", - value: function fetchApp(slug) { - return this.client.stackClient.fetchJSON('GET', "/registry/".concat(slug)); + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); } - /** - * Fetch the latest version of an app for the given channel and slug - * - * @param {object} params - Fetching parameters - * @param {string} params.slug - The slug of the app to fetch - * @param {RegistryAppChannel} params.channel - The channel of the app to fetch - * @param {string} params.version - The version of the app to fetch. Can also be "latest" - * - * @returns {RegistryApp} - */ - - }, { - key: "fetchAppVersion", - value: function fetchAppVersion(params) { - if (!params.slug) { - throw new Error('Need to pass a slug to use fetchAppVersion'); - } - - var slug = params.slug, - channel = params.channel, - version = params.version; - var finalChannel = !channel && (!version || version === 'latest') ? 'stable' : channel; - var url = "/registry/".concat(slug, "/"); + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); - if (finalChannel) { - url += "".concat(finalChannel, "/").concat(version || 'latest'); - } else { - url += "".concat(version); + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; } - - return this.client.stackClient.fetchJSON('GET', url); } - }]); - return Registry; -}(); + return collection; + }; +} + +module.exports = createBaseEach; -var _default = Registry; -exports["default"] = _default; /***/ }), -/* 597 */ -/***/ (function() { +/* 569 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var identity = __webpack_require__(471); /** + * Casts `value` to `identity` if it's not a function. * - * - * @author Jerry Bendy <jerry@icewingcc.com> - * @licence MIT - * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. */ +function castFunction(value) { + return typeof value == 'function' ? value : identity; +} -(function(self) { - 'use strict'; +module.exports = castFunction; - var nativeURLSearchParams = (function() { - // #41 Fix issue in RN - try { - if (self.URLSearchParams && (new self.URLSearchParams('foo=bar')).get('foo') === 'bar') { - return self.URLSearchParams; - } - } catch (e) {} - return null; - })(), - isSupportObjectConstructor = nativeURLSearchParams && (new nativeURLSearchParams({a: 1})).toString() === 'a=1', - // There is a bug in safari 10.1 (and earlier) that incorrectly decodes `%2B` as an empty space and not a plus. - decodesPlusesCorrectly = nativeURLSearchParams && (new nativeURLSearchParams('s=%2B').get('s') === '+'), - __URLSearchParams__ = "__URLSearchParams__", - // Fix bug in Edge which cannot encode ' &' correctly - encodesAmpersandsCorrectly = nativeURLSearchParams ? (function() { - var ampersandTest = new nativeURLSearchParams(); - ampersandTest.append('s', ' &'); - return ampersandTest.toString() === 's=+%26'; - })() : true, - prototype = URLSearchParamsPolyfill.prototype, - iterable = !!(self.Symbol && self.Symbol.iterator); - if (nativeURLSearchParams && isSupportObjectConstructor && decodesPlusesCorrectly && encodesAmpersandsCorrectly) { - return; +/***/ }), +/* 570 */ +/***/ ((module) => { + +function M() { this._events = {}; } +M.prototype = { + on: function(ev, cb) { + this._events || (this._events = {}); + var e = this._events; + (e[ev] || (e[ev] = [])).push(cb); + return this; + }, + removeListener: function(ev, cb) { + var e = this._events[ev] || [], i; + for(i = e.length-1; i >= 0 && e[i]; i--){ + if(e[i] === cb || e[i].cb === cb) { e.splice(i, 1); } + } + }, + removeAllListeners: function(ev) { + if(!ev) { this._events = {}; } + else { this._events[ev] && (this._events[ev] = []); } + }, + listeners: function(ev) { + return (this._events ? this._events[ev] || [] : []); + }, + emit: function(ev) { + this._events || (this._events = {}); + var args = Array.prototype.slice.call(arguments, 1), i, e = this._events[ev] || []; + for(i = e.length-1; i >= 0 && e[i]; i--){ + e[i].apply(this, args); + } + return this; + }, + when: function(ev, cb) { + return this.once(ev, cb, true); + }, + once: function(ev, cb, when) { + if(!cb) return this; + function c() { + if(!when) this.removeListener(ev, c); + if(cb.apply(this, arguments) && when) this.removeListener(ev, c); } + c.cb = cb; + this.on(ev, c); + return this; + } +}; +M.mixin = function(dest) { + var o = M.prototype, k; + for (k in o) { + o.hasOwnProperty(k) && (dest.prototype[k] = o[k]); + } +}; +module.exports = M; - /** - * Make a URLSearchParams instance - * - * @param {object|string|URLSearchParams} search - * @constructor - */ - function URLSearchParamsPolyfill(search) { - search = search || ""; +/***/ }), +/* 571 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - // support construct object with another URLSearchParams instance - if (search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill) { - search = search.toString(); - } - this [__URLSearchParams__] = parseToDict(search); - } +"use strict"; - /** - * Appends a specified key/value pair as a new search parameter. - * - * @param {string} name - * @param {string} value - */ - prototype.append = function(name, value) { - appendTo(this [__URLSearchParams__], name, value); - }; +var _interopRequireWildcard = __webpack_require__(522); - /** - * Deletes the given search parameter, and its associated value, - * from the list of all search parameters. - * - * @param {string} name - */ - prototype['delete'] = function(name) { - delete this [__URLSearchParams__] [name]; - }; +var _interopRequireDefault = __webpack_require__(524); - /** - * Returns the first value associated to the given search parameter. - * - * @param {string} name - * @returns {string|null} - */ - prototype.get = function(name) { - var dict = this [__URLSearchParams__]; - return this.has(name) ? dict[name][0] : null; - }; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "default", ({ + enumerable: true, + get: function get() { + return _CozyStackClient.default; + } +})); +Object.defineProperty(exports, "OAuthClient", ({ + enumerable: true, + get: function get() { + return _OAuthClient.default; + } +})); +Object.defineProperty(exports, "errors", ({ + enumerable: true, + get: function get() { + return _errors.default; + } +})); +Object.defineProperty(exports, "FetchError", ({ + enumerable: true, + get: function get() { + return _errors.FetchError; + } +})); +Object.defineProperty(exports, "normalizeDoc", ({ + enumerable: true, + get: function get() { + return _DocumentCollection.normalizeDoc; + } +})); - /** - * Returns all the values association with a given search parameter. - * - * @param {string} name - * @returns {Array} - */ - prototype.getAll = function(name) { - var dict = this [__URLSearchParams__]; - return this.has(name) ? dict [name].slice(0) : []; - }; +var _CozyStackClient = _interopRequireDefault(__webpack_require__(572)); - /** - * Returns a Boolean indicating if such a search parameter exists. - * - * @param {string} name - * @returns {boolean} - */ - prototype.has = function(name) { - return hasOwnProperty(this [__URLSearchParams__], name); - }; +var _OAuthClient = _interopRequireDefault(__webpack_require__(696)); - /** - * Sets the value associated to a given search parameter to - * the given value. If there were several values, delete the - * others. - * - * @param {string} name - * @param {string} value - */ - prototype.set = function set(name, value) { - this [__URLSearchParams__][name] = ['' + value]; - }; +var _errors = _interopRequireWildcard(__webpack_require__(663)); - /** - * Returns a string containg a query string suitable for use in a URL. - * - * @returns {string} - */ - prototype.toString = function() { - var dict = this[__URLSearchParams__], query = [], i, key, name, value; - for (key in dict) { - name = encode(key); - for (i = 0, value = dict[key]; i < value.length; i++) { - query.push(name + '=' + encode(value[i])); - } - } - return query.join('&'); - }; +var _DocumentCollection = __webpack_require__(613); + +/***/ }), +/* 572 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; - // There is a bug in Safari 10.1 and `Proxy`ing it is not enough. - var forSureUsePolyfill = !decodesPlusesCorrectly; - var useProxy = (!forSureUsePolyfill && nativeURLSearchParams && !isSupportObjectConstructor && self.Proxy); - var propValue; - if (useProxy) { - // Safari 10.0 doesn't support Proxy, so it won't extend URLSearchParams on safari 10.0 - propValue = new Proxy(nativeURLSearchParams, { - construct: function (target, args) { - return new target((new URLSearchParamsPolyfill(args[0]).toString())); - } - }) - // Chrome <=60 .toString() on a function proxy got error "Function.prototype.toString is not generic" - propValue.toString = Function.prototype.toString.bind(URLSearchParamsPolyfill); - } else { - propValue = URLSearchParamsPolyfill; - } - /* - * Apply polifill to global object and append other prototype into it - */ - Object.defineProperty(self, 'URLSearchParams', { - value: propValue - }); - var USPProto = self.URLSearchParams.prototype; +var _interopRequireWildcard = __webpack_require__(522); - USPProto.polyfill = true; +var _interopRequireDefault = __webpack_require__(524); - /** - * - * @param {function} callback - * @param {object} thisArg - */ - USPProto.forEach = USPProto.forEach || function(callback, thisArg) { - var dict = parseToDict(this.toString()); - Object.getOwnPropertyNames(dict).forEach(function(name) { - dict[name].forEach(function(value) { - callback.call(thisArg, value, name, this); - }, this); - }, this); - }; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - /** - * Sort all name-value pairs - */ - USPProto.sort = USPProto.sort || function() { - var dict = parseToDict(this.toString()), keys = [], k, i, j; - for (k in dict) { - keys.push(k); - } - keys.sort(); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - for (i = 0; i < keys.length; i++) { - this['delete'](keys[i]); - } - for (i = 0; i < keys.length; i++) { - var key = keys[i], values = dict[key]; - for (j = 0; j < values.length; j++) { - this.append(key, values[j]); - } - } - }; +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - /** - * Returns an iterator allowing to go through all keys of - * the key/value pairs contained in this object. - * - * @returns {function} - */ - USPProto.keys = USPProto.keys || function() { - var items = []; - this.forEach(function(item, name) { - items.push(name); - }); - return makeIterator(items); - }; +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); - /** - * Returns an iterator allowing to go through all values of - * the key/value pairs contained in this object. - * - * @returns {function} - */ - USPProto.values = USPProto.values || function() { - var items = []; - this.forEach(function(item) { - items.push(item); - }); - return makeIterator(items); - }; +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - /** - * Returns an iterator allowing to go through all key/value - * pairs contained in this object. - * - * @returns {function} - */ - USPProto.entries = USPProto.entries || function() { - var items = []; - this.forEach(function(item, name) { - items.push([name, item]); - }); - return makeIterator(items); - }; +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); +var _cloneDeep = _interopRequireDefault(__webpack_require__(573)); - if (iterable) { - USPProto[self.Symbol.iterator] = USPProto[self.Symbol.iterator] || USPProto.entries; - } +var _AppCollection = _interopRequireWildcard(__webpack_require__(602)); +var _AppToken = _interopRequireDefault(__webpack_require__(668)); - function encode(str) { - var replace = { - '!': '%21', - "'": '%27', - '(': '%28', - ')': '%29', - '~': '%7E', - '%20': '+', - '%00': '\x00' - }; - return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function(match) { - return replace[match]; - }); - } +var _AccessToken = _interopRequireDefault(__webpack_require__(669)); - function decode(str) { - return str - .replace(/[ +]/g, '%20') - .replace(/(%[a-f0-9]{2})+/ig, function(match) { - return decodeURIComponent(match); - }); - } +var _DocumentCollection = _interopRequireDefault(__webpack_require__(613)); - function makeIterator(arr) { - var iterator = { - next: function() { - var value = arr.shift(); - return {done: value === undefined, value: value}; - } - }; +var _FileCollection = _interopRequireDefault(__webpack_require__(670)); - if (iterable) { - iterator[self.Symbol.iterator] = function() { - return iterator; - }; - } +var _JobCollection = _interopRequireWildcard(__webpack_require__(679)); - return iterator; - } +var _KonnectorCollection = _interopRequireWildcard(__webpack_require__(680)); - function parseToDict(search) { - var dict = {}; +var _SharingCollection = _interopRequireDefault(__webpack_require__(684)); - if (typeof search === "object") { - // if `search` is an array, treat it as a sequence - if (isArray(search)) { - for (var i = 0; i < search.length; i++) { - var item = search[i]; - if (isArray(item) && item.length === 2) { - appendTo(dict, item[0], item[1]); - } else { - throw new TypeError("Failed to construct 'URLSearchParams': Sequence initializer must only contain pair elements"); - } - } +var _PermissionCollection = _interopRequireDefault(__webpack_require__(685)); - } else { - for (var key in search) { - if (search.hasOwnProperty(key)) { - appendTo(dict, key, search[key]); - } - } - } +var _TriggerCollection = _interopRequireWildcard(__webpack_require__(681)); - } else { - // remove first '?' - if (search.indexOf("?") === 0) { - search = search.slice(1); - } +var _SettingsCollection = _interopRequireWildcard(__webpack_require__(686)); - var pairs = search.split("&"); - for (var j = 0; j < pairs.length; j++) { - var value = pairs [j], - index = value.indexOf('='); +var _NotesCollection = _interopRequireWildcard(__webpack_require__(687)); - if (-1 < index) { - appendTo(dict, decode(value.slice(0, index)), decode(value.slice(index + 1))); +var _OAuthClientsCollection = _interopRequireWildcard(__webpack_require__(689)); - } else { - if (value) { - appendTo(dict, decode(value), ''); - } - } - } - } +var _ShortcutsCollection = _interopRequireWildcard(__webpack_require__(690)); - return dict; - } +var _ContactsCollection = _interopRequireWildcard(__webpack_require__(691)); - function appendTo(dict, name, value) { - var val = typeof value === 'string' ? value : ( - value !== null && value !== undefined && typeof value.toString === 'function' ? value.toString() : JSON.stringify(value) - ); +var _getIconURL2 = _interopRequireDefault(__webpack_require__(692)); - // #47 Prevent using `hasOwnProperty` as a property name - if (hasOwnProperty(dict, name)) { - dict[name].push(val); - } else { - dict[name] = [val]; - } - } +var _logDeprecate = _interopRequireDefault(__webpack_require__(694)); - function isArray(val) { - return !!val && '[object Array]' === Object.prototype.toString.call(val); - } +var _errors = _interopRequireWildcard(__webpack_require__(663)); - function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); - } +var _xhrFetch = __webpack_require__(695); -})(typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : this)); +var _microee = _interopRequireDefault(__webpack_require__(570)); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -/***/ }), -/* 598 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -"use strict"; +var normalizeUri = function normalizeUri(uriArg) { + var uri = uriArg; + if (uri === null) return null; + while (uri[uri.length - 1] === '/') { + uri = uri.slice(0, -1); + } -var _interopRequireDefault = __webpack_require__(512); + return uri; +}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +var isRevocationError = function isRevocationError(err) { + return err.message && _errors.default.CLIENT_NOT_FOUND.test(err.message); +}; +/** + * Main API against the `cozy-stack` server. + */ -var _regenerator = _interopRequireDefault(__webpack_require__(527)); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var CozyStackClient = /*#__PURE__*/function () { + function CozyStackClient(options) { + (0, _classCallCheck2.default)(this, CozyStackClient); -var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525)); + var opts = _objectSpread({}, options); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); + var token = opts.token, + _opts$uri = opts.uri, + uri = _opts$uri === void 0 ? '' : _opts$uri; + this.options = opts; + this.setUri(uri); + this.setToken(token); + this.konnectors = new _KonnectorCollection.default(this); + this.jobs = new _JobCollection.default(this); + } + /** + * Creates a {@link DocumentCollection} instance. + * + * @param {string} doctype The collection doctype. + * @returns {DocumentCollection} + */ -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + (0, _createClass2.default)(CozyStackClient, [{ + key: "collection", + value: function collection(doctype) { + if (!doctype) { + throw new Error('CozyStackClient.collection() called without a doctype'); + } -var TERMS_DOCTYPE = 'io.cozy.terms'; -/* TODO Use collection terms */ + switch (doctype) { + case _AppCollection.APPS_DOCTYPE: + return new _AppCollection.default(this); -function save(_x, _x2) { - return _save.apply(this, arguments); -} + case _KonnectorCollection.KONNECTORS_DOCTYPE: + return new _KonnectorCollection.default(this); -function _save() { - _save = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, terms) { - var id, termsAttributes, _yield$client$query, savedTermsDocs, savedTerms, termsToSave, _termsToSave; + case 'io.cozy.files': + return new _FileCollection.default(doctype, this); - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - id = terms.id, termsAttributes = (0, _objectWithoutProperties2.default)(terms, ["id"]); - _context.next = 3; - return client.query({ - doctype: TERMS_DOCTYPE, - selector: { - termsId: id, - version: termsAttributes.version - }, - limit: 1 - }); + case 'io.cozy.sharings': + return new _SharingCollection.default(doctype, this); - case 3: - _yield$client$query = _context.sent; - savedTermsDocs = _yield$client$query.data; + case 'io.cozy.permissions': + return new _PermissionCollection.default(doctype, this); - if (!(savedTermsDocs && savedTermsDocs.length)) { - _context.next = 13; - break; - } + case _ContactsCollection.CONTACTS_DOCTYPE: + return new _ContactsCollection.default(doctype, this); - // we just update the url if this is the same id and same version - // but the url changed - savedTerms = savedTermsDocs[0]; + case _TriggerCollection.TRIGGERS_DOCTYPE: + return new _TriggerCollection.default(this); - if (!(savedTerms.termsId == id && savedTerms.version == termsAttributes.version && savedTerms.url != termsAttributes.url)) { - _context.next = 11; - break; - } + case _JobCollection.JOBS_DOCTYPE: + return new _JobCollection.default(this); - termsToSave = _objectSpread(_objectSpread({ - _type: TERMS_DOCTYPE - }, savedTerms), {}, { - url: termsAttributes.url - }); - _context.next = 11; - return client.save(termsToSave); + case _SettingsCollection.SETTINGS_DOCTYPE: + return new _SettingsCollection.default(this); - case 11: - _context.next = 16; - break; + case _NotesCollection.NOTES_DOCTYPE: + return new _NotesCollection.default(this); - case 13: - _termsToSave = _objectSpread(_objectSpread({ - _type: TERMS_DOCTYPE - }, termsAttributes), {}, { - termsId: id, - accepted: true, - acceptedAt: new Date() - }); - _context.next = 16; - return client.save(_termsToSave); + case _OAuthClientsCollection.OAUTH_CLIENTS_DOCTYPE: + return new _OAuthClientsCollection.default(this); - case 16: - case "end": - return _context.stop(); - } + case _ShortcutsCollection.SHORTCUTS_DOCTYPE: + return new _ShortcutsCollection.default(this); + + default: + return new _DocumentCollection.default(doctype, this); } - }, _callee); - })); - return _save.apply(this, arguments); -} + } + /** + * Fetches an endpoint in an authorized way. + * + * @param {string} method The HTTP method. + * @param {string} path The URI. + * @param {object} [body] The payload. + * @param {object} [opts={}] Options for fetch + * @returns {object} + * @throws {FetchError} + */ -var _default = { - save: save -}; -exports["default"] = _default; + }, { + key: "fetch", + value: function (_fetch) { + function fetch(_x, _x2, _x3) { + return _fetch.apply(this, arguments); + } -/***/ }), -/* 599 */ -/***/ ((__unused_webpack_module, exports) => { + fetch.toString = function () { + return _fetch.toString(); + }; -"use strict"; + return fetch; + }( /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(method, path, body) { + var opts, + options, + headers, + fullPath, + fetcher, + response, + _args = arguments; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + opts = _args.length > 3 && _args[3] !== undefined ? _args[3] : {}; + options = _objectSpread({}, opts); + options.method = method; + headers = options.headers = _objectSpread({}, opts.headers); + if (method !== 'GET' && method !== 'HEAD' && body !== undefined) { + if (headers['Content-Type']) { + options.body = body; + } + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.APP_TYPE = void 0; -var APP_TYPE = { - KONNECTOR: 'konnector', - WEBAPP: 'webapp' -}; -exports.APP_TYPE = APP_TYPE; + if (!headers.Authorization) { + headers.Authorization = this.getAuthorizationHeader(); + } // the option credentials:include tells fetch to include the cookies in the + // request even for cross-origin requests -/***/ }), -/* 600 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -"use strict"; + options.credentials = 'include'; + fullPath = this.fullpath(path); + fetcher = (0, _xhrFetch.shouldXMLHTTPRequestBeUsed)(method, path, options) ? _xhrFetch.fetchWithXMLHttpRequest : fetch; + _context.prev = 9; + _context.next = 12; + return fetcher(fullPath, options); + case 12: + response = _context.sent; -var _interopRequireDefault = __webpack_require__(512); + if (!response.ok) { + this.emit('error', new _errors.FetchError(response, "".concat(response.status, " ").concat(response.statusText))); + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.Collection = exports.isDocumentUpdateConflict = exports.isNoUsableIndexError = exports.isIndexConflictError = exports.isIndexNotFoundError = exports.dontThrowNotFoundError = void 0; + return _context.abrupt("return", response); -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + case 17: + _context.prev = 17; + _context.t0 = _context["catch"](9); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); + if (isRevocationError(_context.t0)) { + this.onRevocationChange(true); + } -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + throw _context.t0; -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + case 21: + case "end": + return _context.stop(); + } + } + }, _callee, this, [[9, 17]]); + })); -/** - * Handler for error response which return a empty value for "not found" error - * - * @param {Error} error - An error - * @param {Array|object} data Data to return in case of "not found" error - * @returns {object} JsonAPI response with empty data in case of "not - * found" error. - */ -var dontThrowNotFoundError = function dontThrowNotFoundError(error) { - var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + return function (_x4, _x5, _x6) { + return _ref.apply(this, arguments); + }; + }()) + }, { + key: "onTokenRefresh", + value: function onTokenRefresh(token) { + if (this.options && this.options.onTokenRefresh) { + this.options.onTokenRefresh(token); + } + } + }, { + key: "onRevocationChange", + value: function onRevocationChange(state) { + if (this.options && this.options.onRevocationChange) { + this.options.onRevocationChange(state); + } + } + /** + * Returns whether the client has been revoked on the server + */ - if (error.message.match(/not_found/)) { - var expectsCollection = Array.isArray(data); // Return expected JsonAPI attributes : collections are expecting - // meta, skip and next attribute + }, { + key: "checkForRevocation", + value: function () { + var _checkForRevocation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.prev = 0; + _context2.next = 3; + return this.fetchInformation(); - return expectsCollection ? { - data: data, - meta: { - count: 0 - }, - skip: 0, - next: false - } : { - data: data - }; - } + case 3: + return _context2.abrupt("return", false); - throw error; -}; -/** - * Helper to identify an index not found error - * - * @param {Error} error - An error - * @returns {boolean} - Whether or not the error is an index not found error - */ + case 6: + _context2.prev = 6; + _context2.t0 = _context2["catch"](0); + return _context2.abrupt("return", isRevocationError(_context2.t0)); + case 9: + case "end": + return _context2.stop(); + } + } + }, _callee2, this, [[0, 6]]); + })); -exports.dontThrowNotFoundError = dontThrowNotFoundError; + function checkForRevocation() { + return _checkForRevocation.apply(this, arguments); + } -var isIndexNotFoundError = function isIndexNotFoundError(error) { - return error.message.match(/no_index/); -}; -/** - * Helper to identify an index conflict - * - * @param {Error} error - An error - * @returns {boolean} - Whether or not the error is an index conflict error - */ + return checkForRevocation; + }() + /** + * Retrieves a new app token by refreshing the currently used token. + * + * @throws {Error} The client should already have an access token to use this function + * @throws {Error} The client couldn't fetch a new token + * @returns {Promise} A promise that resolves with a new AccessToken object + */ + }, { + key: "refreshToken", + value: function () { + var _refreshToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { + var options, response, html, parser, doc, appNode, data, token, newToken; + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (this.token) { + _context3.next = 2; + break; + } -exports.isIndexNotFoundError = isIndexNotFoundError; + throw new Error('Cannot refresh an empty token'); -var isIndexConflictError = function isIndexConflictError(error) { - return error.message.match(/error_saving_ddoc/); -}; -/** - * Helper to identify a no usable index error - * - * @param {Error} error - An error - * @returns {boolean} - Whether or not the error is a no usable index error - */ + case 2: + options = { + method: 'GET', + credentials: 'include' + }; + + if (global.document) { + _context3.next = 5; + break; + } + throw new Error('Not in a web context, cannot refresh token'); -exports.isIndexConflictError = isIndexConflictError; + case 5: + _context3.next = 7; + return fetch('/?refreshToken', options); -var isNoUsableIndexError = function isNoUsableIndexError(error) { - return error.message.match(/no_usable_index/); -}; -/** - * Helper to identify a document conflict - * - * @param {Error} error - An error - * @returns {boolean} - Whether or not the error is a document conflict error - */ + case 7: + response = _context3.sent; + if (response.ok) { + _context3.next = 10; + break; + } -exports.isNoUsableIndexError = isNoUsableIndexError; + throw new Error("couldn't fetch a new token - response " + response.statusCode); -var isDocumentUpdateConflict = function isDocumentUpdateConflict(error) { - return error.message.match(/Document update conflict/); -}; -/** - * Utility class to abstract an regroup identical methods and logics for - * specific collections. - */ + case 10: + _context3.next = 12; + return response.text(); + case 12: + html = _context3.sent; + parser = new DOMParser(); + doc = parser.parseFromString(html, 'text/html'); -exports.isDocumentUpdateConflict = isDocumentUpdateConflict; + if (doc) { + _context3.next = 17; + break; + } -var Collection = /*#__PURE__*/function () { - function Collection() { - (0, _classCallCheck2.default)(this, Collection); - } + throw Error("couldn't fetch a new token - doc is not html"); - (0, _createClass2.default)(Collection, null, [{ - key: "get", + case 17: + appNode = doc.querySelector('div[role="application"]'); + + if (appNode) { + _context3.next = 20; + break; + } + + throw Error("couldn't fetch a new token - no div[role=application]"); + + case 20: + data = appNode.dataset.cozy ? JSON.parse(appNode.dataset.cozy) : _objectSpread({}, appNode.dataset); + token = data.token; + if (token) { + token = token || data.cozyToken; + } + + if (token) { + _context3.next = 25; + break; + } + + throw Error("couldn't fetch a new token -- missing data-cozy or data-cozy-token attribute"); + + case 25: + newToken = new _AppToken.default(token); + this.onTokenRefresh(newToken); + return _context3.abrupt("return", newToken); + + case 28: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); + + function refreshToken() { + return _refreshToken.apply(this, arguments); + } + + return refreshToken; + }() /** - * Utility method aimed to return only one document. + * Fetches JSON in an authorized way. * - * @param {CozyStackClient} stackClient - CozyStackClient - * @param {string} endpoint - Stack endpoint - * @param {object} options - Options of the collection - * @param {Function} options.normalize Callback to normalize response data - * (default `data => data`) - * @param {string} options.method HTTP method (default `GET`) - * @returns {object} JsonAPI response containing normalized - * document as data attribute + * @param {string} method The HTTP method. + * @param {string} path The URI. + * @param {object} body The payload. + * @param {object} options Options + * @returns {object} + * @throws {FetchError} */ - value: function () { - var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(stackClient, endpoint, _ref) { - var _ref$normalize, normalize, _ref$method, method, resp; - return _regenerator.default.wrap(function _callee$(_context) { + }, { + key: "fetchJSON", + value: function () { + var _fetchJSON = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(method, path, body) { + var options, + token, + _args4 = arguments; + return _regenerator.default.wrap(function _callee4$(_context4) { while (1) { - switch (_context.prev = _context.next) { + switch (_context4.prev = _context4.next) { case 0: - _ref$normalize = _ref.normalize, normalize = _ref$normalize === void 0 ? function (data, response) { - return data; - } : _ref$normalize, _ref$method = _ref.method, method = _ref$method === void 0 ? 'GET' : _ref$method; - _context.prev = 1; - _context.next = 4; - return stackClient.fetchJSON(method, endpoint); + options = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {}; + _context4.prev = 1; + _context4.next = 4; + return this.fetchJSONWithCurrentToken(method, path, body, options); case 4: - resp = _context.sent; - return _context.abrupt("return", { - data: normalize(resp.data, resp) - }); + return _context4.abrupt("return", _context4.sent); - case 8: - _context.prev = 8; - _context.t0 = _context["catch"](1); - return _context.abrupt("return", dontThrowNotFoundError(_context.t0, null)); + case 7: + _context4.prev = 7; + _context4.t0 = _context4["catch"](1); - case 11: + if (!(_errors.default.EXPIRED_TOKEN.test(_context4.t0.message) || _errors.default.INVALID_TOKEN.test(_context4.t0.message))) { + _context4.next = 25; + break; + } + + _context4.prev = 10; + _context4.next = 13; + return this.refreshToken(); + + case 13: + token = _context4.sent; + _context4.next = 19; + break; + + case 16: + _context4.prev = 16; + _context4.t1 = _context4["catch"](10); + throw _context4.t0; + + case 19: + this.setToken(token); + _context4.next = 22; + return this.fetchJSONWithCurrentToken(method, path, body, options); + + case 22: + return _context4.abrupt("return", _context4.sent); + + case 25: + throw _context4.t0; + + case 26: case "end": - return _context.stop(); + return _context4.stop(); } } - }, _callee, null, [[1, 8]]); + }, _callee4, this, [[1, 7], [10, 16]]); })); - function get(_x, _x2, _x3) { - return _get.apply(this, arguments); + function fetchJSON(_x7, _x8, _x9) { + return _fetchJSON.apply(this, arguments); } - return get; + return fetchJSON; }() - }]); - return Collection; -}(); - -exports.Collection = Collection; -var _default = Collection; -exports["default"] = _default; - -/***/ }), -/* 601 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + }, { + key: "fetchJSONWithCurrentToken", + value: function () { + var _fetchJSONWithCurrentToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(method, path, bodyArg) { + var options, + clonedOptions, + headers, + body, + resp, + contentType, + isJson, + data, + _args5 = arguments; + return _regenerator.default.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + options = _args5.length > 3 && _args5[3] !== undefined ? _args5[3] : {}; + //Since we modify the object later by adding in some case a + //content-type, let's clone this object to scope the modification + clonedOptions = (0, _cloneDeep.default)(options); + headers = clonedOptions.headers = clonedOptions.headers || {}; + headers['Accept'] = 'application/json'; + body = bodyArg; -"use strict"; + if (method !== 'GET' && method !== 'HEAD' && body !== undefined) { + if (!headers['Content-Type']) { + headers['Content-Type'] = 'application/json'; + body = JSON.stringify(body); + } + } + _context5.next = 8; + return this.fetch(method, path, body, clonedOptions); -var _interopRequireWildcard = __webpack_require__(510); + case 8: + resp = _context5.sent; + contentType = resp.headers.get('content-type'); + isJson = contentType && contentType.indexOf('json') >= 0; + _context5.next = 13; + return isJson ? resp.json() : resp.text(); -var _interopRequireDefault = __webpack_require__(512); + case 13: + data = _context5.sent; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.normalizeDoc = normalizeDoc; -exports.normalizeDoctype = exports["default"] = void 0; + if (!resp.ok) { + _context5.next = 16; + break; + } -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); + return _context5.abrupt("return", data); -var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525)); + case 16: + throw new _errors.FetchError(resp, data); -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + case 17: + case "end": + return _context5.stop(); + } + } + }, _callee5, this); + })); -var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602)); + function fetchJSONWithCurrentToken(_x10, _x11, _x12) { + return _fetchJSONWithCurrentToken.apply(this, arguments); + } -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); + return fetchJSONWithCurrentToken; + }() + }, { + key: "fullpath", + value: function fullpath(path) { + if (path.startsWith('http')) { + return path; + } else { + return this.uri + path; + } + } + }, { + key: "getAuthorizationHeader", + value: function getAuthorizationHeader() { + return this.token ? this.token.toAuthHeader() : null; + } + }, { + key: "setCredentials", + value: function setCredentials(token) { + (0, _logDeprecate.default)('CozyStackClient::setCredentials is deprecated, use CozyStackClient::setToken'); + return this.setToken(token); + } + }, { + key: "getCredentials", + value: function getCredentials() { + (0, _logDeprecate.default)('CozyStackClient::getCredentials is deprecated, use CozyStackClient::getAuthorizationHeader'); + return this.getAuthorizationHeader(); + } + /** + * Change or set the API token + * + * @param {string|AppToken|AccessToken} token - Stack API token + */ -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + }, { + key: "setToken", + value: function setToken(token) { + if (!token) { + this.token = null; + } else { + if (token.toAuthHeader) { + // AppToken or AccessToken + this.token = token; + } else if (typeof token === 'string') { + // jwt string + this.token = new _AppToken.default(token); + } else { + console.warn('Cozy-Client: Unknown token format', token); + throw new Error('Cozy-Client: Unknown token format'); + } -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + this.onRevocationChange(false); + } + } + /** + * Get the access token string, being an oauth token or an app token + * + * @returns {string} token + */ -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); + }, { + key: "getAccessToken", + value: function getAccessToken() { + return this.token && this.token.getAccessToken(); + } + }, { + key: "setUri", + value: function setUri(uri) { + this.uri = normalizeUri(uri); + } + }, { + key: "getIconURL", + value: function getIconURL(opts) { + return (0, _getIconURL2.default)(this, opts); + } + }]); + return CozyStackClient; +}(); -var _cozyFlags = _interopRequireDefault(__webpack_require__(603)); +_microee.default.mixin(CozyStackClient); -var _utils = __webpack_require__(611); +var _default = CozyStackClient; +exports["default"] = _default; -var _uniq = _interopRequireDefault(__webpack_require__(612)); +/***/ }), +/* 573 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _omit = _interopRequireDefault(__webpack_require__(613)); +var baseClone = __webpack_require__(574); -var _head = _interopRequireDefault(__webpack_require__(621)); +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; -var _startsWith = _interopRequireDefault(__webpack_require__(622)); +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} -var _qs = _interopRequireDefault(__webpack_require__(629)); +module.exports = cloneDeep; -var _mangoIndex = __webpack_require__(645); -var _Collection = _interopRequireWildcard(__webpack_require__(600)); +/***/ }), +/* 574 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var querystring = _interopRequireWildcard(__webpack_require__(647)); +var Stack = __webpack_require__(416), + arrayEach = __webpack_require__(566), + assignValue = __webpack_require__(575), + baseAssign = __webpack_require__(576), + baseAssignIn = __webpack_require__(578), + cloneBuffer = __webpack_require__(582), + copyArray = __webpack_require__(583), + copySymbols = __webpack_require__(584), + copySymbolsIn = __webpack_require__(585), + getAllKeys = __webpack_require__(435), + getAllKeysIn = __webpack_require__(588), + getTag = __webpack_require__(459), + initCloneArray = __webpack_require__(589), + initCloneByTag = __webpack_require__(590), + initCloneObject = __webpack_require__(596), + isArray = __webpack_require__(55), + isBuffer = __webpack_require__(446), + isMap = __webpack_require__(598), + isObject = __webpack_require__(52), + isSet = __webpack_require__(600), + keys = __webpack_require__(441), + keysIn = __webpack_require__(579); -var _errors = __webpack_require__(651); +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; -function _templateObject10() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design/", "/copy?rev=", ""]); +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; - _templateObject10 = function _templateObject10() { - return data; - }; +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; - return data; -} +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = +cloneableTags[boolTag] = cloneableTags[dateTag] = +cloneableTags[float32Tag] = cloneableTags[float64Tag] = +cloneableTags[int8Tag] = cloneableTags[int16Tag] = +cloneableTags[int32Tag] = cloneableTags[mapTag] = +cloneableTags[numberTag] = cloneableTags[objectTag] = +cloneableTags[regexpTag] = cloneableTags[setTag] = +cloneableTags[stringTag] = cloneableTags[symbolTag] = +cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = +cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; -function _templateObject9() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design/", "?rev=", ""]); +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; - _templateObject9 = function _templateObject9() { - return data; - }; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; - return data; -} + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : initCloneObject(value); + if (!isDeep) { + return isFlat + ? copySymbolsIn(value, baseAssignIn(result, value)) + : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); -function _templateObject8() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design_docs?include_docs=true"]); + if (isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } - _templateObject8 = function _templateObject8() { - return data; - }; + var keysFunc = isFull + ? (isFlat ? getAllKeysIn : getAllKeys) + : (isFlat ? keysIn : keys); - return data; + var props = isArr ? undefined : keysFunc(value); + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; } -function _templateObject7() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_index"]); +module.exports = baseClone; - _templateObject7 = function _templateObject7() { - return data; - }; - return data; -} +/***/ }), +/* 575 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } +var baseAssignValue = __webpack_require__(546), + eq = __webpack_require__(397); -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +/** Used for built-in method references. */ +var objectProto = Object.prototype; -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; -function _templateObject6() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "?rev=", ""]); +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } +} - _templateObject6 = function _templateObject6() { - return data; - }; +module.exports = assignValue; - return data; -} -function _templateObject5() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]); +/***/ }), +/* 576 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - _templateObject5 = function _templateObject5() { - return data; - }; +var copyObject = __webpack_require__(577), + keys = __webpack_require__(441); - return data; +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); } -function _templateObject4() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]); +module.exports = baseAssign; - _templateObject4 = function _templateObject4() { - return data; - }; - return data; -} +/***/ }), +/* 577 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _templateObject3() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_all_docs?include_docs=true"]); +var assignValue = __webpack_require__(575), + baseAssignValue = __webpack_require__(546); - _templateObject3 = function _templateObject3() { - return data; - }; +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); - return data; -} + var index = -1, + length = props.length; -function _templateObject2() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_find"]); + while (++index < length) { + var key = props[index]; - _templateObject2 = function _templateObject2() { - return data; - }; + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; - return data; + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; } -function _templateObject() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]); - - _templateObject = function _templateObject() { - return data; - }; +module.exports = copyObject; - return data; -} -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +/***/ }), +/* 578 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +var copyObject = __webpack_require__(577), + keysIn = __webpack_require__(579); -var DATABASE_DOES_NOT_EXIST = 'Database does not exist.'; /** - * Normalize a document, adding its doctype if needed + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. * - * @param {object} doc - Document to normalize - * @param {string} doctype - Document doctype - * @returns {object} normalized document * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. */ - -function normalizeDoc() { - var doc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var doctype = arguments.length > 1 ? arguments[1] : undefined; - var id = doc._id || doc.id; - return _objectSpread({ - id: id, - _id: id, - _type: doctype - }, doc); +function baseAssignIn(object, source) { + return object && copyObject(source, keysIn(source), object); } -var prepareForDeletion = function prepareForDeletion(x) { - return Object.assign({}, (0, _omit.default)(x, '_type'), { - _deleted: true - }); -}; -/** - * Abstracts a collection of documents of the same doctype, providing CRUD methods and other helpers. - */ +module.exports = baseAssignIn; -var DocumentCollection = /*#__PURE__*/function () { - function DocumentCollection(doctype, stackClient) { - (0, _classCallCheck2.default)(this, DocumentCollection); - this.doctype = doctype; - this.stackClient = stackClient; - this.indexes = {}; - this.endpoint = "/data/".concat(this.doctype, "/"); - } - /** - * Provides a callback for `Collection.get` - * - * @private - * @param {string} doctype - Document doctype - * @returns {Function} (data, response) => normalizedDocument - * using `normalizeDoc` - */ +/***/ }), +/* 579 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var arrayLikeKeys = __webpack_require__(442), + baseKeysIn = __webpack_require__(580), + isArrayLike = __webpack_require__(458); - (0, _createClass2.default)(DocumentCollection, [{ - key: "all", +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); +} - /** - * Lists all documents of the collection, without filters. - * - * The returned documents are paginated by the stack. - * - * @param {{limit, skip, bookmark, keys}} options The fetch options: pagination & fetch of specific docs. - * @returns {{data, meta, skip, bookmark, next}} The JSON API conformant response. - * @throws {FetchError} - */ - value: function () { - var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { - var _this = this; +module.exports = keysIn; - var options, - _options$limit, - limit, - _options$skip, - skip, - bookmark, - keys, - isUsingAllDocsRoute, - route, - url, - params, - path, - resp, - data, - next, - _args = arguments; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}; - _options$limit = options.limit, limit = _options$limit === void 0 ? 100 : _options$limit, _options$skip = options.skip, skip = _options$skip === void 0 ? 0 : _options$skip, bookmark = options.bookmark, keys = options.keys; // If the limit is intentionnally null, we need to use _all_docs, since - // _normal_docs uses _find and has a hard limit of 1000 +/***/ }), +/* 580 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - isUsingAllDocsRoute = !!keys || limit === null; - route = isUsingAllDocsRoute ? '_all_docs' : '_normal_docs'; - url = (0, _utils.uri)(_templateObject(), this.doctype, route); - params = { - include_docs: true, - limit: limit, - skip: skip, - keys: keys, - bookmark: bookmark - }; - path = querystring.buildURL(url, params); // If no document of this doctype exist, this route will return a 404, - // so we need to try/catch and return an empty response object in case of a 404 +var isObject = __webpack_require__(52), + isPrototype = __webpack_require__(455), + nativeKeysIn = __webpack_require__(581); - _context.prev = 7; - _context.next = 10; - return this.stackClient.fetchJSON('GET', path); +/** Used for built-in method references. */ +var objectProto = Object.prototype; - case 10: - resp = _context.sent; - _context.next = 16; - break; +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - case 13: - _context.prev = 13; - _context.t0 = _context["catch"](7); - return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0)); +/** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; - case 16: - /* If using `all_docs` we need to filter our design documents and check if - the document is not null. If we use `normal_doc` we can't have any design doc - */ - if (isUsingAllDocsRoute) { - data = resp.rows.filter(function (doc) { - return doc && doc.doc !== null && !doc.error && !(0, _startsWith.default)(doc.id, '_design'); - }).map(function (row) { - return normalizeDoc(row.doc, _this.doctype); - }); - } else { - data = resp.rows.map(function (row) { - return normalizeDoc(row, _this.doctype); - }); - } // The presence of a bookmark doesn’t guarantee that there are more results. - // See https://docs.couchdb.org/en/2.2.0/api/database/find.html#pagination + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} +module.exports = baseKeysIn; - next = bookmark ? resp.rows.length >= limit : skip + resp.rows.length < resp.total_rows; - return _context.abrupt("return", { - data: data, - meta: { - count: isUsingAllDocsRoute ? data.length : resp.total_rows - }, - skip: skip, - bookmark: resp.bookmark, - next: next - }); - case 19: - case "end": - return _context.stop(); - } - } - }, _callee, this, [[7, 13]]); - })); +/***/ }), +/* 581 */ +/***/ ((module) => { - function all() { - return _all.apply(this, arguments); - } +/** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; +} - return all; - }() - }, { - key: "fetchDocumentsWithMango", - value: function () { - var _fetchDocumentsWithMango = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(path, selector) { - var options, - _args2 = arguments; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - options = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : {}; - return _context2.abrupt("return", this.stackClient.fetchJSON('POST', path, this.toMangoOptions(selector, options))); +module.exports = nativeKeysIn; - case 2: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); - function fetchDocumentsWithMango(_x, _x2) { - return _fetchDocumentsWithMango.apply(this, arguments); - } +/***/ }), +/* 582 */ +/***/ ((module, exports, __webpack_require__) => { - return fetchDocumentsWithMango; - }() - /** - * Migrate an existing unamed index to a named one. - * - * Index migration became necessary for optimistic index, because - * we started to use named index while we used to have unamed index, - * i.e. indexes with CouchDB-generated ID. - * - * @param {object} sourceIndex - The index to migrate - * @param {string} targetIndexName - The new index name - * @private - */ +/* module decorator */ module = __webpack_require__.nmd(module); +var root = __webpack_require__(48); - }, { - key: "migrateUnamedIndex", - value: function () { - var _migrateUnamedIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(sourceIndex, targetIndexName) { - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - _context3.prev = 0; - _context3.next = 3; - return this.copyIndex(sourceIndex, targetIndexName); +/** Detect free variable `exports`. */ +var freeExports = true && exports && !exports.nodeType && exports; - case 3: - _context3.next = 5; - return this.destroyIndex(sourceIndex); +/** Detect free variable `module`. */ +var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; - case 5: - _context3.next = 16; - break; +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; - case 7: - _context3.prev = 7; - _context3.t0 = _context3["catch"](0); +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; - if ((0, _Collection.isDocumentUpdateConflict)(_context3.t0)) { - _context3.next = 11; - break; - } +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - throw _context3.t0; + buffer.copy(result); + return result; +} - case 11: - (0, _utils.sleep)(1000); - _context3.next = 14; - return this.copyIndex(sourceIndex, targetIndexName); +module.exports = cloneBuffer; - case 14: - _context3.next = 16; - return this.destroyIndex(sourceIndex); - case 16: - case "end": - return _context3.stop(); - } - } - }, _callee3, this, [[0, 7]]); - })); +/***/ }), +/* 583 */ +/***/ ((module) => { - function migrateUnamedIndex(_x3, _x4) { - return _migrateUnamedIndex.apply(this, arguments); - } +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; - return migrateUnamedIndex; - }() - /** - * Handle index creation if it is missing. - * - * When an index is missing, we first check if there is one with a different - * name but the same definition. If yes, it means we found an old unamed - * index, so we migrate it. If there is none, we create the new index. - * - * @param {object} selector The mango selector - * @param {MangoQueryOptions} options The find options - * @private - */ + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} - }, { - key: "handleMissingIndex", - value: function () { - var _handleMissingIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(selector, options) { - var indexedFields, partialFilter, existingIndex, indexName; - return _regenerator.default.wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - indexedFields = options.indexedFields, partialFilter = options.partialFilter; +module.exports = copyArray; - if (!indexedFields) { - indexedFields = (0, _mangoIndex.getIndexFields)({ - sort: options.sort, - selector: selector - }); - } - _context4.next = 4; - return this.findExistingIndex(selector, options); +/***/ }), +/* 584 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 4: - existingIndex = _context4.sent; - indexName = (0, _mangoIndex.getIndexNameFromFields)(indexedFields); +var copyObject = __webpack_require__(577), + getSymbols = __webpack_require__(438); - if (existingIndex) { - _context4.next = 11; - break; - } +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); +} - _context4.next = 9; - return this.createIndex(indexedFields, { - partialFilter: partialFilter, - indexName: indexName - }); +module.exports = copySymbols; - case 9: - _context4.next = 17; - break; - case 11: - if (!(existingIndex._id !== "_design/".concat(indexName))) { - _context4.next = 16; - break; - } +/***/ }), +/* 585 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - _context4.next = 14; - return this.migrateUnamedIndex(existingIndex, indexName); +var copyObject = __webpack_require__(577), + getSymbolsIn = __webpack_require__(586); - case 14: - _context4.next = 17; - break; +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return copyObject(source, getSymbolsIn(source), object); +} - case 16: - throw new Error("Index unusable for query, index used: ".concat(indexName)); +module.exports = copySymbolsIn; - case 17: - case "end": - return _context4.stop(); - } - } - }, _callee4, this); - })); - function handleMissingIndex(_x5, _x6) { - return _handleMissingIndex.apply(this, arguments); - } +/***/ }), +/* 586 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return handleMissingIndex; - }() - /** - * Find documents with the mango selector and create index - * if missing. - * - * We adopt an optimistic approach for index creation: - * we run the query first, and only if an index missing - * error is returned, the index is created and - * the query run again. - * - * @param {string} path The route path - * @param {object} selector The mango selector - * @param {MangoQueryOptions} options The find options - * - * @returns {object} - The find response - * @private - */ +var arrayPush = __webpack_require__(437), + getPrototype = __webpack_require__(587), + getSymbols = __webpack_require__(438), + stubArray = __webpack_require__(440); - }, { - key: "findWithMango", - value: function () { - var _findWithMango = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(path, selector) { - var options, - resp, - _args5 = arguments; - return _regenerator.default.wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - options = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : {}; - _context5.prev = 1; - _context5.next = 4; - return this.fetchDocumentsWithMango(path, selector, options); +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; - case 4: - resp = _context5.sent; - _context5.next = 18; - break; +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; +}; - case 7: - _context5.prev = 7; - _context5.t0 = _context5["catch"](1); +module.exports = getSymbolsIn; - if (!(!(0, _Collection.isIndexNotFoundError)(_context5.t0) && !(0, _Collection.isNoUsableIndexError)(_context5.t0))) { - _context5.next = 13; - break; - } - throw _context5.t0; +/***/ }), +/* 587 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 13: - _context5.next = 15; - return this.handleMissingIndex(selector, options); +var overArg = __webpack_require__(457); - case 15: - _context5.next = 17; - return this.fetchDocumentsWithMango(path, selector, options); +/** Built-in value references. */ +var getPrototype = overArg(Object.getPrototypeOf, Object); - case 17: - resp = _context5.sent; +module.exports = getPrototype; - case 18: - return _context5.abrupt("return", resp); - case 19: - case "end": - return _context5.stop(); - } - } - }, _callee5, this, [[1, 7]]); - })); +/***/ }), +/* 588 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - function findWithMango(_x7, _x8) { - return _findWithMango.apply(this, arguments); - } +var baseGetAllKeys = __webpack_require__(436), + getSymbolsIn = __webpack_require__(586), + keysIn = __webpack_require__(579); - return findWithMango; - }() - /** - * Returns a filtered list of documents using a Mango selector. - * - * The returned documents are paginated by the stack. - * - * @param {object} selector The Mango selector. - * @param {{sort, fields, limit, skip, bookmark, indexId}} options The query options. - * @returns {{data, skip, bookmark, next}} The JSON API conformant response. - * @throws {FetchError} - */ +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); +} - }, { - key: "find", - value: function () { - var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(selector) { - var _this2 = this; +module.exports = getAllKeysIn; - var options, - _options$skip2, - skip, - resp, - path, - _args6 = arguments; - return _regenerator.default.wrap(function _callee6$(_context6) { - while (1) { - switch (_context6.prev = _context6.next) { - case 0: - options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {}; - _options$skip2 = options.skip, skip = _options$skip2 === void 0 ? 0 : _options$skip2; - _context6.prev = 2; - path = (0, _utils.uri)(_templateObject2(), this.doctype); - _context6.next = 6; - return this.findWithMango(path, selector, options); +/***/ }), +/* 589 */ +/***/ ((module) => { - case 6: - resp = _context6.sent; - _context6.next = 12; - break; +/** Used for built-in method references. */ +var objectProto = Object.prototype; - case 9: - _context6.prev = 9; - _context6.t0 = _context6["catch"](2); - return _context6.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context6.t0)); +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - case 12: - return _context6.abrupt("return", { - data: resp.docs.map(function (doc) { - return normalizeDoc(doc, _this2.doctype); - }), - next: resp.next, - skip: skip, - bookmark: resp.bookmark, - execution_stats: resp.execution_stats - }); +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); - case 13: - case "end": - return _context6.stop(); - } - } - }, _callee6, this, [[2, 9]]); - })); + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} - function find(_x9) { - return _find.apply(this, arguments); - } +module.exports = initCloneArray; - return find; - }() - /** - * Get a document by id - * - * @param {string} id The document id. - * @returns {object} JsonAPI response containing normalized document as data attribute - */ - }, { - key: "get", - value: function () { - var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(id) { - return _regenerator.default.wrap(function _callee7$(_context7) { - while (1) { - switch (_context7.prev = _context7.next) { - case 0: - return _context7.abrupt("return", _Collection.default.get(this.stackClient, "".concat(this.endpoint).concat(encodeURIComponent(id)), { - normalize: this.constructor.normalizeDoctype(this.doctype) - })); +/***/ }), +/* 590 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 1: - case "end": - return _context7.stop(); - } - } - }, _callee7, this); - })); +var cloneArrayBuffer = __webpack_require__(591), + cloneDataView = __webpack_require__(592), + cloneRegExp = __webpack_require__(593), + cloneSymbol = __webpack_require__(594), + cloneTypedArray = __webpack_require__(595); - function get(_x10) { - return _get.apply(this, arguments); - } +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; - return get; - }() - /** - * Get many documents by id - */ +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; - }, { - key: "getAll", - value: function () { - var _getAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(ids) { - var _this3 = this; +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); - var resp, rows; - return _regenerator.default.wrap(function _callee8$(_context8) { - while (1) { - switch (_context8.prev = _context8.next) { - case 0: - _context8.prev = 0; - _context8.next = 3; - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject3(), this.doctype), { - keys: ids - }); + case boolTag: + case dateTag: + return new Ctor(+object); - case 3: - resp = _context8.sent; - _context8.next = 9; - break; + case dataViewTag: + return cloneDataView(object, isDeep); - case 6: - _context8.prev = 6; - _context8.t0 = _context8["catch"](0); - return _context8.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context8.t0)); + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); - case 9: - rows = resp.rows.filter(function (row) { - return row.doc; - }); - return _context8.abrupt("return", { - data: rows.map(function (row) { - return normalizeDoc(row.doc, _this3.doctype); - }), - meta: { - count: rows.length - } - }); + case mapTag: + return new Ctor; - case 11: - case "end": - return _context8.stop(); - } - } - }, _callee8, this, [[0, 6]]); - })); + case numberTag: + case stringTag: + return new Ctor(object); - function getAll(_x11) { - return _getAll.apply(this, arguments); - } + case regexpTag: + return cloneRegExp(object); - return getAll; - }() - /** - * Creates a document - * - * @param {object} doc - Document to create. Optional: you can force the id with the _id attribute - */ + case setTag: + return new Ctor; - }, { - key: "create", - value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(_ref) { - var _id, _type, document, hasFixedId, method, endpoint, resp; + case symbolTag: + return cloneSymbol(object); + } +} - return _regenerator.default.wrap(function _callee9$(_context9) { - while (1) { - switch (_context9.prev = _context9.next) { - case 0: - _id = _ref._id, _type = _ref._type, document = (0, _objectWithoutProperties2.default)(_ref, ["_id", "_type"]); - // In case of a fixed id, let's use the dedicated creation endpoint - // https://github.com/cozy/cozy-stack/blob/master/docs/data-system.md#create-a-document-with-a-fixed-id - hasFixedId = !!_id; - method = hasFixedId ? 'PUT' : 'POST'; - endpoint = (0, _utils.uri)(_templateObject4(), this.doctype, hasFixedId ? _id : ''); - _context9.next = 6; - return this.stackClient.fetchJSON(method, endpoint, document); +module.exports = initCloneByTag; - case 6: - resp = _context9.sent; - return _context9.abrupt("return", { - data: normalizeDoc(resp.data, this.doctype) - }); - case 8: - case "end": - return _context9.stop(); - } - } - }, _callee9, this); - })); +/***/ }), +/* 591 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - function create(_x12) { - return _create.apply(this, arguments); - } +var Uint8Array = __webpack_require__(431); - return create; - }() - /** - * Updates a document - * - * @param {object} document - Document to update. Do not forget the _id attribute - */ +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} - }, { - key: "update", - value: function () { - var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(document) { - var resp; - return _regenerator.default.wrap(function _callee10$(_context10) { - while (1) { - switch (_context10.prev = _context10.next) { - case 0: - _context10.next = 2; - return this.stackClient.fetchJSON('PUT', (0, _utils.uri)(_templateObject5(), this.doctype, document._id), document); +module.exports = cloneArrayBuffer; - case 2: - resp = _context10.sent; - return _context10.abrupt("return", { - data: normalizeDoc(resp.data, this.doctype) - }); - case 4: - case "end": - return _context10.stop(); - } - } - }, _callee10, this); - })); +/***/ }), +/* 592 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - function update(_x13) { - return _update.apply(this, arguments); - } +var cloneArrayBuffer = __webpack_require__(591); - return update; - }() - /** - * Destroys a document - * - * @param {object} doc - Document to destroy. Do not forget _id and _rev attributes - */ +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} - }, { - key: "destroy", - value: function () { - var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(_ref2) { - var _id, _rev, document, resp; +module.exports = cloneDataView; - return _regenerator.default.wrap(function _callee11$(_context11) { - while (1) { - switch (_context11.prev = _context11.next) { - case 0: - _id = _ref2._id, _rev = _ref2._rev, document = (0, _objectWithoutProperties2.default)(_ref2, ["_id", "_rev"]); - _context11.next = 3; - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), this.doctype, _id, _rev)); - case 3: - resp = _context11.sent; - return _context11.abrupt("return", { - data: normalizeDoc(_objectSpread(_objectSpread({}, document), {}, { - _id: _id, - _rev: resp.rev, - _deleted: true - }), this.doctype) - }); +/***/ }), +/* 593 */ +/***/ ((module) => { - case 5: - case "end": - return _context11.stop(); - } - } - }, _callee11, this); - })); +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; - function destroy(_x14) { - return _destroy.apply(this, arguments); - } +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} - return destroy; - }() - /** - * Updates several documents in one batch - * - * @param {Document[]} rawDocs Documents to be updated - */ +module.exports = cloneRegExp; - }, { - key: "updateAll", - value: function () { - var _updateAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(rawDocs) { - var stackClient, docs, update, firstDoc, resp; - return _regenerator.default.wrap(function _callee12$(_context12) { - while (1) { - switch (_context12.prev = _context12.next) { - case 0: - stackClient = this.stackClient; - docs = rawDocs ? rawDocs.map(function (d) { - return (0, _omit.default)(d, '_type'); - }) : rawDocs; - if (!(!docs || !docs.length)) { - _context12.next = 4; - break; - } +/***/ }), +/* 594 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return _context12.abrupt("return", Promise.resolve([])); +var Symbol = __webpack_require__(47); - case 4: - _context12.prev = 4; - _context12.next = 7; - return stackClient.fetchJSON('POST', "/data/".concat(this.doctype, "/_bulk_docs"), { - docs: docs - }); +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; - case 7: - update = _context12.sent; - return _context12.abrupt("return", update); +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} - case 11: - _context12.prev = 11; - _context12.t0 = _context12["catch"](4); +module.exports = cloneSymbol; - if (!(_context12.t0.reason && _context12.t0.reason.reason && _context12.t0.reason.reason === DATABASE_DOES_NOT_EXIST)) { - _context12.next = 24; - break; - } - _context12.next = 16; - return this.create(docs[0]); +/***/ }), +/* 595 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 16: - firstDoc = _context12.sent; - _context12.next = 19; - return this.updateAll(docs.slice(1)); +var cloneArrayBuffer = __webpack_require__(591); - case 19: - resp = _context12.sent; - resp.unshift({ - ok: true, - id: firstDoc._id, - rev: firstDoc._rev - }); - return _context12.abrupt("return", resp); +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} - case 24: - throw _context12.t0; +module.exports = cloneTypedArray; - case 25: - case "end": - return _context12.stop(); - } - } - }, _callee12, this, [[4, 11]]); - })); - function updateAll(_x15) { - return _updateAll.apply(this, arguments); - } +/***/ }), +/* 596 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return updateAll; - }() - /** - * Deletes several documents in one batch - * - * @param {Document[]} docs - Documents to delete - */ +var baseCreate = __webpack_require__(597), + getPrototype = __webpack_require__(587), + isPrototype = __webpack_require__(455); - }, { - key: "destroyAll", - value: function destroyAll(docs) { - return this.updateAll(docs.map(prepareForDeletion)); - } - }, { - key: "toMangoOptions", - value: function toMangoOptions(selector) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var sort = options.sort, - indexedFields = options.indexedFields; - var fields = options.fields, - _options$skip3 = options.skip, - skip = _options$skip3 === void 0 ? 0 : _options$skip3, - limit = options.limit, - bookmark = options.bookmark; - sort = (0, _mangoIndex.transformSort)(sort); - indexedFields = indexedFields ? indexedFields : (0, _mangoIndex.getIndexFields)({ - sort: sort, - selector: selector - }); - var indexName = options.indexId || "_design/".concat((0, _mangoIndex.getIndexNameFromFields)(indexedFields)); +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; +} - if (sort) { - var sortOrders = (0, _uniq.default)(sort.map(function (sortOption) { - return (0, _head.default)(Object.values(sortOption)); - })); - if (sortOrders.length > 1) throw new Error('Mango sort can only use a single order (asc or desc).'); - var sortOrder = sortOrders.length > 0 ? (0, _head.default)(sortOrders) : 'asc'; +module.exports = initCloneObject; - var _iterator = _createForOfIteratorHelper(indexedFields), - _step; - try { - var _loop = function _loop() { - var field = _step.value; - if (!sort.find(function (sortOption) { - return (0, _head.default)(Object.keys(sortOption)) === field; - })) sort.push((0, _defineProperty2.default)({}, field, sortOrder)); - }; +/***/ }), +/* 597 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - _loop(); - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } - } +var isObject = __webpack_require__(52); - var opts = { - selector: selector, - use_index: indexName, - // TODO: type and class should not be necessary, it's just a temp fix for a stack bug - fields: fields ? [].concat((0, _toConsumableArray2.default)(fields), ['_id', '_type', 'class']) : undefined, - limit: limit, - skip: skip, - bookmark: options.bookmark || bookmark, - sort: sort, - execution_stats: (0, _cozyFlags.default)('debug') ? true : undefined - }; - return opts; +/** Built-in value references. */ +var objectCreate = Object.create; + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ +var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; } - }, { - key: "checkUniquenessOf", - value: function () { - var _checkUniquenessOf = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(property, value) { - var indexId, existingDocs; - return _regenerator.default.wrap(function _callee13$(_context13) { - while (1) { - switch (_context13.prev = _context13.next) { - case 0: - _context13.next = 2; - return this.getUniqueIndexId(property); + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; +}()); - case 2: - indexId = _context13.sent; - _context13.next = 5; - return this.find((0, _defineProperty2.default)({}, property, value), { - indexId: indexId, - fields: ['_id'] - }); +module.exports = baseCreate; - case 5: - existingDocs = _context13.sent; - return _context13.abrupt("return", existingDocs.data.length === 0); - case 7: - case "end": - return _context13.stop(); - } - } - }, _callee13, this); - })); +/***/ }), +/* 598 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - function checkUniquenessOf(_x16, _x17) { - return _checkUniquenessOf.apply(this, arguments); - } +var baseIsMap = __webpack_require__(599), + baseUnary = __webpack_require__(452), + nodeUtil = __webpack_require__(453); - return checkUniquenessOf; - }() - }, { - key: "getUniqueIndexId", - value: function getUniqueIndexId(property) { - return this.getIndexId([property], { - indexName: "".concat(this.doctype, "/").concat(property) - }); - } - }, { - key: "getIndexId", - value: function () { - var _getIndexId = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(fields, _ref3) { - var partialFilter, _ref3$indexName, indexName, index; +/* Node.js helper references. */ +var nodeIsMap = nodeUtil && nodeUtil.isMap; - return _regenerator.default.wrap(function _callee14$(_context14) { - while (1) { - switch (_context14.prev = _context14.next) { - case 0: - partialFilter = _ref3.partialFilter, _ref3$indexName = _ref3.indexName, indexName = _ref3$indexName === void 0 ? this.getIndexNameFromFields(fields) : _ref3$indexName; +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; - if (this.indexes[indexName]) { - _context14.next = 20; - break; - } +module.exports = isMap; - _context14.prev = 2; - _context14.next = 5; - return this.createIndex(fields, { - partialFilter: partialFilter - }); - case 5: - index = _context14.sent; - _context14.next = 19; - break; +/***/ }), +/* 599 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 8: - _context14.prev = 8; - _context14.t0 = _context14["catch"](2); +var getTag = __webpack_require__(459), + isObjectLike = __webpack_require__(53); - if ((0, _Collection.isIndexConflictError)(_context14.t0)) { - _context14.next = 14; - break; - } +/** `Object#toString` result references. */ +var mapTag = '[object Map]'; - throw _context14.t0; +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; +} - case 14: - _context14.next = 16; - return (0, _utils.sleep)(1000); +module.exports = baseIsMap; - case 16: - _context14.next = 18; - return this.createIndex(fields, { - partialFilter: partialFilter - }); - case 18: - index = _context14.sent; +/***/ }), +/* 600 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 19: - this.indexes[indexName] = index; +var baseIsSet = __webpack_require__(601), + baseUnary = __webpack_require__(452), + nodeUtil = __webpack_require__(453); - case 20: - return _context14.abrupt("return", this.indexes[indexName].id); +/* Node.js helper references. */ +var nodeIsSet = nodeUtil && nodeUtil.isSet; - case 21: - case "end": - return _context14.stop(); - } - } - }, _callee14, this, [[2, 8]]); - })); +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; - function getIndexId(_x18, _x19) { - return _getIndexId.apply(this, arguments); - } +module.exports = isSet; - return getIndexId; - }() - }, { - key: "createIndex", - value: function () { - var _createIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(fields) { - var _ref4, - partialFilter, - indexName, - indexDef, - resp, - indexResp, - selector, - options, - _args15 = arguments; - return _regenerator.default.wrap(function _callee15$(_context15) { - while (1) { - switch (_context15.prev = _context15.next) { - case 0: - _ref4 = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : {}, partialFilter = _ref4.partialFilter, indexName = _ref4.indexName; - indexDef = { - index: { - fields: fields - } - }; +/***/ }), +/* 601 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (indexName) { - indexDef.ddoc = indexName; - } +var getTag = __webpack_require__(459), + isObjectLike = __webpack_require__(53); - if (partialFilter) { - indexDef.index.partial_filter_selector = partialFilter; - } +/** `Object#toString` result references. */ +var setTag = '[object Set]'; - _context15.prev = 4; - _context15.next = 7; - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject7(), this.doctype), indexDef); +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return isObjectLike(value) && getTag(value) == setTag; +} - case 7: - resp = _context15.sent; - _context15.next = 17; - break; +module.exports = baseIsSet; - case 10: - _context15.prev = 10; - _context15.t0 = _context15["catch"](4); - if ((0, _Collection.isIndexConflictError)(_context15.t0)) { - _context15.next = 16; - break; - } +/***/ }), +/* 602 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - throw _context15.t0; +"use strict"; - case 16: - return _context15.abrupt("return"); - case 17: - indexResp = { - id: resp.id, - fields: fields - }; +var _interopRequireWildcard = __webpack_require__(522); - if (!(resp.result === 'exists')) { - _context15.next = 20; - break; - } +var _interopRequireDefault = __webpack_require__(524); - return _context15.abrupt("return", indexResp); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.normalizeApp = exports.APPS_DOCTYPE = void 0; - case 20: - // indexes might not be usable right after being created; so we delay the resolving until they are - selector = {}; - fields.forEach(function (f) { - return selector[f] = { - $gt: null - }; - }); - options = { - indexId: indexResp.id, - limit: 1 - }; - _context15.next = 25; - return (0, _utils.attempt)(this.find(selector, options)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - case 25: - if (!_context15.sent) { - _context15.next = 27; - break; - } +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - return _context15.abrupt("return", indexResp); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - case 27: - _context15.next = 29; - return (0, _utils.sleep)(1000); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - case 29: - _context15.next = 31; - return (0, _utils.attempt)(this.find(selector, options)); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); - case 31: - if (!_context15.sent) { - _context15.next = 33; - break; - } +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); - return _context15.abrupt("return", indexResp); +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); - case 33: - _context15.next = 35; - return (0, _utils.sleep)(500); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); - case 35: - return _context15.abrupt("return", indexResp); +var _get3 = _interopRequireDefault(__webpack_require__(370)); - case 36: - case "end": - return _context15.stop(); - } - } - }, _callee15, this, [[4, 10]]); - })); +var _registry = __webpack_require__(608); - function createIndex(_x20) { - return _createIndex.apply(this, arguments); - } +var _Collection = _interopRequireDefault(__webpack_require__(612)); - return createIndex; - }() - /** - * Retrieve all design docs of mango indexes - * - * @returns {Array} The design docs - */ +var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613)); - }, { - key: "fetchAllMangoIndexes", - value: function () { - var _fetchAllMangoIndexes = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16() { - var path, indexes; - return _regenerator.default.wrap(function _callee16$(_context16) { - while (1) { - switch (_context16.prev = _context16.next) { - case 0: - path = (0, _utils.uri)(_templateObject8(), this.doctype); - _context16.next = 3; - return this.stackClient.fetchJSON('GET', path); +var _errors = __webpack_require__(663); - case 3: - indexes = _context16.sent; - return _context16.abrupt("return", indexes.rows.filter(function (index) { - return index.doc.language === 'query'; - }).map(function (doc) { - return (0, _mangoIndex.normalizeDesignDoc)(doc); - })); +function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } - case 5: - case "end": - return _context16.stop(); - } - } - }, _callee16, this); - })); +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - function fetchAllMangoIndexes() { - return _fetchAllMangoIndexes.apply(this, arguments); - } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - return fetchAllMangoIndexes; - }() - /** - * Delete the specified design doc - * - * @param {object} index - The design doc to remove - * @returns {object} The delete response - */ +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } - }, { - key: "destroyIndex", - value: function () { - var _destroyIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(index) { - var ddoc, rev, path; - return _regenerator.default.wrap(function _callee17$(_context17) { - while (1) { - switch (_context17.prev = _context17.next) { - case 0: - ddoc = index._id.split('/')[1]; - rev = index._rev; - path = (0, _utils.uri)(_templateObject9(), this.doctype, ddoc, rev); - return _context17.abrupt("return", this.stackClient.fetchJSON('DELETE', path)); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - case 4: - case "end": - return _context17.stop(); - } - } - }, _callee17, this); - })); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - function destroyIndex(_x21) { - return _destroyIndex.apply(this, arguments); - } +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - return destroyIndex; - }() - /** - * Copy an existing design doc. - * - * This is useful to create a new design doc without - * having to recompute the existing index. - * - * @param {object} existingIndex - The design doc to copy - * @param {string} newIndexName - The name of the copy - * @returns {object} The copy response - */ +var APPS_DOCTYPE = 'io.cozy.apps'; +exports.APPS_DOCTYPE = APPS_DOCTYPE; - }, { - key: "copyIndex", - value: function () { - var _copyIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(existingIndex, newIndexName) { - var ddoc, rev, path, options; - return _regenerator.default.wrap(function _callee18$(_context18) { - while (1) { - switch (_context18.prev = _context18.next) { - case 0: - ddoc = existingIndex._id.split('/')[1]; - rev = existingIndex._rev; - path = (0, _utils.uri)(_templateObject10(), this.doctype, ddoc, rev); - options = { - headers: { - Destination: "_design/".concat(newIndexName) - } - }; - return _context18.abrupt("return", this.stackClient.fetchJSON('POST', path, null, options)); +var normalizeApp = function normalizeApp(app, doctype) { + return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, app.attributes), app), (0, _DocumentCollection2.normalizeDoc)(app, doctype)), {}, { + id: app.id // ignores any 'id' attribute in the manifest - case 5: - case "end": - return _context18.stop(); - } - } - }, _callee18, this); - })); + }); +}; +/** + * Extends `DocumentCollection` API along with specific methods for `io.cozy.apps`. + */ - function copyIndex(_x22, _x23) { - return _copyIndex.apply(this, arguments); - } - return copyIndex; - }() - /** - * Find an existing mango index based on the query definition - * - * This is useful to avoid creating new indexes having the - * same definition of an existing one. - * - * @param {object} selector The query selector - * @param {MangoQueryOptions} options The find options - * - * @returns {object} A matching index if it exists - * @private - */ +exports.normalizeApp = normalizeApp; - }, { - key: "findExistingIndex", +var AppCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(AppCollection, _DocumentCollection); + + var _super = _createSuper(AppCollection); + + function AppCollection(stackClient) { + var _this; + + (0, _classCallCheck2.default)(this, AppCollection); + _this = _super.call(this, APPS_DOCTYPE, stackClient); + _this.endpoint = '/apps/'; + return _this; + } + + (0, _createClass2.default)(AppCollection, [{ + key: "get", value: function () { - var _findExistingIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(selector, options) { - var sort, indexedFields, partialFilter, indexes, fieldsToIndex, existingIndex, _iterator2, _step2, index; + var _get2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(idArg, query) { + var _this2 = this; - return _regenerator.default.wrap(function _callee19$(_context19) { + var id, sources, dataFetchers, _iterator, _step, source, res, data, normalizedDoc; + + return _regenerator.default.wrap(function _callee$(_context) { while (1) { - switch (_context19.prev = _context19.next) { + switch (_context.prev = _context.next) { case 0: - sort = options.sort, indexedFields = options.indexedFields, partialFilter = options.partialFilter; - _context19.next = 3; - return this.fetchAllMangoIndexes(); + if (idArg.indexOf('/') > -1) { + id = idArg.split('/')[1]; + } else { + console.warn("Deprecated: in next versions of cozy-client, it will not be possible to query apps/konnectors only with id, please use the form ".concat(this.doctype, "/").concat(idArg, "\n\n- Q('io.cozy.apps').getById('banks')\n+ Q('io.cozy.apps').getById('io.cozy.apps/banks')")); + id = idArg; + } + + if (!(query && query.sources && (!Array.isArray(query.sources) || query.sources.length === 0))) { + _context.next = 3; + break; + } + + throw new Error('Invalid "sources" attribute passed in query, please use an array with at least one element.'); case 3: - indexes = _context19.sent; + sources = (0, _get3.default)(query, 'sources', ['stack']); + dataFetchers = { + stack: function stack() { + return _Collection.default.get(_this2.stackClient, "".concat(_this2.endpoint).concat(encodeURIComponent(id)), { + normalize: _this2.constructor.normalizeDoctype(_this2.doctype) + }); + }, + registry: function registry() { + return _this2.stackClient.fetchJSON('GET', _registry.registryEndpoint + id); + } + }; + _iterator = _createForOfIteratorHelper(sources); + _context.prev = 6; - if (!(indexes.length < 1)) { - _context19.next = 6; + _iterator.s(); + + case 8: + if ((_step = _iterator.n()).done) { + _context.next = 27; break; } - return _context19.abrupt("return", null); - - case 6: - sort = (0, _mangoIndex.transformSort)(sort); - fieldsToIndex = indexedFields ? indexedFields : (0, _mangoIndex.getIndexFields)({ - sort: sort, - selector: selector - }); - existingIndex = indexes.find(function (index) { - return (0, _mangoIndex.isMatchingIndex)(index, fieldsToIndex, partialFilter); - }); - _iterator2 = _createForOfIteratorHelper(indexes); - _context19.prev = 10; + source = _step.value; + _context.prev = 10; + _context.next = 13; + return dataFetchers[source](); - _iterator2.s(); + case 13: + res = _context.sent; - case 12: - if ((_step2 = _iterator2.n()).done) { - _context19.next = 19; + if (!(source !== 'registry')) { + _context.next = 16; break; } - index = _step2.value; + return _context.abrupt("return", res); - if (!(0, _mangoIndex.isInconsistentIndex)(index)) { - _context19.next = 17; + case 16: + data = (0, _registry.transformRegistryFormatToStackFormat)(res); + normalizedDoc = (0, _DocumentCollection2.normalizeDoc)(data, this.doctype); + return _context.abrupt("return", { + data: normalizedDoc + }); + + case 21: + _context.prev = 21; + _context.t0 = _context["catch"](10); + + if (!(source === sources[sources.length - 1])) { + _context.next = 25; break; } - _context19.next = 17; - return this.destroyIndex(index); + throw _context.t0; - case 17: - _context19.next = 12; + case 25: + _context.next = 8; break; - case 19: - _context19.next = 24; + case 27: + _context.next = 32; break; - case 21: - _context19.prev = 21; - _context19.t0 = _context19["catch"](10); - - _iterator2.e(_context19.t0); + case 29: + _context.prev = 29; + _context.t1 = _context["catch"](6); - case 24: - _context19.prev = 24; + _iterator.e(_context.t1); - _iterator2.f(); + case 32: + _context.prev = 32; - return _context19.finish(24); + _iterator.f(); - case 27: - return _context19.abrupt("return", existingIndex); + return _context.finish(32); - case 28: + case 35: case "end": - return _context19.stop(); + return _context.stop(); } } - }, _callee19, this, [[10, 21, 24, 27]]); + }, _callee, this, [[6, 29, 32, 35], [10, 21]]); })); - function findExistingIndex(_x24, _x25) { - return _findExistingIndex.apply(this, arguments); + function get(_x, _x2) { + return _get2.apply(this, arguments); } - return findExistingIndex; + return get; }() /** - * Calls _changes route from CouchDB - * No further treatment is done contrary to fetchchanges + * Lists all apps, without filters. * - * @param {object} couchOptions - Couch options for changes https://kutt.it/5r7MNQ - * @param {string} [couchOptions.since] - Bookmark telling CouchDB from which point in time should changes be returned - * @param {Array<string>} [couchOptions.doc_ids] - Only return changes for a subset of documents - * @param {boolean} [couchOptions.includeDocs] - Includes full documents as part of results + * The returned documents are not paginated by the stack. * - * @see https://docs.couchdb.org/en/stable/api/database/changes.html + * @returns {{data, meta, skip, next}} The JSON API conformant response. + * @throws {FetchError} */ }, { - key: "fetchChangesRaw", + key: "all", value: function () { - var _fetchChangesRaw = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20(couchOptions) { - var hasDocIds, urlParams, method, endpoint, params, result; - return _regenerator.default.wrap(function _callee20$(_context20) { + var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { + var _this3 = this; + + var resp; + return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { - switch (_context20.prev = _context20.next) { + switch (_context2.prev = _context2.next) { case 0: - hasDocIds = couchOptions.doc_ids && couchOptions.doc_ids.length > 0; - urlParams = "?".concat([_qs.default.stringify(_objectSpread(_objectSpread({}, (0, _omit.default)(couchOptions, ['doc_ids', 'includeDocs'])), {}, { - include_docs: couchOptions.includeDocs - })), hasDocIds && couchOptions.filter === undefined ? 'filter=_doc_ids' : undefined].filter(Boolean).join('&')); - method = hasDocIds ? 'POST' : 'GET'; - endpoint = "/data/".concat(this.doctype, "/_changes").concat(urlParams); - params = hasDocIds ? { - doc_ids: couchOptions.doc_ids - } : undefined; - _context20.next = 7; - return this.stackClient.fetchJSON(method, endpoint, params); + _context2.next = 2; + return this.stackClient.fetchJSON('GET', this.endpoint); - case 7: - result = _context20.sent; - return _context20.abrupt("return", result); + case 2: + resp = _context2.sent; + return _context2.abrupt("return", { + data: resp.data.map(function (app) { + return normalizeApp(app, _this3.doctype); + }), + meta: { + count: resp.meta.count + }, + skip: 0, + next: false + }); - case 9: + case 4: case "end": - return _context20.stop(); + return _context2.stop(); } } - }, _callee20, this); + }, _callee2, this); })); - function fetchChangesRaw(_x26) { - return _fetchChangesRaw.apply(this, arguments); + function all() { + return _all.apply(this, arguments); } - return fetchChangesRaw; + return all; }() - /** - * Use Couch _changes API - * Deleted and design docs are filtered by default, thus documents are retrieved in the response - * (include_docs is set to true in the parameters of _changes). - * - * You should use fetchChangesRaw to have low level control on _changes parameters. - * - * @param {object} couchOptions - Couch options for changes - * @param {string} [couchOptions.since] - Bookmark telling CouchDB from which point in time should changes be returned - * @param {Array<string>} [couchOptions.doc_ids] - Only return changes for a subset of documents - * - * @param {object} options - Further options on the returned documents. By default, it is set to { includeDesign: false, includeDeleted: false } - * @param {boolean} [options.includeDesign] - Whether to include changes from design docs (needs include_docs to be true) - * @param {boolean} [options.includeDeleted] - Whether to include changes for deleted documents (needs include_docs to be true) - * - * @typedef {object} FetchChangesReturnValue - * @property {string} newLastSeq - * @property {Array<object>} documents - * @returns {FetchChangesReturnValue} - */ - }, { - key: "fetchChanges", + key: "create", value: function () { - var _fetchChanges = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21() { - var couchOptions, - options, - opts, - result, - newLastSeq, - docs, - _args21 = arguments; - return _regenerator.default.wrap(function _callee21$(_context21) { + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { + return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { - switch (_context21.prev = _context21.next) { + switch (_context3.prev = _context3.next) { case 0: - couchOptions = _args21.length > 0 && _args21[0] !== undefined ? _args21[0] : {}; - options = _args21.length > 1 && _args21[1] !== undefined ? _args21[1] : {}; - opts = { - // Necessary since we deal with deleted and design docs later - includeDocs: true - }; - - if (typeof couchOptions !== 'object') { - opts.since = couchOptions; - console.warn("fetchChanges use couchOptions as Object not a string, since is deprecated, please use fetchChanges({since: \"".concat(couchOptions, "\"}).")); - } else if (Object.keys(couchOptions).length > 0) { - Object.assign(opts, couchOptions); - } - - _context21.next = 6; - return this.fetchChangesRaw(opts); - - case 6: - result = _context21.sent; - newLastSeq = result.last_seq; - docs = result.results.map(function (x) { - return x.doc; - }).filter(Boolean); + throw new Error('create() method is not available for applications'); - if (!options.includeDesign) { - docs = docs.filter(function (doc) { - return doc._id.indexOf('_design') !== 0; - }); - } + case 1: + case "end": + return _context3.stop(); + } + } + }, _callee3); + })); - if (!options.includeDeleted) { - docs = docs.filter(function (doc) { - return !doc._deleted; - }); - } + function create() { + return _create.apply(this, arguments); + } - return _context21.abrupt("return", { - newLastSeq: newLastSeq, - documents: docs - }); + return create; + }() + }, { + key: "update", + value: function () { + var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() { + return _regenerator.default.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + throw new Error('update() method is not available for applications'); - case 12: + case 1: case "end": - return _context21.stop(); + return _context4.stop(); } } - }, _callee21, this); + }, _callee4); })); - function fetchChanges() { - return _fetchChanges.apply(this, arguments); + function update() { + return _update.apply(this, arguments); } - return fetchChanges; + return update; }() - }], [{ - key: "normalizeDoctype", - value: function normalizeDoctype(doctype) { - return this.normalizeDoctypeRawApi(doctype); - } - /** - * `normalizeDoctype` for api end points returning json api responses - * - * @private - * @param {string} doctype - Document doctype - * @returns {Function} (data, response) => normalizedDocument - * using `normalizeDoc` - */ - }, { - key: "normalizeDoctypeJsonApi", - value: function normalizeDoctypeJsonApi(doctype) { - return function (data, response) { - // use the "data" attribute of the response - return normalizeDoc(data, doctype); - }; - } - /** - * `normalizeDoctype` for api end points returning raw documents - * - * @private - * @param {string} doctype - Document doctype - * @returns {Function} (data, response) => normalizedDocument - * using `normalizeDoc` - */ + key: "destroy", + value: function () { + var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() { + return _regenerator.default.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + throw new Error('destroy() method is not available for applications'); - }, { - key: "normalizeDoctypeRawApi", - value: function normalizeDoctypeRawApi(doctype) { - return function (data, response) { - // use the response directly - return normalizeDoc(response, doctype); - }; - } + case 1: + case "end": + return _context5.stop(); + } + } + }, _callee5); + })); + + function destroy() { + return _destroy.apply(this, arguments); + } + + return destroy; + }() }]); - return DocumentCollection; -}(); + return AppCollection; +}(_DocumentCollection2.default); -var _default = DocumentCollection; +AppCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; +var _default = AppCollection; exports["default"] = _default; -var normalizeDoctype = DocumentCollection.normalizeDoctype; -exports.normalizeDoctype = normalizeDoctype; /***/ }), -/* 602 */ -/***/ ((module) => { +/* 603 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _taggedTemplateLiteral(strings, raw) { - if (!raw) { - raw = strings.slice(0); +var setPrototypeOf = __webpack_require__(604); + +function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function"); } - return Object.freeze(Object.defineProperties(strings, { - raw: { - value: Object.freeze(raw) + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true } - })); + }); + if (superClass) setPrototypeOf(subClass, superClass); } -module.exports = _taggedTemplateLiteral; +module.exports = _inherits; module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), -/* 603 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +/* 604 */ +/***/ ((module) => { -var _flag = _interopRequireDefault(__webpack_require__(604)); +function _setPrototypeOf(o, p) { + module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; -/* global __ENABLED_FLAGS__ */ -if (typeof __ENABLED_FLAGS__ !== 'undefined') { - _flag.default.enable(__ENABLED_FLAGS__); + module.exports["default"] = module.exports, module.exports.__esModule = true; + return _setPrototypeOf(o, p); } -var _default = _flag.default; -exports["default"] = _default; +module.exports = _setPrototypeOf; +module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), -/* 604 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; +/* 605 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _typeof = (__webpack_require__(523)["default"]); -var _interopRequireDefault = __webpack_require__(512); +var assertThisInitialized = __webpack_require__(606); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.initialize = exports.initializeFromDOM = exports.getTemplateData = exports.initializeFromRemote = exports.enable = exports.resetFlags = exports.listFlags = void 0; +function _possibleConstructorReturn(self, call) { + if (call && (_typeof(call) === "object" || typeof call === "function")) { + return call; + } else if (call !== void 0) { + throw new TypeError("Derived constructors may only return object or undefined"); + } -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + return assertThisInitialized(self); +} -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +module.exports = _possibleConstructorReturn; +module.exports["default"] = module.exports, module.exports.__esModule = true; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +/***/ }), +/* 606 */ +/***/ ((module) => { -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } -var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520)); + return self; +} -var _store = _interopRequireDefault(__webpack_require__(605)); +module.exports = _assertThisInitialized; +module.exports["default"] = module.exports, module.exports.__esModule = true; -var _dsl = __webpack_require__(607); +/***/ }), +/* 607 */ +/***/ ((module) => { -function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } +function _getPrototypeOf(o) { + module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + module.exports["default"] = module.exports, module.exports.__esModule = true; + return _getPrototypeOf(o); +} -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +module.exports = _getPrototypeOf; +module.exports["default"] = module.exports, module.exports.__esModule = true; -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } +/***/ }), +/* 608 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -var store = new _store.default(); -/** - * Public API to use flags - */ +"use strict"; -var flag = function flag() { - var args = [].slice.call(arguments); - if (args.length === 1) { - return store.get(args[0]); - } else { - store.set(args[0], args[1]); - return args[1]; - } -}; -/** List all flags from the store */ +var _interopRequireDefault = __webpack_require__(524); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.registryEndpoint = exports.transformRegistryFormatToStackFormat = void 0; -var listFlags = function listFlags() { - return store.keys().sort(); -}; -/** Resets all the flags */ +var _regenerator = _interopRequireDefault(__webpack_require__(539)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -exports.listFlags = listFlags; +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var resetFlags = function resetFlags() { - listFlags().forEach(function (name) { - return store.remove(name); - }); -}; -/** - * Enables several flags - * - * Supports passing either object flagName -> flagValue - * - * @param {string[]|Object} flagsToEnable - */ +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -exports.resetFlags = resetFlags; +var _get = _interopRequireDefault(__webpack_require__(370)); -var enable = function enable(flagsToEnable) { - var flagNameToValue; +__webpack_require__(609); - if (Array.isArray(flagsToEnable)) { - // eslint-disable-next-line no-console - console.log('flags.enable: Deprecation warning: prefer to use an object { flag1: true, flag2: true } instead of an array when using flags.enable'); - flagNameToValue = flagsToEnable.map(function (flagName) { - return [flagName, true]; - }); - } else if (typeof flagsToEnable === 'object') { - flagNameToValue = Object.entries(flagsToEnable); - } +var _terms = _interopRequireDefault(__webpack_require__(610)); - if (!flagNameToValue) { - return; - } +var _constants = __webpack_require__(611); - var _iterator = _createForOfIteratorHelper(flagNameToValue), - _step; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - var _step$value = (0, _slicedToArray2.default)(_step.value, 2), - flagName = _step$value[0], - flagValue = _step$value[1]; +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - flag(flagName, flagValue); - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } +var transformRegistryFormatToStackFormat = function transformRegistryFormatToStackFormat(doc) { + return _objectSpread({ + id: (0, _get.default)(doc, 'latest_version.manifest.source'), + attributes: (0, _get.default)(doc, 'latest_version.manifest') + }, doc); }; -/** - * Initializes flags from the remote endpoint serving instance flags - * - * @private - * @see https://docs.cozy.io/en/cozy-stack/settings/#get-settingsflags - * @param {CozyClient} client - */ - - -exports.enable = enable; - -var initializeFromRemote = /*#__PURE__*/function () { - var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client) { - var _yield$client$query, attributes; - - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return client.query((0, _dsl.Q)('io.cozy.settings').getById('flags')); - - case 2: - _yield$client$query = _context.sent; - attributes = _yield$client$query.data.attributes; - enable(attributes); - - case 5: - case "end": - return _context.stop(); - } - } - }, _callee); - })); - - return function initializeFromRemote(_x) { - return _ref.apply(this, arguments); - }; -}(); -exports.initializeFromRemote = initializeFromRemote; +exports.transformRegistryFormatToStackFormat = transformRegistryFormatToStackFormat; +var registryEndpoint = '/registry/'; +exports.registryEndpoint = registryEndpoint; -var capitalize = function capitalize(str) { - return str[0].toUpperCase() + str.slice(1); +var queryPartFromOptions = function queryPartFromOptions(options) { + var query = new URLSearchParams(options).toString(); + return query ? "?".concat(query) : ''; }; -var getTemplateData = function getTemplateData(attr) { - if (typeof document === 'undefined') { - return null; - } - - var allDataNode = document.querySelector('[data-cozy]'); - var attrNode = document.querySelector("[data-cozy-".concat(attr, "]")); +var getBaseRoute = function getBaseRoute(app) { + var type = app.type; // TODO node is an historic type, it should be `konnector`, check with the back - try { - if (allDataNode) { - return JSON.parse(allDataNode.dataset.cozy)[attr]; - } else if (attrNode) { - // eslint-disable-next-line no-console - console.warn('Prefer to use [data-cozy] to store template data. <div data-cozy="{{.CozyData}}></div>. "'); - return JSON.parse(attrNode.dataset["cozy".concat(capitalize(attr))]); - } else { - return null; - } - } catch (e) { - return null; - } + var route = type === _constants.APP_TYPE.KONNECTOR || type === 'node' ? 'konnectors' : 'apps'; + return "/".concat(route); }; /** - * Initialize from the template data injected by cozy-stack into the DOM - * - * @private - * @see https://docs.cozy.io/en/cozy-stack/client-app-dev/#good-practices-for-your-application - * - * @returns {Boolean} - False is DOM initialization could not be completed, true otherwise + * @typedef {object} RegistryApp + * @property {string} slug + * @property {object} terms + * @property {boolean} installed */ - -exports.getTemplateData = getTemplateData; - -var initializeFromDOM = /*#__PURE__*/function () { - var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { - var domData; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - domData = getTemplateData('flags'); - - if (domData) { - _context2.next = 3; - break; - } - - return _context2.abrupt("return", false); - - case 3: - enable(domData); - return _context2.abrupt("return", true); - - case 5: - case "end": - return _context2.stop(); - } - } - }, _callee2); - })); - - return function initializeFromDOM() { - return _ref2.apply(this, arguments); - }; -}(); /** - * Initialize flags from DOM if possible, otherwise from remote endpoint - * - * @example - * - * Flags can be taken from the flags injected by the stack - * ``` - * <div data-cozy="{{ .CozyData }}"></div> - * - * // not recommended but possible - * <div data-flags="{{ .Flags }}"></div> - * ```` - * - * @param {CozyClient} client - A CozyClient - * @return {Promise} Resolves when flags have been initialized + * @typedef {"dev"|"beta"|"stable"} RegistryAppChannel */ -exports.initializeFromDOM = initializeFromDOM; - -var initialize = /*#__PURE__*/function () { - var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(client) { - var domRes; - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - _context3.next = 2; - return initializeFromDOM(); - - case 2: - domRes = _context3.sent; - - if (!(domRes == false)) { - _context3.next = 6; - break; - } - - _context3.next = 6; - return initializeFromRemote(client); - - case 6: - case "end": - return _context3.stop(); - } - } - }, _callee3); - })); - - return function initialize(_x2) { - return _ref3.apply(this, arguments); - }; -}(); +var Registry = /*#__PURE__*/function () { + function Registry(options) { + (0, _classCallCheck2.default)(this, Registry); -exports.initialize = initialize; + if (!options.client) { + throw new Error('Need to pass a client to instantiate a Registry API.'); + } -var FlagClientPlugin = /*#__PURE__*/function () { - function FlagClientPlugin(client) { - (0, _classCallCheck2.default)(this, FlagClientPlugin); - this.client = client; - this.handleLogin = this.handleLogin.bind(this); - this.handleLogout = this.handleLogout.bind(this); - this.client.on('login', this.handleLogin); - this.client.on('logout', this.handleLogout); - this.setupInitializing(); - if (client.isLogged) this.handleLogin(); + this.client = options.client; } /** - * Fetches and sets flags from remote + * Installs or updates an app from a source. + * + * Accepts the terms if the app has them. + * + * @param {RegistryApp} app - App to be installed + * @param {string} source - String (ex: registry://drive/stable) + * @returns {Promise} */ - (0, _createClass2.default)(FlagClientPlugin, [{ - key: "refresh", + (0, _createClass2.default)(Registry, [{ + key: "installApp", value: function () { - var _refresh = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() { - return _regenerator.default.wrap(function _callee4$(_context4) { + var _installApp = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(app, source) { + var slug, terms, searchParams, isUpdate, querypart, verb, baseRoute; + return _regenerator.default.wrap(function _callee$(_context) { while (1) { - switch (_context4.prev = _context4.next) { + switch (_context.prev = _context.next) { case 0: - _context4.next = 2; - return flag.initializeFromRemote(this.client); + slug = app.slug, terms = app.terms; + searchParams = {}; + isUpdate = app.installed; + if (isUpdate) searchParams.PermissionsAcked = isUpdate; + if (source) searchParams.Source = source; + querypart = queryPartFromOptions(searchParams); - case 2: + if (!terms) { + _context.next = 9; + break; + } + + _context.next = 9; + return _terms.default.save(this.client, terms); + + case 9: + verb = app.installed ? 'PUT' : 'POST'; + baseRoute = getBaseRoute(app); + return _context.abrupt("return", this.client.stackClient.fetchJSON(verb, "".concat(baseRoute, "/").concat(slug).concat(querypart))); + + case 12: case "end": - return _context4.stop(); + return _context.stop(); } } - }, _callee4, this); + }, _callee, this); })); - function refresh() { - return _refresh.apply(this, arguments); + function installApp(_x, _x2) { + return _installApp.apply(this, arguments); } - return refresh; + return installApp; }() /** - * Sets up a promise that can be awaited to wait for flag complete - * initialization + * Uninstalls an app. */ }, { - key: "setupInitializing", - value: function setupInitializing() { - var _this = this; - - this.initializing = new Promise(function (resolve) { - _this.resolveInitializing = resolve; - }); - } - }, { - key: "handleLogin", + key: "uninstallApp", value: function () { - var _handleLogin = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() { - return _regenerator.default.wrap(function _callee5$(_context5) { + var _uninstallApp = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(app) { + var slug, baseRoute; + return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { - switch (_context5.prev = _context5.next) { + switch (_context2.prev = _context2.next) { case 0: - _context5.next = 2; - return flag.initialize(this.client); - - case 2: - this.resolveInitializing(); - this.client.emit('plugin:flag:login'); + slug = app.slug; + baseRoute = getBaseRoute(app); + return _context2.abrupt("return", this.client.stackClient.fetchJSON('DELETE', "".concat(baseRoute, "/").concat(slug))); - case 4: + case 3: case "end": - return _context5.stop(); + return _context2.stop(); } } - }, _callee5, this); + }, _callee2, this); })); - function handleLogin() { - return _handleLogin.apply(this, arguments); + function uninstallApp(_x3) { + return _uninstallApp.apply(this, arguments); } - return handleLogin; + return uninstallApp; }() + /** + * Fetch at most 200 apps from the channel + * + * @param {object} params - Fetching parameters + * @param {string} params.type - "webapp" or "konnector" + * @param {RegistryAppChannel} params.channel - The channel of the apps to fetch + * @param {string} params.limit - maximum number of fetched apps - defaults to 200 + * + * @returns {Promise<Array<RegistryApp>>} + */ + }, { - key: "handleLogout", + key: "fetchApps", value: function () { - var _handleLogout = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() { - return _regenerator.default.wrap(function _callee6$(_context6) { + var _fetchApps = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(params) { + var channel, type, _params$limit, limit, searchParams, querypart, _yield$this$client$st, apps; + + return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { - switch (_context6.prev = _context6.next) { + switch (_context3.prev = _context3.next) { case 0: - flag.reset(); - this.setupInitializing(); - this.client.emit('plugin:flag:logout'); + channel = params.channel, type = params.type, _params$limit = params.limit, limit = _params$limit === void 0 ? '200' : _params$limit; + searchParams = { + limit: limit, + versionsChannel: channel, + latestChannelVersion: channel + }; + querypart = new URLSearchParams(searchParams).toString(); - case 3: + if (type) { + // Unfortunately, URLSearchParams encodes brackets so we have to do + // the querypart handling manually + querypart = querypart + "&filter[type]=".concat(type); + } + + _context3.next = 6; + return this.client.stackClient.fetchJSON('GET', "/registry?".concat(querypart)); + + case 6: + _yield$this$client$st = _context3.sent; + apps = _yield$this$client$st.data; + return _context3.abrupt("return", apps); + + case 9: case "end": - return _context6.stop(); + return _context3.stop(); } } - }, _callee6, this); + }, _callee3, this); })); - function handleLogout() { - return _handleLogout.apply(this, arguments); + function fetchApps(_x4) { + return _fetchApps.apply(this, arguments); } - return handleLogout; + return fetchApps; }() + /** + * Fetch the list of apps that are in maintenance mode + * + * @returns {Array<RegistryApp>} + */ + + }, { + key: "fetchAppsInMaintenance", + value: function fetchAppsInMaintenance() { + return this.client.stackClient.fetchJSON('GET', '/registry/maintenance'); + } + /** + * Fetch the status of a single app on the registry + * + * @param {string} slug - The slug of the app to fetch + * + * @returns {RegistryApp} + */ + + }, { + key: "fetchApp", + value: function fetchApp(slug) { + return this.client.stackClient.fetchJSON('GET', "/registry/".concat(slug)); + } + /** + * Fetch the latest version of an app for the given channel and slug + * + * @param {object} params - Fetching parameters + * @param {string} params.slug - The slug of the app to fetch + * @param {RegistryAppChannel} params.channel - The channel of the app to fetch + * @param {string} params.version - The version of the app to fetch. Can also be "latest" + * + * @returns {RegistryApp} + */ + + }, { + key: "fetchAppVersion", + value: function fetchAppVersion(params) { + if (!params.slug) { + throw new Error('Need to pass a slug to use fetchAppVersion'); + } + + var slug = params.slug, + channel = params.channel, + version = params.version; + var finalChannel = !channel && (!version || version === 'latest') ? 'stable' : channel; + var url = "/registry/".concat(slug, "/"); + + if (finalChannel) { + url += "".concat(finalChannel, "/").concat(version || 'latest'); + } else { + url += "".concat(version); + } + + return this.client.stackClient.fetchJSON('GET', url); + } }]); - return FlagClientPlugin; + return Registry; }(); -FlagClientPlugin.pluginName = 'flags'; -flag.store = store; -flag.list = listFlags; -flag.reset = resetFlags; -flag.enable = enable; -flag.initializeFromRemote = initializeFromRemote; -flag.initializeFromDOM = initializeFromDOM; -flag.initialize = initialize; -flag.plugin = FlagClientPlugin; -var _default = flag; +var _default = Registry; exports["default"] = _default; /***/ }), -/* 605 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/* 609 */ +/***/ (function() { -"use strict"; +/** + * + * + * @author Jerry Bendy <jerry@icewingcc.com> + * @licence MIT + * + */ +(function(self) { + 'use strict'; -var _interopRequireDefault = __webpack_require__(512); + var nativeURLSearchParams = (function() { + // #41 Fix issue in RN + try { + if (self.URLSearchParams && (new self.URLSearchParams('foo=bar')).get('foo') === 'bar') { + return self.URLSearchParams; + } + } catch (e) {} + return null; + })(), + isSupportObjectConstructor = nativeURLSearchParams && (new nativeURLSearchParams({a: 1})).toString() === 'a=1', + // There is a bug in safari 10.1 (and earlier) that incorrectly decodes `%2B` as an empty space and not a plus. + decodesPlusesCorrectly = nativeURLSearchParams && (new nativeURLSearchParams('s=%2B').get('s') === '+'), + __URLSearchParams__ = "__URLSearchParams__", + // Fix bug in Edge which cannot encode ' &' correctly + encodesAmpersandsCorrectly = nativeURLSearchParams ? (function() { + var ampersandTest = new nativeURLSearchParams(); + ampersandTest.append('s', ' &'); + return ampersandTest.toString() === 's=+%26'; + })() : true, + prototype = URLSearchParamsPolyfill.prototype, + iterable = !!(self.Symbol && self.Symbol.iterator); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + if (nativeURLSearchParams && isSupportObjectConstructor && decodesPlusesCorrectly && encodesAmpersandsCorrectly) { + return; + } -var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + /** + * Make a URLSearchParams instance + * + * @param {object|string|URLSearchParams} search + * @constructor + */ + function URLSearchParamsPolyfill(search) { + search = search || ""; -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + // support construct object with another URLSearchParams instance + if (search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill) { + search = search.toString(); + } + this [__URLSearchParams__] = parseToDict(search); + } -var _microee = _interopRequireDefault(__webpack_require__(558)); -var _lsAdapter = _interopRequireDefault(__webpack_require__(606)); + /** + * Appends a specified key/value pair as a new search parameter. + * + * @param {string} name + * @param {string} value + */ + prototype.append = function(name, value) { + appendTo(this [__URLSearchParams__], name, value); + }; -/** - * In memory key value storage. - * - * Can potentially be backed by localStorage if present + /** + * Deletes the given search parameter, and its associated value, + * from the list of all search parameters. + * + * @param {string} name + */ + prototype['delete'] = function(name) { + delete this [__URLSearchParams__] [name]; + }; - * Emits `change` when a key is set (eventEmitter) - */ -var FlagStore = /*#__PURE__*/function () { - function FlagStore() { - (0, _classCallCheck2.default)(this, FlagStore); - this.store = {}; + /** + * Returns the first value associated to the given search parameter. + * + * @param {string} name + * @returns {string|null} + */ + prototype.get = function(name) { + var dict = this [__URLSearchParams__]; + return this.has(name) ? dict[name][0] : null; + }; - if (typeof localStorage !== 'undefined') { - this.longtermStore = _lsAdapter.default; + /** + * Returns all the values association with a given search parameter. + * + * @param {string} name + * @returns {Array} + */ + prototype.getAll = function(name) { + var dict = this [__URLSearchParams__]; + return this.has(name) ? dict [name].slice(0) : []; + }; + + /** + * Returns a Boolean indicating if such a search parameter exists. + * + * @param {string} name + * @returns {boolean} + */ + prototype.has = function(name) { + return hasOwnProperty(this [__URLSearchParams__], name); + }; + + /** + * Sets the value associated to a given search parameter to + * the given value. If there were several values, delete the + * others. + * + * @param {string} name + * @param {string} value + */ + prototype.set = function set(name, value) { + this [__URLSearchParams__][name] = ['' + value]; + }; + + /** + * Returns a string containg a query string suitable for use in a URL. + * + * @returns {string} + */ + prototype.toString = function() { + var dict = this[__URLSearchParams__], query = [], i, key, name, value; + for (key in dict) { + name = encode(key); + for (i = 0, value = dict[key]; i < value.length; i++) { + query.push(name + '=' + encode(value[i])); + } + } + return query.join('&'); + }; + + // There is a bug in Safari 10.1 and `Proxy`ing it is not enough. + var forSureUsePolyfill = !decodesPlusesCorrectly; + var useProxy = (!forSureUsePolyfill && nativeURLSearchParams && !isSupportObjectConstructor && self.Proxy); + var propValue; + if (useProxy) { + // Safari 10.0 doesn't support Proxy, so it won't extend URLSearchParams on safari 10.0 + propValue = new Proxy(nativeURLSearchParams, { + construct: function (target, args) { + return new target((new URLSearchParamsPolyfill(args[0]).toString())); + } + }) + // Chrome <=60 .toString() on a function proxy got error "Function.prototype.toString is not generic" + propValue.toString = Function.prototype.toString.bind(URLSearchParamsPolyfill); + } else { + propValue = URLSearchParamsPolyfill; } + /* + * Apply polifill to global object and append other prototype into it + */ + Object.defineProperty(self, 'URLSearchParams', { + value: propValue + }); - this.restore(); - } + var USPProto = self.URLSearchParams.prototype; - (0, _createClass2.default)(FlagStore, [{ - key: "restore", - value: function restore() { - if (!this.longtermStore) { - return; - } + USPProto.polyfill = true; - var allValues = this.longtermStore.getAll(); + /** + * + * @param {function} callback + * @param {object} thisArg + */ + USPProto.forEach = USPProto.forEach || function(callback, thisArg) { + var dict = parseToDict(this.toString()); + Object.getOwnPropertyNames(dict).forEach(function(name) { + dict[name].forEach(function(value) { + callback.call(thisArg, value, name, this); + }, this); + }, this); + }; - for (var _i = 0, _Object$entries = Object.entries(allValues); _i < _Object$entries.length; _i++) { - var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2), - flag = _Object$entries$_i[0], - val = _Object$entries$_i[1]; + /** + * Sort all name-value pairs + */ + USPProto.sort = USPProto.sort || function() { + var dict = parseToDict(this.toString()), keys = [], k, i, j; + for (k in dict) { + keys.push(k); + } + keys.sort(); + + for (i = 0; i < keys.length; i++) { + this['delete'](keys[i]); + } + for (i = 0; i < keys.length; i++) { + var key = keys[i], values = dict[key]; + for (j = 0; j < values.length; j++) { + this.append(key, values[j]); + } + } + }; + + /** + * Returns an iterator allowing to go through all keys of + * the key/value pairs contained in this object. + * + * @returns {function} + */ + USPProto.keys = USPProto.keys || function() { + var items = []; + this.forEach(function(item, name) { + items.push(name); + }); + return makeIterator(items); + }; + + /** + * Returns an iterator allowing to go through all values of + * the key/value pairs contained in this object. + * + * @returns {function} + */ + USPProto.values = USPProto.values || function() { + var items = []; + this.forEach(function(item) { + items.push(item); + }); + return makeIterator(items); + }; + + /** + * Returns an iterator allowing to go through all key/value + * pairs contained in this object. + * + * @returns {function} + */ + USPProto.entries = USPProto.entries || function() { + var items = []; + this.forEach(function(item, name) { + items.push([name, item]); + }); + return makeIterator(items); + }; + + + if (iterable) { + USPProto[self.Symbol.iterator] = USPProto[self.Symbol.iterator] || USPProto.entries; + } + + + function encode(str) { + var replace = { + '!': '%21', + "'": '%27', + '(': '%28', + ')': '%29', + '~': '%7E', + '%20': '+', + '%00': '\x00' + }; + return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function(match) { + return replace[match]; + }); + } + + function decode(str) { + return str + .replace(/[ +]/g, '%20') + .replace(/(%[a-f0-9]{2})+/ig, function(match) { + return decodeURIComponent(match); + }); + } + + function makeIterator(arr) { + var iterator = { + next: function() { + var value = arr.shift(); + return {done: value === undefined, value: value}; + } + }; + + if (iterable) { + iterator[self.Symbol.iterator] = function() { + return iterator; + }; + } + + return iterator; + } + + function parseToDict(search) { + var dict = {}; + + if (typeof search === "object") { + // if `search` is an array, treat it as a sequence + if (isArray(search)) { + for (var i = 0; i < search.length; i++) { + var item = search[i]; + if (isArray(item) && item.length === 2) { + appendTo(dict, item[0], item[1]); + } else { + throw new TypeError("Failed to construct 'URLSearchParams': Sequence initializer must only contain pair elements"); + } + } + + } else { + for (var key in search) { + if (search.hasOwnProperty(key)) { + appendTo(dict, key, search[key]); + } + } + } + + } else { + // remove first '?' + if (search.indexOf("?") === 0) { + search = search.slice(1); + } + + var pairs = search.split("&"); + for (var j = 0; j < pairs.length; j++) { + var value = pairs [j], + index = value.indexOf('='); + + if (-1 < index) { + appendTo(dict, decode(value.slice(0, index)), decode(value.slice(index + 1))); + + } else { + if (value) { + appendTo(dict, decode(value), ''); + } + } + } + } - this.store[flag] = val; - this.emit('change', flag); - } - } - }, { - key: "keys", - value: function keys() { - return Object.keys(this.store); + return dict; } - }, { - key: "get", - value: function get(name) { - if (!this.store.hasOwnProperty(name)) { - this.store[name] = null; - } - return this.store[name]; - } - }, { - key: "set", - value: function set(name, value) { - if (this.longtermStore) { - this.longtermStore.setItem(name, value); - } + function appendTo(dict, name, value) { + var val = typeof value === 'string' ? value : ( + value !== null && value !== undefined && typeof value.toString === 'function' ? value.toString() : JSON.stringify(value) + ); - this.store[name] = value; - this.emit('change', name); + // #47 Prevent using `hasOwnProperty` as a property name + if (hasOwnProperty(dict, name)) { + dict[name].push(val); + } else { + dict[name] = [val]; + } } - }, { - key: "remove", - value: function remove(name) { - delete this.store[name]; - if (this.longtermStore) { - this.longtermStore.removeItem(name); - } + function isArray(val) { + return !!val && '[object Array]' === Object.prototype.toString.call(val); + } - this.emit('change', name); + function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); } - }]); - return FlagStore; -}(); -_microee.default.mixin(FlagStore); +})(typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : this)); -var _default = FlagStore; -exports["default"] = _default; /***/ }), -/* 606 */ -/***/ ((__unused_webpack_module, exports) => { +/* 610 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; +var _interopRequireDefault = __webpack_require__(524); + Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports.getKey = exports.prefix = void 0; +exports["default"] = void 0; -function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } +var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537)); -/* global localStorage */ -var prefix = 'flag__'; -exports.prefix = prefix; +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var getKey = function getKey(name) { - return prefix + name; -}; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -exports.getKey = getKey; +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var listFlagLocalStorage = function listFlagLocalStorage() { - return Object.keys(localStorage).filter(function (x) { - return x.indexOf(prefix) === 0; - }).map(function (x) { - return x.replace(prefix, ''); - }); -}; -/** - * Gets a flag from localStorage, parses value from JSON - * - * @param {String} flag - */ +var TERMS_DOCTYPE = 'io.cozy.terms'; +/* TODO Use collection terms */ +function save(_x, _x2) { + return _save.apply(this, arguments); +} -var getItem = function getItem(flag) { - var val = localStorage.getItem(getKey(flag)); - var parsed = val ? JSON.parse(val) : val; - return parsed; -}; -/** - * Stores a flag in localStorage, stringifies the value for storage - * - * @param {String} flag - * @param {String} value - */ +function _save() { + _save = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, terms) { + var id, termsAttributes, _yield$client$query, savedTermsDocs, savedTerms, termsToSave, _termsToSave; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + id = terms.id, termsAttributes = (0, _objectWithoutProperties2.default)(terms, ["id"]); + _context.next = 3; + return client.query({ + doctype: TERMS_DOCTYPE, + selector: { + termsId: id, + version: termsAttributes.version + }, + limit: 1 + }); -var setItem = function setItem(flag, value) { - var str = JSON.stringify(value); - return localStorage.setItem(getKey(flag), str); -}; -/** - * Removes a flag from localStorage - * - * @param {String} flag - */ + case 3: + _yield$client$query = _context.sent; + savedTermsDocs = _yield$client$query.data; + if (!(savedTermsDocs && savedTermsDocs.length)) { + _context.next = 13; + break; + } -var removeItem = function removeItem(flag) { - return localStorage.removeItem(getKey(flag)); -}; -/** - * Returns all stored flags as an object - */ + // we just update the url if this is the same id and same version + // but the url changed + savedTerms = savedTermsDocs[0]; + if (!(savedTerms.termsId == id && savedTerms.version == termsAttributes.version && savedTerms.url != termsAttributes.url)) { + _context.next = 11; + break; + } -var getAll = function getAll() { - var res = {}; + termsToSave = _objectSpread(_objectSpread({ + _type: TERMS_DOCTYPE + }, savedTerms), {}, { + url: termsAttributes.url + }); + _context.next = 11; + return client.save(termsToSave); - var _iterator = _createForOfIteratorHelper(listFlagLocalStorage()), - _step; + case 11: + _context.next = 16; + break; - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - var flag = _step.value; - res[flag] = getItem(flag); - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } + case 13: + _termsToSave = _objectSpread(_objectSpread({ + _type: TERMS_DOCTYPE + }, termsAttributes), {}, { + termsId: id, + accepted: true, + acceptedAt: new Date() + }); + _context.next = 16; + return client.save(_termsToSave); - return res; + case 16: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + return _save.apply(this, arguments); +} + +var _default = { + save: save }; -/** - * Clears all the flags from localstorage - */ +exports["default"] = _default; +/***/ }), +/* 611 */ +/***/ ((__unused_webpack_module, exports) => { -var clearAll = function clearAll() { - var _iterator2 = _createForOfIteratorHelper(listFlagLocalStorage()), - _step2; +"use strict"; - try { - for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { - var flag = _step2.value; - removeItem(flag); - } - } catch (err) { - _iterator2.e(err); - } finally { - _iterator2.f(); - } -}; -var _default = { - getAll: getAll, - getItem: getItem, - setItem: setItem, - clearAll: clearAll, - removeItem: removeItem +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.APP_TYPE = void 0; +var APP_TYPE = { + KONNECTOR: 'konnector', + WEBAPP: 'webapp' }; -exports["default"] = _default; +exports.APP_TYPE = APP_TYPE; /***/ }), -/* 607 */ +/* 612 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.QueryDefinition = exports.MutationTypes = exports.Mutations = exports.getDoctypeFromOperation = exports.uploadFile = exports.removeReferencedBy = exports.addReferencedBy = exports.removeReferencesTo = exports.addReferencesTo = exports.deleteDocument = exports.updateDocuments = exports.updateDocument = exports.createDocument = exports.isAGetByIdQuery = exports.Q = void 0; - -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +exports["default"] = exports.Collection = exports.isDocumentUpdateConflict = exports.isNoUsableIndexError = exports.isIndexConflictError = exports.isIndexNotFoundError = exports.dontThrowNotFoundError = void 0; -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _isArray = _interopRequireDefault(__webpack_require__(55)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _findKey = _interopRequireDefault(__webpack_require__(608)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _types = __webpack_require__(610); +/** + * Handler for error response which return a empty value for "not found" error + * + * @param {Error} error - An error + * @param {Array|object} data Data to return in case of "not found" error + * @returns {object} JsonAPI response with empty data in case of "not + * found" error. + */ +var dontThrowNotFoundError = function dontThrowNotFoundError(error) { + var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + if (error.message.match(/not_found/)) { + var expectsCollection = Array.isArray(data); // Return expected JsonAPI attributes : collections are expecting + // meta, skip and next attribute -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + return expectsCollection ? { + data: data, + meta: { + count: 0 + }, + skip: 0, + next: false + } : { + data: data + }; + } + throw error; +}; /** - * @typedef PartialQueryDefinition + * Helper to identify an index not found error * - * @property {Array} [indexedFields] - * @property {Array} [sort] - * @property {object} [selector] + * @param {Error} error - An error + * @returns {boolean} - Whether or not the error is an index not found error */ -/** - * @typedef {object} MangoSelector - */ +exports.dontThrowNotFoundError = dontThrowNotFoundError; + +var isIndexNotFoundError = function isIndexNotFoundError(error) { + return error.message.match(/no_index/); +}; /** - * @typedef {object} MangoPartialFilter + * Helper to identify an index conflict + * + * @param {Error} error - An error + * @returns {boolean} - Whether or not the error is an index conflict error */ + +exports.isIndexNotFoundError = isIndexNotFoundError; + +var isIndexConflictError = function isIndexConflictError(error) { + return error.message.match(/error_saving_ddoc/); +}; /** - * Chainable API to create query definitions to retrieve documents - * from a Cozy. `QueryDefinition`s are sent to links. + * Helper to identify a no usable index error * - * @augments {object} + * @param {Error} error - An error + * @returns {boolean} - Whether or not the error is a no usable index error */ -var QueryDefinition = /*#__PURE__*/function () { - /** - * @class - * - * @param {object} options Initial options for the query definition - * @param {Doctype} [options.doctype] - The doctype of the doc. - * @param {DocId|null} [options.id] - The id of the doc. - * @param {Array<DocId>} [options.ids] - The ids of the docs. - * @param {MangoSelector} [options.selector] - The selector to query the docs. - * @param {Array<string>} [options.fields] - The fields to return. - * @param {Array<string>} [options.indexedFields] - The fields to index. - * @param {MangoPartialFilter} [options.partialFilter] - The partial index definition to filter docs. - * @param {Array<object>} [options.sort] - The sorting params. - * @param {Array<string>} [options.includes] - The docs to include. - * @param {string|null} [options.referenced] - The referenced document. - * @param {number|null} [options.limit] - The document's limit to return. - * @param {number|null} [options.skip] - The number of docs to skip. - * @param {CouchDBViewCursor} [options.cursor] - The cursor to paginate views. - * @param {string} [options.bookmark] - The bookmark to paginate mango queries. - */ - function QueryDefinition() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - (0, _classCallCheck2.default)(this, QueryDefinition); - this.doctype = options.doctype; - this.id = options.id; - this.ids = options.ids; - this.selector = options.selector; - this.fields = options.fields; - this.indexedFields = options.indexedFields; - this.partialFilter = options.partialFilter; - this.sort = options.sort; - this.includes = options.includes; - this.referenced = options.referenced; - this.limit = options.limit; - this.skip = options.skip; - this.cursor = options.cursor; - this.bookmark = options.bookmark; - } - /** - * Checks if the sort order matches the index' fields order. - * - * When sorting with CouchDB, it is required to: - * - use indexed fields - * - keep the same order than the indexed fields. - * - * See https://docs.cozy.io/en/tutorials/data/queries/#sort-data-with-mango - * - * @param {PartialQueryDefinition} obj - A partial QueryDefinition to check - */ - (0, _createClass2.default)(QueryDefinition, [{ - key: "checkSortOrder", - value: function checkSortOrder(_ref) { - var sort = _ref.sort, - selector = _ref.selector, - indexedFields = _ref.indexedFields; +exports.isIndexConflictError = isIndexConflictError; - var _sort = this.sort || sort; +var isNoUsableIndexError = function isNoUsableIndexError(error) { + return error.message.match(/no_usable_index/); +}; +/** + * Helper to identify a document conflict + * + * @param {Error} error - An error + * @returns {boolean} - Whether or not the error is a document conflict error + */ - var _selector = this.selector || selector || {}; - var _indexedFields = this.indexedFields || indexedFields; +exports.isNoUsableIndexError = isNoUsableIndexError; - if (!_sort) { - return; - } +var isDocumentUpdateConflict = function isDocumentUpdateConflict(error) { + return error.message.match(/Document update conflict/); +}; +/** + * Utility class to abstract an regroup identical methods and logics for + * specific collections. + */ - var fieldsToIndex = _indexedFields || Object.keys(_selector); - if (!fieldsToIndex || fieldsToIndex.length < 1) { - return; - } +exports.isDocumentUpdateConflict = isDocumentUpdateConflict; - if (_sort.length > fieldsToIndex.length) { - console.warn("You should not sort on non-indexed fields.\n\n Sort: ".concat(JSON.stringify(_sort), "\n\n Indexed fields: ").concat(fieldsToIndex)); - return; - } +var Collection = /*#__PURE__*/function () { + function Collection() { + (0, _classCallCheck2.default)(this, Collection); + } + + (0, _createClass2.default)(Collection, null, [{ + key: "get", - for (var i = 0; i < _sort.length; i++) { - if (Object.keys(_sort[i])[0] !== fieldsToIndex[i]) { - console.warn("The sort order should be the same than the indexed fields.\n\n Sort: ".concat(JSON.stringify(_sort), "\n\n Indexed fields: ").concat(fieldsToIndex, "\n")); - return; - } - } - } /** - * Checks the selector predicates. - * - * It is useful to warn the developer when a partial index might be used. + * Utility method aimed to return only one document. * - * @param {MangoSelector} selector - The selector definition - * @returns {void} + * @param {CozyStackClient} stackClient - CozyStackClient + * @param {string} endpoint - Stack endpoint + * @param {object} options - Options of the collection + * @param {Function} options.normalize Callback to normalize response data + * (default `data => data`) + * @param {string} options.method HTTP method (default `GET`) + * @returns {object} JsonAPI response containing normalized + * document as data attribute */ + value: function () { + var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(stackClient, endpoint, _ref) { + var _ref$normalize, normalize, _ref$method, method, resp; - }, { - key: "checkSelector", - value: function checkSelector(selector) { - var hasExistsFalse = (0, _findKey.default)(selector, ['$exists', false]); + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _ref$normalize = _ref.normalize, normalize = _ref$normalize === void 0 ? function (data, response) { + return data; + } : _ref$normalize, _ref$method = _ref.method, method = _ref$method === void 0 ? 'GET' : _ref$method; + _context.prev = 1; + _context.next = 4; + return stackClient.fetchJSON(method, endpoint); - if (hasExistsFalse) { - console.warn("The \"$exists: false\" predicate should be defined as a partial index for better performance.\n\n Selector: ".concat(selector)); - } + case 4: + resp = _context.sent; + return _context.abrupt("return", { + data: normalize(resp.data, resp) + }); - var hasNe = (0, _findKey.default)(selector, '$ne'); + case 8: + _context.prev = 8; + _context.t0 = _context["catch"](1); + return _context.abrupt("return", dontThrowNotFoundError(_context.t0, null)); - if (hasNe) { - console.info("The use of the $ne operator is more efficient with a partial index.\n\n Selector: ".concat(selector)); - } - } - /** - * Query a single document on its id. - * - * @param {string} id The document id. - * @returns {QueryDefinition} The QueryDefinition object. - */ + case 11: + case "end": + return _context.stop(); + } + } + }, _callee, null, [[1, 8]]); + })); - }, { - key: "getById", - value: function getById(id) { - if (!id) { - throw new Error('getById called with undefined id'); + function get(_x, _x2, _x3) { + return _get.apply(this, arguments); } - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - id: id - })); - } - /** - * Query several documents on their ids. - * - * @param {Array} ids The documents ids. - * @returns {QueryDefinition} The QueryDefinition object. - */ + return get; + }() + }]); + return Collection; +}(); - }, { - key: "getByIds", - value: function getByIds(ids) { - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - ids: ids - })); - } - /** - * Query documents with a [mango selector](http://docs.couchdb.org/en/latest/api/database/find.html#find-selectors). - * Each field passed in the selector will be indexed, except if the indexField option is used. - * - * @param {MangoSelector} selector The Mango selector. - * @returns {QueryDefinition} The QueryDefinition object. - */ +exports.Collection = Collection; +var _default = Collection; +exports["default"] = _default; - }, { - key: "where", - value: function where(selector) { - this.checkSortOrder({ - selector: selector - }); - this.checkSelector(selector); - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - selector: selector - })); - } - /** - * Specify which fields of each object should be returned. If it is omitted, the entire object is returned. - * - * @param {Array} fields The fields to return. - * @returns {QueryDefinition} The QueryDefinition object. - */ +/***/ }), +/* 613 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - }, { - key: "select", - value: function select(fields) { - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - fields: fields - })); - } - /** - * Specify which fields should be indexed. This prevent the automatic indexing of the mango fields. - * - * @param {Array} indexedFields The fields to index. - * @returns {QueryDefinition} The QueryDefinition object. - */ +"use strict"; - }, { - key: "indexFields", - value: function indexFields(indexedFields) { - this.checkSortOrder({ - indexedFields: indexedFields - }); - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - indexedFields: indexedFields - })); - } - /** - * Specify a [partial index](https://docs.couchdb.org/en/stable/api/database/find.html#find-partial-indexes). - * The filter must follow the same syntax than the selector. - * - * A partial index includes a filter, used to select documents before the indexing. - * You can find more information about partial indexes [here](https://docs.cozy.io/en/tutorials/data/advanced/#partial-indexes) - * - * @param {object} partialFilter - The filter definition. - */ - }, { - key: "partialIndex", - value: function partialIndex(partialFilter) { - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - partialFilter: partialFilter - })); - } - /** - * Specify how to sort documents, following the [sort syntax](http://docs.couchdb.org/en/latest/api/database/find.html#find-sort) - * - * @param {Array} sort The list of field name and direction pairs. - * @returns {QueryDefinition} The QueryDefinition object. - */ +var _interopRequireWildcard = __webpack_require__(522); - }, { - key: "sortBy", - value: function sortBy(sort) { - if (!(0, _isArray.default)(sort)) { - throw new Error("Invalid sort, should be an array ([{ label: \"desc\"}, { name: \"asc\"}]), you passed ".concat(JSON.stringify(sort), ".")); - } +var _interopRequireDefault = __webpack_require__(524); - this.checkSortOrder({ - sort: sort - }); - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - sort: sort - })); - } - /** - * Includes documents having a relationships with the ones queried. - * For example, query albums including the photos. - * - * @param {Array} includes The documents to include. - * @returns {QueryDefinition} The QueryDefinition object. - */ +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.normalizeDoc = normalizeDoc; +exports.normalizeDoctype = exports["default"] = void 0; - }, { - key: "include", - value: function include(includes) { - if (!Array.isArray(includes)) { - throw new Error('include() takes an array of relationship names'); - } +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - includes: includes - })); - } - /** - * Maximum number of documents returned, useful for pagination. Default is 100. - * - * @param {number} limit The document's limit. - * @returns {QueryDefinition} The QueryDefinition object. - */ +var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537)); - }, { - key: "limitBy", - value: function limitBy(limit) { - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - limit: limit - })); - } - }, { - key: "UNSAFE_noLimit", - value: function UNSAFE_noLimit() { - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - limit: null - })); - } - /** - * Skip the first ‘n’ documents, where ‘n’ is the value specified. - * - * Beware, this [performs badly](http://docs.couchdb.org/en/stable/ddocs/views/pagination.html#paging-alternate-method) on view's index. - * Prefer cursor-based pagination in such situation. - * - * @param {number} skip The number of documents to skip. - * @returns {QueryDefinition} The QueryDefinition object. - */ +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - }, { - key: "offset", - value: function offset(skip) { - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - bookmark: undefined, - cursor: undefined, - skip: skip - })); - } - /** - * Use [cursor-based](https://docs.cozy.io/en/cozy-stack/jsonapi/#pagination) pagination. - * *Warning*: this is only useful for views. - * The cursor is a [startkey, startkey_docid] array, where startkey is the view's key, - * e.g. ["io.cozy.photos.albums", "album-id"] and startkey_docid is the id of - * the starting document of the query, e.g. "file-id". - * Use the last docid of each query as startkey_docid to paginate or leave blank for the first query. - * - * @param {CouchDBViewCursor} cursor The cursor for pagination. - * @returns {QueryDefinition} The QueryDefinition object. - */ +var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614)); - }, { - key: "offsetCursor", - value: function offsetCursor(cursor) { - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - bookmark: undefined, - skip: undefined, - cursor: cursor - })); - } - /** - * Use [bookmark](https://docs.couchdb.org/en/2.2.0/api/database/find.html#pagination) pagination. - * Note this only applies for mango-queries (not views) and is way more efficient than skip pagination. - * The bookmark is a string returned by the _find response and can be seen as a pointer in - * the index for the next query. - * - * @param {string} bookmark The bookmark to continue a previous paginated query. - * @returns {QueryDefinition} The QueryDefinition object. - */ +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - }, { - key: "offsetBookmark", - value: function offsetBookmark(bookmark) { - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - skip: undefined, - cursor: undefined, - bookmark: bookmark - })); - } - /** - * Use the [file reference system](https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/) - * - * @param {object} document The reference document - * @returns {QueryDefinition} The QueryDefinition object. - */ +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - }, { - key: "referencedBy", - value: function referencedBy(document) { - return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { - referenced: document - })); - } - }, { - key: "toDefinition", - value: function toDefinition() { - return { - doctype: this.doctype, - id: this.id, - ids: this.ids, - selector: this.selector, - fields: this.fields, - indexedFields: this.indexedFields, - partialFilter: this.partialFilter, - sort: this.sort, - includes: this.includes, - referenced: this.referenced, - limit: this.limit, - skip: this.skip, - cursor: this.cursor, - bookmark: this.bookmark - }; - } - }]); - return QueryDefinition; -}(); -/** - * Helper to create a QueryDefinition. Recommended way to create - * query definitions. - * - * @param {Doctype} doctype - Doctype of the query definition - * - * @example - * ``` - * import { Q } from 'cozy-client' - * - * const qDef = Q('io.cozy.todos').where({ _id: '1234' }) - * ``` - */ +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -exports.QueryDefinition = QueryDefinition; +var _cozyFlags = _interopRequireDefault(__webpack_require__(615)); -var Q = function Q(doctype) { - return new QueryDefinition({ - doctype: doctype - }); -}; -/** - * Check if the query is a getById() query - * - * @param {QueryDefinition} queryDefinition The query definition - * - * @returns {boolean} - */ +var _utils = __webpack_require__(623); +var _uniq = _interopRequireDefault(__webpack_require__(624)); -exports.Q = Q; +var _omit = _interopRequireDefault(__webpack_require__(625)); -var isAGetByIdQuery = function isAGetByIdQuery(queryDefinition) { - if (!queryDefinition) return false; - var attributes = Object.values(queryDefinition); - if (attributes.length === 0) return false; // 2 attrs because we check if id and doctype are not undefined +var _head = _interopRequireDefault(__webpack_require__(633)); - return attributes.filter(function (attr) { - return attr !== undefined; - }).length === 2 && queryDefinition.id !== undefined; -}; // Mutations +var _startsWith = _interopRequireDefault(__webpack_require__(634)); +var _qs = _interopRequireDefault(__webpack_require__(641)); -exports.isAGetByIdQuery = isAGetByIdQuery; -var CREATE_DOCUMENT = 'CREATE_DOCUMENT'; -var UPDATE_DOCUMENT = 'UPDATE_DOCUMENT'; -var UPDATE_DOCUMENTS = 'UPDATE_DOCUMENTS'; -var DELETE_DOCUMENT = 'DELETE_DOCUMENT'; -var ADD_REFERENCES_TO = 'ADD_REFERENCES_TO'; -var REMOVE_REFERENCES_TO = 'REMOVE_REFERENCES_TO'; -var ADD_REFERENCED_BY = 'ADD_REFERENCED_BY'; -var REMOVE_REFERENCED_BY = 'REMOVE_REFERENCED_BY'; -var UPLOAD_FILE = 'UPLOAD_FILE'; +var _mangoIndex = __webpack_require__(657); -var createDocument = function createDocument(document) { - return { - mutationType: MutationTypes.CREATE_DOCUMENT, - document: document - }; -}; +var _Collection = _interopRequireWildcard(__webpack_require__(612)); -exports.createDocument = createDocument; +var querystring = _interopRequireWildcard(__webpack_require__(659)); -var updateDocument = function updateDocument(document) { - return { - mutationType: MutationTypes.UPDATE_DOCUMENT, - document: document - }; -}; +var _errors = __webpack_require__(663); -exports.updateDocument = updateDocument; +function _templateObject10() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design/", "/copy?rev=", ""]); -var updateDocuments = function updateDocuments(documents) { - return { - mutationType: MutationTypes.UPDATE_DOCUMENTS, - documents: documents + _templateObject10 = function _templateObject10() { + return data; }; -}; -exports.updateDocuments = updateDocuments; + return data; +} -var deleteDocument = function deleteDocument(document) { - return { - mutationType: MutationTypes.DELETE_DOCUMENT, - document: document +function _templateObject9() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design/", "?rev=", ""]); + + _templateObject9 = function _templateObject9() { + return data; }; -}; -exports.deleteDocument = deleteDocument; + return data; +} -var addReferencesTo = function addReferencesTo(document, referencedDocuments) { - return { - mutationType: MutationTypes.ADD_REFERENCES_TO, - referencedDocuments: referencedDocuments, - document: document +function _templateObject8() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_design_docs?include_docs=true"]); + + _templateObject8 = function _templateObject8() { + return data; }; -}; -exports.addReferencesTo = addReferencesTo; + return data; +} -var removeReferencesTo = function removeReferencesTo(document, referencedDocuments) { - return { - mutationType: MutationTypes.REMOVE_REFERENCES_TO, - referencedDocuments: referencedDocuments, - document: document +function _templateObject7() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_index"]); + + _templateObject7 = function _templateObject7() { + return data; }; -}; -exports.removeReferencesTo = removeReferencesTo; + return data; +} -var addReferencedBy = function addReferencedBy(document, referencedDocuments) { - return { - mutationType: MutationTypes.ADD_REFERENCED_BY, - referencedDocuments: referencedDocuments, - document: document - }; -}; +function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } -exports.addReferencedBy = addReferencedBy; +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } -var removeReferencedBy = function removeReferencedBy(document, referencedDocuments) { - return { - mutationType: MutationTypes.REMOVE_REFERENCED_BY, - referencedDocuments: referencedDocuments, - document: document - }; -}; +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } -exports.removeReferencedBy = removeReferencedBy; +function _templateObject6() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "?rev=", ""]); -var uploadFile = function uploadFile(file, dirPath) { - return { - mutationType: MutationTypes.UPLOAD_FILE, - file: file, - dirPath: dirPath + _templateObject6 = function _templateObject6() { + return data; }; -}; -exports.uploadFile = uploadFile; + return data; +} -var getDoctypeFromOperation = function getDoctypeFromOperation(operation) { - if (operation.mutationType) { - var type = operation.mutationType; +function _templateObject5() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]); - switch (type) { - case CREATE_DOCUMENT: - return operation.document._type; + _templateObject5 = function _templateObject5() { + return data; + }; - case UPDATE_DOCUMENT: - return operation.document._type; + return data; +} - case UPDATE_DOCUMENTS: - return operation.documents[0]._type; +function _templateObject4() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]); - case DELETE_DOCUMENT: - return operation.document._type; + _templateObject4 = function _templateObject4() { + return data; + }; - case ADD_REFERENCES_TO: - throw new Error('Not implemented'); + return data; +} - case UPLOAD_FILE: - throw new Error('Not implemented'); +function _templateObject3() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_all_docs?include_docs=true"]); - default: - throw new Error("Unknown mutationType ".concat(type)); - } - } else { - return operation.doctype; - } -}; + _templateObject3 = function _templateObject3() { + return data; + }; -exports.getDoctypeFromOperation = getDoctypeFromOperation; -var Mutations = { - createDocument: createDocument, - updateDocument: updateDocument, - updateDocuments: updateDocuments, - deleteDocument: deleteDocument, - addReferencesTo: addReferencesTo, - removeReferencesTo: removeReferencesTo, - addReferencedBy: addReferencedBy, - removeReferencedBy: removeReferencedBy, - uploadFile: uploadFile -}; -exports.Mutations = Mutations; -var MutationTypes = { - CREATE_DOCUMENT: CREATE_DOCUMENT, - UPDATE_DOCUMENT: UPDATE_DOCUMENT, - UPDATE_DOCUMENTS: UPDATE_DOCUMENTS, - DELETE_DOCUMENT: DELETE_DOCUMENT, - ADD_REFERENCES_TO: ADD_REFERENCES_TO, - REMOVE_REFERENCES_TO: REMOVE_REFERENCES_TO, - ADD_REFERENCED_BY: ADD_REFERENCED_BY, - REMOVE_REFERENCED_BY: REMOVE_REFERENCED_BY, - UPLOAD_FILE: UPLOAD_FILE -}; -exports.MutationTypes = MutationTypes; + return data; +} -/***/ }), -/* 608 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function _templateObject2() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/_find"]); -var baseFindKey = __webpack_require__(609), - baseForOwn = __webpack_require__(536), - baseIteratee = __webpack_require__(401); + _templateObject2 = function _templateObject2() { + return data; + }; -/** - * This method is like `_.find` except that it returns the key of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Object - * @param {Object} object The object to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(o) { return o.age < 40; }); - * // => 'barney' (iteration order is not guaranteed) - * - * // The `_.matches` iteratee shorthand. - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findKey(users, 'active'); - * // => 'barney' - */ -function findKey(object, predicate) { - return baseFindKey(object, baseIteratee(predicate, 3), baseForOwn); + return data; } -module.exports = findKey; +function _templateObject() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", ""]); + _templateObject = function _templateObject() { + return data; + }; -/***/ }), -/* 609 */ -/***/ ((module) => { + return data; +} + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +var DATABASE_DOES_NOT_EXIST = 'Database does not exist.'; /** - * The base implementation of methods like `_.findKey` and `_.findLastKey`, - * without support for iteratee shorthands, which iterates over `collection` - * using `eachFunc`. + * Normalize a document, adding its doctype if needed * + * @param {object} doc - Document to normalize + * @param {string} doctype - Document doctype + * @returns {object} normalized document * @private - * @param {Array|Object} collection The collection to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the found element or its key, else `undefined`. */ -function baseFindKey(collection, predicate, eachFunc) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = key; - return false; - } - }); - return result; + +function normalizeDoc() { + var doc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var doctype = arguments.length > 1 ? arguments[1] : undefined; + var id = doc._id || doc.id; + return _objectSpread({ + id: id, + _id: id, + _type: doctype + }, doc); } -module.exports = baseFindKey; +var prepareForDeletion = function prepareForDeletion(x) { + return Object.assign({}, (0, _omit.default)(x, '_type'), { + _deleted: true + }); +}; +/** + * Abstracts a collection of documents of the same doctype, providing CRUD methods and other helpers. + */ + +var DocumentCollection = /*#__PURE__*/function () { + function DocumentCollection(doctype, stackClient) { + (0, _classCallCheck2.default)(this, DocumentCollection); + this.doctype = doctype; + this.stackClient = stackClient; + this.indexes = {}; + this.endpoint = "/data/".concat(this.doctype, "/"); + } + /** + * Provides a callback for `Collection.get` + * + * @private + * @param {string} doctype - Document doctype + * @returns {Function} (data, response) => normalizedDocument + * using `normalizeDoc` + */ -/***/ }), -/* 610 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -"use strict"; + (0, _createClass2.default)(DocumentCollection, [{ + key: "all", + /** + * Lists all documents of the collection, without filters. + * + * The returned documents are paginated by the stack. + * + * @param {{limit, skip, bookmark, keys}} options The fetch options: pagination & fetch of specific docs. + * @returns {{data, meta, skip, bookmark, next}} The JSON API conformant response. + * @throws {FetchError} + */ + value: function () { + var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { + var _this = this; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + var options, + _options$limit, + limit, + _options$skip, + skip, + bookmark, + keys, + isUsingAllDocsRoute, + route, + url, + params, + path, + resp, + data, + next, + _args = arguments; -var _dsl = __webpack_require__(607); + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}; + _options$limit = options.limit, limit = _options$limit === void 0 ? 100 : _options$limit, _options$skip = options.skip, skip = _options$skip === void 0 ? 0 : _options$skip, bookmark = options.bookmark, keys = options.keys; // If the limit is intentionnally null, we need to use _all_docs, since + // _normal_docs uses _find and has a hard limit of 1000 -/** - * @typedef {"io.cozy.accounts"} AccountsDoctype - * @typedef {"io.cozy.triggers"} TriggersDoctype - * @typedef {"io.cozy.konnectors"} KonnectorsDoctype - * @typedef {"io.cozy.notes"} NotesDoctype - * @typedef {"io.cozy.apps"} AppsDoctype - * @typedef {"io.cozy.settings"} SettingsDoctype - * @typedef {"io.cozy-oauth.clients"} OAuthClientsDoctype - * @typedef {"io.cozy.files"} FilesDoctype - * @typedef {AccountsDoctype|TriggersDoctype|KonnectorsDoctype|NotesDoctype|AppsDoctype|SettingsDoctype|OAuthClientsDoctype|FilesDoctype} KnownDoctype - * @typedef {KnownDoctype|string} Doctype - */ + isUsingAllDocsRoute = !!keys || limit === null; + route = isUsingAllDocsRoute ? '_all_docs' : '_normal_docs'; + url = (0, _utils.uri)(_templateObject(), this.doctype, route); + params = { + include_docs: true, + limit: limit, + skip: skip, + keys: keys, + bookmark: bookmark + }; + path = querystring.buildURL(url, params); // If no document of this doctype exist, this route will return a 404, + // so we need to try/catch and return an empty response object in case of a 404 -/** - * @typedef {object} Link - * @typedef {object} Mutation - * @typedef {object} DocumentCollection - * @typedef {object} QueryResult - * @typedef {object} HydratedDocument - * @typedef {object} ReduxStore - * @typedef {object} Token - * @typedef {object} ClientResponse - * @typedef {object} Manifest - */ + _context.prev = 7; + _context.next = 10; + return this.stackClient.fetchJSON('GET', path); -/** - * @typedef {object} OldCozyClient - */ + case 10: + resp = _context.sent; + _context.next = 16; + break; -/** - * @typedef {object} NodeEnvironment - */ + case 13: + _context.prev = 13; + _context.t0 = _context["catch"](7); + return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0)); -/** - * @typedef {"loading"|"loaded"|"pending"|"failed"} QueryFetchStatus - */ + case 16: + /* If using `all_docs` we need to filter our design documents and check if + the document is not null. If we use `normal_doc` we can't have any design doc + */ + if (isUsingAllDocsRoute) { + data = resp.rows.filter(function (doc) { + return doc && doc.doc !== null && !doc.error && !(0, _startsWith.default)(doc.id, '_design'); + }).map(function (row) { + return normalizeDoc(row.doc, _this.doctype); + }); + } else { + data = resp.rows.map(function (row) { + return normalizeDoc(row, _this.doctype); + }); + } // The presence of a bookmark doesn’t guarantee that there are more results. + // See https://docs.couchdb.org/en/2.2.0/api/database/find.html#pagination -/** - * @typedef {Record<Doctype, QueryState>} QueriesStateSlice - */ -/** - * @typedef {Record<string, CozyClientDocument>} IndexedDocuments - */ + next = bookmark ? resp.rows.length >= limit : skip + resp.rows.length < resp.total_rows; + return _context.abrupt("return", { + data: data, + meta: { + count: isUsingAllDocsRoute ? data.length : resp.total_rows + }, + skip: skip, + bookmark: resp.bookmark, + next: next + }); -/** - * @typedef {Record<Doctype, IndexedDocuments>} DocumentsStateSlice - */ + case 19: + case "end": + return _context.stop(); + } + } + }, _callee, this, [[7, 13]]); + })); -/** - * @typedef {object} QueryState - * @property {string} id - * @property {QueryDefinition} definition - * @property {QueryFetchStatus} fetchStatus - * @property {number} lastFetch - * @property {number} lastUpdate - * @property {number} lastErrorUpdate - * @property {Error} lastError - * @property {boolean} hasMore - * @property {number} count - * @property {object|Array} data - * @property {string} bookmark - * @property {object} [execution_stats] - * @property {QueryOptions} [options] - */ + function all() { + return _all.apply(this, arguments); + } -/** - * @typedef {object} AutoUpdateOptions - * @param {boolean} update - Should documents be updated in the query (default: true) - * @param {boolean} add - Should documents be added to the query (default: true) - * @param {boolean} remove - Should documents be removed from the query (default: true) - */ + return all; + }() + }, { + key: "fetchDocumentsWithMango", + value: function () { + var _fetchDocumentsWithMango = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(path, selector) { + var options, + _args2 = arguments; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + options = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : {}; + return _context2.abrupt("return", this.stackClient.fetchJSON('POST', path, this.toMangoOptions(selector, options))); -/** - * @typedef {object} QueryOptions - * @property {string} [as] - Name of the query - * @property {Function} [fetchPolicy] - Fetch policy to bypass fetching based on what's already inside the state. See "Fetch policies" - * @property {AutoUpdateOptions} [autoUpdate] - Options for the query auto update - * @property {string} [update] - Does not seem to be used - * @property {Function} [onError] - Callback when the query is errored - * @property {boolean} [enabled=true] - If set to false, the query won't be executed - * @property {object} [hydrated=true] - Whether documents should be returned already hydrated - * @property {object} [singleDocData] - If true, the "data" returned will be - * a single doc instead of an array for single doc queries. Defaults to false for backward - * compatibility but will be set to true in the future. - */ + case 2: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); -/** - * @typedef {object} FetchMoreAble - * @property {Function} fetchMore - */ + function fetchDocumentsWithMango(_x, _x2) { + return _fetchDocumentsWithMango.apply(this, arguments); + } -/** - * @typedef {object} FetchAble - * @property {Function} fetch - */ + return fetchDocumentsWithMango; + }() + /** + * Migrate an existing unamed index to a named one. + * + * Index migration became necessary for optimistic index, because + * we started to use named index while we used to have unamed index, + * i.e. indexes with CouchDB-generated ID. + * + * @param {object} sourceIndex - The index to migrate + * @param {string} targetIndexName - The new index name + * @private + */ -/** - * @typedef {QueryState & FetchMoreAble & FetchAble} UseQueryReturnValue - */ + }, { + key: "migrateUnamedIndex", + value: function () { + var _migrateUnamedIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(sourceIndex, targetIndexName) { + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _context3.prev = 0; + _context3.next = 3; + return this.copyIndex(sourceIndex, targetIndexName); -/** - * A reference to a document - * - * @typedef {object} ReferencedByRelationship - * @property {RelationshipParent} [parent] - * @property {ReferencedBy} [referenced_by] - */ + case 3: + _context3.next = 5; + return this.destroyIndex(sourceIndex); -/** - * @typedef {object} RelationshipParent - * @property {{related: string}} links - * @property {Reference} [data] - */ + case 5: + _context3.next = 16; + break; -/** - * @typedef {object} ReferencedBy - * @property {{self: string}} links - * @property {Reference[]|null} data - */ + case 7: + _context3.prev = 7; + _context3.t0 = _context3["catch"](0); -/** - * A reference to a document - * https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files/#references - * - * @typedef {object} Reference - * @property {string} id - id of the document - * @property {string} type - doctype of the document - */ + if ((0, _Collection.isDocumentUpdateConflict)(_context3.t0)) { + _context3.next = 11; + break; + } -/** - * @typedef {Object.<string, Array<Reference>>} ReferenceMap - */ + throw _context3.t0; -/** - * @typedef {object} MutationOptions - * @property {string} [as] - * @property {Function} [update] - * @property {Function} [updateQueries] - */ + case 11: + (0, _utils.sleep)(1000); + _context3.next = 14; + return this.copyIndex(sourceIndex, targetIndexName); -/** - * @typedef {object} CozyClientDocument - A document - * @property {string} [_id] - Id of the document - * @property {string} [id] - Id of the document - * @property {string} [_type] - Type of the document - * @property {string} [_rev] - Current revision of the document - * @property {boolean} [_deleted] - When the document has been deleted - * @property {ReferencedByRelationship} [relationships] - Relationships of the document - * @property {Reference[]} [referenced_by] - referenced by of another document - */ + case 14: + _context3.next = 16; + return this.destroyIndex(sourceIndex); -/** - * @typedef {object} FileDocument - An io.cozy.files document - * @property {string} _id - Id of the file - * @property {FilesDoctype} _type - Doctype of the file - * @property {string} name - Name of the file - * @property {object} metadata - Metadata of the file - * @property {object} type - Type of the file - * @property {object} class - Class of the file - * @typedef {CozyClientDocument & FileDocument} IOCozyFile - An io.cozy.files document - */ + case 16: + case "end": + return _context3.stop(); + } + } + }, _callee3, this, [[0, 7]]); + })); -/** - * @typedef {object} FolderDocument - An io.cozy.files document - * @property {string} _id - Id of the folder - * @property {FilesDoctype} _type - Doctype of the folder - * @property {string} name - Name of the folder - * @property {object} metadata - Metadata of the folder - * @property {object} type - Type of the folder - * @typedef {CozyClientDocument & FolderDocument} IOCozyFolder - An io.cozy.files document - */ + function migrateUnamedIndex(_x3, _x4) { + return _migrateUnamedIndex.apply(this, arguments); + } -/** - * @typedef {object} OAuthClientDocument - An io.cozy.oauth.clients document - * @property {string} _id - Id of the client - * @property {OAuthClientsDoctype} _type - Doctype of the client - * @property {string} software_id - * @property {string} software_version - * @property {string} client_id - * @property {string} client_name - * @property {string} client_kind - * @property {string} client_uri - * @property {string} logo_uri - * @property {string} policy_uri - * @property {string} notification_platform - * @property {string} notification_device_token - * @property {Array<String>} redirect_uris - * @typedef {CozyClientDocument & OAuthClientDocument} IOCozyOAuthClient - An io.cozy.oauth.clients document - */ + return migrateUnamedIndex; + }() + /** + * Handle index creation if it is missing. + * + * When an index is missing, we first check if there is one with a different + * name but the same definition. If yes, it means we found an old unamed + * index, so we migrate it. If there is none, we create the new index. + * + * @param {object} selector The mango selector + * @param {MangoQueryOptions} options The find options + * @private + */ -/** - * @typedef {object} ClientError - * @property {string} [status] - */ + }, { + key: "handleMissingIndex", + value: function () { + var _handleMissingIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(selector, options) { + var indexedFields, partialFilter, existingIndex, indexName; + return _regenerator.default.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + indexedFields = options.indexedFields, partialFilter = options.partialFilter; -/** - * @typedef FilePlugin - * @property {object} [externalDataDirectory] - * @property {object} [cacheDirectory] - * @property {object} [externalCacheDirectory] - * @property {object} [dataDirectory] - */ + if (!indexedFields) { + indexedFields = (0, _mangoIndex.getIndexFields)({ + sort: options.sort, + selector: selector + }); + } -/** - * @typedef InAppBrowser - * @property {Function} open - */ + _context4.next = 4; + return this.findExistingIndex(selector, options); -/** - * @typedef {object} AppMetadata - */ + case 4: + existingIndex = _context4.sent; + indexName = (0, _mangoIndex.getIndexNameFromFields)(indexedFields); -/** - * @typedef {object} ClientCapabilities - * - * @description Read more about client capabilities here https://docs.cozy.io/en/cozy-stack/settings/#get-settingscapabilities. - * - * @property {boolean} can_auth_with_oidc - Whether OIDC login is possible with this Cozy - * @property {boolean} can_auth_with_password - Whether password login is possible with this Cozy - * @property {boolean} file_versioning - Whether file versioning is active on this Cozy - * @property {boolean} flat_subdomains - Whether the stack has been configured to use flat subdomains - */ + if (existingIndex) { + _context4.next = 11; + break; + } -/** - * @typedef Cordova - * @property {FilePlugin} file - * @property {InAppBrowser} InAppBrowser - * @property {object} plugins - */ + _context4.next = 9; + return this.createIndex(indexedFields, { + partialFilter: partialFilter, + indexName: indexName + }); -/** - * @typedef CordovaWindow - * @property {Cordova} cordova - * @property {object} SafariViewController - * @property {Function} resolveLocalFileSystemURL - * @property {Function} handleOpenURL - */ + case 9: + _context4.next = 17; + break; -/** - * @typedef {object} CouchDBDocument - A document - * @property {string} _id - Id of the document - * @property {string} _rev - Current revision of the document - * @property {boolean} [_deleted] - When the document has been deleted - * @property {object} [relationships] - Relationships of the document - */ + case 11: + if (!(existingIndex._id !== "_design/".concat(indexName))) { + _context4.next = 16; + break; + } -/** - * @typedef {object} CouchDBBulkResult - An item of the CouchDB bulk docs response - * @property {boolean} ok - * @property {string} id - * @property {string} rev - * @property {string?} error? - * @property {string?} reason? - */ + _context4.next = 14; + return this.migrateUnamedIndex(existingIndex, indexName); -/** - * @typedef {Array<string>|string} ViewKey - * @typedef {string} DocId - * @typedef {[ViewKey, DocId]} CouchDBViewCursor - */ + case 14: + _context4.next = 17; + break; -/** - * @typedef {object} Theme - * @property {string} id - * @property {string} label - * @property {string} icon - * @property {Array<QualificationAttributes>} items - * @property {Array<string>} [defaultItems] - * - * @typedef {Array<Theme>} ThemesList - * - * @typedef {'identity'|'family'|'work_study'|'health'|'home'|'transport'|'finance'|'invoice'} ThemesLabels - */ + case 16: + throw new Error("Index unusable for query, index used: ".concat(indexName)); -/** - * @typedef {object} QualificationAttributes - * @property {string} label - * @property {string} [purpose] - * @property {string} [sourceCategory] - * @property {string} [sourceSubCategory] - * @property {Array<string>} [subjects] - */ + case 17: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); -/** - * @typedef {'identity_photo'|'national_id_card'|'passport'|'residence_permit'|'family_record_book'|'birth_certificate'|'driver_license'|'other_identity_document'|'citizen_registration_certificate'|'personal_sporting_licence'} IdentityLabel - * - * @typedef {'family_record_book'|'birth_certificate'|'wedding'|'pacs'|'divorce'|'large_family_card'|'caf'|'other_family_document'|'payment_proof_family_allowance'} FamilyLabel - * - * @typedef {'diploma'|'work_contract'|'pay_sheet'|'unemployment_benefit'|'pension'|'gradebook'|'student_card'|'resume'|'motivation_letter'|'other_work_document'|'work_disability_recognition'|'school_attendance_certificate'} WorkStudyLabels - * - * @typedef {'health_certificate'|'health_book'|'national_health_insurance_card'|'health_insurance_card'|'prescription'|'health_invoice'|'national_health_insurance_right_certificate'|'work_disability_recognition'|'pregnancy_medical_certificate'|'other_health_document'} HealthLabels - * - * @typedef {'phone_invoice'|'isp_invoice'|'telecom_invoice'|'energy_invoice'|'water_invoice'|'house_sale_agreeement'|'building_permit'|'technical_diagnostic_record'|'lease'|'rent_receipt'|'house_insurance'|'work_quote'|'work_invoice'|'other_house_document'|'unfit_for_habitation_declaration'|'accommodation_proof'|'house_insurance'} HomeLabels - * - * @typedef {'driver_license'|'vehicle_registration'|'car_insurance'|'mechanic_invoice'|'transport_invoice'|'other_transport_document'} TransportLabels - * - * @typedef {'tax_return'|'tax_notice'|'tax_timetable'|'pay_sheet'|'receipt'|'other_tax_document'|'bank_details'|'bank_statement'|'loan_agreement'|'other_bank_document'|'payment_proof_family_allowance'|'other_revenue'} FinanceLabels - * - * @typedef {'phone_invoice'|'isp_invoice'|'telecom_invoice'|'energy_invoice'|'water_invoice'|'appliance_invoice'|'web_service_invoice'|'restaurant_invoice'|'work_invoice'|'transport_invoice'|'health_invoice'|'other_invoice'} InvoiceLabels - * - * @typedef {'personal_sporting_licence'|'other_activity_document'} ActivityLabels - * - * @typedef {IdentityLabel|FamilyLabel|WorkStudyLabels|HealthLabels|HomeLabels|TransportLabels|FinanceLabels|InvoiceLabels|ActivityLabels} ItemsLabels - */ + function handleMissingIndex(_x5, _x6) { + return _handleMissingIndex.apply(this, arguments); + } -/** - * @typedef {object} DACCMeasure - * See https://github.com/cozy/DACC - * - * @property {string} measureName - It must match an existing measure name on the DACC server - * @property {string} startDate - Start of the aggregation period. Should be in YYYY-MM-DD format - * @property {number} value - The measured value on the aggregation period - * @property {string} createdBy - The slug of the app creating the measure - * @property {object} group1 - Should be a {key: value} where the key is set in the measure definition. - * @property {object} group2 - Should be a {key: value} where the key is set in the measure definition. - * @property {object} group3 - Should be a {key: value} where the key is set in the measure definition. - */ + return handleMissingIndex; + }() + /** + * Find documents with the mango selector and create index + * if missing. + * + * We adopt an optimistic approach for index creation: + * we run the query first, and only if an index missing + * error is returned, the index is created and + * the query run again. + * + * @param {string} path The route path + * @param {object} selector The mango selector + * @param {MangoQueryOptions} options The find options + * + * @returns {object} - The find response + * @private + */ -/** - * Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions. - * - * @callback OpenURLCallback - * @param {string} url - URL to present to the user - */ + }, { + key: "findWithMango", + value: function () { + var _findWithMango = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(path, selector) { + var options, + resp, + _args5 = arguments; + return _regenerator.default.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + options = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : {}; + _context5.prev = 1; + _context5.next = 4; + return this.fetchDocumentsWithMango(path, selector, options); -/** - * A session code generated by the cozy-stack that can be used to create a session - * - * More information: https://docs.cozy.io/en/cozy-stack/auth/#post-authsession_code - * - * @typedef {string} SessionCode - */ + case 4: + resp = _context5.sent; + _context5.next = 18; + break; -/** - * An object containing a code verifier and a code challenge that can be used in a - * PKCE verification process - * - * More information: https://docs.cozy.io/en/cozy-stack/auth/#pkce-extension - * - * @typedef {object} PKCECodes - * @property {string} [codeVerifier] - * @property {string} [codeChallenge] - */ -var _default = {}; -exports["default"] = _default; + case 7: + _context5.prev = 7; + _context5.t0 = _context5["catch"](1); -/***/ }), -/* 611 */ -/***/ ((__unused_webpack_module, exports) => { + if (!(!(0, _Collection.isIndexNotFoundError)(_context5.t0) && !(0, _Collection.isNoUsableIndexError)(_context5.t0))) { + _context5.next = 13; + break; + } -"use strict"; + throw _context5.t0; + case 13: + _context5.next = 15; + return this.handleMissingIndex(selector, options); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.formatBytes = exports.slugify = exports.sleep = exports.attempt = exports.uri = void 0; + case 15: + _context5.next = 17; + return this.fetchDocumentsWithMango(path, selector, options); -/** - * @function - * @description Template tag function for URIs encoding - * - * Will automatically apply `encodeURIComponent` to template literal placeholders - * - * @example - * ``` - * const safe = uri`/data/${doctype}/_all_docs?limit=${limit}` - * ``` - * - * @private - */ -var uri = function uri(strings) { - var parts = [strings[0]]; + case 17: + resp = _context5.sent; - for (var i = 0; i < (arguments.length <= 1 ? 0 : arguments.length - 1); i++) { - parts.push(encodeURIComponent(i + 1 < 1 || arguments.length <= i + 1 ? undefined : arguments[i + 1]) + strings[i + 1]); - } + case 18: + return _context5.abrupt("return", resp); - return parts.join(''); -}; -/** - * @function - * @description Helps to avoid nested try/catch when using async/await - * - * Inspired by a Go pattern: http://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/ - * - * @example - * ``` - * if (await attempt(collection.all()) return - * await sleep(1000) - * if (await attempt(collection.all()) return - * await sleep(1000) - * return - * ``` - * - * @private - */ + case 19: + case "end": + return _context5.stop(); + } + } + }, _callee5, this, [[1, 7]]); + })); + function findWithMango(_x7, _x8) { + return _findWithMango.apply(this, arguments); + } -exports.uri = uri; + return findWithMango; + }() + /** + * Returns a filtered list of documents using a Mango selector. + * + * The returned documents are paginated by the stack. + * + * @param {object} selector The Mango selector. + * @param {{sort, fields, limit, skip, bookmark, indexId}} options The query options. + * @returns {{data, skip, bookmark, next}} The JSON API conformant response. + * @throws {FetchError} + */ -var attempt = function attempt(promise) { - return promise.then(function () { - return true; - }).catch(function () { - return false; - }); -}; -/** - * @function - * @description Helps to avoid nested try/catch when using async/await — see documentation for attempt - * @private - */ + }, { + key: "find", + value: function () { + var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(selector) { + var _this2 = this; + var options, + _options$skip2, + skip, + resp, + path, + _args6 = arguments; -exports.attempt = attempt; + return _regenerator.default.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {}; + _options$skip2 = options.skip, skip = _options$skip2 === void 0 ? 0 : _options$skip2; + _context6.prev = 2; + path = (0, _utils.uri)(_templateObject2(), this.doctype); + _context6.next = 6; + return this.findWithMango(path, selector, options); -var sleep = function sleep(time, args) { - return new Promise(function (resolve) { - setTimeout(resolve, time, args); - }); -}; + case 6: + resp = _context6.sent; + _context6.next = 12; + break; -exports.sleep = sleep; + case 9: + _context6.prev = 9; + _context6.t0 = _context6["catch"](2); + return _context6.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context6.t0)); -var slugify = function slugify(text) { - return text.toString().toLowerCase().replace(/\s+/g, '-') // Replace spaces with - - .replace(/[^\w-]+/g, '') // Remove all non-word chars - .replace(/--+/g, '-') // Replace multiple - with single - - .replace(/^-+/, '') // Trim - from start of text - .replace(/-+$/, ''); -}; // Trim - from end of text + case 12: + return _context6.abrupt("return", { + data: resp.docs.map(function (doc) { + return normalizeDoc(doc, _this2.doctype); + }), + next: resp.next, + skip: skip, + bookmark: resp.bookmark, + execution_stats: resp.execution_stats + }); + case 13: + case "end": + return _context6.stop(); + } + } + }, _callee6, this, [[2, 9]]); + })); -exports.slugify = slugify; + function find(_x9) { + return _find.apply(this, arguments); + } -var formatBytes = function formatBytes(bytes) { - var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; - if (bytes === 0) return '0 Bytes'; - var k = 1024; - var dm = decimals < 0 ? 0 : decimals; - var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - var i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; -}; + return find; + }() + /** + * Get a document by id + * + * @param {string} id The document id. + * @returns {object} JsonAPI response containing normalized document as data attribute + */ -exports.formatBytes = formatBytes; + }, { + key: "get", + value: function () { + var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(id) { + return _regenerator.default.wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + return _context7.abrupt("return", _Collection.default.get(this.stackClient, "".concat(this.endpoint).concat(encodeURIComponent(id)), { + normalize: this.constructor.normalizeDoctype(this.doctype) + })); -/***/ }), -/* 612 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 1: + case "end": + return _context7.stop(); + } + } + }, _callee7, this); + })); -var baseUniq = __webpack_require__(463); + function get(_x10) { + return _get.apply(this, arguments); + } -/** - * Creates a duplicate-free version of an array, using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons, in which only the first occurrence of each element - * is kept. The order of result values is determined by the order they occur - * in the array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniq([2, 1, 2]); - * // => [2, 1] - */ -function uniq(array) { - return (array && array.length) ? baseUniq(array) : []; -} + return get; + }() + /** + * Get many documents by id + */ -module.exports = uniq; + }, { + key: "getAll", + value: function () { + var _getAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(ids) { + var _this3 = this; + var resp, rows; + return _regenerator.default.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + _context8.prev = 0; + _context8.next = 3; + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject3(), this.doctype), { + keys: ids + }); -/***/ }), -/* 613 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 3: + resp = _context8.sent; + _context8.next = 9; + break; -var arrayMap = __webpack_require__(398), - baseClone = __webpack_require__(562), - baseUnset = __webpack_require__(614), - castPath = __webpack_require__(360), - copyObject = __webpack_require__(565), - customOmitClone = __webpack_require__(618), - flatRest = __webpack_require__(620), - getAllKeysIn = __webpack_require__(576); + case 6: + _context8.prev = 6; + _context8.t0 = _context8["catch"](0); + return _context8.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context8.t0)); -/** Used to compose bitmasks for cloning. */ -var CLONE_DEEP_FLAG = 1, - CLONE_FLAT_FLAG = 2, - CLONE_SYMBOLS_FLAG = 4; + case 9: + rows = resp.rows.filter(function (row) { + return row.doc; + }); + return _context8.abrupt("return", { + data: rows.map(function (row) { + return normalizeDoc(row.doc, _this3.doctype); + }), + meta: { + count: rows.length + } + }); -/** - * The opposite of `_.pick`; this method creates an object composed of the - * own and inherited enumerable property paths of `object` that are not omitted. - * - * **Note:** This method is considerably slower than `_.pick`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [paths] The property paths to omit. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omit(object, ['a', 'c']); - * // => { 'b': '2' } - */ -var omit = flatRest(function(object, paths) { - var result = {}; - if (object == null) { - return result; - } - var isDeep = false; - paths = arrayMap(paths, function(path) { - path = castPath(path, object); - isDeep || (isDeep = path.length > 1); - return path; - }); - copyObject(object, getAllKeysIn(object), result); - if (isDeep) { - result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); - } - var length = paths.length; - while (length--) { - baseUnset(result, paths[length]); - } - return result; -}); + case 11: + case "end": + return _context8.stop(); + } + } + }, _callee8, this, [[0, 6]]); + })); -module.exports = omit; + function getAll(_x11) { + return _getAll.apply(this, arguments); + } + return getAll; + }() + /** + * Creates a document + * + * @param {object} doc - Document to create. Optional: you can force the id with the _id attribute + */ -/***/ }), -/* 614 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + }, { + key: "create", + value: function () { + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(_ref) { + var _id, _type, document, hasFixedId, method, endpoint, resp; -var castPath = __webpack_require__(360), - last = __webpack_require__(615), - parent = __webpack_require__(616), - toKey = __webpack_require__(399); + return _regenerator.default.wrap(function _callee9$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + _id = _ref._id, _type = _ref._type, document = (0, _objectWithoutProperties2.default)(_ref, ["_id", "_type"]); + // In case of a fixed id, let's use the dedicated creation endpoint + // https://github.com/cozy/cozy-stack/blob/master/docs/data-system.md#create-a-document-with-a-fixed-id + hasFixedId = !!_id; + method = hasFixedId ? 'PUT' : 'POST'; + endpoint = (0, _utils.uri)(_templateObject4(), this.doctype, hasFixedId ? _id : ''); + _context9.next = 6; + return this.stackClient.fetchJSON(method, endpoint, document); -/** - * The base implementation of `_.unset`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The property path to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - */ -function baseUnset(object, path) { - path = castPath(path, object); - object = parent(object, path); - return object == null || delete object[toKey(last(path))]; -} + case 6: + resp = _context9.sent; + return _context9.abrupt("return", { + data: normalizeDoc(resp.data, this.doctype) + }); -module.exports = baseUnset; + case 8: + case "end": + return _context9.stop(); + } + } + }, _callee9, this); + })); + function create(_x12) { + return _create.apply(this, arguments); + } -/***/ }), -/* 615 */ -/***/ ((module) => { + return create; + }() + /** + * Updates a document + * + * @param {object} document - Document to update. Do not forget the _id attribute + */ -/** - * Gets the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - */ -function last(array) { - var length = array == null ? 0 : array.length; - return length ? array[length - 1] : undefined; -} + }, { + key: "update", + value: function () { + var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(document) { + var resp; + return _regenerator.default.wrap(function _callee10$(_context10) { + while (1) { + switch (_context10.prev = _context10.next) { + case 0: + _context10.next = 2; + return this.stackClient.fetchJSON('PUT', (0, _utils.uri)(_templateObject5(), this.doctype, document._id), document); -module.exports = last; + case 2: + resp = _context10.sent; + return _context10.abrupt("return", { + data: normalizeDoc(resp.data, this.doctype) + }); + case 4: + case "end": + return _context10.stop(); + } + } + }, _callee10, this); + })); -/***/ }), -/* 616 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + function update(_x13) { + return _update.apply(this, arguments); + } -var baseGet = __webpack_require__(359), - baseSlice = __webpack_require__(617); + return update; + }() + /** + * Destroys a document + * + * @param {object} doc - Document to destroy. Do not forget _id and _rev attributes + */ -/** - * Gets the parent value at `path` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} path The path to get the parent value of. - * @returns {*} Returns the parent value. - */ -function parent(object, path) { - return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); -} + }, { + key: "destroy", + value: function () { + var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(_ref2) { + var _id, _rev, document, resp; -module.exports = parent; + return _regenerator.default.wrap(function _callee11$(_context11) { + while (1) { + switch (_context11.prev = _context11.next) { + case 0: + _id = _ref2._id, _rev = _ref2._rev, document = (0, _objectWithoutProperties2.default)(_ref2, ["_id", "_rev"]); + _context11.next = 3; + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), this.doctype, _id, _rev)); + case 3: + resp = _context11.sent; + return _context11.abrupt("return", { + data: normalizeDoc(_objectSpread(_objectSpread({}, document), {}, { + _id: _id, + _rev: resp.rev, + _deleted: true + }), this.doctype) + }); -/***/ }), -/* 617 */ -/***/ ((module) => { + case 5: + case "end": + return _context11.stop(); + } + } + }, _callee11, this); + })); -/** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ -function baseSlice(array, start, end) { - var index = -1, - length = array.length; + function destroy(_x14) { + return _destroy.apply(this, arguments); + } - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; + return destroy; + }() + /** + * Updates several documents in one batch + * + * @param {Document[]} rawDocs Documents to be updated + */ - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; -} + }, { + key: "updateAll", + value: function () { + var _updateAll = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(rawDocs) { + var stackClient, docs, update, firstDoc, resp; + return _regenerator.default.wrap(function _callee12$(_context12) { + while (1) { + switch (_context12.prev = _context12.next) { + case 0: + stackClient = this.stackClient; + docs = rawDocs ? rawDocs.map(function (d) { + return (0, _omit.default)(d, '_type'); + }) : rawDocs; -module.exports = baseSlice; + if (!(!docs || !docs.length)) { + _context12.next = 4; + break; + } + return _context12.abrupt("return", Promise.resolve([])); -/***/ }), -/* 618 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 4: + _context12.prev = 4; + _context12.next = 7; + return stackClient.fetchJSON('POST', "/data/".concat(this.doctype, "/_bulk_docs"), { + docs: docs + }); -var isPlainObject = __webpack_require__(619); + case 7: + update = _context12.sent; + return _context12.abrupt("return", update); -/** - * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain - * objects. - * - * @private - * @param {*} value The value to inspect. - * @param {string} key The key of the property to inspect. - * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. - */ -function customOmitClone(value) { - return isPlainObject(value) ? undefined : value; -} + case 11: + _context12.prev = 11; + _context12.t0 = _context12["catch"](4); -module.exports = customOmitClone; + if (!(_context12.t0.reason && _context12.t0.reason.reason && _context12.t0.reason.reason === DATABASE_DOES_NOT_EXIST)) { + _context12.next = 24; + break; + } + _context12.next = 16; + return this.create(docs[0]); -/***/ }), -/* 619 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 16: + firstDoc = _context12.sent; + _context12.next = 19; + return this.updateAll(docs.slice(1)); -var baseGetTag = __webpack_require__(46), - getPrototype = __webpack_require__(575), - isObjectLike = __webpack_require__(53); + case 19: + resp = _context12.sent; + resp.unshift({ + ok: true, + id: firstDoc._id, + rev: firstDoc._rev + }); + return _context12.abrupt("return", resp); -/** `Object#toString` result references. */ -var objectTag = '[object Object]'; + case 24: + throw _context12.t0; -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; + case 25: + case "end": + return _context12.stop(); + } + } + }, _callee12, this, [[4, 11]]); + })); -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + function updateAll(_x15) { + return _updateAll.apply(this, arguments); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + return updateAll; + }() + /** + * Deletes several documents in one batch + * + * @param {Document[]} docs - Documents to delete + */ -/** Used to infer the `Object` constructor. */ -var objectCtorString = funcToString.call(Object); + }, { + key: "destroyAll", + value: function destroyAll(docs) { + return this.updateAll(docs.map(prepareForDeletion)); + } + }, { + key: "toMangoOptions", + value: function toMangoOptions(selector) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var sort = options.sort, + indexedFields = options.indexedFields; + var fields = options.fields, + _options$skip3 = options.skip, + skip = _options$skip3 === void 0 ? 0 : _options$skip3, + limit = options.limit, + bookmark = options.bookmark; + sort = (0, _mangoIndex.transformSort)(sort); + indexedFields = indexedFields ? indexedFields : (0, _mangoIndex.getIndexFields)({ + sort: sort, + selector: selector + }); + var indexName = options.indexId || "_design/".concat((0, _mangoIndex.getIndexNameFromFields)(indexedFields)); -/** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ -function isPlainObject(value) { - if (!isObjectLike(value) || baseGetTag(value) != objectTag) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString.call(Ctor) == objectCtorString; -} + if (sort) { + var sortOrders = (0, _uniq.default)(sort.map(function (sortOption) { + return (0, _head.default)(Object.values(sortOption)); + })); + if (sortOrders.length > 1) throw new Error('Mango sort can only use a single order (asc or desc).'); + var sortOrder = sortOrders.length > 0 ? (0, _head.default)(sortOrders) : 'asc'; -module.exports = isPlainObject; + var _iterator = _createForOfIteratorHelper(indexedFields), + _step; + try { + var _loop = function _loop() { + var field = _step.value; + if (!sort.find(function (sortOption) { + return (0, _head.default)(Object.keys(sortOption)) === field; + })) sort.push((0, _defineProperty2.default)({}, field, sortOrder)); + }; -/***/ }), -/* 620 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + _loop(); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } -var flatten = __webpack_require__(540), - overRest = __webpack_require__(545), - setToString = __webpack_require__(547); + var opts = { + selector: selector, + use_index: indexName, + // TODO: type and class should not be necessary, it's just a temp fix for a stack bug + fields: fields ? [].concat((0, _toConsumableArray2.default)(fields), ['_id', '_type', 'class']) : undefined, + limit: limit, + skip: skip, + bookmark: options.bookmark || bookmark, + sort: sort, + execution_stats: (0, _cozyFlags.default)('debug') ? true : undefined + }; + return opts; + } + }, { + key: "checkUniquenessOf", + value: function () { + var _checkUniquenessOf = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(property, value) { + var indexId, existingDocs; + return _regenerator.default.wrap(function _callee13$(_context13) { + while (1) { + switch (_context13.prev = _context13.next) { + case 0: + _context13.next = 2; + return this.getUniqueIndexId(property); -/** - * A specialized version of `baseRest` which flattens the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @returns {Function} Returns the new function. - */ -function flatRest(func) { - return setToString(overRest(func, undefined, flatten), func + ''); -} + case 2: + indexId = _context13.sent; + _context13.next = 5; + return this.find((0, _defineProperty2.default)({}, property, value), { + indexId: indexId, + fields: ['_id'] + }); -module.exports = flatRest; + case 5: + existingDocs = _context13.sent; + return _context13.abrupt("return", existingDocs.data.length === 0); + case 7: + case "end": + return _context13.stop(); + } + } + }, _callee13, this); + })); -/***/ }), -/* 621 */ -/***/ ((module) => { + function checkUniquenessOf(_x16, _x17) { + return _checkUniquenessOf.apply(this, arguments); + } -/** - * Gets the first element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias first - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. - * @example - * - * _.head([1, 2, 3]); - * // => 1 - * - * _.head([]); - * // => undefined - */ -function head(array) { - return (array && array.length) ? array[0] : undefined; -} + return checkUniquenessOf; + }() + }, { + key: "getUniqueIndexId", + value: function getUniqueIndexId(property) { + return this.getIndexId([property], { + indexName: "".concat(this.doctype, "/").concat(property) + }); + } + }, { + key: "getIndexId", + value: function () { + var _getIndexId = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(fields, _ref3) { + var partialFilter, _ref3$indexName, indexName, index; -module.exports = head; + return _regenerator.default.wrap(function _callee14$(_context14) { + while (1) { + switch (_context14.prev = _context14.next) { + case 0: + partialFilter = _ref3.partialFilter, _ref3$indexName = _ref3.indexName, indexName = _ref3$indexName === void 0 ? this.getIndexNameFromFields(fields) : _ref3$indexName; + if (this.indexes[indexName]) { + _context14.next = 20; + break; + } -/***/ }), -/* 622 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + _context14.prev = 2; + _context14.next = 5; + return this.createIndex(fields, { + partialFilter: partialFilter + }); -var baseClamp = __webpack_require__(623), - baseToString = __webpack_require__(397), - toInteger = __webpack_require__(624), - toString = __webpack_require__(396); + case 5: + index = _context14.sent; + _context14.next = 19; + break; -/** - * Checks if `string` starts with the given target string. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to inspect. - * @param {string} [target] The string to search for. - * @param {number} [position=0] The position to search from. - * @returns {boolean} Returns `true` if `string` starts with `target`, - * else `false`. - * @example - * - * _.startsWith('abc', 'a'); - * // => true - * - * _.startsWith('abc', 'b'); - * // => false - * - * _.startsWith('abc', 'b', 1); - * // => true - */ -function startsWith(string, target, position) { - string = toString(string); - position = position == null - ? 0 - : baseClamp(toInteger(position), 0, string.length); + case 8: + _context14.prev = 8; + _context14.t0 = _context14["catch"](2); - target = baseToString(target); - return string.slice(position, position + target.length) == target; -} + if ((0, _Collection.isIndexConflictError)(_context14.t0)) { + _context14.next = 14; + break; + } -module.exports = startsWith; + throw _context14.t0; + case 14: + _context14.next = 16; + return (0, _utils.sleep)(1000); -/***/ }), -/* 623 */ -/***/ ((module) => { + case 16: + _context14.next = 18; + return this.createIndex(fields, { + partialFilter: partialFilter + }); -/** - * The base implementation of `_.clamp` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - */ -function baseClamp(number, lower, upper) { - if (number === number) { - if (upper !== undefined) { - number = number <= upper ? number : upper; - } - if (lower !== undefined) { - number = number >= lower ? number : lower; - } - } - return number; -} + case 18: + index = _context14.sent; -module.exports = baseClamp; + case 19: + this.indexes[indexName] = index; + case 20: + return _context14.abrupt("return", this.indexes[indexName].id); -/***/ }), -/* 624 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 21: + case "end": + return _context14.stop(); + } + } + }, _callee14, this, [[2, 8]]); + })); -var toFinite = __webpack_require__(625); + function getIndexId(_x18, _x19) { + return _getIndexId.apply(this, arguments); + } -/** - * Converts `value` to an integer. - * - * **Note:** This method is loosely based on - * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toInteger(3.2); - * // => 3 - * - * _.toInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toInteger(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toInteger('3.2'); - * // => 3 - */ -function toInteger(value) { - var result = toFinite(value), - remainder = result % 1; + return getIndexId; + }() + }, { + key: "createIndex", + value: function () { + var _createIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(fields) { + var _ref4, + partialFilter, + indexName, + indexDef, + resp, + indexResp, + selector, + options, + _args15 = arguments; - return result === result ? (remainder ? result - remainder : result) : 0; -} + return _regenerator.default.wrap(function _callee15$(_context15) { + while (1) { + switch (_context15.prev = _context15.next) { + case 0: + _ref4 = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : {}, partialFilter = _ref4.partialFilter, indexName = _ref4.indexName; + indexDef = { + index: { + fields: fields + } + }; -module.exports = toInteger; + if (indexName) { + indexDef.ddoc = indexName; + } + if (partialFilter) { + indexDef.index.partial_filter_selector = partialFilter; + } -/***/ }), -/* 625 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + _context15.prev = 4; + _context15.next = 7; + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject7(), this.doctype), indexDef); -var toNumber = __webpack_require__(626); + case 7: + resp = _context15.sent; + _context15.next = 17; + break; -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0, - MAX_INTEGER = 1.7976931348623157e+308; + case 10: + _context15.prev = 10; + _context15.t0 = _context15["catch"](4); -/** - * Converts `value` to a finite number. - * - * @static - * @memberOf _ - * @since 4.12.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted number. - * @example - * - * _.toFinite(3.2); - * // => 3.2 - * - * _.toFinite(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toFinite(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toFinite('3.2'); - * // => 3.2 - */ -function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; - } - return value === value ? value : 0; -} + if ((0, _Collection.isIndexConflictError)(_context15.t0)) { + _context15.next = 16; + break; + } -module.exports = toFinite; + throw _context15.t0; + case 16: + return _context15.abrupt("return"); -/***/ }), -/* 626 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 17: + indexResp = { + id: resp.id, + fields: fields + }; -var baseTrim = __webpack_require__(627), - isObject = __webpack_require__(52), - isSymbol = __webpack_require__(362); + if (!(resp.result === 'exists')) { + _context15.next = 20; + break; + } -/** Used as references for various `Number` constants. */ -var NAN = 0 / 0; + return _context15.abrupt("return", indexResp); -/** Used to detect bad signed hexadecimal string values. */ -var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + case 20: + // indexes might not be usable right after being created; so we delay the resolving until they are + selector = {}; + fields.forEach(function (f) { + return selector[f] = { + $gt: null + }; + }); + options = { + indexId: indexResp.id, + limit: 1 + }; + _context15.next = 25; + return (0, _utils.attempt)(this.find(selector, options)); -/** Used to detect binary string values. */ -var reIsBinary = /^0b[01]+$/i; + case 25: + if (!_context15.sent) { + _context15.next = 27; + break; + } -/** Used to detect octal string values. */ -var reIsOctal = /^0o[0-7]+$/i; + return _context15.abrupt("return", indexResp); -/** Built-in method references without a dependency on `root`. */ -var freeParseInt = parseInt; + case 27: + _context15.next = 29; + return (0, _utils.sleep)(1000); -/** - * Converts `value` to a number. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {number} Returns the number. - * @example - * - * _.toNumber(3.2); - * // => 3.2 - * - * _.toNumber(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toNumber(Infinity); - * // => Infinity - * - * _.toNumber('3.2'); - * // => 3.2 - */ -function toNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject(value)) { - var other = typeof value.valueOf == 'function' ? value.valueOf() : value; - value = isObject(other) ? (other + '') : other; - } - if (typeof value != 'string') { - return value === 0 ? value : +value; - } - value = baseTrim(value); - var isBinary = reIsBinary.test(value); - return (isBinary || reIsOctal.test(value)) - ? freeParseInt(value.slice(2), isBinary ? 2 : 8) - : (reIsBadHex.test(value) ? NAN : +value); -} + case 29: + _context15.next = 31; + return (0, _utils.attempt)(this.find(selector, options)); -module.exports = toNumber; + case 31: + if (!_context15.sent) { + _context15.next = 33; + break; + } + return _context15.abrupt("return", indexResp); -/***/ }), -/* 627 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 33: + _context15.next = 35; + return (0, _utils.sleep)(500); -var trimmedEndIndex = __webpack_require__(628); + case 35: + return _context15.abrupt("return", indexResp); -/** Used to match leading whitespace. */ -var reTrimStart = /^\s+/; + case 36: + case "end": + return _context15.stop(); + } + } + }, _callee15, this, [[4, 10]]); + })); -/** - * The base implementation of `_.trim`. - * - * @private - * @param {string} string The string to trim. - * @returns {string} Returns the trimmed string. - */ -function baseTrim(string) { - return string - ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') - : string; -} + function createIndex(_x20) { + return _createIndex.apply(this, arguments); + } -module.exports = baseTrim; + return createIndex; + }() + /** + * Retrieve all design docs of mango indexes + * + * @returns {Array} The design docs + */ + }, { + key: "fetchAllMangoIndexes", + value: function () { + var _fetchAllMangoIndexes = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16() { + var path, indexes; + return _regenerator.default.wrap(function _callee16$(_context16) { + while (1) { + switch (_context16.prev = _context16.next) { + case 0: + path = (0, _utils.uri)(_templateObject8(), this.doctype); + _context16.next = 3; + return this.stackClient.fetchJSON('GET', path); -/***/ }), -/* 628 */ -/***/ ((module) => { + case 3: + indexes = _context16.sent; + return _context16.abrupt("return", indexes.rows.filter(function (index) { + return index.doc.language === 'query'; + }).map(function (doc) { + return (0, _mangoIndex.normalizeDesignDoc)(doc); + })); -/** Used to match a single whitespace character. */ -var reWhitespace = /\s/; + case 5: + case "end": + return _context16.stop(); + } + } + }, _callee16, this); + })); -/** - * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace - * character of `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the index of the last non-whitespace character. - */ -function trimmedEndIndex(string) { - var index = string.length; + function fetchAllMangoIndexes() { + return _fetchAllMangoIndexes.apply(this, arguments); + } - while (index-- && reWhitespace.test(string.charAt(index))) {} - return index; -} + return fetchAllMangoIndexes; + }() + /** + * Delete the specified design doc + * + * @param {object} index - The design doc to remove + * @returns {object} The delete response + */ -module.exports = trimmedEndIndex; + }, { + key: "destroyIndex", + value: function () { + var _destroyIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(index) { + var ddoc, rev, path; + return _regenerator.default.wrap(function _callee17$(_context17) { + while (1) { + switch (_context17.prev = _context17.next) { + case 0: + ddoc = index._id.split('/')[1]; + rev = index._rev; + path = (0, _utils.uri)(_templateObject9(), this.doctype, ddoc, rev); + return _context17.abrupt("return", this.stackClient.fetchJSON('DELETE', path)); + case 4: + case "end": + return _context17.stop(); + } + } + }, _callee17, this); + })); -/***/ }), -/* 629 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + function destroyIndex(_x21) { + return _destroyIndex.apply(this, arguments); + } -"use strict"; + return destroyIndex; + }() + /** + * Copy an existing design doc. + * + * This is useful to create a new design doc without + * having to recompute the existing index. + * + * @param {object} existingIndex - The design doc to copy + * @param {string} newIndexName - The name of the copy + * @returns {object} The copy response + */ + }, { + key: "copyIndex", + value: function () { + var _copyIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(existingIndex, newIndexName) { + var ddoc, rev, path, options; + return _regenerator.default.wrap(function _callee18$(_context18) { + while (1) { + switch (_context18.prev = _context18.next) { + case 0: + ddoc = existingIndex._id.split('/')[1]; + rev = existingIndex._rev; + path = (0, _utils.uri)(_templateObject10(), this.doctype, ddoc, rev); + options = { + headers: { + Destination: "_design/".concat(newIndexName) + } + }; + return _context18.abrupt("return", this.stackClient.fetchJSON('POST', path, null, options)); -var stringify = __webpack_require__(630); -var parse = __webpack_require__(644); -var formats = __webpack_require__(643); + case 5: + case "end": + return _context18.stop(); + } + } + }, _callee18, this); + })); -module.exports = { - formats: formats, - parse: parse, - stringify: stringify -}; + function copyIndex(_x22, _x23) { + return _copyIndex.apply(this, arguments); + } + return copyIndex; + }() + /** + * Find an existing mango index based on the query definition + * + * This is useful to avoid creating new indexes having the + * same definition of an existing one. + * + * @param {object} selector The query selector + * @param {MangoQueryOptions} options The find options + * + * @returns {object} A matching index if it exists + * @private + */ -/***/ }), -/* 630 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + }, { + key: "findExistingIndex", + value: function () { + var _findExistingIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(selector, options) { + var sort, indexedFields, partialFilter, indexes, fieldsToIndex, existingIndex, _iterator2, _step2, index; -"use strict"; + return _regenerator.default.wrap(function _callee19$(_context19) { + while (1) { + switch (_context19.prev = _context19.next) { + case 0: + sort = options.sort, indexedFields = options.indexedFields, partialFilter = options.partialFilter; + _context19.next = 3; + return this.fetchAllMangoIndexes(); + case 3: + indexes = _context19.sent; -var getSideChannel = __webpack_require__(631); -var utils = __webpack_require__(642); -var formats = __webpack_require__(643); -var has = Object.prototype.hasOwnProperty; + if (!(indexes.length < 1)) { + _context19.next = 6; + break; + } -var arrayPrefixGenerators = { - brackets: function brackets(prefix) { - return prefix + '[]'; - }, - comma: 'comma', - indices: function indices(prefix, key) { - return prefix + '[' + key + ']'; - }, - repeat: function repeat(prefix) { - return prefix; - } -}; + return _context19.abrupt("return", null); -var isArray = Array.isArray; -var push = Array.prototype.push; -var pushToArray = function (arr, valueOrArray) { - push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]); -}; + case 6: + sort = (0, _mangoIndex.transformSort)(sort); + fieldsToIndex = indexedFields ? indexedFields : (0, _mangoIndex.getIndexFields)({ + sort: sort, + selector: selector + }); + existingIndex = indexes.find(function (index) { + return (0, _mangoIndex.isMatchingIndex)(index, fieldsToIndex, partialFilter); + }); + _iterator2 = _createForOfIteratorHelper(indexes); + _context19.prev = 10; -var toISO = Date.prototype.toISOString; + _iterator2.s(); -var defaultFormat = formats['default']; -var defaults = { - addQueryPrefix: false, - allowDots: false, - charset: 'utf-8', - charsetSentinel: false, - delimiter: '&', - encode: true, - encoder: utils.encode, - encodeValuesOnly: false, - format: defaultFormat, - formatter: formats.formatters[defaultFormat], - // deprecated - indices: false, - serializeDate: function serializeDate(date) { - return toISO.call(date); - }, - skipNulls: false, - strictNullHandling: false -}; + case 12: + if ((_step2 = _iterator2.n()).done) { + _context19.next = 19; + break; + } -var isNonNullishPrimitive = function isNonNullishPrimitive(v) { - return typeof v === 'string' - || typeof v === 'number' - || typeof v === 'boolean' - || typeof v === 'symbol' - || typeof v === 'bigint'; -}; + index = _step2.value; -var stringify = function stringify( - object, - prefix, - generateArrayPrefix, - strictNullHandling, - skipNulls, - encoder, - filter, - sort, - allowDots, - serializeDate, - format, - formatter, - encodeValuesOnly, - charset, - sideChannel -) { - var obj = object; + if (!(0, _mangoIndex.isInconsistentIndex)(index)) { + _context19.next = 17; + break; + } - if (sideChannel.has(object)) { - throw new RangeError('Cyclic object value'); - } + _context19.next = 17; + return this.destroyIndex(index); - if (typeof filter === 'function') { - obj = filter(prefix, obj); - } else if (obj instanceof Date) { - obj = serializeDate(obj); - } else if (generateArrayPrefix === 'comma' && isArray(obj)) { - obj = utils.maybeMap(obj, function (value) { - if (value instanceof Date) { - return serializeDate(value); - } - return value; - }); - } + case 17: + _context19.next = 12; + break; - if (obj === null) { - if (strictNullHandling) { - return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix; - } + case 19: + _context19.next = 24; + break; - obj = ''; - } + case 21: + _context19.prev = 21; + _context19.t0 = _context19["catch"](10); - if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) { - if (encoder) { - var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format); - return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))]; - } - return [formatter(prefix) + '=' + formatter(String(obj))]; - } + _iterator2.e(_context19.t0); - var values = []; + case 24: + _context19.prev = 24; - if (typeof obj === 'undefined') { - return values; - } + _iterator2.f(); - var objKeys; - if (generateArrayPrefix === 'comma' && isArray(obj)) { - // we need to join elements in - objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }]; - } else if (isArray(filter)) { - objKeys = filter; - } else { - var keys = Object.keys(obj); - objKeys = sort ? keys.sort(sort) : keys; - } + return _context19.finish(24); - for (var i = 0; i < objKeys.length; ++i) { - var key = objKeys[i]; - var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key]; + case 27: + return _context19.abrupt("return", existingIndex); - if (skipNulls && value === null) { - continue; - } + case 28: + case "end": + return _context19.stop(); + } + } + }, _callee19, this, [[10, 21, 24, 27]]); + })); - var keyPrefix = isArray(obj) - ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix - : prefix + (allowDots ? '.' + key : '[' + key + ']'); + function findExistingIndex(_x24, _x25) { + return _findExistingIndex.apply(this, arguments); + } - sideChannel.set(object, true); - var valueSideChannel = getSideChannel(); - pushToArray(values, stringify( - value, - keyPrefix, - generateArrayPrefix, - strictNullHandling, - skipNulls, - encoder, - filter, - sort, - allowDots, - serializeDate, - format, - formatter, - encodeValuesOnly, - charset, - valueSideChannel - )); - } + return findExistingIndex; + }() + /** + * Calls _changes route from CouchDB + * No further treatment is done contrary to fetchchanges + * + * @param {object} couchOptions - Couch options for changes https://kutt.it/5r7MNQ + * @param {string} [couchOptions.since] - Bookmark telling CouchDB from which point in time should changes be returned + * @param {Array<string>} [couchOptions.doc_ids] - Only return changes for a subset of documents + * @param {boolean} [couchOptions.includeDocs] - Includes full documents as part of results + * + * @see https://docs.couchdb.org/en/stable/api/database/changes.html + */ - return values; -}; + }, { + key: "fetchChangesRaw", + value: function () { + var _fetchChangesRaw = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20(couchOptions) { + var hasDocIds, urlParams, method, endpoint, params, result; + return _regenerator.default.wrap(function _callee20$(_context20) { + while (1) { + switch (_context20.prev = _context20.next) { + case 0: + hasDocIds = couchOptions.doc_ids && couchOptions.doc_ids.length > 0; + urlParams = "?".concat([_qs.default.stringify(_objectSpread(_objectSpread({}, (0, _omit.default)(couchOptions, ['doc_ids', 'includeDocs'])), {}, { + include_docs: couchOptions.includeDocs + })), hasDocIds && couchOptions.filter === undefined ? 'filter=_doc_ids' : undefined].filter(Boolean).join('&')); + method = hasDocIds ? 'POST' : 'GET'; + endpoint = "/data/".concat(this.doctype, "/_changes").concat(urlParams); + params = hasDocIds ? { + doc_ids: couchOptions.doc_ids + } : undefined; + _context20.next = 7; + return this.stackClient.fetchJSON(method, endpoint, params); -var normalizeStringifyOptions = function normalizeStringifyOptions(opts) { - if (!opts) { - return defaults; - } + case 7: + result = _context20.sent; + return _context20.abrupt("return", result); - if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') { - throw new TypeError('Encoder has to be a function.'); - } + case 9: + case "end": + return _context20.stop(); + } + } + }, _callee20, this); + })); - var charset = opts.charset || defaults.charset; - if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { - throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); - } + function fetchChangesRaw(_x26) { + return _fetchChangesRaw.apply(this, arguments); + } - var format = formats['default']; - if (typeof opts.format !== 'undefined') { - if (!has.call(formats.formatters, opts.format)) { - throw new TypeError('Unknown format option provided.'); - } - format = opts.format; - } - var formatter = formats.formatters[format]; + return fetchChangesRaw; + }() + /** + * Use Couch _changes API + * Deleted and design docs are filtered by default, thus documents are retrieved in the response + * (include_docs is set to true in the parameters of _changes). + * + * You should use fetchChangesRaw to have low level control on _changes parameters. + * + * @param {object} couchOptions - Couch options for changes + * @param {string} [couchOptions.since] - Bookmark telling CouchDB from which point in time should changes be returned + * @param {Array<string>} [couchOptions.doc_ids] - Only return changes for a subset of documents + * + * @param {object} options - Further options on the returned documents. By default, it is set to { includeDesign: false, includeDeleted: false } + * @param {boolean} [options.includeDesign] - Whether to include changes from design docs (needs include_docs to be true) + * @param {boolean} [options.includeDeleted] - Whether to include changes for deleted documents (needs include_docs to be true) + * + * @typedef {object} FetchChangesReturnValue + * @property {string} newLastSeq + * @property {Array<object>} documents + * @returns {FetchChangesReturnValue} + */ - var filter = defaults.filter; - if (typeof opts.filter === 'function' || isArray(opts.filter)) { - filter = opts.filter; - } + }, { + key: "fetchChanges", + value: function () { + var _fetchChanges = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21() { + var couchOptions, + options, + opts, + result, + newLastSeq, + docs, + _args21 = arguments; + return _regenerator.default.wrap(function _callee21$(_context21) { + while (1) { + switch (_context21.prev = _context21.next) { + case 0: + couchOptions = _args21.length > 0 && _args21[0] !== undefined ? _args21[0] : {}; + options = _args21.length > 1 && _args21[1] !== undefined ? _args21[1] : {}; + opts = { + // Necessary since we deal with deleted and design docs later + includeDocs: true + }; - return { - addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix, - allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots, - charset: charset, - charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, - delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter, - encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode, - encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder, - encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly, - filter: filter, - format: format, - formatter: formatter, - serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate, - skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls, - sort: typeof opts.sort === 'function' ? opts.sort : null, - strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling - }; -}; + if (typeof couchOptions !== 'object') { + opts.since = couchOptions; + console.warn("fetchChanges use couchOptions as Object not a string, since is deprecated, please use fetchChanges({since: \"".concat(couchOptions, "\"}).")); + } else if (Object.keys(couchOptions).length > 0) { + Object.assign(opts, couchOptions); + } -module.exports = function (object, opts) { - var obj = object; - var options = normalizeStringifyOptions(opts); + _context21.next = 6; + return this.fetchChangesRaw(opts); - var objKeys; - var filter; + case 6: + result = _context21.sent; + newLastSeq = result.last_seq; + docs = result.results.map(function (x) { + return x.doc; + }).filter(Boolean); - if (typeof options.filter === 'function') { - filter = options.filter; - obj = filter('', obj); - } else if (isArray(options.filter)) { - filter = options.filter; - objKeys = filter; - } + if (!options.includeDesign) { + docs = docs.filter(function (doc) { + return doc._id.indexOf('_design') !== 0; + }); + } - var keys = []; + if (!options.includeDeleted) { + docs = docs.filter(function (doc) { + return !doc._deleted; + }); + } - if (typeof obj !== 'object' || obj === null) { - return ''; - } + return _context21.abrupt("return", { + newLastSeq: newLastSeq, + documents: docs + }); - var arrayFormat; - if (opts && opts.arrayFormat in arrayPrefixGenerators) { - arrayFormat = opts.arrayFormat; - } else if (opts && 'indices' in opts) { - arrayFormat = opts.indices ? 'indices' : 'repeat'; - } else { - arrayFormat = 'indices'; - } + case 12: + case "end": + return _context21.stop(); + } + } + }, _callee21, this); + })); - var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; + function fetchChanges() { + return _fetchChanges.apply(this, arguments); + } - if (!objKeys) { - objKeys = Object.keys(obj); + return fetchChanges; + }() + }], [{ + key: "normalizeDoctype", + value: function normalizeDoctype(doctype) { + return this.normalizeDoctypeRawApi(doctype); } + /** + * `normalizeDoctype` for api end points returning json api responses + * + * @private + * @param {string} doctype - Document doctype + * @returns {Function} (data, response) => normalizedDocument + * using `normalizeDoc` + */ - if (options.sort) { - objKeys.sort(options.sort); + }, { + key: "normalizeDoctypeJsonApi", + value: function normalizeDoctypeJsonApi(doctype) { + return function (data, response) { + // use the "data" attribute of the response + return normalizeDoc(data, doctype); + }; } + /** + * `normalizeDoctype` for api end points returning raw documents + * + * @private + * @param {string} doctype - Document doctype + * @returns {Function} (data, response) => normalizedDocument + * using `normalizeDoc` + */ - var sideChannel = getSideChannel(); - for (var i = 0; i < objKeys.length; ++i) { - var key = objKeys[i]; - - if (options.skipNulls && obj[key] === null) { - continue; - } - pushToArray(keys, stringify( - obj[key], - key, - generateArrayPrefix, - options.strictNullHandling, - options.skipNulls, - options.encode ? options.encoder : null, - options.filter, - options.sort, - options.allowDots, - options.serializeDate, - options.format, - options.formatter, - options.encodeValuesOnly, - options.charset, - sideChannel - )); + }, { + key: "normalizeDoctypeRawApi", + value: function normalizeDoctypeRawApi(doctype) { + return function (data, response) { + // use the response directly + return normalizeDoc(response, doctype); + }; } + }]); + return DocumentCollection; +}(); - var joined = keys.join(options.delimiter); - var prefix = options.addQueryPrefix === true ? '?' : ''; +var _default = DocumentCollection; +exports["default"] = _default; +var normalizeDoctype = DocumentCollection.normalizeDoctype; +exports.normalizeDoctype = normalizeDoctype; - if (options.charsetSentinel) { - if (options.charset === 'iso-8859-1') { - // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark - prefix += 'utf8=%26%2310003%3B&'; - } else { - // encodeURIComponent('✓') - prefix += 'utf8=%E2%9C%93&'; - } - } +/***/ }), +/* 614 */ +/***/ ((module) => { - return joined.length > 0 ? prefix + joined : ''; -}; +function _taggedTemplateLiteral(strings, raw) { + if (!raw) { + raw = strings.slice(0); + } + + return Object.freeze(Object.defineProperties(strings, { + raw: { + value: Object.freeze(raw) + } + })); +} +module.exports = _taggedTemplateLiteral; +module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), -/* 631 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 615 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); -var callBound = __webpack_require__(638); -var inspect = __webpack_require__(640); - -var $TypeError = GetIntrinsic('%TypeError%'); -var $WeakMap = GetIntrinsic('%WeakMap%', true); -var $Map = GetIntrinsic('%Map%', true); - -var $weakMapGet = callBound('WeakMap.prototype.get', true); -var $weakMapSet = callBound('WeakMap.prototype.set', true); -var $weakMapHas = callBound('WeakMap.prototype.has', true); -var $mapGet = callBound('Map.prototype.get', true); -var $mapSet = callBound('Map.prototype.set', true); -var $mapHas = callBound('Map.prototype.has', true); +var _interopRequireDefault = __webpack_require__(524); -/* - * This function traverses the list returning the node corresponding to the - * given key. - * - * That node is also moved to the head of the list, so that if it's accessed - * again we don't need to traverse the whole list. By doing so, all the recently - * used nodes can be accessed relatively quickly. - */ -var listGetNode = function (list, key) { // eslint-disable-line consistent-return - for (var prev = list, curr; (curr = prev.next) !== null; prev = curr) { - if (curr.key === key) { - prev.next = curr.next; - curr.next = list.next; - list.next = curr; // eslint-disable-line no-param-reassign - return curr; - } - } -}; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -var listGet = function (objects, key) { - var node = listGetNode(objects, key); - return node && node.value; -}; -var listSet = function (objects, key, value) { - var node = listGetNode(objects, key); - if (node) { - node.value = value; - } else { - // Prepend the new node to the beginning of the list - objects.next = { // eslint-disable-line no-param-reassign - key: key, - next: objects.next, - value: value - }; - } -}; -var listHas = function (objects, key) { - return !!listGetNode(objects, key); -}; +var _flag = _interopRequireDefault(__webpack_require__(616)); -module.exports = function getSideChannel() { - var $wm; - var $m; - var $o; - var channel = { - assert: function (key) { - if (!channel.has(key)) { - throw new $TypeError('Side channel does not contain ' + inspect(key)); - } - }, - get: function (key) { // eslint-disable-line consistent-return - if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { - if ($wm) { - return $weakMapGet($wm, key); - } - } else if ($Map) { - if ($m) { - return $mapGet($m, key); - } - } else { - if ($o) { // eslint-disable-line no-lonely-if - return listGet($o, key); - } - } - }, - has: function (key) { - if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { - if ($wm) { - return $weakMapHas($wm, key); - } - } else if ($Map) { - if ($m) { - return $mapHas($m, key); - } - } else { - if ($o) { // eslint-disable-line no-lonely-if - return listHas($o, key); - } - } - return false; - }, - set: function (key, value) { - if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { - if (!$wm) { - $wm = new $WeakMap(); - } - $weakMapSet($wm, key, value); - } else if ($Map) { - if (!$m) { - $m = new $Map(); - } - $mapSet($m, key, value); - } else { - if (!$o) { - /* - * Initialize the linked list as an empty node, so that we don't have - * to special-case handling of the first node: we can always refer to - * it as (previous node).next, instead of something like (list).head - */ - $o = { key: {}, next: null }; - } - listSet($o, key, value); - } - } - }; - return channel; -}; +/* global __ENABLED_FLAGS__ */ +if (typeof __ENABLED_FLAGS__ !== 'undefined') { + _flag.default.enable(__ENABLED_FLAGS__); +} +var _default = _flag.default; +exports["default"] = _default; /***/ }), -/* 632 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 616 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var undefined; +var _interopRequireDefault = __webpack_require__(524); -var $SyntaxError = SyntaxError; -var $Function = Function; -var $TypeError = TypeError; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.resetFlags = exports.listFlags = exports.initializeFromRemote = exports.initializeFromDOM = exports.initialize = exports.getTemplateData = exports.enable = exports["default"] = void 0; -// eslint-disable-next-line consistent-return -var getEvalledConstructor = function (expressionSyntax) { - try { - return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')(); - } catch (e) {} -}; +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var $gOPD = Object.getOwnPropertyDescriptor; -if ($gOPD) { - try { - $gOPD({}, ''); - } catch (e) { - $gOPD = null; // this is IE 8, which has a broken gOPD - } -} +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var throwTypeError = function () { - throw new $TypeError(); -}; -var ThrowTypeError = $gOPD - ? (function () { - try { - // eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties - arguments.callee; // IE 8 does not throw here - return throwTypeError; - } catch (calleeThrows) { - try { - // IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '') - return $gOPD(arguments, 'callee').get; - } catch (gOPDthrows) { - return throwTypeError; - } - } - }()) - : throwTypeError; +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var hasSymbols = __webpack_require__(633)(); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto +var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532)); -var needsEval = {}; +var _store = _interopRequireDefault(__webpack_require__(617)); -var TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array); +var _dsl = __webpack_require__(619); -var INTRINSICS = { - '%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError, - '%Array%': Array, - '%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer, - '%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined, - '%AsyncFromSyncIteratorPrototype%': undefined, - '%AsyncFunction%': needsEval, - '%AsyncGenerator%': needsEval, - '%AsyncGeneratorFunction%': needsEval, - '%AsyncIteratorPrototype%': needsEval, - '%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics, - '%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt, - '%Boolean%': Boolean, - '%DataView%': typeof DataView === 'undefined' ? undefined : DataView, - '%Date%': Date, - '%decodeURI%': decodeURI, - '%decodeURIComponent%': decodeURIComponent, - '%encodeURI%': encodeURI, - '%encodeURIComponent%': encodeURIComponent, - '%Error%': Error, - '%eval%': eval, // eslint-disable-line no-eval - '%EvalError%': EvalError, - '%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array, - '%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array, - '%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry, - '%Function%': $Function, - '%GeneratorFunction%': needsEval, - '%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array, - '%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array, - '%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array, - '%isFinite%': isFinite, - '%isNaN%': isNaN, - '%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined, - '%JSON%': typeof JSON === 'object' ? JSON : undefined, - '%Map%': typeof Map === 'undefined' ? undefined : Map, - '%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()), - '%Math%': Math, - '%Number%': Number, - '%Object%': Object, - '%parseFloat%': parseFloat, - '%parseInt%': parseInt, - '%Promise%': typeof Promise === 'undefined' ? undefined : Promise, - '%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy, - '%RangeError%': RangeError, - '%ReferenceError%': ReferenceError, - '%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect, - '%RegExp%': RegExp, - '%Set%': typeof Set === 'undefined' ? undefined : Set, - '%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()), - '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer, - '%String%': String, - '%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined, - '%Symbol%': hasSymbols ? Symbol : undefined, - '%SyntaxError%': $SyntaxError, - '%ThrowTypeError%': ThrowTypeError, - '%TypedArray%': TypedArray, - '%TypeError%': $TypeError, - '%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array, - '%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray, - '%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array, - '%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array, - '%URIError%': URIError, - '%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap, - '%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef, - '%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet -}; +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } -var doEval = function doEval(name) { - var value; - if (name === '%AsyncFunction%') { - value = getEvalledConstructor('async function () {}'); - } else if (name === '%GeneratorFunction%') { - value = getEvalledConstructor('function* () {}'); - } else if (name === '%AsyncGeneratorFunction%') { - value = getEvalledConstructor('async function* () {}'); - } else if (name === '%AsyncGenerator%') { - var fn = doEval('%AsyncGeneratorFunction%'); - if (fn) { - value = fn.prototype; - } - } else if (name === '%AsyncIteratorPrototype%') { - var gen = doEval('%AsyncGenerator%'); - if (gen) { - value = getProto(gen.prototype); - } - } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - INTRINSICS[name] = value; +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - return value; -}; +var store = new _store.default(); +/** + * Public API to use flags + */ -var LEGACY_ALIASES = { - '%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'], - '%ArrayPrototype%': ['Array', 'prototype'], - '%ArrayProto_entries%': ['Array', 'prototype', 'entries'], - '%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'], - '%ArrayProto_keys%': ['Array', 'prototype', 'keys'], - '%ArrayProto_values%': ['Array', 'prototype', 'values'], - '%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'], - '%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'], - '%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'], - '%BooleanPrototype%': ['Boolean', 'prototype'], - '%DataViewPrototype%': ['DataView', 'prototype'], - '%DatePrototype%': ['Date', 'prototype'], - '%ErrorPrototype%': ['Error', 'prototype'], - '%EvalErrorPrototype%': ['EvalError', 'prototype'], - '%Float32ArrayPrototype%': ['Float32Array', 'prototype'], - '%Float64ArrayPrototype%': ['Float64Array', 'prototype'], - '%FunctionPrototype%': ['Function', 'prototype'], - '%Generator%': ['GeneratorFunction', 'prototype'], - '%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'], - '%Int8ArrayPrototype%': ['Int8Array', 'prototype'], - '%Int16ArrayPrototype%': ['Int16Array', 'prototype'], - '%Int32ArrayPrototype%': ['Int32Array', 'prototype'], - '%JSONParse%': ['JSON', 'parse'], - '%JSONStringify%': ['JSON', 'stringify'], - '%MapPrototype%': ['Map', 'prototype'], - '%NumberPrototype%': ['Number', 'prototype'], - '%ObjectPrototype%': ['Object', 'prototype'], - '%ObjProto_toString%': ['Object', 'prototype', 'toString'], - '%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'], - '%PromisePrototype%': ['Promise', 'prototype'], - '%PromiseProto_then%': ['Promise', 'prototype', 'then'], - '%Promise_all%': ['Promise', 'all'], - '%Promise_reject%': ['Promise', 'reject'], - '%Promise_resolve%': ['Promise', 'resolve'], - '%RangeErrorPrototype%': ['RangeError', 'prototype'], - '%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'], - '%RegExpPrototype%': ['RegExp', 'prototype'], - '%SetPrototype%': ['Set', 'prototype'], - '%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'], - '%StringPrototype%': ['String', 'prototype'], - '%SymbolPrototype%': ['Symbol', 'prototype'], - '%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'], - '%TypedArrayPrototype%': ['TypedArray', 'prototype'], - '%TypeErrorPrototype%': ['TypeError', 'prototype'], - '%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'], - '%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'], - '%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'], - '%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'], - '%URIErrorPrototype%': ['URIError', 'prototype'], - '%WeakMapPrototype%': ['WeakMap', 'prototype'], - '%WeakSetPrototype%': ['WeakSet', 'prototype'] +var flag = function flag() { + var args = [].slice.call(arguments); + + if (args.length === 1) { + return store.get(args[0]); + } else { + store.set(args[0], args[1]); + return args[1]; + } }; +/** List all flags from the store */ -var bind = __webpack_require__(635); -var hasOwn = __webpack_require__(637); -var $concat = bind.call(Function.call, Array.prototype.concat); -var $spliceApply = bind.call(Function.apply, Array.prototype.splice); -var $replace = bind.call(Function.call, String.prototype.replace); -var $strSlice = bind.call(Function.call, String.prototype.slice); -/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */ -var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g; -var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */ -var stringToPath = function stringToPath(string) { - var first = $strSlice(string, 0, 1); - var last = $strSlice(string, -1); - if (first === '%' && last !== '%') { - throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`'); - } else if (last === '%' && first !== '%') { - throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`'); - } - var result = []; - $replace(string, rePropName, function (match, number, quote, subString) { - result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match; - }); - return result; +var listFlags = function listFlags() { + return store.keys().sort(); }; -/* end adaptation */ - -var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) { - var intrinsicName = name; - var alias; - if (hasOwn(LEGACY_ALIASES, intrinsicName)) { - alias = LEGACY_ALIASES[intrinsicName]; - intrinsicName = '%' + alias[0] + '%'; - } +/** Resets all the flags */ - if (hasOwn(INTRINSICS, intrinsicName)) { - var value = INTRINSICS[intrinsicName]; - if (value === needsEval) { - value = doEval(intrinsicName); - } - if (typeof value === 'undefined' && !allowMissing) { - throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!'); - } - return { - alias: alias, - name: intrinsicName, - value: value - }; - } +exports.listFlags = listFlags; - throw new $SyntaxError('intrinsic ' + name + ' does not exist!'); +var resetFlags = function resetFlags() { + listFlags().forEach(function (name) { + return store.remove(name); + }); }; +/** + * Enables several flags + * + * Supports passing either object flagName -> flagValue + * + * @param {string[]|Object} flagsToEnable + */ -module.exports = function GetIntrinsic(name, allowMissing) { - if (typeof name !== 'string' || name.length === 0) { - throw new $TypeError('intrinsic name must be a non-empty string'); - } - if (arguments.length > 1 && typeof allowMissing !== 'boolean') { - throw new $TypeError('"allowMissing" argument must be a boolean'); - } - var parts = stringToPath(name); - var intrinsicBaseName = parts.length > 0 ? parts[0] : ''; +exports.resetFlags = resetFlags; - var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing); - var intrinsicRealName = intrinsic.name; - var value = intrinsic.value; - var skipFurtherCaching = false; +var enable = function enable(flagsToEnable) { + var flagNameToValue; - var alias = intrinsic.alias; - if (alias) { - intrinsicBaseName = alias[0]; - $spliceApply(parts, $concat([0, 1], alias)); - } + if (Array.isArray(flagsToEnable)) { + if (flagsToEnable.length === 0) { + return; + } // eslint-disable-next-line no-console - for (var i = 1, isOwn = true; i < parts.length; i += 1) { - var part = parts[i]; - var first = $strSlice(part, 0, 1); - var last = $strSlice(part, -1); - if ( - ( - (first === '"' || first === "'" || first === '`') - || (last === '"' || last === "'" || last === '`') - ) - && first !== last - ) { - throw new $SyntaxError('property names with quotes must have matching quotes'); - } - if (part === 'constructor' || !isOwn) { - skipFurtherCaching = true; - } - intrinsicBaseName += '.' + part; - intrinsicRealName = '%' + intrinsicBaseName + '%'; + console.log('flags.enable: Deprecation warning: prefer to use an object { flag1: true, flag2: true } instead of an array when using flags.enable'); + flagNameToValue = flagsToEnable.map(function (flagName) { + return [flagName, true]; + }); + } else if (typeof flagsToEnable === 'object') { + flagNameToValue = Object.entries(flagsToEnable); + } - if (hasOwn(INTRINSICS, intrinsicRealName)) { - value = INTRINSICS[intrinsicRealName]; - } else if (value != null) { - if (!(part in value)) { - if (!allowMissing) { - throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.'); - } - return void undefined; - } - if ($gOPD && (i + 1) >= parts.length) { - var desc = $gOPD(value, part); - isOwn = !!desc; + if (!flagNameToValue) { + return; + } - // By convention, when a data property is converted to an accessor - // property to emulate a data property that does not suffer from - // the override mistake, that accessor's getter is marked with - // an `originalValue` property. Here, when we detect this, we - // uphold the illusion by pretending to see that original data - // property, i.e., returning the value rather than the getter - // itself. - if (isOwn && 'get' in desc && !('originalValue' in desc.get)) { - value = desc.get; - } else { - value = value[part]; - } - } else { - isOwn = hasOwn(value, part); - value = value[part]; - } + var _iterator = _createForOfIteratorHelper(flagNameToValue), + _step; - if (isOwn && !skipFurtherCaching) { - INTRINSICS[intrinsicRealName] = value; - } - } - } - return value; + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _step$value = (0, _slicedToArray2.default)(_step.value, 2), + flagName = _step$value[0], + flagValue = _step$value[1]; + + flag(flagName, flagValue); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } }; +/** + * Initializes flags from the remote endpoint serving instance flags + * + * @private + * @see https://docs.cozy.io/en/cozy-stack/settings/#get-settingsflags + * @param {CozyClient} client + */ -/***/ }), -/* 633 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +exports.enable = enable; -"use strict"; +var initializeFromRemote = /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client) { + var _yield$client$query, attributes; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return client.query((0, _dsl.Q)('io.cozy.settings').getById('flags')); -var origSymbol = typeof Symbol !== 'undefined' && Symbol; -var hasSymbolSham = __webpack_require__(634); + case 2: + _yield$client$query = _context.sent; + attributes = _yield$client$query.data.attributes; + enable(attributes); -module.exports = function hasNativeSymbols() { - if (typeof origSymbol !== 'function') { return false; } - if (typeof Symbol !== 'function') { return false; } - if (typeof origSymbol('foo') !== 'symbol') { return false; } - if (typeof Symbol('bar') !== 'symbol') { return false; } + case 5: + case "end": + return _context.stop(); + } + } + }, _callee); + })); - return hasSymbolSham(); + return function initializeFromRemote(_x) { + return _ref.apply(this, arguments); + }; +}(); + +exports.initializeFromRemote = initializeFromRemote; + +var capitalize = function capitalize(str) { + return str[0].toUpperCase() + str.slice(1); }; +var getTemplateData = function getTemplateData(attr) { + if (typeof document === 'undefined') { + return null; + } -/***/ }), -/* 634 */ -/***/ ((module) => { + var allDataNode = document.querySelector('[data-cozy]'); + var attrNode = document.querySelector("[data-cozy-".concat(attr, "]")); -"use strict"; + try { + if (allDataNode) { + return JSON.parse(allDataNode.dataset.cozy)[attr]; + } else if (attrNode) { + // eslint-disable-next-line no-console + console.warn('Prefer to use [data-cozy] to store template data. <div data-cozy="{{.CozyData}}></div>. "'); + return JSON.parse(attrNode.dataset["cozy".concat(capitalize(attr))]); + } else { + return null; + } + } catch (e) { + return null; + } +}; +/** + * Initialize from the template data injected by cozy-stack into the DOM + * + * @private + * @see https://docs.cozy.io/en/cozy-stack/client-app-dev/#good-practices-for-your-application + * + * @returns {Boolean} - False is DOM initialization could not be completed, true otherwise + */ -/* eslint complexity: [2, 18], max-statements: [2, 33] */ -module.exports = function hasSymbols() { - if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; } - if (typeof Symbol.iterator === 'symbol') { return true; } +exports.getTemplateData = getTemplateData; - var obj = {}; - var sym = Symbol('test'); - var symObj = Object(sym); - if (typeof sym === 'string') { return false; } +var initializeFromDOM = /*#__PURE__*/function () { + var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { + var domData; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + domData = getTemplateData('flags'); - if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; } - if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; } + if (domData) { + _context2.next = 3; + break; + } + + return _context2.abrupt("return", false); + + case 3: + enable(domData); + return _context2.abrupt("return", true); + + case 5: + case "end": + return _context2.stop(); + } + } + }, _callee2); + })); + + return function initializeFromDOM() { + return _ref2.apply(this, arguments); + }; +}(); +/** + * Initialize flags from DOM if possible, otherwise from remote endpoint + * + * @example + * + * Flags can be taken from the flags injected by the stack + * ``` + * <div data-cozy="{{ .CozyData }}"></div> + * + * // not recommended but possible + * <div data-flags="{{ .Flags }}"></div> + * ```` + * + * @param {CozyClient} client - A CozyClient + * @return {Promise} Resolves when flags have been initialized + */ - // temp disabled per https://github.com/ljharb/object.assign/issues/17 - // if (sym instanceof Symbol) { return false; } - // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4 - // if (!(symObj instanceof Symbol)) { return false; } - // if (typeof Symbol.prototype.toString !== 'function') { return false; } - // if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; } +exports.initializeFromDOM = initializeFromDOM; - var symVal = 42; - obj[sym] = symVal; - for (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop - if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; } +var initialize = /*#__PURE__*/function () { + var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(client) { + var domRes; + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _context3.next = 2; + return initializeFromDOM(); - if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; } + case 2: + domRes = _context3.sent; - var syms = Object.getOwnPropertySymbols(obj); - if (syms.length !== 1 || syms[0] !== sym) { return false; } + if (!(domRes == false)) { + _context3.next = 6; + break; + } - if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; } + _context3.next = 6; + return initializeFromRemote(client); - if (typeof Object.getOwnPropertyDescriptor === 'function') { - var descriptor = Object.getOwnPropertyDescriptor(obj, sym); - if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; } - } + case 6: + case "end": + return _context3.stop(); + } + } + }, _callee3); + })); - return true; -}; + return function initialize(_x2) { + return _ref3.apply(this, arguments); + }; +}(); +exports.initialize = initialize; -/***/ }), -/* 635 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var FlagClientPlugin = /*#__PURE__*/function () { + function FlagClientPlugin(client) { + (0, _classCallCheck2.default)(this, FlagClientPlugin); + this.client = client; + this.handleLogin = this.handleLogin.bind(this); + this.handleLogout = this.handleLogout.bind(this); + this.client.on('login', this.handleLogin); + this.client.on('logout', this.handleLogout); + this.setupInitializing(); + if (client.isLogged) this.handleLogin(); + } + /** + * Fetches and sets flags from remote + */ -"use strict"; + (0, _createClass2.default)(FlagClientPlugin, [{ + key: "refresh", + value: function () { + var _refresh = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() { + return _regenerator.default.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return flag.initializeFromRemote(this.client); -var implementation = __webpack_require__(636); + case 2: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); -module.exports = Function.prototype.bind || implementation; + function refresh() { + return _refresh.apply(this, arguments); + } + return refresh; + }() + /** + * Sets up a promise that can be awaited to wait for flag complete + * initialization + */ -/***/ }), -/* 636 */ -/***/ ((module) => { + }, { + key: "setupInitializing", + value: function setupInitializing() { + var _this = this; -"use strict"; + this.initializing = new Promise(function (resolve) { + _this.resolveInitializing = resolve; + }); + } + }, { + key: "handleLogin", + value: function () { + var _handleLogin = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() { + return _regenerator.default.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + _context5.next = 2; + return flag.initialize(this.client); + case 2: + this.resolveInitializing(); + this.client.emit('plugin:flag:login'); -/* eslint no-invalid-this: 1 */ + case 4: + case "end": + return _context5.stop(); + } + } + }, _callee5, this); + })); -var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; -var slice = Array.prototype.slice; -var toStr = Object.prototype.toString; -var funcType = '[object Function]'; + function handleLogin() { + return _handleLogin.apply(this, arguments); + } -module.exports = function bind(that) { - var target = this; - if (typeof target !== 'function' || toStr.call(target) !== funcType) { - throw new TypeError(ERROR_MESSAGE + target); - } - var args = slice.call(arguments, 1); + return handleLogin; + }() + }, { + key: "handleLogout", + value: function () { + var _handleLogout = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() { + return _regenerator.default.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + flag.reset(); + this.setupInitializing(); + this.client.emit('plugin:flag:logout'); - var bound; - var binder = function () { - if (this instanceof bound) { - var result = target.apply( - this, - args.concat(slice.call(arguments)) - ); - if (Object(result) === result) { - return result; + case 3: + case "end": + return _context6.stop(); } - return this; - } else { - return target.apply( - that, - args.concat(slice.call(arguments)) - ); - } - }; - - var boundLength = Math.max(0, target.length - args.length); - var boundArgs = []; - for (var i = 0; i < boundLength; i++) { - boundArgs.push('$' + i); - } - - bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder); + } + }, _callee6, this); + })); - if (target.prototype) { - var Empty = function Empty() {}; - Empty.prototype = target.prototype; - bound.prototype = new Empty(); - Empty.prototype = null; - } + function handleLogout() { + return _handleLogout.apply(this, arguments); + } - return bound; -}; + return handleLogout; + }() + }]); + return FlagClientPlugin; +}(); +FlagClientPlugin.pluginName = 'flags'; +flag.store = store; +flag.list = listFlags; +flag.reset = resetFlags; +flag.enable = enable; +flag.initializeFromRemote = initializeFromRemote; +flag.initializeFromDOM = initializeFromDOM; +flag.initialize = initialize; +flag.plugin = FlagClientPlugin; +var _default = flag; +exports["default"] = _default; /***/ }), -/* 637 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 617 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var bind = __webpack_require__(635); - -module.exports = bind.call(Function.call, Object.prototype.hasOwnProperty); +var _interopRequireDefault = __webpack_require__(524); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -/***/ }), -/* 638 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532)); -"use strict"; +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var GetIntrinsic = __webpack_require__(632); +var _microee = _interopRequireDefault(__webpack_require__(570)); -var callBind = __webpack_require__(639); +var _lsAdapter = _interopRequireDefault(__webpack_require__(618)); -var $indexOf = callBind(GetIntrinsic('String.prototype.indexOf')); +/** + * In memory key value storage. + * + * Can potentially be backed by localStorage if present -module.exports = function callBoundIntrinsic(name, allowMissing) { - var intrinsic = GetIntrinsic(name, !!allowMissing); - if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) { - return callBind(intrinsic); - } - return intrinsic; -}; + * Emits `change` when a key is set (eventEmitter) + */ +var FlagStore = /*#__PURE__*/function () { + function FlagStore() { + (0, _classCallCheck2.default)(this, FlagStore); + this.store = {}; + if (typeof localStorage !== 'undefined') { + this.longtermStore = _lsAdapter.default; + } -/***/ }), -/* 639 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + this.restore(); + } -"use strict"; + (0, _createClass2.default)(FlagStore, [{ + key: "restore", + value: function restore() { + if (!this.longtermStore) { + return; + } + var allValues = this.longtermStore.getAll(); -var bind = __webpack_require__(635); -var GetIntrinsic = __webpack_require__(632); + for (var _i = 0, _Object$entries = Object.entries(allValues); _i < _Object$entries.length; _i++) { + var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2), + flag = _Object$entries$_i[0], + val = _Object$entries$_i[1]; -var $apply = GetIntrinsic('%Function.prototype.apply%'); -var $call = GetIntrinsic('%Function.prototype.call%'); -var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply); + this.store[flag] = val; + this.emit('change', flag); + } + } + }, { + key: "keys", + value: function keys() { + return Object.keys(this.store); + } + }, { + key: "get", + value: function get(name) { + // eslint-disable-next-line no-prototype-builtins + if (!this.store.hasOwnProperty(name)) { + this.store[name] = null; + } -var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true); -var $defineProperty = GetIntrinsic('%Object.defineProperty%', true); -var $max = GetIntrinsic('%Math.max%'); + return this.store[name]; + } + }, { + key: "set", + value: function set(name, value) { + if (this.longtermStore) { + this.longtermStore.setItem(name, value); + } -if ($defineProperty) { - try { - $defineProperty({}, 'a', { value: 1 }); - } catch (e) { - // IE 8 has a broken defineProperty - $defineProperty = null; - } -} + this.store[name] = value; + this.emit('change', name); + } + }, { + key: "remove", + value: function remove(name) { + delete this.store[name]; -module.exports = function callBind(originalFunction) { - var func = $reflectApply(bind, $call, arguments); - if ($gOPD && $defineProperty) { - var desc = $gOPD(func, 'length'); - if (desc.configurable) { - // original length, plus the receiver, minus any additional arguments (after the receiver) - $defineProperty( - func, - 'length', - { value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) } - ); - } - } - return func; -}; + if (this.longtermStore) { + this.longtermStore.removeItem(name); + } -var applyBind = function applyBind() { - return $reflectApply(bind, $apply, arguments); -}; + this.emit('change', name); + } + }]); + return FlagStore; +}(); -if ($defineProperty) { - $defineProperty(module.exports, 'apply', { value: applyBind }); -} else { - module.exports.apply = applyBind; -} +_microee.default.mixin(FlagStore); +var _default = FlagStore; +exports["default"] = _default; /***/ }), -/* 640 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 618 */ +/***/ ((__unused_webpack_module, exports) => { -var hasMap = typeof Map === 'function' && Map.prototype; -var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null; -var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null; -var mapForEach = hasMap && Map.prototype.forEach; -var hasSet = typeof Set === 'function' && Set.prototype; -var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null; -var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null; -var setForEach = hasSet && Set.prototype.forEach; -var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype; -var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null; -var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype; -var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null; -var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype; -var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null; -var booleanValueOf = Boolean.prototype.valueOf; -var objectToString = Object.prototype.toString; -var functionToString = Function.prototype.toString; -var match = String.prototype.match; -var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null; -var gOPS = Object.getOwnPropertySymbols; -var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null; -var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object'; -var isEnumerable = Object.prototype.propertyIsEnumerable; +"use strict"; -var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || ( - [].__proto__ === Array.prototype // eslint-disable-line no-proto - ? function (O) { - return O.__proto__; // eslint-disable-line no-proto - } - : null -); -var inspectCustom = (__webpack_require__(641).custom); -var inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null; -var toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.prefix = exports.getKey = exports["default"] = void 0; -module.exports = function inspect_(obj, options, depth, seen) { - var opts = options || {}; +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } - if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) { - throw new TypeError('option "quoteStyle" must be "single" or "double"'); - } - if ( - has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number' - ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity - : opts.maxStringLength !== null - ) - ) { - throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`'); - } - var customInspect = has(opts, 'customInspect') ? opts.customInspect : true; - if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') { - throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`'); - } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - if ( - has(opts, 'indent') - && opts.indent !== null - && opts.indent !== '\t' - && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0) - ) { - throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`'); - } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - if (typeof obj === 'undefined') { - return 'undefined'; - } - if (obj === null) { - return 'null'; - } - if (typeof obj === 'boolean') { - return obj ? 'true' : 'false'; - } +// eslint-disable-next-line no-redeclare - if (typeof obj === 'string') { - return inspectString(obj, opts); - } - if (typeof obj === 'number') { - if (obj === 0) { - return Infinity / obj > 0 ? '0' : '-0'; - } - return String(obj); - } - if (typeof obj === 'bigint') { - return String(obj) + 'n'; - } +/* global localStorage */ +var prefix = 'flag__'; +exports.prefix = prefix; - var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth; - if (typeof depth === 'undefined') { depth = 0; } - if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') { - return isArray(obj) ? '[Array]' : '[Object]'; - } +var getKey = function getKey(name) { + return prefix + name; +}; - var indent = getIndent(opts, depth); +exports.getKey = getKey; - if (typeof seen === 'undefined') { - seen = []; - } else if (indexOf(seen, obj) >= 0) { - return '[Circular]'; - } +var listFlagLocalStorage = function listFlagLocalStorage() { + return Object.keys(localStorage).filter(function (x) { + return x.indexOf(prefix) === 0; + }).map(function (x) { + return x.replace(prefix, ''); + }); +}; +/** + * Gets a flag from localStorage, parses value from JSON + * + * @param {String} flag + */ - function inspect(value, from, noIndent) { - if (from) { - seen = seen.slice(); - seen.push(from); - } - if (noIndent) { - var newOpts = { - depth: opts.depth - }; - if (has(opts, 'quoteStyle')) { - newOpts.quoteStyle = opts.quoteStyle; - } - return inspect_(value, newOpts, depth + 1, seen); - } - return inspect_(value, opts, depth + 1, seen); - } - if (typeof obj === 'function') { - var name = nameOf(obj); - var keys = arrObjKeys(obj, inspect); - return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : ''); - } - if (isSymbol(obj)) { - var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj); - return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString; - } - if (isElement(obj)) { - var s = '<' + String(obj.nodeName).toLowerCase(); - var attrs = obj.attributes || []; - for (var i = 0; i < attrs.length; i++) { - s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts); - } - s += '>'; - if (obj.childNodes && obj.childNodes.length) { s += '...'; } - s += '</' + String(obj.nodeName).toLowerCase() + '>'; - return s; - } - if (isArray(obj)) { - if (obj.length === 0) { return '[]'; } - var xs = arrObjKeys(obj, inspect); - if (indent && !singleLineValues(xs)) { - return '[' + indentedJoin(xs, indent) + ']'; - } - return '[ ' + xs.join(', ') + ' ]'; - } - if (isError(obj)) { - var parts = arrObjKeys(obj, inspect); - if (parts.length === 0) { return '[' + String(obj) + ']'; } - return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }'; - } - if (typeof obj === 'object' && customInspect) { - if (inspectSymbol && typeof obj[inspectSymbol] === 'function') { - return obj[inspectSymbol](); - } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') { - return obj.inspect(); - } - } - if (isMap(obj)) { - var mapParts = []; - mapForEach.call(obj, function (value, key) { - mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj)); - }); - return collectionOf('Map', mapSize.call(obj), mapParts, indent); - } - if (isSet(obj)) { - var setParts = []; - setForEach.call(obj, function (value) { - setParts.push(inspect(value, obj)); - }); - return collectionOf('Set', setSize.call(obj), setParts, indent); - } - if (isWeakMap(obj)) { - return weakCollectionOf('WeakMap'); - } - if (isWeakSet(obj)) { - return weakCollectionOf('WeakSet'); - } - if (isWeakRef(obj)) { - return weakCollectionOf('WeakRef'); - } - if (isNumber(obj)) { - return markBoxed(inspect(Number(obj))); - } - if (isBigInt(obj)) { - return markBoxed(inspect(bigIntValueOf.call(obj))); - } - if (isBoolean(obj)) { - return markBoxed(booleanValueOf.call(obj)); - } - if (isString(obj)) { - return markBoxed(inspect(String(obj))); - } - if (!isDate(obj) && !isRegExp(obj)) { - var ys = arrObjKeys(obj, inspect); - var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object; - var protoTag = obj instanceof Object ? '' : 'null prototype'; - var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : ''; - var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : ''; - var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : ''); - if (ys.length === 0) { return tag + '{}'; } - if (indent) { - return tag + '{' + indentedJoin(ys, indent) + '}'; - } - return tag + '{ ' + ys.join(', ') + ' }'; - } - return String(obj); +var getItem = function getItem(flag) { + var val = localStorage.getItem(getKey(flag)); + var parsed = val ? JSON.parse(val) : val; + return parsed; }; +/** + * Stores a flag in localStorage, stringifies the value for storage + * + * @param {String} flag + * @param {String} value + */ -function wrapQuotes(s, defaultStyle, opts) { - var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '"' : "'"; - return quoteChar + s + quoteChar; -} - -function quote(s) { - return String(s).replace(/"/g, '"'); -} -function isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } -function isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } -function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } -function isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } -function isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } -function isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } -function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } +var setItem = function setItem(flag, value) { + var str = JSON.stringify(value); + return localStorage.setItem(getKey(flag), str); +}; +/** + * Removes a flag from localStorage + * + * @param {String} flag + */ -// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives -function isSymbol(obj) { - if (hasShammedSymbols) { - return obj && typeof obj === 'object' && obj instanceof Symbol; - } - if (typeof obj === 'symbol') { - return true; - } - if (!obj || typeof obj !== 'object' || !symToString) { - return false; - } - try { - symToString.call(obj); - return true; - } catch (e) {} - return false; -} -function isBigInt(obj) { - if (!obj || typeof obj !== 'object' || !bigIntValueOf) { - return false; - } - try { - bigIntValueOf.call(obj); - return true; - } catch (e) {} - return false; -} +var removeItem = function removeItem(flag) { + return localStorage.removeItem(getKey(flag)); +}; +/** + * Returns all stored flags as an object + */ -var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; }; -function has(obj, key) { - return hasOwn.call(obj, key); -} -function toStr(obj) { - return objectToString.call(obj); -} +var getAll = function getAll() { + var res = {}; -function nameOf(f) { - if (f.name) { return f.name; } - var m = match.call(functionToString.call(f), /^function\s*([\w$]+)/); - if (m) { return m[1]; } - return null; -} + var _iterator = _createForOfIteratorHelper(listFlagLocalStorage()), + _step; -function indexOf(xs, x) { - if (xs.indexOf) { return xs.indexOf(x); } - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) { return i; } + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var flag = _step.value; + res[flag] = getItem(flag); } - return -1; -} + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } -function isMap(x) { - if (!mapSize || !x || typeof x !== 'object') { - return false; - } - try { - mapSize.call(x); - try { - setSize.call(x); - } catch (s) { - return true; - } - return x instanceof Map; // core-js workaround, pre-v2.5.0 - } catch (e) {} - return false; -} + return res; +}; +/** + * Clears all the flags from localstorage + */ -function isWeakMap(x) { - if (!weakMapHas || !x || typeof x !== 'object') { - return false; - } - try { - weakMapHas.call(x, weakMapHas); - try { - weakSetHas.call(x, weakSetHas); - } catch (s) { - return true; - } - return x instanceof WeakMap; // core-js workaround, pre-v2.5.0 - } catch (e) {} - return false; -} -function isWeakRef(x) { - if (!weakRefDeref || !x || typeof x !== 'object') { - return false; - } - try { - weakRefDeref.call(x); - return true; - } catch (e) {} - return false; -} +var clearAll = function clearAll() { + var _iterator2 = _createForOfIteratorHelper(listFlagLocalStorage()), + _step2; -function isSet(x) { - if (!setSize || !x || typeof x !== 'object') { - return false; + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var flag = _step2.value; + removeItem(flag); } - try { - setSize.call(x); - try { - mapSize.call(x); - } catch (m) { - return true; - } - return x instanceof Set; // core-js workaround, pre-v2.5.0 - } catch (e) {} - return false; -} + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } +}; -function isWeakSet(x) { - if (!weakSetHas || !x || typeof x !== 'object') { - return false; - } - try { - weakSetHas.call(x, weakSetHas); - try { - weakMapHas.call(x, weakMapHas); - } catch (s) { - return true; - } - return x instanceof WeakSet; // core-js workaround, pre-v2.5.0 - } catch (e) {} - return false; -} +var _default = { + getAll: getAll, + getItem: getItem, + setItem: setItem, + clearAll: clearAll, + removeItem: removeItem +}; +exports["default"] = _default; -function isElement(x) { - if (!x || typeof x !== 'object') { return false; } - if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) { - return true; - } - return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function'; -} +/***/ }), +/* 619 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -function inspectString(str, opts) { - if (str.length > opts.maxStringLength) { - var remaining = str.length - opts.maxStringLength; - var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : ''); - return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer; - } - // eslint-disable-next-line no-control-regex - var s = str.replace(/(['\\])/g, '\\$1').replace(/[\x00-\x1f]/g, lowbyte); - return wrapQuotes(s, 'single', opts); -} +"use strict"; -function lowbyte(c) { - var n = c.charCodeAt(0); - var x = { - 8: 'b', - 9: 't', - 10: 'n', - 12: 'f', - 13: 'r' - }[n]; - if (x) { return '\\' + x; } - return '\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase(); -} -function markBoxed(str) { - return 'Object(' + str + ')'; -} +var _interopRequireDefault = __webpack_require__(524); -function weakCollectionOf(type) { - return type + ' { ? }'; -} +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.QueryDefinition = exports.MutationTypes = exports.Mutations = exports.getDoctypeFromOperation = exports.uploadFile = exports.removeReferencedBy = exports.addReferencedBy = exports.removeReferencesTo = exports.addReferencesTo = exports.deleteDocument = exports.updateDocuments = exports.updateDocument = exports.createDocument = exports.isAGetByIdQuery = exports.Q = void 0; -function collectionOf(type, size, entries, indent) { - var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', '); - return type + ' (' + size + ') {' + joinedEntries + '}'; -} +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -function singleLineValues(xs) { - for (var i = 0; i < xs.length; i++) { - if (indexOf(xs[i], '\n') >= 0) { - return false; - } - } - return true; -} +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -function getIndent(opts, depth) { - var baseIndent; - if (opts.indent === '\t') { - baseIndent = '\t'; - } else if (typeof opts.indent === 'number' && opts.indent > 0) { - baseIndent = Array(opts.indent + 1).join(' '); - } else { - return null; - } - return { - base: baseIndent, - prev: Array(depth + 1).join(baseIndent) - }; -} +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -function indentedJoin(xs, indent) { - if (xs.length === 0) { return ''; } - var lineJoiner = '\n' + indent.prev + indent.base; - return lineJoiner + xs.join(',' + lineJoiner) + '\n' + indent.prev; -} +var _isArray = _interopRequireDefault(__webpack_require__(55)); -function arrObjKeys(obj, inspect) { - var isArr = isArray(obj); - var xs = []; - if (isArr) { - xs.length = obj.length; - for (var i = 0; i < obj.length; i++) { - xs[i] = has(obj, i) ? inspect(obj[i], obj) : ''; - } - } - var syms = typeof gOPS === 'function' ? gOPS(obj) : []; - var symMap; - if (hasShammedSymbols) { - symMap = {}; - for (var k = 0; k < syms.length; k++) { - symMap['$' + syms[k]] = syms[k]; - } - } +var _findKey = _interopRequireDefault(__webpack_require__(620)); - for (var key in obj) { // eslint-disable-line no-restricted-syntax - if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue - if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue - if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) { - // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section - continue; // eslint-disable-line no-restricted-syntax, no-continue - } else if ((/[^\w$]/).test(key)) { - xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj)); - } else { - xs.push(key + ': ' + inspect(obj[key], obj)); - } - } - if (typeof gOPS === 'function') { - for (var j = 0; j < syms.length; j++) { - if (isEnumerable.call(obj, syms[j])) { - xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj)); - } - } - } - return xs; -} +var _types = __webpack_require__(622); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -/***/ }), -/* 641 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -module.exports = __webpack_require__(64).inspect; +/** + * @typedef PartialQueryDefinition + * + * @property {Array} [indexedFields] + * @property {Array} [sort] + * @property {object} [selector] + */ +/** + * @typedef {object} MangoSelector + */ -/***/ }), -/* 642 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/** + * @typedef {object} MangoPartialFilter + */ -"use strict"; +/** + * Chainable API to create query definitions to retrieve documents + * from a Cozy. `QueryDefinition`s are sent to links. + * + * @augments {object} + */ +var QueryDefinition = /*#__PURE__*/function () { + /** + * @class + * + * @param {object} options Initial options for the query definition + * @param {Doctype} [options.doctype] - The doctype of the doc. + * @param {DocId|null} [options.id] - The id of the doc. + * @param {Array<DocId>} [options.ids] - The ids of the docs. + * @param {MangoSelector} [options.selector] - The selector to query the docs. + * @param {Array<string>} [options.fields] - The fields to return. + * @param {Array<string>} [options.indexedFields] - The fields to index. + * @param {MangoPartialFilter} [options.partialFilter] - The partial index definition to filter docs. + * @param {Array<object>} [options.sort] - The sorting params. + * @param {Array<string>} [options.includes] - The docs to include. + * @param {string|null} [options.referenced] - The referenced document. + * @param {number|null} [options.limit] - The document's limit to return. + * @param {number|null} [options.skip] - The number of docs to skip. + * @param {CouchDBViewCursor} [options.cursor] - The cursor to paginate views. + * @param {string} [options.bookmark] - The bookmark to paginate mango queries. + */ + function QueryDefinition() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + (0, _classCallCheck2.default)(this, QueryDefinition); + this.doctype = options.doctype; + this.id = options.id; + this.ids = options.ids; + this.selector = options.selector; + this.fields = options.fields; + this.indexedFields = options.indexedFields; + this.partialFilter = options.partialFilter; + this.sort = options.sort; + this.includes = options.includes; + this.referenced = options.referenced; + this.limit = options.limit; + this.skip = options.skip; + this.cursor = options.cursor; + this.bookmark = options.bookmark; + } + /** + * Checks if the sort order matches the index' fields order. + * + * When sorting with CouchDB, it is required to: + * - use indexed fields + * - keep the same order than the indexed fields. + * + * See https://docs.cozy.io/en/tutorials/data/queries/#sort-data-with-mango + * + * @param {PartialQueryDefinition} obj - A partial QueryDefinition to check + */ -var formats = __webpack_require__(643); + (0, _createClass2.default)(QueryDefinition, [{ + key: "checkSortOrder", + value: function checkSortOrder(_ref) { + var sort = _ref.sort, + selector = _ref.selector, + indexedFields = _ref.indexedFields; -var has = Object.prototype.hasOwnProperty; -var isArray = Array.isArray; + var _sort = this.sort || sort; -var hexTable = (function () { - var array = []; - for (var i = 0; i < 256; ++i) { - array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase()); - } + var _selector = this.selector || selector || {}; - return array; -}()); + var _indexedFields = this.indexedFields || indexedFields; -var compactQueue = function compactQueue(queue) { - while (queue.length > 1) { - var item = queue.pop(); - var obj = item.obj[item.prop]; + if (!_sort) { + return; + } - if (isArray(obj)) { - var compacted = []; + var fieldsToIndex = _indexedFields || Object.keys(_selector); - for (var j = 0; j < obj.length; ++j) { - if (typeof obj[j] !== 'undefined') { - compacted.push(obj[j]); - } - } + if (!fieldsToIndex || fieldsToIndex.length < 1) { + return; + } - item.obj[item.prop] = compacted; + if (_sort.length > fieldsToIndex.length) { + console.warn("You should not sort on non-indexed fields.\n\n Sort: ".concat(JSON.stringify(_sort), "\n\n Indexed fields: ").concat(fieldsToIndex)); + return; + } + + for (var i = 0; i < _sort.length; i++) { + if (Object.keys(_sort[i])[0] !== fieldsToIndex[i]) { + console.warn("The sort order should be the same than the indexed fields.\n\n Sort: ".concat(JSON.stringify(_sort), "\n\n Indexed fields: ").concat(fieldsToIndex, "\n")); + return; } + } } -}; + /** + * Checks the selector predicates. + * + * It is useful to warn the developer when a partial index might be used. + * + * @param {MangoSelector} selector - The selector definition + * @returns {void} + */ -var arrayToObject = function arrayToObject(source, options) { - var obj = options && options.plainObjects ? Object.create(null) : {}; - for (var i = 0; i < source.length; ++i) { - if (typeof source[i] !== 'undefined') { - obj[i] = source[i]; - } + }, { + key: "checkSelector", + value: function checkSelector(selector) { + var hasExistsFalse = (0, _findKey.default)(selector, ['$exists', false]); + + if (hasExistsFalse) { + console.warn("The \"$exists: false\" predicate should be defined as a partial index for better performance.\n\n Selector: ".concat(selector)); + } + + var hasNe = (0, _findKey.default)(selector, '$ne'); + + if (hasNe) { + console.info("The use of the $ne operator is more efficient with a partial index.\n\n Selector: ".concat(selector)); + } } + /** + * Query a single document on its id. + * + * @param {string} id The document id. + * @returns {QueryDefinition} The QueryDefinition object. + */ - return obj; -}; + }, { + key: "getById", + value: function getById(id) { + if (!id) { + throw new Error('getById called with undefined id'); + } -var merge = function merge(target, source, options) { - /* eslint no-param-reassign: 0 */ - if (!source) { - return target; + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + id: id + })); } + /** + * Query several documents on their ids. + * + * @param {Array} ids The documents ids. + * @returns {QueryDefinition} The QueryDefinition object. + */ - if (typeof source !== 'object') { - if (isArray(target)) { - target.push(source); - } else if (target && typeof target === 'object') { - if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) { - target[source] = true; - } - } else { - return [target, source]; - } + }, { + key: "getByIds", + value: function getByIds(ids) { + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + ids: ids + })); + } + /** + * Query documents with a [mango selector](http://docs.couchdb.org/en/latest/api/database/find.html#find-selectors). + * Each field passed in the selector will be indexed, except if the indexField option is used. + * + * @param {MangoSelector} selector The Mango selector. + * @returns {QueryDefinition} The QueryDefinition object. + */ - return target; + }, { + key: "where", + value: function where(selector) { + this.checkSortOrder({ + selector: selector + }); + this.checkSelector(selector); + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + selector: selector + })); } + /** + * Specify which fields of each object should be returned. If it is omitted, the entire object is returned. + * + * @param {Array} fields The fields to return. + * @returns {QueryDefinition} The QueryDefinition object. + */ - if (!target || typeof target !== 'object') { - return [target].concat(source); + }, { + key: "select", + value: function select(fields) { + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + fields: fields + })); } + /** + * Specify which fields should be indexed. This prevent the automatic indexing of the mango fields. + * + * @param {Array} indexedFields The fields to index. + * @returns {QueryDefinition} The QueryDefinition object. + */ - var mergeTarget = target; - if (isArray(target) && !isArray(source)) { - mergeTarget = arrayToObject(target, options); + }, { + key: "indexFields", + value: function indexFields(indexedFields) { + this.checkSortOrder({ + indexedFields: indexedFields + }); + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + indexedFields: indexedFields + })); } + /** + * Specify a [partial index](https://docs.couchdb.org/en/stable/api/database/find.html#find-partial-indexes). + * The filter must follow the same syntax than the selector. + * + * A partial index includes a filter, used to select documents before the indexing. + * You can find more information about partial indexes [here](https://docs.cozy.io/en/tutorials/data/advanced/#partial-indexes) + * + * @param {object} partialFilter - The filter definition. + */ - if (isArray(target) && isArray(source)) { - source.forEach(function (item, i) { - if (has.call(target, i)) { - var targetItem = target[i]; - if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') { - target[i] = merge(targetItem, item, options); - } else { - target.push(item); - } - } else { - target[i] = item; - } - }); - return target; + }, { + key: "partialIndex", + value: function partialIndex(partialFilter) { + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + partialFilter: partialFilter + })); } + /** + * Specify how to sort documents, following the [sort syntax](http://docs.couchdb.org/en/latest/api/database/find.html#find-sort) + * + * @param {Array} sort The list of field name and direction pairs. + * @returns {QueryDefinition} The QueryDefinition object. + */ - return Object.keys(source).reduce(function (acc, key) { - var value = source[key]; + }, { + key: "sortBy", + value: function sortBy(sort) { + if (!(0, _isArray.default)(sort)) { + throw new Error("Invalid sort, should be an array ([{ label: \"desc\"}, { name: \"asc\"}]), you passed ".concat(JSON.stringify(sort), ".")); + } - if (has.call(acc, key)) { - acc[key] = merge(acc[key], value, options); - } else { - acc[key] = value; - } - return acc; - }, mergeTarget); -}; + this.checkSortOrder({ + sort: sort + }); + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + sort: sort + })); + } + /** + * Includes documents having a relationships with the ones queried. + * For example, query albums including the photos. + * + * @param {Array} includes The documents to include. + * @returns {QueryDefinition} The QueryDefinition object. + */ -var assign = function assignSingleSource(target, source) { - return Object.keys(source).reduce(function (acc, key) { - acc[key] = source[key]; - return acc; - }, target); -}; + }, { + key: "include", + value: function include(includes) { + if (!Array.isArray(includes)) { + throw new Error('include() takes an array of relationship names'); + } -var decode = function (str, decoder, charset) { - var strWithoutPlus = str.replace(/\+/g, ' '); - if (charset === 'iso-8859-1') { - // unescape never throws, no try...catch needed: - return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape); - } - // utf-8 - try { - return decodeURIComponent(strWithoutPlus); - } catch (e) { - return strWithoutPlus; + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + includes: includes + })); } -}; + /** + * Maximum number of documents returned, useful for pagination. Default is 100. + * + * @param {number} limit The document's limit. + * @returns {QueryDefinition} The QueryDefinition object. + */ -var encode = function encode(str, defaultEncoder, charset, kind, format) { - // This code was originally written by Brian White (mscdex) for the io.js core querystring library. - // It has been adapted here for stricter adherence to RFC 3986 - if (str.length === 0) { - return str; + }, { + key: "limitBy", + value: function limitBy(limit) { + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + limit: limit + })); } - - var string = str; - if (typeof str === 'symbol') { - string = Symbol.prototype.toString.call(str); - } else if (typeof str !== 'string') { - string = String(str); + }, { + key: "UNSAFE_noLimit", + value: function UNSAFE_noLimit() { + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + limit: null + })); } + /** + * Skip the first ‘n’ documents, where ‘n’ is the value specified. + * + * Beware, this [performs badly](http://docs.couchdb.org/en/stable/ddocs/views/pagination.html#paging-alternate-method) on view's index. + * Prefer cursor-based pagination in such situation. + * + * @param {number} skip The number of documents to skip. + * @returns {QueryDefinition} The QueryDefinition object. + */ - if (charset === 'iso-8859-1') { - return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { - return '%26%23' + parseInt($0.slice(2), 16) + '%3B'; - }); + }, { + key: "offset", + value: function offset(skip) { + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + bookmark: undefined, + cursor: undefined, + skip: skip + })); } + /** + * Use [cursor-based](https://docs.cozy.io/en/cozy-stack/jsonapi/#pagination) pagination. + * *Warning*: this is only useful for views. + * The cursor is a [startkey, startkey_docid] array, where startkey is the view's key, + * e.g. ["io.cozy.photos.albums", "album-id"] and startkey_docid is the id of + * the starting document of the query, e.g. "file-id". + * Use the last docid of each query as startkey_docid to paginate or leave blank for the first query. + * + * @param {CouchDBViewCursor} cursor The cursor for pagination. + * @returns {QueryDefinition} The QueryDefinition object. + */ - var out = ''; - for (var i = 0; i < string.length; ++i) { - var c = string.charCodeAt(i); - - if ( - c === 0x2D // - - || c === 0x2E // . - || c === 0x5F // _ - || c === 0x7E // ~ - || (c >= 0x30 && c <= 0x39) // 0-9 - || (c >= 0x41 && c <= 0x5A) // a-z - || (c >= 0x61 && c <= 0x7A) // A-Z - || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( ) - ) { - out += string.charAt(i); - continue; - } - - if (c < 0x80) { - out = out + hexTable[c]; - continue; - } - - if (c < 0x800) { - out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); - continue; - } - - if (c < 0xD800 || c >= 0xE000) { - out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); - continue; - } - - i += 1; - c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); - out += hexTable[0xF0 | (c >> 18)] - + hexTable[0x80 | ((c >> 12) & 0x3F)] - + hexTable[0x80 | ((c >> 6) & 0x3F)] - + hexTable[0x80 | (c & 0x3F)]; + }, { + key: "offsetCursor", + value: function offsetCursor(cursor) { + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + bookmark: undefined, + skip: undefined, + cursor: cursor + })); } + /** + * Use [bookmark](https://docs.couchdb.org/en/2.2.0/api/database/find.html#pagination) pagination. + * Note this only applies for mango-queries (not views) and is way more efficient than skip pagination. + * The bookmark is a string returned by the _find response and can be seen as a pointer in + * the index for the next query. + * + * @param {string} bookmark The bookmark to continue a previous paginated query. + * @returns {QueryDefinition} The QueryDefinition object. + */ - return out; -}; - -var compact = function compact(value) { - var queue = [{ obj: { o: value }, prop: 'o' }]; - var refs = []; - - for (var i = 0; i < queue.length; ++i) { - var item = queue[i]; - var obj = item.obj[item.prop]; - - var keys = Object.keys(obj); - for (var j = 0; j < keys.length; ++j) { - var key = keys[j]; - var val = obj[key]; - if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) { - queue.push({ obj: obj, prop: key }); - refs.push(val); - } - } + }, { + key: "offsetBookmark", + value: function offsetBookmark(bookmark) { + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + skip: undefined, + cursor: undefined, + bookmark: bookmark + })); } + /** + * Use the [file reference system](https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/) + * + * @param {object} document The reference document + * @returns {QueryDefinition} The QueryDefinition object. + */ - compactQueue(queue); - - return value; -}; - -var isRegExp = function isRegExp(obj) { - return Object.prototype.toString.call(obj) === '[object RegExp]'; -}; - -var isBuffer = function isBuffer(obj) { - if (!obj || typeof obj !== 'object') { - return false; + }, { + key: "referencedBy", + value: function referencedBy(document) { + return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, { + referenced: document + })); } + }, { + key: "toDefinition", + value: function toDefinition() { + return { + doctype: this.doctype, + id: this.id, + ids: this.ids, + selector: this.selector, + fields: this.fields, + indexedFields: this.indexedFields, + partialFilter: this.partialFilter, + sort: this.sort, + includes: this.includes, + referenced: this.referenced, + limit: this.limit, + skip: this.skip, + cursor: this.cursor, + bookmark: this.bookmark + }; + } + }]); + return QueryDefinition; +}(); +/** + * Helper to create a QueryDefinition. Recommended way to create + * query definitions. + * + * @param {Doctype} doctype - Doctype of the query definition + * + * @example + * ``` + * import { Q } from 'cozy-client' + * + * const qDef = Q('io.cozy.todos').where({ _id: '1234' }) + * ``` + */ - return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); -}; - -var combine = function combine(a, b) { - return [].concat(a, b); -}; -var maybeMap = function maybeMap(val, fn) { - if (isArray(val)) { - var mapped = []; - for (var i = 0; i < val.length; i += 1) { - mapped.push(fn(val[i])); - } - return mapped; - } - return fn(val); -}; +exports.QueryDefinition = QueryDefinition; -module.exports = { - arrayToObject: arrayToObject, - assign: assign, - combine: combine, - compact: compact, - decode: decode, - encode: encode, - isBuffer: isBuffer, - isRegExp: isRegExp, - maybeMap: maybeMap, - merge: merge +var Q = function Q(doctype) { + return new QueryDefinition({ + doctype: doctype + }); }; +/** + * Check if the query is a getById() query + * + * @param {QueryDefinition} queryDefinition The query definition + * + * @returns {boolean} + */ -/***/ }), -/* 643 */ -/***/ ((module) => { +exports.Q = Q; -"use strict"; +var isAGetByIdQuery = function isAGetByIdQuery(queryDefinition) { + if (!queryDefinition) return false; + var attributes = Object.values(queryDefinition); + if (attributes.length === 0) return false; // 2 attrs because we check if id and doctype are not undefined + return attributes.filter(function (attr) { + return attr !== undefined; + }).length === 2 && queryDefinition.id !== undefined; +}; // Mutations -var replace = String.prototype.replace; -var percentTwenties = /%20/g; -var Format = { - RFC1738: 'RFC1738', - RFC3986: 'RFC3986' -}; +exports.isAGetByIdQuery = isAGetByIdQuery; +var CREATE_DOCUMENT = 'CREATE_DOCUMENT'; +var UPDATE_DOCUMENT = 'UPDATE_DOCUMENT'; +var UPDATE_DOCUMENTS = 'UPDATE_DOCUMENTS'; +var DELETE_DOCUMENT = 'DELETE_DOCUMENT'; +var ADD_REFERENCES_TO = 'ADD_REFERENCES_TO'; +var REMOVE_REFERENCES_TO = 'REMOVE_REFERENCES_TO'; +var ADD_REFERENCED_BY = 'ADD_REFERENCED_BY'; +var REMOVE_REFERENCED_BY = 'REMOVE_REFERENCED_BY'; +var UPLOAD_FILE = 'UPLOAD_FILE'; -module.exports = { - 'default': Format.RFC3986, - formatters: { - RFC1738: function (value) { - return replace.call(value, percentTwenties, '+'); - }, - RFC3986: function (value) { - return String(value); - } - }, - RFC1738: Format.RFC1738, - RFC3986: Format.RFC3986 +var createDocument = function createDocument(document) { + return { + mutationType: MutationTypes.CREATE_DOCUMENT, + document: document + }; }; +exports.createDocument = createDocument; -/***/ }), -/* 644 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; +var updateDocument = function updateDocument(document) { + return { + mutationType: MutationTypes.UPDATE_DOCUMENT, + document: document + }; +}; +exports.updateDocument = updateDocument; -var utils = __webpack_require__(642); +var updateDocuments = function updateDocuments(documents) { + return { + mutationType: MutationTypes.UPDATE_DOCUMENTS, + documents: documents + }; +}; -var has = Object.prototype.hasOwnProperty; -var isArray = Array.isArray; +exports.updateDocuments = updateDocuments; -var defaults = { - allowDots: false, - allowPrototypes: false, - allowSparse: false, - arrayLimit: 20, - charset: 'utf-8', - charsetSentinel: false, - comma: false, - decoder: utils.decode, - delimiter: '&', - depth: 5, - ignoreQueryPrefix: false, - interpretNumericEntities: false, - parameterLimit: 1000, - parseArrays: true, - plainObjects: false, - strictNullHandling: false +var deleteDocument = function deleteDocument(document) { + return { + mutationType: MutationTypes.DELETE_DOCUMENT, + document: document + }; }; -var interpretNumericEntities = function (str) { - return str.replace(/&#(\d+);/g, function ($0, numberStr) { - return String.fromCharCode(parseInt(numberStr, 10)); - }); +exports.deleteDocument = deleteDocument; + +var addReferencesTo = function addReferencesTo(document, referencedDocuments) { + return { + mutationType: MutationTypes.ADD_REFERENCES_TO, + referencedDocuments: referencedDocuments, + document: document + }; }; -var parseArrayValue = function (val, options) { - if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) { - return val.split(','); - } +exports.addReferencesTo = addReferencesTo; - return val; +var removeReferencesTo = function removeReferencesTo(document, referencedDocuments) { + return { + mutationType: MutationTypes.REMOVE_REFERENCES_TO, + referencedDocuments: referencedDocuments, + document: document + }; }; -// This is what browsers will submit when the ✓ character occurs in an -// application/x-www-form-urlencoded body and the encoding of the page containing -// the form is iso-8859-1, or when the submitted form has an accept-charset -// attribute of iso-8859-1. Presumably also with other charsets that do not contain -// the ✓ character, such as us-ascii. -var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓') +exports.removeReferencesTo = removeReferencesTo; -// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded. -var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓') +var addReferencedBy = function addReferencedBy(document, referencedDocuments) { + return { + mutationType: MutationTypes.ADD_REFERENCED_BY, + referencedDocuments: referencedDocuments, + document: document + }; +}; -var parseValues = function parseQueryStringValues(str, options) { - var obj = {}; - var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str; - var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit; - var parts = cleanStr.split(options.delimiter, limit); - var skipIndex = -1; // Keep track of where the utf8 sentinel was found - var i; +exports.addReferencedBy = addReferencedBy; - var charset = options.charset; - if (options.charsetSentinel) { - for (i = 0; i < parts.length; ++i) { - if (parts[i].indexOf('utf8=') === 0) { - if (parts[i] === charsetSentinel) { - charset = 'utf-8'; - } else if (parts[i] === isoSentinel) { - charset = 'iso-8859-1'; - } - skipIndex = i; - i = parts.length; // The eslint settings do not allow break; - } - } - } +var removeReferencedBy = function removeReferencedBy(document, referencedDocuments) { + return { + mutationType: MutationTypes.REMOVE_REFERENCED_BY, + referencedDocuments: referencedDocuments, + document: document + }; +}; - for (i = 0; i < parts.length; ++i) { - if (i === skipIndex) { - continue; - } - var part = parts[i]; +exports.removeReferencedBy = removeReferencedBy; - var bracketEqualsPos = part.indexOf(']='); - var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1; +var uploadFile = function uploadFile(file, dirPath) { + return { + mutationType: MutationTypes.UPLOAD_FILE, + file: file, + dirPath: dirPath + }; +}; - var key, val; - if (pos === -1) { - key = options.decoder(part, defaults.decoder, charset, 'key'); - val = options.strictNullHandling ? null : ''; - } else { - key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key'); - val = utils.maybeMap( - parseArrayValue(part.slice(pos + 1), options), - function (encodedVal) { - return options.decoder(encodedVal, defaults.decoder, charset, 'value'); - } - ); - } +exports.uploadFile = uploadFile; - if (val && options.interpretNumericEntities && charset === 'iso-8859-1') { - val = interpretNumericEntities(val); - } +var getDoctypeFromOperation = function getDoctypeFromOperation(operation) { + if (operation.mutationType) { + var type = operation.mutationType; - if (part.indexOf('[]=') > -1) { - val = isArray(val) ? [val] : val; - } + switch (type) { + case CREATE_DOCUMENT: + return operation.document._type; - if (has.call(obj, key)) { - obj[key] = utils.combine(obj[key], val); - } else { - obj[key] = val; - } - } + case UPDATE_DOCUMENT: + return operation.document._type; - return obj; -}; + case UPDATE_DOCUMENTS: + return operation.documents[0]._type; -var parseObject = function (chain, val, options, valuesParsed) { - var leaf = valuesParsed ? val : parseArrayValue(val, options); + case DELETE_DOCUMENT: + return operation.document._type; - for (var i = chain.length - 1; i >= 0; --i) { - var obj; - var root = chain[i]; + case ADD_REFERENCES_TO: + throw new Error('Not implemented'); - if (root === '[]' && options.parseArrays) { - obj = [].concat(leaf); - } else { - obj = options.plainObjects ? Object.create(null) : {}; - var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root; - var index = parseInt(cleanRoot, 10); - if (!options.parseArrays && cleanRoot === '') { - obj = { 0: leaf }; - } else if ( - !isNaN(index) - && root !== cleanRoot - && String(index) === cleanRoot - && index >= 0 - && (options.parseArrays && index <= options.arrayLimit) - ) { - obj = []; - obj[index] = leaf; - } else { - obj[cleanRoot] = leaf; - } - } + case UPLOAD_FILE: + throw new Error('Not implemented'); - leaf = obj; + default: + throw new Error("Unknown mutationType ".concat(type)); } + } else { + return operation.doctype; + } +}; - return leaf; +exports.getDoctypeFromOperation = getDoctypeFromOperation; +var Mutations = { + createDocument: createDocument, + updateDocument: updateDocument, + updateDocuments: updateDocuments, + deleteDocument: deleteDocument, + addReferencesTo: addReferencesTo, + removeReferencesTo: removeReferencesTo, + addReferencedBy: addReferencedBy, + removeReferencedBy: removeReferencedBy, + uploadFile: uploadFile +}; +exports.Mutations = Mutations; +var MutationTypes = { + CREATE_DOCUMENT: CREATE_DOCUMENT, + UPDATE_DOCUMENT: UPDATE_DOCUMENT, + UPDATE_DOCUMENTS: UPDATE_DOCUMENTS, + DELETE_DOCUMENT: DELETE_DOCUMENT, + ADD_REFERENCES_TO: ADD_REFERENCES_TO, + REMOVE_REFERENCES_TO: REMOVE_REFERENCES_TO, + ADD_REFERENCED_BY: ADD_REFERENCED_BY, + REMOVE_REFERENCED_BY: REMOVE_REFERENCED_BY, + UPLOAD_FILE: UPLOAD_FILE }; +exports.MutationTypes = MutationTypes; -var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) { - if (!givenKey) { - return; - } +/***/ }), +/* 620 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Transform dot notation to bracket notation - var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; +var baseFindKey = __webpack_require__(621), + baseForOwn = __webpack_require__(548), + baseIteratee = __webpack_require__(413); - // The regex chunks +/** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ +function findKey(object, predicate) { + return baseFindKey(object, baseIteratee(predicate, 3), baseForOwn); +} - var brackets = /(\[[^[\]]*])/; - var child = /(\[[^[\]]*])/g; +module.exports = findKey; - // Get the parent - var segment = options.depth > 0 && brackets.exec(key); - var parent = segment ? key.slice(0, segment.index) : key; +/***/ }), +/* 621 */ +/***/ ((module) => { - // Stash the parent if it exists +/** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ +function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; +} - var keys = []; - if (parent) { - // If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties - if (!options.plainObjects && has.call(Object.prototype, parent)) { - if (!options.allowPrototypes) { - return; - } - } +module.exports = baseFindKey; - keys.push(parent); - } - // Loop through children appending to the array until we hit depth +/***/ }), +/* 622 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - var i = 0; - while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) { - i += 1; - if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) { - if (!options.allowPrototypes) { - return; - } - } - keys.push(segment[1]); - } +"use strict"; - // If there's a remainder, just add whatever is left - if (segment) { - keys.push('[' + key.slice(segment.index) + ']'); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - return parseObject(keys, val, options, valuesParsed); -}; +var _dsl = __webpack_require__(619); -var normalizeParseOptions = function normalizeParseOptions(opts) { - if (!opts) { - return defaults; - } +/** + * @typedef {"io.cozy.accounts"} AccountsDoctype + * @typedef {"io.cozy.triggers"} TriggersDoctype + * @typedef {"io.cozy.konnectors"} KonnectorsDoctype + * @typedef {"io.cozy.notes"} NotesDoctype + * @typedef {"io.cozy.apps"} AppsDoctype + * @typedef {"io.cozy.settings"} SettingsDoctype + * @typedef {"io.cozy-oauth.clients"} OAuthClientsDoctype + * @typedef {"io.cozy.files"} FilesDoctype + * @typedef {AccountsDoctype|TriggersDoctype|KonnectorsDoctype|NotesDoctype|AppsDoctype|SettingsDoctype|OAuthClientsDoctype|FilesDoctype} KnownDoctype + * @typedef {KnownDoctype|string} Doctype + */ - if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') { - throw new TypeError('Decoder has to be a function.'); - } +/** + * @typedef {object} Link + * @typedef {object} Mutation + * @typedef {object} DocumentCollection + * @typedef {object} QueryResult + * @typedef {object} HydratedDocument + * @typedef {object} ReduxStore + * @typedef {object} Token + * @typedef {object} ClientResponse + * @typedef {object} Manifest + */ - if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { - throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); - } - var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset; +/** + * @typedef {object} OldCozyClient + */ - return { - allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots, - allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes, - allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse, - arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit, - charset: charset, - charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, - comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma, - decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder, - delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter, - // eslint-disable-next-line no-implicit-coercion, no-extra-parens - depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth, - ignoreQueryPrefix: opts.ignoreQueryPrefix === true, - interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities, - parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit, - parseArrays: opts.parseArrays !== false, - plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects, - strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling - }; -}; +/** + * @typedef {object} NodeEnvironment + */ -module.exports = function (str, opts) { - var options = normalizeParseOptions(opts); +/** + * @typedef {"loading"|"loaded"|"pending"|"failed"} QueryFetchStatus + */ - if (str === '' || str === null || typeof str === 'undefined') { - return options.plainObjects ? Object.create(null) : {}; - } +/** + * @typedef {Record<Doctype, QueryState>} QueriesStateSlice + */ - var tempObj = typeof str === 'string' ? parseValues(str, options) : str; - var obj = options.plainObjects ? Object.create(null) : {}; +/** + * @typedef {Record<string, CozyClientDocument>} IndexedDocuments + */ - // Iterate over the keys and setup the new object +/** + * @typedef {Record<Doctype, IndexedDocuments>} DocumentsStateSlice + */ - var keys = Object.keys(tempObj); - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string'); - obj = utils.merge(obj, newObj, options); - } +/** + * @typedef {object} QueryState + * @property {string} id + * @property {QueryDefinition} definition + * @property {QueryFetchStatus} fetchStatus + * @property {number} lastFetch + * @property {number} lastUpdate + * @property {number} lastErrorUpdate + * @property {Error} lastError + * @property {boolean} hasMore + * @property {number} count + * @property {object|Array} data + * @property {string} bookmark + * @property {object} [execution_stats] + * @property {QueryOptions} [options] + */ - if (options.allowSparse === true) { - return obj; - } +/** + * @typedef {object} AutoUpdateOptions + * @param {boolean} update - Should documents be updated in the query (default: true) + * @param {boolean} add - Should documents be added to the query (default: true) + * @param {boolean} remove - Should documents be removed from the query (default: true) + */ - return utils.compact(obj); -}; +/** + * @typedef {object} QueryOptions + * @property {string} [as] - Name of the query + * @property {Function} [fetchPolicy] - Fetch policy to bypass fetching based on what's already inside the state. See "Fetch policies" + * @property {AutoUpdateOptions} [autoUpdate] - Options for the query auto update + * @property {string} [update] - Does not seem to be used + * @property {Function} [onError] - Callback when the query is errored + * @property {boolean} [enabled=true] - If set to false, the query won't be executed + * @property {object} [hydrated=true] - Whether documents should be returned already hydrated + * @property {object} [singleDocData] - If true, the "data" returned will be + * a single doc instead of an array for single doc queries. Defaults to false for backward + * compatibility but will be set to true in the future. + */ +/** + * @typedef {object} FetchMoreAble + * @property {Function} fetchMore + */ -/***/ }), -/* 645 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/** + * @typedef {object} FetchAble + * @property {Function} fetch + */ -"use strict"; +/** + * @typedef {QueryState & FetchMoreAble & FetchAble} UseQueryReturnValue + */ + +/** + * A reference to a document + * + * @typedef {object} ReferencedByRelationship + * @property {RelationshipParent} [parent] + * @property {ReferencedBy} [referenced_by] + */ +/** + * @typedef {object} RelationshipParent + * @property {{related: string}} links + * @property {Reference} [data] + */ -var _interopRequireDefault = __webpack_require__(512); +/** + * @typedef {object} ReferencedBy + * @property {{self: string}} links + * @property {Reference[]|null} data + */ -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.isMatchingIndex = exports.isInconsistentIndex = exports.getIndexFields = exports.transformSort = exports.getIndexNameFromFields = exports.normalizeDesignDoc = void 0; +/** + * A reference to a document + * https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files/#references + * + * @typedef {object} Reference + * @property {string} id - id of the document + * @property {string} type - doctype of the document + */ -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); +/** + * @typedef {Object.<string, Array<Reference>>} ReferenceMap + */ -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +/** + * @typedef {object} MutationOptions + * @property {string} [as] + * @property {Function} [update] + * @property {Function} [updateQueries] + */ -var _utils = __webpack_require__(611); +/** + * @typedef {object} CozyClientDocument - A document + * @property {string} [_id] - Id of the document + * @property {string} [id] - Id of the document + * @property {string} [_type] - Type of the document + * @property {string} [_rev] - Current revision of the document + * @property {boolean} [_deleted] - When the document has been deleted + * @property {ReferencedByRelationship} [relationships] - Relationships of the document + * @property {Reference[]} [referenced_by] - referenced by of another document + */ -var _head = _interopRequireDefault(__webpack_require__(621)); +/** + * @typedef {object} FileDocument - An io.cozy.files document + * @property {string} _id - Id of the file + * @property {FilesDoctype} _type - Doctype of the file + * @property {string} name - Name of the file + * @property {object} metadata - Metadata of the file + * @property {string} type - Type of the file + * @property {string} class - Class of the file + * @property {string} mime - Mime of the file + * @property {boolean} executable - Whether or not the file is executable + * @property {boolean} encrypted - Whether or not the file is client-side encrypted + * @typedef {CozyClientDocument & FileDocument} IOCozyFile - An io.cozy.files document + */ -var _get = _interopRequireDefault(__webpack_require__(358)); +/** + * @typedef {object} FolderDocument - An io.cozy.files document + * @property {string} _id - Id of the folder + * @property {FilesDoctype} _type - Doctype of the folder + * @property {string} name - Name of the folder + * @property {object} metadata - Metadata of the folder + * @property {object} type - Type of the folder + * @typedef {CozyClientDocument & FolderDocument} IOCozyFolder - An io.cozy.files document + */ -var _isEqual = _interopRequireDefault(__webpack_require__(646)); +/** + * @typedef {object} OAuthClientDocument - An io.cozy.oauth.clients document + * @property {string} _id - Id of the client + * @property {OAuthClientsDoctype} _type - Doctype of the client + * @property {string} software_id + * @property {string} software_version + * @property {string} client_id + * @property {string} client_name + * @property {string} client_kind + * @property {string} client_uri + * @property {string} logo_uri + * @property {string} policy_uri + * @property {string} notification_platform + * @property {string} notification_device_token + * @property {Array<String>} redirect_uris + * @typedef {CozyClientDocument & OAuthClientDocument} IOCozyOAuthClient - An io.cozy.oauth.clients document + */ -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +/** + * @typedef {object} ClientError + * @property {string} [status] + */ -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +/** + * @typedef FilePlugin + * @property {object} [externalDataDirectory] + * @property {object} [cacheDirectory] + * @property {object} [externalCacheDirectory] + * @property {object} [dataDirectory] + */ /** - * @typedef {object} MangoPartialFilter + * @typedef InAppBrowser + * @property {Function} open */ /** - * @typedef {object} MangoQueryOptions - * - * @property {Array<object>} [sort] The sorting parameters - * @property {Array<string>} [fields] The fields to return - * @property {number|null} [limit] For pagination, the number of results to return - * @property {number|null} [skip] For skip-based pagination, the number of referenced files to skip - * @property {string|null} [indexId] The _id of the CouchDB index to use for this request - * @property {string|null} [bookmark] For bookmark-based pagination, the document _id to start from - * @property {Array<string>} [indexedFields] - * @property {MangoPartialFilter|null} [partialFilter] An optional partial filter + * @typedef {object} AppMetadata */ /** - * Attributes representing a design doc + * @typedef {object} ClientCapabilities * - * @typedef {object} DesignDoc + * @description Read more about client capabilities here https://docs.cozy.io/en/cozy-stack/settings/#get-settingscapabilities. * - * @property {string} _id - Id of the design doc. Can be named, e.g. '_design/by_indexed_attribute' or not, e.g. '_design/12345' - * @property {string} language - The index language. Can be 'query' for mango index or 'javascript' for views. - * @property {object} views - Views definition, i.e. the index. + * @property {boolean} can_auth_with_oidc - Whether OIDC login is possible with this Cozy + * @property {boolean} can_auth_with_password - Whether password login is possible with this Cozy + * @property {boolean} file_versioning - Whether file versioning is active on this Cozy + * @property {boolean} flat_subdomains - Whether the stack has been configured to use flat subdomains */ -var normalizeDesignDoc = function normalizeDesignDoc(designDoc) { - var id = designDoc._id || designDoc.id; - return _objectSpread({ - id: id, - _id: id - }, designDoc.doc); -}; -exports.normalizeDesignDoc = normalizeDesignDoc; +/** + * @typedef Cordova + * @property {FilePlugin} file + * @property {InAppBrowser} InAppBrowser + * @property {object} plugins + */ -var getIndexNameFromFields = function getIndexNameFromFields(fields) { - return "by_".concat(fields.join('_and_')); -}; +/** + * @typedef CordovaWindow + * @property {Cordova} cordova + * @property {object} SafariViewController + * @property {Function} resolveLocalFileSystemURL + * @property {Function} handleOpenURL + */ -exports.getIndexNameFromFields = getIndexNameFromFields; +/** + * @typedef {object} CouchDBDocument - A document + * @property {string} _id - Id of the document + * @property {string} _rev - Current revision of the document + * @property {boolean} [_deleted] - When the document has been deleted + * @property {object} [relationships] - Relationships of the document + */ -var transformSort = function transformSort(sort) { - if (!sort || Array.isArray(sort)) { - return sort; - } +/** + * @typedef {object} CouchDBBulkResult - An item of the CouchDB bulk docs response + * @property {boolean} ok + * @property {string} id + * @property {string} rev + * @property {string?} error? + * @property {string?} reason? + */ - console.warn('Passing an object to the "sort" is deprecated, please use an array instead.'); - return (0, _utils.transform)(sort, function (acc, order, field) { - return acc.push((0, _defineProperty2.default)({}, field, order)); - }, []); -}; /** - * Compute fields that should be indexed for a mango - * query to work + * @typedef {Array<string>|string} ViewKey + * @typedef {string} DocId + * @typedef {[ViewKey, DocId]} CouchDBViewCursor + */ + +/** + * @typedef {object} Theme + * @property {string} id + * @property {string} label + * @property {string} icon + * @property {Array<QualificationAttributes>} items + * @property {Array<string>} [defaultItems] * - * @param {MangoQueryOptions} options - Mango query options + * @typedef {Array<Theme>} ThemesList * - * @returns {Array} - Fields to index + * @typedef {'identity'|'family'|'work_study'|'health'|'home'|'transport'|'finance'|'invoice'} ThemesLabels */ +/** + * @typedef {object} QualificationAttributes + * @property {string} label + * @property {string} [purpose] + * @property {string} [sourceCategory] + * @property {string} [sourceSubCategory] + * @property {Array<string>} [subjects] + */ -exports.transformSort = transformSort; - -var getIndexFields = function getIndexFields(_ref) { - var selector = _ref.selector, - _ref$sort = _ref.sort, - sort = _ref$sort === void 0 ? [] : _ref$sort; - return Array.from(new Set([].concat((0, _toConsumableArray2.default)(sort.map(function (sortOption) { - return (0, _head.default)(Object.keys(sortOption)); - })), (0, _toConsumableArray2.default)(selector ? Object.keys(selector) : [])))); -}; /** - * Check if an index is in an inconsistent state, i.e. its name - * contains the indexed attributes which are not in correct order. + * @typedef {'identity_photo'|'national_id_card'|'passport'|'residence_permit'|'family_record_book'|'birth_certificate'|'driver_license'|'other_identity_document'|'citizen_registration_certificate'|'personal_sporting_licence'} IdentityLabel * - * @param {DesignDoc} index - The index to check - * @returns {boolean} True if the index is inconsistent + * @typedef {'family_record_book'|'birth_certificate'|'wedding'|'pacs'|'divorce'|'large_family_card'|'caf'|'other_family_document'|'payment_proof_family_allowance'} FamilyLabel + * + * @typedef {'diploma'|'work_contract'|'pay_sheet'|'unemployment_benefit'|'pension'|'gradebook'|'student_card'|'resume'|'motivation_letter'|'other_work_document'|'work_disability_recognition'|'school_attendance_certificate'} WorkStudyLabels + * + * @typedef {'health_certificate'|'health_book'|'national_health_insurance_card'|'health_insurance_card'|'prescription'|'health_invoice'|'national_health_insurance_right_certificate'|'work_disability_recognition'|'pregnancy_medical_certificate'|'other_health_document'} HealthLabels + * + * @typedef {'phone_invoice'|'isp_invoice'|'telecom_invoice'|'energy_invoice'|'water_invoice'|'house_sale_agreeement'|'building_permit'|'technical_diagnostic_record'|'lease'|'rent_receipt'|'house_insurance'|'work_quote'|'work_invoice'|'other_house_document'|'unfit_for_habitation_declaration'|'accommodation_proof'|'house_insurance'} HomeLabels + * + * @typedef {'driver_license'|'vehicle_registration'|'car_insurance'|'mechanic_invoice'|'transport_invoice'|'other_transport_document'} TransportLabels + * + * @typedef {'tax_return'|'tax_notice'|'tax_timetable'|'pay_sheet'|'receipt'|'other_tax_document'|'bank_details'|'bank_statement'|'loan_agreement'|'other_bank_document'|'payment_proof_family_allowance'|'other_revenue'} FinanceLabels + * + * @typedef {'phone_invoice'|'isp_invoice'|'telecom_invoice'|'energy_invoice'|'water_invoice'|'appliance_invoice'|'web_service_invoice'|'restaurant_invoice'|'work_invoice'|'transport_invoice'|'health_invoice'|'other_invoice'} InvoiceLabels + * + * @typedef {'personal_sporting_licence'|'other_activity_document'} ActivityLabels + * + * @typedef {IdentityLabel|FamilyLabel|WorkStudyLabels|HealthLabels|HomeLabels|TransportLabels|FinanceLabels|InvoiceLabels|ActivityLabels} ItemsLabels */ - -exports.getIndexFields = getIndexFields; - -var isInconsistentIndex = function isInconsistentIndex(index) { - var indexId = index._id; - - if (!indexId.startsWith('_design/by_')) { - return false; - } - - var fieldsInName = indexId.split('_design/by_')[1].split('_and_'); - var viewId = Object.keys((0, _get.default)(index, "views"))[0]; - var fieldsInIndex = Object.keys((0, _get.default)(index, "views.".concat(viewId, ".map.fields"))); - return !(0, _isEqual.default)(fieldsInName, fieldsInIndex); -}; /** - * Check if an index is matching the given fields + * @typedef {object} DACCMeasure + * See https://github.com/cozy/DACC * - * @param {DesignDoc} index - The index to check - * @param {Array} fields - The fields that the index must have - * @param {object} partialFilter - An optional partial filter - * @returns {boolean} True if the index is matches the given fields + * @property {string} measureName - It must match an existing measure name on the DACC server + * @property {string} startDate - Start of the aggregation period. Should be in YYYY-MM-DD format + * @property {number} value - The measured value on the aggregation period + * @property {string} createdBy - The slug of the app creating the measure + * @property {object} group1 - Should be a {key: value} where the key is set in the measure definition. + * @property {object} group2 - Should be a {key: value} where the key is set in the measure definition. + * @property {object} group3 - Should be a {key: value} where the key is set in the measure definition. */ - -exports.isInconsistentIndex = isInconsistentIndex; - -var isMatchingIndex = function isMatchingIndex(index, fields, partialFilter) { - var viewId = Object.keys((0, _get.default)(index, "views"))[0]; - var fieldsInIndex = Object.keys((0, _get.default)(index, "views.".concat(viewId, ".map.fields"))); - - if ((0, _isEqual.default)(fieldsInIndex, fields)) { - if (!partialFilter) { - return true; - } - - var partialFilterInIndex = (0, _get.default)(index, "views.".concat(viewId, ".map.partial_filter_selector")); - - if ((0, _isEqual.default)(partialFilter, partialFilterInIndex)) { - return true; - } - } - - return false; -}; - -exports.isMatchingIndex = isMatchingIndex; - -/***/ }), -/* 646 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var baseIsEqual = __webpack_require__(410); - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. + * Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions. * - * **Note:** This method supports comparing arrays, array buffers, booleans, - * date objects, error objects, maps, numbers, `Object` objects, regexes, - * sets, strings, symbols, and typed arrays. `Object` objects are compared - * by their own, not inherited, enumerable properties. Functions and DOM - * nodes are compared by strict equality, i.e. `===`. + * @callback OpenURLCallback + * @param {string} url - URL to present to the user + */ + +/** + * A session code generated by the cozy-stack that can be used to create a session * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example + * More information: https://docs.cozy.io/en/cozy-stack/auth/#post-authsession_code * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; + * @typedef {string} SessionCode + */ + +/** + * An object containing a code verifier and a code challenge that can be used in a + * PKCE verification process * - * _.isEqual(object, other); - * // => true + * More information: https://docs.cozy.io/en/cozy-stack/auth/#pkce-extension * - * object === other; - * // => false + * @typedef {object} PKCECodes + * @property {string} [codeVerifier] + * @property {string} [codeChallenge] */ -function isEqual(value, other) { - return baseIsEqual(value, other); -} - -module.exports = isEqual; - +var _default = {}; +exports["default"] = _default; /***/ }), -/* 647 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/* 623 */ +/***/ ((__unused_webpack_module, exports) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); - Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.buildURL = exports.encode = void 0; - -var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520)); - -var _pickBy = _interopRequireDefault(__webpack_require__(648)); +exports.formatBytes = exports.slugify = exports.sleep = exports.attempt = exports.uri = void 0; /** - * Encode a value of any type into a URI search param compatible string with a specific treatment for arrays which will keep their brackets (they do not with standard `toString()` method). - * - * Examples: - * - * encodeValues([['io.cozy.files', 'abcd1234'], '12345']) - * // → '[[%22io.cozy.files%22,%22abcd1234%22],%2212345%22]' - * - * encodeValues([['io.cozy.files', 'abcd1234'], '12345'].toString(), true) - * // → '%22io.cozy.files%2Cabcd1234%2C12345%22' + * @function + * @description Template tag function for URIs encoding * - * encodeValues([['io.cozy.files', 'abcd1234'], '12345'].toString(), false) - * // → 'io.cozy.files%2Cabcd1234%2C12345' + * Will automatically apply `encodeURIComponent` to template literal placeholders * - * encodeValues('[1234]') - * // → %5B1234%5D + * @example + * ``` + * const safe = uri`/data/${doctype}/_all_docs?limit=${limit}` + * ``` * - * @function * @private */ -var encodeValues = function encodeValues(values) { - var fromArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; +var uri = function uri(strings) { + var parts = [strings[0]]; - if (Array.isArray(values)) { - return '[' + values.map(function (v) { - return encodeValues(v, true); - }).join(',') + ']'; + for (var i = 0; i < (arguments.length <= 1 ? 0 : arguments.length - 1); i++) { + parts.push(encodeURIComponent(i + 1 < 1 || arguments.length <= i + 1 ? undefined : arguments[i + 1]) + strings[i + 1]); } - return fromArray ? encodeURIComponent("\"".concat(values, "\"")) : encodeURIComponent(values); + return parts.join(''); }; /** - * Encode an object as querystring, values are encoded as - * URI components, keys are not. - * * @function + * @description Helps to avoid nested try/catch when using async/await + * + * Inspired by a Go pattern: http://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/ + * + * @example + * ``` + * if (await attempt(collection.all()) return + * await sleep(1000) + * if (await attempt(collection.all()) return + * await sleep(1000) + * return + * ``` + * * @private */ -var encode = function encode(data) { - return Object.entries(data).map(function (_ref) { - var _ref2 = (0, _slicedToArray2.default)(_ref, 2), - k = _ref2[0], - v = _ref2[1]; +exports.uri = uri; - var encodedValue = encodeValues(v); - return "".concat(k, "=").concat(encodedValue); - }).join('&'); +var attempt = function attempt(promise) { + return promise.then(function () { + return true; + }).catch(function () { + return false; + }); }; /** - * Returns a URL from base url and a query parameter object. - * Any undefined parameter is removed. - * * @function + * @description Helps to avoid nested try/catch when using async/await — see documentation for attempt * @private */ -exports.encode = encode; +exports.attempt = attempt; -var buildURL = function buildURL(url, params) { - var qs = encode((0, _pickBy.default)(params)); +var sleep = function sleep(time, args) { + return new Promise(function (resolve) { + setTimeout(resolve, time, args); + }); +}; - if (qs) { - return "".concat(url, "?").concat(qs); - } else { - return url; - } +exports.sleep = sleep; + +var slugify = function slugify(text) { + return text.toString().toLowerCase().replace(/\s+/g, '-') // Replace spaces with - + .replace(/[^\w-]+/g, '') // Remove all non-word chars + .replace(/--+/g, '-') // Replace multiple - with single - + .replace(/^-+/, '') // Trim - from start of text + .replace(/-+$/, ''); +}; // Trim - from end of text + + +exports.slugify = slugify; + +var formatBytes = function formatBytes(bytes) { + var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; + if (bytes === 0) return '0 Bytes'; + var k = 1024; + var dm = decimals < 0 ? 0 : decimals; + var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + var i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; }; -exports.buildURL = buildURL; +exports.formatBytes = formatBytes; /***/ }), -/* 648 */ +/* 624 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var arrayMap = __webpack_require__(398), - baseIteratee = __webpack_require__(401), - basePickBy = __webpack_require__(649), - getAllKeysIn = __webpack_require__(576); +var baseUniq = __webpack_require__(475); /** - * Creates an object composed of the `object` properties `predicate` returns - * truthy for. The predicate is invoked with two arguments: (value, key). + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. The order of result values is determined by the order they occur + * in the array. * * @static * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. * @example * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pickBy(object, _.isNumber); - * // => { 'a': 1, 'c': 3 } + * _.uniq([2, 1, 2]); + * // => [2, 1] */ -function pickBy(object, predicate) { - if (object == null) { - return {}; - } - var props = arrayMap(getAllKeysIn(object), function(prop) { - return [prop]; - }); - predicate = baseIteratee(predicate); - return basePickBy(object, props, function(value, path) { - return predicate(value, path[0]); - }); +function uniq(array) { + return (array && array.length) ? baseUniq(array) : []; } -module.exports = pickBy; +module.exports = uniq; /***/ }), -/* 649 */ +/* 625 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseGet = __webpack_require__(359), - baseSet = __webpack_require__(650), - castPath = __webpack_require__(360); +var arrayMap = __webpack_require__(410), + baseClone = __webpack_require__(574), + baseUnset = __webpack_require__(626), + castPath = __webpack_require__(372), + copyObject = __webpack_require__(577), + customOmitClone = __webpack_require__(630), + flatRest = __webpack_require__(632), + getAllKeysIn = __webpack_require__(588); + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; /** - * The base implementation of `_.pickBy` without support for iteratee shorthands. + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable property paths of `object` that are not omitted. * - * @private + * **Note:** This method is considerably slower than `_.pick`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object * @param {Object} object The source object. - * @param {string[]} paths The property paths to pick. - * @param {Function} predicate The function invoked per property. + * @param {...(string|string[])} [paths] The property paths to omit. * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } */ -function basePickBy(object, paths, predicate) { - var index = -1, - length = paths.length, - result = {}; - - while (++index < length) { - var path = paths[index], - value = baseGet(object, path); - - if (predicate(value, path)) { - baseSet(result, castPath(path, object), value); - } +var omit = flatRest(function(object, paths) { + var result = {}; + if (object == null) { + return result; + } + var isDeep = false; + paths = arrayMap(paths, function(path) { + path = castPath(path, object); + isDeep || (isDeep = path.length > 1); + return path; + }); + copyObject(object, getAllKeysIn(object), result); + if (isDeep) { + result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); + } + var length = paths.length; + while (length--) { + baseUnset(result, paths[length]); } return result; -} +}); -module.exports = basePickBy; +module.exports = omit; /***/ }), -/* 650 */ +/* 626 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var assignValue = __webpack_require__(563), - castPath = __webpack_require__(360), - isIndex = __webpack_require__(436), - isObject = __webpack_require__(52), - toKey = __webpack_require__(399); +var castPath = __webpack_require__(372), + last = __webpack_require__(627), + parent = __webpack_require__(628), + toKey = __webpack_require__(411); /** - * The base implementation of `_.set`. + * The base implementation of `_.unset`. * * @private * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. + * @param {Array|string} path The property path to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. */ -function baseSet(object, path, value, customizer) { - if (!isObject(object)) { - return object; - } +function baseUnset(object, path) { path = castPath(path, object); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]), - newValue = value; - - if (key === '__proto__' || key === 'constructor' || key === 'prototype') { - return object; - } - - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = isObject(objValue) - ? objValue - : (isIndex(path[index + 1]) ? [] : {}); - } - } - assignValue(nested, key, newValue); - nested = nested[key]; - } - return object; + object = parent(object, path); + return object == null || delete object[toKey(last(path))]; } -module.exports = baseSet; +module.exports = baseUnset; /***/ }), -/* 651 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.FetchError = exports["default"] = void 0; - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +/* 627 */ +/***/ ((module) => { -var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(594)); +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +module.exports = last; -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +/***/ }), +/* 628 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652)); +var baseGet = __webpack_require__(371), + baseSlice = __webpack_require__(629); -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +/** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ +function parent(object, path) { + return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); +} -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +module.exports = parent; -var EXPIRED_TOKEN = /Expired token/; -var CLIENT_NOT_FOUND = /Client not found/; -var INVALID_TOKEN = /Invalid JWT token/; -var _default = { - EXPIRED_TOKEN: EXPIRED_TOKEN, - CLIENT_NOT_FOUND: CLIENT_NOT_FOUND, - INVALID_TOKEN: INVALID_TOKEN -}; -exports["default"] = _default; -var getWwwAuthenticateErrorMessage = function getWwwAuthenticateErrorMessage(response) { - var invalidTokenRegex = /invalid_token/; - var expiredTokenRegex = /access token expired/; - var wwwAuthenticateHeader = response.headers && response.headers.get('www-authenticate'); +/***/ }), +/* 629 */ +/***/ ((module) => { - if (!wwwAuthenticateHeader) { - return undefined; - } +/** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function baseSlice(array, start, end) { + var index = -1, + length = array.length; - if (expiredTokenRegex.test(wwwAuthenticateHeader)) { - return 'Expired token'; + if (start < 0) { + start = -start > length ? 0 : (length + start); } - - if (invalidTokenRegex.test(wwwAuthenticateHeader)) { - return 'Invalid token'; + end = end > length ? length : end; + if (end < 0) { + end += length; } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; - return undefined; -}; - -var FetchError = /*#__PURE__*/function (_Error) { - (0, _inherits2.default)(FetchError, _Error); - - var _super = _createSuper(FetchError); - - function FetchError(response, reason) { - var _this; - - (0, _classCallCheck2.default)(this, FetchError); - _this = _super.call(this); - - if (Error.captureStackTrace) { - Error.captureStackTrace((0, _assertThisInitialized2.default)(_this), _this.constructor); - } // WARN We have to hardcode this because babel doesn't play nice when extending Error - - - _this.name = 'FetchError'; - _this.response = response; - _this.url = response.url; - _this.status = response.status; - _this.reason = reason; - var wwwAuthenticateErrorMessage = getWwwAuthenticateErrorMessage(response); - Object.defineProperty((0, _assertThisInitialized2.default)(_this), 'message', { - value: reason.message || wwwAuthenticateErrorMessage || (typeof reason === 'string' ? reason : JSON.stringify(reason)) - }); - return _this; + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; } + return result; +} - return FetchError; -}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); +module.exports = baseSlice; -exports.FetchError = FetchError; /***/ }), -/* 652 */ +/* 630 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var getPrototypeOf = __webpack_require__(595); - -var setPrototypeOf = __webpack_require__(592); - -var isNativeFunction = __webpack_require__(653); - -var construct = __webpack_require__(654); - -function _wrapNativeSuper(Class) { - var _cache = typeof Map === "function" ? new Map() : undefined; - - module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) { - if (Class === null || !isNativeFunction(Class)) return Class; - - if (typeof Class !== "function") { - throw new TypeError("Super expression must either be null or a function"); - } - - if (typeof _cache !== "undefined") { - if (_cache.has(Class)) return _cache.get(Class); - - _cache.set(Class, Wrapper); - } - - function Wrapper() { - return construct(Class, arguments, getPrototypeOf(this).constructor); - } - - Wrapper.prototype = Object.create(Class.prototype, { - constructor: { - value: Wrapper, - enumerable: false, - writable: true, - configurable: true - } - }); - return setPrototypeOf(Wrapper, Class); - }; +var isPlainObject = __webpack_require__(631); - module.exports["default"] = module.exports, module.exports.__esModule = true; - return _wrapNativeSuper(Class); +/** + * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain + * objects. + * + * @private + * @param {*} value The value to inspect. + * @param {string} key The key of the property to inspect. + * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. + */ +function customOmitClone(value) { + return isPlainObject(value) ? undefined : value; } -module.exports = _wrapNativeSuper; -module.exports["default"] = module.exports, module.exports.__esModule = true; - -/***/ }), -/* 653 */ -/***/ ((module) => { - -function _isNativeFunction(fn) { - return Function.toString.call(fn).indexOf("[native code]") !== -1; -} +module.exports = customOmitClone; -module.exports = _isNativeFunction; -module.exports["default"] = module.exports, module.exports.__esModule = true; /***/ }), -/* 654 */ +/* 631 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var setPrototypeOf = __webpack_require__(592); - -var isNativeReflectConstruct = __webpack_require__(655); - -function _construct(Parent, args, Class) { - if (isNativeReflectConstruct()) { - module.exports = _construct = Reflect.construct; - module.exports["default"] = module.exports, module.exports.__esModule = true; - } else { - module.exports = _construct = function _construct(Parent, args, Class) { - var a = [null]; - a.push.apply(a, args); - var Constructor = Function.bind.apply(Parent, a); - var instance = new Constructor(); - if (Class) setPrototypeOf(instance, Class.prototype); - return instance; - }; +var baseGetTag = __webpack_require__(46), + getPrototype = __webpack_require__(587), + isObjectLike = __webpack_require__(53); - module.exports["default"] = module.exports, module.exports.__esModule = true; - } +/** `Object#toString` result references. */ +var objectTag = '[object Object]'; - return _construct.apply(null, arguments); -} +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; -module.exports = _construct; -module.exports["default"] = module.exports, module.exports.__esModule = true; +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; -/***/ }), -/* 655 */ -/***/ ((module) => { +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; -function _isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); - try { - Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); - return true; - } catch (e) { +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { return false; } -} - -module.exports = _isNativeReflectConstruct; -module.exports["default"] = module.exports, module.exports.__esModule = true; - -/***/ }), -/* 656 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -var AppToken = /*#__PURE__*/function () { - function AppToken(token) { - (0, _classCallCheck2.default)(this, AppToken); - this.token = token || ''; - } - - (0, _createClass2.default)(AppToken, [{ - key: "toAuthHeader", - value: function toAuthHeader() { - return 'Bearer ' + this.token; - } - }, { - key: "toBasicAuth", - value: function toBasicAuth() { - return "user:".concat(this.token, "@"); - } - /** - * Get the app token string - * - * @see CozyStackClient.getAccessToken - * @returns {string} token - */ - - }, { - key: "getAccessToken", - value: function getAccessToken() { - return this.token; - } - }]); - return AppToken; -}(); - -exports["default"] = AppToken; - -/***/ }), -/* 657 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -var AccessToken = /*#__PURE__*/function () { - function AccessToken(dataArg) { - (0, _classCallCheck2.default)(this, AccessToken); - var data = dataArg; - if (typeof data === 'string') data = JSON.parse(data); - this.tokenType = data.token_type || data.tokenType; - this.accessToken = data.access_token || data.accessToken; - this.refreshToken = data.refresh_token || data.refreshToken; - this.scope = data.scope; + var proto = getPrototype(value); + if (proto === null) { + return true; } - - (0, _createClass2.default)(AccessToken, [{ - key: "toAuthHeader", - value: function toAuthHeader() { - return 'Bearer ' + this.accessToken; - } - }, { - key: "toBasicAuth", - value: function toBasicAuth() { - return "user:".concat(this.accessToken, "@"); - } - }, { - key: "toJSON", - value: function toJSON() { - return { - tokenType: this.tokenType, - accessToken: this.accessToken, - refreshToken: this.refreshToken, - scope: this.scope - }; - } - }, { - key: "toString", - value: function toString() { - return JSON.stringify(this.toJSON()); - } - /** - * Get the access token string - * - * @see CozyStackClient.getAccessToken - * @returns {string} token - */ - - }, { - key: "getAccessToken", - value: function getAccessToken() { - return this.accessToken; - } - }]); - return AccessToken; -}(); - -exports["default"] = AccessToken; - -/***/ }), -/* 658 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireWildcard = __webpack_require__(510); - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.isDirectory = exports.isFile = void 0; - -var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525)); - -var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602)); - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(594)); - -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); - -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); - -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); - -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); - -var _lite = _interopRequireDefault(__webpack_require__(659)); - -var _has = _interopRequireDefault(__webpack_require__(662)); - -var _get = _interopRequireDefault(__webpack_require__(358)); - -var _omit = _interopRequireDefault(__webpack_require__(613)); - -var _pick = _interopRequireDefault(__webpack_require__(664)); - -var _mangoIndex = __webpack_require__(645); - -var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601)); - -var _utils = __webpack_require__(611); - -var _errors = __webpack_require__(651); - -var _Collection = __webpack_require__(600); - -var _getIllegalCharacter = __webpack_require__(666); - -var querystring = _interopRequireWildcard(__webpack_require__(647)); - -function _templateObject23() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/_changes"]); - - _templateObject23 = function _templateObject23() { - return data; - }; - - return data; -} - -function _templateObject22() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]); - - _templateObject22 = function _templateObject22() { - return data; - }; - - return data; -} - -function _templateObject21() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]); - - _templateObject21 = function _templateObject21() { - return data; - }; - - return data; -} - -function _templateObject20() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]); - - _templateObject20 = function _templateObject20() { - return data; - }; - - return data; -} - -function _templateObject19() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/versions"]); - - _templateObject19 = function _templateObject19() { - return data; - }; - - return data; -} - -function _templateObject18() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/upload/metadata"]); - - _templateObject18 = function _templateObject18() { - return data; - }; - - return data; + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; } -function _templateObject17() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); - - _templateObject17 = function _templateObject17() { - return data; - }; +module.exports = isPlainObject; - return data; -} -function _templateObject16() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=directory"]); +/***/ }), +/* 632 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - _templateObject16 = function _templateObject16() { - return data; - }; +var flatten = __webpack_require__(552), + overRest = __webpack_require__(557), + setToString = __webpack_require__(559); - return data; +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return setToString(overRest(func, undefined, flatten), func + ''); } -function _templateObject15() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/metadata?Path=", ""]); +module.exports = flatRest; - _templateObject15 = function _templateObject15() { - return data; - }; - return data; +/***/ }), +/* 633 */ +/***/ ((module) => { + +/** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ +function head(array) { + return (array && array.length) ? array[0] : undefined; } -function _templateObject14() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); +module.exports = head; - _templateObject14 = function _templateObject14() { - return data; - }; - return data; -} +/***/ }), +/* 634 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _templateObject13() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?Path=", ""]); +var baseClamp = __webpack_require__(635), + baseToString = __webpack_require__(409), + toInteger = __webpack_require__(636), + toString = __webpack_require__(408); - _templateObject13 = function _templateObject13() { - return data; - }; +/** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, + * else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ +function startsWith(string, target, position) { + string = toString(string); + position = position == null + ? 0 + : baseClamp(toInteger(position), 0, string.length); - return data; + target = baseToString(target); + return string.slice(position, position + target.length) == target; } -function _templateObject12() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?VersionId=", "&Filename=", ""]); +module.exports = startsWith; - _templateObject12 = function _templateObject12() { - return data; - }; - return data; +/***/ }), +/* 635 */ +/***/ ((module) => { + +/** + * The base implementation of `_.clamp` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ +function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; } -function _templateObject11() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?Id=", "&Filename=", ""]); +module.exports = baseClamp; - _templateObject11 = function _templateObject11() { - return data; - }; - return data; -} +/***/ }), +/* 636 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _templateObject10() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=file&Executable=", ""]); +var toFinite = __webpack_require__(637); - _templateObject10 = function _templateObject10() { - return data; - }; +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; - return data; + return result === result ? (remainder ? result - remainder : result) : 0; } -function _templateObject9() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=file&Executable=", "&MetadataID=", "&Size=", ""]); +module.exports = toInteger; - _templateObject9 = function _templateObject9() { - return data; - }; - return data; -} +/***/ }), +/* 637 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _templateObject8() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); +var toNumber = __webpack_require__(638); - _templateObject8 = function _templateObject8() { - return data; - }; +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; - return data; +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; } -function _templateObject7() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/trash/", ""]); +module.exports = toFinite; - _templateObject7 = function _templateObject7() { - return data; - }; - return data; -} +/***/ }), +/* 638 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _templateObject6() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); +var baseTrim = __webpack_require__(639), + isObject = __webpack_require__(52), + isSymbol = __webpack_require__(374); - _templateObject6 = function _templateObject6() { - return data; - }; +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; - return data; -} +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; -function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; -function _templateObject5() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]); +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} - _templateObject5 = function _templateObject5() { - return data; - }; +module.exports = toNumber; - return data; -} -function _templateObject4() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]); +/***/ }), +/* 639 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - _templateObject4 = function _templateObject4() { - return data; - }; +var trimmedEndIndex = __webpack_require__(640); - return data; +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; } -function _templateObject3() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/relationships/referenced_by"]); +module.exports = baseTrim; - _templateObject3 = function _templateObject3() { - return data; - }; - return data; -} +/***/ }), +/* 640 */ +/***/ ((module) => { -function _templateObject2() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/relationships/referenced_by"]); +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; - _templateObject2 = function _templateObject2() { - return data; - }; +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; - return data; + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; } -function _templateObject() { - var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]); +module.exports = trimmedEndIndex; - _templateObject = function _templateObject() { - return data; - }; - return data; -} +/***/ }), +/* 641 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +"use strict"; -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +var stringify = __webpack_require__(642); +var parse = __webpack_require__(656); +var formats = __webpack_require__(655); -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +module.exports = { + formats: formats, + parse: parse, + stringify: stringify +}; -/** - * Cursor used for Mango queries pagination - * - * @typedef {Array<string>|string} ViewKey - * @typedef {string} DocId - * @typedef {Array<*> & {0: ViewKey, 1: DocId}} CouchDBViewCursor - */ -/** - * Attributes used for directory creation - * - * @typedef {object} DirectoryAttributes - * @property {string} dirId - Id of the parent directory. - * @property {boolean} name - Name of the created directory. - * @property {boolean} executable - Indicates whether the file will be executable. - */ +/***/ }), +/* 642 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/** - * Attributes used for file creation - * - * @typedef {object} FileAttributes - * @property {string} dirId - Id of the parent directory. - * @property {string} name - Name of the created file. - * @property {Date} lastModifiedDate - Can be used to set the last modified date of a file. - * @property {boolean} executable - Whether or not the file is executable - * @property {object} metadata io.cozy.files.metadata to attach to the file - */ +"use strict"; -/** - * Document representing a io.cozy.files - * - * @typedef {object} FileDocument - * @property {string} _id - Id of the file - * @property {FileAttributes} attributes - Attributes of the file - */ -/** - * Stream is not defined in a browser, but is on NodeJS environment - * - * @typedef {object} Stream - */ +var getSideChannel = __webpack_require__(643); +var utils = __webpack_require__(654); +var formats = __webpack_require__(655); +var has = Object.prototype.hasOwnProperty; -/** - * Document representing a io.cozy.oauth.clients - * - * @typedef {object} OAuthClient - * @property {string} _id - Id of the client - * @property {string} _type - Doctype of the client (i.e. io.cozy.oauth.clients) - */ -var ROOT_DIR_ID = 'io.cozy.files.root-dir'; -var CONTENT_TYPE_OCTET_STREAM = 'application/octet-stream'; -/** - * Normalize a file, adding document's doctype if needed - * - * @param {FileDocument} file - File to normalize - * @returns {FileDocument} normalized file - * @private - */ +var arrayPrefixGenerators = { + brackets: function brackets(prefix) { + return prefix + '[]'; + }, + comma: 'comma', + indices: function indices(prefix, key) { + return prefix + '[' + key + ']'; + }, + repeat: function repeat(prefix) { + return prefix; + } +}; -var normalizeFile = function normalizeFile(file) { - return _objectSpread(_objectSpread({}, (0, _DocumentCollection2.normalizeDoc)(file, 'io.cozy.files')), file.attributes); +var isArray = Array.isArray; +var push = Array.prototype.push; +var pushToArray = function (arr, valueOrArray) { + push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]); }; -/** - * Normalize references, expliciting _type and _id — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/ - * - * @param {Array<object>} references - The list of files referenced by a document to normalize - * @returns {Array<object>} the data attribute of the normalized references - * @private - */ +var toISO = Date.prototype.toISOString; -var normalizeReferences = function normalizeReferences(references) { - return references ? references.map(function (ref) { - return { - _type: ref.type, - _id: ref.id - }; - }) : []; +var defaultFormat = formats['default']; +var defaults = { + addQueryPrefix: false, + allowDots: false, + charset: 'utf-8', + charsetSentinel: false, + delimiter: '&', + encode: true, + encoder: utils.encode, + encodeValuesOnly: false, + format: defaultFormat, + formatter: formats.formatters[defaultFormat], + // deprecated + indices: false, + serializeDate: function serializeDate(date) { + return toISO.call(date); + }, + skipNulls: false, + strictNullHandling: false }; -/** - * Sanitize the file name by trimming spaces - * - * @param {string} name - The file name to trim - * @returns {string} the trimmed file name - * @private - */ - -var sanitizeFileName = function sanitizeFileName(name) { - return name && name.trim(); +var isNonNullishPrimitive = function isNonNullishPrimitive(v) { + return typeof v === 'string' + || typeof v === 'number' + || typeof v === 'boolean' + || typeof v === 'symbol' + || typeof v === 'bigint'; }; -/** - * Sanitize and validate the file name - throw errors according to case - * - * @param {string} name - The file name - * @returns {string} the trimmed safe file name - * @throws {Error} - explaining reason why file name is not valid - * @private - */ +var stringify = function stringify( + object, + prefix, + generateArrayPrefix, + strictNullHandling, + skipNulls, + encoder, + filter, + sort, + allowDots, + serializeDate, + format, + formatter, + encodeValuesOnly, + charset, + sideChannel +) { + var obj = object; -var sanitizeAndValidateFileName = function sanitizeAndValidateFileName(name) { - var safeName = sanitizeFileName(name); + if (sideChannel.has(object)) { + throw new RangeError('Cyclic object value'); + } - if (typeof safeName !== 'string' || safeName === '') { - throw new Error('Missing name argument'); - } + if (typeof filter === 'function') { + obj = filter(prefix, obj); + } else if (obj instanceof Date) { + obj = serializeDate(obj); + } else if (generateArrayPrefix === 'comma' && isArray(obj)) { + obj = utils.maybeMap(obj, function (value) { + if (value instanceof Date) { + return serializeDate(value); + } + return value; + }); + } - if (name === '.' || name === '..') { - throw new Error("Invalid filename: ".concat(name)); - } + if (obj === null) { + if (strictNullHandling) { + return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix; + } - var illegalCharacters = (0, _getIllegalCharacter.getIllegalCharacters)(safeName); + obj = ''; + } - if (illegalCharacters.length) { - throw new Error("Invalid filename containing illegal character(s): ".concat(illegalCharacters)); - } + if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) { + if (encoder) { + var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format); + return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))]; + } + return [formatter(prefix) + '=' + formatter(String(obj))]; + } - return safeName; -}; -/** - * Returns true when parameter has type directory, file or has _type io.cozy.files - * - * @param {object} doc - The document whose type is checked - * @param {string} [doc._type] - The document's doctype - * @param {'directory'|'file'} [doc.type] - The io.cozy-files document type - * - * @returns {boolean} true when objects has type directory, file or has _type io.cozy.files or false - */ + var values = []; + if (typeof obj === 'undefined') { + return values; + } -var isFile = function isFile(_ref) { - var _type = _ref._type, - type = _ref.type; - return _type === 'io.cozy.files' || type === 'directory' || type === 'file'; -}; -/** - * Returns true when parameters has type directory - * - * @param {string} type - The type of the file - * @returns {boolean} true when parameters has type directory or false - */ + var objKeys; + if (generateArrayPrefix === 'comma' && isArray(obj)) { + // we need to join elements in + objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }]; + } else if (isArray(filter)) { + objKeys = filter; + } else { + var keys = Object.keys(obj); + objKeys = sort ? keys.sort(sort) : keys; + } + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key]; -exports.isFile = isFile; + if (skipNulls && value === null) { + continue; + } -var isDirectory = function isDirectory(_ref2) { - var type = _ref2.type; - return type === 'directory'; -}; + var keyPrefix = isArray(obj) + ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix + : prefix + (allowDots ? '.' + key : '[' + key + ']'); -exports.isDirectory = isDirectory; + sideChannel.set(object, true); + var valueSideChannel = getSideChannel(); + pushToArray(values, stringify( + value, + keyPrefix, + generateArrayPrefix, + strictNullHandling, + skipNulls, + encoder, + filter, + sort, + allowDots, + serializeDate, + format, + formatter, + encodeValuesOnly, + charset, + valueSideChannel + )); + } -var raceWithCondition = function raceWithCondition(promises, predicate) { - return new Promise(function (resolve) { - promises.forEach(function (p) { - return p.then(function (res) { - if (predicate(res)) { - resolve(true); - } - }); - }); - Promise.all(promises).then(function () { - return resolve(false); - }); - }); + return values; }; -var dirName = function dirName(path) { - var lastIndex = path.lastIndexOf('/'); - return path.substring(0, lastIndex); -}; -/** - * Implements `DocumentCollection` API along with specific methods for - * `io.cozy.files`. - * - * Files are a special type of documents and are handled differently by the stack: - * special routes are to be used, and there is a notion of referenced files, aka - * files associated to a specific document - */ +var normalizeStringifyOptions = function normalizeStringifyOptions(opts) { + if (!opts) { + return defaults; + } + if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') { + throw new TypeError('Encoder has to be a function.'); + } -var FileCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(FileCollection, _DocumentCollection); + var charset = opts.charset || defaults.charset; + if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { + throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); + } - var _super = _createSuper(FileCollection); + var format = formats['default']; + if (typeof opts.format !== 'undefined') { + if (!has.call(formats.formatters, opts.format)) { + throw new TypeError('Unknown format option provided.'); + } + format = opts.format; + } + var formatter = formats.formatters[format]; - function FileCollection(doctype, stackClient) { - var _this; + var filter = defaults.filter; + if (typeof opts.filter === 'function' || isArray(opts.filter)) { + filter = opts.filter; + } - (0, _classCallCheck2.default)(this, FileCollection); - _this = _super.call(this, doctype, stackClient); - (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "extractResponseLinkRelated", function (res) { - var href = res.links && res.links.related; - if (!href) throw new Error('No related link in server response'); - return _this.stackClient.fullpath(href); - }); - (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "forceFileDownload", function (href, filename) { - var element = document.createElement('a'); - element.setAttribute('href', href); - element.setAttribute('download', filename); - element.style.display = 'none'; - document.body.appendChild(element); - element.click(); - document.body.removeChild(element); - }); - _this.specialDirectories = {}; - return _this; - } - /** - * Fetches the file's data - * - * @param {string} id File id - * @returns {{data, included}} Information about the file or folder and it's descendents - */ + return { + addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix, + allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots, + charset: charset, + charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, + delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter, + encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode, + encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder, + encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly, + filter: filter, + format: format, + formatter: formatter, + serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate, + skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls, + sort: typeof opts.sort === 'function' ? opts.sort : null, + strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling + }; +}; +module.exports = function (object, opts) { + var obj = object; + var options = normalizeStringifyOptions(opts); - (0, _createClass2.default)(FileCollection, [{ - key: "get", - value: function get(id) { - return this.statById(id); + var objKeys; + var filter; + + if (typeof options.filter === 'function') { + filter = options.filter; + obj = filter('', obj); + } else if (isArray(options.filter)) { + filter = options.filter; + objKeys = filter; } - }, { - key: "fetchFindFiles", - value: function () { - var _fetchFindFiles = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(selector, options) { - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - return _context.abrupt("return", this.stackClient.fetchJSON('POST', '/files/_find', this.toMangoOptions(selector, options))); - case 1: - case "end": - return _context.stop(); - } - } - }, _callee, this); - })); + var keys = []; - function fetchFindFiles(_x, _x2) { - return _fetchFindFiles.apply(this, arguments); - } + if (typeof obj !== 'object' || obj === null) { + return ''; + } - return fetchFindFiles; - }() - /** - * Returns a filtered list of documents using a Mango selector. - * - * The returned documents are paginated by the stack. - * - * @param {object} selector The Mango selector. - * @param {MangoQueryOptions} options The query options - * - * @returns {{data, meta, skip, next, bookmark}} The JSON API conformant response. - * @throws {FetchError} - */ + var arrayFormat; + if (opts && opts.arrayFormat in arrayPrefixGenerators) { + arrayFormat = opts.arrayFormat; + } else if (opts && 'indices' in opts) { + arrayFormat = opts.indices ? 'indices' : 'repeat'; + } else { + arrayFormat = 'indices'; + } - }, { - key: "find", - value: function () { - var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(selector) { - var options, - _options$skip, - skip, - resp, - path, - nextLink, - nextLinkURL, - nextBookmark, - _args2 = arguments; + var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - options = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {}; - _options$skip = options.skip, skip = _options$skip === void 0 ? 0 : _options$skip; - _context2.prev = 2; - path = '/files/_find'; - _context2.next = 6; - return this.findWithMango(path, selector, options); + if (!objKeys) { + objKeys = Object.keys(obj); + } - case 6: - resp = _context2.sent; - _context2.next = 12; - break; + if (options.sort) { + objKeys.sort(options.sort); + } - case 9: - _context2.prev = 9; - _context2.t0 = _context2["catch"](2); - return _context2.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context2.t0)); + var sideChannel = getSideChannel(); + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; - case 12: - nextLink = (0, _get.default)(resp, 'links.next', ''); - nextLinkURL = new URL("".concat(this.stackClient.uri).concat(nextLink)); - nextBookmark = nextLinkURL.searchParams.get('page[cursor]'); - return _context2.abrupt("return", { - data: resp.data.map(function (f) { - return normalizeFile(f); - }), - meta: resp.meta, - next: resp.meta.count > skip + resp.data.length, - skip: skip, - bookmark: nextBookmark || undefined, - execution_stats: resp.meta.execution_stats - }); + if (options.skipNulls && obj[key] === null) { + continue; + } + pushToArray(keys, stringify( + obj[key], + key, + generateArrayPrefix, + options.strictNullHandling, + options.skipNulls, + options.encode ? options.encoder : null, + options.filter, + options.sort, + options.allowDots, + options.serializeDate, + options.format, + options.formatter, + options.encodeValuesOnly, + options.charset, + sideChannel + )); + } - case 16: - case "end": - return _context2.stop(); - } - } - }, _callee2, this, [[2, 9]]); - })); + var joined = keys.join(options.delimiter); + var prefix = options.addQueryPrefix === true ? '?' : ''; - function find(_x3) { - return _find.apply(this, arguments); - } + if (options.charsetSentinel) { + if (options.charset === 'iso-8859-1') { + // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark + prefix += 'utf8=%26%2310003%3B&'; + } else { + // encodeURIComponent('✓') + prefix += 'utf8=%E2%9C%93&'; + } + } - return find; - }() - /** - * async findReferencedBy - Returns the list of files referenced by a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/ - * - * @param {object} document A JSON representing a document, with at least a `_type` and `_id` field. - * @param {object} options Additional options - * @param {number|null} [options.skip] For skip-based pagination, the number of referenced files to skip. - * @param {number|null} [options.limit] For pagination, the number of results to return. - * @param {CouchDBViewCursor|null} [options.cursor] For cursor-based pagination, the index cursor. - * @returns {{data, included, meta, skip, next, bookmark}} The JSON API conformant response. - */ + return joined.length > 0 ? prefix + joined : ''; +}; - }, { - key: "findReferencedBy", - value: function () { - var _findReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document) { - var _ref3, - _ref3$skip, - skip, - limit, - cursor, - params, - path, - url, - resp, - _args3 = arguments; - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - _ref3 = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {}, _ref3$skip = _ref3.skip, skip = _ref3$skip === void 0 ? 0 : _ref3$skip, limit = _ref3.limit, cursor = _ref3.cursor; - params = { - include: 'files', - 'page[limit]': limit, - 'page[cursor]': cursor, - sort: 'datetime' - }; - path = (0, _utils.uri)(_templateObject(), document._type, document._id); - url = querystring.buildURL(path, params); - _context3.next = 6; - return this.stackClient.fetchJSON('GET', url); +/***/ }), +/* 643 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 6: - resp = _context3.sent; - return _context3.abrupt("return", { - data: normalizeReferences(resp.data), - included: resp.included ? resp.included.map(function (f) { - return normalizeFile(f); - }) : [], - next: (0, _has.default)(resp, 'links.next'), - meta: resp.meta, - skip: skip - }); +"use strict"; - case 8: - case "end": - return _context3.stop(); - } - } - }, _callee3, this); - })); - function findReferencedBy(_x4) { - return _findReferencedBy.apply(this, arguments); - } +var GetIntrinsic = __webpack_require__(644); +var callBound = __webpack_require__(650); +var inspect = __webpack_require__(652); - return findReferencedBy; - }() - /** - * Add referenced_by documents to a file — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#post-filesfile-idrelationshipsreferenced_by - * - * For example, to have an album referenced by a file: - * ``` - * addReferencedBy({_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}, [{_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}]) - * ``` - * - * @param {FileDocument} document A JSON representing the file - * @param {Array} documents An array of JSON documents having a `_type` and `_id` field. - * @returns {{data, meta}} The JSON API conformant response. - */ +var $TypeError = GetIntrinsic('%TypeError%'); +var $WeakMap = GetIntrinsic('%WeakMap%', true); +var $Map = GetIntrinsic('%Map%', true); - }, { - key: "addReferencedBy", - value: function () { - var _addReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(document, documents) { - var refs, resp; - return _regenerator.default.wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - refs = documents.map(function (d) { - return { - id: d._id, - type: d._type - }; - }); - _context4.next = 3; - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject2(), document._id), { - data: refs - }); +var $weakMapGet = callBound('WeakMap.prototype.get', true); +var $weakMapSet = callBound('WeakMap.prototype.set', true); +var $weakMapHas = callBound('WeakMap.prototype.has', true); +var $mapGet = callBound('Map.prototype.get', true); +var $mapSet = callBound('Map.prototype.set', true); +var $mapHas = callBound('Map.prototype.has', true); + +/* + * This function traverses the list returning the node corresponding to the + * given key. + * + * That node is also moved to the head of the list, so that if it's accessed + * again we don't need to traverse the whole list. By doing so, all the recently + * used nodes can be accessed relatively quickly. + */ +var listGetNode = function (list, key) { // eslint-disable-line consistent-return + for (var prev = list, curr; (curr = prev.next) !== null; prev = curr) { + if (curr.key === key) { + prev.next = curr.next; + curr.next = list.next; + list.next = curr; // eslint-disable-line no-param-reassign + return curr; + } + } +}; - case 3: - resp = _context4.sent; - return _context4.abrupt("return", { - data: normalizeReferences(resp.data), - meta: resp.meta - }); +var listGet = function (objects, key) { + var node = listGetNode(objects, key); + return node && node.value; +}; +var listSet = function (objects, key, value) { + var node = listGetNode(objects, key); + if (node) { + node.value = value; + } else { + // Prepend the new node to the beginning of the list + objects.next = { // eslint-disable-line no-param-reassign + key: key, + next: objects.next, + value: value + }; + } +}; +var listHas = function (objects, key) { + return !!listGetNode(objects, key); +}; - case 5: - case "end": - return _context4.stop(); - } - } - }, _callee4, this); - })); +module.exports = function getSideChannel() { + var $wm; + var $m; + var $o; + var channel = { + assert: function (key) { + if (!channel.has(key)) { + throw new $TypeError('Side channel does not contain ' + inspect(key)); + } + }, + get: function (key) { // eslint-disable-line consistent-return + if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { + if ($wm) { + return $weakMapGet($wm, key); + } + } else if ($Map) { + if ($m) { + return $mapGet($m, key); + } + } else { + if ($o) { // eslint-disable-line no-lonely-if + return listGet($o, key); + } + } + }, + has: function (key) { + if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { + if ($wm) { + return $weakMapHas($wm, key); + } + } else if ($Map) { + if ($m) { + return $mapHas($m, key); + } + } else { + if ($o) { // eslint-disable-line no-lonely-if + return listHas($o, key); + } + } + return false; + }, + set: function (key, value) { + if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { + if (!$wm) { + $wm = new $WeakMap(); + } + $weakMapSet($wm, key, value); + } else if ($Map) { + if (!$m) { + $m = new $Map(); + } + $mapSet($m, key, value); + } else { + if (!$o) { + /* + * Initialize the linked list as an empty node, so that we don't have + * to special-case handling of the first node: we can always refer to + * it as (previous node).next, instead of something like (list).head + */ + $o = { key: {}, next: null }; + } + listSet($o, key, value); + } + } + }; + return channel; +}; - function addReferencedBy(_x5, _x6) { - return _addReferencedBy.apply(this, arguments); - } - return addReferencedBy; - }() - /** - * Remove referenced_by documents from a file — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#delete-filesfile-idrelationshipsreferenced_by - * - * For example, to remove an album reference from a file: - * ``` - * removeReferencedBy({_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}, [{_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}]) - * ``` - * - * @param {object} document A JSON representing the file - * @param {Array} documents An array of JSON documents having a `_type` and `_id` field. - * @returns {{data, meta}} The JSON API conformant response. - */ +/***/ }), +/* 644 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - }, { - key: "removeReferencedBy", - value: function () { - var _removeReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(document, documents) { - var refs, resp; - return _regenerator.default.wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - refs = documents.map(function (d) { - return { - id: d._id, - type: d._type - }; - }); - _context5.next = 3; - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject3(), document._id), { - data: refs - }); +"use strict"; - case 3: - resp = _context5.sent; - return _context5.abrupt("return", { - data: normalizeReferences(resp.data), - meta: resp.meta - }); - case 5: - case "end": - return _context5.stop(); - } - } - }, _callee5, this); - })); +var undefined; - function removeReferencedBy(_x7, _x8) { - return _removeReferencedBy.apply(this, arguments); - } +var $SyntaxError = SyntaxError; +var $Function = Function; +var $TypeError = TypeError; - return removeReferencedBy; - }() - /** - * Add files references to a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#post-datatypedoc-idrelationshipsreferences - * - * For example, to add a photo to an album: - * ``` - * addReferencesTo({_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}, [{_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}]) - * ``` - * - * @param {object} document A JSON representing a document, with at least a `_type` and `_id` field. - * @param {Array} documents An array of JSON files having an `_id` field. - * - * Returns 204 No Content - */ +// eslint-disable-next-line consistent-return +var getEvalledConstructor = function (expressionSyntax) { + try { + return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')(); + } catch (e) {} +}; - }, { - key: "addReferencesTo", - value: function () { - var _addReferencesTo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(document, documents) { - var refs; - return _regenerator.default.wrap(function _callee6$(_context6) { - while (1) { - switch (_context6.prev = _context6.next) { - case 0: - refs = documents.map(function (d) { - return { - id: d._id, - type: 'io.cozy.files' - }; - }); - return _context6.abrupt("return", this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject4(), document._type, document._id), { - data: refs - })); +var $gOPD = Object.getOwnPropertyDescriptor; +if ($gOPD) { + try { + $gOPD({}, ''); + } catch (e) { + $gOPD = null; // this is IE 8, which has a broken gOPD + } +} - case 2: - case "end": - return _context6.stop(); - } - } - }, _callee6, this); - })); +var throwTypeError = function () { + throw new $TypeError(); +}; +var ThrowTypeError = $gOPD + ? (function () { + try { + // eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties + arguments.callee; // IE 8 does not throw here + return throwTypeError; + } catch (calleeThrows) { + try { + // IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '') + return $gOPD(arguments, 'callee').get; + } catch (gOPDthrows) { + return throwTypeError; + } + } + }()) + : throwTypeError; - function addReferencesTo(_x9, _x10) { - return _addReferencesTo.apply(this, arguments); - } +var hasSymbols = __webpack_require__(645)(); - return addReferencesTo; - }() - /** - * Remove files references to a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#delete-datatypedoc-idrelationshipsreferences - * - * For example, to remove a photo from an album: - * ``` - * removeReferencesTo({_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}, [{_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}]) - * ``` - * - * @param {object} document A JSON representing a document, with at least a `_type` and `_id` field. - * @param {Array} documents An array of JSON files having an `_id` field. - * - * Returns 204 No Content - */ +var getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto - }, { - key: "removeReferencesTo", - value: function () { - var _removeReferencesTo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(document, documents) { - var refs; - return _regenerator.default.wrap(function _callee7$(_context7) { - while (1) { - switch (_context7.prev = _context7.next) { - case 0: - refs = documents.map(function (d) { - return { - id: d._id, - type: 'io.cozy.files' - }; - }); - return _context7.abrupt("return", this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject5(), document._type, document._id), { - data: refs - })); +var needsEval = {}; - case 2: - case "end": - return _context7.stop(); - } - } - }, _callee7, this); - })); +var TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array); - function removeReferencesTo(_x11, _x12) { - return _removeReferencesTo.apply(this, arguments); - } +var INTRINSICS = { + '%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError, + '%Array%': Array, + '%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer, + '%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined, + '%AsyncFromSyncIteratorPrototype%': undefined, + '%AsyncFunction%': needsEval, + '%AsyncGenerator%': needsEval, + '%AsyncGeneratorFunction%': needsEval, + '%AsyncIteratorPrototype%': needsEval, + '%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics, + '%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt, + '%Boolean%': Boolean, + '%DataView%': typeof DataView === 'undefined' ? undefined : DataView, + '%Date%': Date, + '%decodeURI%': decodeURI, + '%decodeURIComponent%': decodeURIComponent, + '%encodeURI%': encodeURI, + '%encodeURIComponent%': encodeURIComponent, + '%Error%': Error, + '%eval%': eval, // eslint-disable-line no-eval + '%EvalError%': EvalError, + '%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array, + '%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array, + '%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry, + '%Function%': $Function, + '%GeneratorFunction%': needsEval, + '%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array, + '%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array, + '%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array, + '%isFinite%': isFinite, + '%isNaN%': isNaN, + '%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined, + '%JSON%': typeof JSON === 'object' ? JSON : undefined, + '%Map%': typeof Map === 'undefined' ? undefined : Map, + '%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()), + '%Math%': Math, + '%Number%': Number, + '%Object%': Object, + '%parseFloat%': parseFloat, + '%parseInt%': parseInt, + '%Promise%': typeof Promise === 'undefined' ? undefined : Promise, + '%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy, + '%RangeError%': RangeError, + '%ReferenceError%': ReferenceError, + '%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect, + '%RegExp%': RegExp, + '%Set%': typeof Set === 'undefined' ? undefined : Set, + '%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()), + '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer, + '%String%': String, + '%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined, + '%Symbol%': hasSymbols ? Symbol : undefined, + '%SyntaxError%': $SyntaxError, + '%ThrowTypeError%': ThrowTypeError, + '%TypedArray%': TypedArray, + '%TypeError%': $TypeError, + '%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array, + '%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray, + '%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array, + '%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array, + '%URIError%': URIError, + '%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap, + '%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef, + '%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet +}; - return removeReferencesTo; - }() - /** - * Sends file to trash and removes references to it - * - * @param {FileDocument} file - File that will be sent to trash - * @returns {Promise} - Resolves when references have been removed - * and file has been sent to trash - */ +var doEval = function doEval(name) { + var value; + if (name === '%AsyncFunction%') { + value = getEvalledConstructor('async function () {}'); + } else if (name === '%GeneratorFunction%') { + value = getEvalledConstructor('function* () {}'); + } else if (name === '%AsyncGeneratorFunction%') { + value = getEvalledConstructor('async function* () {}'); + } else if (name === '%AsyncGenerator%') { + var fn = doEval('%AsyncGeneratorFunction%'); + if (fn) { + value = fn.prototype; + } + } else if (name === '%AsyncIteratorPrototype%') { + var gen = doEval('%AsyncGenerator%'); + if (gen) { + value = getProto(gen.prototype); + } + } - }, { - key: "destroy", - value: function () { - var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(file) { - var _ref4, - _ref4$ifMatch, - ifMatch, - _id, - relationships, - _iterator, - _step, - ref, - resp, - _args8 = arguments; + INTRINSICS[name] = value; - return _regenerator.default.wrap(function _callee8$(_context8) { - while (1) { - switch (_context8.prev = _context8.next) { - case 0: - _ref4 = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {}, _ref4$ifMatch = _ref4.ifMatch, ifMatch = _ref4$ifMatch === void 0 ? '' : _ref4$ifMatch; - _id = file._id, relationships = file.relationships; + return value; +}; - if (!(relationships && relationships.referenced_by && Array.isArray(relationships.referenced_by.data))) { - _context8.next = 20; - break; - } +var LEGACY_ALIASES = { + '%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'], + '%ArrayPrototype%': ['Array', 'prototype'], + '%ArrayProto_entries%': ['Array', 'prototype', 'entries'], + '%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'], + '%ArrayProto_keys%': ['Array', 'prototype', 'keys'], + '%ArrayProto_values%': ['Array', 'prototype', 'values'], + '%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'], + '%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'], + '%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'], + '%BooleanPrototype%': ['Boolean', 'prototype'], + '%DataViewPrototype%': ['DataView', 'prototype'], + '%DatePrototype%': ['Date', 'prototype'], + '%ErrorPrototype%': ['Error', 'prototype'], + '%EvalErrorPrototype%': ['EvalError', 'prototype'], + '%Float32ArrayPrototype%': ['Float32Array', 'prototype'], + '%Float64ArrayPrototype%': ['Float64Array', 'prototype'], + '%FunctionPrototype%': ['Function', 'prototype'], + '%Generator%': ['GeneratorFunction', 'prototype'], + '%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'], + '%Int8ArrayPrototype%': ['Int8Array', 'prototype'], + '%Int16ArrayPrototype%': ['Int16Array', 'prototype'], + '%Int32ArrayPrototype%': ['Int32Array', 'prototype'], + '%JSONParse%': ['JSON', 'parse'], + '%JSONStringify%': ['JSON', 'stringify'], + '%MapPrototype%': ['Map', 'prototype'], + '%NumberPrototype%': ['Number', 'prototype'], + '%ObjectPrototype%': ['Object', 'prototype'], + '%ObjProto_toString%': ['Object', 'prototype', 'toString'], + '%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'], + '%PromisePrototype%': ['Promise', 'prototype'], + '%PromiseProto_then%': ['Promise', 'prototype', 'then'], + '%Promise_all%': ['Promise', 'all'], + '%Promise_reject%': ['Promise', 'reject'], + '%Promise_resolve%': ['Promise', 'resolve'], + '%RangeErrorPrototype%': ['RangeError', 'prototype'], + '%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'], + '%RegExpPrototype%': ['RegExp', 'prototype'], + '%SetPrototype%': ['Set', 'prototype'], + '%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'], + '%StringPrototype%': ['String', 'prototype'], + '%SymbolPrototype%': ['Symbol', 'prototype'], + '%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'], + '%TypedArrayPrototype%': ['TypedArray', 'prototype'], + '%TypeErrorPrototype%': ['TypeError', 'prototype'], + '%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'], + '%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'], + '%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'], + '%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'], + '%URIErrorPrototype%': ['URIError', 'prototype'], + '%WeakMapPrototype%': ['WeakMap', 'prototype'], + '%WeakSetPrototype%': ['WeakSet', 'prototype'] +}; - _iterator = _createForOfIteratorHelper(relationships.referenced_by.data); - _context8.prev = 4; +var bind = __webpack_require__(647); +var hasOwn = __webpack_require__(649); +var $concat = bind.call(Function.call, Array.prototype.concat); +var $spliceApply = bind.call(Function.apply, Array.prototype.splice); +var $replace = bind.call(Function.call, String.prototype.replace); +var $strSlice = bind.call(Function.call, String.prototype.slice); - _iterator.s(); +/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */ +var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g; +var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */ +var stringToPath = function stringToPath(string) { + var first = $strSlice(string, 0, 1); + var last = $strSlice(string, -1); + if (first === '%' && last !== '%') { + throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`'); + } else if (last === '%' && first !== '%') { + throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`'); + } + var result = []; + $replace(string, rePropName, function (match, number, quote, subString) { + result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match; + }); + return result; +}; +/* end adaptation */ - case 6: - if ((_step = _iterator.n()).done) { - _context8.next = 12; - break; - } +var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) { + var intrinsicName = name; + var alias; + if (hasOwn(LEGACY_ALIASES, intrinsicName)) { + alias = LEGACY_ALIASES[intrinsicName]; + intrinsicName = '%' + alias[0] + '%'; + } - ref = _step.value; - _context8.next = 10; - return this.removeReferencesTo({ - _id: ref.id, - _type: ref.type - }, [{ - _id: _id - }]); + if (hasOwn(INTRINSICS, intrinsicName)) { + var value = INTRINSICS[intrinsicName]; + if (value === needsEval) { + value = doEval(intrinsicName); + } + if (typeof value === 'undefined' && !allowMissing) { + throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!'); + } - case 10: - _context8.next = 6; - break; + return { + alias: alias, + name: intrinsicName, + value: value + }; + } - case 12: - _context8.next = 17; - break; + throw new $SyntaxError('intrinsic ' + name + ' does not exist!'); +}; - case 14: - _context8.prev = 14; - _context8.t0 = _context8["catch"](4); +module.exports = function GetIntrinsic(name, allowMissing) { + if (typeof name !== 'string' || name.length === 0) { + throw new $TypeError('intrinsic name must be a non-empty string'); + } + if (arguments.length > 1 && typeof allowMissing !== 'boolean') { + throw new $TypeError('"allowMissing" argument must be a boolean'); + } - _iterator.e(_context8.t0); + var parts = stringToPath(name); + var intrinsicBaseName = parts.length > 0 ? parts[0] : ''; - case 17: - _context8.prev = 17; + var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing); + var intrinsicRealName = intrinsic.name; + var value = intrinsic.value; + var skipFurtherCaching = false; - _iterator.f(); + var alias = intrinsic.alias; + if (alias) { + intrinsicBaseName = alias[0]; + $spliceApply(parts, $concat([0, 1], alias)); + } - return _context8.finish(17); + for (var i = 1, isOwn = true; i < parts.length; i += 1) { + var part = parts[i]; + var first = $strSlice(part, 0, 1); + var last = $strSlice(part, -1); + if ( + ( + (first === '"' || first === "'" || first === '`') + || (last === '"' || last === "'" || last === '`') + ) + && first !== last + ) { + throw new $SyntaxError('property names with quotes must have matching quotes'); + } + if (part === 'constructor' || !isOwn) { + skipFurtherCaching = true; + } - case 20: - _context8.next = 22; - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), _id), undefined, { - headers: { - 'If-Match': ifMatch - } - }); + intrinsicBaseName += '.' + part; + intrinsicRealName = '%' + intrinsicBaseName + '%'; - case 22: - resp = _context8.sent; - return _context8.abrupt("return", { - data: normalizeFile(resp.data) - }); + if (hasOwn(INTRINSICS, intrinsicRealName)) { + value = INTRINSICS[intrinsicRealName]; + } else if (value != null) { + if (!(part in value)) { + if (!allowMissing) { + throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.'); + } + return void undefined; + } + if ($gOPD && (i + 1) >= parts.length) { + var desc = $gOPD(value, part); + isOwn = !!desc; - case 24: - case "end": - return _context8.stop(); - } - } - }, _callee8, this, [[4, 14, 17, 20]]); - })); + // By convention, when a data property is converted to an accessor + // property to emulate a data property that does not suffer from + // the override mistake, that accessor's getter is marked with + // an `originalValue` property. Here, when we detect this, we + // uphold the illusion by pretending to see that original data + // property, i.e., returning the value rather than the getter + // itself. + if (isOwn && 'get' in desc && !('originalValue' in desc.get)) { + value = desc.get; + } else { + value = value[part]; + } + } else { + isOwn = hasOwn(value, part); + value = value[part]; + } - function destroy(_x13) { - return _destroy.apply(this, arguments); - } + if (isOwn && !skipFurtherCaching) { + INTRINSICS[intrinsicRealName] = value; + } + } + } + return value; +}; - return destroy; - }() - /** - * Empty the Trash - */ - }, { - key: "emptyTrash", - value: function emptyTrash() { - return this.stackClient.fetchJSON('DELETE', '/files/trash'); - } - /** - * Restores a trashed file. - * - * @param {string} id - The file's id - * @returns {Promise} - A promise that returns the restored file if resolved. - * @throws {FetchError} - * - */ +/***/ }), +/* 645 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - }, { - key: "restore", - value: function restore(id) { - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject7(), id)); - } - /** - * async deleteFilePermanently - Definitely delete a file - * - * @param {string} id - The id of the file to delete - * @returns {object} The deleted file object - */ +"use strict"; - }, { - key: "deleteFilePermanently", - value: function () { - var _deleteFilePermanently = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(id) { - var resp; - return _regenerator.default.wrap(function _callee9$(_context9) { - while (1) { - switch (_context9.prev = _context9.next) { - case 0: - _context9.next = 2; - return this.stackClient.fetchJSON('PATCH', (0, _utils.uri)(_templateObject8(), id), { - data: { - type: 'io.cozy.files', - id: id, - attributes: { - permanent_delete: true - } - } - }); - case 2: - resp = _context9.sent; - return _context9.abrupt("return", resp.data); +var origSymbol = typeof Symbol !== 'undefined' && Symbol; +var hasSymbolSham = __webpack_require__(646); - case 4: - case "end": - return _context9.stop(); - } - } - }, _callee9, this); - })); +module.exports = function hasNativeSymbols() { + if (typeof origSymbol !== 'function') { return false; } + if (typeof Symbol !== 'function') { return false; } + if (typeof origSymbol('foo') !== 'symbol') { return false; } + if (typeof Symbol('bar') !== 'symbol') { return false; } - function deleteFilePermanently(_x14) { - return _deleteFilePermanently.apply(this, arguments); - } + return hasSymbolSham(); +}; - return deleteFilePermanently; - }() - /** - * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded - * @param {string} dirPath Path to upload the file to. ie : /Administative/XXX/ - * @returns {object} Created io.cozy.files - */ - }, { - key: "upload", - value: function () { - var _upload = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(data, dirPath) { - var dirId; - return _regenerator.default.wrap(function _callee10$(_context10) { - while (1) { - switch (_context10.prev = _context10.next) { - case 0: - _context10.next = 2; - return this.ensureDirectoryExists(dirPath); +/***/ }), +/* 646 */ +/***/ ((module) => { - case 2: - dirId = _context10.sent; - return _context10.abrupt("return", this.createFile(data, { - dirId: dirId - })); +"use strict"; - case 4: - case "end": - return _context10.stop(); - } - } - }, _callee10, this); - })); - function upload(_x15, _x16) { - return _upload.apply(this, arguments); - } +/* eslint complexity: [2, 18], max-statements: [2, 33] */ +module.exports = function hasSymbols() { + if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; } + if (typeof Symbol.iterator === 'symbol') { return true; } - return upload; - }() - /** - * Creates directory or file. - * - Used by StackLink to support CozyClient.create('io.cozy.files', options) - * - * @param {FileAttributes|DirectoryAttributes} attributes - Attributes of the created file/directory - * @param {File|Blob|string|ArrayBuffer} attributes.data Will be used as content of the created file - * @throws {Error} - explaining reason why creation failed - */ + var obj = {}; + var sym = Symbol('test'); + var symObj = Object(sym); + if (typeof sym === 'string') { return false; } - }, { - key: "create", - value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(attributes) { - var data, createFileOptions; - return _regenerator.default.wrap(function _callee11$(_context11) { - while (1) { - switch (_context11.prev = _context11.next) { - case 0: - if (!(attributes.type === 'directory')) { - _context11.next = 4; - break; - } + if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; } + if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; } - return _context11.abrupt("return", this.createDirectory(attributes)); + // temp disabled per https://github.com/ljharb/object.assign/issues/17 + // if (sym instanceof Symbol) { return false; } + // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4 + // if (!(symObj instanceof Symbol)) { return false; } - case 4: - data = attributes.data, createFileOptions = (0, _objectWithoutProperties2.default)(attributes, ["data"]); - return _context11.abrupt("return", this.createFile(data, createFileOptions)); + // if (typeof Symbol.prototype.toString !== 'function') { return false; } + // if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; } - case 6: - case "end": - return _context11.stop(); - } - } - }, _callee11, this); - })); + var symVal = 42; + obj[sym] = symVal; + for (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop + if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; } - function create(_x17) { - return _create.apply(this, arguments); - } + if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; } - return create; - }() - /*** - * Update the io.cozy.files - * Used by StackLink to support CozyClient.save({file}) - * @param {FileAttributes} file - The file with its new content - * @returns {FileAttributes} Updated document - * @throws {Error} - explaining reason why update failed - */ + var syms = Object.getOwnPropertySymbols(obj); + if (syms.length !== 1 || syms[0] !== sym) { return false; } - }, { - key: "update", - value: function () { - var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(file) { - return _regenerator.default.wrap(function _callee12$(_context12) { - while (1) { - switch (_context12.prev = _context12.next) { - case 0: - return _context12.abrupt("return", this.updateAttributes(file.id, file)); + if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; } - case 1: - case "end": - return _context12.stop(); - } - } - }, _callee12, this); - })); + if (typeof Object.getOwnPropertyDescriptor === 'function') { + var descriptor = Object.getOwnPropertyDescriptor(obj, sym); + if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; } + } - function update(_x18) { - return _update.apply(this, arguments); - } + return true; +}; - return update; - }() - /** - * Creates a file - * - * @private - * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded - * @param {FileAttributes} params Additional parameters - * @param {object} params.options Options to pass to doUpload method (additional headers) - * @throws {Error} - explaining reason why creation failed - */ - }, { - key: "createFile", - value: function () { - var _createFile = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(data) { - var _ref5, - nameOption, - _ref5$dirId, - dirId, - executableOption, - metadata, - options, - name, - executable, - metadataId, - meta, - size, - path, - _args13 = arguments; +/***/ }), +/* 647 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return _regenerator.default.wrap(function _callee13$(_context13) { - while (1) { - switch (_context13.prev = _context13.next) { - case 0: - _ref5 = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : {}; - nameOption = _ref5.name, _ref5$dirId = _ref5.dirId, dirId = _ref5$dirId === void 0 ? '' : _ref5$dirId, executableOption = _ref5.executable, metadata = _ref5.metadata, options = (0, _objectWithoutProperties2.default)(_ref5, ["name", "dirId", "executable", "metadata"]); - name = nameOption; - executable = executableOption; // handle case where data is a file and contains the name +"use strict"; - if (!name && typeof data.name === 'string') { - name = data.name; - } - name = sanitizeAndValidateFileName(name); +var implementation = __webpack_require__(648); - if (executable === undefined) { - executable = false; - } +module.exports = Function.prototype.bind || implementation; - metadataId = ''; - if (!metadata) { - _context13.next = 13; - break; - } +/***/ }), +/* 648 */ +/***/ ((module) => { - _context13.next = 11; - return this.createFileMetadata(metadata); +"use strict"; - case 11: - meta = _context13.sent; - metadataId = meta.data.id; - case 13: - size = ''; +/* eslint no-invalid-this: 1 */ - if (options.contentLength) { - size = String(options.contentLength); - } +var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; +var slice = Array.prototype.slice; +var toStr = Object.prototype.toString; +var funcType = '[object Function]'; - path = (0, _utils.uri)(_templateObject9(), dirId, name, executable, metadataId, size); - return _context13.abrupt("return", this.doUpload(data, path, options)); +module.exports = function bind(that) { + var target = this; + if (typeof target !== 'function' || toStr.call(target) !== funcType) { + throw new TypeError(ERROR_MESSAGE + target); + } + var args = slice.call(arguments, 1); - case 17: - case "end": - return _context13.stop(); + var bound; + var binder = function () { + if (this instanceof bound) { + var result = target.apply( + this, + args.concat(slice.call(arguments)) + ); + if (Object(result) === result) { + return result; } - } - }, _callee13, this); - })); - - function createFile(_x19) { - return _createFile.apply(this, arguments); - } + return this; + } else { + return target.apply( + that, + args.concat(slice.call(arguments)) + ); + } + }; - return createFile; - }() - /** - * updateFile - Updates a file's data - * - * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded - * @param {FileAttributes} params Additional parameters - * @param {object} params.options Options to pass to doUpload method (additional headers) - * @returns {object} Updated document - * @throws {Error} - explaining reason why update failed - */ + var boundLength = Math.max(0, target.length - args.length); + var boundArgs = []; + for (var i = 0; i < boundLength; i++) { + boundArgs.push('$' + i); + } - }, { - key: "updateFile", - value: function () { - var _updateFile = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(data) { - var _ref6, - _ref6$executable, - executable, - fileId, - _ref6$name, - name, - metadata, - options, - fileName, - sanitizedName, - metadataId, - path, - meta, - size, - _args14 = arguments; + bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder); - return _regenerator.default.wrap(function _callee14$(_context14) { - while (1) { - switch (_context14.prev = _context14.next) { - case 0: - _ref6 = _args14.length > 1 && _args14[1] !== undefined ? _args14[1] : {}; - _ref6$executable = _ref6.executable, executable = _ref6$executable === void 0 ? false : _ref6$executable, fileId = _ref6.fileId, _ref6$name = _ref6.name, name = _ref6$name === void 0 ? '' : _ref6$name, metadata = _ref6.metadata, options = (0, _objectWithoutProperties2.default)(_ref6, ["executable", "fileId", "name", "metadata"]); + if (target.prototype) { + var Empty = function Empty() {}; + Empty.prototype = target.prototype; + bound.prototype = new Empty(); + Empty.prototype = null; + } - if (!(!fileId || typeof fileId !== 'string')) { - _context14.next = 4; - break; - } + return bound; +}; - throw new Error('missing fileId argument'); - case 4: - // name might be set in a File object - fileName = name || data.name; +/***/ }), +/* 649 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!(!fileName || typeof fileName !== 'string')) { - _context14.next = 7; - break; - } +"use strict"; - throw new Error('missing name in data argument'); - case 7: - sanitizedName = sanitizeAndValidateFileName(fileName); - /** - * We already use the body to send the content of the file. So we have 2 choices : - * Use an object in a query string to send the metadata - * create a new header http - * In both case, we have a size limitation depending of the browser. - * - * So we had this current workaround where we create the metadata before - * (no size limit since we can use the body for that) and after we use the ID. - */ +var bind = __webpack_require__(647); - path = (0, _utils.uri)(_templateObject10(), fileId, sanitizedName, executable); +module.exports = bind.call(Function.call, Object.prototype.hasOwnProperty); - if (!metadata) { - _context14.next = 15; - break; - } - _context14.next = 12; - return this.createFileMetadata(metadata); +/***/ }), +/* 650 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case 12: - meta = _context14.sent; - metadataId = meta.data.id; - path = path + "&MetadataID=".concat(metadataId); +"use strict"; - case 15: - size = ''; - if (options.contentLength) { - size = String(options.contentLength); - path = path + "&Size=".concat(size); - } +var GetIntrinsic = __webpack_require__(644); - return _context14.abrupt("return", this.doUpload(data, path, options, 'PUT')); +var callBind = __webpack_require__(651); - case 18: - case "end": - return _context14.stop(); - } - } - }, _callee14, this); - })); +var $indexOf = callBind(GetIntrinsic('String.prototype.indexOf')); - function updateFile(_x20) { - return _updateFile.apply(this, arguments); - } +module.exports = function callBoundIntrinsic(name, allowMissing) { + var intrinsic = GetIntrinsic(name, !!allowMissing); + if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) { + return callBind(intrinsic); + } + return intrinsic; +}; - return updateFile; - }() - }, { - key: "getDownloadLinkById", - value: function getDownloadLinkById(id, filename) { - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject11(), id, filename)).then(this.extractResponseLinkRelated); - } - }, { - key: "getDownloadLinkByRevision", - value: function getDownloadLinkByRevision(versionId, filename) { - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject12(), versionId, filename)).then(this.extractResponseLinkRelated); - } - }, { - key: "getDownloadLinkByPath", - value: function getDownloadLinkByPath(path) { - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject13(), path)).then(this.extractResponseLinkRelated); - } - }, { - key: "download", - /** - * Download a file or a specific version of the file - * - * @param {object} file io.cozy.files object - * @param {string} versionId Id of the io.cozy.files.version - * @param {string} filename The name you want for the downloaded file - * (by default the same as the file) - */ - value: function () { - var _download = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(file) { - var versionId, - filename, - href, - filenameToUse, - _args15 = arguments; - return _regenerator.default.wrap(function _callee15$(_context15) { - while (1) { - switch (_context15.prev = _context15.next) { - case 0: - versionId = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : null; - filename = _args15.length > 2 && _args15[2] !== undefined ? _args15[2] : undefined; - filenameToUse = filename ? filename : file.name; - /** - * Passing a filename to forceFileDownload is not enough - * for a few browsers since the stack's response header will - * not contain that name. Passing the filename to - * getDownloadLinkBy{Id,Revision} will ask the stack to - * return this filename in its content-disposition - * header response - */ +/***/ }), +/* 651 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (versionId) { - _context15.next = 9; - break; - } +"use strict"; - _context15.next = 6; - return this.getDownloadLinkById(file._id, filenameToUse); - case 6: - href = _context15.sent; - _context15.next = 12; - break; +var bind = __webpack_require__(647); +var GetIntrinsic = __webpack_require__(644); - case 9: - _context15.next = 11; - return this.getDownloadLinkByRevision(versionId, filenameToUse); +var $apply = GetIntrinsic('%Function.prototype.apply%'); +var $call = GetIntrinsic('%Function.prototype.call%'); +var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply); - case 11: - href = _context15.sent; +var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true); +var $defineProperty = GetIntrinsic('%Object.defineProperty%', true); +var $max = GetIntrinsic('%Math.max%'); - case 12: - this.forceFileDownload("".concat(href, "?Dl=1"), filenameToUse); +if ($defineProperty) { + try { + $defineProperty({}, 'a', { value: 1 }); + } catch (e) { + // IE 8 has a broken defineProperty + $defineProperty = null; + } +} - case 13: - case "end": - return _context15.stop(); - } - } - }, _callee15, this); - })); +module.exports = function callBind(originalFunction) { + var func = $reflectApply(bind, $call, arguments); + if ($gOPD && $defineProperty) { + var desc = $gOPD(func, 'length'); + if (desc.configurable) { + // original length, plus the receiver, minus any additional arguments (after the receiver) + $defineProperty( + func, + 'length', + { value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) } + ); + } + } + return func; +}; - function download(_x21) { - return _download.apply(this, arguments); - } +var applyBind = function applyBind() { + return $reflectApply(bind, $apply, arguments); +}; - return download; - }() - }, { - key: "fetchFileContent", - value: function () { - var _fetchFileContent = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16(id) { - return _regenerator.default.wrap(function _callee16$(_context16) { - while (1) { - switch (_context16.prev = _context16.next) { - case 0: - console.warn('FileCollection.fetchFileContent() is deprecated. Use FileCollection.fetchFileContentById() instead'); - return _context16.abrupt("return", this.fetchFileContentById(id)); +if ($defineProperty) { + $defineProperty(module.exports, 'apply', { value: applyBind }); +} else { + module.exports.apply = applyBind; +} - case 2: - case "end": - return _context16.stop(); - } - } - }, _callee16, this); - })); - function fetchFileContent(_x22) { - return _fetchFileContent.apply(this, arguments); - } +/***/ }), +/* 652 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return fetchFileContent; - }() - /** - * Fetch the binary of a file or a specific version of a file - * Useful for instance when you can't download the file directly - * (via a content-disposition attachement header) and need to store - * it before doing an operation. - * - * @param {string} id Id of the io.cozy.files or io.cozy.files.version - * - */ +var hasMap = typeof Map === 'function' && Map.prototype; +var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null; +var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null; +var mapForEach = hasMap && Map.prototype.forEach; +var hasSet = typeof Set === 'function' && Set.prototype; +var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null; +var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null; +var setForEach = hasSet && Set.prototype.forEach; +var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype; +var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null; +var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype; +var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null; +var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype; +var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null; +var booleanValueOf = Boolean.prototype.valueOf; +var objectToString = Object.prototype.toString; +var functionToString = Function.prototype.toString; +var match = String.prototype.match; +var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null; +var gOPS = Object.getOwnPropertySymbols; +var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null; +var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object'; +var isEnumerable = Object.prototype.propertyIsEnumerable; - }, { - key: "fetchFileContentById", - value: function () { - var _fetchFileContentById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(id) { - return _regenerator.default.wrap(function _callee17$(_context17) { - while (1) { - switch (_context17.prev = _context17.next) { - case 0: - return _context17.abrupt("return", this.stackClient.fetch('GET', "/files/download/".concat(id))); +var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || ( + [].__proto__ === Array.prototype // eslint-disable-line no-proto + ? function (O) { + return O.__proto__; // eslint-disable-line no-proto + } + : null +); - case 1: - case "end": - return _context17.stop(); - } - } - }, _callee17, this); - })); +var inspectCustom = (__webpack_require__(653).custom); +var inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null; +var toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null; - function fetchFileContentById(_x23) { - return _fetchFileContentById.apply(this, arguments); - } +module.exports = function inspect_(obj, options, depth, seen) { + var opts = options || {}; - return fetchFileContentById; - }() - /** - * Get a beautified size for a given file - * 1024B => 1KB - * 102404500404B => 95.37 GB - * - * @param {object} file io.cozy.files object - * @param {number} decimal number of decimal - */ + if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) { + throw new TypeError('option "quoteStyle" must be "single" or "double"'); + } + if ( + has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number' + ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity + : opts.maxStringLength !== null + ) + ) { + throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`'); + } + var customInspect = has(opts, 'customInspect') ? opts.customInspect : true; + if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') { + throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`'); + } - }, { - key: "getBeautifulSize", - value: function getBeautifulSize(file, decimal) { - return (0, _utils.formatBytes)(parseInt(file.size), decimal); + if ( + has(opts, 'indent') + && opts.indent !== null + && opts.indent !== '\t' + && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0) + ) { + throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`'); } - }, { - key: "downloadArchive", - value: function () { - var _downloadArchive = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(fileIds) { - var notSecureFilename, - filename, - href, - fullpath, - _args18 = arguments; - return _regenerator.default.wrap(function _callee18$(_context18) { - while (1) { - switch (_context18.prev = _context18.next) { - case 0: - notSecureFilename = _args18.length > 1 && _args18[1] !== undefined ? _args18[1] : 'files'; - filename = (0, _utils.slugify)(notSecureFilename); - _context18.next = 4; - return this.getArchiveLinkByIds(fileIds, filename); - case 4: - href = _context18.sent; - fullpath = this.stackClient.fullpath(href); - this.forceFileDownload(fullpath, filename + '.zip'); + if (typeof obj === 'undefined') { + return 'undefined'; + } + if (obj === null) { + return 'null'; + } + if (typeof obj === 'boolean') { + return obj ? 'true' : 'false'; + } - case 7: - case "end": - return _context18.stop(); - } - } - }, _callee18, this); - })); + if (typeof obj === 'string') { + return inspectString(obj, opts); + } + if (typeof obj === 'number') { + if (obj === 0) { + return Infinity / obj > 0 ? '0' : '-0'; + } + return String(obj); + } + if (typeof obj === 'bigint') { + return String(obj) + 'n'; + } - function downloadArchive(_x24) { - return _downloadArchive.apply(this, arguments); - } + var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth; + if (typeof depth === 'undefined') { depth = 0; } + if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') { + return isArray(obj) ? '[Array]' : '[Object]'; + } - return downloadArchive; - }() - }, { - key: "getArchiveLinkByIds", - value: function () { - var _getArchiveLinkByIds = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(ids) { - var name, - resp, - _args19 = arguments; - return _regenerator.default.wrap(function _callee19$(_context19) { - while (1) { - switch (_context19.prev = _context19.next) { - case 0: - name = _args19.length > 1 && _args19[1] !== undefined ? _args19[1] : 'files'; - _context19.next = 3; - return this.stackClient.fetchJSON('POST', '/files/archive', { - data: { - type: 'io.cozy.archives', - attributes: { - name: name, - ids: ids - } - } - }); + var indent = getIndent(opts, depth); - case 3: - resp = _context19.sent; - return _context19.abrupt("return", resp.links.related); + if (typeof seen === 'undefined') { + seen = []; + } else if (indexOf(seen, obj) >= 0) { + return '[Circular]'; + } - case 5: - case "end": - return _context19.stop(); + function inspect(value, from, noIndent) { + if (from) { + seen = seen.slice(); + seen.push(from); + } + if (noIndent) { + var newOpts = { + depth: opts.depth + }; + if (has(opts, 'quoteStyle')) { + newOpts.quoteStyle = opts.quoteStyle; } - } - }, _callee19, this); - })); + return inspect_(value, newOpts, depth + 1, seen); + } + return inspect_(value, opts, depth + 1, seen); + } - function getArchiveLinkByIds(_x25) { - return _getArchiveLinkByIds.apply(this, arguments); - } + if (typeof obj === 'function') { + var name = nameOf(obj); + var keys = arrObjKeys(obj, inspect); + return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : ''); + } + if (isSymbol(obj)) { + var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj); + return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString; + } + if (isElement(obj)) { + var s = '<' + String(obj.nodeName).toLowerCase(); + var attrs = obj.attributes || []; + for (var i = 0; i < attrs.length; i++) { + s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts); + } + s += '>'; + if (obj.childNodes && obj.childNodes.length) { s += '...'; } + s += '</' + String(obj.nodeName).toLowerCase() + '>'; + return s; + } + if (isArray(obj)) { + if (obj.length === 0) { return '[]'; } + var xs = arrObjKeys(obj, inspect); + if (indent && !singleLineValues(xs)) { + return '[' + indentedJoin(xs, indent) + ']'; + } + return '[ ' + xs.join(', ') + ' ]'; + } + if (isError(obj)) { + var parts = arrObjKeys(obj, inspect); + if (parts.length === 0) { return '[' + String(obj) + ']'; } + return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }'; + } + if (typeof obj === 'object' && customInspect) { + if (inspectSymbol && typeof obj[inspectSymbol] === 'function') { + return obj[inspectSymbol](); + } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') { + return obj.inspect(); + } + } + if (isMap(obj)) { + var mapParts = []; + mapForEach.call(obj, function (value, key) { + mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj)); + }); + return collectionOf('Map', mapSize.call(obj), mapParts, indent); + } + if (isSet(obj)) { + var setParts = []; + setForEach.call(obj, function (value) { + setParts.push(inspect(value, obj)); + }); + return collectionOf('Set', setSize.call(obj), setParts, indent); + } + if (isWeakMap(obj)) { + return weakCollectionOf('WeakMap'); + } + if (isWeakSet(obj)) { + return weakCollectionOf('WeakSet'); + } + if (isWeakRef(obj)) { + return weakCollectionOf('WeakRef'); + } + if (isNumber(obj)) { + return markBoxed(inspect(Number(obj))); + } + if (isBigInt(obj)) { + return markBoxed(inspect(bigIntValueOf.call(obj))); + } + if (isBoolean(obj)) { + return markBoxed(booleanValueOf.call(obj)); + } + if (isString(obj)) { + return markBoxed(inspect(String(obj))); + } + if (!isDate(obj) && !isRegExp(obj)) { + var ys = arrObjKeys(obj, inspect); + var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object; + var protoTag = obj instanceof Object ? '' : 'null prototype'; + var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : ''; + var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : ''; + var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : ''); + if (ys.length === 0) { return tag + '{}'; } + if (indent) { + return tag + '{' + indentedJoin(ys, indent) + '}'; + } + return tag + '{ ' + ys.join(', ') + ' }'; + } + return String(obj); +}; - return getArchiveLinkByIds; - }() - /** - * Checks if the file belongs to the parent's hierarchy. - * - * @param {string|object} child The file which can either be an id or an object - * @param {string|object} parent The parent target which can either be an id or an object - * @returns {boolean} Whether the file is a parent's child - */ +function wrapQuotes(s, defaultStyle, opts) { + var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '"' : "'"; + return quoteChar + s + quoteChar; +} - }, { - key: "isChildOf", - value: function () { - var _isChildOf = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20(child, parent) { - var _this2 = this; +function quote(s) { + return String(s).replace(/"/g, '"'); +} - var _ref7, childID, childDirID, childPath, _ref8, parentID, childDoc, currPath, targetsPath, newPath; +function isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } +function isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } +function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } +function isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } +function isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } +function isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } +function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } - return _regenerator.default.wrap(function _callee20$(_context20) { - while (1) { - switch (_context20.prev = _context20.next) { - case 0: - _ref7 = typeof child === 'object' ? child : { - _id: child - }, childID = _ref7._id, childDirID = _ref7.dirID, childPath = _ref7.path; - _ref8 = typeof parent === 'object' ? parent : { - _id: parent - }, parentID = _ref8._id; +// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives +function isSymbol(obj) { + if (hasShammedSymbols) { + return obj && typeof obj === 'object' && obj instanceof Symbol; + } + if (typeof obj === 'symbol') { + return true; + } + if (!obj || typeof obj !== 'object' || !symToString) { + return false; + } + try { + symToString.call(obj); + return true; + } catch (e) {} + return false; +} - if (!(childID === parentID || childDirID === parentID)) { - _context20.next = 4; - break; - } +function isBigInt(obj) { + if (!obj || typeof obj !== 'object' || !bigIntValueOf) { + return false; + } + try { + bigIntValueOf.call(obj); + return true; + } catch (e) {} + return false; +} - return _context20.abrupt("return", true); +var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; }; +function has(obj, key) { + return hasOwn.call(obj, key); +} - case 4: - if (childPath) { - _context20.next = 10; - break; - } +function toStr(obj) { + return objectToString.call(obj); +} - _context20.next = 7; - return this.statById(childID); +function nameOf(f) { + if (f.name) { return f.name; } + var m = match.call(functionToString.call(f), /^function\s*([\w$]+)/); + if (m) { return m[1]; } + return null; +} - case 7: - childDoc = _context20.sent; - childPath = childDoc.data.path; - childDirID = childDoc.data.dirID; +function indexOf(xs, x) { + if (xs.indexOf) { return xs.indexOf(x); } + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) { return i; } + } + return -1; +} - case 10: - // Build hierarchy paths - currPath = childPath; - targetsPath = [childPath]; +function isMap(x) { + if (!mapSize || !x || typeof x !== 'object') { + return false; + } + try { + mapSize.call(x); + try { + setSize.call(x); + } catch (s) { + return true; + } + return x instanceof Map; // core-js workaround, pre-v2.5.0 + } catch (e) {} + return false; +} - while (currPath != '') { - newPath = dirName(currPath); +function isWeakMap(x) { + if (!weakMapHas || !x || typeof x !== 'object') { + return false; + } + try { + weakMapHas.call(x, weakMapHas); + try { + weakSetHas.call(x, weakSetHas); + } catch (s) { + return true; + } + return x instanceof WeakMap; // core-js workaround, pre-v2.5.0 + } catch (e) {} + return false; +} - if (newPath != '') { - targetsPath.push(newPath); - } +function isWeakRef(x) { + if (!weakRefDeref || !x || typeof x !== 'object') { + return false; + } + try { + weakRefDeref.call(x); + return true; + } catch (e) {} + return false; +} - currPath = newPath; - } +function isSet(x) { + if (!setSize || !x || typeof x !== 'object') { + return false; + } + try { + setSize.call(x); + try { + mapSize.call(x); + } catch (m) { + return true; + } + return x instanceof Set; // core-js workaround, pre-v2.5.0 + } catch (e) {} + return false; +} - targetsPath.reverse(); // Look for all hierarchy in parallel and return true as soon as a dir is the searched parent +function isWeakSet(x) { + if (!weakSetHas || !x || typeof x !== 'object') { + return false; + } + try { + weakSetHas.call(x, weakSetHas); + try { + weakMapHas.call(x, weakMapHas); + } catch (s) { + return true; + } + return x instanceof WeakSet; // core-js workaround, pre-v2.5.0 + } catch (e) {} + return false; +} - return _context20.abrupt("return", raceWithCondition(targetsPath.map(function (path) { - return _this2.statByPath(path); - }), function (stat) { - return stat.data._id == parentID; - })); +function isElement(x) { + if (!x || typeof x !== 'object') { return false; } + if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) { + return true; + } + return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function'; +} - case 15: - case "end": - return _context20.stop(); - } - } - }, _callee20, this); - })); +function inspectString(str, opts) { + if (str.length > opts.maxStringLength) { + var remaining = str.length - opts.maxStringLength; + var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : ''); + return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer; + } + // eslint-disable-next-line no-control-regex + var s = str.replace(/(['\\])/g, '\\$1').replace(/[\x00-\x1f]/g, lowbyte); + return wrapQuotes(s, 'single', opts); +} - function isChildOf(_x26, _x27) { - return _isChildOf.apply(this, arguments); - } +function lowbyte(c) { + var n = c.charCodeAt(0); + var x = { + 8: 'b', + 9: 't', + 10: 'n', + 12: 'f', + 13: 'r' + }[n]; + if (x) { return '\\' + x; } + return '\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase(); +} - return isChildOf; - }() - /** - * statById - Fetches the metadata about a document. For folders, the results include the list of child files and folders. - * - * @param {string} id ID of the document - * @param {object|null} options Pagination options - * @param {number|null} [options.page[limit]] For pagination, the number of results to return. - * @param {number|null} [options.page[skip]] For skip-based pagination, the number of referenced files to skip. - * @param {CouchDBViewCursor|null} [options.page[cursor]] For cursor-based pagination, the index cursor. - * - * @returns {object} A promise resolving to an object containing "data" (the document metadata), "included" (the child documents) and "links" (pagination informations) - */ +function markBoxed(str) { + return 'Object(' + str + ')'; +} - }, { - key: "statById", - value: function () { - var _statById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21(id) { - var options, - params, - path, - url, - resp, - _args21 = arguments; - return _regenerator.default.wrap(function _callee21$(_context21) { - while (1) { - switch (_context21.prev = _context21.next) { - case 0: - options = _args21.length > 1 && _args21[1] !== undefined ? _args21[1] : {}; - params = (0, _pick.default)(options, ['page[limit]', 'page[skip]', 'page[cursor]']); - path = (0, _utils.uri)(_templateObject14(), id); - url = querystring.buildURL(path, params); - _context21.next = 6; - return this.stackClient.fetchJSON('GET', url); +function weakCollectionOf(type) { + return type + ' { ? }'; +} - case 6: - resp = _context21.sent; - return _context21.abrupt("return", { - data: normalizeFile(resp.data), - included: resp.included && resp.included.map(function (f) { - return normalizeFile(f); - }), - links: resp.links - }); +function collectionOf(type, size, entries, indent) { + var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', '); + return type + ' (' + size + ') {' + joinedEntries + '}'; +} - case 8: - case "end": - return _context21.stop(); - } - } - }, _callee21, this); - })); +function singleLineValues(xs) { + for (var i = 0; i < xs.length; i++) { + if (indexOf(xs[i], '\n') >= 0) { + return false; + } + } + return true; +} - function statById(_x28) { - return _statById.apply(this, arguments); - } +function getIndent(opts, depth) { + var baseIndent; + if (opts.indent === '\t') { + baseIndent = '\t'; + } else if (typeof opts.indent === 'number' && opts.indent > 0) { + baseIndent = Array(opts.indent + 1).join(' '); + } else { + return null; + } + return { + base: baseIndent, + prev: Array(depth + 1).join(baseIndent) + }; +} - return statById; - }() - }, { - key: "statByPath", - value: function () { - var _statByPath = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22(path) { - var resp; - return _regenerator.default.wrap(function _callee22$(_context22) { - while (1) { - switch (_context22.prev = _context22.next) { - case 0: - _context22.next = 2; - return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject15(), path)); +function indentedJoin(xs, indent) { + if (xs.length === 0) { return ''; } + var lineJoiner = '\n' + indent.prev + indent.base; + return lineJoiner + xs.join(',' + lineJoiner) + '\n' + indent.prev; +} - case 2: - resp = _context22.sent; - return _context22.abrupt("return", { - data: normalizeFile(resp.data), - included: resp.included && resp.included.map(function (f) { - return normalizeFile(f); - }) - }); +function arrObjKeys(obj, inspect) { + var isArr = isArray(obj); + var xs = []; + if (isArr) { + xs.length = obj.length; + for (var i = 0; i < obj.length; i++) { + xs[i] = has(obj, i) ? inspect(obj[i], obj) : ''; + } + } + var syms = typeof gOPS === 'function' ? gOPS(obj) : []; + var symMap; + if (hasShammedSymbols) { + symMap = {}; + for (var k = 0; k < syms.length; k++) { + symMap['$' + syms[k]] = syms[k]; + } + } - case 4: - case "end": - return _context22.stop(); + for (var key in obj) { // eslint-disable-line no-restricted-syntax + if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue + if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue + if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) { + // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section + continue; // eslint-disable-line no-restricted-syntax, no-continue + } else if ((/[^\w$]/).test(key)) { + xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj)); + } else { + xs.push(key + ': ' + inspect(obj[key], obj)); + } + } + if (typeof gOPS === 'function') { + for (var j = 0; j < syms.length; j++) { + if (isEnumerable.call(obj, syms[j])) { + xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj)); } - } - }, _callee22, this); - })); + } + } + return xs; +} - function statByPath(_x29) { - return _statByPath.apply(this, arguments); - } - return statByPath; - }() - /** - * Create directory - * - * @private - * @param {DirectoryAttributes} attributes - Attributes of the directory - * @returns {Promise} - * @throws {Error} - explaining reason why creation failed - */ +/***/ }), +/* 653 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - }, { - key: "createDirectory", - value: function () { - var _createDirectory = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee23() { - var attributes, - name, - dirId, - lastModifiedDate, - safeName, - lastModified, - resp, - _args23 = arguments; - return _regenerator.default.wrap(function _callee23$(_context23) { - while (1) { - switch (_context23.prev = _context23.next) { - case 0: - attributes = _args23.length > 0 && _args23[0] !== undefined ? _args23[0] : {}; - name = attributes.name, dirId = attributes.dirId, lastModifiedDate = attributes.lastModifiedDate; - safeName = sanitizeAndValidateFileName(name); - lastModified = lastModifiedDate && (typeof lastModifiedDate === 'string' ? new Date(lastModifiedDate) : lastModifiedDate); - _context23.next = 6; - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject16(), dirId, safeName), undefined, { - headers: { - Date: lastModified ? lastModified.toGMTString() : '' - } - }); +module.exports = __webpack_require__(64).inspect; - case 6: - resp = _context23.sent; - return _context23.abrupt("return", { - data: normalizeFile(resp.data) - }); - case 8: - case "end": - return _context23.stop(); - } - } - }, _callee23, this); - })); +/***/ }), +/* 654 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - function createDirectory() { - return _createDirectory.apply(this, arguments); - } +"use strict"; - return createDirectory; - }() - }, { - key: "ensureDirectoryExists", - value: function () { - var _ensureDirectoryExists = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee24(path) { - var resp; - return _regenerator.default.wrap(function _callee24$(_context24) { - while (1) { - switch (_context24.prev = _context24.next) { - case 0: - if (this.specialDirectories[path]) { - _context24.next = 5; - break; - } - _context24.next = 3; - return this.createDirectoryByPath(path); +var formats = __webpack_require__(655); - case 3: - resp = _context24.sent; - this.specialDirectories[path] = resp.data._id; +var has = Object.prototype.hasOwnProperty; +var isArray = Array.isArray; - case 5: - return _context24.abrupt("return", this.specialDirectories[path]); +var hexTable = (function () { + var array = []; + for (var i = 0; i < 256; ++i) { + array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase()); + } - case 6: - case "end": - return _context24.stop(); - } - } - }, _callee24, this); - })); + return array; +}()); - function ensureDirectoryExists(_x30) { - return _ensureDirectoryExists.apply(this, arguments); - } +var compactQueue = function compactQueue(queue) { + while (queue.length > 1) { + var item = queue.pop(); + var obj = item.obj[item.prop]; - return ensureDirectoryExists; - }() - }, { - key: "getDirectoryOrCreate", - value: function () { - var _getDirectoryOrCreate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee25(name, parentDirectory) { - var safeName, path, stat, parsedError, errors; - return _regenerator.default.wrap(function _callee25$(_context25) { - while (1) { - switch (_context25.prev = _context25.next) { - case 0: - if (!(parentDirectory && !parentDirectory.attributes)) { - _context25.next = 2; - break; + if (isArray(obj)) { + var compacted = []; + + for (var j = 0; j < obj.length; ++j) { + if (typeof obj[j] !== 'undefined') { + compacted.push(obj[j]); } + } - throw new Error('Malformed parent directory'); + item.obj[item.prop] = compacted; + } + } +}; - case 2: - safeName = sanitizeFileName(name); - path = "".concat(parentDirectory._id === ROOT_DIR_ID ? '' : parentDirectory.attributes.path, "/").concat(safeName); - _context25.prev = 4; - _context25.next = 7; - return this.statByPath(path || '/'); +var arrayToObject = function arrayToObject(source, options) { + var obj = options && options.plainObjects ? Object.create(null) : {}; + for (var i = 0; i < source.length; ++i) { + if (typeof source[i] !== 'undefined') { + obj[i] = source[i]; + } + } + + return obj; +}; + +var merge = function merge(target, source, options) { + /* eslint no-param-reassign: 0 */ + if (!source) { + return target; + } + + if (typeof source !== 'object') { + if (isArray(target)) { + target.push(source); + } else if (target && typeof target === 'object') { + if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) { + target[source] = true; + } + } else { + return [target, source]; + } - case 7: - stat = _context25.sent; - return _context25.abrupt("return", stat); + return target; + } - case 11: - _context25.prev = 11; - _context25.t0 = _context25["catch"](4); - parsedError = JSON.parse(_context25.t0.message); - errors = parsedError.errors; + if (!target || typeof target !== 'object') { + return [target].concat(source); + } - if (!(errors && errors.length && errors[0].status === '404')) { - _context25.next = 17; - break; - } + var mergeTarget = target; + if (isArray(target) && !isArray(source)) { + mergeTarget = arrayToObject(target, options); + } - return _context25.abrupt("return", this.createDirectory({ - name: safeName, - dirId: parentDirectory && parentDirectory._id - })); + if (isArray(target) && isArray(source)) { + source.forEach(function (item, i) { + if (has.call(target, i)) { + var targetItem = target[i]; + if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') { + target[i] = merge(targetItem, item, options); + } else { + target.push(item); + } + } else { + target[i] = item; + } + }); + return target; + } - case 17: - throw errors; + return Object.keys(source).reduce(function (acc, key) { + var value = source[key]; - case 18: - case "end": - return _context25.stop(); - } - } - }, _callee25, this, [[4, 11]]); - })); + if (has.call(acc, key)) { + acc[key] = merge(acc[key], value, options); + } else { + acc[key] = value; + } + return acc; + }, mergeTarget); +}; - function getDirectoryOrCreate(_x31, _x32) { - return _getDirectoryOrCreate.apply(this, arguments); - } +var assign = function assignSingleSource(target, source) { + return Object.keys(source).reduce(function (acc, key) { + acc[key] = source[key]; + return acc; + }, target); +}; - return getDirectoryOrCreate; - }() - /** - * async createDirectoryByPath - Creates one or more folders until the given path exists - * - * @param {string} path - Path of the created directory - * @returns {object} The document corresponding to the last segment of the path - */ +var decode = function (str, decoder, charset) { + var strWithoutPlus = str.replace(/\+/g, ' '); + if (charset === 'iso-8859-1') { + // unescape never throws, no try...catch needed: + return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape); + } + // utf-8 + try { + return decodeURIComponent(strWithoutPlus); + } catch (e) { + return strWithoutPlus; + } +}; - }, { - key: "createDirectoryByPath", - value: function () { - var _createDirectoryByPath = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee26(path) { - var parts, root, parentDir, _iterator2, _step2, part; +var encode = function encode(str, defaultEncoder, charset, kind, format) { + // This code was originally written by Brian White (mscdex) for the io.js core querystring library. + // It has been adapted here for stricter adherence to RFC 3986 + if (str.length === 0) { + return str; + } - return _regenerator.default.wrap(function _callee26$(_context26) { - while (1) { - switch (_context26.prev = _context26.next) { - case 0: - parts = path.split('/').filter(function (part) { - return part !== ''; - }); - _context26.next = 3; - return this.statById(ROOT_DIR_ID); + var string = str; + if (typeof str === 'symbol') { + string = Symbol.prototype.toString.call(str); + } else if (typeof str !== 'string') { + string = String(str); + } - case 3: - root = _context26.sent; + if (charset === 'iso-8859-1') { + return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { + return '%26%23' + parseInt($0.slice(2), 16) + '%3B'; + }); + } - if (parts.length) { - _context26.next = 6; - break; - } + var out = ''; + for (var i = 0; i < string.length; ++i) { + var c = string.charCodeAt(i); - return _context26.abrupt("return", root); + if ( + c === 0x2D // - + || c === 0x2E // . + || c === 0x5F // _ + || c === 0x7E // ~ + || (c >= 0x30 && c <= 0x39) // 0-9 + || (c >= 0x41 && c <= 0x5A) // a-z + || (c >= 0x61 && c <= 0x7A) // A-Z + || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( ) + ) { + out += string.charAt(i); + continue; + } - case 6: - parentDir = root; - _iterator2 = _createForOfIteratorHelper(parts); - _context26.prev = 8; + if (c < 0x80) { + out = out + hexTable[c]; + continue; + } - _iterator2.s(); + if (c < 0x800) { + out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); + continue; + } - case 10: - if ((_step2 = _iterator2.n()).done) { - _context26.next = 17; - break; - } + if (c < 0xD800 || c >= 0xE000) { + out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); + continue; + } - part = _step2.value; - _context26.next = 14; - return this.getDirectoryOrCreate(part, parentDir.data); + i += 1; + c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); + out += hexTable[0xF0 | (c >> 18)] + + hexTable[0x80 | ((c >> 12) & 0x3F)] + + hexTable[0x80 | ((c >> 6) & 0x3F)] + + hexTable[0x80 | (c & 0x3F)]; + } - case 14: - parentDir = _context26.sent; + return out; +}; - case 15: - _context26.next = 10; - break; +var compact = function compact(value) { + var queue = [{ obj: { o: value }, prop: 'o' }]; + var refs = []; - case 17: - _context26.next = 22; - break; + for (var i = 0; i < queue.length; ++i) { + var item = queue[i]; + var obj = item.obj[item.prop]; - case 19: - _context26.prev = 19; - _context26.t0 = _context26["catch"](8); + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; ++j) { + var key = keys[j]; + var val = obj[key]; + if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) { + queue.push({ obj: obj, prop: key }); + refs.push(val); + } + } + } - _iterator2.e(_context26.t0); + compactQueue(queue); - case 22: - _context26.prev = 22; + return value; +}; - _iterator2.f(); +var isRegExp = function isRegExp(obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; +}; - return _context26.finish(22); +var isBuffer = function isBuffer(obj) { + if (!obj || typeof obj !== 'object') { + return false; + } - case 25: - return _context26.abrupt("return", parentDir); + return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); +}; - case 26: - case "end": - return _context26.stop(); - } - } - }, _callee26, this, [[8, 19, 22, 25]]); - })); +var combine = function combine(a, b) { + return [].concat(a, b); +}; - function createDirectoryByPath(_x33) { - return _createDirectoryByPath.apply(this, arguments); - } +var maybeMap = function maybeMap(val, fn) { + if (isArray(val)) { + var mapped = []; + for (var i = 0; i < val.length; i += 1) { + mapped.push(fn(val[i])); + } + return mapped; + } + return fn(val); +}; - return createDirectoryByPath; - }() - /** - * - * async updateAttributes - Updates a file / folder's attributes except - * the metadata attribute. If you want to update its metadata attribute, - * then use `updateFileMetadataAttribute` since `metadata` is a specific - * doctype. - * - * For instance, if you want to update the name of a file, you can pass - * attributes = { name: 'newName'} - * - * You can see the attributes for both Folder and File (as they share the - * same doctype they have a few in common) here : - * https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files/#iocozyfiles - * - * @private You shoud use update() directly. - * @param {string} id File id - * @param {object} attributes New file attributes - * @returns {object} Updated document - * @throws {Error} - explaining reason why update failed - */ +module.exports = { + arrayToObject: arrayToObject, + assign: assign, + combine: combine, + compact: compact, + decode: decode, + encode: encode, + isBuffer: isBuffer, + isRegExp: isRegExp, + maybeMap: maybeMap, + merge: merge +}; - }, { - key: "updateAttributes", - value: function () { - var _updateAttributes = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee27(id, attributes) { - var sanitizedAttributes, resp; - return _regenerator.default.wrap(function _callee27$(_context27) { - while (1) { - switch (_context27.prev = _context27.next) { - case 0: - sanitizedAttributes = _objectSpread({}, attributes); - if (attributes.name) { - sanitizedAttributes.name = sanitizeAndValidateFileName(attributes.name); - } +/***/ }), +/* 655 */ +/***/ ((module) => { - _context27.next = 4; - return this.stackClient.fetchJSON('PATCH', (0, _utils.uri)(_templateObject17(), id), { - data: { - type: 'io.cozy.files', - id: id, - attributes: sanitizedAttributes - } - }); +"use strict"; - case 4: - resp = _context27.sent; - return _context27.abrupt("return", { - data: normalizeFile(resp.data) - }); - case 6: - case "end": - return _context27.stop(); - } - } - }, _callee27, this); - })); +var replace = String.prototype.replace; +var percentTwenties = /%20/g; - function updateAttributes(_x34, _x35) { - return _updateAttributes.apply(this, arguments); - } +var Format = { + RFC1738: 'RFC1738', + RFC3986: 'RFC3986' +}; - return updateAttributes; - }() - }, { - key: "updateFileMetadata", - value: function () { - var _updateFileMetadata = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee28(id, attributes) { - return _regenerator.default.wrap(function _callee28$(_context28) { - while (1) { - switch (_context28.prev = _context28.next) { - case 0: - console.warn('CozyClient FileCollection updateFileMetadata method is deprecated. Use updateAttributes instead'); - return _context28.abrupt("return", this.updateAttributes(id, attributes)); +module.exports = { + 'default': Format.RFC3986, + formatters: { + RFC1738: function (value) { + return replace.call(value, percentTwenties, '+'); + }, + RFC3986: function (value) { + return String(value); + } + }, + RFC1738: Format.RFC1738, + RFC3986: Format.RFC3986 +}; - case 2: - case "end": - return _context28.stop(); - } - } - }, _callee28, this); - })); - function updateFileMetadata(_x36, _x37) { - return _updateFileMetadata.apply(this, arguments); - } +/***/ }), +/* 656 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return updateFileMetadata; - }() - /** - * Send a metadata object that can be associated to a file uploaded after that, - * via the MetadataID query parameter. - * See https://github.com/cozy/cozy-stack/blob/master/docs/files.md#post-filesuploadmetadata - * - * @param {object} attributes The file's metadata - * @returns {object} The Metadata object - */ +"use strict"; - }, { - key: "createFileMetadata", - value: function () { - var _createFileMetadata = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee29(attributes) { - var resp; - return _regenerator.default.wrap(function _callee29$(_context29) { - while (1) { - switch (_context29.prev = _context29.next) { - case 0: - _context29.next = 2; - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject18()), { - data: { - type: 'io.cozy.files.metadata', - attributes: attributes - } - }); - case 2: - resp = _context29.sent; - return _context29.abrupt("return", { - data: resp.data - }); +var utils = __webpack_require__(654); - case 4: - case "end": - return _context29.stop(); - } - } - }, _callee29, this); - })); +var has = Object.prototype.hasOwnProperty; +var isArray = Array.isArray; - function createFileMetadata(_x38) { - return _createFileMetadata.apply(this, arguments); - } +var defaults = { + allowDots: false, + allowPrototypes: false, + allowSparse: false, + arrayLimit: 20, + charset: 'utf-8', + charsetSentinel: false, + comma: false, + decoder: utils.decode, + delimiter: '&', + depth: 5, + ignoreQueryPrefix: false, + interpretNumericEntities: false, + parameterLimit: 1000, + parseArrays: true, + plainObjects: false, + strictNullHandling: false +}; - return createFileMetadata; - }() - /** - * - * Updates the metadata attribute of a io.cozy.files - * Creates a new version of the file without having - * to upload again the file's content - * - * To see available content of the metadata attribute - * see : https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files_metadata/ - * - * @param {string} id File id - * @param {object} metadata io.cozy.files.metadata attributes - * @returns {object} io.cozy.files updated - */ +var interpretNumericEntities = function (str) { + return str.replace(/&#(\d+);/g, function ($0, numberStr) { + return String.fromCharCode(parseInt(numberStr, 10)); + }); +}; - }, { - key: "updateMetadataAttribute", - value: function () { - var _updateMetadataAttribute = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee30(id, metadata) { - var resp; - return _regenerator.default.wrap(function _callee30$(_context30) { - while (1) { - switch (_context30.prev = _context30.next) { - case 0: - _context30.next = 2; - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject19(), id), { - data: { - type: 'io.cozy.files.metadata', - attributes: metadata - } - }); +var parseArrayValue = function (val, options) { + if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) { + return val.split(','); + } - case 2: - resp = _context30.sent; - return _context30.abrupt("return", { - data: resp.data - }); + return val; +}; - case 4: - case "end": - return _context30.stop(); - } - } - }, _callee30, this); - })); +// This is what browsers will submit when the ✓ character occurs in an +// application/x-www-form-urlencoded body and the encoding of the page containing +// the form is iso-8859-1, or when the submitted form has an accept-charset +// attribute of iso-8859-1. Presumably also with other charsets that do not contain +// the ✓ character, such as us-ascii. +var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓') - function updateMetadataAttribute(_x39, _x40) { - return _updateMetadataAttribute.apply(this, arguments); - } +// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded. +var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓') - return updateMetadataAttribute; - }() - /** - * Get the file mime-type based on its name - * - * @param {string} name - The file name - * @returns {string} the inferred file mime-type - */ +var parseValues = function parseQueryStringValues(str, options) { + var obj = {}; + var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str; + var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit; + var parts = cleanStr.split(options.delimiter, limit); + var skipIndex = -1; // Keep track of where the utf8 sentinel was found + var i; - }, { - key: "getFileTypeFromName", - value: function getFileTypeFromName(name) { - return _lite.default.getType(name) || CONTENT_TYPE_OCTET_STREAM; + var charset = options.charset; + if (options.charsetSentinel) { + for (i = 0; i < parts.length; ++i) { + if (parts[i].indexOf('utf8=') === 0) { + if (parts[i] === charsetSentinel) { + charset = 'utf-8'; + } else if (parts[i] === isoSentinel) { + charset = 'iso-8859-1'; + } + skipIndex = i; + i = parts.length; // The eslint settings do not allow break; + } + } } - /** - * - * This method should not be called directly to upload a file. - * You should use `createFile` - * - * @param {File|Blob|Stream|string|ArrayBuffer} dataArg file to be uploaded - * @param {string} path Uri to call the stack from. Something like - * `/files/${dirId}?Name=${name}&Type=file&Executable=${executable}&MetadataID=${metadataId}` - * @param {object} options Additional headers - * @param {string} method POST / PUT / PATCH - */ - }, { - key: "doUpload", - value: function () { - var _doUpload = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee31(dataArg, path, options) { - var method, - correctPath, - data, - isBuffer, - isFile, - isBlob, - isStream, - isString, - _ref9, - contentType, - contentLength, - checksum, - lastModifiedDate, - ifMatch, - sPath, - params, - name, - headers, - date, - resp, - _args31 = arguments; + for (i = 0; i < parts.length; ++i) { + if (i === skipIndex) { + continue; + } + var part = parts[i]; - return _regenerator.default.wrap(function _callee31$(_context31) { - while (1) { - switch (_context31.prev = _context31.next) { - case 0: - method = _args31.length > 3 && _args31[3] !== undefined ? _args31[3] : 'POST'; - correctPath = path; - data = dataArg; + var bracketEqualsPos = part.indexOf(']='); + var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1; - if (data) { - _context31.next = 5; - break; + var key, val; + if (pos === -1) { + key = options.decoder(part, defaults.decoder, charset, 'key'); + val = options.strictNullHandling ? null : ''; + } else { + key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key'); + val = utils.maybeMap( + parseArrayValue(part.slice(pos + 1), options), + function (encodedVal) { + return options.decoder(encodedVal, defaults.decoder, charset, 'value'); } + ); + } - throw new Error('missing data argument'); + if (val && options.interpretNumericEntities && charset === 'iso-8859-1') { + val = interpretNumericEntities(val); + } - case 5: - // transform any ArrayBufferView to ArrayBuffer - if (data.buffer && data.buffer instanceof ArrayBuffer) { - data = data.buffer; - } + if (part.indexOf('[]=') > -1) { + val = isArray(val) ? [val] : val; + } - isBuffer = typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer; - isFile = typeof File !== 'undefined' && data instanceof File; - isBlob = typeof Blob !== 'undefined' && data instanceof Blob; - isStream = data.readable === true && typeof data.pipe === 'function'; - isString = typeof data === 'string'; + if (has.call(obj, key)) { + obj[key] = utils.combine(obj[key], val); + } else { + obj[key] = val; + } + } - if (!(!isBuffer && !isFile && !isBlob && !isStream && !isString)) { - _context31.next = 13; - break; - } + return obj; +}; - throw new Error('invalid data type'); +var parseObject = function (chain, val, options, valuesParsed) { + var leaf = valuesParsed ? val : parseArrayValue(val, options); - case 13: - _ref9 = options || {}, contentType = _ref9.contentType, contentLength = _ref9.contentLength, checksum = _ref9.checksum, lastModifiedDate = _ref9.lastModifiedDate, ifMatch = _ref9.ifMatch; + for (var i = chain.length - 1; i >= 0; --i) { + var obj; + var root = chain[i]; - if (!contentType) { - if (typeof data === 'string') { - contentType = 'text/plain'; - } else { - if (data.type) { - // The type is specified in the file object - contentType = data.type; - } else { - // Extract the name from the correctPath and infer the type - sPath = correctPath.split('?'); - params = sPath.length > 1 ? sPath[1] : ''; - name = new URLSearchParams(params).get('Name'); - contentType = this.getFileTypeFromName(name.toLowerCase()); - } - } - } + if (root === '[]' && options.parseArrays) { + obj = [].concat(leaf); + } else { + obj = options.plainObjects ? Object.create(null) : {}; + var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root; + var index = parseInt(cleanRoot, 10); + if (!options.parseArrays && cleanRoot === '') { + obj = { 0: leaf }; + } else if ( + !isNaN(index) + && root !== cleanRoot + && String(index) === cleanRoot + && index >= 0 + && (options.parseArrays && index <= options.arrayLimit) + ) { + obj = []; + obj[index] = leaf; + } else { + obj[cleanRoot] = leaf; + } + } - lastModifiedDate = lastModifiedDate || data.lastModified; + leaf = obj; + } - if (lastModifiedDate) { - lastModifiedDate = new Date(lastModifiedDate); - } + return leaf; +}; - headers = { - 'Content-Type': contentType - }; - if (contentLength) headers['Content-Length'] = String(contentLength); - if (checksum) headers['Content-MD5'] = checksum; +var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) { + if (!givenKey) { + return; + } - if (lastModifiedDate) { - date = lastModifiedDate.toISOString(); - correctPath = "".concat(correctPath, "&UpdatedAt=").concat(date, "&CreatedAt=").concat(date); - } + // Transform dot notation to bracket notation + var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; - if (ifMatch) headers['If-Match'] = ifMatch; - _context31.next = 24; - return this.stackClient.fetchJSON(method, correctPath, data, { - headers: headers, - onUploadProgress: options.onUploadProgress - }); + // The regex chunks - case 24: - resp = _context31.sent; - return _context31.abrupt("return", { - data: normalizeFile(resp.data) - }); + var brackets = /(\[[^[\]]*])/; + var child = /(\[[^[\]]*])/g; - case 26: - case "end": - return _context31.stop(); - } - } - }, _callee31, this); - })); + // Get the parent - function doUpload(_x41, _x42, _x43) { - return _doUpload.apply(this, arguments); - } + var segment = options.depth > 0 && brackets.exec(key); + var parent = segment ? key.slice(0, segment.index) : key; - return doUpload; - }() - /** - * async findNotSynchronizedDirectories - Returns the list of directories not synchronized on the given OAuth client (mainly Cozy Desktop clients) — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#get-datatypedoc-idrelationshipsnot_synchronizing - * - * @param {OAuthClient} oauthClient A JSON representing an OAuth client, with at least a `_type` and `_id` field. - * @param {object|null} options Pagination options - * @param {number|null} options.skip For skip-based pagination, the number of referenced files to skip. - * @param {number|null} options.limit For pagination, the number of results to return. - * @param {CouchDBViewCursor|null} options.cursor For cursor-based pagination, the index cursor. - * @param {boolean} options.includeFiles Include the whole file documents in the results list - * - * @returns {Array<object|IOCozyFolder>} The JSON API conformant response. - */ + // Stash the parent if it exists - }, { - key: "findNotSynchronizedDirectories", - value: function () { - var _findNotSynchronizedDirectories = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee32(oauthClient) { - var _ref10, - _ref10$skip, - skip, - limit, - cursor, - _ref10$includeFiles, - includeFiles, - params, - path, - url, - resp, - _args32 = arguments; + var keys = []; + if (parent) { + // If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties + if (!options.plainObjects && has.call(Object.prototype, parent)) { + if (!options.allowPrototypes) { + return; + } + } - return _regenerator.default.wrap(function _callee32$(_context32) { - while (1) { - switch (_context32.prev = _context32.next) { - case 0: - _ref10 = _args32.length > 1 && _args32[1] !== undefined ? _args32[1] : {}, _ref10$skip = _ref10.skip, skip = _ref10$skip === void 0 ? 0 : _ref10$skip, limit = _ref10.limit, cursor = _ref10.cursor, _ref10$includeFiles = _ref10.includeFiles, includeFiles = _ref10$includeFiles === void 0 ? false : _ref10$includeFiles; - params = { - include: includeFiles ? 'files' : undefined, - 'page[limit]': limit, - 'page[cursor]': cursor, - sort: 'id' - }; - path = (0, _utils.uri)(_templateObject20(), oauthClient._type, oauthClient._id); - url = querystring.buildURL(path, params); - _context32.next = 6; - return this.stackClient.fetchJSON('GET', url); + keys.push(parent); + } - case 6: - resp = _context32.sent; - return _context32.abrupt("return", { - data: resp.data.map(function (f) { - return normalizeFile(f); - }), - included: resp.included ? resp.included.map(function (f) { - return normalizeFile(f); - }) : [], - next: (0, _has.default)(resp, 'links.next'), - meta: resp.meta, - skip: skip - }); + // Loop through children appending to the array until we hit depth - case 8: - case "end": - return _context32.stop(); + var i = 0; + while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) { + i += 1; + if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) { + if (!options.allowPrototypes) { + return; } - } - }, _callee32, this); - })); + } + keys.push(segment[1]); + } - function findNotSynchronizedDirectories(_x44) { - return _findNotSynchronizedDirectories.apply(this, arguments); - } + // If there's a remainder, just add whatever is left - return findNotSynchronizedDirectories; - }() - /** - * Add directory synchronization exclusions to an OAuth client — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#post-datatypedoc-idrelationshipsnot_synchronizing - * - * For example, to exclude directory `/Photos` from `My Computer`'s desktop synchronization: - * ``` - * addNotSynchronizedDirectories({_id: 123, _type: "io.cozy.oauth.clients", clientName: "Cozy Drive (My Computer)", clientKind: "desktop"}, [{_id: 456, _type: "io.cozy.files", name: "Photos", path: "/Photos"}]) - * ``` - * - * @param {OAuthClient} oauthClient A JSON representing the OAuth client - * @param {Array} directories An array of JSON documents having a `_type` and `_id` fields and representing directories. - * - * Returns 204 No Content - */ + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); + } - }, { - key: "addNotSynchronizedDirectories", - value: function addNotSynchronizedDirectories(oauthClient, directories) { - var refs = directories.map(function (d) { - return { - id: d._id, - type: d._type - }; - }); - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject21(), oauthClient._type, oauthClient._id), { - data: refs - }); + return parseObject(keys, val, options, valuesParsed); +}; + +var normalizeParseOptions = function normalizeParseOptions(opts) { + if (!opts) { + return defaults; } - /** - * Remove directory synchronization exclusions from an OAuth client — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#delete-datatypedoc-idrelationshipsnot_synchronizing - * - * For example, to re-include directory `/Photos` into `My Computer`'s desktop synchronization: - * ``` - * removeNotSynchronizedDirectories({_id: 123, _type: "io.cozy.oauth.clients", clientName: "Cozy Drive (My Computer)", clientKind: "desktop"}, [{_id: 456, _type: "io.cozy.files", name: "Photos", path: "/Photos"}]) - * ``` - * - * @param {OAuthClient} oauthClient A JSON representing the OAuth client - * @param {Array} directories An array of JSON documents having a `_type` and `_id` field and representing directories. - * - * Returns 204 No Content - */ - }, { - key: "removeNotSynchronizedDirectories", - value: function removeNotSynchronizedDirectories(oauthClient, directories) { - var refs = directories.map(function (d) { - return { - id: d._id, - type: d._type - }; - }); - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject22(), oauthClient._type, oauthClient._id), { - data: refs - }); + if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') { + throw new TypeError('Decoder has to be a function.'); } - /** - * Use cozy-stack's _changes API for io.cozy.files - * Design docs are filtered by default, thus documents are retrieved in the - * response (includeDocs is set to true in the parameters of _changes). - * Deleted and trashed documents can be filtered on demand and files' paths - * can be requested as well. - * - * Since deleted and trashed documents are skipped by cozy-stack rather than - * CouchDB, when either option is set to true, the response can contain less - * documents than the defined limit. Thus one should rely solely on the - * `pending` result attribute to determine if more documents can be fetched or - * not. - * - * You should use fetchChangesRaw to call CouchDB's _changes API. - * - * @typedef {object} CouchOptions - * @property {string} since - Bookmark telling CouchDB from which point in time should changes be returned - * @property {number} limit - The maximum number of returned documents for one call - * @property {boolean} includeDocs - Whether or not complete documents should be returned - * - * @typedef {object} FetchChangesOptions - * @property {Array<string>} fields - The list of fields that should be returned for each document - * @property {boolean} includeFilePath - Whether to include the path of file changes (needs includeDocs to be true) - * @property {boolean} skipDeleted - Whether to skip changes for deleted documents - * @property {boolean} skipTrashed - Whether to skip changes for trashed documents (needs includeDocs to be true) - * - * @param {CouchOptions} couchOptions - Couch options for changes - * @param {FetchChangesOptions} options - Further options on the returned documents. By default, it is set to - * { includeFilePath: false, skipDeleted: false, skipTrashed: false } - * - * @typedef {object} FetchChangesReturnValue - * @property {string} newLastSeq - * @property {boolean} pending - * @property {Array<object>} documents - * @returns {FetchChangesReturnValue} - */ - }, { - key: "fetchChanges", - value: function () { - var _fetchChanges = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee33() { - var couchOptions, - options, - opts, - params, - path, - url, - _yield$this$stackClie, - newLastSeq, - pending, - results, - _args33 = arguments; + if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { + throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); + } + var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset; - return _regenerator.default.wrap(function _callee33$(_context33) { - while (1) { - switch (_context33.prev = _context33.next) { - case 0: - couchOptions = _args33.length > 0 && _args33[0] !== undefined ? _args33[0] : {}; - options = _args33.length > 1 && _args33[1] !== undefined ? _args33[1] : {}; - opts = {}; + return { + allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots, + allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes, + allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse, + arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit, + charset: charset, + charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, + comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma, + decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder, + delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter, + // eslint-disable-next-line no-implicit-coercion, no-extra-parens + depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth, + ignoreQueryPrefix: opts.ignoreQueryPrefix === true, + interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities, + parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit, + parseArrays: opts.parseArrays !== false, + plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects, + strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling + }; +}; - if (typeof couchOptions !== 'object') { - opts.since = couchOptions; - console.warn("fetchChanges use couchOptions as Object not a string, since is deprecated, please use fetchChanges({since: \"".concat(couchOptions, "\"}).")); - } else if (Object.keys(couchOptions).length > 0) { - Object.assign(opts, couchOptions); - } +module.exports = function (str, opts) { + var options = normalizeParseOptions(opts); - if (Object.keys(options).length > 0) { - Object.assign(opts, options); + if (str === '' || str === null || typeof str === 'undefined') { + return options.plainObjects ? Object.create(null) : {}; + } - if (options.skipTrashed || options.includeFilePath) { - opts.includeDocs = true; - } - } + var tempObj = typeof str === 'string' ? parseValues(str, options) : str; + var obj = options.plainObjects ? Object.create(null) : {}; - params = _objectSpread(_objectSpread({}, (0, _omit.default)(opts, ['fields', 'includeDocs', 'includeFilePath', 'skipDeleted', 'skipTrashed'])), {}, { - fields: opts.fields ? opts.fields.join(',') : null, - include_docs: opts.includeDocs, - include_file_path: opts.includeFilePath, - skip_deleted: opts.skipDeleted, - skip_trashed: opts.skipTrashed - }); - path = (0, _utils.uri)(_templateObject23()); - url = querystring.buildURL(path, params); - _context33.next = 10; - return this.stackClient.fetchJSON('GET', url); + // Iterate over the keys and setup the new object - case 10: - _yield$this$stackClie = _context33.sent; - newLastSeq = _yield$this$stackClie.last_seq; - pending = _yield$this$stackClie.pending; - results = _yield$this$stackClie.results; - return _context33.abrupt("return", { - newLastSeq: newLastSeq, - pending: pending, - results: results - }); + var keys = Object.keys(tempObj); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string'); + obj = utils.merge(obj, newObj, options); + } - case 15: - case "end": - return _context33.stop(); - } - } - }, _callee33, this); - })); + if (options.allowSparse === true) { + return obj; + } - function fetchChanges() { - return _fetchChanges.apply(this, arguments); - } + return utils.compact(obj); +}; - return fetchChanges; - }() - }]); - return FileCollection; -}(_DocumentCollection2.default); -var _default = FileCollection; -exports["default"] = _default; +/***/ }), +/* 657 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(524); + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.isMatchingIndex = exports.isInconsistentIndex = exports.getIndexFields = exports.transformSort = exports.getIndexNameFromFields = exports.normalizeDesignDoc = void 0; -/***/ }), -/* 659 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); -"use strict"; +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); +var _utils = __webpack_require__(623); -let Mime = __webpack_require__(660); -module.exports = new Mime(__webpack_require__(661)); +var _head = _interopRequireDefault(__webpack_require__(633)); +var _get = _interopRequireDefault(__webpack_require__(370)); -/***/ }), -/* 660 */ -/***/ ((module) => { +var _isEqual = _interopRequireDefault(__webpack_require__(658)); -"use strict"; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** - * @param typeMap [Object] Map of MIME type -> Array[extensions] - * @param ... + * @typedef {object} MangoPartialFilter */ -function Mime() { - this._types = Object.create(null); - this._extensions = Object.create(null); - - for (let i = 0; i < arguments.length; i++) { - this.define(arguments[i]); - } - - this.define = this.define.bind(this); - this.getType = this.getType.bind(this); - this.getExtension = this.getExtension.bind(this); -} /** - * Define mimetype -> extension mappings. Each key is a mime-type that maps - * to an array of extensions associated with the type. The first extension is - * used as the default extension for the type. - * - * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); - * - * If a type declares an extension that has already been defined, an error will - * be thrown. To suppress this error and force the extension to be associated - * with the new type, pass `force`=true. Alternatively, you may prefix the - * extension with "*" to map the type to extension, without mapping the - * extension to the type. + * @typedef {object} MangoQueryOptions * - * e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']}); + * @property {Array<object>} [sort] The sorting parameters + * @property {Array<string>} [fields] The fields to return + * @property {number|null} [limit] For pagination, the number of results to return + * @property {number|null} [skip] For skip-based pagination, the number of referenced files to skip + * @property {string|null} [indexId] The _id of the CouchDB index to use for this request + * @property {string|null} [bookmark] For bookmark-based pagination, the document _id to start from + * @property {Array<string>} [indexedFields] + * @property {MangoPartialFilter|null} [partialFilter] An optional partial filter + */ + +/** + * Attributes representing a design doc * + * @typedef {object} DesignDoc * - * @param map (Object) type definitions - * @param force (Boolean) if true, force overriding of existing definitions + * @property {string} _id - Id of the design doc. Can be named, e.g. '_design/by_indexed_attribute' or not, e.g. '_design/12345' + * @property {string} language - The index language. Can be 'query' for mango index or 'javascript' for views. + * @property {object} views - Views definition, i.e. the index. */ -Mime.prototype.define = function(typeMap, force) { - for (let type in typeMap) { - let extensions = typeMap[type].map(function(t) { - return t.toLowerCase(); - }); - type = type.toLowerCase(); - - for (let i = 0; i < extensions.length; i++) { - const ext = extensions[i]; +var normalizeDesignDoc = function normalizeDesignDoc(designDoc) { + var id = designDoc._id || designDoc.id; + return _objectSpread({ + id: id, + _id: id + }, designDoc.doc); +}; - // '*' prefix = not the preferred type for this extension. So fixup the - // extension, and skip it. - if (ext[0] === '*') { - continue; - } +exports.normalizeDesignDoc = normalizeDesignDoc; - if (!force && (ext in this._types)) { - throw new Error( - 'Attempt to change mapping for "' + ext + - '" extension from "' + this._types[ext] + '" to "' + type + - '". Pass `force=true` to allow this, otherwise remove "' + ext + - '" from the list of extensions for "' + type + '".' - ); - } +var getIndexNameFromFields = function getIndexNameFromFields(fields) { + return "by_".concat(fields.join('_and_')); +}; - this._types[ext] = type; - } +exports.getIndexNameFromFields = getIndexNameFromFields; - // Use first extension as default - if (force || !this._extensions[type]) { - const ext = extensions[0]; - this._extensions[type] = (ext[0] !== '*') ? ext : ext.substr(1); - } +var transformSort = function transformSort(sort) { + if (!sort || Array.isArray(sort)) { + return sort; } -}; + console.warn('Passing an object to the "sort" is deprecated, please use an array instead.'); + return (0, _utils.transform)(sort, function (acc, order, field) { + return acc.push((0, _defineProperty2.default)({}, field, order)); + }, []); +}; /** - * Lookup a mime type based on extension + * Compute fields that should be indexed for a mango + * query to work + * + * @param {MangoQueryOptions} options - Mango query options + * + * @returns {Array} - Fields to index */ -Mime.prototype.getType = function(path) { - path = String(path); - let last = path.replace(/^.*[/\\]/, '').toLowerCase(); - let ext = last.replace(/^.*\./, '').toLowerCase(); - let hasPath = last.length < path.length; - let hasDot = ext.length < last.length - 1; - return (hasDot || !hasPath) && this._types[ext] || null; -}; +exports.transformSort = transformSort; +var getIndexFields = function getIndexFields(_ref) { + var selector = _ref.selector, + _ref$sort = _ref.sort, + sort = _ref$sort === void 0 ? [] : _ref$sort; + return Array.from(new Set([].concat((0, _toConsumableArray2.default)(sort.map(function (sortOption) { + return (0, _head.default)(Object.keys(sortOption)); + })), (0, _toConsumableArray2.default)(selector ? Object.keys(selector) : [])))); +}; /** - * Return file extension associated with a mime type + * Check if an index is in an inconsistent state, i.e. its name + * contains the indexed attributes which are not in correct order. + * + * @param {DesignDoc} index - The index to check + * @returns {boolean} True if the index is inconsistent */ -Mime.prototype.getExtension = function(type) { - type = /^\s*([^;\s]*)/.test(type) && RegExp.$1; - return type && this._extensions[type.toLowerCase()] || null; + + +exports.getIndexFields = getIndexFields; + +var isInconsistentIndex = function isInconsistentIndex(index) { + var indexId = index._id; + + if (!indexId.startsWith('_design/by_')) { + return false; + } + + var fieldsInName = indexId.split('_design/by_')[1].split('_and_'); + var viewId = Object.keys((0, _get.default)(index, "views"))[0]; + var fieldsInIndex = Object.keys((0, _get.default)(index, "views.".concat(viewId, ".map.fields"))); + return !(0, _isEqual.default)(fieldsInName, fieldsInIndex); }; +/** + * Check if an index is matching the given fields + * + * @param {DesignDoc} index - The index to check + * @param {Array} fields - The fields that the index must have + * @param {object} partialFilter - An optional partial filter + * @returns {boolean} True if the index is matches the given fields + */ -module.exports = Mime; +exports.isInconsistentIndex = isInconsistentIndex; -/***/ }), -/* 661 */ -/***/ ((module) => { +var isMatchingIndex = function isMatchingIndex(index, fields, partialFilter) { + var viewId = Object.keys((0, _get.default)(index, "views"))[0]; + var fieldsInIndex = Object.keys((0, _get.default)(index, "views.".concat(viewId, ".map.fields"))); -module.exports = {"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomdeleted+xml":["atomdeleted"],"application/atomsvc+xml":["atomsvc"],"application/atsc-dwd+xml":["dwd"],"application/atsc-held+xml":["held"],"application/atsc-rsat+xml":["rsat"],"application/bdoc":["bdoc"],"application/calendar+xml":["xcs"],"application/ccxml+xml":["ccxml"],"application/cdfx+xml":["cdfx"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["ecma","es"],"application/emma+xml":["emma"],"application/emotionml+xml":["emotionml"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/fdt+xml":["fdt"],"application/font-tdpfr":["pfr"],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hjson":["hjson"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/its+xml":["its"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lgr+xml":["lgr"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mmt-aei+xml":["maei"],"application/mmt-usd+xml":["musd"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/mrb-consumer+xml":["*xdf"],"application/mrb-publish+xml":["*xdf"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/n-quads":["nq"],"application/n-triples":["nt"],"application/node":["cjs"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/p2p-overlay+xml":["relo"],"application/patch-ops-error+xml":["*xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/provenance+xml":["provx"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf","owl"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/route-apd+xml":["rapd"],"application/route-s-tsid+xml":["sls"],"application/route-usd+xml":["rusd"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/senml+xml":["senmlx"],"application/sensml+xml":["sensmlx"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/sieve":["siv","sieve"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/swid+xml":["swidtag"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/toml":["toml"],"application/ttml+xml":["ttml"],"application/ubjson":["ubj"],"application/urc-ressheet+xml":["rsheet"],"application/urc-targetdesc+xml":["td"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/xaml+xml":["xaml"],"application/xcap-att+xml":["xav"],"application/xcap-caps+xml":["xca"],"application/xcap-diff+xml":["xdf"],"application/xcap-el+xml":["xel"],"application/xcap-error+xml":["xer"],"application/xcap-ns+xml":["xns"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xliff+xml":["xlf"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["*xsl","xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":["*3gpp"],"audio/adpcm":["adp"],"audio/amr":["amr"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mobile-xmf":["mxmf"],"audio/mp3":["*mp3"],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx","opus"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/wav":["wav"],"audio/wave":["*wav"],"audio/webm":["weba"],"audio/xm":["xm"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/aces":["exr"],"image/apng":["apng"],"image/avif":["avif"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/dicom-rle":["drle"],"image/emf":["emf"],"image/fits":["fits"],"image/g3fax":["g3"],"image/gif":["gif"],"image/heic":["heic"],"image/heic-sequence":["heics"],"image/heif":["heif"],"image/heif-sequence":["heifs"],"image/hej2k":["hej2"],"image/hsj2":["hsj2"],"image/ief":["ief"],"image/jls":["jls"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jph":["jph"],"image/jphc":["jhc"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/jxr":["jxr"],"image/jxra":["jxra"],"image/jxrs":["jxrs"],"image/jxs":["jxs"],"image/jxsc":["jxsc"],"image/jxsi":["jxsi"],"image/jxss":["jxss"],"image/ktx":["ktx"],"image/ktx2":["ktx2"],"image/png":["png"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/t38":["t38"],"image/tiff":["tif","tiff"],"image/tiff-fx":["tfx"],"image/webp":["webp"],"image/wmf":["wmf"],"message/disposition-notification":["disposition-notification"],"message/global":["u8msg"],"message/global-delivery-status":["u8dsn"],"message/global-disposition-notification":["u8mdn"],"message/global-headers":["u8hdr"],"message/rfc822":["eml","mime"],"model/3mf":["3mf"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/mtl":["mtl"],"model/obj":["obj"],"model/stl":["stl"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["*x3db","x3dbz"],"model/x3d+fastinfoset":["x3db"],"model/x3d+vrml":["*x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"model/x3d-vrml":["x3dv"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/mdx":["mdx"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/richtext":["rtx"],"text/rtf":["*rtf"],"text/sgml":["sgml","sgm"],"text/shex":["shex"],"text/slim":["slim","slm"],"text/spdx":["spdx"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vtt":["vtt"],"text/xml":["*xml"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/iso.segment":["m4s"],"video/jpeg":["jpgv"],"video/jpm":["*jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/webm":["webm"]}; + if ((0, _isEqual.default)(fieldsInIndex, fields)) { + if (!partialFilter) { + return true; + } + + var partialFilterInIndex = (0, _get.default)(index, "views.".concat(viewId, ".map.partial_filter_selector")); + + if ((0, _isEqual.default)(partialFilter, partialFilterInIndex)) { + return true; + } + } + + return false; +}; + +exports.isMatchingIndex = isMatchingIndex; /***/ }), -/* 662 */ +/* 658 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseHas = __webpack_require__(663), - hasPath = __webpack_require__(458); +var baseIsEqual = __webpack_require__(422); /** - * Checks if `path` is a direct property of `object`. + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. * * @static - * @since 0.1.0 * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * - * var object = { 'a': { 'b': 2 } }; - * var other = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.has(object, 'a'); - * // => true - * - * _.has(object, 'a.b'); - * // => true + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; * - * _.has(object, ['a', 'b']); + * _.isEqual(object, other); * // => true * - * _.has(other, 'a'); + * object === other; * // => false */ -function has(object, path) { - return object != null && hasPath(object, path, baseHas); +function isEqual(value, other) { + return baseIsEqual(value, other); } -module.exports = has; +module.exports = isEqual; /***/ }), -/* 663 */ -/***/ ((module) => { +/* 659 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -/** Used for built-in method references. */ -var objectProto = Object.prototype; +"use strict"; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + +var _interopRequireDefault = __webpack_require__(524); + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.buildURL = exports.encode = void 0; + +var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532)); + +var _pickBy = _interopRequireDefault(__webpack_require__(660)); /** - * The base implementation of `_.has` without support for deep paths. + * Encode a value of any type into a URI search param compatible string with a specific treatment for arrays which will keep their brackets (they do not with standard `toString()` method). + * + * Examples: + * + * encodeValues([['io.cozy.files', 'abcd1234'], '12345']) + * // → '[[%22io.cozy.files%22,%22abcd1234%22],%2212345%22]' * + * encodeValues([['io.cozy.files', 'abcd1234'], '12345'].toString(), true) + * // → '%22io.cozy.files%2Cabcd1234%2C12345%22' + * + * encodeValues([['io.cozy.files', 'abcd1234'], '12345'].toString(), false) + * // → 'io.cozy.files%2Cabcd1234%2C12345' + * + * encodeValues('[1234]') + * // → %5B1234%5D + * + * @function * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. */ -function baseHas(object, key) { - return object != null && hasOwnProperty.call(object, key); -} +var encodeValues = function encodeValues(values) { + var fromArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; -module.exports = baseHas; + if (Array.isArray(values)) { + return '[' + values.map(function (v) { + return encodeValues(v, true); + }).join(',') + ']'; + } + + return fromArray ? encodeURIComponent("\"".concat(values, "\"")) : encodeURIComponent(values); +}; +/** + * Encode an object as querystring, values are encoded as + * URI components, keys are not. + * + * @function + * @private + */ + + +var encode = function encode(data) { + return Object.entries(data).map(function (_ref) { + var _ref2 = (0, _slicedToArray2.default)(_ref, 2), + k = _ref2[0], + v = _ref2[1]; + + var encodedValue = encodeValues(v); + return "".concat(k, "=").concat(encodedValue); + }).join('&'); +}; +/** + * Returns a URL from base url and a query parameter object. + * Any undefined parameter is removed. + * + * @function + * @private + */ + + +exports.encode = encode; + +var buildURL = function buildURL(url, params) { + var qs = encode((0, _pickBy.default)(params)); + + if (qs) { + return "".concat(url, "?").concat(qs); + } else { + return url; + } +}; +exports.buildURL = buildURL; /***/ }), -/* 664 */ +/* 660 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var basePick = __webpack_require__(665), - flatRest = __webpack_require__(620); +var arrayMap = __webpack_require__(410), + baseIteratee = __webpack_require__(413), + basePickBy = __webpack_require__(661), + getAllKeysIn = __webpack_require__(588); /** - * Creates an object composed of the picked `object` properties. + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). * * @static - * @since 0.1.0 * @memberOf _ + * @since 4.0.0 * @category Object * @param {Object} object The source object. - * @param {...(string|string[])} [paths] The property paths to pick. + * @param {Function} [predicate=_.identity] The function invoked per property. * @returns {Object} Returns the new object. * @example * * var object = { 'a': 1, 'b': '2', 'c': 3 }; * - * _.pick(object, ['a', 'c']); + * _.pickBy(object, _.isNumber); * // => { 'a': 1, 'c': 3 } */ -var pick = flatRest(function(object, paths) { - return object == null ? {} : basePick(object, paths); -}); +function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = baseIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); +} -module.exports = pick; +module.exports = pickBy; /***/ }), -/* 665 */ +/* 661 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var basePickBy = __webpack_require__(649), - hasIn = __webpack_require__(456); +var baseGet = __webpack_require__(371), + baseSet = __webpack_require__(662), + castPath = __webpack_require__(372); /** - * The base implementation of `_.pick` without support for individual - * property identifiers. + * The base implementation of `_.pickBy` without support for iteratee shorthands. * * @private * @param {Object} object The source object. * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. * @returns {Object} Returns the new object. */ -function basePick(object, paths) { - return basePickBy(object, paths, function(value, path) { - return hasIn(object, path); - }); -} +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; -module.exports = basePick; + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; +} -/***/ }), -/* 666 */ -/***/ ((__unused_webpack_module, exports) => { +module.exports = basePickBy; -"use strict"; +/***/ }), +/* 662 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.getIllegalCharacters = void 0; +var assignValue = __webpack_require__(575), + castPath = __webpack_require__(372), + isIndex = __webpack_require__(448), + isObject = __webpack_require__(52), + toKey = __webpack_require__(411); /** - * Get the list of illegal characters in the file name + * The base implementation of `_.set`. * - * @public - * @param {string} name - the file name - * @returns {string} illegal characters separated by spaces + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. */ -var getIllegalCharacters = function getIllegalCharacters(name) { - var FILENAME_ILLEGAL_CHARACTERS = /\/|\x00|\n|\r/g; // eslint-disable-line no-control-regex +function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); - var match = name.match(FILENAME_ILLEGAL_CHARACTERS); - return match ? match.join(' ') : ''; -}; + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +module.exports = baseSet; -exports.getIllegalCharacters = getIllegalCharacters; /***/ }), -/* 667 */ +/* 663 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports.hasJobFinished = exports.normalizeJob = exports.JOBS_DOCTYPE = void 0; - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602)); +exports.FetchError = exports["default"] = void 0; -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(606)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var _Collection = _interopRequireDefault(__webpack_require__(600)); +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var _DocumentCollection = __webpack_require__(601); +var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664)); -var _utils = __webpack_require__(611); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -function _templateObject() { - var data = (0, _taggedTemplateLiteral2.default)(["/jobs/", ""]); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - _templateObject = function _templateObject() { - return data; - }; +var EXPIRED_TOKEN = /Expired token/; +var CLIENT_NOT_FOUND = /Client not found/; +var INVALID_TOKEN = /Invalid JWT token/; +var _default = { + EXPIRED_TOKEN: EXPIRED_TOKEN, + CLIENT_NOT_FOUND: CLIENT_NOT_FOUND, + INVALID_TOKEN: INVALID_TOKEN +}; +exports["default"] = _default; - return data; -} +var getWwwAuthenticateErrorMessage = function getWwwAuthenticateErrorMessage(response) { + var invalidTokenRegex = /invalid_token/; + var expiredTokenRegex = /access token expired/; + var wwwAuthenticateHeader = response.headers && response.headers.get('www-authenticate'); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + if (!wwwAuthenticateHeader) { + return undefined; + } -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + if (expiredTokenRegex.test(wwwAuthenticateHeader)) { + return 'Expired token'; + } -var JOBS_DOCTYPE = 'io.cozy.jobs'; -exports.JOBS_DOCTYPE = JOBS_DOCTYPE; + if (invalidTokenRegex.test(wwwAuthenticateHeader)) { + return 'Invalid token'; + } -var sleep = function sleep(delay) { - return new Promise(function (resolve) { - return setTimeout(resolve, delay); - }); + return undefined; }; -var normalizeJob = function normalizeJob(job) { - return _objectSpread(_objectSpread(_objectSpread({}, job), (0, _DocumentCollection.normalizeDoc)(job, JOBS_DOCTYPE)), job.attributes); -}; +var FetchError = /*#__PURE__*/function (_Error) { + (0, _inherits2.default)(FetchError, _Error); -exports.normalizeJob = normalizeJob; + var _super = _createSuper(FetchError); -var hasJobFinished = function hasJobFinished(job) { - return job.state === 'done' || job.state === 'errored'; -}; -/** - * Document representing a io.cozy.jobs - * - * @typedef {object} JobDocument - * @property {string} _id - Id of the job - * @property {string} attributes.state - state of the job. Can be 'errored', 'running', 'queued', 'done' - * @property {string} attributes.error - Error message of the job if any - */ + function FetchError(response, reason) { + var _this; + (0, _classCallCheck2.default)(this, FetchError); + _this = _super.call(this); -exports.hasJobFinished = hasJobFinished; + if (Error.captureStackTrace) { + Error.captureStackTrace((0, _assertThisInitialized2.default)(_this), _this.constructor); + } // WARN We have to hardcode this because babel doesn't play nice when extending Error -var JobCollection = /*#__PURE__*/function () { - function JobCollection(stackClient) { - (0, _classCallCheck2.default)(this, JobCollection); - this.stackClient = stackClient; + + _this.name = 'FetchError'; + _this.response = response; + _this.url = response.url; + _this.status = response.status; + _this.reason = reason; + var wwwAuthenticateErrorMessage = getWwwAuthenticateErrorMessage(response); + Object.defineProperty((0, _assertThisInitialized2.default)(_this), 'message', { + value: reason.message || wwwAuthenticateErrorMessage || (typeof reason === 'string' ? reason : JSON.stringify(reason)) + }); + return _this; } - (0, _createClass2.default)(JobCollection, [{ - key: "queued", - value: function queued(workerType) { - return this.stackClient.fetchJSON('GET', "/jobs/queue/".concat(workerType)); - } - /** - * Creates a job - * - * @param {string} workerType - Ex: "konnector" - * @param {object} [args={}] - Ex: {"slug": "my-konnector", "trigger": "trigger-id"} - * @param {object} [options={}] - creation options - * @param {boolean} [manual=false] - Manual execution - * @returns {object} createdJob - */ + return FetchError; +}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); - }, { - key: "create", - value: function create(workerType) { - var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var manual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - return this.stackClient.fetchJSON('POST', "/jobs/queue/".concat(workerType), { - data: { - type: JOBS_DOCTYPE, - attributes: { - arguments: args, - options: options, - manual: manual - } - } - }); +exports.FetchError = FetchError; + +/***/ }), +/* 664 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getPrototypeOf = __webpack_require__(607); + +var setPrototypeOf = __webpack_require__(604); + +var isNativeFunction = __webpack_require__(665); + +var construct = __webpack_require__(666); + +function _wrapNativeSuper(Class) { + var _cache = typeof Map === "function" ? new Map() : undefined; + + module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) { + if (Class === null || !isNativeFunction(Class)) return Class; + + if (typeof Class !== "function") { + throw new TypeError("Super expression must either be null or a function"); } - /** - * Return a normalized job, given its id - * - * @param {string} id - id of the job - * @returns {JobDocument} - */ - }, { - key: "get", - value: function () { - var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(id) { - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - return _context.abrupt("return", _Collection.default.get(this.stackClient, (0, _utils.uri)(_templateObject(), id), { - normalize: normalizeJob - })); + if (typeof _cache !== "undefined") { + if (_cache.has(Class)) return _cache.get(Class); - case 1: - case "end": - return _context.stop(); - } - } - }, _callee, this); - })); + _cache.set(Class, Wrapper); + } - function get(_x) { - return _get.apply(this, arguments); + function Wrapper() { + return construct(Class, arguments, getPrototypeOf(this).constructor); + } + + Wrapper.prototype = Object.create(Class.prototype, { + constructor: { + value: Wrapper, + enumerable: false, + writable: true, + configurable: true } + }); + return setPrototypeOf(Wrapper, Class); + }; - return get; - }() - /** - * Update the job's state - * This does work only for jobs comming from @client triggers - * - * @param {JobDocument} job - io.cozy.jobs document - */ + module.exports["default"] = module.exports, module.exports.__esModule = true; + return _wrapNativeSuper(Class); +} - }, { - key: "update", - value: function () { - var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(job) { - var jobResult; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - if (!(job.worker !== 'client')) { - _context2.next = 2; - break; - } +module.exports = _wrapNativeSuper; +module.exports["default"] = module.exports, module.exports.__esModule = true; - throw new Error("JobCollection.update only works for client workers. ".concat(job.worker, " given")); +/***/ }), +/* 665 */ +/***/ ((module) => { - case 2: - _context2.next = 4; - return this.stackClient.fetchJSON('PATCH', "/jobs/".concat(job._id), { - data: { - type: JOBS_DOCTYPE, - id: job._id, - attributes: { - state: job.attributes.state, - error: job.attributes.error - } - } - }); +function _isNativeFunction(fn) { + return Function.toString.call(fn).indexOf("[native code]") !== -1; +} - case 4: - jobResult = _context2.sent; - return _context2.abrupt("return", normalizeJob(jobResult.data)); +module.exports = _isNativeFunction; +module.exports["default"] = module.exports, module.exports.__esModule = true; - case 6: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); +/***/ }), +/* 666 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - function update(_x2) { - return _update.apply(this, arguments); - } +var setPrototypeOf = __webpack_require__(604); - return update; - }() - /** - * Polls a job state until it is finished - * - * `options.until` can be used to tweak when to stop waiting. It will be - * given the current job state. If true is returned, the awaiting is - * stopped. - */ +var isNativeReflectConstruct = __webpack_require__(667); - }, { - key: "waitFor", - value: function () { - var _waitFor = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(id) { - var _ref, - _ref$onUpdate, - onUpdate, - _ref$until, - until, - _ref$delay, - delay, - _ref$timeout, - timeout, - start, - jobData, - now, - _args3 = arguments; +function _construct(Parent, args, Class) { + if (isNativeReflectConstruct()) { + module.exports = _construct = Reflect.construct; + module.exports["default"] = module.exports, module.exports.__esModule = true; + } else { + module.exports = _construct = function _construct(Parent, args, Class) { + var a = [null]; + a.push.apply(a, args); + var Constructor = Function.bind.apply(Parent, a); + var instance = new Constructor(); + if (Class) setPrototypeOf(instance, Class.prototype); + return instance; + }; - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - _ref = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {}, _ref$onUpdate = _ref.onUpdate, onUpdate = _ref$onUpdate === void 0 ? null : _ref$onUpdate, _ref$until = _ref.until, until = _ref$until === void 0 ? hasJobFinished : _ref$until, _ref$delay = _ref.delay, delay = _ref$delay === void 0 ? 5 * 1000 : _ref$delay, _ref$timeout = _ref.timeout, timeout = _ref$timeout === void 0 ? 60 * 5 * 1000 : _ref$timeout; - start = Date.now(); - _context3.next = 4; - return this.get(id); + module.exports["default"] = module.exports, module.exports.__esModule = true; + } - case 4: - jobData = _context3.sent.data.attributes; + return _construct.apply(null, arguments); +} - case 5: - if (!(!jobData || !until(jobData))) { - _context3.next = 17; - break; - } +module.exports = _construct; +module.exports["default"] = module.exports, module.exports.__esModule = true; - _context3.next = 8; - return sleep(delay); +/***/ }), +/* 667 */ +/***/ ((module) => { - case 8: - _context3.next = 10; - return this.get(id); +function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; - case 10: - jobData = _context3.sent.data.attributes; + try { + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); + return true; + } catch (e) { + return false; + } +} - if (onUpdate) { - onUpdate(jobData); - } +module.exports = _isNativeReflectConstruct; +module.exports["default"] = module.exports, module.exports.__esModule = true; - now = Date.now(); +/***/ }), +/* 668 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - if (!(start - now > timeout)) { - _context3.next = 15; - break; - } +"use strict"; - throw new Error('Timeout for JobCollection::waitFor'); - case 15: - _context3.next = 5; - break; +var _interopRequireDefault = __webpack_require__(524); - case 17: - return _context3.abrupt("return", jobData); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - case 18: - case "end": - return _context3.stop(); - } - } - }, _callee3, this); - })); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - function waitFor(_x3) { - return _waitFor.apply(this, arguments); - } +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - return waitFor; - }() +var AppToken = /*#__PURE__*/function () { + function AppToken(token) { + (0, _classCallCheck2.default)(this, AppToken); + this.token = token || ''; + } + + (0, _createClass2.default)(AppToken, [{ + key: "toAuthHeader", + value: function toAuthHeader() { + return 'Bearer ' + this.token; + } + }, { + key: "toBasicAuth", + value: function toBasicAuth() { + return "user:".concat(this.token, "@"); + } + /** + * Get the app token string + * + * @see CozyStackClient.getAccessToken + * @returns {string} token + */ + + }, { + key: "getAccessToken", + value: function getAccessToken() { + return this.token; + } }]); - return JobCollection; + return AppToken; }(); -var _default = JobCollection; -exports["default"] = _default; +exports["default"] = AppToken; /***/ }), -/* 668 */ +/* 669 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(524); + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); + +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); + +var AccessToken = /*#__PURE__*/function () { + function AccessToken(dataArg) { + (0, _classCallCheck2.default)(this, AccessToken); + var data = dataArg; + if (typeof data === 'string') data = JSON.parse(data); + this.tokenType = data.token_type || data.tokenType; + this.accessToken = data.access_token || data.accessToken; + this.refreshToken = data.refresh_token || data.refreshToken; + this.scope = data.scope; + } + + (0, _createClass2.default)(AccessToken, [{ + key: "toAuthHeader", + value: function toAuthHeader() { + return 'Bearer ' + this.accessToken; + } + }, { + key: "toBasicAuth", + value: function toBasicAuth() { + return "user:".concat(this.accessToken, "@"); + } + }, { + key: "toJSON", + value: function toJSON() { + return { + tokenType: this.tokenType, + accessToken: this.accessToken, + refreshToken: this.refreshToken, + scope: this.scope + }; + } + }, { + key: "toString", + value: function toString() { + return JSON.stringify(this.toJSON()); + } + /** + * Get the access token string + * + * @see CozyStackClient.getAccessToken + * @returns {string} token + */ + + }, { + key: "getAccessToken", + value: function getAccessToken() { + return this.accessToken; + } + }]); + return AccessToken; +}(); + +exports["default"] = AccessToken; + +/***/ }), +/* 670 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireWildcard = __webpack_require__(510); +var _interopRequireWildcard = __webpack_require__(522); -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports.KONNECTORS_DOCTYPE = void 0; +exports["default"] = exports.isDirectory = exports.isFile = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(606)); -var _pick = _interopRequireDefault(__webpack_require__(664)); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -var _AppCollection2 = _interopRequireDefault(__webpack_require__(590)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var _TriggerCollection = _interopRequireWildcard(__webpack_require__(669)); +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var _DocumentCollection = __webpack_require__(601); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +var _lite = _interopRequireDefault(__webpack_require__(671)); -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +var _has = _interopRequireDefault(__webpack_require__(674)); -var KONNECTORS_DOCTYPE = 'io.cozy.konnectors'; -exports.KONNECTORS_DOCTYPE = KONNECTORS_DOCTYPE; +var _get = _interopRequireDefault(__webpack_require__(370)); -var KonnectorCollection = /*#__PURE__*/function (_AppCollection) { - (0, _inherits2.default)(KonnectorCollection, _AppCollection); +var _omit = _interopRequireDefault(__webpack_require__(625)); - var _super = _createSuper(KonnectorCollection); +var _pick = _interopRequireDefault(__webpack_require__(676)); - function KonnectorCollection(stackClient) { - var _this; +var _mangoIndex = __webpack_require__(657); - (0, _classCallCheck2.default)(this, KonnectorCollection); - _this = _super.call(this, stackClient); - _this.doctype = KONNECTORS_DOCTYPE; - _this.endpoint = '/konnectors/'; - return _this; - } +var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613)); - (0, _createClass2.default)(KonnectorCollection, [{ - key: "create", - value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - throw new Error('create() method is not available for konnectors'); +var _utils = __webpack_require__(623); - case 1: - case "end": - return _context.stop(); - } - } - }, _callee); - })); +var _errors = __webpack_require__(663); - function create() { - return _create.apply(this, arguments); - } +var _Collection = __webpack_require__(612); - return create; - }() - }, { - key: "destroy", - value: function () { - var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - throw new Error('destroy() method is not available for konnectors'); +var _getIllegalCharacter = __webpack_require__(678); - case 1: - case "end": - return _context2.stop(); - } - } - }, _callee2); - })); +var querystring = _interopRequireWildcard(__webpack_require__(659)); - function destroy() { - return _destroy.apply(this, arguments); - } +function _templateObject23() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/_changes"]); - return destroy; - }() - /** - * Find triggers for a particular konnector - * - * @param {string} slug of the konnector - */ + _templateObject23 = function _templateObject23() { + return data; + }; - }, { - key: "findTriggersBySlug", - value: function () { - var _findTriggersBySlug = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(slug) { - var triggerCol, _yield$triggerCol$all, rawTriggers; + return data; +} - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - triggerCol = new _TriggerCollection.default(this.stackClient); - _context3.next = 3; - return triggerCol.all({ - limit: null - }); +function _templateObject22() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]); - case 3: - _yield$triggerCol$all = _context3.sent; - rawTriggers = _yield$triggerCol$all.data; - return _context3.abrupt("return", rawTriggers.map(function (x) { - return x.attributes; - }).filter(function (triggerAttrs) { - return (0, _TriggerCollection.isForKonnector)(triggerAttrs, slug); - })); + _templateObject22 = function _templateObject22() { + return data; + }; + + return data; +} + +function _templateObject21() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]); + + _templateObject21 = function _templateObject21() { + return data; + }; + + return data; +} + +function _templateObject20() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/not_synchronizing"]); + + _templateObject20 = function _templateObject20() { + return data; + }; + + return data; +} - case 6: - case "end": - return _context3.stop(); - } - } - }, _callee3, this); - })); +function _templateObject19() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/versions"]); - function findTriggersBySlug(_x) { - return _findTriggersBySlug.apply(this, arguments); - } + _templateObject19 = function _templateObject19() { + return data; + }; - return findTriggersBySlug; - }() - /** - * Launch a trigger for a given konnector. - * - * @param {string} slug - * @param {object} options - * @param {object} options.accountId - Pinpoint the account that should be used, useful if the user - * has more than 1 account for 1 konnector - */ + return data; +} - }, { - key: "launch", - value: function () { - var _launch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(slug) { - var options, - triggerCol, - konnTriggers, - filteredTriggers, - filterAttrs, - _args4 = arguments; - return _regenerator.default.wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {}; - triggerCol = new _TriggerCollection.default(this.stackClient); - _context4.next = 4; - return this.findTriggersBySlug(slug); +function _templateObject18() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/upload/metadata"]); - case 4: - konnTriggers = _context4.sent; - filteredTriggers = options.accountId ? konnTriggers.filter(function (triggerAttrs) { - return (0, _TriggerCollection.isForAccount)(triggerAttrs, options.accountId); - }) : konnTriggers; + _templateObject18 = function _templateObject18() { + return data; + }; - if (!(filteredTriggers.length === 1)) { - _context4.next = 10; - break; - } + return data; +} - return _context4.abrupt("return", triggerCol.launch(konnTriggers[0])); +function _templateObject17() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); - case 10: - filterAttrs = JSON.stringify((0, _pick.default)({ - slug: slug, - accountId: options.accountId - })); + _templateObject17 = function _templateObject17() { + return data; + }; - if (!(filteredTriggers.length === 0)) { - _context4.next = 15; - break; - } + return data; +} - throw new Error("No trigger found for ".concat(filterAttrs)); +function _templateObject16() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=directory"]); - case 15: - if (!(filteredTriggers.length > 1)) { - _context4.next = 17; - break; - } + _templateObject16 = function _templateObject16() { + return data; + }; - throw new Error("More than 1 trigger found for ".concat(filterAttrs)); + return data; +} - case 17: - case "end": - return _context4.stop(); - } - } - }, _callee4, this); - })); +function _templateObject15() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/metadata?Path=", ""]); - function launch(_x2) { - return _launch.apply(this, arguments); - } + _templateObject15 = function _templateObject15() { + return data; + }; - return launch; - }() - /** - * Updates a konnector - * - * @param {string} slug - * @param {object} options - * @param {object} options.source - Specify the source (ex: registry://slug/stable) - * @param {boolean} options.sync - Wait for konnector to be updated, otherwise the job - * is just scheduled - */ + return data; +} - }, { - key: "update", - value: function () { - var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(slug) { - var options, - source, - sync, - reqOptions, - rawKonnector, - _args5 = arguments; - return _regenerator.default.wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {}; +function _templateObject14() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); - if (slug) { - _context5.next = 3; - break; - } + _templateObject14 = function _templateObject14() { + return data; + }; - throw new Error('Cannot call update with no slug'); + return data; +} - case 3: - source = options.source || null; - sync = options.sync || false; - reqOptions = sync ? { - headers: { - Accept: 'text/event-stream' - } - } : {}; - _context5.next = 8; - return this.stackClient.fetchJSON('PUT', "/konnectors/".concat(slug) + (source ? "?Source=".concat(source) : ''), reqOptions); +function _templateObject13() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?Path=", ""]); - case 8: - rawKonnector = _context5.sent; - return _context5.abrupt("return", (0, _DocumentCollection.normalizeDoc)(rawKonnector)); + _templateObject13 = function _templateObject13() { + return data; + }; - case 10: - case "end": - return _context5.stop(); - } - } - }, _callee5, this); - })); + return data; +} - function update(_x3) { - return _update.apply(this, arguments); - } +function _templateObject12() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?VersionId=", "&Filename=", ""]); - return update; - }() - }]); - return KonnectorCollection; -}(_AppCollection2.default); + _templateObject12 = function _templateObject12() { + return data; + }; -var _default = KonnectorCollection; -exports["default"] = _default; + return data; +} -/***/ }), -/* 669 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +function _templateObject11() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/downloads?Id=", "&Filename=", ""]); -"use strict"; + _templateObject11 = function _templateObject11() { + return data; + }; + return data; +} -var _interopRequireWildcard = __webpack_require__(510); +function _templateObject10() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=file&Executable=", "&Encrypted=", ""]); -var _interopRequireDefault = __webpack_require__(512); + _templateObject10 = function _templateObject10() { + return data; + }; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.isForAccount = exports.isForKonnector = exports.normalizeTrigger = exports.TRIGGERS_DOCTYPE = exports.JOBS_DOCTYPE = void 0; + return data; +} + +function _templateObject9() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/", "?Name=", "&Type=file&Executable=", "&Encrypted=", "&MetadataID=", "&Size=", ""]); + + _templateObject9 = function _templateObject9() { + return data; + }; -var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525)); + return data; +} -var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602)); +function _templateObject8() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + _templateObject8 = function _templateObject8() { + return data; + }; -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); + return data; +} -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +function _templateObject7() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/trash/", ""]); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + _templateObject7 = function _templateObject7() { + return data; + }; -var _get3 = _interopRequireDefault(__webpack_require__(670)); + return data; +} -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +function _templateObject6() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); + _templateObject6 = function _templateObject6() { + return data; + }; -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + return data; +} -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } -var _Collection = _interopRequireWildcard(__webpack_require__(600)); +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } -var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601)); +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } -var _JobCollection = __webpack_require__(667); +function _templateObject5() { + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]); -var _utils = __webpack_require__(611); + _templateObject5 = function _templateObject5() { + return data; + }; -var _errors = __webpack_require__(651); + return data; +} function _templateObject4() { - var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", "/launch"]); + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]); _templateObject4 = function _templateObject4() { return data; @@ -106503,7 +105256,7 @@ function _templateObject4() { } function _templateObject3() { - var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", ""]); + var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/relationships/referenced_by"]); _templateObject3 = function _templateObject3() { return data; @@ -106513,7 +105266,7 @@ function _templateObject3() { } function _templateObject2() { - var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", ""]); + var data = (0, _taggedTemplateLiteral2.default)(["/files/", "/relationships/referenced_by"]); _templateObject2 = function _templateObject2() { return data; @@ -106523,7 +105276,7 @@ function _templateObject2() { } function _templateObject() { - var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers"]); + var data = (0, _taggedTemplateLiteral2.default)(["/data/", "/", "/relationships/references"]); _templateObject = function _templateObject() { return data; @@ -106540,206 +105293,389 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var JOBS_DOCTYPE = 'io.cozy.jobs'; -exports.JOBS_DOCTYPE = JOBS_DOCTYPE; -var TRIGGERS_DOCTYPE = 'io.cozy.triggers'; -exports.TRIGGERS_DOCTYPE = TRIGGERS_DOCTYPE; +/** + * Cursor used for Mango queries pagination + * + * @typedef {Array<string>|string} ViewKey + * @typedef {string} DocId + * @typedef {Array<*> & {0: ViewKey, 1: DocId}} CouchDBViewCursor + */ -var normalizeTrigger = function normalizeTrigger(trigger) { - return _objectSpread(_objectSpread(_objectSpread({}, trigger), (0, _DocumentCollection2.normalizeDoc)(trigger, TRIGGERS_DOCTYPE)), trigger.attributes); +/** + * Attributes used for directory creation + * + * @typedef {object} DirectoryAttributes + * @property {string} dirId - Id of the parent directory. + * @property {boolean} name - Name of the created directory. + * @property {boolean} executable - Indicates whether the file will be executable. + */ + +/** + * Attributes used for file creation + * + * @typedef {object} FileAttributes + * @property {string} dirId - Id of the parent directory. + * @property {string} name - Name of the created file. + * @property {Date} lastModifiedDate - Can be used to set the last modified date of a file. + * @property {boolean} executable - Whether or not the file is executable + * @property {boolean} encrypted - Whether or not the file is client-side encrypted + * @property {object} metadata io.cozy.files.metadata to attach to the file + */ + +/** + * Document representing a io.cozy.files + * + * @typedef {object} FileDocument + * @property {string} _id - Id of the file + * @property {FileAttributes} attributes - Attributes of the file + */ + +/** + * Stream is not defined in a browser, but is on NodeJS environment + * + * @typedef {object} Stream + */ + +/** + * Document representing a io.cozy.oauth.clients + * + * @typedef {object} OAuthClient + * @property {string} _id - Id of the client + * @property {string} _type - Doctype of the client (i.e. io.cozy.oauth.clients) + */ +var ROOT_DIR_ID = 'io.cozy.files.root-dir'; +var CONTENT_TYPE_OCTET_STREAM = 'application/octet-stream'; +/** + * Normalize a file, adding document's doctype if needed + * + * @param {FileDocument} file - File to normalize + * @returns {FileDocument} normalized file + * @private + */ + +var normalizeFile = function normalizeFile(file) { + var _file$meta; + + return _objectSpread(_objectSpread(_objectSpread({}, (0, _DocumentCollection2.normalizeDoc)(file, 'io.cozy.files')), file.attributes), {}, { + _rev: file === null || file === void 0 ? void 0 : (_file$meta = file.meta) === null || _file$meta === void 0 ? void 0 : _file$meta.rev // Beware of JSON-API + + }); }; +/** + * Normalize references, expliciting _type and _id — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/ + * + * @param {Array<object>} references - The list of files referenced by a document to normalize + * @returns {Array<object>} the data attribute of the normalized references + * @private + */ -exports.normalizeTrigger = normalizeTrigger; -var isForKonnector = function isForKonnector(triggerAttrs, slug) { - return triggerAttrs.worker === 'konnector' && triggerAttrs.message.konnector == slug; +var normalizeReferences = function normalizeReferences(references) { + return references ? references.map(function (ref) { + return { + _type: ref.type, + _id: ref.id + }; + }) : []; }; +/** + * Sanitize the file name by trimming spaces + * + * @param {string} name - The file name to trim + * @returns {string} the trimmed file name + * @private + */ -exports.isForKonnector = isForKonnector; -var isForAccount = function isForAccount(triggerAttrs, accountId) { - return triggerAttrs.message.account == accountId; +var sanitizeFileName = function sanitizeFileName(name) { + return name && name.trim(); }; +/** + * Sanitize and validate the file name - throw errors according to case + * + * @param {string} name - The file name + * @returns {string} the trimmed safe file name + * @throws {Error} - explaining reason why file name is not valid + * @private + */ -exports.isForAccount = isForAccount; -var buildParamsUrl = function buildParamsUrl(worker, type) { - var urlParams = new URLSearchParams(); +var sanitizeAndValidateFileName = function sanitizeAndValidateFileName(name) { + var safeName = sanitizeFileName(name); - if (worker) { - if (Array.isArray(worker.$in)) { - urlParams.set('Worker', worker.$in.join(',')); - } else { - urlParams.set('Worker', worker); - } + if (typeof safeName !== 'string' || safeName === '') { + throw new Error('Missing name argument'); } - if (type) { - if (Array.isArray(type.$in)) { - urlParams.set('Type', type.$in.join(',')); - } else { - urlParams.set('Type', type); - } + if (name === '.' || name === '..') { + throw new Error("Invalid filename: ".concat(name)); } - return urlParams.toString(); + var illegalCharacters = (0, _getIllegalCharacter.getIllegalCharacters)(safeName); + + if (illegalCharacters.length) { + throw new Error("Invalid filename containing illegal character(s): ".concat(illegalCharacters)); + } + + return safeName; }; /** - * Implements `DocumentCollection` API along with specific methods for `io.cozy.triggers`. + * Returns true when parameter has type directory, file or has _type io.cozy.files + * + * @param {object} doc - The document whose type is checked + * @param {string} [doc._type] - The document's doctype + * @param {'directory'|'file'} [doc.type] - The io.cozy-files document type + * + * @returns {boolean} true when objects has type directory, file or has _type io.cozy.files or false */ -var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(TriggerCollection, _DocumentCollection); +var isFile = function isFile(_ref) { + var _type = _ref._type, + type = _ref.type; + return _type === 'io.cozy.files' || type === 'directory' || type === 'file'; +}; +/** + * Returns true when parameters has type directory + * + * @param {string} type - The type of the file + * @returns {boolean} true when parameters has type directory or false + */ - var _super = _createSuper(TriggerCollection); - function TriggerCollection(stackClient) { - (0, _classCallCheck2.default)(this, TriggerCollection); - return _super.call(this, TRIGGERS_DOCTYPE, stackClient); +exports.isFile = isFile; + +var isDirectory = function isDirectory(_ref2) { + var type = _ref2.type; + return type === 'directory'; +}; + +exports.isDirectory = isDirectory; + +var raceWithCondition = function raceWithCondition(promises, predicate) { + return new Promise(function (resolve) { + promises.forEach(function (p) { + return p.then(function (res) { + if (predicate(res)) { + resolve(true); + } + }); + }); + Promise.all(promises).then(function () { + return resolve(false); + }); + }); +}; + +var dirName = function dirName(path) { + var lastIndex = path.lastIndexOf('/'); + return path.substring(0, lastIndex); +}; +/** + * Implements `DocumentCollection` API along with specific methods for + * `io.cozy.files`. + * + * Files are a special type of documents and are handled differently by the stack: + * special routes are to be used, and there is a notion of referenced files, aka + * files associated to a specific document + */ + + +var FileCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(FileCollection, _DocumentCollection); + + var _super = _createSuper(FileCollection); + + function FileCollection(doctype, stackClient) { + var _this; + + (0, _classCallCheck2.default)(this, FileCollection); + _this = _super.call(this, doctype, stackClient); + (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "extractResponseLinkRelated", function (res) { + var href = res.links && res.links.related; + if (!href) throw new Error('No related link in server response'); + return _this.stackClient.fullpath(href); + }); + (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "forceFileDownload", function (href, filename) { + var element = document.createElement('a'); + element.setAttribute('href', href); + element.setAttribute('download', filename); + element.style.display = 'none'; + document.body.appendChild(element); + element.click(); + document.body.removeChild(element); + }); + _this.specialDirectories = {}; + return _this; } /** - * Get the list of triggers. + * Fetches the file's data * - * @see https://docs.cozy.io/en/cozy-stack/jobs/#get-jobstriggers - * @param {{Worker}} options The fetch options: Worker allow to filter only triggers associated with a specific worker. - * @returns {{data}} The JSON API conformant response. - * @throws {FetchError} + * @param {string} id File id + * @returns {{data, included}} Information about the file or folder and it's descendents */ - (0, _createClass2.default)(TriggerCollection, [{ - key: "all", + (0, _createClass2.default)(FileCollection, [{ + key: "get", + value: function get(id) { + return this.statById(id); + } + }, { + key: "fetchFindFiles", value: function () { - var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { - var options, - resp, - _args = arguments; + var _fetchFindFiles = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(selector, options) { return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: - options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}; - _context.prev = 1; - _context.next = 4; - return this.stackClient.fetchJSON('GET', "/jobs/triggers"); - - case 4: - resp = _context.sent; - return _context.abrupt("return", { - data: resp.data.map(function (row) { - return normalizeTrigger(row, TRIGGERS_DOCTYPE); - }), - meta: { - count: resp.data.length - }, - next: false, - skip: 0 - }); - - case 8: - _context.prev = 8; - _context.t0 = _context["catch"](1); - return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0)); + return _context.abrupt("return", this.stackClient.fetchJSON('POST', '/files/_find', this.toMangoOptions(selector, options))); - case 11: + case 1: case "end": return _context.stop(); } } - }, _callee, this, [[1, 8]]); + }, _callee, this); })); - function all() { - return _all.apply(this, arguments); + function fetchFindFiles(_x, _x2) { + return _fetchFindFiles.apply(this, arguments); } - return all; + return fetchFindFiles; }() /** - * Creates a Trigger document + * Returns a filtered list of documents using a Mango selector. * - * @see https://docs.cozy.io/en/cozy-stack/jobs/#post-jobstriggers - * @param {object} attributes Trigger's attributes - * @returns {object} Stack response, containing trigger document under `data` attribute. + * The returned documents are paginated by the stack. + * + * @param {object} selector The Mango selector. + * @param {MangoQueryOptions} options The query options + * + * @returns {{data, meta, skip, next, bookmark}} The JSON API conformant response. + * @throws {FetchError} */ }, { - key: "create", + key: "find", value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(attributes) { - var path, resp; + var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(selector) { + var options, + _options$skip, + skip, + resp, + path, + nextLink, + nextLinkURL, + nextBookmark, + _args2 = arguments; + return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: - path = (0, _utils.uri)(_templateObject()); - _context2.next = 3; - return this.stackClient.fetchJSON('POST', path, { - data: { - attributes: attributes - } - }); + options = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {}; + _options$skip = options.skip, skip = _options$skip === void 0 ? 0 : _options$skip; + _context2.prev = 2; + path = '/files/_find'; + _context2.next = 6; + return this.findWithMango(path, selector, options); - case 3: + case 6: resp = _context2.sent; + _context2.next = 12; + break; + + case 9: + _context2.prev = 9; + _context2.t0 = _context2["catch"](2); + return _context2.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context2.t0)); + + case 12: + nextLink = (0, _get.default)(resp, 'links.next', ''); + nextLinkURL = new URL("".concat(this.stackClient.uri).concat(nextLink)); + nextBookmark = nextLinkURL.searchParams.get('page[cursor]'); return _context2.abrupt("return", { - data: normalizeTrigger(resp.data) + data: resp.data.map(function (f) { + return normalizeFile(f); + }), + meta: resp.meta, + next: resp.meta.count > skip + resp.data.length, + skip: skip, + bookmark: nextBookmark || undefined, + execution_stats: resp.meta.execution_stats }); - case 5: + case 16: case "end": return _context2.stop(); } } - }, _callee2, this); + }, _callee2, this, [[2, 9]]); })); - function create(_x) { - return _create.apply(this, arguments); + function find(_x3) { + return _find.apply(this, arguments); } - return create; + return find; }() /** - * Deletes a trigger + * async findReferencedBy - Returns the list of files referenced by a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/ * - * @see https://docs.cozy.io/en/cozy-stack/jobs/#delete-jobstriggerstrigger-id - * @param {object} document The trigger to delete — must have an _id field - * @returns {object} The deleted document + * @param {object} document A JSON representing a document, with at least a `_type` and `_id` field. + * @param {object} options Additional options + * @param {number|null} [options.skip] For skip-based pagination, the number of referenced files to skip. + * @param {number|null} [options.limit] For pagination, the number of results to return. + * @param {CouchDBViewCursor|null} [options.cursor] For cursor-based pagination, the index cursor. + * @returns {{data, included, meta, skip, next, bookmark}} The JSON API conformant response. */ }, { - key: "destroy", + key: "findReferencedBy", value: function () { - var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document) { - var _id; + var _findReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document) { + var _ref3, + _ref3$skip, + skip, + limit, + cursor, + params, + path, + url, + resp, + _args3 = arguments; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: - _id = document._id; - - if (_id) { - _context3.next = 3; - break; - } - - throw new Error('TriggerCollection.destroy needs a document with an _id'); - - case 3: - _context3.next = 5; - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject2(), _id)); + _ref3 = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {}, _ref3$skip = _ref3.skip, skip = _ref3$skip === void 0 ? 0 : _ref3$skip, limit = _ref3.limit, cursor = _ref3.cursor; + params = { + include: 'files', + 'page[limit]': limit, + 'page[cursor]': cursor, + sort: 'datetime' + }; + path = (0, _utils.uri)(_templateObject(), document._type, document._id); + url = querystring.buildURL(path, params); + _context3.next = 6; + return this.stackClient.fetchJSON('GET', url); - case 5: + case 6: + resp = _context3.sent; return _context3.abrupt("return", { - data: normalizeTrigger(_objectSpread(_objectSpread({}, document), {}, { - _deleted: true - })) + data: normalizeReferences(resp.data), + included: resp.included ? resp.included.map(function (f) { + return normalizeFile(f); + }) : [], + next: (0, _has.default)(resp, 'links.next'), + meta: resp.meta, + skip: skip }); - case 6: + case 8: case "end": return _context3.stop(); } @@ -106747,110 +105683,107 @@ var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) { }, _callee3, this); })); - function destroy(_x2) { - return _destroy.apply(this, arguments); + function findReferencedBy(_x4) { + return _findReferencedBy.apply(this, arguments); } - return destroy; + return findReferencedBy; }() /** + * Add referenced_by documents to a file — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#post-filesfile-idrelationshipsreferenced_by * - * Be warned, ATM /jobs/triggers does not return the same informations - * than /data/io.cozy.triggers (used by the super.find method). - * - * See https://github.com/cozy/cozy-stack/pull/2010 + * For example, to have an album referenced by a file: + * ``` + * addReferencedBy({_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}, [{_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}]) + * ``` * - * @param {object} selector - Which kind of worker {konnector,service} - * @param {object} options - Options - * @returns {{data, meta, skip, next}} The JSON API conformant response. - * @throws {FetchError} + * @param {FileDocument} document A JSON representing the file + * @param {Array} documents An array of JSON documents having a `_type` and `_id` field. + * @returns {{data, meta}} The JSON API conformant response. */ }, { - key: "find", + key: "addReferencedBy", value: function () { - var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() { - var selector, - options, - worker, - type, - rest, - hasOnlyWorkerAndType, - url, - resp, - _args4 = arguments; + var _addReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(document, documents) { + var refs, resp; return _regenerator.default.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: - selector = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {}; - options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {}; - worker = selector.worker, type = selector.type, rest = (0, _objectWithoutProperties2.default)(selector, ["worker", "type"]); - hasOnlyWorkerAndType = Object.keys(rest).length === 0; - - if (!hasOnlyWorkerAndType) { - _context4.next = 18; - break; - } - - // @see https://github.com/cozy/cozy-stack/blob/master/docs/jobs.md#get-jobstriggers - url = "/jobs/triggers?".concat(buildParamsUrl(worker, type)); - _context4.prev = 6; - _context4.next = 9; - return this.stackClient.fetchJSON('GET', url); + refs = documents.map(function (d) { + return { + id: d._id, + type: d._type + }; + }); + _context4.next = 3; + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject2(), document._id), { + data: refs + }); - case 9: + case 3: resp = _context4.sent; return _context4.abrupt("return", { - data: resp.data.map(function (row) { - return normalizeTrigger(row, TRIGGERS_DOCTYPE); - }), - meta: { - count: resp.data.length - }, - next: false, - skip: 0 + data: normalizeReferences(resp.data), + meta: resp.meta }); - case 13: - _context4.prev = 13; - _context4.t0 = _context4["catch"](6); - return _context4.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context4.t0)); - - case 16: - _context4.next = 19; - break; - - case 18: - return _context4.abrupt("return", (0, _get3.default)((0, _getPrototypeOf2.default)(TriggerCollection.prototype), "find", this).call(this, selector, options)); - - case 19: + case 5: case "end": return _context4.stop(); } } - }, _callee4, this, [[6, 13]]); + }, _callee4, this); })); - function find() { - return _find.apply(this, arguments); + function addReferencedBy(_x5, _x6) { + return _addReferencedBy.apply(this, arguments); } - return find; + return addReferencedBy; }() + /** + * Remove referenced_by documents from a file — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#delete-filesfile-idrelationshipsreferenced_by + * + * For example, to remove an album reference from a file: + * ``` + * removeReferencedBy({_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}, [{_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}]) + * ``` + * + * @param {object} document A JSON representing the file + * @param {Array} documents An array of JSON documents having a `_type` and `_id` field. + * @returns {{data, meta}} The JSON API conformant response. + */ + }, { - key: "get", + key: "removeReferencedBy", value: function () { - var _get2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(id) { + var _removeReferencedBy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(document, documents) { + var refs, resp; return _regenerator.default.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: - return _context5.abrupt("return", _Collection.default.get(this.stackClient, (0, _utils.uri)(_templateObject3(), id), { - normalize: normalizeTrigger - })); + refs = documents.map(function (d) { + return { + id: d._id, + type: d._type + }; + }); + _context5.next = 3; + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject3(), document._id), { + data: refs + }); - case 1: + case 3: + resp = _context5.sent; + return _context5.abrupt("return", { + data: normalizeReferences(resp.data), + meta: resp.meta + }); + + case 5: case "end": return _context5.stop(); } @@ -106858,40 +105791,46 @@ var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) { }, _callee5, this); })); - function get(_x3) { - return _get2.apply(this, arguments); + function removeReferencedBy(_x7, _x8) { + return _removeReferencedBy.apply(this, arguments); } - return get; + return removeReferencedBy; }() /** - * Force given trigger execution. + * Add files references to a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#post-datatypedoc-idrelationshipsreferences * - * @see https://docs.cozy.io/en/cozy-stack/jobs/#post-jobstriggerstrigger-idlaunch - * @param {object} trigger Trigger to launch - * @returns {object} Stack response, containing job launched by trigger, under `data` attribute. + * For example, to add a photo to an album: + * ``` + * addReferencesTo({_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}, [{_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}]) + * ``` + * + * @param {object} document A JSON representing a document, with at least a `_type` and `_id` field. + * @param {Array} documents An array of JSON files having an `_id` field. + * + * Returns 204 No Content */ }, { - key: "launch", + key: "addReferencesTo", value: function () { - var _launch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(trigger) { - var path, resp; + var _addReferencesTo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(document, documents) { + var refs; return _regenerator.default.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: - path = (0, _utils.uri)(_templateObject4(), trigger._id); - _context6.next = 3; - return this.stackClient.fetchJSON('POST', path); - - case 3: - resp = _context6.sent; - return _context6.abrupt("return", { - data: (0, _JobCollection.normalizeJob)(resp.data) + refs = documents.map(function (d) { + return { + id: d._id, + type: 'io.cozy.files' + }; }); + return _context6.abrupt("return", this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject4(), document._type, document._id), { + data: refs + })); - case 5: + case 2: case "end": return _context6.stop(); } @@ -106899,1640 +105838,2107 @@ var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) { }, _callee6, this); })); - function launch(_x4) { - return _launch.apply(this, arguments); + function addReferencesTo(_x9, _x10) { + return _addReferencesTo.apply(this, arguments); } - return launch; + return addReferencesTo; }() + /** + * Remove files references to a document — see https://docs.cozy.io/en/cozy-stack/references-docs-in-vfs/#delete-datatypedoc-idrelationshipsreferences + * + * For example, to remove a photo from an album: + * ``` + * removeReferencesTo({_id: 456, _type: "io.cozy.photos.albums", name: "Happy Cloud"}, [{_id: 123, _type: "io.cozy.files", name: "cozy.jpg"}]) + * ``` + * + * @param {object} document A JSON representing a document, with at least a `_type` and `_id` field. + * @param {Array} documents An array of JSON files having an `_id` field. + * + * Returns 204 No Content + */ + }, { - key: "update", + key: "removeReferencesTo", value: function () { - var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7() { + var _removeReferencesTo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(document, documents) { + var refs; return _regenerator.default.wrap(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: - throw new Error('update() method is not available for triggers'); + refs = documents.map(function (d) { + return { + id: d._id, + type: 'io.cozy.files' + }; + }); + return _context7.abrupt("return", this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject5(), document._type, document._id), { + data: refs + })); - case 1: + case 2: case "end": return _context7.stop(); } } - }, _callee7); + }, _callee7, this); })); - function update() { - return _update.apply(this, arguments); + function removeReferencesTo(_x11, _x12) { + return _removeReferencesTo.apply(this, arguments); } - return update; + return removeReferencesTo; }() - }]); - return TriggerCollection; -}(_DocumentCollection2.default); - -TriggerCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; -var _default = TriggerCollection; -exports["default"] = _default; - -/***/ }), -/* 670 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var superPropBase = __webpack_require__(671); - -function _get(target, property, receiver) { - if (typeof Reflect !== "undefined" && Reflect.get) { - module.exports = _get = Reflect.get; - module.exports["default"] = module.exports, module.exports.__esModule = true; - } else { - module.exports = _get = function _get(target, property, receiver) { - var base = superPropBase(target, property); - if (!base) return; - var desc = Object.getOwnPropertyDescriptor(base, property); - - if (desc.get) { - return desc.get.call(receiver); - } - - return desc.value; - }; - - module.exports["default"] = module.exports, module.exports.__esModule = true; - } - - return _get(target, property, receiver || target); -} - -module.exports = _get; -module.exports["default"] = module.exports, module.exports.__esModule = true; - -/***/ }), -/* 671 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var getPrototypeOf = __webpack_require__(595); - -function _superPropBase(object, property) { - while (!Object.prototype.hasOwnProperty.call(object, property)) { - object = getPrototypeOf(object); - if (object === null) break; - } - - return object; -} - -module.exports = _superPropBase; -module.exports["default"] = module.exports, module.exports.__esModule = true; - -/***/ }), -/* 672 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireWildcard = __webpack_require__(510); - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.getSharingRules = exports.BITWARDEN_CIPHERS_DOCTYPE = exports.BITWARDEN_ORGANIZATIONS_DOCTYPE = exports.SHARING_DOCTYPE = void 0; - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); - -var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602)); - -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); - -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); - -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); - -var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601)); - -var _FileCollection = __webpack_require__(658); - -var _utils = __webpack_require__(611); - -function _templateObject6() { - var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients"]); - - _templateObject6 = function _templateObject6() { - return data; - }; - - return data; -} - -function _templateObject5() { - var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients/self"]); - - _templateObject5 = function _templateObject5() { - return data; - }; - - return data; -} - -function _templateObject4() { - var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients/", ""]); - - _templateObject4 = function _templateObject4() { - return data; - }; - - return data; -} - -function _templateObject3() { - var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients"]); - - _templateObject3 = function _templateObject3() { - return data; - }; - - return data; -} - -function _templateObject2() { - var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", ""]); + /** + * Sends file to trash and removes references to it + * + * @param {FileDocument} file - File that will be sent to trash + * @returns {Promise} - Resolves when references have been removed + * and file has been sent to trash + */ - _templateObject2 = function _templateObject2() { - return data; - }; + }, { + key: "destroy", + value: function () { + var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(file) { + var _ref4, + _ref4$ifMatch, + ifMatch, + _id, + relationships, + _iterator, + _step, + ref, + resp, + _args8 = arguments; - return data; -} + return _regenerator.default.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + _ref4 = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {}, _ref4$ifMatch = _ref4.ifMatch, ifMatch = _ref4$ifMatch === void 0 ? '' : _ref4$ifMatch; + _id = file._id, relationships = file.relationships; -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + if (!(relationships && relationships.referenced_by && Array.isArray(relationships.referenced_by.data))) { + _context8.next = 20; + break; + } -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + _iterator = _createForOfIteratorHelper(relationships.referenced_by.data); + _context8.prev = 4; -function _templateObject() { - var data = (0, _taggedTemplateLiteral2.default)(["/sharings/doctype/", ""]); + _iterator.s(); - _templateObject = function _templateObject() { - return data; - }; + case 6: + if ((_step = _iterator.n()).done) { + _context8.next = 12; + break; + } - return data; -} + ref = _step.value; + _context8.next = 10; + return this.removeReferencesTo({ + _id: ref.id, + _type: ref.type + }, [{ + _id: _id + }]); -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } + case 10: + _context8.next = 6; + break; -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + case 12: + _context8.next = 17; + break; -var SHARING_DOCTYPE = 'io.cozy.sharings'; -exports.SHARING_DOCTYPE = SHARING_DOCTYPE; -var BITWARDEN_ORGANIZATIONS_DOCTYPE = 'com.bitwarden.organizations'; -exports.BITWARDEN_ORGANIZATIONS_DOCTYPE = BITWARDEN_ORGANIZATIONS_DOCTYPE; -var BITWARDEN_CIPHERS_DOCTYPE = 'com.bitwarden.ciphers'; -exports.BITWARDEN_CIPHERS_DOCTYPE = BITWARDEN_CIPHERS_DOCTYPE; + case 14: + _context8.prev = 14; + _context8.t0 = _context8["catch"](4); -var normalizeSharing = function normalizeSharing(sharing) { - return (0, _DocumentCollection2.normalizeDoc)(sharing, SHARING_DOCTYPE); -}; -/** - * @typedef {object} Rule A sharing rule - * @property {string} title - * @property {string} doctype - * @property {Array} values - * @property {string=} add - * @property {string=} update - * @property {string=} remove - */ + _iterator.e(_context8.t0); -/** - * @typedef {object} Recipient An io.cozy.contact - */ + case 17: + _context8.prev = 17; -/** - * @typedef {object} Sharing An io.cozy.sharings document - */ + _iterator.f(); -/** - * @typedef {object} SharingPolicy Define the add/update/remove policies for a sharing - * @property {string} add - * @property {string} update - * @property {string} remove - */ + return _context8.finish(17); -/** - * @typedef {(undefined|'one-way'|'two-way')} SharingType Define how a document is synced between sharing's owner and receivers. - */ + case 20: + _context8.next = 22; + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), _id), undefined, { + headers: { + 'If-Match': ifMatch + } + }); -/** - * @typedef {object} RelationshipItem Define a recipient that can be used as target of a sharing - * @property {string} id - Recipient's ID - * @property {string} type - Reciptient's type (should be 'io.cozy.contacts') - */ + case 22: + resp = _context8.sent; + return _context8.abrupt("return", { + data: normalizeFile(resp.data) + }); -/** - * Implements the `DocumentCollection` API along with specific methods for - * `io.cozy.sharings`. - */ + case 24: + case "end": + return _context8.stop(); + } + } + }, _callee8, this, [[4, 14, 17, 20]]); + })); + function destroy(_x13) { + return _destroy.apply(this, arguments); + } -var SharingCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(SharingCollection, _DocumentCollection); + return destroy; + }() + /** + * Empty the Trash + */ - var _super = _createSuper(SharingCollection); + }, { + key: "emptyTrash", + value: function emptyTrash() { + return this.stackClient.fetchJSON('DELETE', '/files/trash'); + } + /** + * Restores a trashed file. + * + * @param {string} id - The file's id + * @returns {Promise} - A promise that returns the restored file if resolved. + * @throws {FetchError} + * + */ - function SharingCollection() { - (0, _classCallCheck2.default)(this, SharingCollection); - return _super.apply(this, arguments); - } + }, { + key: "restore", + value: function restore(id) { + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject7(), id)); + } + /** + * async deleteFilePermanently - Definitely delete a file + * + * @param {string} id - The id of the file to delete + * @returns {object} The deleted file object + */ - (0, _createClass2.default)(SharingCollection, [{ - key: "findByDoctype", + }, { + key: "deleteFilePermanently", value: function () { - var _findByDoctype = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(doctype) { + var _deleteFilePermanently = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(id) { var resp; - return _regenerator.default.wrap(function _callee$(_context) { + return _regenerator.default.wrap(function _callee9$(_context9) { while (1) { - switch (_context.prev = _context.next) { + switch (_context9.prev = _context9.next) { case 0: - _context.next = 2; - return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject(), doctype)); + _context9.next = 2; + return this.stackClient.fetchJSON('PATCH', (0, _utils.uri)(_templateObject8(), id), { + data: { + type: 'io.cozy.files', + id: id, + attributes: { + permanent_delete: true + } + } + }); case 2: - resp = _context.sent; - return _context.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { - data: resp.data.map(normalizeSharing) - })); + resp = _context9.sent; + return _context9.abrupt("return", resp.data); case 4: case "end": - return _context.stop(); + return _context9.stop(); } } - }, _callee, this); + }, _callee9, this); })); - function findByDoctype(_x) { - return _findByDoctype.apply(this, arguments); + function deleteFilePermanently(_x14) { + return _deleteFilePermanently.apply(this, arguments); } - return findByDoctype; + return deleteFilePermanently; }() /** - * Fetches a sharing by id - * - * @param {string} id Sharing's id - * @returns {Sharing} sharing + * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded + * @param {string} dirPath Path to upload the file to. ie : /Administative/XXX/ + * @returns {object} Created io.cozy.files */ }, { - key: "get", + key: "upload", value: function () { - var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) { - var path, resp; - return _regenerator.default.wrap(function _callee2$(_context2) { + var _upload = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(data, dirPath) { + var dirId; + return _regenerator.default.wrap(function _callee10$(_context10) { while (1) { - switch (_context2.prev = _context2.next) { + switch (_context10.prev = _context10.next) { case 0: - path = (0, _utils.uri)(_templateObject2(), id); - _context2.next = 3; - return this.stackClient.fetchJSON('GET', path); + _context10.next = 2; + return this.ensureDirectoryExists(dirPath); - case 3: - resp = _context2.sent; - return _context2.abrupt("return", { - data: normalizeSharing(resp.data) - }); + case 2: + dirId = _context10.sent; + return _context10.abrupt("return", this.createFile(data, { + dirId: dirId + })); - case 5: + case 4: case "end": - return _context2.stop(); + return _context10.stop(); } } - }, _callee2, this); + }, _callee10, this); })); - function get(_x2) { - return _get.apply(this, arguments); + function upload(_x15, _x16) { + return _upload.apply(this, arguments); } - return get; + return upload; }() /** + * Creates directory or file. + * - Used by StackLink to support CozyClient.create('io.cozy.files', options) * - * Creates a new Sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#post-sharings - * - * @param {object} params Sharing params - * @param {Sharing} params.document The document to share - * @param {string} params.description Description of the sharing - * @param {string=} params.previewPath The preview path - * @param {Array<Rule>=} params.rules The rules defined to the sharing. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing - * @param {Array<Recipient>=} params.recipients Recipients to add to the sharings (will have the same permissions given by the rules defined by the sharing ) - * @param {Array<Recipient>=} params.readOnlyRecipients Recipients to add to the sharings with only read only access - * @param {boolean=} params.openSharing If someone else than the owner can add a recipient to the sharing - * @param {string=} params.appSlug Slug of the targeted app + * @param {FileAttributes|DirectoryAttributes} attributes - Attributes of the created file/directory + * @param {File|Blob|string|ArrayBuffer} attributes.data Will be used as content of the created file + * @throws {Error} - explaining reason why creation failed */ }, { key: "create", value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref) { - var document, description, previewPath, rules, _ref$recipients, recipients, _ref$readOnlyRecipien, readOnlyRecipients, openSharing, appSlug, attributes, optionalAttributes, resp; - - return _regenerator.default.wrap(function _callee3$(_context3) { + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(attributes) { + var data, createFileOptions; + return _regenerator.default.wrap(function _callee11$(_context11) { while (1) { - switch (_context3.prev = _context3.next) { + switch (_context11.prev = _context11.next) { case 0: - document = _ref.document, description = _ref.description, previewPath = _ref.previewPath, rules = _ref.rules, _ref$recipients = _ref.recipients, recipients = _ref$recipients === void 0 ? [] : _ref$recipients, _ref$readOnlyRecipien = _ref.readOnlyRecipients, readOnlyRecipients = _ref$readOnlyRecipien === void 0 ? [] : _ref$readOnlyRecipien, openSharing = _ref.openSharing, appSlug = _ref.appSlug; - attributes = { - description: description, - preview_path: previewPath, - open_sharing: openSharing, - rules: rules ? rules : getSharingRules(document) - }; - optionalAttributes = {}; - - if (appSlug) { - optionalAttributes = { - app_slug: appSlug - }; + if (!(attributes.type === 'directory')) { + _context11.next = 4; + break; } - _context3.next = 6; - return this.stackClient.fetchJSON('POST', '/sharings/', { - data: { - type: 'io.cozy.sharings', - attributes: _objectSpread(_objectSpread({}, attributes), optionalAttributes), - relationships: _objectSpread(_objectSpread({}, recipients.length > 0 && { - recipients: { - data: recipients.map(toRelationshipItem) - } - }), readOnlyRecipients.length > 0 && { - read_only_recipients: { - data: readOnlyRecipients.map(toRelationshipItem) - } - }) - } - }); + return _context11.abrupt("return", this.createDirectory(attributes)); - case 6: - resp = _context3.sent; - return _context3.abrupt("return", { - data: normalizeSharing(resp.data) - }); + case 4: + data = attributes.data, createFileOptions = (0, _objectWithoutProperties2.default)(attributes, ["data"]); + return _context11.abrupt("return", this.createFile(data, createFileOptions)); - case 8: + case 6: case "end": - return _context3.stop(); + return _context11.stop(); } } - }, _callee3, this); + }, _callee11, this); })); - function create(_x3) { + function create(_x17) { return _create.apply(this, arguments); } return create; }() - /** - * @deprecated Use create() instead - * share - Creates a new sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#post-sharings + /*** + * Updates an existing file or directory * - * @param {Sharing} document The document to share. Should have and _id and a name. - * @param {Array} recipients A list of io.cozy.contacts - * @param {string} sharingType - If "two-way", will set the open_sharing attribute to true - * @param {string} description - Describes the sharing - * @param {string=} previewPath Relative URL of the sharings preview page + * Used by StackLink to support CozyClient.save({file}). + * Update the binary file if a `data` param is passed. Only updates + * attributes otherwise. + * + * @param {FileAttributes} file - The file with its new content + * @param {File|Blob|string|ArrayBuffer} attributes.data Will be used as content of the updated file + * @returns {FileAttributes} Updated document + * @throws {Error} - explaining reason why update failed */ }, { - key: "share", + key: "update", value: function () { - var _share = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(document, recipients, sharingType, description) { - var previewPath, - recipientsToUse, - _args4 = arguments; - return _regenerator.default.wrap(function _callee4$(_context4) { + var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(attributes) { + var data, updateFileOptions, fileId; + return _regenerator.default.wrap(function _callee12$(_context12) { while (1) { - switch (_context4.prev = _context4.next) { + switch (_context12.prev = _context12.next) { case 0: - previewPath = _args4.length > 4 && _args4[4] !== undefined ? _args4[4] : null; - console.warn('SharingCollection.share is deprecated, use SharingCollection.create instead'); - recipientsToUse = sharingType === 'two-way' ? { - recipients: recipients - } : { - readOnlyRecipients: recipients - }; - return _context4.abrupt("return", this.create(_objectSpread(_objectSpread({ - document: document - }, recipientsToUse), {}, { - description: description, - previewPath: previewPath, - openSharing: sharingType === 'two-way', - rules: getSharingRules(document, sharingType) - }))); + data = attributes.data, updateFileOptions = (0, _objectWithoutProperties2.default)(attributes, ["data"]); + fileId = attributes.id || attributes._id; - case 4: + if (!data) { + _context12.next = 7; + break; + } + + if (!(attributes.type === 'directory')) { + _context12.next = 5; + break; + } + + throw new Error('You cannot pass a data object for a directory'); + + case 5: + updateFileOptions.fileId = fileId; + return _context12.abrupt("return", this.updateFile(data, updateFileOptions)); + + case 7: + return _context12.abrupt("return", this.updateAttributes(fileId, attributes)); + + case 8: case "end": - return _context4.stop(); + return _context12.stop(); } } - }, _callee4, this); + }, _callee12, this); })); - function share(_x4, _x5, _x6, _x7) { - return _share.apply(this, arguments); + function update(_x18) { + return _update.apply(this, arguments); } - return share; + return update; }() /** - * getDiscoveryLink - Returns the URL of the page that can be used to accept a sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#get-sharingssharing-iddiscovery - * - * @param {string} sharingId - Id of the sharing - * @param {string} sharecode - Code of the sharing - * @returns {string} - */ - - }, { - key: "getDiscoveryLink", - value: function getDiscoveryLink(sharingId, sharecode) { - return this.stackClient.fullpath("/sharings/".concat(sharingId, "/discovery?sharecode=").concat(sharecode)); - } - /** - * Add an array of contacts to the Sharing + * Creates a file * - * @param {object} options Object - * @param {Sharing} options.document Sharing Object - * @param {Array<Recipient>=} options.recipients Recipients to add to the sharing - * @param {Array<Recipient>=} options.readOnlyRecipients Recipients to add to the sharings with only read only access + * @private + * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded + * @param {FileAttributes} params Additional parameters + * @param {object} params.options Options to pass to doUpload method (additional headers) + * @throws {Error} - explaining reason why creation failed */ }, { - key: "addRecipients", + key: "createFile", value: function () { - var _addRecipients = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(_ref2) { - var document, _ref2$recipients, recipients, _ref2$readOnlyRecipie, readOnlyRecipients, resp; + var _createFile = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(data) { + var _ref5, + nameOption, + _ref5$dirId, + dirId, + _ref5$executable, + executable, + _ref5$encrypted, + encrypted, + metadata, + options, + name, + metadataId, + meta, + size, + path, + _args13 = arguments; - return _regenerator.default.wrap(function _callee5$(_context5) { + return _regenerator.default.wrap(function _callee13$(_context13) { while (1) { - switch (_context5.prev = _context5.next) { + switch (_context13.prev = _context13.next) { case 0: - document = _ref2.document, _ref2$recipients = _ref2.recipients, recipients = _ref2$recipients === void 0 ? [] : _ref2$recipients, _ref2$readOnlyRecipie = _ref2.readOnlyRecipients, readOnlyRecipients = _ref2$readOnlyRecipie === void 0 ? [] : _ref2$readOnlyRecipie; - _context5.next = 3; - return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject3(), document._id), { - data: { - type: 'io.cozy.sharings', - id: document._id, - relationships: _objectSpread(_objectSpread({}, recipients.length > 0 && { - recipients: { - data: recipients.map(toRelationshipItem) - } - }), readOnlyRecipients.length > 0 && { - read_only_recipients: { - data: readOnlyRecipients.map(toRelationshipItem) - } - }) - } - }); + _ref5 = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : {}; + nameOption = _ref5.name, _ref5$dirId = _ref5.dirId, dirId = _ref5$dirId === void 0 ? '' : _ref5$dirId, _ref5$executable = _ref5.executable, executable = _ref5$executable === void 0 ? false : _ref5$executable, _ref5$encrypted = _ref5.encrypted, encrypted = _ref5$encrypted === void 0 ? false : _ref5$encrypted, metadata = _ref5.metadata, options = (0, _objectWithoutProperties2.default)(_ref5, ["name", "dirId", "executable", "encrypted", "metadata"]); + name = nameOption; // handle case where data is a file and contains the name - case 3: - resp = _context5.sent; - return _context5.abrupt("return", { - data: normalizeSharing(resp.data) - }); + if (!name && typeof data.name === 'string') { + name = data.name; + } - case 5: + name = sanitizeAndValidateFileName(name); + metadataId = ''; + + if (!metadata) { + _context13.next = 11; + break; + } + + _context13.next = 9; + return this.createFileMetadata(metadata); + + case 9: + meta = _context13.sent; + metadataId = meta.data.id; + + case 11: + size = ''; + + if (options.contentLength) { + size = String(options.contentLength); + } + + path = (0, _utils.uri)(_templateObject9(), dirId, name, executable, encrypted, metadataId, size); + return _context13.abrupt("return", this.doUpload(data, path, options)); + + case 15: case "end": - return _context5.stop(); + return _context13.stop(); } } - }, _callee5, this); + }, _callee13, this); })); - function addRecipients(_x8) { - return _addRecipients.apply(this, arguments); + function createFile(_x19) { + return _createFile.apply(this, arguments); } - return addRecipients; + return createFile; }() /** - * Revoke only one recipient of the sharing. - * - * @param {object} sharing Sharing Object - * @param {number} recipientIndex Index of this recipient in the members array of the sharing - */ - - }, { - key: "revokeRecipient", - value: function revokeRecipient(sharing, recipientIndex) { - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject4(), sharing._id, recipientIndex)); - } - /** - * Remove self from the sharing. - * - * @param {object} sharing Sharing Object - */ - - }, { - key: "revokeSelf", - value: function revokeSelf(sharing) { - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject5(), sharing._id)); - } - /** - * Revoke the sharing for all the members. Must be called - * from the owner's cozy + * updateFile - Updates a file's data * - * @param {object} sharing Sharing Objects + * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded + * @param {FileAttributes} params Additional parameters + * @param {object} params.options Options to pass to doUpload method (additional headers) + * @returns {object} Updated document + * @throws {Error} - explaining reason why update failed */ }, { - key: "revokeAllRecipients", - value: function revokeAllRecipients(sharing) { - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), sharing._id)); - } - }]); - return SharingCollection; -}(_DocumentCollection2.default); - -SharingCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; + key: "updateFile", + value: function () { + var _updateFile = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(data) { + var _ref6, + _ref6$executable, + executable, + _ref6$encrypted, + encrypted, + fileId, + _ref6$name, + name, + metadata, + options, + fileName, + sanitizedName, + metadataId, + path, + meta, + size, + _args14 = arguments; -var getSharingRulesWithoutWarning = function getSharingRulesWithoutWarning(document, sharingType) { - if ((0, _FileCollection.isFile)(document)) { - return getSharingRulesForFile(document, sharingType); - } + return _regenerator.default.wrap(function _callee14$(_context14) { + while (1) { + switch (_context14.prev = _context14.next) { + case 0: + _ref6 = _args14.length > 1 && _args14[1] !== undefined ? _args14[1] : {}; + _ref6$executable = _ref6.executable, executable = _ref6$executable === void 0 ? false : _ref6$executable, _ref6$encrypted = _ref6.encrypted, encrypted = _ref6$encrypted === void 0 ? false : _ref6$encrypted, fileId = _ref6.fileId, _ref6$name = _ref6.name, name = _ref6$name === void 0 ? '' : _ref6$name, metadata = _ref6.metadata, options = (0, _objectWithoutProperties2.default)(_ref6, ["executable", "encrypted", "fileId", "name", "metadata"]); - if (document._type === BITWARDEN_ORGANIZATIONS_DOCTYPE) { - return getSharingRulesForOrganizations(document); - } + if (!(!fileId || typeof fileId !== 'string')) { + _context14.next = 4; + break; + } - return getSharingRulesForPhotosAlbum(document, sharingType); -}; -/** - * Rules determine the behavior of the sharing when changes are made to the shared document - * See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing - * - * @param {Sharing} document - The document to share. Should have and _id and a name - * @param {SharingType} sharingType - The type of the sharing - * - * @returns {Array<Rule>=} The rules that define how to share the document - */ + throw new Error('missing fileId argument'); + case 4: + // name might be set in a File object + fileName = name || data.name; -var getSharingRules = function getSharingRules(document, sharingType) { - if (sharingType) { - console.warn("sharingType is deprecated and will be removed. We now set this default rules: ".concat(getSharingRulesWithoutWarning(document), "} \n \n If this default rules do not fill your need, please set custom rules \n by using the 'rules' object of the SharingCollection.create() method")); - } + if (!(!fileName || typeof fileName !== 'string')) { + _context14.next = 7; + break; + } - return getSharingRulesWithoutWarning(document, sharingType); -}; -/** - * Compute the rules that define how to share a Photo Album. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing - * - * @param {Sharing} document - The document to share. Should have and _id and a name - * @param {SharingType} sharingType - The type of the sharing - * - * @returns {Array<Rule>=} The rules that define how to share a Photo Album - */ + throw new Error('missing name in data argument'); + case 7: + sanitizedName = sanitizeAndValidateFileName(fileName); + /** + * We already use the body to send the content of the file. So we have 2 choices : + * Use an object in a query string to send the metadata + * create a new header http + * In both case, we have a size limitation depending of the browser. + * + * So we had this current workaround where we create the metadata before + * (no size limit since we can use the body for that) and after we use the ID. + */ -exports.getSharingRules = getSharingRules; + path = (0, _utils.uri)(_templateObject10(), fileId, sanitizedName, executable, encrypted); -var getSharingRulesForPhotosAlbum = function getSharingRulesForPhotosAlbum(document, sharingType) { - var _id = document._id, - _type = document._type; - return [_objectSpread({ - title: 'collection', - doctype: _type, - values: [_id] - }, getSharingPolicyForAlbum(sharingType)), _objectSpread({ - title: 'items', - doctype: 'io.cozy.files', - values: ["".concat(_type, "/").concat(_id)], - selector: 'referenced_by' - }, getSharingPolicyForReferencedFiles(sharingType))]; -}; -/** - * Compute the sharing policy for a ReferencedFile based on its sharing type - * - * @param {SharingType} sharingType - The type of the sharing - * - * @returns {SharingPolicy} The sharing policy for the ReferencedFile - */ + if (!metadata) { + _context14.next = 15; + break; + } + _context14.next = 12; + return this.createFileMetadata(metadata); -var getSharingPolicyForReferencedFiles = function getSharingPolicyForReferencedFiles(sharingType) { - return sharingType === 'two-way' ? { - add: 'sync', - update: 'sync', - remove: 'sync' - } : { - add: 'push', - update: 'none', - remove: 'push' - }; -}; -/** - * Compute the sharing policy for an Album based on its sharing type - * - * @param {SharingType} sharingType - The type of the sharing - * - * @returns {Array<Rule>=} The sharing policy for the Album - */ + case 12: + meta = _context14.sent; + metadataId = meta.data.id; + path = path + "&MetadataID=".concat(metadataId); + case 15: + size = ''; -var getSharingPolicyForAlbum = function getSharingPolicyForAlbum(sharingType) { - if (!sharingType) return { - update: 'sync', - remove: 'revoke' - }; - return sharingType === 'two-way' ? { - update: 'sync', - remove: 'revoke' - } : { - update: 'push', - remove: 'revoke' - }; -}; -/** - * Compute the rules that define how to share a File. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing - * - * @param {Sharing} document - The document to share. Should have and _id and a name - * @param {SharingType} sharingType - The type of the sharing - * - * @returns {Array<Rule>=} The rules that define how to share a File - */ + if (options.contentLength) { + size = String(options.contentLength); + path = path + "&Size=".concat(size); + } + return _context14.abrupt("return", this.doUpload(data, path, options, 'PUT')); -var getSharingRulesForFile = function getSharingRulesForFile(document, sharingType) { - var _id = document._id, - name = document.name; - return [_objectSpread({ - title: name, - doctype: 'io.cozy.files', - values: [_id] - }, getSharingPolicyForFile(document, sharingType))]; -}; -/** - * Compute the sharing policy for a File based on its sharing type - * - * @param {Sharing} document - The document to share. Should have and _id and a name - * @param {SharingType} sharingType - The type of the sharing - * - * @returns {SharingPolicy} The sharing policy for the File - */ + case 18: + case "end": + return _context14.stop(); + } + } + }, _callee14, this); + })); + function updateFile(_x20) { + return _updateFile.apply(this, arguments); + } -var getSharingPolicyForFile = function getSharingPolicyForFile(document, sharingType) { - if ((0, _FileCollection.isDirectory)(document)) { - if (!sharingType) return { - add: 'sync', - update: 'sync', - remove: 'sync' - }; - return sharingType === 'two-way' ? { - add: 'sync', - update: 'sync', - remove: 'sync' - } : { - add: 'push', - update: 'push', - remove: 'push' - }; - } + return updateFile; + }() + }, { + key: "getDownloadLinkById", + value: function getDownloadLinkById(id, filename) { + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject11(), id, filename)).then(this.extractResponseLinkRelated); + } + }, { + key: "getDownloadLinkByRevision", + value: function getDownloadLinkByRevision(versionId, filename) { + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject12(), versionId, filename)).then(this.extractResponseLinkRelated); + } + }, { + key: "getDownloadLinkByPath", + value: function getDownloadLinkByPath(path) { + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject13(), path)).then(this.extractResponseLinkRelated); + } + }, { + key: "download", - if (!sharingType) return { - update: 'sync', - remove: 'revoke' - }; - return sharingType === 'two-way' ? { - update: 'sync', - remove: 'revoke' - } : { - update: 'push', - remove: 'revoke' - }; -}; -/** - * Compute the rules that define how to share an Organization. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing - * - * @param {Sharing} document The document to share. Should have and _id and a name - * - * @returns {Array<Rule>=} The rules that define how to share an Organization - */ + /** + * Download a file or a specific version of the file + * + * @param {object} file io.cozy.files object + * @param {string} versionId Id of the io.cozy.files.version + * @param {string} filename The name you want for the downloaded file + * (by default the same as the file) + */ + value: function () { + var _download = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(file) { + var versionId, + filename, + href, + filenameToUse, + _args15 = arguments; + return _regenerator.default.wrap(function _callee15$(_context15) { + while (1) { + switch (_context15.prev = _context15.next) { + case 0: + versionId = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : null; + filename = _args15.length > 2 && _args15[2] !== undefined ? _args15[2] : undefined; + filenameToUse = filename ? filename : file.name; + /** + * Passing a filename to forceFileDownload is not enough + * for a few browsers since the stack's response header will + * not contain that name. Passing the filename to + * getDownloadLinkBy{Id,Revision} will ask the stack to + * return this filename in its content-disposition + * header response + */ + if (versionId) { + _context15.next = 9; + break; + } -var getSharingRulesForOrganizations = function getSharingRulesForOrganizations(document) { - var _id = document._id, - name = document.name; - var sharingRules = [{ - title: name, - doctype: BITWARDEN_ORGANIZATIONS_DOCTYPE, - values: [_id], - add: 'sync', - update: 'sync', - remove: 'revoke' - }, { - title: 'Ciphers', - doctype: BITWARDEN_CIPHERS_DOCTYPE, - values: [_id], - add: 'sync', - update: 'sync', - remove: 'sync', - selector: 'organization_id' - }]; - return sharingRules; -}; -/** - * Compute the RelationshipItem that can be referenced as a sharing recipient - * - * @param {Recipient} item The recipient of a sharing - * - * @returns {RelationshipItem} The RelationshipItem that can be referenced as a sharing recipient - */ + _context15.next = 6; + return this.getDownloadLinkById(file._id, filenameToUse); + case 6: + href = _context15.sent; + _context15.next = 12; + break; -var toRelationshipItem = function toRelationshipItem(item) { - return { - id: item._id, - type: item._type - }; -}; + case 9: + _context15.next = 11; + return this.getDownloadLinkByRevision(versionId, filenameToUse); -var _default = SharingCollection; -exports["default"] = _default; + case 11: + href = _context15.sent; -/***/ }), -/* 673 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + case 12: + this.forceFileDownload("".concat(href, "?Dl=1"), filenameToUse); -"use strict"; + case 13: + case "end": + return _context15.stop(); + } + } + }, _callee15, this); + })); + function download(_x21) { + return _download.apply(this, arguments); + } -var _interopRequireWildcard = __webpack_require__(510); + return download; + }() + }, { + key: "fetchFileContent", + value: function () { + var _fetchFileContent = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16(id) { + return _regenerator.default.wrap(function _callee16$(_context16) { + while (1) { + switch (_context16.prev = _context16.next) { + case 0: + console.warn('FileCollection.fetchFileContent() is deprecated. Use FileCollection.fetchFileContentById() instead'); + return _context16.abrupt("return", this.fetchFileContentById(id)); -var _interopRequireDefault = __webpack_require__(512); + case 2: + case "end": + return _context16.stop(); + } + } + }, _callee16, this); + })); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.getPermissionsFor = void 0; + function fetchFileContent(_x22) { + return _fetchFileContent.apply(this, arguments); + } -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); + return fetchFileContent; + }() + /** + * Fetch the binary of a file or a specific version of a file + * Useful for instance when you can't download the file directly + * (via a content-disposition attachement header) and need to store + * it before doing an operation. + * + * @param {string} id Id of the io.cozy.files or io.cozy.files.version + * + */ -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); + }, { + key: "fetchFileContentById", + value: function () { + var _fetchFileContentById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(id) { + return _regenerator.default.wrap(function _callee17$(_context17) { + while (1) { + switch (_context17.prev = _context17.next) { + case 0: + return _context17.abrupt("return", this.stackClient.fetch('GET', "/files/download/".concat(id))); -var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525)); + case 1: + case "end": + return _context17.stop(); + } + } + }, _callee17, this); + })); -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + function fetchFileContentById(_x23) { + return _fetchFileContentById.apply(this, arguments); + } -var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602)); + return fetchFileContentById; + }() + /** + * Get a beautified size for a given file + * 1024B => 1KB + * 102404500404B => 95.37 GB + * + * @param {object} file io.cozy.files object + * @param {number} decimal number of decimal + */ -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); + }, { + key: "getBeautifulSize", + value: function getBeautifulSize(file, decimal) { + return (0, _utils.formatBytes)(parseInt(file.size), decimal); + } + }, { + key: "downloadArchive", + value: function () { + var _downloadArchive = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(fileIds) { + var notSecureFilename, + filename, + href, + fullpath, + _args18 = arguments; + return _regenerator.default.wrap(function _callee18$(_context18) { + while (1) { + switch (_context18.prev = _context18.next) { + case 0: + notSecureFilename = _args18.length > 1 && _args18[1] !== undefined ? _args18[1] : 'files'; + filename = (0, _utils.slugify)(notSecureFilename); + _context18.next = 4; + return this.getArchiveLinkByIds(fileIds, filename); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + case 4: + href = _context18.sent; + fullpath = this.stackClient.fullpath(href); + this.forceFileDownload(fullpath, filename + '.zip'); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + case 7: + case "end": + return _context18.stop(); + } + } + }, _callee18, this); + })); -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); + function downloadArchive(_x24) { + return _downloadArchive.apply(this, arguments); + } -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); + return downloadArchive; + }() + }, { + key: "getArchiveLinkByIds", + value: function () { + var _getArchiveLinkByIds = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(ids) { + var name, + resp, + _args19 = arguments; + return _regenerator.default.wrap(function _callee19$(_context19) { + while (1) { + switch (_context19.prev = _context19.next) { + case 0: + name = _args19.length > 1 && _args19[1] !== undefined ? _args19[1] : 'files'; + _context19.next = 3; + return this.stackClient.fetchJSON('POST', '/files/archive', { + data: { + type: 'io.cozy.archives', + attributes: { + name: name, + ids: ids + } + } + }); -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + case 3: + resp = _context19.sent; + return _context19.abrupt("return", resp.links.related); -var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601)); + case 5: + case "end": + return _context19.stop(); + } + } + }, _callee19, this); + })); -var _FileCollection = __webpack_require__(658); + function getArchiveLinkByIds(_x25) { + return _getArchiveLinkByIds.apply(this, arguments); + } -var _utils = __webpack_require__(611); + return getArchiveLinkByIds; + }() + /** + * Checks if the file belongs to the parent's hierarchy. + * + * @param {string|object} child The file which can either be an id or an object + * @param {string|object} parent The parent target which can either be an id or an object + * @returns {boolean} Whether the file is a parent's child + */ -function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + }, { + key: "isChildOf", + value: function () { + var _isChildOf = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20(child, parent) { + var _this2 = this; -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + var _ref7, childID, childDirID, childPath, _ref8, parentID, childDoc, currPath, targetsPath, newPath; -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + return _regenerator.default.wrap(function _callee20$(_context20) { + while (1) { + switch (_context20.prev = _context20.next) { + case 0: + _ref7 = typeof child === 'object' ? child : { + _id: child + }, childID = _ref7._id, childDirID = _ref7.dirID, childPath = _ref7.path; + _ref8 = typeof parent === 'object' ? parent : { + _id: parent + }, parentID = _ref8._id; -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + if (!(childID === parentID || childDirID === parentID)) { + _context20.next = 4; + break; + } -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + return _context20.abrupt("return", true); -function _templateObject3() { - var data = (0, _taggedTemplateLiteral2.default)(["/permissions/doctype/", "/shared-by-link"]); + case 4: + if (childPath) { + _context20.next = 10; + break; + } - _templateObject3 = function _templateObject3() { - return data; - }; + _context20.next = 7; + return this.statById(childID); - return data; -} + case 7: + childDoc = _context20.sent; + childPath = childDoc.data.path; + childDirID = childDoc.data.dirID; -function _templateObject2() { - var data = (0, _taggedTemplateLiteral2.default)(["/permissions/", ""]); + case 10: + // Build hierarchy paths + currPath = childPath; + targetsPath = [childPath]; - _templateObject2 = function _templateObject2() { - return data; - }; + while (currPath != '') { + newPath = dirName(currPath); - return data; -} + if (newPath != '') { + targetsPath.push(newPath); + } -function _templateObject() { - var data = (0, _taggedTemplateLiteral2.default)(["/permissions/", ""]); + currPath = newPath; + } - _templateObject = function _templateObject() { - return data; - }; + targetsPath.reverse(); // Look for all hierarchy in parallel and return true as soon as a dir is the searched parent - return data; -} + return _context20.abrupt("return", raceWithCondition(targetsPath.map(function (path) { + return _this2.statByPath(path); + }), function (stat) { + return stat.data._id == parentID; + })); -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } + case 15: + case "end": + return _context20.stop(); + } + } + }, _callee20, this); + })); -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + function isChildOf(_x26, _x27) { + return _isChildOf.apply(this, arguments); + } -var normalizePermission = function normalizePermission(perm) { - return (0, _DocumentCollection2.normalizeDoc)(perm, 'io.cozy.permissions'); -}; -/** - * Implements `DocumentCollection` API along with specific methods for `io.cozy.permissions`. - */ + return isChildOf; + }() + /** + * statById - Fetches the metadata about a document. For folders, the results include the list of child files and folders. + * + * @param {string} id ID of the document + * @param {object|null} options Pagination options + * @param {number|null} [options.page[limit]] For pagination, the number of results to return. + * @param {number|null} [options.page[skip]] For skip-based pagination, the number of referenced files to skip. + * @param {CouchDBViewCursor|null} [options.page[cursor]] For cursor-based pagination, the index cursor. + * + * @returns {object} A promise resolving to an object containing "data" (the document metadata), "included" (the child documents) and "links" (pagination informations) + */ + }, { + key: "statById", + value: function () { + var _statById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21(id) { + var options, + params, + path, + url, + resp, + _args21 = arguments; + return _regenerator.default.wrap(function _callee21$(_context21) { + while (1) { + switch (_context21.prev = _context21.next) { + case 0: + options = _args21.length > 1 && _args21[1] !== undefined ? _args21[1] : {}; + params = (0, _pick.default)(options, ['page[limit]', 'page[skip]', 'page[cursor]']); + path = (0, _utils.uri)(_templateObject14(), id); + url = querystring.buildURL(path, params); + _context21.next = 6; + return this.stackClient.fetchJSON('GET', url); -var PermissionCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(PermissionCollection, _DocumentCollection); + case 6: + resp = _context21.sent; + return _context21.abrupt("return", { + data: normalizeFile(resp.data), + included: resp.included && resp.included.map(function (f) { + return normalizeFile(f); + }), + links: resp.links + }); - var _super = _createSuper(PermissionCollection); + case 8: + case "end": + return _context21.stop(); + } + } + }, _callee21, this); + })); - function PermissionCollection() { - (0, _classCallCheck2.default)(this, PermissionCollection); - return _super.apply(this, arguments); - } + function statById(_x28) { + return _statById.apply(this, arguments); + } - (0, _createClass2.default)(PermissionCollection, [{ - key: "get", + return statById; + }() + }, { + key: "statByPath", value: function () { - var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(id) { + var _statByPath = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22(path) { var resp; - return _regenerator.default.wrap(function _callee$(_context) { + return _regenerator.default.wrap(function _callee22$(_context22) { while (1) { - switch (_context.prev = _context.next) { + switch (_context22.prev = _context22.next) { case 0: - _context.next = 2; - return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject(), id)); + _context22.next = 2; + return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject15(), path)); case 2: - resp = _context.sent; - return _context.abrupt("return", { - data: normalizePermission(resp.data) + resp = _context22.sent; + return _context22.abrupt("return", { + data: normalizeFile(resp.data), + included: resp.included && resp.included.map(function (f) { + return normalizeFile(f); + }) }); case 4: case "end": - return _context.stop(); + return _context22.stop(); } } - }, _callee, this); + }, _callee22, this); })); - function get(_x) { - return _get.apply(this, arguments); + function statByPath(_x29) { + return _statByPath.apply(this, arguments); } - return get; + return statByPath; }() /** - * Create a new set of permissions - * It can also associates one or more codes to it, via the codes parameter - * - * @param {object} permission - * @param {string} permission.codes A comma separed list of values (defaulted to code) - * @param {string} permission.ttl Make the codes expire after a delay (bigduration format) - * @param {boolean} permission.tiny If set to true then the generated shortcode will be 6 digits - * Cozy-Stack has a few conditions to be able to use this tiny shortcode ATM you have to specifiy - * a ttl < 1h, but it can change. - * see https://docs.cozy.io/en/cozy-stack/permissions/#post-permissions for exact informations - * - * bigduration format: https://github.com/justincampbell/bigduration/blob/master/README.md - * @see https://docs.cozy.io/en/cozy-stack/permissions/#post-permissions + * Create directory * + * @private + * @param {DirectoryAttributes} attributes - Attributes of the directory + * @returns {Promise} + * @throws {Error} - explaining reason why creation failed */ }, { - key: "create", + key: "createDirectory", value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref) { - var _id, _type, _ref$codes, codes, ttl, tiny, attributes, searchParams, resp; - - return _regenerator.default.wrap(function _callee2$(_context2) { + var _createDirectory = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee23() { + var attributes, + name, + dirId, + lastModifiedDate, + safeName, + lastModified, + resp, + _args23 = arguments; + return _regenerator.default.wrap(function _callee23$(_context23) { while (1) { - switch (_context2.prev = _context2.next) { + switch (_context23.prev = _context23.next) { case 0: - _id = _ref._id, _type = _ref._type, _ref$codes = _ref.codes, codes = _ref$codes === void 0 ? 'code' : _ref$codes, ttl = _ref.ttl, tiny = _ref.tiny, attributes = (0, _objectWithoutProperties2.default)(_ref, ["_id", "_type", "codes", "ttl", "tiny"]); - searchParams = new URLSearchParams(); - searchParams.append('codes', codes); - if (ttl) searchParams.append('ttl', ttl); - if (tiny) searchParams.append('tiny', true); - _context2.next = 7; - return this.stackClient.fetchJSON('POST', "/permissions?".concat(searchParams), { - data: { - type: 'io.cozy.permissions', - attributes: attributes + attributes = _args23.length > 0 && _args23[0] !== undefined ? _args23[0] : {}; + name = attributes.name, dirId = attributes.dirId, lastModifiedDate = attributes.lastModifiedDate; + safeName = sanitizeAndValidateFileName(name); + lastModified = lastModifiedDate && (typeof lastModifiedDate === 'string' ? new Date(lastModifiedDate) : lastModifiedDate); + _context23.next = 6; + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject16(), dirId, safeName), undefined, { + headers: { + Date: lastModified ? lastModified.toGMTString() : '' } }); - case 7: - resp = _context2.sent; - return _context2.abrupt("return", { - data: normalizePermission(resp.data) + case 6: + resp = _context23.sent; + return _context23.abrupt("return", { + data: normalizeFile(resp.data) }); - case 9: + case 8: case "end": - return _context2.stop(); + return _context23.stop(); } } - }, _callee2, this); + }, _callee23, this); })); - function create(_x2) { - return _create.apply(this, arguments); + function createDirectory() { + return _createDirectory.apply(this, arguments); } - return create; + return createDirectory; }() - /** - * Adds a permission to the given document. Document type must be - * `io.cozy.apps`, `io.cozy.konnectors` or `io.cozy.permissions` - * - * @param {object} document - Document which receives the permission - * @param {object} permission - Describes the permission - * @returns {Promise} - * - * @example - * ``` - * const permissions = await client - * .collection('io.cozy.permissions') - * .add(konnector, { - * folder: { - * type: 'io.cozy.files', - * verbs: ['GET', 'PUT'], - * values: [`io.cozy.files.bc57b60eb2954537b0dcdc6ebd8e9d23`] - * } - * }) - * ``` - */ - }, { - key: "add", + key: "ensureDirectoryExists", value: function () { - var _add = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document, permission) { - var endpoint, resp; - return _regenerator.default.wrap(function _callee3$(_context3) { + var _ensureDirectoryExists = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee24(path) { + var resp; + return _regenerator.default.wrap(function _callee24$(_context24) { while (1) { - switch (_context3.prev = _context3.next) { + switch (_context24.prev = _context24.next) { case 0: - _context3.t0 = document._type; - _context3.next = _context3.t0 === 'io.cozy.apps' ? 3 : _context3.t0 === 'io.cozy.konnectors' ? 5 : _context3.t0 === 'io.cozy.permissions' ? 7 : 9; - break; + if (this.specialDirectories[path]) { + _context24.next = 5; + break; + } + + _context24.next = 3; + return this.createDirectoryByPath(path); case 3: - endpoint = "/permissions/apps/".concat(document.slug); - return _context3.abrupt("break", 10); + resp = _context24.sent; + this.specialDirectories[path] = resp.data._id; case 5: - endpoint = "/permissions/konnectors/".concat(document.slug); - return _context3.abrupt("break", 10); - - case 7: - endpoint = "/permissions/".concat(document._id); - return _context3.abrupt("break", 10); - - case 9: - throw new Error('Permissions can only be added on existing permissions, apps and konnectors.'); - - case 10: - _context3.next = 12; - return this.stackClient.fetchJSON('PATCH', endpoint, { - data: { - type: 'io.cozy.permissions', - attributes: { - permissions: permission - } - } - }); - - case 12: - resp = _context3.sent; - return _context3.abrupt("return", { - data: normalizePermission(resp.data) - }); + return _context24.abrupt("return", this.specialDirectories[path]); - case 14: + case 6: case "end": - return _context3.stop(); + return _context24.stop(); } } - }, _callee3, this); + }, _callee24, this); })); - function add(_x3, _x4) { - return _add.apply(this, arguments); + function ensureDirectoryExists(_x30) { + return _ensureDirectoryExists.apply(this, arguments); } - return add; + return ensureDirectoryExists; }() }, { - key: "destroy", - value: function destroy(permission) { - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject2(), permission.id)); - } - }, { - key: "findLinksByDoctype", + key: "getDirectoryOrCreate", value: function () { - var _findLinksByDoctype = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(doctype) { - var resp; - return _regenerator.default.wrap(function _callee4$(_context4) { + var _getDirectoryOrCreate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee25(name, parentDirectory) { + var safeName, path, stat, parsedError, errors; + return _regenerator.default.wrap(function _callee25$(_context25) { while (1) { - switch (_context4.prev = _context4.next) { + switch (_context25.prev = _context25.next) { case 0: - _context4.next = 2; - return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject3(), doctype)); + if (!(parentDirectory && !parentDirectory.attributes)) { + _context25.next = 2; + break; + } + + throw new Error('Malformed parent directory'); case 2: - resp = _context4.sent; - return _context4.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { - data: resp.data.map(normalizePermission) + safeName = sanitizeFileName(name); + path = "".concat(parentDirectory._id === ROOT_DIR_ID ? '' : parentDirectory.attributes.path, "/").concat(safeName); + _context25.prev = 4; + _context25.next = 7; + return this.statByPath(path || '/'); + + case 7: + stat = _context25.sent; + return _context25.abrupt("return", stat); + + case 11: + _context25.prev = 11; + _context25.t0 = _context25["catch"](4); + parsedError = JSON.parse(_context25.t0.message); + errors = parsedError.errors; + + if (!(errors && errors.length && errors[0].status === '404')) { + _context25.next = 17; + break; + } + + return _context25.abrupt("return", this.createDirectory({ + name: safeName, + dirId: parentDirectory && parentDirectory._id })); - case 4: + case 17: + throw errors; + + case 18: case "end": - return _context4.stop(); + return _context25.stop(); } } - }, _callee4, this); + }, _callee25, this, [[4, 11]]); })); - function findLinksByDoctype(_x5) { - return _findLinksByDoctype.apply(this, arguments); + function getDirectoryOrCreate(_x31, _x32) { + return _getDirectoryOrCreate.apply(this, arguments); } - return findLinksByDoctype; + return getDirectoryOrCreate; }() + /** + * async createDirectoryByPath - Creates one or more folders until the given path exists + * + * @param {string} path - Path of the created directory + * @returns {object} The document corresponding to the last segment of the path + */ + }, { - key: "findApps", + key: "createDirectoryByPath", value: function () { - var _findApps = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() { - var resp; - return _regenerator.default.wrap(function _callee5$(_context5) { + var _createDirectoryByPath = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee26(path) { + var parts, root, parentDir, _iterator2, _step2, part; + + return _regenerator.default.wrap(function _callee26$(_context26) { while (1) { - switch (_context5.prev = _context5.next) { + switch (_context26.prev = _context26.next) { case 0: - _context5.next = 2; - return this.stackClient.fetchJSON('GET', '/apps/'); + parts = path.split('/').filter(function (part) { + return part !== ''; + }); + _context26.next = 3; + return this.statById(ROOT_DIR_ID); - case 2: - resp = _context5.sent; - return _context5.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { - data: resp.data.map(function (a) { - return _objectSpread({ - _id: a.id - }, a); - }) - })); + case 3: + root = _context26.sent; - case 4: + if (parts.length) { + _context26.next = 6; + break; + } + + return _context26.abrupt("return", root); + + case 6: + parentDir = root; + _iterator2 = _createForOfIteratorHelper(parts); + _context26.prev = 8; + + _iterator2.s(); + + case 10: + if ((_step2 = _iterator2.n()).done) { + _context26.next = 17; + break; + } + + part = _step2.value; + _context26.next = 14; + return this.getDirectoryOrCreate(part, parentDir.data); + + case 14: + parentDir = _context26.sent; + + case 15: + _context26.next = 10; + break; + + case 17: + _context26.next = 22; + break; + + case 19: + _context26.prev = 19; + _context26.t0 = _context26["catch"](8); + + _iterator2.e(_context26.t0); + + case 22: + _context26.prev = 22; + + _iterator2.f(); + + return _context26.finish(22); + + case 25: + return _context26.abrupt("return", parentDir); + + case 26: case "end": - return _context5.stop(); + return _context26.stop(); } } - }, _callee5, this); + }, _callee26, this, [[8, 19, 22, 25]]); })); - function findApps() { - return _findApps.apply(this, arguments); + function createDirectoryByPath(_x33) { + return _createDirectoryByPath.apply(this, arguments); } - return findApps; + return createDirectoryByPath; }() /** - * Create a share link * - * @param {{_id, _type}} document - cozy document - * @param {object} options - options - * @param {string[]} options.verbs - explicit permissions to use + * async updateAttributes - Updates a file / folder's attributes except + * the metadata attribute. If you want to update its metadata attribute, + * then use `updateFileMetadataAttribute` since `metadata` is a specific + * doctype. + * + * For instance, if you want to update the name of a file, you can pass + * attributes = { name: 'newName'} + * + * You can see the attributes for both Folder and File (as they share the + * same doctype they have a few in common) here : + * https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files/#iocozyfiles + * + * @private You shoud use update() directly. + * @param {string} id File id + * @param {object} attributes New file attributes + * @returns {object} Updated document + * @throws {Error} - explaining reason why update failed */ }, { - key: "createSharingLink", + key: "updateAttributes", value: function () { - var _createSharingLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(document) { - var options, - verbs, - resp, - _args6 = arguments; - return _regenerator.default.wrap(function _callee6$(_context6) { + var _updateAttributes = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee27(id, attributes) { + var sanitizedAttributes, resp; + return _regenerator.default.wrap(function _callee27$(_context27) { while (1) { - switch (_context6.prev = _context6.next) { + switch (_context27.prev = _context27.next) { case 0: - options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {}; - verbs = options.verbs; - _context6.next = 4; - return this.stackClient.fetchJSON('POST', "/permissions?codes=email", { + sanitizedAttributes = _objectSpread({}, attributes); + + if (attributes.name) { + sanitizedAttributes.name = sanitizeAndValidateFileName(attributes.name); + } + + _context27.next = 4; + return this.stackClient.fetchJSON('PATCH', (0, _utils.uri)(_templateObject17(), id), { data: { - type: 'io.cozy.permissions', - attributes: { - permissions: getPermissionsFor(document, true, verbs ? { - verbs: verbs - } : {}) - } + type: 'io.cozy.files', + id: id, + attributes: sanitizedAttributes } }); case 4: - resp = _context6.sent; - return _context6.abrupt("return", { - data: normalizePermission(resp.data) + resp = _context27.sent; + return _context27.abrupt("return", { + data: normalizeFile(resp.data) }); case 6: case "end": - return _context6.stop(); + return _context27.stop(); } } - }, _callee6, this); + }, _callee27, this); })); - function createSharingLink(_x6) { - return _createSharingLink.apply(this, arguments); + function updateAttributes(_x34, _x35) { + return _updateAttributes.apply(this, arguments); } - return createSharingLink; + return updateAttributes; + }() + }, { + key: "updateFileMetadata", + value: function () { + var _updateFileMetadata = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee28(id, attributes) { + return _regenerator.default.wrap(function _callee28$(_context28) { + while (1) { + switch (_context28.prev = _context28.next) { + case 0: + console.warn('CozyClient FileCollection updateFileMetadata method is deprecated. Use updateAttributes instead'); + return _context28.abrupt("return", this.updateAttributes(id, attributes)); + + case 2: + case "end": + return _context28.stop(); + } + } + }, _callee28, this); + })); + + function updateFileMetadata(_x36, _x37) { + return _updateFileMetadata.apply(this, arguments); + } + + return updateFileMetadata; }() /** - * Follow the next link to fetch the next permissions + * Send a metadata object that can be associated to a file uploaded after that, + * via the MetadataID query parameter. + * See https://github.com/cozy/cozy-stack/blob/master/docs/files.md#post-filesuploadmetadata * - * @param {object} permissions JSON-API based permissions document + * @param {object} attributes The file's metadata + * @returns {object} The Metadata object */ }, { - key: "fetchPermissionsByLink", + key: "createFileMetadata", value: function () { - var _fetchPermissionsByLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(permissions) { - return _regenerator.default.wrap(function _callee7$(_context7) { + var _createFileMetadata = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee29(attributes) { + var resp; + return _regenerator.default.wrap(function _callee29$(_context29) { while (1) { - switch (_context7.prev = _context7.next) { + switch (_context29.prev = _context29.next) { case 0: - if (!(permissions.links && permissions.links.next)) { - _context7.next = 4; - break; - } - - _context7.next = 3; - return this.stackClient.fetchJSON('GET', permissions.links.next); + _context29.next = 2; + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject18()), { + data: { + type: 'io.cozy.files.metadata', + attributes: attributes + } + }); - case 3: - return _context7.abrupt("return", _context7.sent); + case 2: + resp = _context29.sent; + return _context29.abrupt("return", { + data: resp.data + }); case 4: case "end": - return _context7.stop(); + return _context29.stop(); } } - }, _callee7, this); + }, _callee29, this); })); - function fetchPermissionsByLink(_x7) { - return _fetchPermissionsByLink.apply(this, arguments); + function createFileMetadata(_x38) { + return _createFileMetadata.apply(this, arguments); } - return fetchPermissionsByLink; + return createFileMetadata; }() /** * - * @param {object} document Cozy doc - * @returns {object} with all the permissions + * Updates the metadata attribute of a io.cozy.files + * Creates a new version of the file without having + * to upload again the file's content + * + * To see available content of the metadata attribute + * see : https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files_metadata/ + * + * @param {string} id File id + * @param {object} metadata io.cozy.files.metadata attributes + * @returns {object} io.cozy.files updated */ }, { - key: "fetchAllLinks", + key: "updateMetadataAttribute", value: function () { - var _fetchAllLinks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(document) { - var allLinks, resp, _allLinks$data; - - return _regenerator.default.wrap(function _callee8$(_context8) { + var _updateMetadataAttribute = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee30(id, metadata) { + var resp; + return _regenerator.default.wrap(function _callee30$(_context30) { while (1) { - switch (_context8.prev = _context8.next) { + switch (_context30.prev = _context30.next) { case 0: - _context8.next = 2; - return this.findLinksByDoctype(document._type); + _context30.next = 2; + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject19(), id), { + data: { + type: 'io.cozy.files.metadata', + attributes: metadata + } + }); case 2: - allLinks = _context8.sent; - resp = allLinks; + resp = _context30.sent; + return _context30.abrupt("return", { + data: resp.data + }); case 4: - if (!(resp.links && resp.links.next)) { - _context8.next = 11; - break; - } - - _context8.next = 7; - return this.fetchPermissionsByLink(resp); - - case 7: - resp = _context8.sent; - - (_allLinks$data = allLinks.data).push.apply(_allLinks$data, (0, _toConsumableArray2.default)(resp.data.map(normalizePermission))); - - _context8.next = 4; - break; - - case 11: - return _context8.abrupt("return", allLinks); - - case 12: case "end": - return _context8.stop(); + return _context30.stop(); } } - }, _callee8, this); + }, _callee30, this); })); - function fetchAllLinks(_x8) { - return _fetchAllLinks.apply(this, arguments); + function updateMetadataAttribute(_x39, _x40) { + return _updateMetadataAttribute.apply(this, arguments); } - return fetchAllLinks; + return updateMetadataAttribute; }() /** - * Destroy a sharing link and the related permissions + * Get the file mime-type based on its name * - * @param {object} document + * @param {string} name - The file name + * @returns {string} the inferred file mime-type */ }, { - key: "revokeSharingLink", + key: "getFileTypeFromName", + value: function getFileTypeFromName(name) { + return _lite.default.getType(name) || CONTENT_TYPE_OCTET_STREAM; + } + /** + * + * This method should not be called directly to upload a file. + * You should use `createFile` + * + * @param {File|Blob|Stream|string|ArrayBuffer} dataArg file to be uploaded + * @param {string} path Uri to call the stack from. Something like + * `/files/${dirId}?Name=${name}&Type=file&Executable=${executable}&MetadataID=${metadataId}` + * @param {object} options Additional headers + * @param {string} method POST / PUT / PATCH + */ + + }, { + key: "doUpload", value: function () { - var _revokeSharingLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(document) { - var allLinks, links, _iterator, _step, perm; + var _doUpload = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee31(dataArg, path, options) { + var method, + correctPath, + data, + isBuffer, + isFile, + isBlob, + isStream, + isString, + _ref9, + contentType, + contentLength, + checksum, + lastModifiedDate, + ifMatch, + sPath, + params, + name, + headers, + date, + resp, + _args31 = arguments; - return _regenerator.default.wrap(function _callee9$(_context9) { + return _regenerator.default.wrap(function _callee31$(_context31) { while (1) { - switch (_context9.prev = _context9.next) { + switch (_context31.prev = _context31.next) { case 0: - _context9.next = 2; - return this.fetchAllLinks(document); + method = _args31.length > 3 && _args31[3] !== undefined ? _args31[3] : 'POST'; + correctPath = path; + data = dataArg; - case 2: - allLinks = _context9.sent; - links = allLinks.data.filter(function (perm) { - return isPermissionRelatedTo(perm, document); - }); - _iterator = _createForOfIteratorHelper(links); - _context9.prev = 5; + if (data) { + _context31.next = 5; + break; + } - _iterator.s(); + throw new Error('missing data argument'); - case 7: - if ((_step = _iterator.n()).done) { - _context9.next = 13; - break; + case 5: + // transform any ArrayBufferView to ArrayBuffer + if (data.buffer && data.buffer instanceof ArrayBuffer) { + data = data.buffer; } - perm = _step.value; - _context9.next = 11; - return this.destroy(perm); + isBuffer = typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer; + isFile = typeof File !== 'undefined' && data instanceof File; + isBlob = typeof Blob !== 'undefined' && data instanceof Blob; + isStream = data.readable === true && typeof data.pipe === 'function'; + isString = typeof data === 'string'; - case 11: - _context9.next = 7; - break; + if (!(!isBuffer && !isFile && !isBlob && !isStream && !isString)) { + _context31.next = 13; + break; + } + + throw new Error('invalid data type'); case 13: - _context9.next = 18; - break; + _ref9 = options || {}, contentType = _ref9.contentType, contentLength = _ref9.contentLength, checksum = _ref9.checksum, lastModifiedDate = _ref9.lastModifiedDate, ifMatch = _ref9.ifMatch; - case 15: - _context9.prev = 15; - _context9.t0 = _context9["catch"](5); + if (!contentType) { + if (typeof data === 'string') { + contentType = 'text/plain'; + } else { + if (data.type) { + // The type is specified in the file object + contentType = data.type; + } else { + // Extract the name from the correctPath and infer the type + sPath = correctPath.split('?'); + params = sPath.length > 1 ? sPath[1] : ''; + name = new URLSearchParams(params).get('Name'); + contentType = this.getFileTypeFromName(name.toLowerCase()); + } + } + } - _iterator.e(_context9.t0); + lastModifiedDate = lastModifiedDate || data.lastModified; - case 18: - _context9.prev = 18; + if (lastModifiedDate) { + lastModifiedDate = new Date(lastModifiedDate); + } - _iterator.f(); + headers = { + 'Content-Type': contentType + }; + if (contentLength) headers['Content-Length'] = String(contentLength); + if (checksum) headers['Content-MD5'] = checksum; - return _context9.finish(18); + if (lastModifiedDate) { + date = lastModifiedDate.toISOString(); + correctPath = "".concat(correctPath, "&UpdatedAt=").concat(date, "&CreatedAt=").concat(date); + } - case 21: + if (ifMatch) headers['If-Match'] = ifMatch; + _context31.next = 24; + return this.stackClient.fetchJSON(method, correctPath, data, { + headers: headers, + onUploadProgress: options.onUploadProgress + }); + + case 24: + resp = _context31.sent; + return _context31.abrupt("return", { + data: normalizeFile(resp.data) + }); + + case 26: case "end": - return _context9.stop(); + return _context31.stop(); } } - }, _callee9, this, [[5, 15, 18, 21]]); + }, _callee31, this); })); - function revokeSharingLink(_x9) { - return _revokeSharingLink.apply(this, arguments); + function doUpload(_x41, _x42, _x43) { + return _doUpload.apply(this, arguments); } - return revokeSharingLink; + return doUpload; }() /** - * async getOwnPermissions - deprecated: please use fetchOwnPermissions instead + * async findNotSynchronizedDirectories - Returns the list of directories not synchronized on the given OAuth client (mainly Cozy Desktop clients) — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#get-datatypedoc-idrelationshipsnot_synchronizing * - * @typedef {object} Permission + * @param {OAuthClient} oauthClient A JSON representing an OAuth client, with at least a `_type` and `_id` field. + * @param {object|null} options Pagination options + * @param {number|null} options.skip For skip-based pagination, the number of referenced files to skip. + * @param {number|null} options.limit For pagination, the number of results to return. + * @param {CouchDBViewCursor|null} options.cursor For cursor-based pagination, the index cursor. + * @param {boolean} options.includeFiles Include the whole file documents in the results list * - * @returns {Permission} permission + * @returns {Array<object|IOCozyFolder>} The JSON API conformant response. */ }, { - key: "getOwnPermissions", + key: "findNotSynchronizedDirectories", value: function () { - var _getOwnPermissions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10() { - return _regenerator.default.wrap(function _callee10$(_context10) { + var _findNotSynchronizedDirectories = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee32(oauthClient) { + var _ref10, + _ref10$skip, + skip, + limit, + cursor, + _ref10$includeFiles, + includeFiles, + params, + path, + url, + resp, + _args32 = arguments; + + return _regenerator.default.wrap(function _callee32$(_context32) { while (1) { - switch (_context10.prev = _context10.next) { + switch (_context32.prev = _context32.next) { case 0: - console.warn('getOwnPermissions is deprecated, please use fetchOwnPermissions instead'); - return _context10.abrupt("return", this.fetchOwnPermissions()); + _ref10 = _args32.length > 1 && _args32[1] !== undefined ? _args32[1] : {}, _ref10$skip = _ref10.skip, skip = _ref10$skip === void 0 ? 0 : _ref10$skip, limit = _ref10.limit, cursor = _ref10.cursor, _ref10$includeFiles = _ref10.includeFiles, includeFiles = _ref10$includeFiles === void 0 ? false : _ref10$includeFiles; + params = { + include: includeFiles ? 'files' : undefined, + 'page[limit]': limit, + 'page[cursor]': cursor, + sort: 'id' + }; + path = (0, _utils.uri)(_templateObject20(), oauthClient._type, oauthClient._id); + url = querystring.buildURL(path, params); + _context32.next = 6; + return this.stackClient.fetchJSON('GET', url); - case 2: + case 6: + resp = _context32.sent; + return _context32.abrupt("return", { + data: resp.data.map(function (f) { + return normalizeFile(f); + }), + included: resp.included ? resp.included.map(function (f) { + return normalizeFile(f); + }) : [], + next: (0, _has.default)(resp, 'links.next'), + meta: resp.meta, + skip: skip + }); + + case 8: case "end": - return _context10.stop(); + return _context32.stop(); } } - }, _callee10, this); + }, _callee32, this); })); - function getOwnPermissions() { - return _getOwnPermissions.apply(this, arguments); + function findNotSynchronizedDirectories(_x44) { + return _findNotSynchronizedDirectories.apply(this, arguments); } - return getOwnPermissions; + return findNotSynchronizedDirectories; }() /** - * async fetchOwnPermissions - Fetches permissions + * Add directory synchronization exclusions to an OAuth client — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#post-datatypedoc-idrelationshipsnot_synchronizing + * + * For example, to exclude directory `/Photos` from `My Computer`'s desktop synchronization: + * ``` + * addNotSynchronizedDirectories({_id: 123, _type: "io.cozy.oauth.clients", clientName: "Cozy Drive (My Computer)", clientKind: "desktop"}, [{_id: 456, _type: "io.cozy.files", name: "Photos", path: "/Photos"}]) + * ``` + * + * @param {OAuthClient} oauthClient A JSON representing the OAuth client + * @param {Array} directories An array of JSON documents having a `_type` and `_id` fields and representing directories. + * + * Returns 204 No Content + */ + + }, { + key: "addNotSynchronizedDirectories", + value: function addNotSynchronizedDirectories(oauthClient, directories) { + var refs = directories.map(function (d) { + return { + id: d._id, + type: d._type + }; + }); + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject21(), oauthClient._type, oauthClient._id), { + data: refs + }); + } + /** + * Remove directory synchronization exclusions from an OAuth client — see https://docs.cozy.io/en/cozy-stack/not-synchronized-vfs/#delete-datatypedoc-idrelationshipsnot_synchronizing + * + * For example, to re-include directory `/Photos` into `My Computer`'s desktop synchronization: + * ``` + * removeNotSynchronizedDirectories({_id: 123, _type: "io.cozy.oauth.clients", clientName: "Cozy Drive (My Computer)", clientKind: "desktop"}, [{_id: 456, _type: "io.cozy.files", name: "Photos", path: "/Photos"}]) + * ``` + * + * @param {OAuthClient} oauthClient A JSON representing the OAuth client + * @param {Array} directories An array of JSON documents having a `_type` and `_id` field and representing directories. + * + * Returns 204 No Content + */ + + }, { + key: "removeNotSynchronizedDirectories", + value: function removeNotSynchronizedDirectories(oauthClient, directories) { + var refs = directories.map(function (d) { + return { + id: d._id, + type: d._type + }; + }); + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject22(), oauthClient._type, oauthClient._id), { + data: refs + }); + } + /** + * Use cozy-stack's _changes API for io.cozy.files + * Design docs are filtered by default, thus documents are retrieved in the + * response (includeDocs is set to true in the parameters of _changes). + * Deleted and trashed documents can be filtered on demand and files' paths + * can be requested as well. + * + * Since deleted and trashed documents are skipped by cozy-stack rather than + * CouchDB, when either option is set to true, the response can contain less + * documents than the defined limit. Thus one should rely solely on the + * `pending` result attribute to determine if more documents can be fetched or + * not. + * + * You should use fetchChangesRaw to call CouchDB's _changes API. + * + * @typedef {object} CouchOptions + * @property {string} since - Bookmark telling CouchDB from which point in time should changes be returned + * @property {number} limit - The maximum number of returned documents for one call + * @property {boolean} includeDocs - Whether or not complete documents should be returned * - * @typedef {object} Permission + * @typedef {object} FetchChangesOptions + * @property {Array<string>} fields - The list of fields that should be returned for each document + * @property {boolean} includeFilePath - Whether to include the path of file changes (needs includeDocs to be true) + * @property {boolean} skipDeleted - Whether to skip changes for deleted documents + * @property {boolean} skipTrashed - Whether to skip changes for trashed documents (needs includeDocs to be true) * - * @returns {Permission} permission + * @param {CouchOptions} couchOptions - Couch options for changes + * @param {FetchChangesOptions} options - Further options on the returned documents. By default, it is set to + * { includeFilePath: false, skipDeleted: false, skipTrashed: false } + * + * @typedef {object} FetchChangesReturnValue + * @property {string} newLastSeq + * @property {boolean} pending + * @property {Array<object>} documents + * @returns {FetchChangesReturnValue} */ }, { - key: "fetchOwnPermissions", + key: "fetchChanges", value: function () { - var _fetchOwnPermissions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11() { - var resp; - return _regenerator.default.wrap(function _callee11$(_context11) { + var _fetchChanges = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee33() { + var couchOptions, + options, + opts, + params, + path, + url, + _yield$this$stackClie, + newLastSeq, + pending, + results, + _args33 = arguments; + + return _regenerator.default.wrap(function _callee33$(_context33) { while (1) { - switch (_context11.prev = _context11.next) { + switch (_context33.prev = _context33.next) { case 0: - _context11.next = 2; - return this.stackClient.fetchJSON('GET', '/permissions/self'); + couchOptions = _args33.length > 0 && _args33[0] !== undefined ? _args33[0] : {}; + options = _args33.length > 1 && _args33[1] !== undefined ? _args33[1] : {}; + opts = {}; - case 2: - resp = _context11.sent; - return _context11.abrupt("return", { - data: normalizePermission(resp.data), - included: resp.included ? resp.included.map(normalizePermission) : [] + if (typeof couchOptions !== 'object') { + opts.since = couchOptions; + console.warn("fetchChanges use couchOptions as Object not a string, since is deprecated, please use fetchChanges({since: \"".concat(couchOptions, "\"}).")); + } else if (Object.keys(couchOptions).length > 0) { + Object.assign(opts, couchOptions); + } + + if (Object.keys(options).length > 0) { + Object.assign(opts, options); + + if (options.skipTrashed || options.includeFilePath) { + opts.includeDocs = true; + } + } + + params = _objectSpread(_objectSpread({}, (0, _omit.default)(opts, ['fields', 'includeDocs', 'includeFilePath', 'skipDeleted', 'skipTrashed'])), {}, { + fields: opts.fields ? opts.fields.join(',') : null, + include_docs: opts.includeDocs, + include_file_path: opts.includeFilePath, + skip_deleted: opts.skipDeleted, + skip_trashed: opts.skipTrashed }); + path = (0, _utils.uri)(_templateObject23()); + url = querystring.buildURL(path, params); + _context33.next = 10; + return this.stackClient.fetchJSON('GET', url); - case 4: + case 10: + _yield$this$stackClie = _context33.sent; + newLastSeq = _yield$this$stackClie.last_seq; + pending = _yield$this$stackClie.pending; + results = _yield$this$stackClie.results; + return _context33.abrupt("return", { + newLastSeq: newLastSeq, + pending: pending, + results: results + }); + + case 15: case "end": - return _context11.stop(); + return _context33.stop(); } } - }, _callee11, this); + }, _callee33, this); })); - function fetchOwnPermissions() { - return _fetchOwnPermissions.apply(this, arguments); + function fetchChanges() { + return _fetchChanges.apply(this, arguments); } - return fetchOwnPermissions; + return fetchChanges; }() }]); - return PermissionCollection; + return FileCollection; }(_DocumentCollection2.default); + +var _default = FileCollection; +exports["default"] = _default; + +/***/ }), +/* 671 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +let Mime = __webpack_require__(672); +module.exports = new Mime(__webpack_require__(673)); + + +/***/ }), +/* 672 */ +/***/ ((module) => { + +"use strict"; + + /** - * Build a permission set + * @param typeMap [Object] Map of MIME type -> Array[extensions] + * @param ... + */ +function Mime() { + this._types = Object.create(null); + this._extensions = Object.create(null); + + for (let i = 0; i < arguments.length; i++) { + this.define(arguments[i]); + } + + this.define = this.define.bind(this); + this.getType = this.getType.bind(this); + this.getExtension = this.getExtension.bind(this); +} + +/** + * Define mimetype -> extension mappings. Each key is a mime-type that maps + * to an array of extensions associated with the type. The first extension is + * used as the default extension for the type. * - * @param {{_id, _type}} document - cozy document - * @param {boolean} publicLink - are the permissions for a public link ? - * @param {object} options - options - * @param {string[]} options.verbs - explicit permissions to use - * @returns {object} permissions object that can be sent through /permissions/* + * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); + * + * If a type declares an extension that has already been defined, an error will + * be thrown. To suppress this error and force the extension to be associated + * with the new type, pass `force`=true. Alternatively, you may prefix the + * extension with "*" to map the type to extension, without mapping the + * extension to the type. + * + * e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']}); + * + * + * @param map (Object) type definitions + * @param force (Boolean) if true, force overriding of existing definitions */ +Mime.prototype.define = function(typeMap, force) { + for (let type in typeMap) { + let extensions = typeMap[type].map(function(t) { + return t.toLowerCase(); + }); + type = type.toLowerCase(); + for (let i = 0; i < extensions.length; i++) { + const ext = extensions[i]; -var getPermissionsFor = function getPermissionsFor(document) { - var publicLink = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var _id = document._id, - _type = document._type; - var verbs = options.verbs ? options.verbs : publicLink ? ['GET'] : ['ALL']; // TODO: this works for albums, but it needs to be generalized and integrated - // with cozy-client ; some sort of doctype "schema" will be needed here + // '*' prefix = not the preferred type for this extension. So fixup the + // extension, and skip it. + if (ext[0] === '*') { + continue; + } - return (0, _FileCollection.isFile)(document) ? { - files: { - type: 'io.cozy.files', - verbs: verbs, - values: [_id] + if (!force && (ext in this._types)) { + throw new Error( + 'Attempt to change mapping for "' + ext + + '" extension from "' + this._types[ext] + '" to "' + type + + '". Pass `force=true` to allow this, otherwise remove "' + ext + + '" from the list of extensions for "' + type + '".' + ); + } + + this._types[ext] = type; } - } : { - collection: { - type: _type, - verbs: verbs, - values: [_id] - }, - files: { - type: 'io.cozy.files', - verbs: verbs, - values: ["".concat(_type, "/").concat(_id)], - selector: 'referenced_by' + + // Use first extension as default + if (force || !this._extensions[type]) { + const ext = extensions[0]; + this._extensions[type] = (ext[0] !== '*') ? ext : ext.substr(1); } - }; + } }; -exports.getPermissionsFor = getPermissionsFor; -PermissionCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; +/** + * Lookup a mime type based on extension + */ +Mime.prototype.getType = function(path) { + path = String(path); + let last = path.replace(/^.*[/\\]/, '').toLowerCase(); + let ext = last.replace(/^.*\./, '').toLowerCase(); -var isPermissionRelatedTo = function isPermissionRelatedTo(perm, document) { - var _id = document._id; - return (0, _FileCollection.isFile)(document) ? perm.attributes.permissions.files.values.indexOf(_id) !== -1 : perm.attributes.permissions.collection.values.indexOf(_id) !== -1; + let hasPath = last.length < path.length; + let hasDot = ext.length < last.length - 1; + + return (hasDot || !hasPath) && this._types[ext] || null; }; -var _default = PermissionCollection; -exports["default"] = _default; +/** + * Return file extension associated with a mime type + */ +Mime.prototype.getExtension = function(type) { + type = /^\s*([^;\s]*)/.test(type) && RegExp.$1; + return type && this._extensions[type.toLowerCase()] || null; +}; + +module.exports = Mime; + + +/***/ }), +/* 673 */ +/***/ ((module) => { + +module.exports = {"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomdeleted+xml":["atomdeleted"],"application/atomsvc+xml":["atomsvc"],"application/atsc-dwd+xml":["dwd"],"application/atsc-held+xml":["held"],"application/atsc-rsat+xml":["rsat"],"application/bdoc":["bdoc"],"application/calendar+xml":["xcs"],"application/ccxml+xml":["ccxml"],"application/cdfx+xml":["cdfx"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["ecma","es"],"application/emma+xml":["emma"],"application/emotionml+xml":["emotionml"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/fdt+xml":["fdt"],"application/font-tdpfr":["pfr"],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hjson":["hjson"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/its+xml":["its"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lgr+xml":["lgr"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mmt-aei+xml":["maei"],"application/mmt-usd+xml":["musd"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/mrb-consumer+xml":["*xdf"],"application/mrb-publish+xml":["*xdf"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/n-quads":["nq"],"application/n-triples":["nt"],"application/node":["cjs"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/p2p-overlay+xml":["relo"],"application/patch-ops-error+xml":["*xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/provenance+xml":["provx"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf","owl"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/route-apd+xml":["rapd"],"application/route-s-tsid+xml":["sls"],"application/route-usd+xml":["rusd"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/senml+xml":["senmlx"],"application/sensml+xml":["sensmlx"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/sieve":["siv","sieve"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/swid+xml":["swidtag"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/toml":["toml"],"application/ttml+xml":["ttml"],"application/ubjson":["ubj"],"application/urc-ressheet+xml":["rsheet"],"application/urc-targetdesc+xml":["td"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/xaml+xml":["xaml"],"application/xcap-att+xml":["xav"],"application/xcap-caps+xml":["xca"],"application/xcap-diff+xml":["xdf"],"application/xcap-el+xml":["xel"],"application/xcap-error+xml":["xer"],"application/xcap-ns+xml":["xns"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xliff+xml":["xlf"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["*xsl","xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":["*3gpp"],"audio/adpcm":["adp"],"audio/amr":["amr"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mobile-xmf":["mxmf"],"audio/mp3":["*mp3"],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx","opus"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/wav":["wav"],"audio/wave":["*wav"],"audio/webm":["weba"],"audio/xm":["xm"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/aces":["exr"],"image/apng":["apng"],"image/avif":["avif"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/dicom-rle":["drle"],"image/emf":["emf"],"image/fits":["fits"],"image/g3fax":["g3"],"image/gif":["gif"],"image/heic":["heic"],"image/heic-sequence":["heics"],"image/heif":["heif"],"image/heif-sequence":["heifs"],"image/hej2k":["hej2"],"image/hsj2":["hsj2"],"image/ief":["ief"],"image/jls":["jls"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jph":["jph"],"image/jphc":["jhc"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/jxr":["jxr"],"image/jxra":["jxra"],"image/jxrs":["jxrs"],"image/jxs":["jxs"],"image/jxsc":["jxsc"],"image/jxsi":["jxsi"],"image/jxss":["jxss"],"image/ktx":["ktx"],"image/ktx2":["ktx2"],"image/png":["png"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/t38":["t38"],"image/tiff":["tif","tiff"],"image/tiff-fx":["tfx"],"image/webp":["webp"],"image/wmf":["wmf"],"message/disposition-notification":["disposition-notification"],"message/global":["u8msg"],"message/global-delivery-status":["u8dsn"],"message/global-disposition-notification":["u8mdn"],"message/global-headers":["u8hdr"],"message/rfc822":["eml","mime"],"model/3mf":["3mf"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/mtl":["mtl"],"model/obj":["obj"],"model/stl":["stl"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["*x3db","x3dbz"],"model/x3d+fastinfoset":["x3db"],"model/x3d+vrml":["*x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"model/x3d-vrml":["x3dv"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/mdx":["mdx"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/richtext":["rtx"],"text/rtf":["*rtf"],"text/sgml":["sgml","sgm"],"text/shex":["shex"],"text/slim":["slim","slm"],"text/spdx":["spdx"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vtt":["vtt"],"text/xml":["*xml"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/iso.segment":["m4s"],"video/jpeg":["jpgv"],"video/jpm":["*jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/webm":["webm"]}; /***/ }), /* 674 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; +var baseHas = __webpack_require__(675), + hasPath = __webpack_require__(470); +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && hasPath(object, path, baseHas); +} -var _interopRequireDefault = __webpack_require__(512); +module.exports = has; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.SETTINGS_DOCTYPE = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +/***/ }), +/* 675 */ +/***/ ((module) => { -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +/** Used for built-in method references. */ +var objectProto = Object.prototype; -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && hasOwnProperty.call(object, key); +} -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +module.exports = baseHas; -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); +/***/ }), +/* 676 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +var basePick = __webpack_require__(677), + flatRest = __webpack_require__(632); -var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(601)); +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = flatRest(function(object, paths) { + return object == null ? {} : basePick(object, paths); +}); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +module.exports = pick; -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +/***/ }), +/* 677 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +var basePickBy = __webpack_require__(661), + hasIn = __webpack_require__(468); -var SETTINGS_DOCTYPE = 'io.cozy.settings'; /** - * Implements `DocumentCollection` API to interact with the /settings endpoint of the stack + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. */ +function basePick(object, paths) { + return basePickBy(object, paths, function(value, path) { + return hasIn(object, path); + }); +} -exports.SETTINGS_DOCTYPE = SETTINGS_DOCTYPE; - -var SettingsCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(SettingsCollection, _DocumentCollection); - - var _super = _createSuper(SettingsCollection); +module.exports = basePick; - function SettingsCollection(stackClient) { - (0, _classCallCheck2.default)(this, SettingsCollection); - return _super.call(this, SETTINGS_DOCTYPE, stackClient); - } - /** - * async get - Calls a route on the /settings API - * - * @param {string} path The setting route to call, eg `instance` or `context` - * @returns {object} The response from the route - */ +/***/ }), +/* 678 */ +/***/ ((__unused_webpack_module, exports) => { - (0, _createClass2.default)(SettingsCollection, [{ - key: "get", - value: function () { - var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(path) { - var resp; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return this.stackClient.fetchJSON('GET', "/settings/".concat(path)); +"use strict"; - case 2: - resp = _context.sent; - return _context.abrupt("return", { - data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SETTINGS_DOCTYPE)(_objectSpread({ - id: "/settings/".concat(path) - }, resp.data), resp) - }); - case 4: - case "end": - return _context.stop(); - } - } - }, _callee, this); - })); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getIllegalCharacters = void 0; - function get(_x) { - return _get.apply(this, arguments); - } +/** + * Get the list of illegal characters in the file name + * + * @public + * @param {string} name - the file name + * @returns {string} illegal characters separated by spaces + */ +var getIllegalCharacters = function getIllegalCharacters(name) { + var FILENAME_ILLEGAL_CHARACTERS = /\/|\x00|\n|\r/g; // eslint-disable-line no-control-regex - return get; - }() - }]); - return SettingsCollection; -}(_DocumentCollection2.default); + var match = name.match(FILENAME_ILLEGAL_CHARACTERS); + return match ? match.join(' ') : ''; +}; -SettingsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; -var _default = SettingsCollection; -exports["default"] = _default; +exports.getIllegalCharacters = getIllegalCharacters; /***/ }), -/* 675 */ +/* 679 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports.NOTES_URL_DOCTYPE = exports.NOTES_DOCTYPE = void 0; - -var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602)); - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +exports["default"] = exports.hasJobFinished = exports.normalizeJob = exports.JOBS_DOCTYPE = void 0; -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614)); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(601)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _utils = __webpack_require__(611); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _NotesSchema = __webpack_require__(676); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -function _templateObject2() { - var data = (0, _taggedTemplateLiteral2.default)(["/notes/", "/open"]); +var _Collection = _interopRequireDefault(__webpack_require__(612)); - _templateObject2 = function _templateObject2() { - return data; - }; +var _DocumentCollection = __webpack_require__(613); - return data; -} +var _utils = __webpack_require__(623); function _templateObject() { - var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); + var data = (0, _taggedTemplateLiteral2.default)(["/jobs/", ""]); _templateObject = function _templateObject() { return data; @@ -108541,975 +107947,628 @@ function _templateObject() { return data; } -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var NOTES_DOCTYPE = 'io.cozy.notes'; -exports.NOTES_DOCTYPE = NOTES_DOCTYPE; -var NOTES_URL_DOCTYPE = 'io.cozy.notes.url'; -exports.NOTES_URL_DOCTYPE = NOTES_URL_DOCTYPE; +var JOBS_DOCTYPE = 'io.cozy.jobs'; +exports.JOBS_DOCTYPE = JOBS_DOCTYPE; -var normalizeDoc = _DocumentCollection2.default.normalizeDoctypeJsonApi(NOTES_DOCTYPE); +var sleep = function sleep(delay) { + return new Promise(function (resolve) { + return setTimeout(resolve, delay); + }); +}; -var normalizeNote = function normalizeNote(note) { - return _objectSpread(_objectSpread({}, normalizeDoc(note, NOTES_DOCTYPE)), note.attributes); +var normalizeJob = function normalizeJob(job) { + return _objectSpread(_objectSpread(_objectSpread({}, job), (0, _DocumentCollection.normalizeDoc)(job, JOBS_DOCTYPE)), job.attributes); }; -var normalizeNoteUrl = function normalizeNoteUrl(noteUrl) { - return _objectSpread(_objectSpread({}, _DocumentCollection2.default.normalizeDoctypeJsonApi(NOTES_URL_DOCTYPE)(noteUrl)), noteUrl.attributes); +exports.normalizeJob = normalizeJob; + +var hasJobFinished = function hasJobFinished(job) { + return job.state === 'done' || job.state === 'errored'; }; /** - * Implements `DocumentCollection` API to interact with the /notes endpoint of the stack + * Document representing a io.cozy.jobs + * + * @typedef {object} JobDocument + * @property {string} _id - Id of the job + * @property {string} attributes.state - state of the job. Can be 'errored', 'running', 'queued', 'done' + * @property {string} attributes.error - Error message of the job if any */ -var NotesCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(NotesCollection, _DocumentCollection); - - var _super = _createSuper(NotesCollection); +exports.hasJobFinished = hasJobFinished; - function NotesCollection(stackClient) { - (0, _classCallCheck2.default)(this, NotesCollection); - return _super.call(this, NOTES_DOCTYPE, stackClient); +var JobCollection = /*#__PURE__*/function () { + function JobCollection(stackClient) { + (0, _classCallCheck2.default)(this, JobCollection); + this.stackClient = stackClient; } - /** - * Fetches all notes - * - * @returns {{data, links, meta}} The JSON API conformant response. - */ - - - (0, _createClass2.default)(NotesCollection, [{ - key: "all", - value: function () { - var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { - var resp; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return this.stackClient.fetchJSON('GET', '/notes'); - - case 2: - resp = _context.sent; - return _context.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { - data: resp.data.map(normalizeNote) - })); - - case 4: - case "end": - return _context.stop(); - } - } - }, _callee, this); - })); - - function all() { - return _all.apply(this, arguments); - } - - return all; - }() - /** - * Destroys the note on the server - * - * @param {object} note The io.cozy.notes document to destroy - * @param {string} [note._id] The note's id - * - * @returns {{ data }} The deleted note - */ - - }, { - key: "destroy", - value: function () { - var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref) { - var _id, resp; - - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _id = _ref._id; - _context2.next = 3; - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject(), _id)); - - case 3: - resp = _context2.sent; - return _context2.abrupt("return", { - data: _objectSpread(_objectSpread({}, normalizeNote(resp.data)), {}, { - _deleted: true - }) - }); - - case 5: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); - - function destroy(_x) { - return _destroy.apply(this, arguments); - } - return destroy; - }() + (0, _createClass2.default)(JobCollection, [{ + key: "queued", + value: function queued(workerType) { + return this.stackClient.fetchJSON('GET', "/jobs/queue/".concat(workerType)); + } /** - * Create a note - * - * @param {object} options - * @param {string} [options.dir_id] dir_id where to create the note + * Creates a job * - * @returns {{data, links, meta}} The JSON API conformant response. + * @param {string} workerType - Ex: "konnector" + * @param {object} [args={}] - Ex: {"slug": "my-konnector", "trigger": "trigger-id"} + * @param {object} [options={}] - creation options + * @param {boolean} [manual=false] - Manual execution + * @returns {object} createdJob */ }, { key: "create", - value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref2) { - var dir_id, resp; - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - dir_id = _ref2.dir_id; - _context3.next = 3; - return this.stackClient.fetchJSON('POST', '/notes', { - data: { - type: 'io.cozy.notes.documents', - attributes: { - title: '', - schema: (0, _NotesSchema.getDefaultSchema)(), - dir_id: dir_id - } - } - }); - - case 3: - resp = _context3.sent; - return _context3.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { - data: normalizeNote(resp.data) - })); - - case 5: - case "end": - return _context3.stop(); - } - } - }, _callee3, this); - })); - - function create(_x2) { - return _create.apply(this, arguments); - } - - return create; - }() - /** - * Returns the details to build the note's url - * - * @see https://github.com/cozy/cozy-stack/blob/master/docs/notes.md#get-notesidopen - * - * @param {object} note The io.cozy.notes document to open - * @param {string} [note._id] The note's id - * - * @returns {{ data }} The note's url details - */ - - }, { - key: "fetchURL", - value: function () { - var _fetchURL = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(_ref3) { - var _id, resp; - - return _regenerator.default.wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - _id = _ref3._id; - _context4.next = 3; - return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject2(), _id)); - - case 3: - resp = _context4.sent; - return _context4.abrupt("return", { - data: normalizeNoteUrl(resp.data) - }); - - case 5: - case "end": - return _context4.stop(); - } - } - }, _callee4, this); - })); - - function fetchURL(_x3) { - return _fetchURL.apply(this, arguments); - } - - return fetchURL; - }() - /** - * Returns promise mirror schema for a note - * - * @returns {object} schema - */ - - }, { - key: "getDefaultSchema", - value: function getDefaultSchema() { - return (0, _NotesSchema.getDefaultSchema)(); - } - }]); - return NotesCollection; -}(_DocumentCollection2.default); - -NotesCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; -var _default = NotesCollection; -exports["default"] = _default; - -/***/ }), -/* 676 */ -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.getDefaultSchema = exports.marks = exports.nodes = void 0; -// taken from a debug of @atlakit/editor/editor-core/create-editor/create-editor -// L139 (new Schema({nodes ,marks})) -// static because the @atlaskit code base requires a real navigator -// TODO: either find and exclude plugins requiring interaction -// or running a JSDOM faking a navigator -var nodes = [['doc', { - content: '(block)+', - marks: 'link' -}], ['paragraph', { - content: 'inline*', - group: 'block', - marks: 'strong code em link strike subsup textColor typeAheadQuery underline', - parseDOM: [{ - tag: 'p' - }] -}], ['text', { - group: 'inline' -}], ['bulletList', { - group: 'block', - content: 'listItem+', - parseDOM: [{ - tag: 'ul' - }] -}], ['orderedList', { - group: 'block', - content: 'listItem+', - parseDOM: [{ - tag: 'ol' - }] -}], ['listItem', { - content: '(paragraph ) (paragraph | bulletList | orderedList )*', - defining: true, - parseDOM: [{ - tag: 'li' - }] -}], ['heading', { - attrs: { - level: { - default: 1 - } - }, - content: 'inline*', - group: 'block', - defining: true, - parseDOM: [{ - tag: 'h1', - attrs: { - level: 1 - } - }, { - tag: 'h2', - attrs: { - level: 2 - } - }, { - tag: 'h3', - attrs: { - level: 3 - } - }, { - tag: 'h4', - attrs: { - level: 4 - } - }, { - tag: 'h5', - attrs: { - level: 5 - } - }, { - tag: 'h6', - attrs: { - level: 6 - } - }] -}], ['blockquote', { - content: 'paragraph+', - group: 'block', - defining: true, - selectable: false, - parseDOM: [{ - tag: 'blockquote' - }] -}], ['rule', { - group: 'block', - parseDOM: [{ - tag: 'hr' - }] -}], ['panel', { - group: 'block', - content: '(paragraph | heading | bulletList | orderedList)+', - attrs: { - panelType: { - default: 'info' - } - }, - parseDOM: [{ - tag: 'div[data-panel-type]' - }] -}], ['confluenceUnsupportedBlock', { - group: 'block', - attrs: { - cxhtml: { - default: null - } - }, - parseDOM: [{ - tag: 'div[data-node-type="confluenceUnsupportedBlock"]' - }] -}], ['confluenceUnsupportedInline', { - group: 'inline', - inline: true, - atom: true, - attrs: { - cxhtml: { - default: null - } - }, - parseDOM: [{ - tag: 'div[data-node-type="confluenceUnsupportedInline"]' - }] -}], ['unsupportedBlock', { - inline: false, - group: 'block', - atom: true, - selectable: true, - attrs: { - originalValue: { - default: {} - } - }, - parseDOM: [{ - tag: '[data-node-type="unsupportedBlock"]' - }] -}], ['unsupportedInline', { - inline: true, - group: 'inline', - selectable: true, - attrs: { - originalValue: { - default: {} - } - }, - parseDOM: [{ - tag: '[data-node-type="unsupportedInline"]' - }] -}], ['hardBreak', { - inline: true, - group: 'inline', - selectable: false, - parseDOM: [{ - tag: 'br' - }] -}], ['table', { - content: 'tableRow+', - attrs: { - isNumberColumnEnabled: { - default: false - }, - layout: { - default: 'default' - }, - __autoSize: { - default: false - } - }, - tableRole: 'table', - isolating: true, - selectable: false, - group: 'block', - parseDOM: [{ - tag: 'table' - }] -}], ['tableHeader', { - content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading )+', - attrs: { - colspan: { - default: 1 - }, - rowspan: { - default: 1 - }, - colwidth: { - default: null - }, - background: { - default: null - } - }, - tableRole: 'header_cell', - isolating: true, - marks: '', - parseDOM: [{ - tag: 'th' - }] -}], ['tableRow', { - content: '(tableCell | tableHeader)+', - tableRole: 'row', - parseDOM: [{ - tag: 'tr' - }] -}], ['tableCell', { - content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | unsupportedBlock)+', - attrs: { - colspan: { - default: 1 - }, - rowspan: { - default: 1 - }, - colwidth: { - default: null - }, - background: { - default: null - } - }, - tableRole: 'cell', - marks: '', - isolating: true, - parseDOM: [{ - tag: '.ak-renderer-table-number-column', - ignore: true - }, { - tag: 'td' - }] -}]]; -exports.nodes = nodes; -var marks = [['link', { - excludes: 'color', - group: 'link', - attrs: { - href: {}, - __confluenceMetadata: { - default: null - } - }, - inclusive: false, - parseDOM: [{ - tag: 'a[href]' - }] -}], ['em', { - inclusive: true, - group: 'fontStyle', - parseDOM: [{ - tag: 'i' - }, { - tag: 'em' - }, { - style: 'font-style=italic' - }] -}], ['strong', { - inclusive: true, - group: 'fontStyle', - parseDOM: [{ - tag: 'strong' - }, { - tag: 'b' - }, { - style: 'font-weight' - }] -}], ['textColor', { - attrs: { - color: {} - }, - inclusive: true, - group: 'color', - parseDOM: [{ - style: 'color' - }] -}], ['strike', { - inclusive: true, - group: 'fontStyle', - parseDOM: [{ - tag: 'strike' - }, { - tag: 's' - }, { - tag: 'del' - }, { - style: 'text-decoration' - }] -}], ['subsup', { - inclusive: true, - group: 'fontStyle', - attrs: { - type: { - default: 'sub' - } - }, - parseDOM: [{ - tag: 'sub', - attrs: { - type: 'sub' - } - }, { - tag: 'sup', - attrs: { - type: 'sup' - } - }] -}], ['underline', { - inclusive: true, - group: 'fontStyle', - parseDOM: [{ - tag: 'u' - }, { - style: 'text-decoration' - }] -}], ['code', { - excludes: 'fontStyle link searchQuery color', - inclusive: true, - parseDOM: [{ - tag: 'span.code', - preserveWhitespace: true - }, { - tag: 'code', - preserveWhitespace: true + value: function create(workerType) { + var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var manual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + return this.stackClient.fetchJSON('POST', "/jobs/queue/".concat(workerType), { + data: { + type: JOBS_DOCTYPE, + attributes: { + arguments: args, + options: options, + manual: manual + } + } + }); + } + /** + * Return a normalized job, given its id + * + * @param {string} id - id of the job + * @returns {JobDocument} + */ + }, { - tag: 'tt', - preserveWhitespace: true + key: "get", + value: function () { + var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(id) { + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + return _context.abrupt("return", _Collection.default.get(this.stackClient, (0, _utils.uri)(_templateObject(), id), { + normalize: normalizeJob + })); + + case 1: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function get(_x) { + return _get.apply(this, arguments); + } + + return get; + }() + /** + * Update the job's state + * This does work only for jobs comming from @client triggers + * + * @param {JobDocument} job - io.cozy.jobs document + */ + }, { - tag: 'span', - preserveWhitespace: true - }] -}], ['typeAheadQuery', { - excludes: 'searchQuery', - inclusive: true, - group: 'searchQuery', - parseDOM: [{ - tag: 'span[data-type-ahead-query]' - }], - attrs: { - trigger: { - default: '' - } - } -}]]; -exports.marks = marks; + key: "update", + value: function () { + var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(job) { + var jobResult; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (!(job.worker !== 'client')) { + _context2.next = 2; + break; + } -var getDefaultSchema = function getDefaultSchema() { - return { - nodes: nodes, - marks: marks - }; -}; + throw new Error("JobCollection.update only works for client workers. ".concat(job.worker, " given")); -exports.getDefaultSchema = getDefaultSchema; + case 2: + _context2.next = 4; + return this.stackClient.fetchJSON('PATCH', "/jobs/".concat(job._id), { + data: { + type: JOBS_DOCTYPE, + id: job._id, + attributes: { + state: job.attributes.state, + error: job.attributes.error + } + } + }); -/***/ }), -/* 677 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + case 4: + jobResult = _context2.sent; + return _context2.abrupt("return", normalizeJob(jobResult.data)); -"use strict"; + case 6: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + function update(_x2) { + return _update.apply(this, arguments); + } -var _interopRequireWildcard = __webpack_require__(510); + return update; + }() + /** + * Polls a job state until it is finished + * + * `options.until` can be used to tweak when to stop waiting. It will be + * given the current job state. If true is returned, the awaiting is + * stopped. + */ -var _interopRequireDefault = __webpack_require__(512); + }, { + key: "waitFor", + value: function () { + var _waitFor = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(id) { + var _ref, + _ref$onUpdate, + onUpdate, + _ref$until, + until, + _ref$delay, + delay, + _ref$timeout, + timeout, + start, + jobData, + now, + _args3 = arguments; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.OAUTH_CLIENTS_DOCTYPE = void 0; + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _ref = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {}, _ref$onUpdate = _ref.onUpdate, onUpdate = _ref$onUpdate === void 0 ? null : _ref$onUpdate, _ref$until = _ref.until, until = _ref$until === void 0 ? hasJobFinished : _ref$until, _ref$delay = _ref.delay, delay = _ref$delay === void 0 ? 5 * 1000 : _ref$delay, _ref$timeout = _ref.timeout, timeout = _ref$timeout === void 0 ? 60 * 5 * 1000 : _ref$timeout; + start = Date.now(); + _context3.next = 4; + return this.get(id); -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + case 4: + jobData = _context3.sent.data.attributes; -var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602)); + case 5: + if (!(!jobData || !until(jobData))) { + _context3.next = 17; + break; + } -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); + _context3.next = 8; + return sleep(delay); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + case 8: + _context3.next = 10; + return this.get(id); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + case 10: + jobData = _context3.sent.data.attributes; -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); + if (onUpdate) { + onUpdate(jobData); + } -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); + now = Date.now(); -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + if (!(start - now > timeout)) { + _context3.next = 15; + break; + } -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); + throw new Error('Timeout for JobCollection::waitFor'); -var _get2 = _interopRequireDefault(__webpack_require__(358)); + case 15: + _context3.next = 5; + break; -var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(601)); + case 17: + return _context3.abrupt("return", jobData); -var _utils = __webpack_require__(611); + case 18: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); -var querystring = _interopRequireWildcard(__webpack_require__(647)); + function waitFor(_x3) { + return _waitFor.apply(this, arguments); + } -var _Collection = __webpack_require__(600); + return waitFor; + }() + }]); + return JobCollection; +}(); -var _errors = __webpack_require__(651); +var _default = JobCollection; +exports["default"] = _default; -function _templateObject3() { - var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients/", ""]); +/***/ }), +/* 680 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - _templateObject3 = function _templateObject3() { - return data; - }; +"use strict"; - return data; -} -function _templateObject2() { - var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients/", ""]); +var _interopRequireWildcard = __webpack_require__(522); - _templateObject2 = function _templateObject2() { - return data; - }; +var _interopRequireDefault = __webpack_require__(524); - return data; -} +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.KONNECTORS_DOCTYPE = void 0; -function _templateObject() { - var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients"]); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - _templateObject = function _templateObject() { - return data; - }; +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - return data; -} +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var OAUTH_CLIENTS_DOCTYPE = 'io.cozy.oauth.clients'; -exports.OAUTH_CLIENTS_DOCTYPE = OAUTH_CLIENTS_DOCTYPE; +var _pick = _interopRequireDefault(__webpack_require__(676)); -var normalizeDoc = _DocumentCollection2.default.normalizeDoctypeJsonApi(OAUTH_CLIENTS_DOCTYPE); +var _AppCollection2 = _interopRequireDefault(__webpack_require__(602)); -var normalizeOAuthClient = function normalizeOAuthClient(client) { - return _objectSpread(_objectSpread({}, normalizeDoc(client, OAUTH_CLIENTS_DOCTYPE)), client.attributes); -}; -/** - * Implements `DocumentCollection` API to interact with the /settings/clients endpoint of the stack - */ +var _TriggerCollection = _interopRequireWildcard(__webpack_require__(681)); +var _DocumentCollection = __webpack_require__(613); -var OAuthClientsCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(OAuthClientsCollection, _DocumentCollection); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } - var _super = _createSuper(OAuthClientsCollection); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - function OAuthClientsCollection(stackClient) { - (0, _classCallCheck2.default)(this, OAuthClientsCollection); - return _super.call(this, OAUTH_CLIENTS_DOCTYPE, stackClient); - } - /** - * Fetches all OAuth clients - * - * @param {object} options Query options - * @param {number} [options.limit] For pagination, the number of results to return. - * @param {string} [options.bookmark] For bookmark-based pagination, the document _id to start from - * @param {Array<string>} [options.keys] Ids of specific clients to return (within the current page), - * - * @returns {object} The JSON API conformant response. - */ +var KONNECTORS_DOCTYPE = 'io.cozy.konnectors'; +exports.KONNECTORS_DOCTYPE = KONNECTORS_DOCTYPE; +var KonnectorCollection = /*#__PURE__*/function (_AppCollection) { + (0, _inherits2.default)(KonnectorCollection, _AppCollection); - (0, _createClass2.default)(OAuthClientsCollection, [{ - key: "all", - value: function () { - var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { - var options, - _options$limit, - limit, - bookmark, - keys, - params, - url, - path, - resp, - nextLink, - nextLinkURL, - nextBookmark, - hasBookmark, - data, - meta, - _args = arguments; + var _super = _createSuper(KonnectorCollection); + + function KonnectorCollection(stackClient) { + var _this; + + (0, _classCallCheck2.default)(this, KonnectorCollection); + _this = _super.call(this, stackClient); + _this.doctype = KONNECTORS_DOCTYPE; + _this.endpoint = '/konnectors/'; + return _this; + } + (0, _createClass2.default)(KonnectorCollection, [{ + key: "create", + value: function () { + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: - options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}; - _options$limit = options.limit, limit = _options$limit === void 0 ? 100 : _options$limit, bookmark = options.bookmark, keys = options.keys; - params = { - 'page[limit]': limit, - 'page[cursor]': bookmark - }; - url = (0, _utils.uri)(_templateObject()); - path = querystring.buildURL(url, params); - _context.prev = 5; - _context.next = 8; - return this.stackClient.fetchJSON('GET', path); + throw new Error('create() method is not available for konnectors'); - case 8: - resp = _context.sent; - _context.next = 14; - break; + case 1: + case "end": + return _context.stop(); + } + } + }, _callee); + })); - case 11: - _context.prev = 11; - _context.t0 = _context["catch"](5); - return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0)); + function create() { + return _create.apply(this, arguments); + } - case 14: - nextLink = (0, _get2.default)(resp, 'links.next', ''); - nextLinkURL = new URL("".concat(this.stackClient.uri).concat(nextLink)); - nextBookmark = nextLinkURL.searchParams.get('page[cursor]') || undefined; - hasBookmark = nextBookmark !== undefined; + return create; + }() + }, { + key: "destroy", + value: function () { + var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + throw new Error('destroy() method is not available for konnectors'); - if (!keys) { - _context.next = 24; - break; - } + case 1: + case "end": + return _context2.stop(); + } + } + }, _callee2); + })); - data = resp.data.filter(function (c) { - return keys.includes(c.id); - }).map(function (c) { - return normalizeOAuthClient(c); - }); - meta = _objectSpread(_objectSpread({}, resp.meta), {}, { - count: data.length - }); - return _context.abrupt("return", { - data: data, - meta: meta, - next: keys.length > data.length && hasBookmark, - bookmark: nextBookmark - }); + function destroy() { + return _destroy.apply(this, arguments); + } - case 24: - return _context.abrupt("return", { - data: resp.data.map(function (c) { - return normalizeOAuthClient(c); - }), - meta: resp.meta, - next: hasBookmark, - bookmark: nextBookmark + return destroy; + }() + /** + * Find triggers for a particular konnector + * + * @param {string} slug of the konnector + */ + + }, { + key: "findTriggersBySlug", + value: function () { + var _findTriggersBySlug = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(slug) { + var triggerCol, _yield$triggerCol$all, rawTriggers; + + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + triggerCol = new _TriggerCollection.default(this.stackClient); + _context3.next = 3; + return triggerCol.all({ + limit: null }); - case 25: + case 3: + _yield$triggerCol$all = _context3.sent; + rawTriggers = _yield$triggerCol$all.data; + return _context3.abrupt("return", rawTriggers.map(function (x) { + return x.attributes; + }).filter(function (triggerAttrs) { + return (0, _TriggerCollection.isForKonnector)(triggerAttrs, slug); + })); + + case 6: case "end": - return _context.stop(); + return _context3.stop(); } } - }, _callee, this, [[5, 11]]); + }, _callee3, this); })); - function all() { - return _all.apply(this, arguments); + function findTriggersBySlug(_x) { + return _findTriggersBySlug.apply(this, arguments); } - return all; + return findTriggersBySlug; }() /** - * Get an OAuth client by id + * Launch a trigger for a given konnector. * - * @param {string} id The client id. - * @returns {object} JsonAPI response containing normalized client as data attribute + * @param {string} slug + * @param {object} options + * @param {object} options.accountId - Pinpoint the account that should be used, useful if the user + * has more than 1 account for 1 konnector */ }, { - key: "get", + key: "launch", value: function () { - var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) { - var resp; - return _regenerator.default.wrap(function _callee2$(_context2) { + var _launch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(slug) { + var options, + triggerCol, + konnTriggers, + filteredTriggers, + filterAttrs, + _args4 = arguments; + return _regenerator.default.wrap(function _callee4$(_context4) { while (1) { - switch (_context2.prev = _context2.next) { + switch (_context4.prev = _context4.next) { case 0: - _context2.next = 2; - return this.all({ - keys: [id] - }); + options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {}; + triggerCol = new _TriggerCollection.default(this.stackClient); + _context4.next = 4; + return this.findTriggersBySlug(slug); - case 2: - resp = _context2.sent; + case 4: + konnTriggers = _context4.sent; + filteredTriggers = options.accountId ? konnTriggers.filter(function (triggerAttrs) { + return (0, _TriggerCollection.isForAccount)(triggerAttrs, options.accountId); + }) : konnTriggers; - case 3: - if (!resp.next) { - _context2.next = 9; + if (!(filteredTriggers.length === 1)) { + _context4.next = 10; break; } - _context2.next = 6; - return this.all({ - keys: [id], - bookmark: resp.bookmark - }); + return _context4.abrupt("return", triggerCol.launch(konnTriggers[0])); - case 6: - resp = _context2.sent; - _context2.next = 3; - break; + case 10: + filterAttrs = JSON.stringify((0, _pick.default)({ + slug: slug, + accountId: options.accountId + })); - case 9: - if (!resp.data.length) { - _context2.next = 13; + if (!(filteredTriggers.length === 0)) { + _context4.next = 15; break; } - return _context2.abrupt("return", { - data: normalizeOAuthClient(resp.data[0]) - }); + throw new Error("No trigger found for ".concat(filterAttrs)); - case 13: - resp.url = (0, _utils.uri)(_templateObject2(), id); - resp.status = '404'; - throw new _errors.FetchError(resp, 'Not Found'); + case 15: + if (!(filteredTriggers.length > 1)) { + _context4.next = 17; + break; + } - case 16: + throw new Error("More than 1 trigger found for ".concat(filterAttrs)); + + case 17: case "end": - return _context2.stop(); + return _context4.stop(); } } - }, _callee2, this); + }, _callee4, this); })); - function get(_x) { - return _get.apply(this, arguments); + function launch(_x2) { + return _launch.apply(this, arguments); } - return get; + return launch; }() /** - * Destroys the OAuth client on the server - * - * @param {object} oauthClient The io.cozy.oauth.clients document to destroy + * Updates a konnector * - * @returns {{ data }} The deleted client + * @param {string} slug + * @param {object} options + * @param {object} options.source - Specify the source (ex: registry://slug/stable) + * @param {boolean} options.sync - Wait for konnector to be updated, otherwise the job + * is just scheduled */ }, { - key: "destroy", + key: "update", value: function () { - var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(oauthClient) { - var _id; - - return _regenerator.default.wrap(function _callee3$(_context3) { + var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(slug) { + var options, + source, + sync, + reqOptions, + rawKonnector, + _args5 = arguments; + return _regenerator.default.wrap(function _callee5$(_context5) { while (1) { - switch (_context3.prev = _context3.next) { + switch (_context5.prev = _context5.next) { case 0: - _id = oauthClient._id; - _context3.next = 3; - return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject3(), _id)); + options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {}; + + if (slug) { + _context5.next = 3; + break; + } + + throw new Error('Cannot call update with no slug'); case 3: - return _context3.abrupt("return", { - data: _objectSpread(_objectSpread({}, normalizeOAuthClient(oauthClient)), {}, { - _deleted: true - }) - }); + source = options.source || null; + sync = options.sync || false; + reqOptions = sync ? { + headers: { + Accept: 'text/event-stream' + } + } : {}; + _context5.next = 8; + return this.stackClient.fetchJSON('PUT', "/konnectors/".concat(slug) + (source ? "?Source=".concat(source) : ''), reqOptions); - case 4: + case 8: + rawKonnector = _context5.sent; + return _context5.abrupt("return", (0, _DocumentCollection.normalizeDoc)(rawKonnector)); + + case 10: case "end": - return _context3.stop(); + return _context5.stop(); } } - }, _callee3, this); + }, _callee5, this); })); - function destroy(_x2) { - return _destroy.apply(this, arguments); + function update(_x3) { + return _update.apply(this, arguments); } - return destroy; + return update; }() }]); - return OAuthClientsCollection; -}(_DocumentCollection2.default); + return KonnectorCollection; +}(_AppCollection2.default); -OAuthClientsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; -var _default = OAuthClientsCollection; +var _default = KonnectorCollection; exports["default"] = _default; /***/ }), -/* 678 */ +/* 681 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireWildcard = __webpack_require__(522); + +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports.SHORTCUTS_DOCTYPE = void 0; +exports["default"] = exports.isForAccount = exports.isForKonnector = exports.normalizeTrigger = exports.TRIGGERS_DOCTYPE = exports.JOBS_DOCTYPE = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537)); -var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(602)); +var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); +var _get3 = _interopRequireDefault(__webpack_require__(682)); + +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); + +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); + +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); + +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); + +var _Collection = _interopRequireWildcard(__webpack_require__(612)); + +var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613)); + +var _JobCollection = __webpack_require__(679); + +var _utils = __webpack_require__(623); + +var _errors = __webpack_require__(663); + +function _templateObject4() { + var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", "/launch"]); + + _templateObject4 = function _templateObject4() { + return data; + }; -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + return data; +} -var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(601)); +function _templateObject3() { + var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", ""]); -var _utils = __webpack_require__(611); + _templateObject3 = function _templateObject3() { + return data; + }; -var _getIllegalCharacter = __webpack_require__(666); + return data; +} function _templateObject2() { - var data = (0, _taggedTemplateLiteral2.default)(["/shortcuts/", ""]); + var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers/", ""]); _templateObject2 = function _templateObject2() { return data; @@ -109519,7 +108578,7 @@ function _templateObject2() { } function _templateObject() { - var data = (0, _taggedTemplateLiteral2.default)(["/shortcuts"]); + var data = (0, _taggedTemplateLiteral2.default)(["/jobs/triggers"]); _templateObject = function _templateObject() { return data; @@ -109532,116 +108591,155 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -var SHORTCUTS_DOCTYPE = 'io.cozy.files.shortcuts'; -exports.SHORTCUTS_DOCTYPE = SHORTCUTS_DOCTYPE; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -var ShortcutsCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(ShortcutsCollection, _DocumentCollection); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - var _super = _createSuper(ShortcutsCollection); +var JOBS_DOCTYPE = 'io.cozy.jobs'; +exports.JOBS_DOCTYPE = JOBS_DOCTYPE; +var TRIGGERS_DOCTYPE = 'io.cozy.triggers'; +exports.TRIGGERS_DOCTYPE = TRIGGERS_DOCTYPE; - function ShortcutsCollection(stackClient) { - (0, _classCallCheck2.default)(this, ShortcutsCollection); - return _super.call(this, SHORTCUTS_DOCTYPE, stackClient); - } - /** - * Create a shortcut - * - * @param {object} attributes shortcut's attributes - * @param {string} attributes.name Filename - * @param {string} attributes.url Shortcut's URL - * @param {string} attributes.dir_id dir_id where to create the shortcut - * @throws {Error} - explaining reason why creation failed - */ +var normalizeTrigger = function normalizeTrigger(trigger) { + return _objectSpread(_objectSpread(_objectSpread({}, trigger), (0, _DocumentCollection2.normalizeDoc)(trigger, TRIGGERS_DOCTYPE)), trigger.attributes); +}; +exports.normalizeTrigger = normalizeTrigger; - (0, _createClass2.default)(ShortcutsCollection, [{ - key: "create", - value: function () { - var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(attributes) { - var name, illegalCharacters, path, resp; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - if (!attributes.type) { - attributes.type = SHORTCUTS_DOCTYPE; - } +var isForKonnector = function isForKonnector(triggerAttrs, slug) { + return triggerAttrs.worker === 'konnector' && triggerAttrs.message.konnector == slug; +}; - if (!(!attributes.name || !attributes.name.trim() || !attributes.url || !attributes.dir_id)) { - _context.next = 3; - break; - } +exports.isForKonnector = isForKonnector; - throw new Error('you need at least a name, an url and a dir_id attributes to create a shortcut'); +var isForAccount = function isForAccount(triggerAttrs, accountId) { + return triggerAttrs.message.account == accountId; +}; - case 3: - name = attributes.name.trim(); +exports.isForAccount = isForAccount; - if (!(name === '.' || name === '..')) { - _context.next = 6; - break; - } +var buildParamsUrl = function buildParamsUrl(worker, type) { + var urlParams = new URLSearchParams(); - throw new Error("Invalid filename: ".concat(name)); + if (worker) { + if (Array.isArray(worker.$in)) { + urlParams.set('Worker', worker.$in.join(',')); + } else { + urlParams.set('Worker', worker); + } + } - case 6: - illegalCharacters = (0, _getIllegalCharacter.getIllegalCharacters)(name); + if (type) { + if (Array.isArray(type.$in)) { + urlParams.set('Type', type.$in.join(',')); + } else { + urlParams.set('Type', type); + } + } - if (!illegalCharacters.length) { - _context.next = 9; - break; - } + return urlParams.toString(); +}; +/** + * Implements `DocumentCollection` API along with specific methods for `io.cozy.triggers`. + */ - throw new Error("Invalid filename containing illegal character(s): ".concat(illegalCharacters)); - case 9: - path = (0, _utils.uri)(_templateObject()); - _context.next = 12; - return this.stackClient.fetchJSON('POST', path, { - data: { - attributes: attributes, - type: 'io.cozy.files.shortcuts' - } - }); +var TriggerCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(TriggerCollection, _DocumentCollection); - case 12: + var _super = _createSuper(TriggerCollection); + + function TriggerCollection(stackClient) { + (0, _classCallCheck2.default)(this, TriggerCollection); + return _super.call(this, TRIGGERS_DOCTYPE, stackClient); + } + /** + * Get the list of triggers. + * + * @see https://docs.cozy.io/en/cozy-stack/jobs/#get-jobstriggers + * @param {{Worker}} options The fetch options: Worker allow to filter only triggers associated with a specific worker. + * @returns {{data}} The JSON API conformant response. + * @throws {FetchError} + */ + + + (0, _createClass2.default)(TriggerCollection, [{ + key: "all", + value: function () { + var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { + var options, + resp, + _args = arguments; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}; + _context.prev = 1; + _context.next = 4; + return this.stackClient.fetchJSON('GET', "/jobs/triggers"); + + case 4: resp = _context.sent; return _context.abrupt("return", { - data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SHORTCUTS_DOCTYPE)(resp.data, resp) + data: resp.data.map(function (row) { + return normalizeTrigger(row, TRIGGERS_DOCTYPE); + }), + meta: { + count: resp.data.length + }, + next: false, + skip: 0 }); - case 14: + case 8: + _context.prev = 8; + _context.t0 = _context["catch"](1); + return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0)); + + case 11: case "end": return _context.stop(); } } - }, _callee, this); + }, _callee, this, [[1, 8]]); })); - function create(_x) { - return _create.apply(this, arguments); + function all() { + return _all.apply(this, arguments); } - return create; + return all; }() + /** + * Creates a Trigger document + * + * @see https://docs.cozy.io/en/cozy-stack/jobs/#post-jobstriggers + * @param {object} attributes Trigger's attributes + * @returns {object} Stack response, containing trigger document under `data` attribute. + */ + }, { - key: "get", + key: "create", value: function () { - var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) { + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(attributes) { var path, resp; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: - path = (0, _utils.uri)(_templateObject2(), id); + path = (0, _utils.uri)(_templateObject()); _context2.next = 3; - return this.stackClient.fetchJSON('GET', path); + return this.stackClient.fetchJSON('POST', path, { + data: { + attributes: attributes + } + }); case 3: resp = _context2.sent; return _context2.abrupt("return", { - data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SHORTCUTS_DOCTYPE)(resp.data, resp) + data: normalizeTrigger(resp.data) }); case 5: @@ -109652,1112 +108750,1109 @@ var ShortcutsCollection = /*#__PURE__*/function (_DocumentCollection) { }, _callee2, this); })); - function get(_x2) { - return _get.apply(this, arguments); + function create(_x) { + return _create.apply(this, arguments); } - return get; + return create; }() - }]); - return ShortcutsCollection; -}(_DocumentCollection2.default); - -ShortcutsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; -var _default = ShortcutsCollection; -exports["default"] = _default; - -/***/ }), -/* 679 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; + /** + * Deletes a trigger + * + * @see https://docs.cozy.io/en/cozy-stack/jobs/#delete-jobstriggerstrigger-id + * @param {object} document The trigger to delete — must have an _id field + * @returns {object} The deleted document + */ + }, { + key: "destroy", + value: function () { + var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document) { + var _id; -var _interopRequireWildcard = __webpack_require__(510); + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _id = document._id; -var _interopRequireDefault = __webpack_require__(512); + if (_id) { + _context3.next = 3; + break; + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.CONTACTS_DOCTYPE = void 0; + throw new Error('TriggerCollection.destroy needs a document with an _id'); -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + case 3: + _context3.next = 5; + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject2(), _id)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); + case 5: + return _context3.abrupt("return", { + data: normalizeTrigger(_objectSpread(_objectSpread({}, document), {}, { + _deleted: true + })) + }); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + case 6: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + function destroy(_x2) { + return _destroy.apply(this, arguments); + } -var _get2 = _interopRequireDefault(__webpack_require__(670)); + return destroy; + }() + /** + * + * Be warned, ATM /jobs/triggers does not return the same informations + * than /data/io.cozy.triggers (used by the super.find method). + * + * See https://github.com/cozy/cozy-stack/pull/2010 + * + * @param {object} selector - Which kind of worker {konnector,service} + * @param {object} options - Options + * @returns {{data, meta, skip, next}} The JSON API conformant response. + * @throws {FetchError} + */ -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); + }, { + key: "find", + value: function () { + var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() { + var selector, + options, + worker, + type, + rest, + hasOnlyWorkerAndType, + url, + resp, + _args4 = arguments; + return _regenerator.default.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + selector = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {}; + options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {}; + worker = selector.worker, type = selector.type, rest = (0, _objectWithoutProperties2.default)(selector, ["worker", "type"]); + hasOnlyWorkerAndType = Object.keys(rest).length === 0; -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); + if (!hasOnlyWorkerAndType) { + _context4.next = 18; + break; + } -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + // @see https://github.com/cozy/cozy-stack/blob/master/docs/jobs.md#get-jobstriggers + url = "/jobs/triggers?".concat(buildParamsUrl(worker, type)); + _context4.prev = 6; + _context4.next = 9; + return this.stackClient.fetchJSON('GET', url); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); + case 9: + resp = _context4.sent; + return _context4.abrupt("return", { + data: resp.data.map(function (row) { + return normalizeTrigger(row, TRIGGERS_DOCTYPE); + }), + meta: { + count: resp.data.length + }, + next: false, + skip: 0 + }); -var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(601)); + case 13: + _context4.prev = 13; + _context4.t0 = _context4["catch"](6); + return _context4.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context4.t0)); -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } + case 16: + _context4.next = 19; + break; -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + case 18: + return _context4.abrupt("return", (0, _get3.default)((0, _getPrototypeOf2.default)(TriggerCollection.prototype), "find", this).call(this, selector, options)); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + case 19: + case "end": + return _context4.stop(); + } + } + }, _callee4, this, [[6, 13]]); + })); -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + function find() { + return _find.apply(this, arguments); + } -var normalizeMyselfResp = function normalizeMyselfResp(resp) { - return _objectSpread(_objectSpread(_objectSpread({}, (0, _DocumentCollection2.normalizeDoc)(resp.data, CONTACTS_DOCTYPE)), resp.data.attributes), {}, { - _rev: resp.data.meta.rev - }); -}; + return find; + }() + }, { + key: "get", + value: function () { + var _get2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(id) { + return _regenerator.default.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + return _context5.abrupt("return", _Collection.default.get(this.stackClient, (0, _utils.uri)(_templateObject3(), id), { + normalize: normalizeTrigger + })); -var ContactsCollection = /*#__PURE__*/function (_DocumentCollection) { - (0, _inherits2.default)(ContactsCollection, _DocumentCollection); + case 1: + case "end": + return _context5.stop(); + } + } + }, _callee5, this); + })); - var _super = _createSuper(ContactsCollection); + function get(_x3) { + return _get2.apply(this, arguments); + } - function ContactsCollection() { - (0, _classCallCheck2.default)(this, ContactsCollection); - return _super.apply(this, arguments); - } + return get; + }() + /** + * Force given trigger execution. + * + * @see https://docs.cozy.io/en/cozy-stack/jobs/#post-jobstriggerstrigger-idlaunch + * @param {object} trigger Trigger to launch + * @returns {object} Stack response, containing job launched by trigger, under `data` attribute. + */ - (0, _createClass2.default)(ContactsCollection, [{ - key: "find", + }, { + key: "launch", value: function () { - var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(selector, options) { - return _regenerator.default.wrap(function _callee$(_context) { + var _launch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(trigger) { + var path, resp; + return _regenerator.default.wrap(function _callee6$(_context6) { while (1) { - switch (_context.prev = _context.next) { + switch (_context6.prev = _context6.next) { case 0: - if (!(Object.values(selector).length === 1 && selector['me'] == true)) { - _context.next = 4; - break; - } - - return _context.abrupt("return", this.findMyself()); + path = (0, _utils.uri)(_templateObject4(), trigger._id); + _context6.next = 3; + return this.stackClient.fetchJSON('POST', path); - case 4: - return _context.abrupt("return", (0, _get2.default)((0, _getPrototypeOf2.default)(ContactsCollection.prototype), "find", this).call(this, selector, options)); + case 3: + resp = _context6.sent; + return _context6.abrupt("return", { + data: (0, _JobCollection.normalizeJob)(resp.data) + }); case 5: case "end": - return _context.stop(); + return _context6.stop(); } } - }, _callee, this); + }, _callee6, this); })); - function find(_x, _x2) { - return _find.apply(this, arguments); + function launch(_x4) { + return _launch.apply(this, arguments); } - return find; + return launch; }() }, { - key: "findMyself", + key: "update", value: function () { - var _findMyself = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { - var resp, col; - return _regenerator.default.wrap(function _callee2$(_context2) { + var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7() { + return _regenerator.default.wrap(function _callee7$(_context7) { while (1) { - switch (_context2.prev = _context2.next) { + switch (_context7.prev = _context7.next) { case 0: - _context2.next = 2; - return this.stackClient.fetchJSON('POST', '/contacts/myself'); - - case 2: - resp = _context2.sent; - col = { - data: [normalizeMyselfResp(resp)], - next: false, - meta: null, - bookmark: false - }; - return _context2.abrupt("return", col); + throw new Error('update() method is not available for triggers'); - case 5: + case 1: case "end": - return _context2.stop(); + return _context7.stop(); } } - }, _callee2, this); + }, _callee7); })); - function findMyself() { - return _findMyself.apply(this, arguments); + function update() { + return _update.apply(this, arguments); } - return findMyself; + return update; }() }]); - return ContactsCollection; + return TriggerCollection; }(_DocumentCollection2.default); -var CONTACTS_DOCTYPE = 'io.cozy.contacts'; -exports.CONTACTS_DOCTYPE = CONTACTS_DOCTYPE; -var _default = ContactsCollection; +TriggerCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; +var _default = TriggerCollection; exports["default"] = _default; /***/ }), -/* 680 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/* 682 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; +var superPropBase = __webpack_require__(683); +function _get(target, property, receiver) { + if (typeof Reflect !== "undefined" && Reflect.get) { + module.exports = _get = Reflect.get; + module.exports["default"] = module.exports, module.exports.__esModule = true; + } else { + module.exports = _get = function _get(target, property, receiver) { + var base = superPropBase(target, property); + if (!base) return; + var desc = Object.getOwnPropertyDescriptor(base, property); -var _interopRequireWildcard = __webpack_require__(510); + if (desc.get) { + return desc.get.call(receiver); + } -var _interopRequireDefault = __webpack_require__(512); + return desc.value; + }; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.getIconURL = exports["default"] = exports._getIconURL = void 0; + module.exports["default"] = module.exports, module.exports.__esModule = true; + } -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + return _get(target, property, receiver || target); +} -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +module.exports = _get; +module.exports["default"] = module.exports, module.exports.__esModule = true; -var _memoize = _interopRequireWildcard(__webpack_require__(681)); +/***/ }), +/* 683 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } +var getPrototypeOf = __webpack_require__(607); -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function _superPropBase(object, property) { + while (!Object.prototype.hasOwnProperty.call(object, property)) { + object = getPrototypeOf(object); + if (object === null) break; + } -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + return object; +} -/** - * Get Icon source Url - * - * @param {object} app - Apps data - io.cozy.apps - * @param {string} slug - Slug - string - * @param {string|undefined} domain - Host to use in the origin (e.g. cozy.tools) - * @param {string} protocol - Url protocol (e.g. http / https) - * @returns {string} Source Url of icon - * @private - * @throws {Error} When cannot fetch or get icon source - */ -var loadIcon = /*#__PURE__*/function () { - var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(app, slug, domain, protocol) { - var source; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - if (domain) { - _context.next = 2; - break; - } +module.exports = _superPropBase; +module.exports["default"] = module.exports, module.exports.__esModule = true; - throw new Error('Cannot fetch icon: missing domain'); +/***/ }), +/* 684 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - case 2: - source = _getAppIconURL(app, slug, domain, protocol); +"use strict"; - if (source) { - _context.next = 5; - break; - } - throw new Error("Cannot get icon source for app ".concat(app.name)); +var _interopRequireWildcard = __webpack_require__(522); - case 5: - return _context.abrupt("return", source); +var _interopRequireDefault = __webpack_require__(524); - case 6: - case "end": - return _context.stop(); - } - } - }, _callee); - })); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.getSharingRules = exports.BITWARDEN_CIPHERS_DOCTYPE = exports.BITWARDEN_ORGANIZATIONS_DOCTYPE = exports.SHARING_DOCTYPE = void 0; - return function loadIcon(_x, _x2, _x3, _x4) { - return _ref.apply(this, arguments); - }; -}(); -/** - * Get App Icon URL - * - * @param {object} app - Apps data - io.cozy.apps or Slug - string - * @param {string} slug - Slug - string - * @param {string|undefined} domain - Host to use in the origin (e.g. cozy.tools) - * @param {string} protocol - Url protocol (e.g. http / https) - * @private - * @returns {string|null} App Icon URL - */ +var _regenerator = _interopRequireDefault(__webpack_require__(539)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _getAppIconURL = function _getAppIconURL(app, slug, domain, protocol) { - var path = app && app.links && app.links.icon || _getRegistryIconPath(app, slug); +var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614)); - return path ? "".concat(protocol, "//").concat(domain).concat(path) : null; -}; -/** - * Get Registry Icon Path - * - * @param {object} app - Apps data - io.cozy.apps or Slug - string - * @param {string} slug - Slug - string - * @returns {string|undefined} Registry icon path - * @private - */ +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _getRegistryIconPath = function _getRegistryIconPath(app, slug) { - if (slug) { - return "/registry/".concat(slug, "/icon"); - } +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - return app && app.latest_version && app.latest_version.version && "/registry/".concat(app.slug, "/").concat(app.latest_version.version, "/icon"); -}; +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -var mimeTypes = { - gif: 'image/gif', - ico: 'image/vnd.microsoft.icon', - jpeg: 'image/jpeg', - jpg: 'image/jpeg', - png: 'image/png', - svg: 'image/svg+xml' -}; -/** - * Get icon extension - * - * @param {object} app io.cozy.apps or io.cozy.konnectors document - * @param {string} app.icon - App Icon - * @param {string} app.name - App Name - * @returns {string} icon extension - * @private - * @throws {Error} When problem while detecting icon mime type - */ +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var getIconExtensionFromApp = function getIconExtensionFromApp(app) { - if (!app.icon) { - throw new Error("".concat(app.name, ": Cannot detect icon mime type since app has no icon")); - } +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); - var extension = app.icon.split('.').pop(); +var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613)); - if (!extension) { - throw new Error("".concat(app.name, ": Unable to detect icon mime type from extension (").concat(app.icon, ")")); - } +var _FileCollection = __webpack_require__(670); - return extension; -}; +var _utils = __webpack_require__(623); -var fallbacks = /*#__PURE__*/function () { - var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(tries, check) { - var err, _iterator, _step, _try, res; +function _templateObject6() { + var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients"]); - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _iterator = _createForOfIteratorHelper(tries); - _context2.prev = 1; + _templateObject6 = function _templateObject6() { + return data; + }; - _iterator.s(); + return data; +} - case 3: - if ((_step = _iterator.n()).done) { - _context2.next = 18; - break; - } +function _templateObject5() { + var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients/self"]); - _try = _step.value; - _context2.prev = 5; - _context2.next = 8; - return _try(); + _templateObject5 = function _templateObject5() { + return data; + }; - case 8: - res = _context2.sent; - check && check(res); - return _context2.abrupt("return", res); + return data; +} - case 13: - _context2.prev = 13; - _context2.t0 = _context2["catch"](5); - err = _context2.t0; +function _templateObject4() { + var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients/", ""]); - case 16: - _context2.next = 3; - break; + _templateObject4 = function _templateObject4() { + return data; + }; - case 18: - _context2.next = 23; - break; + return data; +} - case 20: - _context2.prev = 20; - _context2.t1 = _context2["catch"](1); +function _templateObject3() { + var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", "/recipients"]); - _iterator.e(_context2.t1); + _templateObject3 = function _templateObject3() { + return data; + }; - case 23: - _context2.prev = 23; + return data; +} - _iterator.f(); +function _templateObject2() { + var data = (0, _taggedTemplateLiteral2.default)(["/sharings/", ""]); - return _context2.finish(23); + _templateObject2 = function _templateObject2() { + return data; + }; - case 26: - throw err; + return data; +} - case 27: - case "end": - return _context2.stop(); - } - } - }, _callee2, null, [[1, 20, 23, 26], [5, 13]]); - })); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - return function fallbacks(_x5, _x6) { - return _ref2.apply(this, arguments); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _templateObject() { + var data = (0, _taggedTemplateLiteral2.default)(["/sharings/doctype/", ""]); + + _templateObject = function _templateObject() { + return data; }; -}(); -/** - * Fetch application/konnector that is installed - * - * @private - */ + return data; +} -var fetchAppOrKonnector = function fetchAppOrKonnector(stackClient, type, slug) { - return stackClient.fetchJSON('GET', "/".concat(type, "s/").concat(slug)).then(function (x) { - return x.data.attributes; - }); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +var SHARING_DOCTYPE = 'io.cozy.sharings'; +exports.SHARING_DOCTYPE = SHARING_DOCTYPE; +var BITWARDEN_ORGANIZATIONS_DOCTYPE = 'com.bitwarden.organizations'; +exports.BITWARDEN_ORGANIZATIONS_DOCTYPE = BITWARDEN_ORGANIZATIONS_DOCTYPE; +var BITWARDEN_CIPHERS_DOCTYPE = 'com.bitwarden.ciphers'; +exports.BITWARDEN_CIPHERS_DOCTYPE = BITWARDEN_CIPHERS_DOCTYPE; + +var normalizeSharing = function normalizeSharing(sharing) { + return (0, _DocumentCollection2.normalizeDoc)(sharing, SHARING_DOCTYPE); }; /** - * Fetch application/konnector from the registry - * - * @private + * @typedef {object} Rule A sharing rule + * @property {string} title + * @property {string} doctype + * @property {Array} values + * @property {string=} add + * @property {string=} update + * @property {string=} remove */ - -var fetchAppOrKonnectorViaRegistry = function fetchAppOrKonnectorViaRegistry(stackClient, type, slug) { - return stackClient.fetchJSON('GET', "/registry/".concat(slug)).then(function (x) { - return x.latest_version.manifest; - }); -}; /** - * Get Icon URL using blob mechanism if OAuth connected - * or using preloaded url when blob not needed - * - * @param {CozyStackClient} stackClient - CozyStackClient - * @param {object} stackClient.oauthOptions - oauthOptions used to detect fetching mechanism - * @param {object} opts - Options - * @param {string} opts.type - Options type - * @param {string|undefined} opts.slug - Options slug - * @param {object|string|undefined} opts.appData - Apps data - io.cozy.apps - * @param {string} [opts.priority='stack'] - Options priority - * @returns {Promise<string>|string} DOMString containing URL source or a URL representing the Blob . - * @private - * @throws {Error} while fetching icon, or unknown image extension + * @typedef {object} Recipient An io.cozy.contact */ +/** + * @typedef {object} Sharing An io.cozy.sharings document + */ -var _getIconURL = /*#__PURE__*/function () { - var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(stackClient, opts) { - var type, slug, appData, _opts$priority, priority, iconDataFetchers, resp, icon, app, appDataFetchers, ext, _URL, domain, protocol; +/** + * @typedef {object} SharingPolicy Define the add/update/remove policies for a sharing + * @property {string} add + * @property {string} update + * @property {string} remove + */ - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - type = opts.type, slug = opts.slug, appData = opts.appData, _opts$priority = opts.priority, priority = _opts$priority === void 0 ? 'stack' : _opts$priority; +/** + * @typedef {(undefined|'one-way'|'two-way')} SharingType Define how a document is synced between sharing's owner and receivers. + */ - if (!stackClient.oauthOptions) { - _context3.next = 29; - break; - } +/** + * @typedef {object} RelationshipItem Define a recipient that can be used as target of a sharing + * @property {string} id - Recipient's ID + * @property {string} type - Reciptient's type (should be 'io.cozy.contacts') + */ - iconDataFetchers = [function () { - return stackClient.fetch('GET', "/".concat(type, "s/").concat(slug, "/icon")); - }, function () { - return stackClient.fetch('GET', "/registry/".concat(slug, "/icon")); - }]; +/** + * Implements the `DocumentCollection` API along with specific methods for + * `io.cozy.sharings`. + */ - if (priority === 'registry') { - iconDataFetchers.reverse(); - } - _context3.next = 6; - return fallbacks(iconDataFetchers, function (resp) { - if (!resp.ok) { - throw new Error("Error while fetching icon ".concat(resp.statusText)); - } - }); +var SharingCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(SharingCollection, _DocumentCollection); - case 6: - resp = _context3.sent; - _context3.next = 9; - return resp.blob(); + var _super = _createSuper(SharingCollection); - case 9: - icon = _context3.sent; + function SharingCollection() { + (0, _classCallCheck2.default)(this, SharingCollection); + return _super.apply(this, arguments); + } - if (icon.type) { - _context3.next = 26; - break; - } + (0, _createClass2.default)(SharingCollection, [{ + key: "findByDoctype", + value: function () { + var _findByDoctype = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(doctype) { + var resp; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject(), doctype)); - // iOS10 does not set correctly mime type for images, so we assume - // that an empty mime type could mean that the app is running on iOS10. - // For regular images like jpeg, png or gif it still works well in the - // Safari browser but not for SVG. - // So let's set a mime type manually. We cannot always set it to - // image/svg+xml and must guess the mime type based on the icon attribute - // from app/manifest - // See https://stackoverflow.com/questions/38318411/uiwebview-on-ios-10-beta-not-loading-any-svg-images - appDataFetchers = [function () { - return fetchAppOrKonnector(stackClient, type, slug); - }, function () { - return fetchAppOrKonnectorViaRegistry(stackClient, type, slug); - }]; + case 2: + resp = _context.sent; + return _context.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { + data: resp.data.map(normalizeSharing) + })); - if (priority === 'registry') { - appDataFetchers.reverse(); + case 4: + case "end": + return _context.stop(); } + } + }, _callee, this); + })); - _context3.t1 = appData; - - if (_context3.t1) { - _context3.next = 18; - break; - } + function findByDoctype(_x) { + return _findByDoctype.apply(this, arguments); + } - _context3.next = 17; - return fallbacks(appDataFetchers); + return findByDoctype; + }() + /** + * Fetches a sharing by id + * + * @param {string} id Sharing's id + * @returns {Sharing} sharing + */ - case 17: - _context3.t1 = _context3.sent; + }, { + key: "get", + value: function () { + var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) { + var path, resp; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + path = (0, _utils.uri)(_templateObject2(), id); + _context2.next = 3; + return this.stackClient.fetchJSON('GET', path); - case 18: - _context3.t0 = _context3.t1; + case 3: + resp = _context2.sent; + return _context2.abrupt("return", { + data: normalizeSharing(resp.data) + }); - if (_context3.t0) { - _context3.next = 21; - break; + case 5: + case "end": + return _context2.stop(); } + } + }, _callee2, this); + })); - _context3.t0 = {}; + function get(_x2) { + return _get.apply(this, arguments); + } - case 21: - app = _context3.t0; - ext = getIconExtensionFromApp(app); + return get; + }() + /** + * + * Creates a new Sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#post-sharings + * + * @param {object} params Sharing params + * @param {Sharing} params.document The document to share + * @param {string} params.description Description of the sharing + * @param {string=} params.previewPath The preview path + * @param {Array<Rule>=} params.rules The rules defined to the sharing. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing + * @param {Array<Recipient>=} params.recipients Recipients to add to the sharings (will have the same permissions given by the rules defined by the sharing ) + * @param {Array<Recipient>=} params.readOnlyRecipients Recipients to add to the sharings with only read only access + * @param {boolean=} params.openSharing If someone else than the owner can add a recipient to the sharing + * @param {string=} params.appSlug Slug of the targeted app + */ - if (mimeTypes[ext]) { - _context3.next = 25; - break; - } + }, { + key: "create", + value: function () { + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref) { + var document, description, previewPath, rules, _ref$recipients, recipients, _ref$readOnlyRecipien, readOnlyRecipients, openSharing, appSlug, attributes, optionalAttributes, resp; - throw new Error("Unknown image extension \"".concat(ext, "\" for app ").concat(app.name)); + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + document = _ref.document, description = _ref.description, previewPath = _ref.previewPath, rules = _ref.rules, _ref$recipients = _ref.recipients, recipients = _ref$recipients === void 0 ? [] : _ref$recipients, _ref$readOnlyRecipien = _ref.readOnlyRecipients, readOnlyRecipients = _ref$readOnlyRecipien === void 0 ? [] : _ref$readOnlyRecipien, openSharing = _ref.openSharing, appSlug = _ref.appSlug; + attributes = { + description: description, + preview_path: previewPath, + open_sharing: openSharing, + rules: rules ? rules : getSharingRules(document) + }; + optionalAttributes = {}; - case 25: - icon = new Blob([icon], { - type: mimeTypes[ext] - }); + if (appSlug) { + optionalAttributes = { + app_slug: appSlug + }; + } - case 26: - return _context3.abrupt("return", URL.createObjectURL(icon)); + _context3.next = 6; + return this.stackClient.fetchJSON('POST', '/sharings/', { + data: { + type: 'io.cozy.sharings', + attributes: _objectSpread(_objectSpread({}, attributes), optionalAttributes), + relationships: _objectSpread(_objectSpread({}, recipients.length > 0 && { + recipients: { + data: recipients.map(toRelationshipItem) + } + }), readOnlyRecipients.length > 0 && { + read_only_recipients: { + data: readOnlyRecipients.map(toRelationshipItem) + } + }) + } + }); - case 29: - _context3.prev = 29; - _URL = new URL(stackClient.uri), domain = _URL.host, protocol = _URL.protocol; - return _context3.abrupt("return", loadIcon(appData, slug, domain, protocol)); + case 6: + resp = _context3.sent; + return _context3.abrupt("return", { + data: normalizeSharing(resp.data) + }); - case 34: - _context3.prev = 34; - _context3.t2 = _context3["catch"](29); - throw new Error("Cannot fetch icon: invalid stackClient.uri: ".concat(_context3.t2.message)); + case 8: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); - case 37: - case "end": - return _context3.stop(); - } + function create(_x3) { + return _create.apply(this, arguments); } - }, _callee3, null, [[29, 34]]); - })); - - return function _getIconURL(_x7, _x8) { - return _ref3.apply(this, arguments); - }; -}(); -/** - * Get Icon URL using blob mechanism if OAuth connected - * or using preloaded url when blob not needed - * - * @param {CozyStackClient} stackClient - CozyStackClient - * @param {object} stackClient.oauthOptions - oauthOptions used to detect fetching mechanism - * @param {object} opts - Options - * @param {string} opts.type - Options type - * @param {string|undefined} opts.slug - Options slug - * @param {object|string|undefined} opts.appData - Apps data - io.cozy.apps or Slug - string - * @param {string} [opts.priority='stack'] - Options priority - * @returns {Promise<string>|string} DOMString containing URL source or a URL representing the Blob or ErrorReturned - */ - - -exports._getIconURL = _getIconURL; - -var getIconURL = function getIconURL() { - return _getIconURL.apply(this, arguments).catch(function () { - return new _memoize.ErrorReturned(); - }); -}; -exports.getIconURL = getIconURL; + return create; + }() + /** + * @deprecated Use create() instead + * share - Creates a new sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#post-sharings + * + * @param {Sharing} document The document to share. Should have and _id and a name. + * @param {Array} recipients A list of io.cozy.contacts + * @param {string} sharingType - If "two-way", will set the open_sharing attribute to true + * @param {string} description - Describes the sharing + * @param {string=} previewPath Relative URL of the sharings preview page + */ -var _default = (0, _memoize.default)(getIconURL, { - maxDuration: 300 * 1000, - key: function key(stackClient, opts) { - var type = opts.type, - slug = opts.slug, - priority = opts.priority; - return stackClient.uri + +':' + type + ':' + slug + ':' + priority; - } -}); + }, { + key: "share", + value: function () { + var _share = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(document, recipients, sharingType, description) { + var previewPath, + recipientsToUse, + _args4 = arguments; + return _regenerator.default.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + previewPath = _args4.length > 4 && _args4[4] !== undefined ? _args4[4] : null; + console.warn('SharingCollection.share is deprecated, use SharingCollection.create instead'); + recipientsToUse = sharingType === 'two-way' ? { + recipients: recipients + } : { + readOnlyRecipients: recipients + }; + return _context4.abrupt("return", this.create(_objectSpread(_objectSpread({ + document: document + }, recipientsToUse), {}, { + description: description, + previewPath: previewPath, + openSharing: sharingType === 'two-way', + rules: getSharingRules(document, sharingType) + }))); -exports["default"] = _default; + case 4: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); -/***/ }), -/* 681 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + function share(_x4, _x5, _x6, _x7) { + return _share.apply(this, arguments); + } -"use strict"; + return share; + }() + /** + * getDiscoveryLink - Returns the URL of the page that can be used to accept a sharing. See https://docs.cozy.io/en/cozy-stack/sharing/#get-sharingssharing-iddiscovery + * + * @param {string} sharingId - Id of the sharing + * @param {string} sharecode - Code of the sharing + * @returns {string} + */ + }, { + key: "getDiscoveryLink", + value: function getDiscoveryLink(sharingId, sharecode) { + return this.stackClient.fullpath("/sharings/".concat(sharingId, "/discovery?sharecode=").concat(sharecode)); + } + /** + * Add an array of contacts to the Sharing + * + * @param {object} options Object + * @param {Sharing} options.document Sharing Object + * @param {Array<Recipient>=} options.recipients Recipients to add to the sharing + * @param {Array<Recipient>=} options.readOnlyRecipients Recipients to add to the sharings with only read only access + */ -var _interopRequireDefault = __webpack_require__(512); + }, { + key: "addRecipients", + value: function () { + var _addRecipients = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(_ref2) { + var document, _ref2$recipients, recipients, _ref2$readOnlyRecipie, readOnlyRecipients, resp; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.ErrorReturned = exports["default"] = void 0; + return _regenerator.default.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + document = _ref2.document, _ref2$recipients = _ref2.recipients, recipients = _ref2$recipients === void 0 ? [] : _ref2$recipients, _ref2$readOnlyRecipie = _ref2.readOnlyRecipients, readOnlyRecipients = _ref2$readOnlyRecipie === void 0 ? [] : _ref2$readOnlyRecipie; + _context5.next = 3; + return this.stackClient.fetchJSON('POST', (0, _utils.uri)(_templateObject3(), document._id), { + data: { + type: 'io.cozy.sharings', + id: document._id, + relationships: _objectSpread(_objectSpread({}, recipients.length > 0 && { + recipients: { + data: recipients.map(toRelationshipItem) + } + }), readOnlyRecipients.length > 0 && { + read_only_recipients: { + data: readOnlyRecipients.map(toRelationshipItem) + } + }) + } + }); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + case 3: + resp = _context5.sent; + return _context5.abrupt("return", { + data: normalizeSharing(resp.data) + }); -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); + case 5: + case "end": + return _context5.stop(); + } + } + }, _callee5, this); + })); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); + function addRecipients(_x8) { + return _addRecipients.apply(this, arguments); + } -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + return addRecipients; + }() + /** + * Revoke only one recipient of the sharing. + * + * @param {object} sharing Sharing Object + * @param {number} recipientIndex Index of this recipient in the members array of the sharing + */ -var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652)); + }, { + key: "revokeRecipient", + value: function revokeRecipient(sharing, recipientIndex) { + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject4(), sharing._id, recipientIndex)); + } + /** + * Remove self from the sharing. + * + * @param {object} sharing Sharing Object + */ -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } + }, { + key: "revokeSelf", + value: function revokeSelf(sharing) { + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject5(), sharing._id)); + } + /** + * Revoke the sharing for all the members. Must be called + * from the owner's cozy + * + * @param {object} sharing Sharing Objects + */ -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + }, { + key: "revokeAllRecipients", + value: function revokeAllRecipients(sharing) { + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject6(), sharing._id)); + } + }]); + return SharingCollection; +}(_DocumentCollection2.default); -var ErrorReturned = /*#__PURE__*/function (_String) { - (0, _inherits2.default)(ErrorReturned, _String); +SharingCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; - var _super = _createSuper(ErrorReturned); +var getSharingRulesWithoutWarning = function getSharingRulesWithoutWarning(document, sharingType) { + if ((0, _FileCollection.isFile)(document)) { + return getSharingRulesForFile(document, sharingType); + } - function ErrorReturned() { - (0, _classCallCheck2.default)(this, ErrorReturned); - return _super.apply(this, arguments); + if (document._type === BITWARDEN_ORGANIZATIONS_DOCTYPE) { + return getSharingRulesForOrganizations(document); } - return ErrorReturned; -}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(String)); + return getSharingRulesForPhotosAlbum(document, sharingType); +}; /** - * Delete outdated results from cache + * Rules determine the behavior of the sharing when changes are made to the shared document + * See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing + * + * @param {Sharing} document - The document to share. Should have and _id and a name + * @param {SharingType} sharingType - The type of the sharing + * + * @returns {Array<Rule>=} The rules that define how to share the document */ -exports.ErrorReturned = ErrorReturned; +var getSharingRules = function getSharingRules(document, sharingType) { + if (sharingType) { + console.warn("sharingType is deprecated and will be removed. We now set this default rules: ".concat(getSharingRulesWithoutWarning(document), "} \n \n If this default rules do not fill your need, please set custom rules \n by using the 'rules' object of the SharingCollection.create() method")); + } -var garbageCollect = function garbageCollect(cache, maxDuration) { - var now = Date.now(); + return getSharingRulesWithoutWarning(document, sharingType); +}; +/** + * Compute the rules that define how to share a Photo Album. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing + * + * @param {Sharing} document - The document to share. Should have and _id and a name + * @param {SharingType} sharingType - The type of the sharing + * + * @returns {Array<Rule>=} The rules that define how to share a Photo Album + */ - for (var _i = 0, _Object$keys = Object.keys(cache); _i < _Object$keys.length; _i++) { - var key = _Object$keys[_i]; - var delta = now - cache[key].date; - if (delta > maxDuration) { - delete cache[key]; - } - } -}; +exports.getSharingRules = getSharingRules; -var isPromise = function isPromise(maybePromise) { - return typeof maybePromise === 'object' && typeof maybePromise.then === 'function'; +var getSharingRulesForPhotosAlbum = function getSharingRulesForPhotosAlbum(document, sharingType) { + var _id = document._id, + _type = document._type; + return [_objectSpread({ + title: 'collection', + doctype: _type, + values: [_id] + }, getSharingPolicyForAlbum(sharingType)), _objectSpread({ + title: 'items', + doctype: 'io.cozy.files', + values: ["".concat(_type, "/").concat(_id)], + selector: 'referenced_by' + }, getSharingPolicyForReferencedFiles(sharingType))]; }; /** - * Memoize with maxDuration and custom key + * Compute the sharing policy for a ReferencedFile based on its sharing type + * + * @param {SharingType} sharingType - The type of the sharing + * + * @returns {SharingPolicy} The sharing policy for the ReferencedFile */ -var memoize = function memoize(fn, options) { - var cache = {}; - return function () { - var key = options.key.apply(null, arguments); - garbageCollect(cache, options.maxDuration); - var existing = cache[key]; - - if (existing) { - return existing.result; - } else { - var result = fn.apply(this, arguments); - cache[key] = { - result: result, - date: Date.now() - }; - /** - * If the result is a promise and this promise - * failed or resolved with a specific error (aka ErrorReturned), - * let's remove the result from the cache since we don't want to - * memoize error - */ +var getSharingPolicyForReferencedFiles = function getSharingPolicyForReferencedFiles(sharingType) { + return sharingType === 'two-way' ? { + add: 'sync', + update: 'sync', + remove: 'sync' + } : { + add: 'push', + update: 'none', + remove: 'push' + }; +}; +/** + * Compute the sharing policy for an Album based on its sharing type + * + * @param {SharingType} sharingType - The type of the sharing + * + * @returns {Array<Rule>=} The sharing policy for the Album + */ - if (isPromise(result)) { - result.then(function (v) { - if (v instanceof ErrorReturned) { - delete cache[key]; - } - }).catch(function (e) { - delete cache[key]; - }); - } - return result; - } +var getSharingPolicyForAlbum = function getSharingPolicyForAlbum(sharingType) { + if (!sharingType) return { + update: 'sync', + remove: 'revoke' + }; + return sharingType === 'two-way' ? { + update: 'sync', + remove: 'revoke' + } : { + update: 'push', + remove: 'revoke' }; }; +/** + * Compute the rules that define how to share a File. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing + * + * @param {Sharing} document - The document to share. Should have and _id and a name + * @param {SharingType} sharingType - The type of the sharing + * + * @returns {Array<Rule>=} The rules that define how to share a File + */ -var _default = memoize; -exports["default"] = _default; -/***/ }), -/* 682 */ -/***/ ((__unused_webpack_module, exports) => { +var getSharingRulesForFile = function getSharingRulesForFile(document, sharingType) { + var _id = document._id, + name = document.name; + return [_objectSpread({ + title: name, + doctype: 'io.cozy.files', + values: [_id] + }, getSharingPolicyForFile(document, sharingType))]; +}; +/** + * Compute the sharing policy for a File based on its sharing type + * + * @param {Sharing} document - The document to share. Should have and _id and a name + * @param {SharingType} sharingType - The type of the sharing + * + * @returns {SharingPolicy} The sharing policy for the File + */ -"use strict"; +var getSharingPolicyForFile = function getSharingPolicyForFile(document, sharingType) { + if ((0, _FileCollection.isDirectory)(document)) { + if (!sharingType) return { + add: 'sync', + update: 'sync', + remove: 'sync' + }; + return sharingType === 'two-way' ? { + add: 'sync', + update: 'sync', + remove: 'sync' + } : { + add: 'push', + update: 'push', + remove: 'push' + }; + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + if (!sharingType) return { + update: 'sync', + remove: 'revoke' + }; + return sharingType === 'two-way' ? { + update: 'sync', + remove: 'revoke' + } : { + update: 'push', + remove: 'revoke' + }; +}; +/** + * Compute the rules that define how to share an Organization. See https://docs.cozy.io/en/cozy-stack/sharing-design/#description-of-a-sharing + * + * @param {Sharing} document The document to share. Should have and _id and a name + * + * @returns {Array<Rule>=} The rules that define how to share an Organization + */ -var logDeprecate = function logDeprecate() { - var _console; - if (process.env.NODE_ENV === 'test') { - throw new Error('Deprecation error: ' + (arguments.length <= 0 ? undefined : arguments[0])); - } +var getSharingRulesForOrganizations = function getSharingRulesForOrganizations(document) { + var _id = document._id, + name = document.name; + var sharingRules = [{ + title: name, + doctype: BITWARDEN_ORGANIZATIONS_DOCTYPE, + values: [_id], + add: 'sync', + update: 'sync', + remove: 'revoke' + }, { + title: 'Ciphers', + doctype: BITWARDEN_CIPHERS_DOCTYPE, + values: [_id], + add: 'sync', + update: 'sync', + remove: 'sync', + selector: 'organization_id' + }]; + return sharingRules; +}; +/** + * Compute the RelationshipItem that can be referenced as a sharing recipient + * + * @param {Recipient} item The recipient of a sharing + * + * @returns {RelationshipItem} The RelationshipItem that can be referenced as a sharing recipient + */ - (_console = console).warn.apply(_console, arguments); + +var toRelationshipItem = function toRelationshipItem(item) { + return { + id: item._id, + type: item._type + }; }; -var _default = logDeprecate; +var _default = SharingCollection; exports["default"] = _default; /***/ }), -/* 683 */ +/* 685 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireWildcard = __webpack_require__(522); + +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.shouldXMLHTTPRequestBeUsed = exports.fetchWithXMLHttpRequest = void 0; - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520)); +exports["default"] = exports.getPermissionsFor = void 0; -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); -var _memoize = _interopRequireDefault(__webpack_require__(365)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var headersFromString = function headersFromString(headerString) { - return new Headers(headerString.split('\r\n').map(function (x) { - return x.split(':', 2); - }).filter(function (x) { - return x.length == 2; - })); -}; -/** - * Returns a `fetch()` like response but uses XHR. - * XMLHTTPRequest provides upload progress events unlike fetch. - * - * @private - * @param {string} fullpath - Route path - * @param {object} options - Fetch options - * @param {Function} options.onUploadProgress - Callback to receive upload progress events - */ +var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var fetchWithXMLHttpRequest = /*#__PURE__*/function () { - var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(fullpath, options) { - var response; - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - _context3.next = 2; - return new Promise(function (resolve, reject) { - var xhr = new XMLHttpRequest(); +var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614)); - if (options.onUploadProgress && xhr.upload) { - xhr.upload.addEventListener('progress', options.onUploadProgress, false); - } +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - xhr.onload = function () { - if (this.readyState == 4) { - resolve(this); - } else { - reject(this); - } - }; +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - xhr.onerror = function (err) { - reject(err); - }; +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - xhr.open(options.method, fullpath, true); - xhr.withCredentials = true; +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); - for (var _i = 0, _Object$entries = Object.entries(options.headers); _i < _Object$entries.length; _i++) { - var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2), - headerName = _Object$entries$_i[0], - headerValue = _Object$entries$_i[1]; +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); - xhr.setRequestHeader(headerName, headerValue); - } +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); - xhr.send(options.body); - }); +var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613)); - case 2: - response = _context3.sent; - return _context3.abrupt("return", { - headers: headersFromString(response.getAllResponseHeaders()), - ok: response.status >= 200 && response.status < 300, - text: function () { - var _text = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - return _context.abrupt("return", response.responseText); +var _FileCollection = __webpack_require__(670); - case 1: - case "end": - return _context.stop(); - } - } - }, _callee); - })); +var _utils = __webpack_require__(623); - function text() { - return _text.apply(this, arguments); - } +function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } - return text; - }(), - json: function () { - var _json = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - return _context2.abrupt("return", JSON.parse(response.responseText)); +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - case 1: - case "end": - return _context2.stop(); - } - } - }, _callee2); - })); +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - function json() { - return _json.apply(this, arguments); - } +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - return json; - }(), - status: response.status, - statusText: response.statusText - }); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - case 4: - case "end": - return _context3.stop(); - } - } - }, _callee3); - })); +function _templateObject3() { + var data = (0, _taggedTemplateLiteral2.default)(["/permissions/doctype/", "/shared-by-link"]); - return function fetchWithXMLHttpRequest(_x, _x2) { - return _ref.apply(this, arguments); + _templateObject3 = function _templateObject3() { + return data; }; -}(); - -exports.fetchWithXMLHttpRequest = fetchWithXMLHttpRequest; -var doesXHRSupportLoadAndProgress = (0, _memoize.default)(function () { - var xhr = new XMLHttpRequest(); - return 'onload' in xhr && 'onprogress' in xhr; -}); - -var shouldXMLHTTPRequestBeUsed = function shouldXMLHTTPRequestBeUsed(method, path, options) { - return Boolean(options.onUploadProgress) && doesXHRSupportLoadAndProgress(); -}; - -exports.shouldXMLHTTPRequestBeUsed = shouldXMLHTTPRequestBeUsed; - -/***/ }), -/* 684 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652)); - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); - -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); -var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525)); - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -var _get2 = _interopRequireDefault(__webpack_require__(670)); - -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); - -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); + return data; +} -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +function _templateObject2() { + var data = (0, _taggedTemplateLiteral2.default)(["/permissions/", ""]); -var _CozyStackClient2 = _interopRequireDefault(__webpack_require__(560)); + _templateObject2 = function _templateObject2() { + return data; + }; -var _AccessToken = _interopRequireDefault(__webpack_require__(657)); + return data; +} -var _logDeprecate = _interopRequireDefault(__webpack_require__(682)); +function _templateObject() { + var data = (0, _taggedTemplateLiteral2.default)(["/permissions/", ""]); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + _templateObject = function _templateObject() { + return data; + }; -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + return data; +} function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -var defaultoauthOptions = { - clientID: '', - clientName: '', - clientKind: '', - clientSecret: '', - clientURI: '', - registrationAccessToken: '', - redirectURI: '', - softwareID: '', - softwareVersion: '', - logoURI: '', - policyURI: '', - notificationPlatform: '', - notificationDeviceToken: '' +var normalizePermission = function normalizePermission(perm) { + return (0, _DocumentCollection2.normalizeDoc)(perm, 'io.cozy.permissions'); }; /** - * Specialized `CozyStackClient` for mobile, implementing stack registration - * through OAuth. + * Implements `DocumentCollection` API along with specific methods for `io.cozy.permissions`. */ -var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { - (0, _inherits2.default)(OAuthClient, _CozyStackClient); - - var _super = _createSuper(OAuthClient); - - function OAuthClient(_ref) { - var _this; - - var oauth = _ref.oauth, - _ref$scope = _ref.scope, - scope = _ref$scope === void 0 ? [] : _ref$scope, - onTokenRefresh = _ref.onTokenRefresh, - options = (0, _objectWithoutProperties2.default)(_ref, ["oauth", "scope", "onTokenRefresh"]); - (0, _classCallCheck2.default)(this, OAuthClient); - _this = _super.call(this, options); - _this.setOAuthOptions(_objectSpread(_objectSpread({}, defaultoauthOptions), oauth)); +var PermissionCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(PermissionCollection, _DocumentCollection); - if (oauth.token) { - _this.setToken(oauth.token); - } + var _super = _createSuper(PermissionCollection); - _this.scope = scope; - _this.onTokenRefresh = onTokenRefresh; - return _this; + function PermissionCollection() { + (0, _classCallCheck2.default)(this, PermissionCollection); + return _super.apply(this, arguments); } - /** - * Checks if the client has his registration information from the server - * - * @returns {boolean} true if registered, false otherwise - * @private - */ - - - (0, _createClass2.default)(OAuthClient, [{ - key: "isRegistered", - value: function isRegistered() { - return this.oauthOptions.clientID !== ''; - } - /** - * Converts a camel-cased data set to snake case, suitable for sending to the OAuth server - * - * @param {object} data Initial data - * @returns {object} Formatted data - * @private - */ - - }, { - key: "snakeCaseOAuthData", - value: function snakeCaseOAuthData(data) { - var mappedFields = { - softwareID: 'software_id', - softwareVersion: 'software_version', - clientID: 'client_id', - clientName: 'client_name', - clientKind: 'client_kind', - clientURI: 'client_uri', - logoURI: 'logo_uri', - policyURI: 'policy_uri', - notificationPlatform: 'notification_platform', - notificationDeviceToken: 'notification_device_token', - redirectURI: 'redirect_uris' - }; - var result = {}; - Object.keys(data).forEach(function (fieldName) { - var key = mappedFields[fieldName] || fieldName; - var value = data[fieldName]; - result[key] = value; - }); // special case: turn redirect_uris into an array - - if (result['redirect_uris'] && result['redirect_uris'] instanceof Array === false) result['redirect_uris'] = [result['redirect_uris']]; - return result; - } - /** - * Converts a snake-cased data set to camel case, suitable for internal use - * - * @param {object} data Initial data - * @returns {object} Formatted data - * @private - */ - - }, { - key: "camelCaseOAuthData", - value: function camelCaseOAuthData(data) { - var mappedFields = { - client_id: 'clientID', - client_name: 'clientName', - client_secret: 'clientSecret', - registration_access_token: 'registrationAccessToken', - software_id: 'softwareID', - redirect_uris: 'redirectURI' - }; - var result = {}; - Object.keys(data).forEach(function (fieldName) { - var key = mappedFields[fieldName] || fieldName; - var value = data[fieldName]; - result[key] = value; - }); - return result; - } - /** Performs the HTTP call to register the client to the server */ - - }, { - key: "doRegistration", - value: function doRegistration() { - return this.fetchJSON('POST', '/auth/register', this.snakeCaseOAuthData({ - redirectURI: this.oauthOptions.redirectURI, - clientName: this.oauthOptions.clientName, - softwareID: this.oauthOptions.softwareID, - clientKind: this.oauthOptions.clientKind, - clientURI: this.oauthOptions.clientURI, - logoURI: this.oauthOptions.logoURI, - policyURI: this.oauthOptions.policyURI, - softwareVersion: this.oauthOptions.softwareVersion, - notificationPlatform: this.oauthOptions.notificationPlatform, - notificationDeviceToken: this.oauthOptions.notificationDeviceToken - })); - } - /** - * Registers the currenly configured client with the OAuth server and - * sets internal information from the server response - * - * @throws {Error} When the client is already registered - * @returns {Promise} A promise that resolves with a complete list of client information, including client ID and client secret. - */ - }, { - key: "register", + (0, _createClass2.default)(PermissionCollection, [{ + key: "get", value: function () { - var _register = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { - var mandatoryFields, fields, missingMandatoryFields, data; + var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(id) { + var resp; return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: - if (!this.isRegistered()) { - _context.next = 2; - break; - } - - throw new Error('Client already registered'); + _context.next = 2; + return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject(), id)); case 2: - mandatoryFields = ['redirectURI']; - fields = Object.keys(this.oauthOptions); - missingMandatoryFields = mandatoryFields.filter(function (fieldName) { - return fields[fieldName]; + resp = _context.sent; + return _context.abrupt("return", { + data: normalizePermission(resp.data) }); - if (!(missingMandatoryFields.length > 0)) { - _context.next = 7; - break; - } - - throw new Error("Can't register client : missing ".concat(missingMandatoryFields, " fields")); - - case 7: - _context.next = 9; - return this.doRegistration(); - - case 9: - data = _context.sent; - this.setOAuthOptions(_objectSpread(_objectSpread({}, this.oauthOptions), {}, { - client_id: data.client_id, - client_name: data.client_name, - client_secret: data.client_secret, - registration_access_token: data.registration_access_token, - software_id: data.software_id - })); - return _context.abrupt("return", this.oauthOptions); - - case 12: + case 4: case "end": return _context.stop(); } @@ -110765,45 +109860,59 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { }, _callee, this); })); - function register() { - return _register.apply(this, arguments); + function get(_x) { + return _get.apply(this, arguments); } - return register; + return get; }() /** - * Unregisters the currenly configured client with the OAuth server. + * Create a new set of permissions + * It can also associates one or more codes to it, via the codes parameter + * + * @param {object} permission + * @param {string} permission.codes A comma separed list of values (defaulted to code) + * @param {string} permission.ttl Make the codes expire after a delay (bigduration format) + * @param {boolean} permission.tiny If set to true then the generated shortcode will be 6 digits + * Cozy-Stack has a few conditions to be able to use this tiny shortcode ATM you have to specifiy + * a ttl < 1h, but it can change. + * see https://docs.cozy.io/en/cozy-stack/permissions/#post-permissions for exact informations + * + * bigduration format: https://github.com/justincampbell/bigduration/blob/master/README.md + * @see https://docs.cozy.io/en/cozy-stack/permissions/#post-permissions * - * @throws {NotRegisteredException} When the client doesn't have it's registration information - * @returns {Promise} */ }, { - key: "unregister", + key: "create", value: function () { - var _unregister = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { - var clientID; + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref) { + var _id, _type, _ref$codes, codes, ttl, tiny, attributes, searchParams, resp; + return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: - if (this.isRegistered()) { - _context2.next = 2; - break; - } - - throw new NotRegisteredException(); - - case 2: - clientID = this.oauthOptions.clientID; - this.oauthOptions.clientID = ''; - return _context2.abrupt("return", this.fetchJSON('DELETE', "/auth/register/".concat(clientID), null, { - headers: { - Authorization: this.registrationAccessTokenToAuthHeader() + _id = _ref._id, _type = _ref._type, _ref$codes = _ref.codes, codes = _ref$codes === void 0 ? 'code' : _ref$codes, ttl = _ref.ttl, tiny = _ref.tiny, attributes = (0, _objectWithoutProperties2.default)(_ref, ["_id", "_type", "codes", "ttl", "tiny"]); + searchParams = new URLSearchParams(); + searchParams.append('codes', codes); + if (ttl) searchParams.append('ttl', ttl); + if (tiny) searchParams.append('tiny', true); + _context2.next = 7; + return this.stackClient.fetchJSON('POST', "/permissions?".concat(searchParams), { + data: { + type: 'io.cozy.permissions', + attributes: attributes } - })); + }); - case 5: + case 7: + resp = _context2.sent; + return _context2.abrupt("return", { + data: normalizePermission(resp.data) + }); + + case 9: case "end": return _context2.stop(); } @@ -110811,42 +109920,80 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { }, _callee2, this); })); - function unregister() { - return _unregister.apply(this, arguments); + function create(_x2) { + return _create.apply(this, arguments); } - return unregister; + return create; }() /** - * Fetches the complete set of client information from the server after it has been registered. + * Adds a permission to the given document. Document type must be + * `io.cozy.apps`, `io.cozy.konnectors` or `io.cozy.permissions` * - * @throws {NotRegisteredException} When the client doesn't have it's registration information + * @param {object} document - Document which receives the permission + * @param {object} permission - Describes the permission * @returns {Promise} + * + * @example + * ``` + * const permissions = await client + * .collection('io.cozy.permissions') + * .add(konnector, { + * folder: { + * type: 'io.cozy.files', + * verbs: ['GET', 'PUT'], + * values: [`io.cozy.files.bc57b60eb2954537b0dcdc6ebd8e9d23`] + * } + * }) + * ``` */ }, { - key: "fetchInformation", + key: "add", value: function () { - var _fetchInformation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { + var _add = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(document, permission) { + var endpoint, resp; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: - if (this.isRegistered()) { - _context3.next = 2; - break; - } + _context3.t0 = document._type; + _context3.next = _context3.t0 === 'io.cozy.apps' ? 3 : _context3.t0 === 'io.cozy.konnectors' ? 5 : _context3.t0 === 'io.cozy.permissions' ? 7 : 9; + break; - throw new NotRegisteredException(); + case 3: + endpoint = "/permissions/apps/".concat(document.slug); + return _context3.abrupt("break", 10); - case 2: - return _context3.abrupt("return", this.fetchJSON('GET', "/auth/register/".concat(this.oauthOptions.clientID), null, { - headers: { - Authorization: this.registrationAccessTokenToAuthHeader() + case 5: + endpoint = "/permissions/konnectors/".concat(document.slug); + return _context3.abrupt("break", 10); + + case 7: + endpoint = "/permissions/".concat(document._id); + return _context3.abrupt("break", 10); + + case 9: + throw new Error('Permissions can only be added on existing permissions, apps and konnectors.'); + + case 10: + _context3.next = 12; + return this.stackClient.fetchJSON('PATCH', endpoint, { + data: { + type: 'io.cozy.permissions', + attributes: { + permissions: permission + } } - })); + }); - case 3: + case 12: + resp = _context3.sent; + return _context3.abrupt("return", { + data: normalizePermission(resp.data) + }); + + case 14: case "end": return _context3.stop(); } @@ -110854,65 +110001,36 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { }, _callee3, this); })); - function fetchInformation() { - return _fetchInformation.apply(this, arguments); + function add(_x3, _x4) { + return _add.apply(this, arguments); } - return fetchInformation; + return add; }() - /** - * Overwrites the client own information. This method will update both the local information and the remote information on the OAuth server. - * - * @throws {NotRegisteredException} When the client doesn't have it's registration information - * @param {object} information Set of information to update. Note that some fields such as `clientID` can't be updated. - * @param {boolean} resetSecret = false Optionnal, whether to reset the client secret or not - * @returns {Promise} Resolves to a complete, updated list of client information - */ - }, { - key: "updateInformation", + key: "destroy", + value: function destroy(permission) { + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject2(), permission.id)); + } + }, { + key: "findLinksByDoctype", value: function () { - var _updateInformation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(information) { - var resetSecret, - mandatoryFields, - data, - result, - _args4 = arguments; + var _findLinksByDoctype = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(doctype) { + var resp; return _regenerator.default.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: - resetSecret = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : false; - - if (this.isRegistered()) { - _context4.next = 3; - break; - } - - throw new NotRegisteredException(); - - case 3: - mandatoryFields = { - clientID: this.oauthOptions.clientID, - clientName: this.oauthOptions.clientName, - redirectURI: this.oauthOptions.redirectURI, - softwareID: this.oauthOptions.softwareID - }; - data = this.snakeCaseOAuthData(_objectSpread(_objectSpread({}, mandatoryFields), information)); - if (resetSecret) data['client_secret'] = this.oauthOptions.clientSecret; - _context4.next = 8; - return this.fetchJSON('PUT', "/auth/register/".concat(this.oauthOptions.clientID), data, { - headers: { - Authorization: this.registrationAccessTokenToAuthHeader() - } - }); + _context4.next = 2; + return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject3(), doctype)); - case 8: - result = _context4.sent; - this.setOAuthOptions(_objectSpread(_objectSpread({}, data), result)); - return _context4.abrupt("return", this.oauthOptions); + case 2: + resp = _context4.sent; + return _context4.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { + data: resp.data.map(normalizePermission) + })); - case 11: + case 4: case "end": return _context4.stop(); } @@ -110920,170 +110038,35 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { }, _callee4, this); })); - function updateInformation(_x) { - return _updateInformation.apply(this, arguments); + function findLinksByDoctype(_x5) { + return _findLinksByDoctype.apply(this, arguments); } - return updateInformation; + return findLinksByDoctype; }() - /** - * Generates a random state code to be used during the OAuth process - * - * @returns {string} - */ - - }, { - key: "generateStateCode", - value: function generateStateCode() { - var STATE_SIZE = 16; - var hasCrypto = typeof window !== 'undefined' && typeof window.crypto !== 'undefined' && typeof window.crypto.getRandomValues === 'function'; - var buffer; - - if (hasCrypto) { - buffer = new Uint8Array(STATE_SIZE); - window.crypto.getRandomValues(buffer); - } else { - buffer = new Array(STATE_SIZE); - - for (var i = 0; i < buffer.length; i++) { - buffer[i] = Math.floor(Math.random() * 255); - } - } - - return btoa(String.fromCharCode.apply(null, buffer)).replace(/=+$/, '').replace(/\//g, '_').replace(/\+/g, '-'); - } - /** - * Generates the URL that the user should be sent to in order to accept the app's permissions. - * - * @throws {NotRegisteredException} When the client doesn't have it's registration information - * @param {object} options - URL generation options - * @param {string} options.stateCode - A random code to be included in the URl for security. Can be generated with `client.generateStateCode()` - * @param {Array} [options.scopes] - An array of permission scopes for the token. - * @param {SessionCode} [options.sessionCode] - A session code that can be used to create a session. - * @param {string} [options.codeChallenge] - A code challenge that can be used in a PKCE verification process. - * @returns {string} The URL - */ - - }, { - key: "getAuthCodeURL", - value: function getAuthCodeURL(_ref2) { - var stateCode = _ref2.stateCode, - _ref2$scopes = _ref2.scopes, - scopes = _ref2$scopes === void 0 ? this.scope : _ref2$scopes, - _ref2$sessionCode = _ref2.sessionCode, - sessionCode = _ref2$sessionCode === void 0 ? undefined : _ref2$sessionCode, - _ref2$codeChallenge = _ref2.codeChallenge, - codeChallenge = _ref2$codeChallenge === void 0 ? undefined : _ref2$codeChallenge; - if (!this.isRegistered()) throw new NotRegisteredException(); - var query = { - client_id: this.oauthOptions.clientID, - redirect_uri: this.oauthOptions.redirectURI, - state: stateCode, - response_type: 'code', - scope: scopes.join(' ') - }; - - if (this.oauthOptions.registerToken) { - query = _objectSpread(_objectSpread({}, query), {}, { - registerToken: this.oauthOptions.registerToken - }); - } - - if (sessionCode) { - query = _objectSpread(_objectSpread({}, query), {}, { - session_code: sessionCode - }); - } - - if (codeChallenge) { - query = _objectSpread(_objectSpread({}, query), {}, { - code_challenge: codeChallenge, - code_challenge_method: 'S256' - }); - } - - return "".concat(this.uri, "/auth/authorize?").concat(this.dataToQueryString(query)); - } - }, { - key: "dataToQueryString", - value: function dataToQueryString(data) { - return Object.keys(data).map(function (param) { - return "".concat(param, "=").concat(encodeURIComponent(data[param])); - }).join('&'); - } - /** - * Retrieves the access code contained in the URL to which the user is redirected after accepting the app's permissions (the `redirectURI`). - * - * @throws {Error} The URL should contain the same state code as the one generated with `client.getAuthCodeURL()`. If not, it will throw an error - * @param {string} pageURL The redirected page URL, containing the state code and the access code - * @param {string} stateCode The state code that was contained in the original URL the user was sent to (see `client.getAuthCodeURL()`) - * @returns {string} The access code - */ - - }, { - key: "getAccessCodeFromURL", - value: function getAccessCodeFromURL(pageURL, stateCode) { - if (!stateCode) throw new Error('Missing state code'); - var params = new URL(pageURL).searchParams; - var urlStateCode = params.get('state'); - var urlAccessCode = params.get('access_code'); - if (stateCode !== urlStateCode) throw new Error('Given state does not match url query state'); - return urlAccessCode; - } - /** - * Exchanges an access code for an access token. This function does **not** update the client's token. - * - * @throws {NotRegisteredException} When the client doesn't have it's registration information - * @param {string} accessCode - The access code contained in the redirection URL — see `client.getAccessCodeFromURL()` - * @param {object} oauthOptionsArg — To use when OAuthClient is not yet registered (during login process) - * @param {string} uri — To use when OAuthClient is not yet registered (during login process) - * @param {string} codeVerifier — The PKCE code verifier (see https://docs.cozy.io/en/cozy-stack/auth/#pkce-extension) - * @returns {Promise} A promise that resolves with an AccessToken object. - */ - }, { - key: "fetchAccessToken", + key: "findApps", value: function () { - var _fetchAccessToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(accessCode, oauthOptionsArg, uri, codeVerifier) { - var oauthOptions, data, result; + var _findApps = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() { + var resp; return _regenerator.default.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: - if (!(!this.isRegistered() && !oauthOptionsArg)) { - _context5.next = 2; - break; - } - - throw new NotRegisteredException(); + _context5.next = 2; + return this.stackClient.fetchJSON('GET', '/apps/'); case 2: - oauthOptions = oauthOptionsArg || this.oauthOptions; - data = { - grant_type: 'authorization_code', - code: accessCode, - client_id: oauthOptions.clientID, - client_secret: oauthOptions.clientSecret - }; - - if (codeVerifier) { - data = _objectSpread(_objectSpread({}, data), {}, { - code_verifier: codeVerifier - }); - } - - _context5.next = 7; - return this.fetchJSON('POST', (uri || '') + '/auth/access_token', this.dataToQueryString(data), { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - } - }); - - case 7: - result = _context5.sent; - return _context5.abrupt("return", new _AccessToken.default(result)); + resp = _context5.sent; + return _context5.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { + data: resp.data.map(function (a) { + return _objectSpread({ + _id: a.id + }, a); + }) + })); - case 9: + case 4: case "end": return _context5.stop(); } @@ -111091,35 +110074,53 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { }, _callee5, this); })); - function fetchAccessToken(_x2, _x3, _x4, _x5) { - return _fetchAccessToken.apply(this, arguments); + function findApps() { + return _findApps.apply(this, arguments); } - return fetchAccessToken; + return findApps; }() /** - * @typedef SessionCodeRes - * @property {string} session_code The value of the session code - */ - - /** - * Fetches a new session code. Only usable by the Flagship application + * Create a share link * - * @throws {NotRegisteredException} When the client isn't certified to be the Flagship application - * @returns {Promise<SessionCodeRes>} A promise that resolves with a new session_code + * @param {{_id, _type}} document - cozy document + * @param {object} options - options + * @param {string[]} options.verbs - explicit permissions to use */ }, { - key: "fetchSessionCode", + key: "createSharingLink", value: function () { - var _fetchSessionCode = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() { + var _createSharingLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(document) { + var options, + verbs, + resp, + _args6 = arguments; return _regenerator.default.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: - return _context6.abrupt("return", this.fetchJSON('POST', '/auth/session_code')); + options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {}; + verbs = options.verbs; + _context6.next = 4; + return this.stackClient.fetchJSON('POST', "/permissions?codes=email", { + data: { + type: 'io.cozy.permissions', + attributes: { + permissions: getPermissionsFor(document, true, verbs ? { + verbs: verbs + } : {}) + } + } + }); - case 1: + case 4: + resp = _context6.sent; + return _context6.abrupt("return", { + data: normalizePermission(resp.data) + }); + + case 6: case "end": return _context6.stop(); } @@ -111127,37 +110128,38 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { }, _callee6, this); })); - function fetchSessionCode() { - return _fetchSessionCode.apply(this, arguments); + function createSharingLink(_x6) { + return _createSharingLink.apply(this, arguments); } - return fetchSessionCode; + return createSharingLink; }() /** - * Fetches a new session code. Only usable by the Flagship application + * Follow the next link to fetch the next permissions * - * @throws {NotRegisteredException} When the client isn't certified to be the Flagship application - * @returns {Promise<SessionCodeRes>} A promise that resolves with a new session_code + * @param {object} permissions JSON-API based permissions document */ }, { - key: "fetchSessionCodeWithPassword", + key: "fetchPermissionsByLink", value: function () { - var _fetchSessionCodeWithPassword = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(_ref3) { - var passwordHash, _ref3$twoFactorToken, twoFactorToken, _ref3$twoFactorPassco, twoFactorPasscode; - + var _fetchPermissionsByLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(permissions) { return _regenerator.default.wrap(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: - passwordHash = _ref3.passwordHash, _ref3$twoFactorToken = _ref3.twoFactorToken, twoFactorToken = _ref3$twoFactorToken === void 0 ? undefined : _ref3$twoFactorToken, _ref3$twoFactorPassco = _ref3.twoFactorPasscode, twoFactorPasscode = _ref3$twoFactorPassco === void 0 ? undefined : _ref3$twoFactorPassco; - return _context7.abrupt("return", this.fetchJSON('POST', '/auth/session_code', { - passphrase: passwordHash, - two_factor_token: twoFactorToken, - two_factor_passcode: twoFactorPasscode - })); + if (!(permissions.links && permissions.links.next)) { + _context7.next = 4; + break; + } - case 2: + _context7.next = 3; + return this.stackClient.fetchJSON('GET', permissions.links.next); + + case 3: + return _context7.abrupt("return", _context7.sent); + + case 4: case "end": return _context7.stop(); } @@ -111165,71 +110167,56 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { }, _callee7, this); })); - function fetchSessionCodeWithPassword(_x6) { - return _fetchSessionCodeWithPassword.apply(this, arguments); + function fetchPermissionsByLink(_x7) { + return _fetchPermissionsByLink.apply(this, arguments); } - return fetchSessionCodeWithPassword; + return fetchPermissionsByLink; }() /** - * Retrieves a new access token by refreshing the currently used token. * - * @throws {NotRegisteredException} When the client doesn't have it's registration information - * @throws {Error} The client should already have an access token to use this function - * @returns {Promise} A promise that resolves with a new AccessToken object + * @param {object} document Cozy doc + * @returns {object} with all the permissions */ }, { - key: "refreshToken", + key: "fetchAllLinks", value: function () { - var _refreshToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8() { - var data, result, newToken; + var _fetchAllLinks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(document) { + var allLinks, resp, _allLinks$data; + return _regenerator.default.wrap(function _callee8$(_context8) { while (1) { switch (_context8.prev = _context8.next) { case 0: - if (this.isRegistered()) { - _context8.next = 2; - break; - } - - throw new NotRegisteredException(); + _context8.next = 2; + return this.findLinksByDoctype(document._type); case 2: - if (this.token) { - _context8.next = 4; + allLinks = _context8.sent; + resp = allLinks; + + case 4: + if (!(resp.links && resp.links.next)) { + _context8.next = 11; break; } - throw new Error('No token to refresh'); - - case 4: - data = { - grant_type: 'refresh_token', - refresh_token: this.token.refreshToken, - client_id: this.oauthOptions.clientID, - client_secret: this.oauthOptions.clientSecret - }; _context8.next = 7; - return (0, _get2.default)((0, _getPrototypeOf2.default)(OAuthClient.prototype), "fetchJSON", this).call(this, 'POST', '/auth/access_token', this.dataToQueryString(data), { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - } - }); + return this.fetchPermissionsByLink(resp); case 7: - result = _context8.sent; - newToken = new _AccessToken.default(_objectSpread({ - refresh_token: this.token.refreshToken - }, result)); + resp = _context8.sent; - if (this.onTokenRefresh && typeof this.onTokenRefresh === 'function') { - this.onTokenRefresh(newToken); - } + (_allLinks$data = allLinks.data).push.apply(_allLinks$data, (0, _toConsumableArray2.default)(resp.data.map(normalizePermission))); - return _context8.abrupt("return", newToken); + _context8.next = 4; + break; case 11: + return _context8.abrupt("return", allLinks); + + case 12: case "end": return _context8.stop(); } @@ -111237,168 +110224,213 @@ var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { }, _callee8, this); })); - function refreshToken() { - return _refreshToken.apply(this, arguments); + function fetchAllLinks(_x8) { + return _fetchAllLinks.apply(this, arguments); } - return refreshToken; + return fetchAllLinks; }() - }, { - key: "exchangeOAuthSecret", - value: function exchangeOAuthSecret(uri, secret) { - return this.fetchJSON('POST', uri + '/auth/secret_exchange', { - secret: secret - }); - } /** - * Updates the client's stored token + * Destroy a sharing link and the related permissions * - * @param {string} token = null The new token to use — can be a string, a json object or an AccessToken instance. + * @param {object} document */ }, { - key: "setToken", - value: function setToken(token) { - if (token) { - this.token = token instanceof _AccessToken.default ? token : new _AccessToken.default(token); - } else { - this.token = null; + key: "revokeSharingLink", + value: function () { + var _revokeSharingLink = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(document) { + var allLinks, links, _iterator, _step, perm; + + return _regenerator.default.wrap(function _callee9$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + _context9.next = 2; + return this.fetchAllLinks(document); + + case 2: + allLinks = _context9.sent; + links = allLinks.data.filter(function (perm) { + return isPermissionRelatedTo(perm, document); + }); + _iterator = _createForOfIteratorHelper(links); + _context9.prev = 5; + + _iterator.s(); + + case 7: + if ((_step = _iterator.n()).done) { + _context9.next = 13; + break; + } + + perm = _step.value; + _context9.next = 11; + return this.destroy(perm); + + case 11: + _context9.next = 7; + break; + + case 13: + _context9.next = 18; + break; + + case 15: + _context9.prev = 15; + _context9.t0 = _context9["catch"](5); + + _iterator.e(_context9.t0); + + case 18: + _context9.prev = 18; + + _iterator.f(); + + return _context9.finish(18); + + case 21: + case "end": + return _context9.stop(); + } + } + }, _callee9, this, [[5, 15, 18, 21]]); + })); + + function revokeSharingLink(_x9) { + return _revokeSharingLink.apply(this, arguments); } - } - }, { - key: "setCredentials", - value: function setCredentials(token) { - (0, _logDeprecate.default)('setCredentials is deprecated, please replace by setToken'); - return this.setToken(token); - } - /** - * Updates the OAuth informations - * - * @param {object} options Map of OAuth options - */ - }, { - key: "setOAuthOptions", - value: function setOAuthOptions(options) { - this.oauthOptions = this.camelCaseOAuthData(options); - } - }, { - key: "resetClientId", - value: function resetClientId() { - this.oauthOptions.clientID = ''; - } + return revokeSharingLink; + }() /** - * Reset the current OAuth client + * async getOwnPermissions - deprecated: please use fetchOwnPermissions instead + * + * @typedef {object} Permission + * + * @returns {Permission} permission */ }, { - key: "resetClient", - value: function resetClient() { - this.resetClientId(); - this.setUri(null); - this.setToken(null); - } - /** - * Turns the client's registration access token into a header suitable for HTTP requests. Used in some queries to manipulate the client on the server side. - * - * @returns {string} - * @private - */ + key: "getOwnPermissions", + value: function () { + var _getOwnPermissions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10() { + return _regenerator.default.wrap(function _callee10$(_context10) { + while (1) { + switch (_context10.prev = _context10.next) { + case 0: + console.warn('getOwnPermissions is deprecated, please use fetchOwnPermissions instead'); + return _context10.abrupt("return", this.fetchOwnPermissions()); - }, { - key: "registrationAccessTokenToAuthHeader", - value: function registrationAccessTokenToAuthHeader() { - if (!this.oauthOptions.registrationAccessToken) { - throw new Error('No registration access token'); + case 2: + case "end": + return _context10.stop(); + } + } + }, _callee10, this); + })); + + function getOwnPermissions() { + return _getOwnPermissions.apply(this, arguments); } - return 'Bearer ' + this.oauthOptions.registrationAccessToken; - } + return getOwnPermissions; + }() /** - * This method should be used in flagship app onboarding process to finalize the - * cozy creation by setting the user password into the cozy-stack + * async fetchOwnPermissions - Fetches permissions * - * More info: https://docs.cozy.io/en/cozy-stack/settings/#post-settingspassphraseflagship + * @typedef {object} Permission * - * @param {object} params - * @param {string} params.registerToken - registration token provided by the onboarding link - * @param {string} params.passwordHash - hash of the master password - * @param {string} params.hint - hint for the master password - * @param {string} params.key - key (crypted) used for the vault encryption - * @param {string} params.publicKey - public key used for sharing ciphers from the vault - * @param {string} params.privateKey - private key (crypted) used for sharing ciphers from the vault - * @param {string} params.iterations - number of KDF iterations applied when hashing the master password - * @returns {object} token - The OAauth token + * @returns {Permission} permission */ }, { - key: "setPassphraseFlagship", - value: function setPassphraseFlagship(_ref4) { - var registerToken = _ref4.registerToken, - passwordHash = _ref4.passwordHash, - hint = _ref4.hint, - key = _ref4.key, - publicKey = _ref4.publicKey, - privateKey = _ref4.privateKey, - iterations = _ref4.iterations; - return this.fetchJSON('POST', '/settings/passphrase/flagship', { - register_token: registerToken, - passphrase: passwordHash, - hint: hint, - key: key, - public_key: publicKey, - private_key: privateKey, - iterations: iterations, - client_id: this.oauthOptions.clientID, - client_secret: this.oauthOptions.clientSecret - }, { - // TODO: faut il mettre le header? - headers: { - Authorization: this.registrationAccessTokenToAuthHeader() - } - }); - } - }]); - return OAuthClient; -}(_CozyStackClient2.default); + key: "fetchOwnPermissions", + value: function () { + var _fetchOwnPermissions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11() { + var resp; + return _regenerator.default.wrap(function _callee11$(_context11) { + while (1) { + switch (_context11.prev = _context11.next) { + case 0: + _context11.next = 2; + return this.stackClient.fetchJSON('GET', '/permissions/self'); -var NotRegisteredException = /*#__PURE__*/function (_Error) { - (0, _inherits2.default)(NotRegisteredException, _Error); + case 2: + resp = _context11.sent; + return _context11.abrupt("return", { + data: normalizePermission(resp.data), + included: resp.included ? resp.included.map(normalizePermission) : [] + }); - var _super2 = _createSuper(NotRegisteredException); + case 4: + case "end": + return _context11.stop(); + } + } + }, _callee11, this); + })); - function NotRegisteredException() { - var _this2; + function fetchOwnPermissions() { + return _fetchOwnPermissions.apply(this, arguments); + } - var message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Client not registered or missing OAuth information'; - (0, _classCallCheck2.default)(this, NotRegisteredException); - _this2 = _super2.call(this, message); - _this2.message = message; - _this2.name = 'NotRegisteredException'; - return _this2; - } + return fetchOwnPermissions; + }() + }]); + return PermissionCollection; +}(_DocumentCollection2.default); +/** + * Build a permission set + * + * @param {{_id, _type}} document - cozy document + * @param {boolean} publicLink - are the permissions for a public link ? + * @param {object} options - options + * @param {string[]} options.verbs - explicit permissions to use + * @returns {object} permissions object that can be sent through /permissions/* + */ - return NotRegisteredException; -}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); -var _default = OAuthClient; -exports["default"] = _default; +var getPermissionsFor = function getPermissionsFor(document) { + var publicLink = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _id = document._id, + _type = document._type; + var verbs = options.verbs ? options.verbs : publicLink ? ['GET'] : ['ALL']; // TODO: this works for albums, but it needs to be generalized and integrated + // with cozy-client ; some sort of doctype "schema" will be needed here -/***/ }), -/* 685 */ -/***/ ((__unused_webpack_module, exports) => { + return (0, _FileCollection.isFile)(document) ? { + files: { + type: 'io.cozy.files', + verbs: verbs, + values: [_id] + } + } : { + collection: { + type: _type, + verbs: verbs, + values: [_id] + }, + files: { + type: 'io.cozy.files', + verbs: verbs, + values: ["".concat(_type, "/").concat(_id)], + selector: 'referenced_by' + } + }; +}; -"use strict"; +exports.getPermissionsFor = getPermissionsFor; +PermissionCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; +var isPermissionRelatedTo = function isPermissionRelatedTo(perm, document) { + var _id = document._id; + return (0, _FileCollection.isFile)(document) ? perm.attributes.permissions.files.values.indexOf(_id) !== -1 : perm.attributes.permissions.collection.values.indexOf(_id) !== -1; +}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.DOCTYPE_FILES = exports.REGISTRATION_ABORT = void 0; -var REGISTRATION_ABORT = 'REGISTRATION_ABORT'; -exports.REGISTRATION_ABORT = REGISTRATION_ABORT; -var DOCTYPE_FILES = 'io.cozy.files'; -exports.DOCTYPE_FILES = DOCTYPE_FILES; +var _default = PermissionCollection; +exports["default"] = _default; /***/ }), /* 686 */ @@ -111407,229 +110439,84 @@ exports.DOCTYPE_FILES = DOCTYPE_FILES; "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports.transformBulkDocsResponse = void 0; - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); - -var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525)); - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); - -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); - -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +exports["default"] = exports.SETTINGS_DOCTYPE = void 0; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _dsl = __webpack_require__(607); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _CozyLink2 = _interopRequireDefault(__webpack_require__(687)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _types = __webpack_require__(610); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _const = __webpack_require__(685); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _errors = __webpack_require__(688); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -var _zipWith = _interopRequireDefault(__webpack_require__(689)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(613)); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -/** - * Returns full documents after a bulk update - * - * @private - * - * @param {CouchDBBulkResult[]} bulkResponse - Response from bulk docs - * @param {CozyClientDocument[]} originalDocuments - Documents that were updated - * @returns {{ data: CozyClientDocument[] }} - Full documents with updated _id and _rev - */ -var transformBulkDocsResponse = function transformBulkDocsResponse(bulkResponse, originalDocuments) { - var updatedDocs = (0, _zipWith.default)(bulkResponse, originalDocuments, function (result, od) { - return result.ok ? _objectSpread(_objectSpread({}, od), {}, { - _id: result.id, - _rev: result.rev - }) : od; - }); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } - if (bulkResponse.find(function (x) { - return !x.ok; - })) { - throw new _errors.BulkEditError(bulkResponse, updatedDocs); - } +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - return { - data: updatedDocs - }; -}; +var SETTINGS_DOCTYPE = 'io.cozy.settings'; /** - * Transfers queries and mutations to a remote stack + * Implements `DocumentCollection` API to interact with the /settings endpoint of the stack */ +exports.SETTINGS_DOCTYPE = SETTINGS_DOCTYPE; -exports.transformBulkDocsResponse = transformBulkDocsResponse; - -var StackLink = /*#__PURE__*/function (_CozyLink) { - (0, _inherits2.default)(StackLink, _CozyLink); +var SettingsCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(SettingsCollection, _DocumentCollection); - var _super = _createSuper(StackLink); + var _super = _createSuper(SettingsCollection); + function SettingsCollection(stackClient) { + (0, _classCallCheck2.default)(this, SettingsCollection); + return _super.call(this, SETTINGS_DOCTYPE, stackClient); + } /** - * @param {object} [options] - Options - * @param {object} [options.stackClient] - A StackClient - * @param {object} [options.client] - A StackClient (deprecated) + * async get - Calls a route on the /settings API + * + * @param {string} path The setting route to call, eg `instance` or `context` + * @returns {object} The response from the route */ - function StackLink() { - var _this; - - var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, - client = _ref.client, - stackClient = _ref.stackClient; - - (0, _classCallCheck2.default)(this, StackLink); - _this = _super.call(this); - - if (client) { - console.warn('Using options.client is deprecated, prefer options.stackClient'); - } - - _this.stackClient = stackClient || client; - return _this; - } - - (0, _createClass2.default)(StackLink, [{ - key: "registerClient", - value: function registerClient(client) { - this.stackClient = client.stackClient || client.client; - } - }, { - key: "reset", - value: function reset() { - this.stackClient = null; - } - }, { - key: "request", - value: function request(operation, result, forward) { - if (operation.mutationType) { - return this.executeMutation(operation, result, forward); - } - - return this.executeQuery(operation); - } - }, { - key: "executeQuery", - value: function executeQuery(query) { - var doctype = query.doctype, - selector = query.selector, - id = query.id, - ids = query.ids, - referenced = query.referenced, - options = (0, _objectWithoutProperties2.default)(query, ["doctype", "selector", "id", "ids", "referenced"]); - - if (!doctype) { - console.warn('Bad query', query); - throw new Error('No doctype found in a query definition'); - } - - var collection = this.stackClient.collection(doctype); - - if (id) { - return collection.get(id, query); - } - if (ids) { - return collection.getAll(ids); - } - - if (referenced) { - return collection.findReferencedBy(referenced, options); - } - return !selector && !options.sort ? collection.all(options) : collection.find(selector, options); - } - }, { - key: "executeMutation", + (0, _createClass2.default)(SettingsCollection, [{ + key: "get", value: function () { - var _executeMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(mutation, result, forward) { - var mutationType, doc, docs, props, updateAllResp; + var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(path) { + var resp; return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: - mutationType = mutation.mutationType, doc = mutation.document, docs = mutation.documents, props = (0, _objectWithoutProperties2.default)(mutation, ["mutationType", "document", "documents"]); - _context.t0 = mutationType; - _context.next = _context.t0 === _dsl.MutationTypes.CREATE_DOCUMENT ? 4 : _context.t0 === _dsl.MutationTypes.UPDATE_DOCUMENTS ? 5 : _context.t0 === _dsl.MutationTypes.UPDATE_DOCUMENT ? 9 : _context.t0 === _dsl.MutationTypes.DELETE_DOCUMENT ? 10 : _context.t0 === _dsl.MutationTypes.ADD_REFERENCES_TO ? 11 : _context.t0 === _dsl.MutationTypes.REMOVE_REFERENCES_TO ? 12 : _context.t0 === _dsl.MutationTypes.ADD_REFERENCED_BY ? 13 : _context.t0 === _dsl.MutationTypes.REMOVE_REFERENCED_BY ? 18 : _context.t0 === _dsl.MutationTypes.UPLOAD_FILE ? 23 : 24; - break; - - case 4: - return _context.abrupt("return", this.stackClient.collection(doc._type).create(doc)); - - case 5: - _context.next = 7; - return this.stackClient.collection(docs[0]._type).updateAll(docs); - - case 7: - updateAllResp = _context.sent; - return _context.abrupt("return", transformBulkDocsResponse(updateAllResp, docs)); - - case 9: - return _context.abrupt("return", this.stackClient.collection(doc._type).update(doc)); - - case 10: - return _context.abrupt("return", this.stackClient.collection(doc._type).destroy(doc)); - - case 11: - return _context.abrupt("return", this.stackClient.collection(props.referencedDocuments[0]._type).addReferencesTo(doc, props.referencedDocuments)); - - case 12: - return _context.abrupt("return", this.stackClient.collection(props.referencedDocuments[0]._type).removeReferencesTo(doc, props.referencedDocuments)); - - case 13: - if (!(doc._type === _const.DOCTYPE_FILES)) { - _context.next = 17; - break; - } - - return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).addReferencedBy(doc, props.referencedDocuments)); - - case 17: - throw new Error('The document type should be io.cozy.files'); - - case 18: - if (!(doc._type === _const.DOCTYPE_FILES)) { - _context.next = 22; - break; - } - - return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).removeReferencedBy(doc, props.referencedDocuments)); - - case 22: - throw new Error('The document type should be io.cozy.files'); - - case 23: - return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).upload(props.file, props.dirPath)); + _context.next = 2; + return this.stackClient.fetchJSON('GET', "/settings/".concat(path)); - case 24: - return _context.abrupt("return", forward(mutation, result)); + case 2: + resp = _context.sent; + return _context.abrupt("return", { + data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SETTINGS_DOCTYPE)(_objectSpread({ + id: "/settings/".concat(path) + }, resp.data), resp) + }); - case 25: + case 4: case "end": return _context.stop(); } @@ -111637,17 +110524,19 @@ var StackLink = /*#__PURE__*/function (_CozyLink) { }, _callee, this); })); - function executeMutation(_x, _x2, _x3) { - return _executeMutation.apply(this, arguments); + function get(_x) { + return _get.apply(this, arguments); } - return executeMutation; + return get; }() }]); - return StackLink; -}(_CozyLink2.default); + return SettingsCollection; +}(_DocumentCollection2.default); -exports["default"] = StackLink; +SettingsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; +var _default = SettingsCollection; +exports["default"] = _default; /***/ }), /* 687 */ @@ -111656,13476 +110545,14618 @@ exports["default"] = StackLink; "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.chain = exports["default"] = void 0; +exports["default"] = exports.NOTES_URL_DOCTYPE = exports.NOTES_DOCTYPE = void 0; -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); +var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var CozyLink = /*#__PURE__*/function () { - function CozyLink(requestHandler) { - (0, _classCallCheck2.default)(this, CozyLink); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - if (typeof requestHandler === 'function') { - this.request = requestHandler; - } - } +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - (0, _createClass2.default)(CozyLink, [{ - key: "request", - value: function request(operation, result, forward) { - throw new Error('request is not implemented'); - } - }]); - return CozyLink; -}(); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -exports["default"] = CozyLink; +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var toLink = function toLink(handler) { - return typeof handler === 'function' ? new CozyLink(handler) : handler; -}; +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var defaultLinkHandler = function defaultLinkHandler(operation, result) { - if (result) return result;else if (operation.execute) return operation.execute();else throw new Error("No link could handle operation ".concat(JSON.stringify(operation))); -}; +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var chain = function chain(links) { - return [].concat((0, _toConsumableArray2.default)(links), [defaultLinkHandler]).map(toLink).reduce(concat); -}; +var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(613)); -exports.chain = chain; +var _utils = __webpack_require__(623); -var concat = function concat(firstLink, nextLink) { - return new CozyLink(function (operation, result, forward) { - var nextForward = function nextForward(op, res) { - return nextLink.request(op, res, forward); - }; +var _NotesSchema = __webpack_require__(688); - return firstLink.request(operation, result, nextForward); - }); -}; +function _templateObject2() { + var data = (0, _taggedTemplateLiteral2.default)(["/notes/", "/open"]); -/***/ }), -/* 688 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + _templateObject2 = function _templateObject2() { + return data; + }; -"use strict"; + return data; +} +function _templateObject() { + var data = (0, _taggedTemplateLiteral2.default)(["/files/", ""]); -var _interopRequireDefault = __webpack_require__(512); + _templateObject = function _templateObject() { + return data; + }; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.BulkEditError = void 0; + return data; +} -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); +var NOTES_DOCTYPE = 'io.cozy.notes'; +exports.NOTES_DOCTYPE = NOTES_DOCTYPE; +var NOTES_URL_DOCTYPE = 'io.cozy.notes.url'; +exports.NOTES_URL_DOCTYPE = NOTES_URL_DOCTYPE; -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +var normalizeDoc = _DocumentCollection2.default.normalizeDoctypeJsonApi(NOTES_DOCTYPE); -var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652)); +var normalizeNote = function normalizeNote(note) { + return _objectSpread(_objectSpread({}, normalizeDoc(note, NOTES_DOCTYPE)), note.attributes); +}; -var _zipWith = _interopRequireDefault(__webpack_require__(689)); +var normalizeNoteUrl = function normalizeNoteUrl(noteUrl) { + return _objectSpread(_objectSpread({}, _DocumentCollection2.default.normalizeDoctypeJsonApi(NOTES_URL_DOCTYPE)(noteUrl)), noteUrl.attributes); +}; +/** + * Implements `DocumentCollection` API to interact with the /notes endpoint of the stack + */ -var _types = __webpack_require__(610); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +var NotesCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(NotesCollection, _DocumentCollection); -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + var _super = _createSuper(NotesCollection); -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } + function NotesCollection(stackClient) { + (0, _classCallCheck2.default)(this, NotesCollection); + return _super.call(this, NOTES_DOCTYPE, stackClient); + } + /** + * Fetches all notes + * + * @returns {{data, links, meta}} The JSON API conformant response. + */ -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -var BulkEditError = /*#__PURE__*/function (_Error) { - (0, _inherits2.default)(BulkEditError, _Error); + (0, _createClass2.default)(NotesCollection, [{ + key: "all", + value: function () { + var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { + var resp; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return this.stackClient.fetchJSON('GET', '/notes'); - var _super = _createSuper(BulkEditError); + case 2: + resp = _context.sent; + return _context.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { + data: resp.data.map(normalizeNote) + })); - /** - * Indicates that a bulk edit has (potentially partially) failed - * - * @param {CouchDBBulkResult[]} bulkResponse - CouchDB Bulk response - * @param {CozyClientDocument[]} updatedDocs - Docs with updated _id and _rev - */ - function BulkEditError(bulkResponse, updatedDocs) { - var _this; + case 4: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); - (0, _classCallCheck2.default)(this, BulkEditError); - _this = _super.call(this, 'Error while bulk saving'); - _this.name = 'BulkEditError'; - _this.results = (0, _zipWith.default)(bulkResponse, updatedDocs, function (result, doc) { - return _objectSpread(_objectSpread({}, result), {}, { - doc: doc - }); - }); - return _this; - } - /** - * Get documents that have been correctly updated - * - * @returns {CozyClientDocument[]} - */ + function all() { + return _all.apply(this, arguments); + } + return all; + }() + /** + * Destroys the note on the server + * + * @param {object} note The io.cozy.notes document to destroy + * @param {string} [note._id] The note's id + * + * @returns {{ data }} The deleted note + */ - (0, _createClass2.default)(BulkEditError, [{ - key: "getUpdatedDocuments", - value: function getUpdatedDocuments() { - return this.results.filter(function (r) { - return r.ok; - }).map(function (r) { - return r.doc; - }); - } + }, { + key: "destroy", + value: function () { + var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref) { + var _id, resp; + + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _id = _ref._id; + _context2.next = 3; + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject(), _id)); + + case 3: + resp = _context2.sent; + return _context2.abrupt("return", { + data: _objectSpread(_objectSpread({}, normalizeNote(resp.data)), {}, { + _deleted: true + }) + }); + + case 5: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function destroy(_x) { + return _destroy.apply(this, arguments); + } + + return destroy; + }() /** - * Get bulk errors results + * Create a note * - * @returns {Array<CouchDBBulkResult & { doc: CozyClientDocument }>} + * @param {object} options + * @param {string} [options.dir_id] dir_id where to create the note + * + * @returns {{data, links, meta}} The JSON API conformant response. */ }, { - key: "getErrors", - value: function getErrors() { - return this.results.filter(function (r) { - return !r.ok; - }); - } - }]); - return BulkEditError; -}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); + key: "create", + value: function () { + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref2) { + var dir_id, resp; + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + dir_id = _ref2.dir_id; + _context3.next = 3; + return this.stackClient.fetchJSON('POST', '/notes', { + data: { + type: 'io.cozy.notes.documents', + attributes: { + title: '', + schema: (0, _NotesSchema.getDefaultSchema)(), + dir_id: dir_id + } + } + }); -exports.BulkEditError = BulkEditError; + case 3: + resp = _context3.sent; + return _context3.abrupt("return", _objectSpread(_objectSpread({}, resp), {}, { + data: normalizeNote(resp.data) + })); -/***/ }), -/* 689 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 5: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); -var baseRest = __webpack_require__(544), - unzipWith = __webpack_require__(690); + function create(_x2) { + return _create.apply(this, arguments); + } -/** - * This method is like `_.zip` except that it accepts `iteratee` to specify - * how grouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @param {Function} [iteratee=_.identity] The function to combine - * grouped values. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { - * return a + b + c; - * }); - * // => [111, 222] - */ -var zipWith = baseRest(function(arrays) { - var length = arrays.length, - iteratee = length > 1 ? arrays[length - 1] : undefined; + return create; + }() + /** + * Returns the details to build the note's url + * + * @see https://github.com/cozy/cozy-stack/blob/master/docs/notes.md#get-notesidopen + * + * @param {object} note The io.cozy.notes document to open + * @param {string} [note._id] The note's id + * + * @returns {{ data }} The note's url details + */ - iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; - return unzipWith(arrays, iteratee); -}); + }, { + key: "fetchURL", + value: function () { + var _fetchURL = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(_ref3) { + var _id, resp; -module.exports = zipWith; + return _regenerator.default.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _id = _ref3._id; + _context4.next = 3; + return this.stackClient.fetchJSON('GET', (0, _utils.uri)(_templateObject2(), _id)); + + case 3: + resp = _context4.sent; + return _context4.abrupt("return", { + data: normalizeNoteUrl(resp.data) + }); + + case 5: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); + + function fetchURL(_x3) { + return _fetchURL.apply(this, arguments); + } + + return fetchURL; + }() + /** + * Returns promise mirror schema for a note + * + * @returns {object} schema + */ + + }, { + key: "getDefaultSchema", + value: function getDefaultSchema() { + return (0, _NotesSchema.getDefaultSchema)(); + } + }]); + return NotesCollection; +}(_DocumentCollection2.default); +NotesCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; +var _default = NotesCollection; +exports["default"] = _default; /***/ }), -/* 690 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 688 */ +/***/ ((__unused_webpack_module, exports) => { -var apply = __webpack_require__(546), - arrayMap = __webpack_require__(398), - unzip = __webpack_require__(551); +"use strict"; -/** - * This method is like `_.unzip` except that it accepts `iteratee` to specify - * how regrouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @param {Function} [iteratee=_.identity] The function to combine - * regrouped values. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip([1, 2], [10, 20], [100, 200]); - * // => [[1, 10, 100], [2, 20, 200]] - * - * _.unzipWith(zipped, _.add); - * // => [3, 30, 300] - */ -function unzipWith(array, iteratee) { - if (!(array && array.length)) { - return []; - } - var result = unzip(array); - if (iteratee == null) { - return result; + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getDefaultSchema = exports.marks = exports.nodes = void 0; +// taken from a debug of @atlakit/editor/editor-core/create-editor/create-editor +// L139 (new Schema({nodes ,marks})) +// static because the @atlaskit code base requires a real navigator +// TODO: either find and exclude plugins requiring interaction +// or running a JSDOM faking a navigator +var nodes = [['doc', { + content: '(block)+', + marks: 'link' +}], ['paragraph', { + content: 'inline*', + group: 'block', + marks: 'strong code em link strike subsup textColor typeAheadQuery underline', + parseDOM: [{ + tag: 'p' + }] +}], ['text', { + group: 'inline' +}], ['bulletList', { + group: 'block', + content: 'listItem+', + parseDOM: [{ + tag: 'ul' + }] +}], ['orderedList', { + group: 'block', + content: 'listItem+', + parseDOM: [{ + tag: 'ol' + }] +}], ['listItem', { + content: '(paragraph ) (paragraph | bulletList | orderedList )*', + defining: true, + parseDOM: [{ + tag: 'li' + }] +}], ['heading', { + attrs: { + level: { + default: 1 + } + }, + content: 'inline*', + group: 'block', + defining: true, + parseDOM: [{ + tag: 'h1', + attrs: { + level: 1 + } + }, { + tag: 'h2', + attrs: { + level: 2 + } + }, { + tag: 'h3', + attrs: { + level: 3 + } + }, { + tag: 'h4', + attrs: { + level: 4 + } + }, { + tag: 'h5', + attrs: { + level: 5 + } + }, { + tag: 'h6', + attrs: { + level: 6 + } + }] +}], ['blockquote', { + content: 'paragraph+', + group: 'block', + defining: true, + selectable: false, + parseDOM: [{ + tag: 'blockquote' + }] +}], ['rule', { + group: 'block', + parseDOM: [{ + tag: 'hr' + }] +}], ['panel', { + group: 'block', + content: '(paragraph | heading | bulletList | orderedList)+', + attrs: { + panelType: { + default: 'info' + } + }, + parseDOM: [{ + tag: 'div[data-panel-type]' + }] +}], ['confluenceUnsupportedBlock', { + group: 'block', + attrs: { + cxhtml: { + default: null + } + }, + parseDOM: [{ + tag: 'div[data-node-type="confluenceUnsupportedBlock"]' + }] +}], ['confluenceUnsupportedInline', { + group: 'inline', + inline: true, + atom: true, + attrs: { + cxhtml: { + default: null + } + }, + parseDOM: [{ + tag: 'div[data-node-type="confluenceUnsupportedInline"]' + }] +}], ['unsupportedBlock', { + inline: false, + group: 'block', + atom: true, + selectable: true, + attrs: { + originalValue: { + default: {} + } + }, + parseDOM: [{ + tag: '[data-node-type="unsupportedBlock"]' + }] +}], ['unsupportedInline', { + inline: true, + group: 'inline', + selectable: true, + attrs: { + originalValue: { + default: {} + } + }, + parseDOM: [{ + tag: '[data-node-type="unsupportedInline"]' + }] +}], ['hardBreak', { + inline: true, + group: 'inline', + selectable: false, + parseDOM: [{ + tag: 'br' + }] +}], ['table', { + content: 'tableRow+', + attrs: { + isNumberColumnEnabled: { + default: false + }, + layout: { + default: 'default' + }, + __autoSize: { + default: false + } + }, + tableRole: 'table', + isolating: true, + selectable: false, + group: 'block', + parseDOM: [{ + tag: 'table' + }] +}], ['tableHeader', { + content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading )+', + attrs: { + colspan: { + default: 1 + }, + rowspan: { + default: 1 + }, + colwidth: { + default: null + }, + background: { + default: null + } + }, + tableRole: 'header_cell', + isolating: true, + marks: '', + parseDOM: [{ + tag: 'th' + }] +}], ['tableRow', { + content: '(tableCell | tableHeader)+', + tableRole: 'row', + parseDOM: [{ + tag: 'tr' + }] +}], ['tableCell', { + content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | unsupportedBlock)+', + attrs: { + colspan: { + default: 1 + }, + rowspan: { + default: 1 + }, + colwidth: { + default: null + }, + background: { + default: null + } + }, + tableRole: 'cell', + marks: '', + isolating: true, + parseDOM: [{ + tag: '.ak-renderer-table-number-column', + ignore: true + }, { + tag: 'td' + }] +}]]; +exports.nodes = nodes; +var marks = [['link', { + excludes: 'color', + group: 'link', + attrs: { + href: {}, + __confluenceMetadata: { + default: null + } + }, + inclusive: false, + parseDOM: [{ + tag: 'a[href]' + }] +}], ['em', { + inclusive: true, + group: 'fontStyle', + parseDOM: [{ + tag: 'i' + }, { + tag: 'em' + }, { + style: 'font-style=italic' + }] +}], ['strong', { + inclusive: true, + group: 'fontStyle', + parseDOM: [{ + tag: 'strong' + }, { + tag: 'b' + }, { + style: 'font-weight' + }] +}], ['textColor', { + attrs: { + color: {} + }, + inclusive: true, + group: 'color', + parseDOM: [{ + style: 'color' + }] +}], ['strike', { + inclusive: true, + group: 'fontStyle', + parseDOM: [{ + tag: 'strike' + }, { + tag: 's' + }, { + tag: 'del' + }, { + style: 'text-decoration' + }] +}], ['subsup', { + inclusive: true, + group: 'fontStyle', + attrs: { + type: { + default: 'sub' + } + }, + parseDOM: [{ + tag: 'sub', + attrs: { + type: 'sub' + } + }, { + tag: 'sup', + attrs: { + type: 'sup' + } + }] +}], ['underline', { + inclusive: true, + group: 'fontStyle', + parseDOM: [{ + tag: 'u' + }, { + style: 'text-decoration' + }] +}], ['code', { + excludes: 'fontStyle link searchQuery color', + inclusive: true, + parseDOM: [{ + tag: 'span.code', + preserveWhitespace: true + }, { + tag: 'code', + preserveWhitespace: true + }, { + tag: 'tt', + preserveWhitespace: true + }, { + tag: 'span', + preserveWhitespace: true + }] +}], ['typeAheadQuery', { + excludes: 'searchQuery', + inclusive: true, + group: 'searchQuery', + parseDOM: [{ + tag: 'span[data-type-ahead-query]' + }], + attrs: { + trigger: { + default: '' + } } - return arrayMap(result, function(group) { - return apply(iteratee, undefined, group); - }); -} +}]]; +exports.marks = marks; -module.exports = unzipWith; +var getDefaultSchema = function getDefaultSchema() { + return { + nodes: nodes, + marks: marks + }; +}; +exports.getDefaultSchema = getDefaultSchema; /***/ }), -/* 691 */ +/* 689 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireWildcard = __webpack_require__(522); + +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -Object.defineProperty(exports, "HasManyFiles", ({ - enumerable: true, - get: function get() { - return _HasManyFiles.default; - } -})); -Object.defineProperty(exports, "HasMany", ({ - enumerable: true, - get: function get() { - return _HasMany.default; - } -})); -Object.defineProperty(exports, "HasOne", ({ - enumerable: true, - get: function get() { - return _HasOne.default; - } -})); -Object.defineProperty(exports, "HasOneInPlace", ({ - enumerable: true, - get: function get() { - return _HasOneInPlace.default; - } -})); -Object.defineProperty(exports, "HasManyInPlace", ({ - enumerable: true, - get: function get() { - return _HasManyInPlace.default; - } -})); -Object.defineProperty(exports, "HasManyTriggers", ({ - enumerable: true, - get: function get() { - return _HasManyTriggers.default; - } -})); -Object.defineProperty(exports, "Association", ({ - enumerable: true, - get: function get() { - return _Association.default; - } -})); -Object.defineProperty(exports, "resolveClass", ({ - enumerable: true, - get: function get() { - return _helpers.resolveClass; - } -})); -Object.defineProperty(exports, "create", ({ - enumerable: true, - get: function get() { - return _helpers.create; - } -})); -Object.defineProperty(exports, "isReferencedBy", ({ - enumerable: true, - get: function get() { - return _helpers.isReferencedBy; - } -})); -Object.defineProperty(exports, "isReferencedById", ({ - enumerable: true, - get: function get() { - return _helpers.isReferencedById; - } -})); -Object.defineProperty(exports, "getReferencedBy", ({ - enumerable: true, - get: function get() { - return _helpers.getReferencedBy; - } -})); -Object.defineProperty(exports, "getReferencedById", ({ - enumerable: true, - get: function get() { - return _helpers.getReferencedById; - } -})); - -var _HasManyFiles = _interopRequireDefault(__webpack_require__(692)); - -var _HasMany = _interopRequireDefault(__webpack_require__(741)); - -var _HasOne = _interopRequireDefault(__webpack_require__(750)); - -var _HasOneInPlace = _interopRequireDefault(__webpack_require__(752)); - -var _HasManyInPlace = _interopRequireDefault(__webpack_require__(753)); - -var _HasManyTriggers = _interopRequireDefault(__webpack_require__(754)); - -var _Association = _interopRequireDefault(__webpack_require__(740)); +exports["default"] = exports.OAUTH_CLIENTS_DOCTYPE = void 0; -var _helpers = __webpack_require__(755); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -/***/ }), -/* 692 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614)); -"use strict"; +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _interopRequireDefault = __webpack_require__(512); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _get2 = _interopRequireDefault(__webpack_require__(370)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(613)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _utils = __webpack_require__(623); -var _get3 = _interopRequireDefault(__webpack_require__(670)); +var querystring = _interopRequireWildcard(__webpack_require__(659)); -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +var _Collection = __webpack_require__(612); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); +var _errors = __webpack_require__(663); -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +function _templateObject3() { + var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients/", ""]); -var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520)); + _templateObject3 = function _templateObject3() { + return data; + }; -var _get4 = _interopRequireDefault(__webpack_require__(358)); + return data; +} -var _omit = _interopRequireDefault(__webpack_require__(613)); +function _templateObject2() { + var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients/", ""]); -var _uniq = _interopRequireDefault(__webpack_require__(612)); + _templateObject2 = function _templateObject2() { + return data; + }; -var _dsl = __webpack_require__(607); + return data; +} -var _store = __webpack_require__(693); +function _templateObject() { + var data = (0, _taggedTemplateLiteral2.default)(["/settings/clients"]); -var _types = __webpack_require__(610); + _templateObject = function _templateObject() { + return data; + }; -var _const = __webpack_require__(685); + return data; +} -var _Association = _interopRequireDefault(__webpack_require__(740)); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -var _HasMany2 = _interopRequireDefault(__webpack_require__(741)); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +var OAUTH_CLIENTS_DOCTYPE = 'io.cozy.oauth.clients'; +exports.OAUTH_CLIENTS_DOCTYPE = OAUTH_CLIENTS_DOCTYPE; -/** - * newCursor - Returns a CouchDB view Cursor for cursor-based pagination - * - * @param {ViewKey} key - The CouchDB key of the view which will be requested - * @param {DocId} startDocId - The first doc _id to return from the view - * - * @returns {CouchDBViewCursor} - */ -var newCursor = function newCursor(_ref, startDocId) { - var _ref2 = (0, _slicedToArray2.default)(_ref, 3), - doctype = _ref2[0], - id = _ref2[1], - lastDatetime = _ref2[2]; +var normalizeDoc = _DocumentCollection2.default.normalizeDoctypeJsonApi(OAUTH_CLIENTS_DOCTYPE); - var cursorKey = lastDatetime ? [doctype, id, lastDatetime] : [doctype, id]; - return [cursorKey, startDocId]; +var normalizeOAuthClient = function normalizeOAuthClient(client) { + return _objectSpread(_objectSpread({}, normalizeDoc(client, OAUTH_CLIENTS_DOCTYPE)), client.attributes); }; /** - * This class is only used for photos albums relationships. - * Behind the hood, the queries uses a view returning the files sorted - * by datetime, with a cursor-based pagination. + * Implements `DocumentCollection` API to interact with the /settings/clients endpoint of the stack */ -var HasManyFiles = /*#__PURE__*/function (_HasMany) { - (0, _inherits2.default)(HasManyFiles, _HasMany); +var OAuthClientsCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(OAuthClientsCollection, _DocumentCollection); - var _super = _createSuper(HasManyFiles); + var _super = _createSuper(OAuthClientsCollection); - function HasManyFiles() { - (0, _classCallCheck2.default)(this, HasManyFiles); - return _super.apply(this, arguments); + function OAuthClientsCollection(stackClient) { + (0, _classCallCheck2.default)(this, OAuthClientsCollection); + return _super.call(this, OAUTH_CLIENTS_DOCTYPE, stackClient); } + /** + * Fetches all OAuth clients + * + * @param {object} options Query options + * @param {number} [options.limit] For pagination, the number of results to return. + * @param {string} [options.bookmark] For bookmark-based pagination, the document _id to start from + * @param {Array<string>} [options.keys] Ids of specific clients to return (within the current page), + * + * @returns {object} The JSON API conformant response. + */ - (0, _createClass2.default)(HasManyFiles, [{ - key: "fetchMore", + + (0, _createClass2.default)(OAuthClientsCollection, [{ + key: "all", value: function () { - var _fetchMore = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { - var _this = this; + var _all = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { + var options, + _options$limit, + limit, + bookmark, + keys, + params, + url, + path, + resp, + nextLink, + nextLinkURL, + nextBookmark, + hasBookmark, + data, + meta, + _args = arguments; - var queryDef, relationships, lastRelationship; - return _regenerator.default.wrap(function _callee2$(_context2) { + return _regenerator.default.wrap(function _callee$(_context) { while (1) { - switch (_context2.prev = _context2.next) { + switch (_context.prev = _context.next) { case 0: - queryDef = new _dsl.QueryDefinition({ - doctype: _const.DOCTYPE_FILES - }); - relationships = this.getRelationship().data; // Get last datetime for cursor + options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}; + _options$limit = options.limit, limit = _options$limit === void 0 ? 100 : _options$limit, bookmark = options.bookmark, keys = options.keys; + params = { + 'page[limit]': limit, + 'page[cursor]': bookmark + }; + url = (0, _utils.uri)(_templateObject()); + path = querystring.buildURL(url, params); + _context.prev = 5; + _context.next = 8; + return this.stackClient.fetchJSON('GET', path); - lastRelationship = relationships[relationships.length - 1]; - _context2.next = 5; - return this.dispatch( /*#__PURE__*/function () { - var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(dispatch, getState) { - var lastRelDoc, lastDatetime, cursor, response; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - lastRelDoc = (0, _store.getDocumentFromState)(getState(), lastRelationship._type, lastRelationship._id); // Photos always have a datetime field in metadata + case 8: + resp = _context.sent; + _context.next = 14; + break; - lastDatetime = lastRelDoc.attributes.metadata.datetime; // cursor-based pagination + case 11: + _context.prev = 11; + _context.t0 = _context["catch"](5); + return _context.abrupt("return", (0, _Collection.dontThrowNotFoundError)(_context.t0)); - cursor = newCursor([_this.target._type, _this.target._id, lastDatetime], relationships[relationships.length - 1]._id); - _context.next = 5; - return _this.query(queryDef.referencedBy(_this.target).offsetCursor(cursor)); + case 14: + nextLink = (0, _get2.default)(resp, 'links.next', ''); + nextLinkURL = new URL("".concat(this.stackClient.uri).concat(nextLink)); + nextBookmark = nextLinkURL.searchParams.get('page[cursor]') || undefined; + hasBookmark = nextBookmark !== undefined; - case 5: - response = _context.sent; - // Remove first returned element, used as starting point for the query - response.data.shift(); - _context.next = 9; - return _this.dispatch(_this.updateRelationshipData(function (previousRelationshipData) { - return _objectSpread(_objectSpread({}, previousRelationshipData), {}, { - data: [].concat((0, _toConsumableArray2.default)(previousRelationshipData.data), (0, _toConsumableArray2.default)(response.data)), - next: response.next - }); - })); + if (!keys) { + _context.next = 24; + break; + } - case 9: - case "end": - return _context.stop(); - } - } - }, _callee); - })); + data = resp.data.filter(function (c) { + return keys.includes(c.id); + }).map(function (c) { + return normalizeOAuthClient(c); + }); + meta = _objectSpread(_objectSpread({}, resp.meta), {}, { + count: data.length + }); + return _context.abrupt("return", { + data: data, + meta: meta, + next: keys.length > data.length && hasBookmark, + bookmark: nextBookmark + }); - return function (_x, _x2) { - return _ref3.apply(this, arguments); - }; - }()); + case 24: + return _context.abrupt("return", { + data: resp.data.map(function (c) { + return normalizeOAuthClient(c); + }), + meta: resp.meta, + next: hasBookmark, + bookmark: nextBookmark + }); - case 5: + case 25: case "end": - return _context2.stop(); + return _context.stop(); } } - }, _callee2, this); + }, _callee, this, [[5, 11]]); })); - function fetchMore() { - return _fetchMore.apply(this, arguments); + function all() { + return _all.apply(this, arguments); } - return fetchMore; + return all; }() + /** + * Get an OAuth client by id + * + * @param {string} id The client id. + * @returns {object} JsonAPI response containing normalized client as data attribute + */ + }, { - key: "addById", + key: "get", value: function () { - var _addById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(idsArg) { - var _this2 = this; - - var ids, relations; - return _regenerator.default.wrap(function _callee3$(_context3) { + var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) { + var resp; + return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { - switch (_context3.prev = _context3.next) { + switch (_context2.prev = _context2.next) { case 0: - ids = Array.isArray(idsArg) ? idsArg : [idsArg]; - relations = ids.map(function (id) { - return { - _id: id, - _type: _this2.doctype - }; + _context2.next = 2; + return this.all({ + keys: [id] }); - _context3.next = 4; - return this.mutate(this.addReferences(relations)); - case 4: - this.addTargetRelationships(ids); + case 2: + resp = _context2.sent; - case 5: + case 3: + if (!resp.next) { + _context2.next = 9; + break; + } + + _context2.next = 6; + return this.all({ + keys: [id], + bookmark: resp.bookmark + }); + + case 6: + resp = _context2.sent; + _context2.next = 3; + break; + + case 9: + if (!resp.data.length) { + _context2.next = 13; + break; + } + + return _context2.abrupt("return", { + data: normalizeOAuthClient(resp.data[0]) + }); + + case 13: + resp.url = (0, _utils.uri)(_templateObject2(), id); + resp.status = '404'; + throw new _errors.FetchError(resp, 'Not Found'); + + case 16: case "end": - return _context3.stop(); + return _context2.stop(); } } - }, _callee3, this); + }, _callee2, this); })); - function addById(_x3) { - return _addById.apply(this, arguments); + function get(_x) { + return _get.apply(this, arguments); } - return addById; + return get; }() + /** + * Destroys the OAuth client on the server + * + * @param {object} oauthClient The io.cozy.oauth.clients document to destroy + * + * @returns {{ data }} The deleted client + */ + }, { - key: "removeById", + key: "destroy", value: function () { - var _removeById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(idsArg) { - var _this3 = this; + var _destroy = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(oauthClient) { + var _id; - var ids, references; - return _regenerator.default.wrap(function _callee4$(_context4) { + return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { - switch (_context4.prev = _context4.next) { + switch (_context3.prev = _context3.next) { case 0: - ids = Array.isArray(idsArg) ? idsArg : [idsArg]; - references = ids.map(function (id) { - return { - _id: id, - _type: _this3.doctype - }; + _id = oauthClient._id; + _context3.next = 3; + return this.stackClient.fetchJSON('DELETE', (0, _utils.uri)(_templateObject3(), _id)); + + case 3: + return _context3.abrupt("return", { + data: _objectSpread(_objectSpread({}, normalizeOAuthClient(oauthClient)), {}, { + _deleted: true + }) }); - _context4.next = 4; - return this.mutate(this.removeReferences(references)); case 4: - this.removeTargetRelationships(ids); - - case 5: case "end": - return _context4.stop(); + return _context3.stop(); } } - }, _callee4, this); + }, _callee3, this); })); - function removeById(_x4) { - return _removeById.apply(this, arguments); + function destroy(_x2) { + return _destroy.apply(this, arguments); } - return removeById; + return destroy; }() - }, { - key: "addReferences", - value: function addReferences(referencedDocs) { - if (this.target._type === _const.DOCTYPE_FILES) { - return _dsl.Mutations.addReferencedBy(this.target, referencedDocs); - } else if (referencedDocs[0]._type === _const.DOCTYPE_FILES) { - return _dsl.Mutations.addReferencesTo(this.target, referencedDocs); - } else { - throw new Error('Either the document or the references should be io.cozy.files'); - } - } - }, { - key: "removeReferences", - value: function removeReferences(referencedDocs) { - if (this.target._type === _const.DOCTYPE_FILES) { - return _dsl.Mutations.removeReferencedBy(this.target, referencedDocs); - } else if (referencedDocs[0]._type === _const.DOCTYPE_FILES) { - return _dsl.Mutations.removeReferencesTo(this.target, referencedDocs); - } else { - throw new Error('Either the document or the references should be io.cozy.files'); - } - } - }, { - key: "dehydrate", - value: function dehydrate(doc) { - // HasManyFiles relationships are stored on the file doctype, not the document the files are related to - return (0, _omit.default)(doc, [this.name, "relationships.".concat(this.name)]); - } - /** - * @param {CozyClientDocument} document - Document to query - * @param {object} client - The CozyClient instance - * @param {Association} assoc - The query params - * - * @returns {CozyClientDocument | QueryDefinition} - */ - - }, { - key: "data", - get: function get() { - var _this4 = this; - - if (this.target._type === _const.DOCTYPE_FILES) { - var refs = (0, _get4.default)(this.target, 'referenced_by', []); - return refs.map(function (_ref4) { - var id = _ref4.id, - type = _ref4.type; - return _this4.get(type, id); - }).filter(Boolean); - } else { - return (0, _get3.default)((0, _getPrototypeOf2.default)(HasManyFiles.prototype), "data", this); - } - } - }], [{ - key: "query", - value: function query(document, client, assoc) { - if (document._type === _const.DOCTYPE_FILES) { - var refs = (0, _get4.default)(document, "relationships.referenced_by.data", []); - var ids = (0, _uniq.default)(refs.filter(function (ref) { - return ref.type === assoc.doctype; - }).map(function (ref) { - return ref.id; - })); - return ids.length > 0 ? (0, _dsl.Q)(assoc.doctype).getByIds(ids) : null; - } else { - var cursor = newCursor([document._type, document._id], ''); - return (0, _dsl.Q)(assoc.doctype).referencedBy(document).offsetCursor(cursor); - } - } }]); - return HasManyFiles; -}(_HasMany2.default); + return OAuthClientsCollection; +}(_DocumentCollection2.default); -exports["default"] = HasManyFiles; +OAuthClientsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; +var _default = OAuthClientsCollection; +exports["default"] = _default; /***/ }), -/* 693 */ +/* 690 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireWildcard = __webpack_require__(510); - -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -Object.defineProperty(exports, "initQuery", ({ - enumerable: true, - get: function get() { - return _queries.initQuery; - } -})); -Object.defineProperty(exports, "loadQuery", ({ - enumerable: true, - get: function get() { - return _queries.loadQuery; - } -})); -Object.defineProperty(exports, "receiveQueryResult", ({ - enumerable: true, - get: function get() { - return _queries.receiveQueryResult; - } -})); -Object.defineProperty(exports, "receiveQueryError", ({ - enumerable: true, - get: function get() { - return _queries.receiveQueryError; - } -})); -Object.defineProperty(exports, "initMutation", ({ - enumerable: true, - get: function get() { - return _mutations.initMutation; - } -})); -Object.defineProperty(exports, "receiveMutationResult", ({ - enumerable: true, - get: function get() { - return _mutations.receiveMutationResult; - } -})); -Object.defineProperty(exports, "receiveMutationError", ({ - enumerable: true, - get: function get() { - return _mutations.receiveMutationError; - } -})); -exports.resetState = exports.getRawQueryFromState = exports.getQueryFromState = exports.getQueryFromStore = exports.getDocumentFromState = exports.getCollectionFromState = exports.getStateRoot = exports.createStore = exports["default"] = exports.StoreProxy = void 0; +exports["default"] = exports.SHORTCUTS_DOCTYPE = void 0; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(614)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _cozyFlags = _interopRequireDefault(__webpack_require__(603)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _redux = __webpack_require__(694); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _reduxThunk = _interopRequireDefault(__webpack_require__(697)); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -var _documents = _interopRequireWildcard(__webpack_require__(698)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var _queries = _interopRequireWildcard(__webpack_require__(723)); +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var _mutations = __webpack_require__(738); +var _DocumentCollection2 = _interopRequireDefault(__webpack_require__(613)); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +var _utils = __webpack_require__(623); -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +var _getIllegalCharacter = __webpack_require__(678); -var RESET_ACTION_TYPE = 'COZY_CLIENT.RESET_STATE'; +function _templateObject2() { + var data = (0, _taggedTemplateLiteral2.default)(["/shortcuts/", ""]); -var resetState = function resetState() { - return { - type: RESET_ACTION_TYPE + _templateObject2 = function _templateObject2() { + return data; }; -}; -exports.resetState = resetState; + return data; +} -var StoreProxy = /*#__PURE__*/function () { - function StoreProxy(state) { - (0, _classCallCheck2.default)(this, StoreProxy); - this.state = state; - } +function _templateObject() { + var data = (0, _taggedTemplateLiteral2.default)(["/shortcuts"]); - (0, _createClass2.default)(StoreProxy, [{ - key: "readDocument", - value: function readDocument(doctype, id) { - return this.state.documents[doctype][id]; - } - }, { - key: "writeDocument", - value: function writeDocument(document) { - this.setState(function (state) { - return _objectSpread(_objectSpread({}, state), {}, { - documents: _objectSpread(_objectSpread({}, state.documents), {}, (0, _defineProperty2.default)({}, document._type, _objectSpread(_objectSpread({}, state.documents[document._type]), {}, (0, _defineProperty2.default)({}, document._id, document)))) - }); - }); - } - }, { - key: "setState", - value: function setState(updaterFn) { - this.state = updaterFn(this.state); - } - }, { - key: "getState", - value: function getState() { - return this.state; - } - }]); - return StoreProxy; -}(); + _templateObject = function _templateObject() { + return data; + }; -exports.StoreProxy = StoreProxy; -var initialState = { - documents: {}, - queries: {} -}; + return data; +} -var combinedReducer = function combinedReducer() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; - var action = arguments.length > 1 ? arguments[1] : undefined; +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } - if (action.type == RESET_ACTION_TYPE) { - return initialState; - } +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - if (!(0, _queries.isQueryAction)(action) && !(0, _mutations.isMutationAction)(action)) { - return state; - } +var SHORTCUTS_DOCTYPE = 'io.cozy.files.shortcuts'; +exports.SHORTCUTS_DOCTYPE = SHORTCUTS_DOCTYPE; - if (action.update) { - var proxy = new StoreProxy(state); - action.update(proxy, action.response); - return { - documents: proxy.getState().documents, - queries: (0, _queries.default)(proxy.getState().queries, action, proxy.getState().documents) - }; +var ShortcutsCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(ShortcutsCollection, _DocumentCollection); + + var _super = _createSuper(ShortcutsCollection); + + function ShortcutsCollection(stackClient) { + (0, _classCallCheck2.default)(this, ShortcutsCollection); + return _super.call(this, SHORTCUTS_DOCTYPE, stackClient); } + /** + * Create a shortcut + * + * @param {object} attributes shortcut's attributes + * @param {string} attributes.name Filename + * @param {string} attributes.url Shortcut's URL + * @param {string} attributes.dir_id dir_id where to create the shortcut + * @throws {Error} - explaining reason why creation failed + */ - var nextDocuments = (0, _documents.default)(state.documents, action); - var haveDocumentsChanged = nextDocuments !== state.documents; - return { - documents: nextDocuments, - queries: (0, _queries.default)(state.queries, action, nextDocuments, haveDocumentsChanged) - }; -}; -var _default = combinedReducer; -exports["default"] = _default; + (0, _createClass2.default)(ShortcutsCollection, [{ + key: "create", + value: function () { + var _create = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(attributes) { + var name, illegalCharacters, path, resp; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!attributes.type) { + attributes.type = SHORTCUTS_DOCTYPE; + } -var composedEnhancer = // @ts-ignore '__REDUX_DEVTOOLS_EXTENSION_COMPOSE__' doesn't exist 'Window & typeof globalThis'.ts(2339) -// should be (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ in ts file -// see https://github.com/reduxjs/redux-devtools/tree/main/extension#11-basic-store -(0, _cozyFlags.default)('debug') && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || _redux.compose; + if (!(!attributes.name || !attributes.name.trim() || !attributes.url || !attributes.dir_id)) { + _context.next = 3; + break; + } -var createStore = function createStore() { - return (0, _redux.createStore)((0, _redux.combineReducers)({ - cozy: combinedReducer - }), composedEnhancer((0, _redux.applyMiddleware)(_reduxThunk.default))); -}; + throw new Error('you need at least a name, an url and a dir_id attributes to create a shortcut'); -exports.createStore = createStore; + case 3: + name = attributes.name.trim(); -var getStateRoot = function getStateRoot(state) { - return state.cozy || {}; -}; + if (!(name === '.' || name === '..')) { + _context.next = 6; + break; + } -exports.getStateRoot = getStateRoot; + throw new Error("Invalid filename: ".concat(name)); -var getCollectionFromState = function getCollectionFromState(state, doctype) { - return (0, _documents.getCollectionFromSlice)(getStateRoot(state).documents, doctype); -}; + case 6: + illegalCharacters = (0, _getIllegalCharacter.getIllegalCharacters)(name); -exports.getCollectionFromState = getCollectionFromState; + if (!illegalCharacters.length) { + _context.next = 9; + break; + } -var getDocumentFromState = function getDocumentFromState(state, doctype, id) { - return (0, _documents.getDocumentFromSlice)(getStateRoot(state).documents, doctype, id); -}; + throw new Error("Invalid filename containing illegal character(s): ".concat(illegalCharacters)); -exports.getDocumentFromState = getDocumentFromState; + case 9: + path = (0, _utils.uri)(_templateObject()); + _context.next = 12; + return this.stackClient.fetchJSON('POST', path, { + data: { + attributes: attributes, + type: 'io.cozy.files.shortcuts' + } + }); -var getQueryFromStore = function getQueryFromStore(store, queryId) { - return getQueryFromState(store.getState(), queryId); -}; + case 12: + resp = _context.sent; + return _context.abrupt("return", { + data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SHORTCUTS_DOCTYPE)(resp.data, resp) + }); -exports.getQueryFromStore = getQueryFromStore; + case 14: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); -var getQueryFromState = function getQueryFromState(state, queryId) { - return (0, _queries.getQueryFromSlice)(getStateRoot(state).queries, queryId, getStateRoot(state).documents); -}; + function create(_x) { + return _create.apply(this, arguments); + } -exports.getQueryFromState = getQueryFromState; + return create; + }() + }, { + key: "get", + value: function () { + var _get = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) { + var path, resp; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + path = (0, _utils.uri)(_templateObject2(), id); + _context2.next = 3; + return this.stackClient.fetchJSON('GET', path); -var getRawQueryFromState = function getRawQueryFromState(state, queryId) { - return (0, _queries.getQueryFromSlice)(getStateRoot(state).queries, queryId); -}; + case 3: + resp = _context2.sent; + return _context2.abrupt("return", { + data: _DocumentCollection2.default.normalizeDoctypeJsonApi(SHORTCUTS_DOCTYPE)(resp.data, resp) + }); -exports.getRawQueryFromState = getRawQueryFromState; + case 5: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function get(_x2) { + return _get.apply(this, arguments); + } + + return get; + }() + }]); + return ShortcutsCollection; +}(_DocumentCollection2.default); + +ShortcutsCollection.normalizeDoctype = _DocumentCollection2.default.normalizeDoctypeJsonApi; +var _default = ShortcutsCollection; +exports["default"] = _default; /***/ }), -/* 694 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +/* 691 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "__DO_NOT_USE__ActionTypes": () => (/* binding */ ActionTypes), -/* harmony export */ "applyMiddleware": () => (/* binding */ applyMiddleware), -/* harmony export */ "bindActionCreators": () => (/* binding */ bindActionCreators), -/* harmony export */ "combineReducers": () => (/* binding */ combineReducers), -/* harmony export */ "compose": () => (/* binding */ compose), -/* harmony export */ "createStore": () => (/* binding */ createStore) -/* harmony export */ }); -/* harmony import */ var _babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(695); -/** - * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js - * - * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes - * during build. - * @param {number} code - */ -function formatProdErrorMessage(code) { - return "Minified Redux error #" + code + "; visit https://redux.js.org/Errors?code=" + code + " for the full message or " + 'use the non-minified dev environment for full errors. '; -} +var _interopRequireWildcard = __webpack_require__(522); -// Inlined version of the `symbol-observable` polyfill -var $$observable = (function () { - return typeof Symbol === 'function' && Symbol.observable || '@@observable'; -})(); +var _interopRequireDefault = __webpack_require__(524); -/** - * These are private action types reserved by Redux. - * For any unknown actions, you must return the current state. - * If the current state is undefined, you must return the initial state. - * Do not reference these action types directly in your code. - */ -var randomString = function randomString() { - return Math.random().toString(36).substring(7).split('').join('.'); -}; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.CONTACTS_DOCTYPE = void 0; -var ActionTypes = { - INIT: "@@redux/INIT" + randomString(), - REPLACE: "@@redux/REPLACE" + randomString(), - PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() { - return "@@redux/PROBE_UNKNOWN_ACTION" + randomString(); - } +var _regenerator = _interopRequireDefault(__webpack_require__(539)); + +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); + +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); + +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); + +var _get2 = _interopRequireDefault(__webpack_require__(682)); + +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); + +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); + +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); + +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); + +var _DocumentCollection2 = _interopRequireWildcard(__webpack_require__(613)); + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +var normalizeMyselfResp = function normalizeMyselfResp(resp) { + return _objectSpread(_objectSpread(_objectSpread({}, (0, _DocumentCollection2.normalizeDoc)(resp.data, CONTACTS_DOCTYPE)), resp.data.attributes), {}, { + _rev: resp.data.meta.rev + }); }; -/** - * @param {any} obj The object to inspect. - * @returns {boolean} True if the argument appears to be a plain object. - */ -function isPlainObject(obj) { - if (typeof obj !== 'object' || obj === null) return false; - var proto = obj; +var ContactsCollection = /*#__PURE__*/function (_DocumentCollection) { + (0, _inherits2.default)(ContactsCollection, _DocumentCollection); - while (Object.getPrototypeOf(proto) !== null) { - proto = Object.getPrototypeOf(proto); + var _super = _createSuper(ContactsCollection); + + function ContactsCollection() { + (0, _classCallCheck2.default)(this, ContactsCollection); + return _super.apply(this, arguments); } - return Object.getPrototypeOf(obj) === proto; -} + (0, _createClass2.default)(ContactsCollection, [{ + key: "find", + value: function () { + var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(selector, options) { + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!(Object.values(selector).length === 1 && selector['me'] == true)) { + _context.next = 4; + break; + } + + return _context.abrupt("return", this.findMyself()); + + case 4: + return _context.abrupt("return", (0, _get2.default)((0, _getPrototypeOf2.default)(ContactsCollection.prototype), "find", this).call(this, selector, options)); + + case 5: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function find(_x, _x2) { + return _find.apply(this, arguments); + } + + return find; + }() + }, { + key: "findMyself", + value: function () { + var _findMyself = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { + var resp, col; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return this.stackClient.fetchJSON('POST', '/contacts/myself'); + + case 2: + resp = _context2.sent; + col = { + data: [normalizeMyselfResp(resp)], + next: false, + meta: null, + bookmark: false + }; + return _context2.abrupt("return", col); + + case 5: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function findMyself() { + return _findMyself.apply(this, arguments); + } + + return findMyself; + }() + }]); + return ContactsCollection; +}(_DocumentCollection2.default); -// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of -function miniKindOf(val) { - if (val === void 0) return 'undefined'; - if (val === null) return 'null'; - var type = typeof val; +var CONTACTS_DOCTYPE = 'io.cozy.contacts'; +exports.CONTACTS_DOCTYPE = CONTACTS_DOCTYPE; +var _default = ContactsCollection; +exports["default"] = _default; - switch (type) { - case 'boolean': - case 'string': - case 'number': - case 'symbol': - case 'function': - { - return type; - } - } +/***/ }), +/* 692 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - if (Array.isArray(val)) return 'array'; - if (isDate(val)) return 'date'; - if (isError(val)) return 'error'; - var constructorName = ctorName(val); +"use strict"; - switch (constructorName) { - case 'Symbol': - case 'Promise': - case 'WeakMap': - case 'WeakSet': - case 'Map': - case 'Set': - return constructorName; - } // other +var _interopRequireWildcard = __webpack_require__(522); - return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); -} +var _interopRequireDefault = __webpack_require__(524); -function ctorName(val) { - return typeof val.constructor === 'function' ? val.constructor.name : null; -} +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getIconURL = exports["default"] = exports._getIconURL = void 0; -function isError(val) { - return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'; -} +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -function isDate(val) { - if (val instanceof Date) return true; - return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function'; -} +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -function kindOf(val) { - var typeOfVal = typeof val; +var _memoize = _interopRequireWildcard(__webpack_require__(693)); - if (process.env.NODE_ENV !== 'production') { - typeOfVal = miniKindOf(val); - } +function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } - return typeOfVal; -} +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } /** - * Creates a Redux store that holds the state tree. - * The only way to change the data in the store is to call `dispatch()` on it. - * - * There should only be a single store in your app. To specify how different - * parts of the state tree respond to actions, you may combine several reducers - * into a single reducer function by using `combineReducers`. - * - * @param {Function} reducer A function that returns the next state tree, given - * the current state tree and the action to handle. - * - * @param {any} [preloadedState] The initial state. You may optionally specify it - * to hydrate the state from the server in universal apps, or to restore a - * previously serialized user session. - * If you use `combineReducers` to produce the root reducer function, this must be - * an object with the same shape as `combineReducers` keys. - * - * @param {Function} [enhancer] The store enhancer. You may optionally specify it - * to enhance the store with third-party capabilities such as middleware, - * time travel, persistence, etc. The only store enhancer that ships with Redux - * is `applyMiddleware()`. + * Get Icon source Url * - * @returns {Store} A Redux store that lets you read the state, dispatch actions - * and subscribe to changes. + * @param {object} app - Apps data - io.cozy.apps + * @param {string} slug - Slug - string + * @param {string|undefined} domain - Host to use in the origin (e.g. cozy.tools) + * @param {string} protocol - Url protocol (e.g. http / https) + * @returns {string} Source Url of icon + * @private + * @throws {Error} When cannot fetch or get icon source */ +var loadIcon = /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(app, slug, domain, protocol) { + var source; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (domain) { + _context.next = 2; + break; + } -function createStore(reducer, preloadedState, enhancer) { - var _ref2; + throw new Error('Cannot fetch icon: missing domain'); - if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.'); - } + case 2: + source = _getAppIconURL(app, slug, domain, protocol); - if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { - enhancer = preloadedState; - preloadedState = undefined; - } + if (source) { + _context.next = 5; + break; + } - if (typeof enhancer !== 'undefined') { - if (typeof enhancer !== 'function') { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(1) : "Expected the enhancer to be a function. Instead, received: '" + kindOf(enhancer) + "'"); - } + throw new Error("Cannot get icon source for app ".concat(app.name)); - return enhancer(createStore)(reducer, preloadedState); - } + case 5: + return _context.abrupt("return", source); - if (typeof reducer !== 'function') { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(2) : "Expected the root reducer to be a function. Instead, received: '" + kindOf(reducer) + "'"); - } + case 6: + case "end": + return _context.stop(); + } + } + }, _callee); + })); - var currentReducer = reducer; - var currentState = preloadedState; - var currentListeners = []; - var nextListeners = currentListeners; - var isDispatching = false; - /** - * This makes a shallow copy of currentListeners so we can use - * nextListeners as a temporary list while dispatching. - * - * This prevents any bugs around consumers calling - * subscribe/unsubscribe in the middle of a dispatch. - */ + return function loadIcon(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; +}(); +/** + * Get App Icon URL + * + * @param {object} app - Apps data - io.cozy.apps or Slug - string + * @param {string} slug - Slug - string + * @param {string|undefined} domain - Host to use in the origin (e.g. cozy.tools) + * @param {string} protocol - Url protocol (e.g. http / https) + * @private + * @returns {string|null} App Icon URL + */ - function ensureCanMutateNextListeners() { - if (nextListeners === currentListeners) { - nextListeners = currentListeners.slice(); - } - } - /** - * Reads the state tree managed by the store. - * - * @returns {any} The current state tree of your application. - */ +var _getAppIconURL = function _getAppIconURL(app, slug, domain, protocol) { + var path = app && app.links && app.links.icon || _getRegistryIconPath(app, slug); - function getState() { - if (isDispatching) { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(3) : 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.'); - } + return path ? "".concat(protocol, "//").concat(domain).concat(path) : null; +}; +/** + * Get Registry Icon Path + * + * @param {object} app - Apps data - io.cozy.apps or Slug - string + * @param {string} slug - Slug - string + * @returns {string|undefined} Registry icon path + * @private + */ - return currentState; - } - /** - * Adds a change listener. It will be called any time an action is dispatched, - * and some part of the state tree may potentially have changed. You may then - * call `getState()` to read the current state tree inside the callback. - * - * You may call `dispatch()` from a change listener, with the following - * caveats: - * - * 1. The subscriptions are snapshotted just before every `dispatch()` call. - * If you subscribe or unsubscribe while the listeners are being invoked, this - * will not have any effect on the `dispatch()` that is currently in progress. - * However, the next `dispatch()` call, whether nested or not, will use a more - * recent snapshot of the subscription list. - * - * 2. The listener should not expect to see all state changes, as the state - * might have been updated multiple times during a nested `dispatch()` before - * the listener is called. It is, however, guaranteed that all subscribers - * registered before the `dispatch()` started will be called with the latest - * state by the time it exits. - * - * @param {Function} listener A callback to be invoked on every dispatch. - * @returns {Function} A function to remove this change listener. - */ +var _getRegistryIconPath = function _getRegistryIconPath(app, slug) { + if (slug) { + return "/registry/".concat(slug, "/icon"); + } - function subscribe(listener) { - if (typeof listener !== 'function') { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(4) : "Expected the listener to be a function. Instead, received: '" + kindOf(listener) + "'"); - } + return app && app.latest_version && app.latest_version.version && "/registry/".concat(app.slug, "/").concat(app.latest_version.version, "/icon"); +}; - if (isDispatching) { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.'); - } +var mimeTypes = { + gif: 'image/gif', + ico: 'image/vnd.microsoft.icon', + jpeg: 'image/jpeg', + jpg: 'image/jpeg', + png: 'image/png', + svg: 'image/svg+xml' +}; +/** + * Get icon extension + * + * @param {object} app io.cozy.apps or io.cozy.konnectors document + * @param {string} app.icon - App Icon + * @param {string} app.name - App Name + * @returns {string} icon extension + * @private + * @throws {Error} When problem while detecting icon mime type + */ - var isSubscribed = true; - ensureCanMutateNextListeners(); - nextListeners.push(listener); - return function unsubscribe() { - if (!isSubscribed) { - return; - } +var getIconExtensionFromApp = function getIconExtensionFromApp(app) { + if (!app.icon) { + throw new Error("".concat(app.name, ": Cannot detect icon mime type since app has no icon")); + } - if (isDispatching) { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.'); - } + var extension = app.icon.split('.').pop(); - isSubscribed = false; - ensureCanMutateNextListeners(); - var index = nextListeners.indexOf(listener); - nextListeners.splice(index, 1); - currentListeners = null; - }; + if (!extension) { + throw new Error("".concat(app.name, ": Unable to detect icon mime type from extension (").concat(app.icon, ")")); } - /** - * Dispatches an action. It is the only way to trigger a state change. - * - * The `reducer` function, used to create the store, will be called with the - * current state tree and the given `action`. Its return value will - * be considered the **next** state of the tree, and the change listeners - * will be notified. - * - * The base implementation only supports plain object actions. If you want to - * dispatch a Promise, an Observable, a thunk, or something else, you need to - * wrap your store creating function into the corresponding middleware. For - * example, see the documentation for the `redux-thunk` package. Even the - * middleware will eventually dispatch plain object actions using this method. - * - * @param {Object} action A plain object representing “what changedâ€. It is - * a good idea to keep actions serializable so you can record and replay user - * sessions, or use the time travelling `redux-devtools`. An action must have - * a `type` property which may not be `undefined`. It is a good idea to use - * string constants for action types. - * - * @returns {Object} For convenience, the same action object you dispatched. - * - * Note that, if you use a custom middleware, it may wrap `dispatch()` to - * return something else (for example, a Promise you can await). - */ + return extension; +}; - function dispatch(action) { - if (!isPlainObject(action)) { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(7) : "Actions must be plain objects. Instead, the actual type was: '" + kindOf(action) + "'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples."); - } +var fallbacks = /*#__PURE__*/function () { + var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(tries, check) { + var err, _iterator, _step, _try, res; - if (typeof action.type === 'undefined') { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(8) : 'Actions may not have an undefined "type" property. You may have misspelled an action type string constant.'); - } + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _iterator = _createForOfIteratorHelper(tries); + _context2.prev = 1; - if (isDispatching) { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.'); - } + _iterator.s(); - try { - isDispatching = true; - currentState = currentReducer(currentState, action); - } finally { - isDispatching = false; - } + case 3: + if ((_step = _iterator.n()).done) { + _context2.next = 18; + break; + } - var listeners = currentListeners = nextListeners; + _try = _step.value; + _context2.prev = 5; + _context2.next = 8; + return _try(); - for (var i = 0; i < listeners.length; i++) { - var listener = listeners[i]; - listener(); - } + case 8: + res = _context2.sent; + check && check(res); + return _context2.abrupt("return", res); - return action; - } - /** - * Replaces the reducer currently used by the store to calculate the state. - * - * You might need this if your app implements code splitting and you want to - * load some of the reducers dynamically. You might also need this if you - * implement a hot reloading mechanism for Redux. - * - * @param {Function} nextReducer The reducer for the store to use instead. - * @returns {void} - */ + case 13: + _context2.prev = 13; + _context2.t0 = _context2["catch"](5); + err = _context2.t0; + case 16: + _context2.next = 3; + break; - function replaceReducer(nextReducer) { - if (typeof nextReducer !== 'function') { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(10) : "Expected the nextReducer to be a function. Instead, received: '" + kindOf(nextReducer)); - } + case 18: + _context2.next = 23; + break; - currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT. - // Any reducers that existed in both the new and old rootReducer - // will receive the previous state. This effectively populates - // the new state tree with any relevant data from the old one. + case 20: + _context2.prev = 20; + _context2.t1 = _context2["catch"](1); - dispatch({ - type: ActionTypes.REPLACE - }); - } - /** - * Interoperability point for observable/reactive libraries. - * @returns {observable} A minimal observable of state changes. - * For more information, see the observable proposal: - * https://github.com/tc39/proposal-observable - */ + _iterator.e(_context2.t1); + case 23: + _context2.prev = 23; - function observable() { - var _ref; + _iterator.f(); - var outerSubscribe = subscribe; - return _ref = { - /** - * The minimal observable subscription method. - * @param {Object} observer Any object that can be used as an observer. - * The observer object should have a `next` method. - * @returns {subscription} An object with an `unsubscribe` method that can - * be used to unsubscribe the observable from the store, and prevent further - * emission of values from the observable. - */ - subscribe: function subscribe(observer) { - if (typeof observer !== 'object' || observer === null) { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(11) : "Expected the observer to be an object. Instead, received: '" + kindOf(observer) + "'"); - } + return _context2.finish(23); - function observeState() { - if (observer.next) { - observer.next(getState()); - } - } + case 26: + throw err; - observeState(); - var unsubscribe = outerSubscribe(observeState); - return { - unsubscribe: unsubscribe - }; + case 27: + case "end": + return _context2.stop(); + } } - }, _ref[$$observable] = function () { - return this; - }, _ref; - } // When a store is created, an "INIT" action is dispatched so that every - // reducer returns their initial state. This effectively populates - // the initial state tree. - - - dispatch({ - type: ActionTypes.INIT - }); - return _ref2 = { - dispatch: dispatch, - subscribe: subscribe, - getState: getState, - replaceReducer: replaceReducer - }, _ref2[$$observable] = observable, _ref2; -} + }, _callee2, null, [[1, 20, 23, 26], [5, 13]]); + })); + return function fallbacks(_x5, _x6) { + return _ref2.apply(this, arguments); + }; +}(); /** - * Prints a warning in the console if it exists. + * Fetch application/konnector that is installed * - * @param {String} message The warning message. - * @returns {void} + * @private */ -function warning(message) { - /* eslint-disable no-console */ - if (typeof console !== 'undefined' && typeof console.error === 'function') { - console.error(message); - } - /* eslint-enable no-console */ - - - try { - // This error was thrown as a convenience so that if you enable - // "break on all exceptions" in your console, - // it would pause the execution at this line. - throw new Error(message); - } catch (e) {} // eslint-disable-line no-empty -} - -function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) { - var reducerKeys = Object.keys(reducers); - var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer'; - - if (reducerKeys.length === 0) { - return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.'; - } - - if (!isPlainObject(inputState)) { - return "The " + argumentName + " has unexpected type of \"" + kindOf(inputState) + "\". Expected argument to be an object with the following " + ("keys: \"" + reducerKeys.join('", "') + "\""); - } - var unexpectedKeys = Object.keys(inputState).filter(function (key) { - return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key]; - }); - unexpectedKeys.forEach(function (key) { - unexpectedKeyCache[key] = true; +var fetchAppOrKonnector = function fetchAppOrKonnector(stackClient, type, slug) { + return stackClient.fetchJSON('GET', "/".concat(type, "s/").concat(slug)).then(function (x) { + return x.data.attributes; }); - if (action && action.type === ActionTypes.REPLACE) return; - - if (unexpectedKeys.length > 0) { - return "Unexpected " + (unexpectedKeys.length > 1 ? 'keys' : 'key') + " " + ("\"" + unexpectedKeys.join('", "') + "\" found in " + argumentName + ". ") + "Expected to find one of the known reducer keys instead: " + ("\"" + reducerKeys.join('", "') + "\". Unexpected keys will be ignored."); - } -} - -function assertReducerShape(reducers) { - Object.keys(reducers).forEach(function (key) { - var reducer = reducers[key]; - var initialState = reducer(undefined, { - type: ActionTypes.INIT - }); +}; +/** + * Fetch application/konnector from the registry + * + * @private + */ - if (typeof initialState === 'undefined') { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(12) : "The slice reducer for key \"" + key + "\" returned undefined during initialization. " + "If the state passed to the reducer is undefined, you must " + "explicitly return the initial state. The initial state may " + "not be undefined. If you don't want to set a value for this reducer, " + "you can use null instead of undefined."); - } - if (typeof reducer(undefined, { - type: ActionTypes.PROBE_UNKNOWN_ACTION() - }) === 'undefined') { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(13) : "The slice reducer for key \"" + key + "\" returned undefined when probed with a random type. " + ("Don't try to handle '" + ActionTypes.INIT + "' or other actions in \"redux/*\" ") + "namespace. They are considered private. Instead, you must return the " + "current state for any unknown actions, unless it is undefined, " + "in which case you must return the initial state, regardless of the " + "action type. The initial state may not be undefined, but can be null."); - } +var fetchAppOrKonnectorViaRegistry = function fetchAppOrKonnectorViaRegistry(stackClient, type, slug) { + return stackClient.fetchJSON('GET', "/registry/".concat(slug)).then(function (x) { + return x.latest_version.manifest; }); -} +}; /** - * Turns an object whose values are different reducer functions, into a single - * reducer function. It will call every child reducer, and gather their results - * into a single state object, whose keys correspond to the keys of the passed - * reducer functions. - * - * @param {Object} reducers An object whose values correspond to different - * reducer functions that need to be combined into one. One handy way to obtain - * it is to use ES6 `import * as reducers` syntax. The reducers may never return - * undefined for any action. Instead, they should return their initial state - * if the state passed to them was undefined, and the current state for any - * unrecognized action. + * Get Icon URL using blob mechanism if OAuth connected + * or using preloaded url when blob not needed * - * @returns {Function} A reducer function that invokes every reducer inside the - * passed object, and builds a state object with the same shape. + * @param {CozyStackClient} stackClient - CozyStackClient + * @param {object} stackClient.oauthOptions - oauthOptions used to detect fetching mechanism + * @param {object} opts - Options + * @param {string} opts.type - Options type + * @param {string|undefined} opts.slug - Options slug + * @param {object|string|undefined} opts.appData - Apps data - io.cozy.apps + * @param {string} [opts.priority='stack'] - Options priority + * @returns {Promise<string>|string} DOMString containing URL source or a URL representing the Blob . + * @private + * @throws {Error} while fetching icon, or unknown image extension */ -function combineReducers(reducers) { - var reducerKeys = Object.keys(reducers); - var finalReducers = {}; +var _getIconURL = /*#__PURE__*/function () { + var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(stackClient, opts) { + var type, slug, appData, _opts$priority, priority, iconDataFetchers, resp, icon, app, appDataFetchers, ext, _URL, domain, protocol; - for (var i = 0; i < reducerKeys.length; i++) { - var key = reducerKeys[i]; + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + type = opts.type, slug = opts.slug, appData = opts.appData, _opts$priority = opts.priority, priority = _opts$priority === void 0 ? 'stack' : _opts$priority; - if (process.env.NODE_ENV !== 'production') { - if (typeof reducers[key] === 'undefined') { - warning("No reducer provided for key \"" + key + "\""); - } - } + if (!stackClient.oauthOptions) { + _context3.next = 29; + break; + } - if (typeof reducers[key] === 'function') { - finalReducers[key] = reducers[key]; - } - } + iconDataFetchers = [function () { + return stackClient.fetch('GET', "/".concat(type, "s/").concat(slug, "/icon")); + }, function () { + return stackClient.fetch('GET', "/registry/".concat(slug, "/icon")); + }]; - var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same - // keys multiple times. + if (priority === 'registry') { + iconDataFetchers.reverse(); + } - var unexpectedKeyCache; + _context3.next = 6; + return fallbacks(iconDataFetchers, function (resp) { + if (!resp.ok) { + throw new Error("Error while fetching icon ".concat(resp.statusText)); + } + }); - if (process.env.NODE_ENV !== 'production') { - unexpectedKeyCache = {}; - } + case 6: + resp = _context3.sent; + _context3.next = 9; + return resp.blob(); - var shapeAssertionError; + case 9: + icon = _context3.sent; - try { - assertReducerShape(finalReducers); - } catch (e) { - shapeAssertionError = e; - } + if (icon.type) { + _context3.next = 26; + break; + } - return function combination(state, action) { - if (state === void 0) { - state = {}; - } + // iOS10 does not set correctly mime type for images, so we assume + // that an empty mime type could mean that the app is running on iOS10. + // For regular images like jpeg, png or gif it still works well in the + // Safari browser but not for SVG. + // So let's set a mime type manually. We cannot always set it to + // image/svg+xml and must guess the mime type based on the icon attribute + // from app/manifest + // See https://stackoverflow.com/questions/38318411/uiwebview-on-ios-10-beta-not-loading-any-svg-images + appDataFetchers = [function () { + return fetchAppOrKonnector(stackClient, type, slug); + }, function () { + return fetchAppOrKonnectorViaRegistry(stackClient, type, slug); + }]; - if (shapeAssertionError) { - throw shapeAssertionError; - } + if (priority === 'registry') { + appDataFetchers.reverse(); + } - if (process.env.NODE_ENV !== 'production') { - var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache); + _context3.t1 = appData; - if (warningMessage) { - warning(warningMessage); - } - } + if (_context3.t1) { + _context3.next = 18; + break; + } - var hasChanged = false; - var nextState = {}; + _context3.next = 17; + return fallbacks(appDataFetchers); - for (var _i = 0; _i < finalReducerKeys.length; _i++) { - var _key = finalReducerKeys[_i]; - var reducer = finalReducers[_key]; - var previousStateForKey = state[_key]; - var nextStateForKey = reducer(previousStateForKey, action); + case 17: + _context3.t1 = _context3.sent; - if (typeof nextStateForKey === 'undefined') { - var actionType = action && action.type; - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(14) : "When called with an action of type " + (actionType ? "\"" + String(actionType) + "\"" : '(unknown type)') + ", the slice reducer for key \"" + _key + "\" returned undefined. " + "To ignore an action, you must explicitly return the previous state. " + "If you want this reducer to hold no value, you can return null instead of undefined."); - } + case 18: + _context3.t0 = _context3.t1; - nextState[_key] = nextStateForKey; - hasChanged = hasChanged || nextStateForKey !== previousStateForKey; - } + if (_context3.t0) { + _context3.next = 21; + break; + } - hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length; - return hasChanged ? nextState : state; - }; -} + _context3.t0 = {}; -function bindActionCreator(actionCreator, dispatch) { - return function () { - return dispatch(actionCreator.apply(this, arguments)); - }; -} -/** - * Turns an object whose values are action creators, into an object with the - * same keys, but with every function wrapped into a `dispatch` call so they - * may be invoked directly. This is just a convenience method, as you can call - * `store.dispatch(MyActionCreators.doSomething())` yourself just fine. - * - * For convenience, you can also pass an action creator as the first argument, - * and get a dispatch wrapped function in return. - * - * @param {Function|Object} actionCreators An object whose values are action - * creator functions. One handy way to obtain it is to use ES6 `import * as` - * syntax. You may also pass a single function. - * - * @param {Function} dispatch The `dispatch` function available on your Redux - * store. - * - * @returns {Function|Object} The object mimicking the original object, but with - * every action creator wrapped into the `dispatch` call. If you passed a - * function as `actionCreators`, the return value will also be a single - * function. - */ + case 21: + app = _context3.t0; + ext = getIconExtensionFromApp(app); + if (mimeTypes[ext]) { + _context3.next = 25; + break; + } -function bindActionCreators(actionCreators, dispatch) { - if (typeof actionCreators === 'function') { - return bindActionCreator(actionCreators, dispatch); - } + throw new Error("Unknown image extension \"".concat(ext, "\" for app ").concat(app.name)); - if (typeof actionCreators !== 'object' || actionCreators === null) { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(16) : "bindActionCreators expected an object or a function, but instead received: '" + kindOf(actionCreators) + "'. " + "Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?"); - } + case 25: + icon = new Blob([icon], { + type: mimeTypes[ext] + }); - var boundActionCreators = {}; + case 26: + return _context3.abrupt("return", URL.createObjectURL(icon)); - for (var key in actionCreators) { - var actionCreator = actionCreators[key]; + case 29: + _context3.prev = 29; + _URL = new URL(stackClient.uri), domain = _URL.host, protocol = _URL.protocol; + return _context3.abrupt("return", loadIcon(appData, slug, domain, protocol)); - if (typeof actionCreator === 'function') { - boundActionCreators[key] = bindActionCreator(actionCreator, dispatch); - } - } + case 34: + _context3.prev = 34; + _context3.t2 = _context3["catch"](29); + throw new Error("Cannot fetch icon: invalid stackClient.uri: ".concat(_context3.t2.message)); - return boundActionCreators; -} + case 37: + case "end": + return _context3.stop(); + } + } + }, _callee3, null, [[29, 34]]); + })); + return function _getIconURL(_x7, _x8) { + return _ref3.apply(this, arguments); + }; +}(); /** - * Composes single-argument functions from right to left. The rightmost - * function can take multiple arguments as it provides the signature for - * the resulting composite function. + * Get Icon URL using blob mechanism if OAuth connected + * or using preloaded url when blob not needed * - * @param {...Function} funcs The functions to compose. - * @returns {Function} A function obtained by composing the argument functions - * from right to left. For example, compose(f, g, h) is identical to doing - * (...args) => f(g(h(...args))). + * @param {CozyStackClient} stackClient - CozyStackClient + * @param {object} stackClient.oauthOptions - oauthOptions used to detect fetching mechanism + * @param {object} opts - Options + * @param {string} opts.type - Options type + * @param {string|undefined} opts.slug - Options slug + * @param {object|string|undefined} opts.appData - Apps data - io.cozy.apps or Slug - string + * @param {string} [opts.priority='stack'] - Options priority + * @returns {Promise<string>|string} DOMString containing URL source or a URL representing the Blob or ErrorReturned */ -function compose() { - for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) { - funcs[_key] = arguments[_key]; - } - if (funcs.length === 0) { - return function (arg) { - return arg; - }; - } - if (funcs.length === 1) { - return funcs[0]; - } +exports._getIconURL = _getIconURL; - return funcs.reduce(function (a, b) { - return function () { - return a(b.apply(void 0, arguments)); - }; +var getIconURL = function getIconURL() { + return _getIconURL.apply(this, arguments).catch(function () { + return new _memoize.ErrorReturned(); }); -} +}; -/** - * Creates a store enhancer that applies middleware to the dispatch method - * of the Redux store. This is handy for a variety of tasks, such as expressing - * asynchronous actions in a concise manner, or logging every action payload. - * - * See `redux-thunk` package as an example of the Redux middleware. - * - * Because middleware is potentially asynchronous, this should be the first - * store enhancer in the composition chain. - * - * Note that each middleware will be given the `dispatch` and `getState` functions - * as named arguments. - * - * @param {...Function} middlewares The middleware chain to be applied. - * @returns {Function} A store enhancer applying the middleware. - */ +exports.getIconURL = getIconURL; -function applyMiddleware() { - for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) { - middlewares[_key] = arguments[_key]; +var _default = (0, _memoize.default)(getIconURL, { + maxDuration: 300 * 1000, + key: function key(stackClient, opts) { + var type = opts.type, + slug = opts.slug, + priority = opts.priority; + return stackClient.uri + +':' + type + ':' + slug + ':' + priority; } +}); - return function (createStore) { - return function () { - var store = createStore.apply(void 0, arguments); +exports["default"] = _default; - var _dispatch = function dispatch() { - throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.'); - }; +/***/ }), +/* 693 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - var middlewareAPI = { - getState: store.getState, - dispatch: function dispatch() { - return _dispatch.apply(void 0, arguments); - } - }; - var chain = middlewares.map(function (middleware) { - return middleware(middlewareAPI); - }); - _dispatch = compose.apply(void 0, chain)(store.dispatch); - return (0,_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, store), {}, { - dispatch: _dispatch - }); - }; - }; -} +"use strict"; -/* - * This is a dummy function to check if the function name has been altered by minification. - * If the function has been minified and NODE_ENV !== 'production', warn the user. - */ -function isCrushed() {} +var _interopRequireDefault = __webpack_require__(524); -if (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') { - warning('You are currently using minified code outside of NODE_ENV === "production". ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or setting mode to production in webpack (https://webpack.js.org/concepts/mode/) ' + 'to ensure you have the correct code for your production build.'); -} +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ErrorReturned = exports["default"] = void 0; +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -/***/ }), -/* 695 */ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ _objectSpread2) -/* harmony export */ }); -/* harmony import */ var _defineProperty_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(696); +var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664)); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -function ownKeys(object, enumerableOnly) { - var keys = Object.keys(object); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - if (Object.getOwnPropertySymbols) { - var symbols = Object.getOwnPropertySymbols(object); +var ErrorReturned = /*#__PURE__*/function (_String) { + (0, _inherits2.default)(ErrorReturned, _String); - if (enumerableOnly) { - symbols = symbols.filter(function (sym) { - return Object.getOwnPropertyDescriptor(object, sym).enumerable; - }); - } + var _super = _createSuper(ErrorReturned); - keys.push.apply(keys, symbols); + function ErrorReturned() { + (0, _classCallCheck2.default)(this, ErrorReturned); + return _super.apply(this, arguments); } - return keys; -} + return ErrorReturned; +}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(String)); +/** + * Delete outdated results from cache + */ -function _objectSpread2(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i] != null ? arguments[i] : {}; - if (i % 2) { - ownKeys(Object(source), true).forEach(function (key) { - (0,_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__["default"])(target, key, source[key]); - }); - } else if (Object.getOwnPropertyDescriptors) { - Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); - } else { - ownKeys(Object(source)).forEach(function (key) { - Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); - }); - } - } +exports.ErrorReturned = ErrorReturned; - return target; -} +var garbageCollect = function garbageCollect(cache, maxDuration) { + var now = Date.now(); -/***/ }), -/* 696 */ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + for (var _i = 0, _Object$keys = Object.keys(cache); _i < _Object$keys.length; _i++) { + var key = _Object$keys[_i]; + var delta = now - cache[key].date; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ _defineProperty) -/* harmony export */ }); -function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; + if (delta > maxDuration) { + delete cache[key]; + } } +}; - return obj; -} +var isPromise = function isPromise(maybePromise) { + return typeof maybePromise === 'object' && typeof maybePromise.then === 'function'; +}; +/** + * Memoize with maxDuration and custom key + */ -/***/ }), -/* 697 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -function createThunkMiddleware(extraArgument) { - return function (_ref) { - var dispatch = _ref.dispatch, - getState = _ref.getState; - return function (next) { - return function (action) { - if (typeof action === 'function') { - return action(dispatch, getState, extraArgument); - } +var memoize = function memoize(fn, options) { + var cache = {}; + return function () { + var key = options.key.apply(null, arguments); + garbageCollect(cache, options.maxDuration); + var existing = cache[key]; - return next(action); + if (existing) { + return existing.result; + } else { + var result = fn.apply(this, arguments); + cache[key] = { + result: result, + date: Date.now() }; - }; - }; -} + /** + * If the result is a promise and this promise + * failed or resolved with a specific error (aka ErrorReturned), + * let's remove the result from the cache since we don't want to + * memoize error + */ -var thunk = createThunkMiddleware(); -thunk.withExtraArgument = createThunkMiddleware; + if (isPromise(result)) { + result.then(function (v) { + if (v instanceof ErrorReturned) { + delete cache[key]; + } + }).catch(function (e) { + delete cache[key]; + }); + } -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (thunk); + return result; + } + }; +}; + +var _default = memoize; +exports["default"] = _default; /***/ }), -/* 698 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/* 694 */ +/***/ ((__unused_webpack_module, exports) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); - Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.extractAndMergeDocument = exports.getCollectionFromSlice = exports.getDocumentFromSlice = exports["default"] = exports.mergeDocumentsWithRelationships = void 0; - -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); - -var _keyBy = _interopRequireDefault(__webpack_require__(699)); - -var _get = _interopRequireDefault(__webpack_require__(358)); - -var _isEqual = _interopRequireDefault(__webpack_require__(646)); - -var _omit = _interopRequireDefault(__webpack_require__(613)); - -var _logger = _interopRequireDefault(__webpack_require__(703)); - -var _queries = __webpack_require__(723); +exports["default"] = void 0; -var _dsl = __webpack_require__(607); +var logDeprecate = function logDeprecate() { + var _console; -var _mutations = __webpack_require__(738); + if (process.env.NODE_ENV === 'test') { + throw new Error('Deprecation error: ' + (arguments.length <= 0 ? undefined : arguments[0])); + } -var _types = __webpack_require__(610); + (_console = console).warn.apply(_console, arguments); +}; -var _helpers = __webpack_require__(739); +var _default = logDeprecate; +exports["default"] = _default; -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +/***/ }), +/* 695 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +"use strict"; -var storeDocument = function storeDocument(state, document) { - var type = document._type; - if (!type) { - if (process.env.NODE_ENV !== 'production') { - _logger.default.info('Document without _type', document); - } +var _interopRequireDefault = __webpack_require__(524); - throw new Error('Document without _type'); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.shouldXMLHTTPRequestBeUsed = exports.fetchWithXMLHttpRequest = void 0; - if (!(0, _helpers.properId)(document)) { - if (process.env.NODE_ENV !== 'production') { - _logger.default.info('Document without id', document); - } +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - throw new Error('Document without id'); - } +var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532)); - var existingDoc = (0, _get.default)(state, [type, (0, _helpers.properId)(document)]); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - if ((0, _isEqual.default)(existingDoc, document)) { - return state; - } else { - return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, type, _objectSpread(_objectSpread({}, state[type]), {}, (0, _defineProperty2.default)({}, (0, _helpers.properId)(document), mergeDocumentsWithRelationships(existingDoc, document))))); - } +var _memoize = _interopRequireDefault(__webpack_require__(377)); + +var headersFromString = function headersFromString(headerString) { + return new Headers(headerString.split('\r\n').map(function (x) { + return x.split(':', 2); + }).filter(function (x) { + return x.length == 2; + })); }; +/** + * Returns a `fetch()` like response but uses XHR. + * XMLHTTPRequest provides upload progress events unlike fetch. + * + * @private + * @param {string} fullpath - Route path + * @param {object} options - Fetch options + * @param {Function} options.onUploadProgress - Callback to receive upload progress events + */ -var mergeDocumentsWithRelationships = function mergeDocumentsWithRelationships() { - var prevDocument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var nextDocument = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - /** - * @type {CozyClientDocument} - */ - var merged = _objectSpread(_objectSpread({}, prevDocument), nextDocument); +var fetchWithXMLHttpRequest = /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(fullpath, options) { + var response; + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _context3.next = 2; + return new Promise(function (resolve, reject) { + var xhr = new XMLHttpRequest(); - if (prevDocument.relationships || nextDocument.relationships) merged.relationships = _objectSpread(_objectSpread({}, prevDocument.relationships), nextDocument.relationships); - return merged; -}; // reducer + if (options.onUploadProgress && xhr.upload) { + xhr.upload.addEventListener('progress', options.onUploadProgress, false); + } + xhr.onload = function () { + if (this.readyState == 4) { + resolve(this); + } else { + reject(this); + } + }; -exports.mergeDocumentsWithRelationships = mergeDocumentsWithRelationships; + xhr.onerror = function (err) { + reject(err); + }; -var documents = function documents() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var action = arguments.length > 1 ? arguments[1] : undefined; + xhr.open(options.method, fullpath, true); + xhr.withCredentials = true; - if (!(0, _queries.isReceivingData)(action) && !(0, _mutations.isReceivingMutationResult)(action)) { - return state; - } + for (var _i = 0, _Object$entries = Object.entries(options.headers); _i < _Object$entries.length; _i++) { + var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2), + headerName = _Object$entries$_i[0], + headerValue = _Object$entries$_i[1]; - if (action && action.definition && action.definition.mutationType === _dsl.MutationTypes.DELETE_DOCUMENT) { - var docId = action.definition.document._id; - var _type = action.definition.document._type; - return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, _type, (0, _omit.default)(state[_type], docId))); - } + xhr.setRequestHeader(headerName, headerValue); + } - var _action$response = action.response, - data = _action$response.data, - included = _action$response.included; - if (!data || Array.isArray(data) && data.length === 0) return state; - var updatedStateWithIncluded = included ? included.reduce(storeDocument, state) : state; + xhr.send(options.body); + }); - if (!Array.isArray(data)) { - return storeDocument(updatedStateWithIncluded, data); - } + case 2: + response = _context3.sent; + return _context3.abrupt("return", { + headers: headersFromString(response.getAllResponseHeaders()), + ok: response.status >= 200 && response.status < 300, + text: function () { + var _text = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + return _context.abrupt("return", response.responseText); - return extractAndMergeDocument(data, updatedStateWithIncluded); -}; + case 1: + case "end": + return _context.stop(); + } + } + }, _callee); + })); -var _default = documents; // selector + function text() { + return _text.apply(this, arguments); + } -exports["default"] = _default; + return text; + }(), + json: function () { + var _json = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + return _context2.abrupt("return", JSON.parse(response.responseText)); -var getDocumentFromSlice = function getDocumentFromSlice() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var doctype = arguments.length > 1 ? arguments[1] : undefined; - var id = arguments.length > 2 ? arguments[2] : undefined; + case 1: + case "end": + return _context2.stop(); + } + } + }, _callee2); + })); - if (!doctype) { - throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined doctype'); - } + function json() { + return _json.apply(this, arguments); + } - if (!id) { - throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined id'); - } + return json; + }(), + status: response.status, + statusText: response.statusText + }); - if (!state[doctype]) { - if (process.env.NODE_ENV !== 'production') { - _logger.default.info("getDocumentFromSlice: ".concat(doctype, " is absent from the store's documents. State is"), state); - } + case 4: + case "end": + return _context3.stop(); + } + } + }, _callee3); + })); - return null; - } else if (!state[doctype][id]) { - if (process.env.NODE_ENV !== 'production') { - _logger.default.info("getDocumentFromSlice: ".concat(doctype, ":").concat(id, " is absent from the store documents. State is"), state); - } + return function fetchWithXMLHttpRequest(_x, _x2) { + return _ref.apply(this, arguments); + }; +}(); - return null; - } +exports.fetchWithXMLHttpRequest = fetchWithXMLHttpRequest; +var doesXHRSupportLoadAndProgress = (0, _memoize.default)(function () { + var xhr = new XMLHttpRequest(); + return 'onload' in xhr && 'onprogress' in xhr; +}); - return state[doctype][id]; +var shouldXMLHTTPRequestBeUsed = function shouldXMLHTTPRequestBeUsed(method, path, options) { + return Boolean(options.onUploadProgress) && doesXHRSupportLoadAndProgress(); }; -exports.getDocumentFromSlice = getDocumentFromSlice; +exports.shouldXMLHTTPRequestBeUsed = shouldXMLHTTPRequestBeUsed; -var getCollectionFromSlice = function getCollectionFromSlice() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var doctype = arguments.length > 1 ? arguments[1] : undefined; +/***/ }), +/* 696 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - if (!doctype) { - throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined doctype'); - } +"use strict"; - if (!state[doctype]) { - if (process.env.NODE_ENV !== 'production') { - _logger.default.info("getCollectionFromSlice: ".concat(doctype, " is absent from the store documents. State is"), state); - } - return null; - } +var _interopRequireDefault = __webpack_require__(524); - return Object.values(state[doctype]); -}; -/* - This method has been created in order to get a returned object - in `data` with the full set on information coming potentially from - `included` +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - This method should be somewhere else. The `document` shall not be - dealt with included / data and so on. +var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664)); - This method takes `data` and `included` and merge both sources - together. It should be always up-to-date. The returned object - will be as full of information as it can be. -*/ +var _regenerator = _interopRequireDefault(__webpack_require__(539)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -exports.getCollectionFromSlice = getCollectionFromSlice; +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var extractAndMergeDocument = function extractAndMergeDocument(data, updatedStateWithIncluded) { - var doctype = data[0]._type; +var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537)); - if (!doctype) { - _logger.default.info('Document without _type', data[0]); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - throw new Error('Document without _type'); - } +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - var sortedData = (0, _keyBy.default)(data, _helpers.properId); - var mergedData = Object.assign({}, updatedStateWithIncluded); - mergedData[doctype] = Object.assign({}, updatedStateWithIncluded[doctype]); - Object.values(sortedData).map(function (data) { - var id = (0, _helpers.properId)(data); +var _get2 = _interopRequireDefault(__webpack_require__(682)); - if (mergedData[doctype][id]) { - mergedData[doctype][id] = _objectSpread(_objectSpread({}, mergedData[doctype][id]), data); - } else { - mergedData[doctype][id] = data; - } - }); - return mergedData; -}; +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -exports.extractAndMergeDocument = extractAndMergeDocument; +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -/***/ }), -/* 699 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var baseAssignValue = __webpack_require__(534), - createAggregator = __webpack_require__(700); +var _CozyStackClient2 = _interopRequireDefault(__webpack_require__(572)); -/** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the last element responsible for generating the key. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var array = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.keyBy(array, function(o) { - * return String.fromCharCode(o.code); - * }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.keyBy(array, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - */ -var keyBy = createAggregator(function(result, value, key) { - baseAssignValue(result, key, value); -}); +var _AccessToken = _interopRequireDefault(__webpack_require__(669)); -module.exports = keyBy; +var _logDeprecate = _interopRequireDefault(__webpack_require__(694)); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -/***/ }), -/* 700 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var arrayAggregator = __webpack_require__(701), - baseAggregator = __webpack_require__(702), - baseIteratee = __webpack_require__(401), - isArray = __webpack_require__(55); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +var defaultoauthOptions = { + clientID: '', + clientName: '', + clientKind: '', + clientSecret: '', + clientURI: '', + registrationAccessToken: '', + redirectURI: '', + softwareID: '', + softwareVersion: '', + logoURI: '', + policyURI: '', + notificationPlatform: '', + notificationDeviceToken: '' +}; /** - * Creates a function like `_.groupBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} [initializer] The accumulator object initializer. - * @returns {Function} Returns the new aggregator function. + * Specialized `CozyStackClient` for mobile, implementing stack registration + * through OAuth. */ -function createAggregator(setter, initializer) { - return function(collection, iteratee) { - var func = isArray(collection) ? arrayAggregator : baseAggregator, - accumulator = initializer ? initializer() : {}; - return func(collection, setter, baseIteratee(iteratee, 2), accumulator); - }; -} +var OAuthClient = /*#__PURE__*/function (_CozyStackClient) { + (0, _inherits2.default)(OAuthClient, _CozyStackClient); -module.exports = createAggregator; + var _super = _createSuper(OAuthClient); + function OAuthClient(_ref) { + var _this; -/***/ }), -/* 701 */ -/***/ ((module) => { + var oauth = _ref.oauth, + _ref$scope = _ref.scope, + scope = _ref$scope === void 0 ? [] : _ref$scope, + onTokenRefresh = _ref.onTokenRefresh, + options = (0, _objectWithoutProperties2.default)(_ref, ["oauth", "scope", "onTokenRefresh"]); + (0, _classCallCheck2.default)(this, OAuthClient); + _this = _super.call(this, options); -/** - * A specialized version of `baseAggregator` for arrays. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ -function arrayAggregator(array, setter, iteratee, accumulator) { - var index = -1, - length = array == null ? 0 : array.length; + _this.setOAuthOptions(_objectSpread(_objectSpread({}, defaultoauthOptions), oauth)); - while (++index < length) { - var value = array[index]; - setter(accumulator, value, iteratee(value), array); - } - return accumulator; -} + if (oauth.token) { + _this.setToken(oauth.token); + } -module.exports = arrayAggregator; + _this.scope = scope; + _this.onTokenRefresh = onTokenRefresh; + return _this; + } + /** + * Checks if the client has his registration information from the server + * + * @returns {boolean} true if registered, false otherwise + * @private + */ -/***/ }), -/* 702 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + (0, _createClass2.default)(OAuthClient, [{ + key: "isRegistered", + value: function isRegistered() { + return this.oauthOptions.clientID !== ''; + } + /** + * Converts a camel-cased data set to snake case, suitable for sending to the OAuth server + * + * @param {object} data Initial data + * @returns {object} Formatted data + * @private + */ -var baseEach = __webpack_require__(555); + }, { + key: "snakeCaseOAuthData", + value: function snakeCaseOAuthData(data) { + var mappedFields = { + softwareID: 'software_id', + softwareVersion: 'software_version', + clientID: 'client_id', + clientName: 'client_name', + clientKind: 'client_kind', + clientURI: 'client_uri', + logoURI: 'logo_uri', + policyURI: 'policy_uri', + notificationPlatform: 'notification_platform', + notificationDeviceToken: 'notification_device_token', + redirectURI: 'redirect_uris' + }; + var result = {}; + Object.keys(data).forEach(function (fieldName) { + var key = mappedFields[fieldName] || fieldName; + var value = data[fieldName]; + result[key] = value; + }); // special case: turn redirect_uris into an array -/** - * Aggregates elements of `collection` on `accumulator` with keys transformed - * by `iteratee` and values set by `setter`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ -function baseAggregator(collection, setter, iteratee, accumulator) { - baseEach(collection, function(value, key, collection) { - setter(accumulator, value, iteratee(value), collection); - }); - return accumulator; -} + if (result['redirect_uris'] && result['redirect_uris'] instanceof Array === false) result['redirect_uris'] = [result['redirect_uris']]; + return result; + } + /** + * Converts a snake-cased data set to camel case, suitable for internal use + * + * @param {object} data Initial data + * @returns {object} Formatted data + * @private + */ -module.exports = baseAggregator; + }, { + key: "camelCaseOAuthData", + value: function camelCaseOAuthData(data) { + var mappedFields = { + client_id: 'clientID', + client_name: 'clientName', + client_secret: 'clientSecret', + registration_access_token: 'registrationAccessToken', + software_id: 'softwareID', + redirect_uris: 'redirectURI' + }; + var result = {}; + Object.keys(data).forEach(function (fieldName) { + var key = mappedFields[fieldName] || fieldName; + var value = data[fieldName]; + result[key] = value; + }); + return result; + } + /** Performs the HTTP call to register the client to the server */ + }, { + key: "doRegistration", + value: function doRegistration() { + return this.fetchJSON('POST', '/auth/register', this.snakeCaseOAuthData({ + redirectURI: this.oauthOptions.redirectURI, + clientName: this.oauthOptions.clientName, + softwareID: this.oauthOptions.softwareID, + clientKind: this.oauthOptions.clientKind, + clientURI: this.oauthOptions.clientURI, + logoURI: this.oauthOptions.logoURI, + policyURI: this.oauthOptions.policyURI, + softwareVersion: this.oauthOptions.softwareVersion, + notificationPlatform: this.oauthOptions.notificationPlatform, + notificationDeviceToken: this.oauthOptions.notificationDeviceToken + })); + } + /** + * Registers the currenly configured client with the OAuth server and + * sets internal information from the server response + * + * @throws {Error} When the client is already registered + * @returns {Promise} A promise that resolves with a complete list of client information, including client ID and client secret. + */ -/***/ }), -/* 703 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + }, { + key: "register", + value: function () { + var _register = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() { + var mandatoryFields, fields, missingMandatoryFields, data; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!this.isRegistered()) { + _context.next = 2; + break; + } -"use strict"; + throw new Error('Client already registered'); + case 2: + mandatoryFields = ['redirectURI']; + fields = Object.keys(this.oauthOptions); + missingMandatoryFields = mandatoryFields.filter(function (fieldName) { + return fields[fieldName]; + }); -var _interopRequireDefault = __webpack_require__(512); + if (!(missingMandatoryFields.length > 0)) { + _context.next = 7; + break; + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + throw new Error("Can't register client : missing ".concat(missingMandatoryFields, " fields")); -var _minilog = _interopRequireDefault(__webpack_require__(704)); + case 7: + _context.next = 9; + return this.doRegistration(); -var logger = (0, _minilog.default)('cozy-client'); + case 9: + data = _context.sent; + this.setOAuthOptions(_objectSpread(_objectSpread({}, this.oauthOptions), {}, { + client_id: data.client_id, + client_name: data.client_name, + client_secret: data.client_secret, + registration_access_token: data.registration_access_token, + software_id: data.software_id + })); + return _context.abrupt("return", this.oauthOptions); -_minilog.default.suggest.deny('cozy-client', 'info'); + case 12: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); -var _default = logger; -exports["default"] = _default; + function register() { + return _register.apply(this, arguments); + } -/***/ }), -/* 704 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return register; + }() + /** + * Unregisters the currenly configured client with the OAuth server. + * + * @throws {NotRegisteredException} When the client doesn't have it's registration information + * @returns {Promise} + */ -module.exports = __webpack_require__(705); + }, { + key: "unregister", + value: function () { + var _unregister = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { + var clientID; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (this.isRegistered()) { + _context2.next = 2; + break; + } -var consoleLogger = __webpack_require__(708); + throw new NotRegisteredException(); -// if we are running inside Electron then use the web version of console.js -var isElectron = (typeof window !== 'undefined' && window.process && window.process.type === 'renderer'); -if (isElectron) { - consoleLogger = (__webpack_require__(717).minilog); -} + case 2: + clientID = this.oauthOptions.clientID; + this.oauthOptions.clientID = ''; + return _context2.abrupt("return", this.fetchJSON('DELETE', "/auth/register/".concat(clientID), null, { + headers: { + Authorization: this.registrationAccessTokenToAuthHeader() + } + })); -// intercept the pipe method and transparently wrap the stringifier, if the -// destination is a Node core stream + case 5: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); -module.exports.Stringifier = __webpack_require__(721); + function unregister() { + return _unregister.apply(this, arguments); + } -var oldPipe = module.exports.pipe; -module.exports.pipe = function(dest) { - if(dest instanceof __webpack_require__(82)) { - return oldPipe.call(module.exports, new (module.exports.Stringifier)).pipe(dest); - } else { - return oldPipe.call(module.exports, dest); - } -}; + return unregister; + }() + /** + * Fetches the complete set of client information from the server after it has been registered. + * + * @throws {NotRegisteredException} When the client doesn't have it's registration information + * @returns {Promise} + */ -module.exports.defaultBackend = consoleLogger; -module.exports.defaultFormatter = consoleLogger.formatMinilog; + }, { + key: "fetchInformation", + value: function () { + var _fetchInformation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (this.isRegistered()) { + _context3.next = 2; + break; + } -module.exports.backends = { - redis: __webpack_require__(722), - nodeConsole: consoleLogger, - console: consoleLogger -}; + throw new NotRegisteredException(); + case 2: + return _context3.abrupt("return", this.fetchJSON('GET', "/auth/register/".concat(this.oauthOptions.clientID), null, { + headers: { + Authorization: this.registrationAccessTokenToAuthHeader() + } + })); -/***/ }), -/* 705 */ -/***/ ((module, exports, __webpack_require__) => { + case 3: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); -var Transform = __webpack_require__(706), - Filter = __webpack_require__(707); + function fetchInformation() { + return _fetchInformation.apply(this, arguments); + } -var log = new Transform(), - slice = Array.prototype.slice; + return fetchInformation; + }() + /** + * Overwrites the client own information. This method will update both the local information and the remote information on the OAuth server. + * + * @throws {NotRegisteredException} When the client doesn't have it's registration information + * @param {object} information Set of information to update. Note that some fields such as `clientID` can't be updated. + * @param {boolean} resetSecret = false Optionnal, whether to reset the client secret or not + * @returns {Promise} Resolves to a complete, updated list of client information + */ -exports = module.exports = function create(name) { - var o = function() { log.write(name, undefined, slice.call(arguments)); return o; }; - o.debug = function() { log.write(name, 'debug', slice.call(arguments)); return o; }; - o.info = function() { log.write(name, 'info', slice.call(arguments)); return o; }; - o.warn = function() { log.write(name, 'warn', slice.call(arguments)); return o; }; - o.error = function() { log.write(name, 'error', slice.call(arguments)); return o; }; - o.group = function() { log.write(name, 'group', slice.call(arguments)); return o; }; - o.groupEnd = function() { log.write(name, 'groupEnd', slice.call(arguments)); return o; }; - o.log = o.debug; // for interface compliance with Node and browser consoles - o.suggest = exports.suggest; - o.format = log.format; - return o; -}; + }, { + key: "updateInformation", + value: function () { + var _updateInformation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(information) { + var resetSecret, + mandatoryFields, + data, + result, + _args4 = arguments; + return _regenerator.default.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + resetSecret = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : false; -// filled in separately -exports.defaultBackend = exports.defaultFormatter = null; + if (this.isRegistered()) { + _context4.next = 3; + break; + } -exports.pipe = function(dest) { - return log.pipe(dest); -}; + throw new NotRegisteredException(); -exports.end = exports.unpipe = exports.disable = function(from) { - return log.unpipe(from); -}; + case 3: + mandatoryFields = { + clientID: this.oauthOptions.clientID, + clientName: this.oauthOptions.clientName, + redirectURI: this.oauthOptions.redirectURI, + softwareID: this.oauthOptions.softwareID + }; + data = this.snakeCaseOAuthData(_objectSpread(_objectSpread({}, mandatoryFields), information)); + if (resetSecret) data['client_secret'] = this.oauthOptions.clientSecret; + _context4.next = 8; + return this.fetchJSON('PUT', "/auth/register/".concat(this.oauthOptions.clientID), data, { + headers: { + Authorization: this.registrationAccessTokenToAuthHeader() + } + }); -exports.Transform = Transform; -exports.Filter = Filter; -// this is the default filter that's applied when .enable() is called normally -// you can bypass it completely and set up your own pipes -exports.suggest = new Filter(); + case 8: + result = _context4.sent; + this.setOAuthOptions(_objectSpread(_objectSpread({}, data), result)); + return _context4.abrupt("return", this.oauthOptions); -exports.enable = function() { - if(exports.defaultFormatter) { - return log.pipe(exports.suggest) // filter - .pipe(exports.defaultFormatter) // formatter - .pipe(exports.defaultBackend); // backend - } - return log.pipe(exports.suggest) // filter - .pipe(exports.defaultBackend); // formatter -}; + case 11: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); + function updateInformation(_x) { + return _updateInformation.apply(this, arguments); + } + return updateInformation; + }() + /** + * Generates a random state code to be used during the OAuth process + * + * @returns {string} + */ -/***/ }), -/* 706 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + }, { + key: "generateStateCode", + value: function generateStateCode() { + var STATE_SIZE = 16; + var hasCrypto = typeof window !== 'undefined' && typeof window.crypto !== 'undefined' && typeof window.crypto.getRandomValues === 'function'; + var buffer; -var microee = __webpack_require__(558); + if (hasCrypto) { + buffer = new Uint8Array(STATE_SIZE); + window.crypto.getRandomValues(buffer); + } else { + buffer = new Array(STATE_SIZE); -// Implements a subset of Node's stream.Transform - in a cross-platform manner. -function Transform() {} + for (var i = 0; i < buffer.length; i++) { + buffer[i] = Math.floor(Math.random() * 255); + } + } -microee.mixin(Transform); + return btoa(String.fromCharCode.apply(null, buffer)).replace(/=+$/, '').replace(/\//g, '_').replace(/\+/g, '-'); + } + /** + * Generates the URL that the user should be sent to in order to accept the app's permissions. + * + * @throws {NotRegisteredException} When the client doesn't have it's registration information + * @param {object} options - URL generation options + * @param {string} options.stateCode - A random code to be included in the URl for security. Can be generated with `client.generateStateCode()` + * @param {Array} [options.scopes] - An array of permission scopes for the token. + * @param {SessionCode} [options.sessionCode] - A session code that can be used to create a session. + * @param {string} [options.codeChallenge] - A code challenge that can be used in a PKCE verification process. + * @returns {string} The URL + */ -// The write() signature is different from Node's -// --> makes it much easier to work with objects in logs. -// One of the lessons from v1 was that it's better to target -// a good browser rather than the lowest common denominator -// internally. -// If you want to use external streams, pipe() to ./stringify.js first. -Transform.prototype.write = function(name, level, args) { - this.emit('item', name, level, args); -}; + }, { + key: "getAuthCodeURL", + value: function getAuthCodeURL(_ref2) { + var stateCode = _ref2.stateCode, + _ref2$scopes = _ref2.scopes, + scopes = _ref2$scopes === void 0 ? this.scope : _ref2$scopes, + _ref2$sessionCode = _ref2.sessionCode, + sessionCode = _ref2$sessionCode === void 0 ? undefined : _ref2$sessionCode, + _ref2$codeChallenge = _ref2.codeChallenge, + codeChallenge = _ref2$codeChallenge === void 0 ? undefined : _ref2$codeChallenge; + if (!this.isRegistered()) throw new NotRegisteredException(); + var query = { + client_id: this.oauthOptions.clientID, + redirect_uri: this.oauthOptions.redirectURI, + state: stateCode, + response_type: 'code', + scope: scopes.join(' ') + }; -Transform.prototype.end = function() { - this.emit('end'); - this.removeAllListeners(); -}; + if (this.oauthOptions.registerToken) { + query = _objectSpread(_objectSpread({}, query), {}, { + registerToken: this.oauthOptions.registerToken + }); + } -Transform.prototype.pipe = function(dest) { - var s = this; - // prevent double piping - s.emit('unpipe', dest); - // tell the dest that it's being piped to - dest.emit('pipe', s); + if (sessionCode) { + query = _objectSpread(_objectSpread({}, query), {}, { + session_code: sessionCode + }); + } - function onItem() { - dest.write.apply(dest, Array.prototype.slice.call(arguments)); - } - function onEnd() { !dest._isStdio && dest.end(); } + if (codeChallenge) { + query = _objectSpread(_objectSpread({}, query), {}, { + code_challenge: codeChallenge, + code_challenge_method: 'S256' + }); + } - s.on('item', onItem); - s.on('end', onEnd); + return "".concat(this.uri, "/auth/authorize?").concat(this.dataToQueryString(query)); + } + }, { + key: "dataToQueryString", + value: function dataToQueryString(data) { + return Object.keys(data).map(function (param) { + return "".concat(param, "=").concat(encodeURIComponent(data[param])); + }).join('&'); + } + /** + * Retrieves the access code contained in the URL to which the user is redirected after accepting the app's permissions (the `redirectURI`). + * + * @throws {Error} The URL should contain the same state code as the one generated with `client.getAuthCodeURL()`. If not, it will throw an error + * @param {string} pageURL The redirected page URL, containing the state code and the access code + * @param {string} stateCode The state code that was contained in the original URL the user was sent to (see `client.getAuthCodeURL()`) + * @returns {string} The access code + */ - s.when('unpipe', function(from) { - var match = (from === dest) || typeof from == 'undefined'; - if(match) { - s.removeListener('item', onItem); - s.removeListener('end', onEnd); - dest.emit('unpipe'); + }, { + key: "getAccessCodeFromURL", + value: function getAccessCodeFromURL(pageURL, stateCode) { + if (!stateCode) throw new Error('Missing state code'); + var params = new URL(pageURL).searchParams; + var urlStateCode = params.get('state'); + var urlAccessCode = params.get('access_code'); + if (stateCode !== urlStateCode) throw new Error('Given state does not match url query state'); + return urlAccessCode; } - return match; - }); + /** + * Exchanges an access code for an access token. This function does **not** update the client's token. + * + * @throws {NotRegisteredException} When the client doesn't have it's registration information + * @param {string} accessCode - The access code contained in the redirection URL — see `client.getAccessCodeFromURL()` + * @param {object} oauthOptionsArg — To use when OAuthClient is not yet registered (during login process) + * @param {string} uri — To use when OAuthClient is not yet registered (during login process) + * @param {string} codeVerifier — The PKCE code verifier (see https://docs.cozy.io/en/cozy-stack/auth/#pkce-extension) + * @returns {Promise} A promise that resolves with an AccessToken object. + */ - return dest; -}; + }, { + key: "fetchAccessToken", + value: function () { + var _fetchAccessToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(accessCode, oauthOptionsArg, uri, codeVerifier) { + var oauthOptions, data, result; + return _regenerator.default.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + if (!(!this.isRegistered() && !oauthOptionsArg)) { + _context5.next = 2; + break; + } -Transform.prototype.unpipe = function(from) { - this.emit('unpipe', from); - return this; -}; + throw new NotRegisteredException(); -Transform.prototype.format = function(dest) { - throw new Error([ - 'Warning: .format() is deprecated in Minilog v2! Use .pipe() instead. For example:', - 'var Minilog = require(\'minilog\');', - 'Minilog', - ' .pipe(Minilog.backends.console.formatClean)', - ' .pipe(Minilog.backends.console);'].join('\n')); -}; + case 2: + oauthOptions = oauthOptionsArg || this.oauthOptions; + data = { + grant_type: 'authorization_code', + code: accessCode, + client_id: oauthOptions.clientID, + client_secret: oauthOptions.clientSecret + }; -Transform.mixin = function(dest) { - var o = Transform.prototype, k; - for (k in o) { - o.hasOwnProperty(k) && (dest.prototype[k] = o[k]); - } -}; + if (codeVerifier) { + data = _objectSpread(_objectSpread({}, data), {}, { + code_verifier: codeVerifier + }); + } -module.exports = Transform; + _context5.next = 7; + return this.fetchJSON('POST', (uri || '') + '/auth/access_token', this.dataToQueryString(data), { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + } + }); + case 7: + result = _context5.sent; + return _context5.abrupt("return", new _AccessToken.default(result)); -/***/ }), -/* 707 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 9: + case "end": + return _context5.stop(); + } + } + }, _callee5, this); + })); -// default filter -var Transform = __webpack_require__(706); + function fetchAccessToken(_x2, _x3, _x4, _x5) { + return _fetchAccessToken.apply(this, arguments); + } -var levelMap = { debug: 1, info: 2, warn: 3, error: 4 }; + return fetchAccessToken; + }() + /** + * @typedef SessionCodeRes + * @property {string} session_code The value of the session code + */ -function Filter() { - this.enabled = true; - this.defaultResult = true; - this.clear(); -} + /** + * Fetches a new session code. Only usable by the Flagship application + * + * @throws {NotRegisteredException} When the client isn't certified to be the Flagship application + * @returns {Promise<SessionCodeRes>} A promise that resolves with a new session_code + */ -Transform.mixin(Filter); + }, { + key: "fetchSessionCode", + value: function () { + var _fetchSessionCode = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() { + return _regenerator.default.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + return _context6.abrupt("return", this.fetchJSON('POST', '/auth/session_code')); -// allow all matching, with level >= given level -Filter.prototype.allow = function(name, level) { - this._white.push({ n: name, l: levelMap[level] }); - return this; -}; + case 1: + case "end": + return _context6.stop(); + } + } + }, _callee6, this); + })); -// deny all matching, with level <= given level -Filter.prototype.deny = function(name, level) { - this._black.push({ n: name, l: levelMap[level] }); - return this; -}; + function fetchSessionCode() { + return _fetchSessionCode.apply(this, arguments); + } + + return fetchSessionCode; + }() + /** + * Fetches a new session code. Only usable by the Flagship application + * + * @throws {NotRegisteredException} When the client isn't certified to be the Flagship application + * @returns {Promise<SessionCodeRes>} A promise that resolves with a new session_code + */ + + }, { + key: "fetchSessionCodeWithPassword", + value: function () { + var _fetchSessionCodeWithPassword = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(_ref3) { + var passwordHash, _ref3$twoFactorToken, twoFactorToken, _ref3$twoFactorPassco, twoFactorPasscode; + + return _regenerator.default.wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + passwordHash = _ref3.passwordHash, _ref3$twoFactorToken = _ref3.twoFactorToken, twoFactorToken = _ref3$twoFactorToken === void 0 ? undefined : _ref3$twoFactorToken, _ref3$twoFactorPassco = _ref3.twoFactorPasscode, twoFactorPasscode = _ref3$twoFactorPassco === void 0 ? undefined : _ref3$twoFactorPassco; + return _context7.abrupt("return", this.fetchJSON('POST', '/auth/session_code', { + passphrase: passwordHash, + two_factor_token: twoFactorToken, + two_factor_passcode: twoFactorPasscode + })); -Filter.prototype.clear = function() { - this._white = []; - this._black = []; - return this; -}; + case 2: + case "end": + return _context7.stop(); + } + } + }, _callee7, this); + })); -function test(rule, name) { - // use .test for RegExps - return (rule.n.test ? rule.n.test(name) : rule.n == name); -}; + function fetchSessionCodeWithPassword(_x6) { + return _fetchSessionCodeWithPassword.apply(this, arguments); + } -Filter.prototype.test = function(name, level) { - var i, len = Math.max(this._white.length, this._black.length); - for(i = 0; i < len; i++) { - if(this._white[i] && test(this._white[i], name) && levelMap[level] >= this._white[i].l) { - return true; - } - if(this._black[i] && test(this._black[i], name) && levelMap[level] <= this._black[i].l) { - return false; - } - } - return this.defaultResult; -}; + return fetchSessionCodeWithPassword; + }() + /** + * @typedef AccessTokenRes + * @property {string} access_token The OAuth access token + * @property {string} refresh_token The OAuth refresh token + * @property {string} token_type The OAuth token type + * @property {string} scope The OAuth scope + */ -Filter.prototype.write = function(name, level, args) { - if(!this.enabled || this.test(name, level)) { - return this.emit('item', name, level, args); - } -}; + /** + * @typedef TwoFactorNeededRes + * @property {string} two_factor_token The 2FA token + */ -module.exports = Filter; + /** + * Get OAuth access and register tokens without having to make OAuth dance + * + * This endpoint returns registration tokens only from a Flagship app, + * otherwise it returns a session_code that should be used in an OAuth dance + * + * More info: https://docs.cozy.io/en/cozy-stack/flagship/ + * More info: https://docs.cozy.io/en/cozy-stack/auth/#post-authloginflagship + * + * @returns {Promise<AccessTokenRes|TwoFactorNeededRes|SessionCodeRes>} A promise that resolves with an access token, a session_code or a 2FA code + */ + }, { + key: "loginFlagship", + value: function () { + var _loginFlagship = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(_ref4) { + var passwordHash, _ref4$twoFactorToken, twoFactorToken, _ref4$twoFactorPassco, twoFactorPasscode; -/***/ }), -/* 708 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return _regenerator.default.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + passwordHash = _ref4.passwordHash, _ref4$twoFactorToken = _ref4.twoFactorToken, twoFactorToken = _ref4$twoFactorToken === void 0 ? undefined : _ref4$twoFactorToken, _ref4$twoFactorPassco = _ref4.twoFactorPasscode, twoFactorPasscode = _ref4$twoFactorPassco === void 0 ? undefined : _ref4$twoFactorPassco; + return _context8.abrupt("return", this.fetchJSON('POST', '/auth/login/flagship', { + client_id: this.oauthOptions.clientID, + client_secret: this.oauthOptions.clientSecret, + passphrase: passwordHash, + two_factor_token: twoFactorToken, + two_factor_passcode: twoFactorPasscode + })); -var Transform = __webpack_require__(706); + case 2: + case "end": + return _context8.stop(); + } + } + }, _callee8, this); + })); -function ConsoleBackend() { } + function loginFlagship(_x7) { + return _loginFlagship.apply(this, arguments); + } -Transform.mixin(ConsoleBackend); + return loginFlagship; + }() + /** + * Retrieves a new access token by refreshing the currently used token. + * + * @throws {NotRegisteredException} When the client doesn't have it's registration information + * @throws {Error} The client should already have an access token to use this function + * @returns {Promise} A promise that resolves with a new AccessToken object + */ -ConsoleBackend.prototype.write = function() { - console.log.apply(console, arguments); -}; + }, { + key: "refreshToken", + value: function () { + var _refreshToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9() { + var data, result, newToken; + return _regenerator.default.wrap(function _callee9$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + if (this.isRegistered()) { + _context9.next = 2; + break; + } -var e = new ConsoleBackend(); + throw new NotRegisteredException(); -var levelMap = (__webpack_require__(709).levelMap); + case 2: + if (this.token) { + _context9.next = 4; + break; + } -e.filterEnv = function() { - console.error('Minilog.backends.console.filterEnv is deprecated in Minilog v2.'); - // return the instance of Minilog - return __webpack_require__(705); -}; + throw new Error('No token to refresh'); -e.formatters = [ - 'formatClean', 'formatColor', 'formatNpm', - 'formatLearnboost', 'formatMinilog', 'formatWithStack', 'formatTime' -]; + case 4: + data = { + grant_type: 'refresh_token', + refresh_token: this.token.refreshToken, + client_id: this.oauthOptions.clientID, + client_secret: this.oauthOptions.clientSecret + }; + _context9.next = 7; + return (0, _get2.default)((0, _getPrototypeOf2.default)(OAuthClient.prototype), "fetchJSON", this).call(this, 'POST', '/auth/access_token', this.dataToQueryString(data), { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + } + }); -e.formatClean = new (__webpack_require__(710)); -e.formatColor = new (__webpack_require__(711)); -e.formatNpm = new (__webpack_require__(712)); -e.formatLearnboost = new (__webpack_require__(713)); -e.formatMinilog = new (__webpack_require__(714)); -e.formatWithStack = new (__webpack_require__(715)); -e.formatTime = new (__webpack_require__(716)); + case 7: + result = _context9.sent; + newToken = new _AccessToken.default(_objectSpread({ + refresh_token: this.token.refreshToken + }, result)); -module.exports = e; + if (this.onTokenRefresh && typeof this.onTokenRefresh === 'function') { + this.onTokenRefresh(newToken); + } + return _context9.abrupt("return", newToken); -/***/ }), -/* 709 */ -/***/ ((__unused_webpack_module, exports) => { + case 11: + case "end": + return _context9.stop(); + } + } + }, _callee9, this); + })); -var styles = { - //styles - bold: ["\x1B[1m", "\x1B[22m"], - italic: ["\x1B[3m", "\x1B[23m"], - underline: ["\x1B[4m", "\x1B[24m"], - inverse: ["\x1B[7m", "\x1B[27m"], - //grayscale - white: ["\x1B[37m", "\x1B[39m"], - grey: ["\x1B[90m", "\x1B[39m"], - black: ["\x1B[30m", "\x1B[39m"], - //colors - blue: ["\x1B[34m", "\x1B[39m"], - cyan: ["\x1B[36m", "\x1B[39m"], - green: ["\x1B[32m", "\x1B[39m"], - magenta: ["\x1B[35m", "\x1B[39m"], - red: ["\x1B[31m", "\x1B[39m"], - yellow: ["\x1B[33m", "\x1B[39m"] -}; + function refreshToken() { + return _refreshToken.apply(this, arguments); + } -exports.levelMap = { debug: 1, info: 2, warn: 3, error: 4 }; + return refreshToken; + }() + }, { + key: "exchangeOAuthSecret", + value: function exchangeOAuthSecret(uri, secret) { + return this.fetchJSON('POST', uri + '/auth/secret_exchange', { + secret: secret + }); + } + /** + * Updates the client's stored token + * + * @param {string} token = null The new token to use — can be a string, a json object or an AccessToken instance. + */ -exports.style = function(str, style) { - return styles[style][0] + str + styles[style][1]; -}; + }, { + key: "setToken", + value: function setToken(token) { + if (token) { + this.token = token instanceof _AccessToken.default ? token : new _AccessToken.default(token); + } else { + this.token = null; + } + } + }, { + key: "setCredentials", + value: function setCredentials(token) { + (0, _logDeprecate.default)('setCredentials is deprecated, please replace by setToken'); + return this.setToken(token); + } + /** + * Updates the OAuth informations + * + * @param {object} options Map of OAuth options + */ + }, { + key: "setOAuthOptions", + value: function setOAuthOptions(options) { + this.oauthOptions = this.camelCaseOAuthData(options); + } + }, { + key: "resetClientId", + value: function resetClientId() { + this.oauthOptions.clientID = ''; + } + /** + * Reset the current OAuth client + */ -/***/ }), -/* 710 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + }, { + key: "resetClient", + value: function resetClient() { + this.resetClientId(); + this.setUri(null); + this.setToken(null); + } + /** + * Turns the client's registration access token into a header suitable for HTTP requests. Used in some queries to manipulate the client on the server side. + * + * @returns {string} + * @private + */ -var Transform = __webpack_require__(706); + }, { + key: "registrationAccessTokenToAuthHeader", + value: function registrationAccessTokenToAuthHeader() { + if (!this.oauthOptions.registrationAccessToken) { + throw new Error('No registration access token'); + } -function FormatClean() {} + return 'Bearer ' + this.oauthOptions.registrationAccessToken; + } + /** + * This method should be used in flagship app onboarding process to finalize the + * cozy creation by setting the user password into the cozy-stack + * + * More info: https://docs.cozy.io/en/cozy-stack/settings/#post-settingspassphraseflagship + * + * @param {object} params + * @param {string} params.registerToken - registration token provided by the onboarding link + * @param {string} params.passwordHash - hash of the master password + * @param {string} params.hint - hint for the master password + * @param {string} params.key - key (crypted) used for the vault encryption + * @param {string} params.publicKey - public key used for sharing ciphers from the vault + * @param {string} params.privateKey - private key (crypted) used for sharing ciphers from the vault + * @param {string} params.iterations - number of KDF iterations applied when hashing the master password + * @returns {object} token - The OAauth token + */ -Transform.mixin(FormatClean); + }, { + key: "setPassphraseFlagship", + value: function setPassphraseFlagship(_ref5) { + var registerToken = _ref5.registerToken, + passwordHash = _ref5.passwordHash, + hint = _ref5.hint, + key = _ref5.key, + publicKey = _ref5.publicKey, + privateKey = _ref5.privateKey, + iterations = _ref5.iterations; + return this.fetchJSON('POST', '/settings/passphrase/flagship', { + register_token: registerToken, + passphrase: passwordHash, + hint: hint, + key: key, + public_key: publicKey, + private_key: privateKey, + iterations: iterations, + client_id: this.oauthOptions.clientID, + client_secret: this.oauthOptions.clientSecret + }, { + // TODO: faut il mettre le header? + headers: { + Authorization: this.registrationAccessTokenToAuthHeader() + } + }); + } + }]); + return OAuthClient; +}(_CozyStackClient2.default); -FormatClean.prototype.write = function(name, level, args) { - function pad(s) { return (s.toString().length == 1? '0'+s : s); } - this.emit('item', (name ? name + ' ' : '') + (level ? level + ' ' : '') + args.join(' ')); -}; +var NotRegisteredException = /*#__PURE__*/function (_Error) { + (0, _inherits2.default)(NotRegisteredException, _Error); -module.exports = FormatClean; + var _super2 = _createSuper(NotRegisteredException); + function NotRegisteredException() { + var _this2; -/***/ }), -/* 711 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Client not registered or missing OAuth information'; + (0, _classCallCheck2.default)(this, NotRegisteredException); + _this2 = _super2.call(this, message); + _this2.message = message; + _this2.name = 'NotRegisteredException'; + return _this2; + } -var Transform = __webpack_require__(706), - style = (__webpack_require__(709).style); + return NotRegisteredException; +}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); -function FormatColor() {} +var _default = OAuthClient; +exports["default"] = _default; -Transform.mixin(FormatColor); +/***/ }), +/* 697 */ +/***/ ((__unused_webpack_module, exports) => { -FormatColor.prototype.write = function(name, level, args) { - var colors = { debug: 'magenta', info: 'cyan', warn: 'yellow', error: 'red' }; - function pad(s) { return (s.toString().length == 4? ' '+s : s); } - this.emit('item', (name ? name + ' ' : '') - + (level ? style('- ' + pad(level.toUpperCase()) + ' -', colors[level]) + ' ' : '') - + args.join(' ')); -}; +"use strict"; -module.exports = FormatColor; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.DOCTYPE_PERMISSIONS = exports.DOCTYPE_FILES = exports.REGISTRATION_ABORT = void 0; +var REGISTRATION_ABORT = 'REGISTRATION_ABORT'; +exports.REGISTRATION_ABORT = REGISTRATION_ABORT; +var DOCTYPE_FILES = 'io.cozy.files'; +exports.DOCTYPE_FILES = DOCTYPE_FILES; +var DOCTYPE_PERMISSIONS = 'io.cozy.permissions'; +exports.DOCTYPE_PERMISSIONS = DOCTYPE_PERMISSIONS; /***/ }), -/* 712 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 698 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -var Transform = __webpack_require__(706); +"use strict"; -function FormatNpm() {} -Transform.mixin(FormatNpm); +var _interopRequireDefault = __webpack_require__(524); -FormatNpm.prototype.write = function(name, level, args) { - var out = { - debug: "\x1B[34;40m" + "debug" + "\x1B[39m ", - info: "\x1B[32m" + "info" + "\x1B[39m ", - warn: "\x1B[30;41m" + "WARN" + "\x1B[0m ", - error: "\x1B[31;40m" + "ERR!" + "\x1B[0m " - }; - this.emit( - "item", - (name ? "\x1B[37;40m" + name + "\x1B[0m " : "") + - (level && out[level] ? out[level] : "") + - args.join(" ") - ); -}; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.transformBulkDocsResponse = void 0; -module.exports = FormatNpm; +var _regenerator = _interopRequireDefault(__webpack_require__(539)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -/***/ }), -/* 713 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537)); -var Transform = __webpack_require__(706), - style = (__webpack_require__(709).style); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -function FormatLearnboost() {} +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -Transform.mixin(FormatLearnboost); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -FormatLearnboost.prototype.write = function(name, level, args) { - var colors = { debug: 'grey', info: 'cyan', warn: 'yellow', error: 'red' }; - this.emit('item', (name ? style(name +' ', 'grey') : '') - + (level ? style(level, colors[level]) + ' ' : '') - + args.join(' ')); -}; +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -module.exports = FormatLearnboost; +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -/***/ }), -/* 714 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _dsl = __webpack_require__(619); -var Transform = __webpack_require__(706), - style = (__webpack_require__(709).style), - util = __webpack_require__(64); +var _CozyLink2 = _interopRequireDefault(__webpack_require__(699)); -function FormatMinilog() {} +var _types = __webpack_require__(622); -Transform.mixin(FormatMinilog); +var _const = __webpack_require__(697); -FormatMinilog.prototype.write = function(name, level, args) { - var colors = { debug: 'blue', info: 'cyan', warn: 'yellow', error: 'red' }; - this.emit('item', (name ? style(name +' ', 'grey') : '') - + (level ? style(level, colors[level]) + ' ' : '') - + args.map(function(item) { - return (typeof item == 'string' ? item : util.inspect(item, null, 3, true)); - }).join(' ')); -}; +var _errors = __webpack_require__(700); -module.exports = FormatMinilog; +var _zipWith = _interopRequireDefault(__webpack_require__(701)); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -/***/ }), -/* 715 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -var Transform = __webpack_require__(706), - style = (__webpack_require__(709).style); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -function FormatNpm() {} +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -Transform.mixin(FormatNpm); +/** + * Returns full documents after a bulk update + * + * @private + * + * @param {CouchDBBulkResult[]} bulkResponse - Response from bulk docs + * @param {CozyClientDocument[]} originalDocuments - Documents that were updated + * @returns {{ data: CozyClientDocument[] }} - Full documents with updated _id and _rev + */ +var transformBulkDocsResponse = function transformBulkDocsResponse(bulkResponse, originalDocuments) { + var updatedDocs = (0, _zipWith.default)(bulkResponse, originalDocuments, function (result, od) { + return result.ok ? _objectSpread(_objectSpread({}, od), {}, { + _id: result.id, + _rev: result.rev + }) : od; + }); -function noop(a){ - return a; -} + if (bulkResponse.find(function (x) { + return !x.ok; + })) { + throw new _errors.BulkEditError(bulkResponse, updatedDocs); + } -var types = { - string: noop, - number: noop, - default: JSON.stringify.bind(JSON) + return { + data: updatedDocs + }; }; +/** + * Transfers queries and mutations to a remote stack + */ -function stringify(args) { - return args.map(function(arg) { - return (types[typeof arg] || types.default)(arg); - }); -} -FormatNpm.prototype.write = function(name, level, args) { - var colors = { debug: 'magenta', info: 'cyan', warn: 'yellow', error: 'red' }; - function pad(s) { return (s.toString().length == 4? ' '+s : s); } - function getStack() { - var orig = Error.prepareStackTrace; - Error.prepareStackTrace = function (err, stack) { - return stack; - }; - var err = new Error; - Error.captureStackTrace(err, arguments.callee); - var stack = err.stack; - Error.prepareStackTrace = orig; - return stack; - } +exports.transformBulkDocsResponse = transformBulkDocsResponse; - var frame = getStack()[5], - fileName = FormatNpm.fullPath ? frame.getFileName() : frame.getFileName().replace(/^.*\/(.+)$/, '/$1'); +var StackLink = /*#__PURE__*/function (_CozyLink) { + (0, _inherits2.default)(StackLink, _CozyLink); - this.emit('item', (name ? name + ' ' : '') - + (level ? style(pad(level), colors[level]) + ' ' : '') - + style(fileName + ":" + frame.getLineNumber(), 'grey') - + ' ' - + stringify(args).join(' ')); -}; + var _super = _createSuper(StackLink); -FormatNpm.fullPath = true; + /** + * @param {object} [options] - Options + * @param {object} [options.stackClient] - A StackClient + * @param {object} [options.client] - A StackClient (deprecated) + */ + function StackLink() { + var _this; -module.exports = FormatNpm; + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + client = _ref.client, + stackClient = _ref.stackClient; + (0, _classCallCheck2.default)(this, StackLink); + _this = _super.call(this); + if (client) { + console.warn('Using options.client is deprecated, prefer options.stackClient'); + } -/***/ }), -/* 716 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + _this.stackClient = stackClient || client; + return _this; + } -var Transform = __webpack_require__(706), - style = (__webpack_require__(709).style), - util = __webpack_require__(64); + (0, _createClass2.default)(StackLink, [{ + key: "registerClient", + value: function registerClient(client) { + this.stackClient = client.stackClient || client.client; + } + }, { + key: "reset", + value: function reset() { + this.stackClient = null; + } + }, { + key: "request", + value: function request(operation, result, forward) { + if (operation.mutationType) { + return this.executeMutation(operation, result, forward); + } -function FormatTime() {} + return this.executeQuery(operation); + } + }, { + key: "executeQuery", + value: function executeQuery(query) { + var doctype = query.doctype, + selector = query.selector, + id = query.id, + ids = query.ids, + referenced = query.referenced, + options = (0, _objectWithoutProperties2.default)(query, ["doctype", "selector", "id", "ids", "referenced"]); -function timestamp() { - var d = new Date(); - return ('0' + d.getDate()).slice(-2) + '-' + - ('0' + (d.getMonth() + 1)).slice(-2) + '-' + - d.getFullYear() + ' ' + - ('0' + d.getHours()).slice(-2) + ':' + - ('0' + d.getMinutes()).slice(-2) + ':' + - ('0' + d.getSeconds()).slice(-2) + '.' + - ('00' + d.getMilliseconds()).slice(-3); -} + if (!doctype) { + console.warn('Bad query', query); + throw new Error('No doctype found in a query definition'); + } -Transform.mixin(FormatTime); + var collection = this.stackClient.collection(doctype); -FormatTime.prototype.write = function(name, level, args) { - var colors = { debug: 'blue', info: 'cyan', warn: 'yellow', error: 'red' }; - this.emit('item', style(timestamp() +' ', 'grey') - + (name ? style(name +' ', 'grey') : '') - + (level ? style(level, colors[level]) + ' ' : '') - + args.map(function(item) { - return (typeof item == 'string' ? item : util.inspect(item, null, 3, true)); - }).join(' ')); -}; + if (id) { + return collection.get(id, query); + } -module.exports = FormatTime; + if (ids) { + return collection.getAll(ids); + } + if (referenced) { + return collection.findReferencedBy(referenced, options); + } -/***/ }), -/* 717 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return !selector && !options.sort ? collection.all(options) : collection.find(selector, options); + } + }, { + key: "executeMutation", + value: function () { + var _executeMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(mutation, result, forward) { + var mutationType, doc, docs, props, updateAllResp; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + mutationType = mutation.mutationType, doc = mutation.document, docs = mutation.documents, props = (0, _objectWithoutProperties2.default)(mutation, ["mutationType", "document", "documents"]); + _context.t0 = mutationType; + _context.next = _context.t0 === _dsl.MutationTypes.CREATE_DOCUMENT ? 4 : _context.t0 === _dsl.MutationTypes.UPDATE_DOCUMENTS ? 5 : _context.t0 === _dsl.MutationTypes.UPDATE_DOCUMENT ? 9 : _context.t0 === _dsl.MutationTypes.DELETE_DOCUMENT ? 10 : _context.t0 === _dsl.MutationTypes.ADD_REFERENCES_TO ? 11 : _context.t0 === _dsl.MutationTypes.REMOVE_REFERENCES_TO ? 12 : _context.t0 === _dsl.MutationTypes.ADD_REFERENCED_BY ? 13 : _context.t0 === _dsl.MutationTypes.REMOVE_REFERENCED_BY ? 18 : _context.t0 === _dsl.MutationTypes.UPLOAD_FILE ? 23 : 24; + break; -var Transform = __webpack_require__(706); + case 4: + return _context.abrupt("return", this.stackClient.collection(doc._type).create(doc)); -var newlines = /\n+$/, - logger = new Transform(); + case 5: + _context.next = 7; + return this.stackClient.collection(docs[0]._type).updateAll(docs); -logger.write = function(name, level, args) { - var i = args.length-1; - if (typeof console === 'undefined' || !console.log) { - return; - } - if(console.log.apply) { - return console.log.apply(console, [name, level].concat(args)); - } else if(JSON && JSON.stringify) { - // console.log.apply is undefined in IE8 and IE9 - // for IE8/9: make console.log at least a bit less awful - if(args[i] && typeof args[i] == 'string') { - args[i] = args[i].replace(newlines, ''); - } - try { - for(i = 0; i < args.length; i++) { - args[i] = JSON.stringify(args[i]); - } - } catch(e) {} - console.log(args.join(' ')); - } -}; + case 7: + updateAllResp = _context.sent; + return _context.abrupt("return", transformBulkDocsResponse(updateAllResp, docs)); -logger.formatters = ['color', 'minilog']; -logger.color = __webpack_require__(718); -logger.minilog = __webpack_require__(720); + case 9: + return _context.abrupt("return", this.stackClient.collection(doc._type).update(doc)); -module.exports = logger; + case 10: + return _context.abrupt("return", this.stackClient.collection(doc._type).destroy(doc)); + case 11: + return _context.abrupt("return", this.stackClient.collection(props.referencedDocuments[0]._type).addReferencesTo(doc, props.referencedDocuments)); -/***/ }), -/* 718 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 12: + return _context.abrupt("return", this.stackClient.collection(props.referencedDocuments[0]._type).removeReferencesTo(doc, props.referencedDocuments)); -var Transform = __webpack_require__(706), - color = __webpack_require__(719); + case 13: + if (!(doc._type === _const.DOCTYPE_FILES)) { + _context.next = 17; + break; + } -var colors = { debug: ['cyan'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] }, - logger = new Transform(); + return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).addReferencedBy(doc, props.referencedDocuments)); -logger.write = function(name, level, args) { - var fn = console.log; - if(console[level] && console[level].apply) { - fn = console[level]; - fn.apply(console, [ '%c'+name+' %c'+level, color('gray'), color.apply(color, colors[level])].concat(args)); - } -}; + case 17: + throw new Error('The document type should be io.cozy.files'); -// NOP, because piping the formatted logs can only cause trouble. -logger.pipe = function() { }; + case 18: + if (!(doc._type === _const.DOCTYPE_FILES)) { + _context.next = 22; + break; + } -module.exports = logger; + return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).removeReferencedBy(doc, props.referencedDocuments)); + case 22: + throw new Error('The document type should be io.cozy.files'); -/***/ }), -/* 719 */ -/***/ ((module) => { + case 23: + return _context.abrupt("return", this.stackClient.collection(_const.DOCTYPE_FILES).upload(props.file, props.dirPath)); -var hex = { - black: '#000', - red: '#c23621', - green: '#25bc26', - yellow: '#bbbb00', - blue: '#492ee1', - magenta: '#d338d3', - cyan: '#33bbc8', - gray: '#808080', - purple: '#708' -}; -function color(fg, isInverse) { - if(isInverse) { - return 'color: #fff; background: '+hex[fg]+';'; - } else { - return 'color: '+hex[fg]+';'; - } -} + case 24: + return _context.abrupt("return", forward(mutation, result)); -module.exports = color; + case 25: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + function executeMutation(_x, _x2, _x3) { + return _executeMutation.apply(this, arguments); + } -/***/ }), -/* 720 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return executeMutation; + }() + }]); + return StackLink; +}(_CozyLink2.default); -var Transform = __webpack_require__(706), - color = __webpack_require__(719), - colors = { debug: ['gray'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] }, - logger = new Transform(); +exports["default"] = StackLink; -logger.write = function(name, level, args) { - var fn = console.log; - if(level != 'debug' && console[level]) { - fn = console[level]; - } +/***/ }), +/* 699 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - var subset = [], i = 0; - if(level != 'info') { - for(; i < args.length; i++) { - if(typeof args[i] != 'string') break; - } - fn.apply(console, [ '%c'+name +' '+ args.slice(0, i).join(' '), color.apply(color, colors[level]) ].concat(args.slice(i))); - } else { - fn.apply(console, [ '%c'+name, color.apply(color, colors[level]) ].concat(args)); - } -}; +"use strict"; -// NOP, because piping the formatted logs can only cause trouble. -logger.pipe = function() { }; -module.exports = logger; +var _interopRequireDefault = __webpack_require__(524); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.chain = exports["default"] = void 0; -/***/ }), -/* 721 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); -var Transform = __webpack_require__(706); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -function Stringify() {} +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -Transform.mixin(Stringify); +var CozyLink = /*#__PURE__*/function () { + function CozyLink(requestHandler) { + (0, _classCallCheck2.default)(this, CozyLink); -Stringify.prototype.write = function(name, level, args) { - var result = []; - if(name) result.push(name); - if(level) result.push(level); - result = result.concat(args); - for(var i = 0; i < result.length; i++) { - if(result[i] && typeof result[i] == 'object') { - // Buffers in Node.js look bad when stringified - if(result[i].constructor && result[i].constructor.isBuffer) { - result[i] = result[i].toString(); - } else { - try { - result[i] = JSON.stringify(result[i]); - } catch(stringifyError) { - // happens when an object has a circular structure - // do not throw an error, when printing, the toString() method of the object will be used - } - } - } else { - result[i] = result[i]; + if (typeof requestHandler === 'function') { + this.request = requestHandler; } } - this.emit('item', result.join(' ') + '\n'); -}; - -module.exports = Stringify; - -/***/ }), -/* 722 */ -/***/ ((module) => { + (0, _createClass2.default)(CozyLink, [{ + key: "request", + value: function request(operation, result, forward) { + throw new Error('request is not implemented'); + } + }]); + return CozyLink; +}(); -function RedisBackend(options) { - this.client = options.client; - this.key = options.key; -} +exports["default"] = CozyLink; -RedisBackend.prototype.write = function(str) { - this.client.rpush(this.key, str); +var toLink = function toLink(handler) { + return typeof handler === 'function' ? new CozyLink(handler) : handler; }; -RedisBackend.prototype.end = function() {}; +var defaultLinkHandler = function defaultLinkHandler(operation, result) { + if (result) return result;else if (operation.execute) return operation.execute();else throw new Error("No link could handle operation ".concat(JSON.stringify(operation))); +}; -RedisBackend.prototype.clear = function(cb) { - this.client.del(this.key, cb); +var chain = function chain(links) { + return [].concat((0, _toConsumableArray2.default)(links), [defaultLinkHandler]).map(toLink).reduce(concat); }; -module.exports = RedisBackend; +exports.chain = chain; + +var concat = function concat(firstLink, nextLink) { + return new CozyLink(function (operation, result, forward) { + var nextForward = function nextForward(op, res) { + return nextLink.request(op, res, forward); + }; + return firstLink.request(operation, result, nextForward); + }); +}; /***/ }), -/* 723 */ +/* 700 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.QueryIDGenerator = exports.getQueryFromSlice = exports.receiveQueryError = exports.receiveQueryResult = exports.loadQuery = exports.initQuery = exports["default"] = exports.makeSorterFromDefinition = exports.mergeSelectorAndPartialIndex = exports.convert$gtNullSelectors = exports.isReceivingData = exports.isQueryAction = void 0; +exports.BulkEditError = void 0; -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var _mapValues = _interopRequireDefault(__webpack_require__(533)); +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var _groupBy = _interopRequireDefault(__webpack_require__(724)); +var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664)); -var _difference = _interopRequireDefault(__webpack_require__(725)); +var _zipWith = _interopRequireDefault(__webpack_require__(701)); -var _intersection = _interopRequireDefault(__webpack_require__(727)); +var _types = __webpack_require__(622); -var _concat = _interopRequireDefault(__webpack_require__(730)); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -var _isPlainObject = _interopRequireDefault(__webpack_require__(619)); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var _uniq = _interopRequireDefault(__webpack_require__(612)); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -var _orderBy = _interopRequireDefault(__webpack_require__(731)); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -var _isArray = _interopRequireDefault(__webpack_require__(55)); +var BulkEditError = /*#__PURE__*/function (_Error) { + (0, _inherits2.default)(BulkEditError, _Error); -var _isString = _interopRequireDefault(__webpack_require__(54)); + var _super = _createSuper(BulkEditError); -var _get = _interopRequireDefault(__webpack_require__(358)); + /** + * Indicates that a bulk edit has (potentially partially) failed + * + * @param {CouchDBBulkResult[]} bulkResponse - CouchDB Bulk response + * @param {CozyClientDocument[]} updatedDocs - Docs with updated _id and _rev + */ + function BulkEditError(bulkResponse, updatedDocs) { + var _this; -var _sift = _interopRequireDefault(__webpack_require__(737)); + (0, _classCallCheck2.default)(this, BulkEditError); + _this = _super.call(this, 'Error while bulk saving'); + _this.name = 'BulkEditError'; + _this.results = (0, _zipWith.default)(bulkResponse, updatedDocs, function (result, doc) { + return _objectSpread(_objectSpread({}, result), {}, { + doc: doc + }); + }); + return _this; + } + /** + * Get documents that have been correctly updated + * + * @returns {CozyClientDocument[]} + */ -var _cozyFlags = _interopRequireDefault(__webpack_require__(603)); -var _documents = __webpack_require__(698); + (0, _createClass2.default)(BulkEditError, [{ + key: "getUpdatedDocuments", + value: function getUpdatedDocuments() { + return this.results.filter(function (r) { + return r.ok; + }).map(function (r) { + return r.doc; + }); + } + /** + * Get bulk errors results + * + * @returns {Array<CouchDBBulkResult & { doc: CozyClientDocument }>} + */ -var _mutations = __webpack_require__(738); + }, { + key: "getErrors", + value: function getErrors() { + return this.results.filter(function (r) { + return !r.ok; + }); + } + }]); + return BulkEditError; +}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); -var _helpers = __webpack_require__(739); +exports.BulkEditError = BulkEditError; -var _dsl = __webpack_require__(607); +/***/ }), +/* 701 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _types = __webpack_require__(610); +var baseRest = __webpack_require__(556), + unzipWith = __webpack_require__(702); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +/** + * This method is like `_.zip` except that it accepts `iteratee` to specify + * how grouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee=_.identity] The function to combine + * grouped values. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { + * return a + b + c; + * }); + * // => [111, 222] + */ +var zipWith = baseRest(function(arrays) { + var length = arrays.length, + iteratee = length > 1 ? arrays[length - 1] : undefined; -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; + return unzipWith(arrays, iteratee); +}); -var INIT_QUERY = 'INIT_QUERY'; -var LOAD_QUERY = 'LOAD_QUERY'; -var RECEIVE_QUERY_RESULT = 'RECEIVE_QUERY_RESULT'; -var RECEIVE_QUERY_ERROR = 'RECEIVE_QUERY_ERROR'; // Read if the devtools are open to store the execution time -// This is done at runtime to not read the value everytime -// we receive a result. So you have to refresh your page -// in order to get the stats +module.exports = zipWith; -var executionStatsEnabled = (0, _cozyFlags.default)('debug'); -var isQueryAction = function isQueryAction(action) { - return [INIT_QUERY, LOAD_QUERY, RECEIVE_QUERY_RESULT, RECEIVE_QUERY_ERROR].indexOf(action.type) !== -1; -}; +/***/ }), +/* 702 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -exports.isQueryAction = isQueryAction; +var apply = __webpack_require__(558), + arrayMap = __webpack_require__(410), + unzip = __webpack_require__(563); -var isReceivingData = function isReceivingData(action) { - return action.type === RECEIVE_QUERY_RESULT; -}; -/** @type {QueryState} */ +/** + * This method is like `_.unzip` except that it accepts `iteratee` to specify + * how regrouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee=_.identity] The function to combine + * regrouped values. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ +function unzipWith(array, iteratee) { + if (!(array && array.length)) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + return arrayMap(result, function(group) { + return apply(iteratee, undefined, group); + }); +} +module.exports = unzipWith; -exports.isReceivingData = isReceivingData; -var queryInitialState = { - id: null, - definition: null, - fetchStatus: 'pending', - lastFetch: null, - lastUpdate: null, - lastErrorUpdate: null, - lastError: null, - hasMore: false, - count: 0, - data: [], - bookmark: null -}; -var updateQueryDataFromResponse = function updateQueryDataFromResponse(queryState, response, documents) { - var updatedIds = (0, _uniq.default)([].concat((0, _toConsumableArray2.default)(queryState.data), (0, _toConsumableArray2.default)(response.data.map(_helpers.properId)))); +/***/ }), +/* 703 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(524); + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "HasManyFiles", ({ + enumerable: true, + get: function get() { + return _HasManyFiles.default; + } +})); +Object.defineProperty(exports, "HasMany", ({ + enumerable: true, + get: function get() { + return _HasMany.default; + } +})); +Object.defineProperty(exports, "HasOne", ({ + enumerable: true, + get: function get() { + return _HasOne.default; + } +})); +Object.defineProperty(exports, "HasOneInPlace", ({ + enumerable: true, + get: function get() { + return _HasOneInPlace.default; + } +})); +Object.defineProperty(exports, "HasManyInPlace", ({ + enumerable: true, + get: function get() { + return _HasManyInPlace.default; + } +})); +Object.defineProperty(exports, "HasManyTriggers", ({ + enumerable: true, + get: function get() { + return _HasManyTriggers.default; + } +})); +Object.defineProperty(exports, "Association", ({ + enumerable: true, + get: function get() { + return _Association.default; + } +})); +Object.defineProperty(exports, "resolveClass", ({ + enumerable: true, + get: function get() { + return _helpers.resolveClass; + } +})); +Object.defineProperty(exports, "create", ({ + enumerable: true, + get: function get() { + return _helpers.create; + } +})); +Object.defineProperty(exports, "isReferencedBy", ({ + enumerable: true, + get: function get() { + return _helpers.isReferencedBy; + } +})); +Object.defineProperty(exports, "isReferencedById", ({ + enumerable: true, + get: function get() { + return _helpers.isReferencedById; + } +})); +Object.defineProperty(exports, "getReferencedBy", ({ + enumerable: true, + get: function get() { + return _helpers.getReferencedBy; + } +})); +Object.defineProperty(exports, "getReferencedById", ({ + enumerable: true, + get: function get() { + return _helpers.getReferencedById; + } +})); + +var _HasManyFiles = _interopRequireDefault(__webpack_require__(704)); + +var _HasMany = _interopRequireDefault(__webpack_require__(753)); - if (queryState.definition.sort) { - var sorter = makeSorterFromDefinition(queryState.definition); - var doctype = queryState.definition.doctype; - var allDocs = documents[doctype]; - var docs = allDocs ? updatedIds.map(function (_id) { - return allDocs[_id]; - }).filter(Boolean) : []; - var sortedDocs = sorter(docs); - updatedIds = sortedDocs.map(_helpers.properId); - } +var _HasOne = _interopRequireDefault(__webpack_require__(762)); - return updatedIds; -}; -/** - * Reducer for a query slice - * - * @param {QueryState} state - Current state - * @param {any} action - Redux action - * @param {DocumentsStateSlice} documents - Reference to the next documents slice - * @returns {QueryState} - Next state - */ +var _HasOneInPlace = _interopRequireDefault(__webpack_require__(764)); +var _HasManyInPlace = _interopRequireDefault(__webpack_require__(765)); -var query = function query() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : queryInitialState; - var action = arguments.length > 1 ? arguments[1] : undefined; - var documents = arguments.length > 2 ? arguments[2] : undefined; +var _HasManyTriggers = _interopRequireDefault(__webpack_require__(766)); - switch (action.type) { - case INIT_QUERY: - if (state.lastUpdate && state.id === action.queryId && state.definition === action.queryDefinition) { - return state; - } +var _Association = _interopRequireDefault(__webpack_require__(752)); - return _objectSpread(_objectSpread({}, state), {}, { - id: action.queryId, - definition: action.queryDefinition, - options: action.options, - // When the query is new, we set "fetchStatus" to "loading" - // directly since we know it will be loaded right away. - // This way, the loadQuery action will have no effect, and - // we save an additional render. - fetchStatus: state.lastUpdate ? state.fetchStatus : 'pending' - }); +var _helpers = __webpack_require__(767); - case LOAD_QUERY: - if (state.fetchStatus === 'loading') { - return state; - } +/***/ }), +/* 704 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - return _objectSpread(_objectSpread({}, state), {}, { - fetchStatus: 'loading' - }); +"use strict"; - case RECEIVE_QUERY_RESULT: - { - var response = action.response; - if (!response.data) { - return state; - } - /** @type {Partial<QueryState>} */ +var _interopRequireDefault = __webpack_require__(524); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - var common = _objectSpread({ - fetchStatus: 'loaded', - lastFetch: Date.now(), - lastUpdate: Date.now() - }, executionStatsEnabled && { - execution_stats: response.execution_stats - }); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - if (!Array.isArray(response.data)) { - return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, { - hasMore: false, - count: 1, - data: [(0, _helpers.properId)(response.data)] - }); - } +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); - return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, { - bookmark: response.bookmark || null, - hasMore: response.next !== undefined ? response.next : state.hasMore, - count: response.meta && response.meta.count ? response.meta.count : response.data.length, - data: updateQueryDataFromResponse(state, response, documents) - }); - } +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); - case RECEIVE_QUERY_ERROR: - return _objectSpread(_objectSpread({}, state), {}, { - id: action.queryId, - fetchStatus: 'failed', - lastError: action.error, - lastErrorUpdate: Date.now() - }); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - default: - return state; - } -}; -/** - * Normalize sift selector - * - * @returns {object} - */ +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var convert$gtNullSelectors = function convert$gtNullSelectors(selector) { - var result = {}; +var _get3 = _interopRequireDefault(__webpack_require__(682)); - for (var _i = 0, _Object$entries = Object.entries(selector); _i < _Object$entries.length; _i++) { - var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2), - key = _Object$entries$_i[0], - value = _Object$entries$_i[1]; +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); - var convertedValue = (0, _isPlainObject.default)(value) ? convert$gtNullSelectors(value) : value; - var convertedKey = key === '$gt' && convertedValue === null ? '$gtnull' : key; - result[convertedKey] = convertedValue; - } +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); - return result; -}; -/** - * Merges query selectors with query partial indexes - * - * @param {object} queryDefinition - A query definition - * @returns {object} A query definition selector - */ +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); +var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532)); -exports.convert$gtNullSelectors = convert$gtNullSelectors; +var _get4 = _interopRequireDefault(__webpack_require__(370)); -var mergeSelectorAndPartialIndex = function mergeSelectorAndPartialIndex(queryDefinition) { - return _objectSpread(_objectSpread({}, queryDefinition.selector), (0, _get.default)(queryDefinition, 'partialFilter')); -}; -/** - * @param {QueryDefinition} queryDefinition - A query definition - * @returns {function(CozyClientDocument): boolean} - */ +var _omit = _interopRequireDefault(__webpack_require__(625)); +var _uniq = _interopRequireDefault(__webpack_require__(624)); -exports.mergeSelectorAndPartialIndex = mergeSelectorAndPartialIndex; +var _dsl = __webpack_require__(619); -var getSelectorFilterFn = function getSelectorFilterFn(queryDefinition) { - if (queryDefinition.selector) { - var selectors = mergeSelectorAndPartialIndex(queryDefinition); // sift does not work like couchdb when using { $gt: null } as a selector, so we use a custom operator +var _store = __webpack_require__(705); - _sift.default.use({ - $gtnull: function $gtnull(_selectorValue, actualValue) { - return !!actualValue; - } - }); +var _types = __webpack_require__(622); + +var _const = __webpack_require__(697); + +var _Association = _interopRequireDefault(__webpack_require__(752)); + +var _HasMany2 = _interopRequireDefault(__webpack_require__(753)); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - return (0, _sift.default)(convert$gtNullSelectors(selectors)); - } else if (queryDefinition.id) { - /** @type {object} */ - var siftQuery = { - _id: queryDefinition.id - }; - return (0, _sift.default)(siftQuery); - } else if (queryDefinition.ids) { - /** @type {object} */ - var _siftQuery = { - _id: { - $in: queryDefinition.ids - } - }; - return (0, _sift.default)(_siftQuery); - } else { - return null; - } -}; /** + * newCursor - Returns a CouchDB view Cursor for cursor-based pagination * - * Returns a predicate function that checks if a document should be - * included in the result of the query. + * @param {ViewKey} key - The CouchDB key of the view which will be requested + * @param {DocId} startDocId - The first doc _id to return from the view * - * @param {QueryState} query - Definition of the query - * @returns {function(CozyClientDocument): boolean} Predicate function + * @returns {CouchDBViewCursor} */ +var newCursor = function newCursor(_ref, startDocId) { + var _ref2 = (0, _slicedToArray2.default)(_ref, 3), + doctype = _ref2[0], + id = _ref2[1], + lastDatetime = _ref2[2]; - -var getQueryDocumentsChecker = function getQueryDocumentsChecker(query) { - var qdoctype = query.definition.doctype; - var selectorFilterFn = getSelectorFilterFn(query.definition); - return function (datum) { - var ddoctype = datum._type; - if (ddoctype !== qdoctype) return false; - if (datum._deleted) return false; - if (!selectorFilterFn) return true; - return !!selectorFilterFn(datum); - }; -}; - -var makeCaseInsensitiveStringSorter = function makeCaseInsensitiveStringSorter(attrName) { - return function (item) { - var attrValue = (0, _get.default)(item, attrName); - return (0, _isString.default)(attrValue) ? attrValue.toLowerCase() : attrValue; - }; + var cursorKey = lastDatetime ? [doctype, id, lastDatetime] : [doctype, id]; + return [cursorKey, startDocId]; }; /** - * Creates a sort function from a definition. - * - * Used to sort query results inside the store when creating a file or - * receiving updates. - * - * @param {QueryDefinition} definition - A query definition - * @returns {function(Array<CozyClientDocument>): Array<CozyClientDocument>} - * - * @private + * This class is only used for photos albums relationships. + * Behind the hood, the queries uses a view returning the files sorted + * by datetime, with a cursor-based pagination. */ -var makeSorterFromDefinition = function makeSorterFromDefinition(definition) { - var sort = definition.sort; +var HasManyFiles = /*#__PURE__*/function (_HasMany) { + (0, _inherits2.default)(HasManyFiles, _HasMany); - if (!sort) { - return function (docs) { - return docs; - }; - } else if (!(0, _isArray.default)(definition.sort)) { - console.warn('Correct update of queries with a sort that is not an array is not supported. Use an array as argument of QueryDefinition::sort'); - return function (docs) { - return docs; - }; - } else { - var attributeOrders = sort.map(function (x) { - return Object.entries(x)[0]; - }); - var attrs = attributeOrders.map(function (x) { - return x[0]; - }).map(makeCaseInsensitiveStringSorter); - var orders = attributeOrders.map(function (x) { - return x[1]; - }); - return function (docs) { - return (0, _orderBy.default)(docs, attrs, orders); - }; + var _super = _createSuper(HasManyFiles); + + function HasManyFiles() { + (0, _classCallCheck2.default)(this, HasManyFiles); + return _super.apply(this, arguments); } -}; -/** - * Updates query state when new data comes in - * - * @param {QueryState} query - Current query state - * @param {Array<CozyClientDocument>} newData - New documents (in most case from the server) - * @param {DocumentsStateSlice} documents - A reference to the documents slice - * @returns {QueryState} - Updated query state - */ + (0, _createClass2.default)(HasManyFiles, [{ + key: "fetchMore", + value: function () { + var _fetchMore = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { + var _this = this; -exports.makeSorterFromDefinition = makeSorterFromDefinition; + var queryDef, relationships, lastRelationship; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + queryDef = new _dsl.QueryDefinition({ + doctype: _const.DOCTYPE_FILES + }); + relationships = this.getRelationship().data; // Get last datetime for cursor -var updateData = function updateData(query, newData, documents) { - var belongsToQuery = getQueryDocumentsChecker(query); - var res = (0, _mapValues.default)((0, _groupBy.default)(newData, belongsToQuery), function (docs) { - return docs.map(_helpers.properId); - }); - var _res$true = res.true, - matchedIds = _res$true === void 0 ? [] : _res$true, - _res$false = res.false, - unmatchedIds = _res$false === void 0 ? [] : _res$false; - var originalIds = query.data; - var autoUpdate = query.options && query.options.autoUpdate; - var shouldRemove = !autoUpdate || autoUpdate.remove !== false; - var shouldAdd = !autoUpdate || autoUpdate.add !== false; - var shouldUpdate = !autoUpdate || autoUpdate.update !== false; - var toRemove = shouldRemove ? (0, _intersection.default)(originalIds, unmatchedIds) : []; - var toAdd = shouldAdd ? (0, _difference.default)(matchedIds, originalIds) : []; - var toUpdate = shouldUpdate ? (0, _intersection.default)(originalIds, matchedIds) : []; - var changed = toRemove.length || toAdd.length || toUpdate.length; // concat doesn't check duplicates (contrarily to union), which is ok as - // toAdd does not contain any id present in originalIds, by construction. - // It is also faster than union. + lastRelationship = relationships[relationships.length - 1]; + _context2.next = 5; + return this.dispatch( /*#__PURE__*/function () { + var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(dispatch, getState) { + var lastRelDoc, lastDatetime, cursor, response; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + lastRelDoc = (0, _store.getDocumentFromState)(getState(), lastRelationship._type, lastRelationship._id); // Photos always have a datetime field in metadata - var updatedData = (0, _difference.default)((0, _concat.default)(originalIds, toAdd), toRemove); + lastDatetime = lastRelDoc.attributes.metadata.datetime; // cursor-based pagination - if (query.definition.sort && documents) { - var sorter = makeSorterFromDefinition(query.definition); - var allDocs = documents[query.definition.doctype]; - var docs = updatedData.map(function (_id) { - return allDocs[_id]; - }); - var sortedDocs = sorter(docs); - updatedData = sortedDocs.map(_helpers.properId); - } + cursor = newCursor([_this.target._type, _this.target._id, lastDatetime], relationships[relationships.length - 1]._id); + _context.next = 5; + return _this.query(queryDef.referencedBy(_this.target).offsetCursor(cursor)); - return _objectSpread(_objectSpread({}, query), {}, { - data: updatedData, - count: updatedData.length, - lastUpdate: changed ? Date.now() : query.lastUpdate - }); -}; -/** - * Creates a function that returns an updated query state - * from an action - * - * @param {object} action - A redux action - * @param {DocumentsStateSlice} documents - Reference to documents slice - * @returns {function(QueryState): QueryState} - Updater query state - */ + case 5: + response = _context.sent; + // Remove first returned element, used as starting point for the query + response.data.shift(); + _context.next = 9; + return _this.dispatch(_this.updateRelationshipData(function (previousRelationshipData) { + return _objectSpread(_objectSpread({}, previousRelationshipData), {}, { + data: [].concat((0, _toConsumableArray2.default)(previousRelationshipData.data), (0, _toConsumableArray2.default)(response.data)), + next: response.next + }); + })); + case 9: + case "end": + return _context.stop(); + } + } + }, _callee); + })); -var autoQueryUpdater = function autoQueryUpdater(action, documents) { - return function (query) { - var data = (0, _get.default)(action, 'response.data') || (0, _get.default)(action, 'definition.document'); - if (!data) return query; + return function (_x, _x2) { + return _ref3.apply(this, arguments); + }; + }()); - if (!Array.isArray(data)) { - data = [data]; - } + case 5: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); - if (!data.length) { - return query; - } + function fetchMore() { + return _fetchMore.apply(this, arguments); + } - if (query.definition.doctype !== data[0]._type) { - return query; - } + return fetchMore; + }() + }, { + key: "addById", + value: function () { + var _addById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(idsArg) { + var _this2 = this; - return updateData(query, data, documents); - }; -}; -/** - * Creates a function that returns an updated query state - * from an action - * - * @param {object} action - A redux action - * @param {DocumentsStateSlice} documents - Reference to documents slice - * @returns {function(QueryState): QueryState} - Updater query state - */ + var ids, relations; + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + ids = Array.isArray(idsArg) ? idsArg : [idsArg]; + relations = ids.map(function (id) { + return { + _id: id, + _type: _this2.doctype + }; + }); + _context3.next = 4; + return this.mutate(this.addReferences(relations)); + case 4: + this.addTargetRelationships(ids); -var manualQueryUpdater = function manualQueryUpdater(action, documents) { - return function (query) { - var updateQueries = action.updateQueries; - var response = action.response; - var updater = updateQueries[query.id]; + case 5: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); - if (!updater) { - return query; - } + function addById(_x3) { + return _addById.apply(this, arguments); + } - var doctype = query.definition.doctype; - var oldData = query.data; - var oldDocs = mapIdsToDocuments(documents, doctype, oldData); - var newData = updater(oldDocs, response); - var newDataIds = newData.map(_helpers.properId); - return _objectSpread(_objectSpread({}, query), {}, { - data: newDataIds, - count: newDataIds.length, - lastUpdate: Date.now() - }); - }; -}; -/** - * @param {QueriesStateSlice} state - Redux slice containing all the query states indexed by name - * @param {object} action - Income redux action - * @param {DocumentsStateSlice} documents - Reference to documents slice - * @param {boolean} haveDocumentsChanged - Has the document slice changed with current action - * @returns {QueriesStateSlice} - */ + return addById; + }() + }, { + key: "removeById", + value: function () { + var _removeById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(idsArg) { + var _this3 = this; + + var ids, references; + return _regenerator.default.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + ids = Array.isArray(idsArg) ? idsArg : [idsArg]; + references = ids.map(function (id) { + return { + _id: id, + _type: _this3.doctype + }; + }); + _context4.next = 4; + return this.mutate(this.removeReferences(references)); + case 4: + this.removeTargetRelationships(ids); -var queries = function queries() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var action = arguments.length > 1 ? arguments[1] : undefined; - var documents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var haveDocumentsChanged = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + case 5: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); - if (action.type == INIT_QUERY) { - var newQueryState = query(state[action.queryId], action, documents); // Do not create new object unnecessarily + function removeById(_x4) { + return _removeById.apply(this, arguments); + } - if (newQueryState === state[action.queryId]) { - return state; + return removeById; + }() + }, { + key: "addReferences", + value: function addReferences(referencedDocs) { + if (this.target._type === _const.DOCTYPE_FILES) { + return _dsl.Mutations.addReferencedBy(this.target, referencedDocs); + } else if (referencedDocs[0]._type === _const.DOCTYPE_FILES) { + return _dsl.Mutations.addReferencesTo(this.target, referencedDocs); + } else { + throw new Error('Either the document or the references should be io.cozy.files'); + } + } + }, { + key: "removeReferences", + value: function removeReferences(referencedDocs) { + if (this.target._type === _const.DOCTYPE_FILES) { + return _dsl.Mutations.removeReferencedBy(this.target, referencedDocs); + } else if (referencedDocs[0]._type === _const.DOCTYPE_FILES) { + return _dsl.Mutations.removeReferencesTo(this.target, referencedDocs); + } else { + throw new Error('Either the document or the references should be io.cozy.files'); + } + } + }, { + key: "dehydrate", + value: function dehydrate(doc) { + // HasManyFiles relationships are stored on the file doctype, not the document the files are related to + return (0, _omit.default)(doc, [this.name, "relationships.".concat(this.name)]); } + /** + * @param {CozyClientDocument} document - Document to query + * @param {object} client - The CozyClient instance + * @param {Association} assoc - The query params + * + * @returns {CozyClientDocument | QueryDefinition} + */ - return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, action.queryId, newQueryState)); - } + }, { + key: "data", + get: function get() { + var _this4 = this; - if (isQueryAction(action)) { - var updater = autoQueryUpdater(action, documents); - return (0, _mapValues.default)(state, function (queryState) { - if (queryState.id == action.queryId) { - return query(queryState, action, documents); - } else if (haveDocumentsChanged) { - return updater(queryState); + if (this.target._type === _const.DOCTYPE_FILES) { + var refs = (0, _get4.default)(this.target, 'referenced_by', []); + return refs.map(function (_ref4) { + var id = _ref4.id, + type = _ref4.type; + return _this4.get(type, id); + }).filter(Boolean); } else { - return queryState; + return (0, _get3.default)((0, _getPrototypeOf2.default)(HasManyFiles.prototype), "data", this); } - }); - } + } + }], [{ + key: "query", + value: function query(document, client, assoc) { + if (document._type === _const.DOCTYPE_FILES) { + var refs = (0, _get4.default)(document, "relationships.referenced_by.data", []); + var ids = (0, _uniq.default)(refs.filter(function (ref) { + return ref.type === assoc.doctype; + }).map(function (ref) { + return ref.id; + })); + return ids.length > 0 ? (0, _dsl.Q)(assoc.doctype).getByIds(ids) : null; + } else { + var cursor = newCursor([document._type, document._id], ''); + return (0, _dsl.Q)(assoc.doctype).referencedBy(document).offsetCursor(cursor); + } + } + }]); + return HasManyFiles; +}(_HasMany2.default); - if ((0, _mutations.isReceivingMutationResult)(action)) { - var _updater = action.updateQueries ? manualQueryUpdater(action, documents) : autoQueryUpdater(action, documents); +exports["default"] = HasManyFiles; - return (0, _mapValues.default)(state, _updater); - } +/***/ }), +/* 705 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - return state; -}; +"use strict"; -var _default = queries; -/** - * Create the query states in the store. Queries are indexed - * in the store by queryId - * - * @param {string} queryId Name/id of the query - * @param {QueryDefinition} queryDefinition - Definition of the created query - * @param {QueryOptions} [options] - Options for the created query - */ -exports["default"] = _default; +var _interopRequireWildcard = __webpack_require__(522); -var initQuery = function initQuery(queryId, queryDefinition) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; +var _interopRequireDefault = __webpack_require__(524); - if (!queryDefinition.doctype) { - throw new Error('Cannot init query with no doctype'); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "initQuery", ({ + enumerable: true, + get: function get() { + return _queries.initQuery; + } +})); +Object.defineProperty(exports, "loadQuery", ({ + enumerable: true, + get: function get() { + return _queries.loadQuery; + } +})); +Object.defineProperty(exports, "receiveQueryResult", ({ + enumerable: true, + get: function get() { + return _queries.receiveQueryResult; + } +})); +Object.defineProperty(exports, "receiveQueryError", ({ + enumerable: true, + get: function get() { + return _queries.receiveQueryError; + } +})); +Object.defineProperty(exports, "initMutation", ({ + enumerable: true, + get: function get() { + return _mutations.initMutation; + } +})); +Object.defineProperty(exports, "receiveMutationResult", ({ + enumerable: true, + get: function get() { + return _mutations.receiveMutationResult; } +})); +Object.defineProperty(exports, "receiveMutationError", ({ + enumerable: true, + get: function get() { + return _mutations.receiveMutationError; + } +})); +exports.resetState = exports.getRawQueryFromState = exports.getQueryFromState = exports.getQueryFromStore = exports.getDocumentFromState = exports.getCollectionFromState = exports.getStateRoot = exports.createStore = exports["default"] = exports.StoreProxy = void 0; - return { - type: INIT_QUERY, - queryId: queryId, - queryDefinition: queryDefinition, - options: options - }; -}; +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -exports.initQuery = initQuery; +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var loadQuery = function loadQuery(queryId) { - return { - type: LOAD_QUERY, - queryId: queryId - }; -}; +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -exports.loadQuery = loadQuery; +var _cozyFlags = _interopRequireDefault(__webpack_require__(615)); -var receiveQueryResult = function receiveQueryResult(queryId, response) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - return _objectSpread({ - type: RECEIVE_QUERY_RESULT, - queryId: queryId, - response: response - }, options); -}; +var _redux = __webpack_require__(706); -exports.receiveQueryResult = receiveQueryResult; +var _reduxThunk = _interopRequireDefault(__webpack_require__(709)); -var receiveQueryError = function receiveQueryError(queryId, error) { - return { - type: RECEIVE_QUERY_ERROR, - queryId: queryId, - error: error - }; -}; // selectors +var _documents = _interopRequireWildcard(__webpack_require__(710)); +var _queries = _interopRequireWildcard(__webpack_require__(735)); -exports.receiveQueryError = receiveQueryError; +var _mutations = __webpack_require__(750); -var mapIdsToDocuments = function mapIdsToDocuments(documents, doctype, ids) { - return ids.map(function (id) { - return (0, _documents.getDocumentFromSlice)(documents, doctype, id); - }); -}; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -var getQueryFromSlice = function getQueryFromSlice(state, queryId, documents) { - if (!state || !state[queryId]) { - return _objectSpread(_objectSpread({}, queryInitialState), {}, { - id: queryId, - data: null - }); - } +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - var query = state[queryId]; - return documents ? _objectSpread(_objectSpread({}, query), {}, { - data: mapIdsToDocuments(documents, query.definition.doctype, query.data) - }) : query; +var RESET_ACTION_TYPE = 'COZY_CLIENT.RESET_STATE'; + +var resetState = function resetState() { + return { + type: RESET_ACTION_TYPE + }; }; -exports.getQueryFromSlice = getQueryFromSlice; +exports.resetState = resetState; -var QueryIDGenerator = /*#__PURE__*/function () { - function QueryIDGenerator() { - (0, _classCallCheck2.default)(this, QueryIDGenerator); - this.idCounter = 1; +var StoreProxy = /*#__PURE__*/function () { + function StoreProxy(state) { + (0, _classCallCheck2.default)(this, StoreProxy); + this.state = state; } - /** - * Generates a random id for unamed queries - */ - - (0, _createClass2.default)(QueryIDGenerator, [{ - key: "generateRandomId", - value: function generateRandomId() { - var id = this.idCounter; - this.idCounter++; - return id.toString(); + (0, _createClass2.default)(StoreProxy, [{ + key: "readDocument", + value: function readDocument(doctype, id) { + return this.state.documents[doctype][id]; } - /** - * Generates an id for queries - * If the query is a getById only query, - * we can generate a name for it. - * - * If not, let's generate a random id - * - * @param {QueryDefinition} queryDefinition The query definition - * @returns {string} - */ - }, { - key: "generateId", - value: function generateId(queryDefinition) { - if (!(0, _dsl.isAGetByIdQuery)(queryDefinition)) { - return this.generateRandomId(); - } else { - var id = queryDefinition.id, - doctype = queryDefinition.doctype; - return "".concat(doctype, "/").concat(id); - } + key: "writeDocument", + value: function writeDocument(document) { + this.setState(function (state) { + return _objectSpread(_objectSpread({}, state), {}, { + documents: _objectSpread(_objectSpread({}, state.documents), {}, (0, _defineProperty2.default)({}, document._type, _objectSpread(_objectSpread({}, state.documents[document._type]), {}, (0, _defineProperty2.default)({}, document._id, document)))) + }); + }); + } + }, { + key: "setState", + value: function setState(updaterFn) { + this.state = updaterFn(this.state); + } + }, { + key: "getState", + value: function getState() { + return this.state; } }]); - return QueryIDGenerator; + return StoreProxy; }(); -exports.QueryIDGenerator = QueryIDGenerator; -QueryIDGenerator.UNNAMED = 'unnamed'; - -/***/ }), -/* 724 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +exports.StoreProxy = StoreProxy; +var initialState = { + documents: {}, + queries: {} +}; -var baseAssignValue = __webpack_require__(534), - createAggregator = __webpack_require__(700); +var combinedReducer = function combinedReducer() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + var action = arguments.length > 1 ? arguments[1] : undefined; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + if (action.type == RESET_ACTION_TYPE) { + return initialState; + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + if (!(0, _queries.isQueryAction)(action) && !(0, _mutations.isMutationAction)(action)) { + return state; + } -/** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The order of grouped values - * is determined by the order they occur in `collection`. The corresponding - * value of each key is an array of elements responsible for generating the - * key. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': [4.2], '6': [6.1, 6.3] } - * - * // The `_.property` iteratee shorthand. - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ -var groupBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - result[key].push(value); - } else { - baseAssignValue(result, key, [value]); + if (action.update) { + var proxy = new StoreProxy(state); + action.update(proxy, action.response); + return { + documents: proxy.getState().documents, + queries: (0, _queries.default)(proxy.getState().queries, action, proxy.getState().documents) + }; } -}); -module.exports = groupBy; + var nextDocuments = (0, _documents.default)(state.documents, action); + var haveDocumentsChanged = nextDocuments !== state.documents; + return { + documents: nextDocuments, + queries: (0, _queries.default)(state.queries, action, nextDocuments, haveDocumentsChanged) + }; +}; +var _default = combinedReducer; +exports["default"] = _default; -/***/ }), -/* 725 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var composedEnhancer = // @ts-ignore '__REDUX_DEVTOOLS_EXTENSION_COMPOSE__' doesn't exist 'Window & typeof globalThis'.ts(2339) +// should be (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ in ts file +// see https://github.com/reduxjs/redux-devtools/tree/main/extension#11-basic-store +(0, _cozyFlags.default)('debug') && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || _redux.compose; -var baseDifference = __webpack_require__(726), - baseFlatten = __webpack_require__(541), - baseRest = __webpack_require__(544), - isArrayLikeObject = __webpack_require__(552); +var createStore = function createStore() { + return (0, _redux.createStore)((0, _redux.combineReducers)({ + cozy: combinedReducer + }), composedEnhancer((0, _redux.applyMiddleware)(_reduxThunk.default))); +}; -/** - * Creates an array of `array` values not included in the other given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. The order and references of result values are - * determined by the first array. - * - * **Note:** Unlike `_.pullAll`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.without, _.xor - * @example - * - * _.difference([2, 1], [2, 3]); - * // => [1] - */ -var difference = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) - : []; -}); +exports.createStore = createStore; -module.exports = difference; +var getStateRoot = function getStateRoot(state) { + return state.cozy || {}; +}; +exports.getStateRoot = getStateRoot; -/***/ }), -/* 726 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var getCollectionFromState = function getCollectionFromState(state, doctype) { + return (0, _documents.getCollectionFromSlice)(getStateRoot(state).documents, doctype); +}; -var SetCache = __webpack_require__(413), - arrayIncludes = __webpack_require__(464), - arrayIncludesWith = __webpack_require__(469), - arrayMap = __webpack_require__(398), - baseUnary = __webpack_require__(440), - cacheHas = __webpack_require__(417); +exports.getCollectionFromState = getCollectionFromState; -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE = 200; +var getDocumentFromState = function getDocumentFromState(state, doctype, id) { + return (0, _documents.getDocumentFromSlice)(getStateRoot(state).documents, doctype, id); +}; -/** - * The base implementation of methods like `_.difference` without support - * for excluding multiple arrays or iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - */ -function baseDifference(array, values, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - isCommon = true, - length = array.length, - result = [], - valuesLength = values.length; +exports.getDocumentFromState = getDocumentFromState; - if (!length) { - return result; - } - if (iteratee) { - values = arrayMap(values, baseUnary(iteratee)); - } - if (comparator) { - includes = arrayIncludesWith; - isCommon = false; - } - else if (values.length >= LARGE_ARRAY_SIZE) { - includes = cacheHas; - isCommon = false; - values = new SetCache(values); - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee == null ? value : iteratee(value); +var getQueryFromStore = function getQueryFromStore(store, queryId) { + return getQueryFromState(store.getState(), queryId); +}; - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === computed) { - continue outer; - } - } - result.push(value); - } - else if (!includes(values, computed, comparator)) { - result.push(value); - } - } - return result; -} +exports.getQueryFromStore = getQueryFromStore; -module.exports = baseDifference; +var getQueryFromState = function getQueryFromState(state, queryId) { + return (0, _queries.getQueryFromSlice)(getStateRoot(state).queries, queryId, getStateRoot(state).documents); +}; + +exports.getQueryFromState = getQueryFromState; + +var getRawQueryFromState = function getRawQueryFromState(state, queryId) { + return (0, _queries.getQueryFromSlice)(getStateRoot(state).queries, queryId); +}; +exports.getRawQueryFromState = getRawQueryFromState; /***/ }), -/* 727 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 706 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "__DO_NOT_USE__ActionTypes": () => (/* binding */ ActionTypes), +/* harmony export */ "applyMiddleware": () => (/* binding */ applyMiddleware), +/* harmony export */ "bindActionCreators": () => (/* binding */ bindActionCreators), +/* harmony export */ "combineReducers": () => (/* binding */ combineReducers), +/* harmony export */ "compose": () => (/* binding */ compose), +/* harmony export */ "createStore": () => (/* binding */ createStore) +/* harmony export */ }); +/* harmony import */ var _babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(707); -var arrayMap = __webpack_require__(398), - baseIntersection = __webpack_require__(728), - baseRest = __webpack_require__(544), - castArrayLikeObject = __webpack_require__(729); /** - * Creates an array of unique values that are included in all given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. The order and references of result values are - * determined by the first array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of intersecting values. - * @example + * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js * - * _.intersection([2, 1], [2, 3]); - * // => [2] + * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes + * during build. + * @param {number} code */ -var intersection = baseRest(function(arrays) { - var mapped = arrayMap(arrays, castArrayLikeObject); - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped) - : []; -}); - -module.exports = intersection; - +function formatProdErrorMessage(code) { + return "Minified Redux error #" + code + "; visit https://redux.js.org/Errors?code=" + code + " for the full message or " + 'use the non-minified dev environment for full errors. '; +} -/***/ }), -/* 728 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +// Inlined version of the `symbol-observable` polyfill +var $$observable = (function () { + return typeof Symbol === 'function' && Symbol.observable || '@@observable'; +})(); -var SetCache = __webpack_require__(413), - arrayIncludes = __webpack_require__(464), - arrayIncludesWith = __webpack_require__(469), - arrayMap = __webpack_require__(398), - baseUnary = __webpack_require__(440), - cacheHas = __webpack_require__(417); +/** + * These are private action types reserved by Redux. + * For any unknown actions, you must return the current state. + * If the current state is undefined, you must return the initial state. + * Do not reference these action types directly in your code. + */ +var randomString = function randomString() { + return Math.random().toString(36).substring(7).split('').join('.'); +}; -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMin = Math.min; +var ActionTypes = { + INIT: "@@redux/INIT" + randomString(), + REPLACE: "@@redux/REPLACE" + randomString(), + PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() { + return "@@redux/PROBE_UNKNOWN_ACTION" + randomString(); + } +}; /** - * The base implementation of methods like `_.intersection`, without support - * for iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of shared values. + * @param {any} obj The object to inspect. + * @returns {boolean} True if the argument appears to be a plain object. */ -function baseIntersection(arrays, iteratee, comparator) { - var includes = comparator ? arrayIncludesWith : arrayIncludes, - length = arrays[0].length, - othLength = arrays.length, - othIndex = othLength, - caches = Array(othLength), - maxLength = Infinity, - result = []; +function isPlainObject(obj) { + if (typeof obj !== 'object' || obj === null) return false; + var proto = obj; - while (othIndex--) { - var array = arrays[othIndex]; - if (othIndex && iteratee) { - array = arrayMap(array, baseUnary(iteratee)); - } - maxLength = nativeMin(array.length, maxLength); - caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) - ? new SetCache(othIndex && array) - : undefined; + while (Object.getPrototypeOf(proto) !== null) { + proto = Object.getPrototypeOf(proto); } - array = arrays[0]; - var index = -1, - seen = caches[0]; + return Object.getPrototypeOf(obj) === proto; +} - outer: - while (++index < length && result.length < maxLength) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; +// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of +function miniKindOf(val) { + if (val === void 0) return 'undefined'; + if (val === null) return 'null'; + var type = typeof val; - value = (comparator || value !== 0) ? value : 0; - if (!(seen - ? cacheHas(seen, computed) - : includes(result, computed, comparator) - )) { - othIndex = othLength; - while (--othIndex) { - var cache = caches[othIndex]; - if (!(cache - ? cacheHas(cache, computed) - : includes(arrays[othIndex], computed, comparator)) - ) { - continue outer; - } - } - if (seen) { - seen.push(computed); + switch (type) { + case 'boolean': + case 'string': + case 'number': + case 'symbol': + case 'function': + { + return type; } - result.push(value); - } } - return result; -} -module.exports = baseIntersection; + if (Array.isArray(val)) return 'array'; + if (isDate(val)) return 'date'; + if (isError(val)) return 'error'; + var constructorName = ctorName(val); + switch (constructorName) { + case 'Symbol': + case 'Promise': + case 'WeakMap': + case 'WeakSet': + case 'Map': + case 'Set': + return constructorName; + } // other -/***/ }), -/* 729 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var isArrayLikeObject = __webpack_require__(552); + return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); +} -/** - * Casts `value` to an empty array if it's not an array like object. - * - * @private - * @param {*} value The value to inspect. - * @returns {Array|Object} Returns the cast array-like object. - */ -function castArrayLikeObject(value) { - return isArrayLikeObject(value) ? value : []; +function ctorName(val) { + return typeof val.constructor === 'function' ? val.constructor.name : null; } -module.exports = castArrayLikeObject; +function isError(val) { + return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'; +} +function isDate(val) { + if (val instanceof Date) return true; + return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function'; +} -/***/ }), -/* 730 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function kindOf(val) { + var typeOfVal = typeof val; -var arrayPush = __webpack_require__(425), - baseFlatten = __webpack_require__(541), - copyArray = __webpack_require__(571), - isArray = __webpack_require__(55); + if (process.env.NODE_ENV !== 'production') { + typeOfVal = miniKindOf(val); + } + + return typeOfVal; +} /** - * Creates a new array concatenating `array` with any additional arrays - * and/or values. + * Creates a Redux store that holds the state tree. + * The only way to change the data in the store is to call `dispatch()` on it. * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to concatenate. - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. - * @example + * There should only be a single store in your app. To specify how different + * parts of the state tree respond to actions, you may combine several reducers + * into a single reducer function by using `combineReducers`. * - * var array = [1]; - * var other = _.concat(array, 2, [3], [[4]]); + * @param {Function} reducer A function that returns the next state tree, given + * the current state tree and the action to handle. * - * console.log(other); - * // => [1, 2, 3, [4]] + * @param {any} [preloadedState] The initial state. You may optionally specify it + * to hydrate the state from the server in universal apps, or to restore a + * previously serialized user session. + * If you use `combineReducers` to produce the root reducer function, this must be + * an object with the same shape as `combineReducers` keys. * - * console.log(array); - * // => [1] + * @param {Function} [enhancer] The store enhancer. You may optionally specify it + * to enhance the store with third-party capabilities such as middleware, + * time travel, persistence, etc. The only store enhancer that ships with Redux + * is `applyMiddleware()`. + * + * @returns {Store} A Redux store that lets you read the state, dispatch actions + * and subscribe to changes. */ -function concat() { - var length = arguments.length; - if (!length) { - return []; + +function createStore(reducer, preloadedState, enhancer) { + var _ref2; + + if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.'); } - var args = Array(length - 1), - array = arguments[0], - index = length; - while (index--) { - args[index - 1] = arguments[index]; + if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { + enhancer = preloadedState; + preloadedState = undefined; } - return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); -} -module.exports = concat; + if (typeof enhancer !== 'undefined') { + if (typeof enhancer !== 'function') { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(1) : "Expected the enhancer to be a function. Instead, received: '" + kindOf(enhancer) + "'"); + } + return enhancer(createStore)(reducer, preloadedState); + } -/***/ }), -/* 731 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (typeof reducer !== 'function') { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(2) : "Expected the root reducer to be a function. Instead, received: '" + kindOf(reducer) + "'"); + } -var baseOrderBy = __webpack_require__(732), - isArray = __webpack_require__(55); + var currentReducer = reducer; + var currentState = preloadedState; + var currentListeners = []; + var nextListeners = currentListeners; + var isDispatching = false; + /** + * This makes a shallow copy of currentListeners so we can use + * nextListeners as a temporary list while dispatching. + * + * This prevents any bugs around consumers calling + * subscribe/unsubscribe in the middle of a dispatch. + */ -/** - * This method is like `_.sortBy` except that it allows specifying the sort - * orders of the iteratees to sort by. If `orders` is unspecified, all values - * are sorted in ascending order. Otherwise, specify an order of "desc" for - * descending or "asc" for ascending sort order of corresponding values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] - * The iteratees to sort by. - * @param {string[]} [orders] The sort orders of `iteratees`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 34 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 36 } - * ]; - * - * // Sort by `user` in ascending order and by `age` in descending order. - * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - */ -function orderBy(collection, iteratees, orders, guard) { - if (collection == null) { - return []; - } - if (!isArray(iteratees)) { - iteratees = iteratees == null ? [] : [iteratees]; + function ensureCanMutateNextListeners() { + if (nextListeners === currentListeners) { + nextListeners = currentListeners.slice(); + } } - orders = guard ? undefined : orders; - if (!isArray(orders)) { - orders = orders == null ? [] : [orders]; + /** + * Reads the state tree managed by the store. + * + * @returns {any} The current state tree of your application. + */ + + + function getState() { + if (isDispatching) { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(3) : 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.'); + } + + return currentState; } - return baseOrderBy(collection, iteratees, orders); -} + /** + * Adds a change listener. It will be called any time an action is dispatched, + * and some part of the state tree may potentially have changed. You may then + * call `getState()` to read the current state tree inside the callback. + * + * You may call `dispatch()` from a change listener, with the following + * caveats: + * + * 1. The subscriptions are snapshotted just before every `dispatch()` call. + * If you subscribe or unsubscribe while the listeners are being invoked, this + * will not have any effect on the `dispatch()` that is currently in progress. + * However, the next `dispatch()` call, whether nested or not, will use a more + * recent snapshot of the subscription list. + * + * 2. The listener should not expect to see all state changes, as the state + * might have been updated multiple times during a nested `dispatch()` before + * the listener is called. It is, however, guaranteed that all subscribers + * registered before the `dispatch()` started will be called with the latest + * state by the time it exits. + * + * @param {Function} listener A callback to be invoked on every dispatch. + * @returns {Function} A function to remove this change listener. + */ -module.exports = orderBy; + function subscribe(listener) { + if (typeof listener !== 'function') { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(4) : "Expected the listener to be a function. Instead, received: '" + kindOf(listener) + "'"); + } -/***/ }), -/* 732 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (isDispatching) { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.'); + } -var arrayMap = __webpack_require__(398), - baseGet = __webpack_require__(359), - baseIteratee = __webpack_require__(401), - baseMap = __webpack_require__(733), - baseSortBy = __webpack_require__(734), - baseUnary = __webpack_require__(440), - compareMultiple = __webpack_require__(735), - identity = __webpack_require__(459), - isArray = __webpack_require__(55); + var isSubscribed = true; + ensureCanMutateNextListeners(); + nextListeners.push(listener); + return function unsubscribe() { + if (!isSubscribed) { + return; + } -/** - * The base implementation of `_.orderBy` without param guards. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {string[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. - */ -function baseOrderBy(collection, iteratees, orders) { - if (iteratees.length) { - iteratees = arrayMap(iteratees, function(iteratee) { - if (isArray(iteratee)) { - return function(value) { - return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); - } + if (isDispatching) { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.'); } - return iteratee; - }); - } else { - iteratees = [identity]; + + isSubscribed = false; + ensureCanMutateNextListeners(); + var index = nextListeners.indexOf(listener); + nextListeners.splice(index, 1); + currentListeners = null; + }; } + /** + * Dispatches an action. It is the only way to trigger a state change. + * + * The `reducer` function, used to create the store, will be called with the + * current state tree and the given `action`. Its return value will + * be considered the **next** state of the tree, and the change listeners + * will be notified. + * + * The base implementation only supports plain object actions. If you want to + * dispatch a Promise, an Observable, a thunk, or something else, you need to + * wrap your store creating function into the corresponding middleware. For + * example, see the documentation for the `redux-thunk` package. Even the + * middleware will eventually dispatch plain object actions using this method. + * + * @param {Object} action A plain object representing “what changedâ€. It is + * a good idea to keep actions serializable so you can record and replay user + * sessions, or use the time travelling `redux-devtools`. An action must have + * a `type` property which may not be `undefined`. It is a good idea to use + * string constants for action types. + * + * @returns {Object} For convenience, the same action object you dispatched. + * + * Note that, if you use a custom middleware, it may wrap `dispatch()` to + * return something else (for example, a Promise you can await). + */ - var index = -1; - iteratees = arrayMap(iteratees, baseUnary(baseIteratee)); - var result = baseMap(collection, function(value, key, collection) { - var criteria = arrayMap(iteratees, function(iteratee) { - return iteratee(value); - }); - return { 'criteria': criteria, 'index': ++index, 'value': value }; - }); + function dispatch(action) { + if (!isPlainObject(action)) { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(7) : "Actions must be plain objects. Instead, the actual type was: '" + kindOf(action) + "'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples."); + } - return baseSortBy(result, function(object, other) { - return compareMultiple(object, other, orders); - }); -} + if (typeof action.type === 'undefined') { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(8) : 'Actions may not have an undefined "type" property. You may have misspelled an action type string constant.'); + } -module.exports = baseOrderBy; + if (isDispatching) { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.'); + } + try { + isDispatching = true; + currentState = currentReducer(currentState, action); + } finally { + isDispatching = false; + } -/***/ }), -/* 733 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var listeners = currentListeners = nextListeners; -var baseEach = __webpack_require__(555), - isArrayLike = __webpack_require__(446); + for (var i = 0; i < listeners.length; i++) { + var listener = listeners[i]; + listener(); + } -/** - * The base implementation of `_.map` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function baseMap(collection, iteratee) { - var index = -1, - result = isArrayLike(collection) ? Array(collection.length) : []; + return action; + } + /** + * Replaces the reducer currently used by the store to calculate the state. + * + * You might need this if your app implements code splitting and you want to + * load some of the reducers dynamically. You might also need this if you + * implement a hot reloading mechanism for Redux. + * + * @param {Function} nextReducer The reducer for the store to use instead. + * @returns {void} + */ - baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); - return result; -} -module.exports = baseMap; + function replaceReducer(nextReducer) { + if (typeof nextReducer !== 'function') { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(10) : "Expected the nextReducer to be a function. Instead, received: '" + kindOf(nextReducer)); + } + currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT. + // Any reducers that existed in both the new and old rootReducer + // will receive the previous state. This effectively populates + // the new state tree with any relevant data from the old one. -/***/ }), -/* 734 */ -/***/ ((module) => { + dispatch({ + type: ActionTypes.REPLACE + }); + } + /** + * Interoperability point for observable/reactive libraries. + * @returns {observable} A minimal observable of state changes. + * For more information, see the observable proposal: + * https://github.com/tc39/proposal-observable + */ -/** - * The base implementation of `_.sortBy` which uses `comparer` to define the - * sort order of `array` and replaces criteria objects with their corresponding - * values. - * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. - */ -function baseSortBy(array, comparer) { - var length = array.length; - array.sort(comparer); - while (length--) { - array[length] = array[length].value; - } - return array; -} + function observable() { + var _ref; -module.exports = baseSortBy; + var outerSubscribe = subscribe; + return _ref = { + /** + * The minimal observable subscription method. + * @param {Object} observer Any object that can be used as an observer. + * The observer object should have a `next` method. + * @returns {subscription} An object with an `unsubscribe` method that can + * be used to unsubscribe the observable from the store, and prevent further + * emission of values from the observable. + */ + subscribe: function subscribe(observer) { + if (typeof observer !== 'object' || observer === null) { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(11) : "Expected the observer to be an object. Instead, received: '" + kindOf(observer) + "'"); + } + function observeState() { + if (observer.next) { + observer.next(getState()); + } + } + + observeState(); + var unsubscribe = outerSubscribe(observeState); + return { + unsubscribe: unsubscribe + }; + } + }, _ref[$$observable] = function () { + return this; + }, _ref; + } // When a store is created, an "INIT" action is dispatched so that every + // reducer returns their initial state. This effectively populates + // the initial state tree. -/***/ }), -/* 735 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var compareAscending = __webpack_require__(736); + dispatch({ + type: ActionTypes.INIT + }); + return _ref2 = { + dispatch: dispatch, + subscribe: subscribe, + getState: getState, + replaceReducer: replaceReducer + }, _ref2[$$observable] = observable, _ref2; +} /** - * Used by `_.orderBy` to compare multiple properties of a value to another - * and stable sort them. - * - * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, - * specify an order of "desc" for descending or "asc" for ascending sort order - * of corresponding values. + * Prints a warning in the console if it exists. * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {boolean[]|string[]} orders The order to sort by for each property. - * @returns {number} Returns the sort order indicator for `object`. + * @param {String} message The warning message. + * @returns {void} */ -function compareMultiple(object, other, orders) { - var index = -1, - objCriteria = object.criteria, - othCriteria = other.criteria, - length = objCriteria.length, - ordersLength = orders.length; - - while (++index < length) { - var result = compareAscending(objCriteria[index], othCriteria[index]); - if (result) { - if (index >= ordersLength) { - return result; - } - var order = orders[index]; - return result * (order == 'desc' ? -1 : 1); - } +function warning(message) { + /* eslint-disable no-console */ + if (typeof console !== 'undefined' && typeof console.error === 'function') { + console.error(message); } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to provide the same value for - // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 - // for more details. - // - // This also ensures a stable sort in V8 and other engines. - // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; -} + /* eslint-enable no-console */ -module.exports = compareMultiple; + try { + // This error was thrown as a convenience so that if you enable + // "break on all exceptions" in your console, + // it would pause the execution at this line. + throw new Error(message); + } catch (e) {} // eslint-disable-line no-empty -/***/ }), -/* 736 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +} -var isSymbol = __webpack_require__(362); +function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) { + var reducerKeys = Object.keys(reducers); + var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer'; -/** - * Compares values to sort them in ascending order. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {number} Returns the sort order indicator for `value`. - */ -function compareAscending(value, other) { - if (value !== other) { - var valIsDefined = value !== undefined, - valIsNull = value === null, - valIsReflexive = value === value, - valIsSymbol = isSymbol(value); + if (reducerKeys.length === 0) { + return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.'; + } - var othIsDefined = other !== undefined, - othIsNull = other === null, - othIsReflexive = other === other, - othIsSymbol = isSymbol(other); + if (!isPlainObject(inputState)) { + return "The " + argumentName + " has unexpected type of \"" + kindOf(inputState) + "\". Expected argument to be an object with the following " + ("keys: \"" + reducerKeys.join('", "') + "\""); + } - if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || - (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || - (valIsNull && othIsDefined && othIsReflexive) || - (!valIsDefined && othIsReflexive) || - !valIsReflexive) { - return 1; - } - if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || - (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || - (othIsNull && valIsDefined && valIsReflexive) || - (!othIsDefined && valIsReflexive) || - !othIsReflexive) { - return -1; - } + var unexpectedKeys = Object.keys(inputState).filter(function (key) { + return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key]; + }); + unexpectedKeys.forEach(function (key) { + unexpectedKeyCache[key] = true; + }); + if (action && action.type === ActionTypes.REPLACE) return; + + if (unexpectedKeys.length > 0) { + return "Unexpected " + (unexpectedKeys.length > 1 ? 'keys' : 'key') + " " + ("\"" + unexpectedKeys.join('", "') + "\" found in " + argumentName + ". ") + "Expected to find one of the known reducer keys instead: " + ("\"" + reducerKeys.join('", "') + "\". Unexpected keys will be ignored."); } - return 0; } -module.exports = compareAscending; - +function assertReducerShape(reducers) { + Object.keys(reducers).forEach(function (key) { + var reducer = reducers[key]; + var initialState = reducer(undefined, { + type: ActionTypes.INIT + }); -/***/ }), -/* 737 */ -/***/ ((module, exports) => { + if (typeof initialState === 'undefined') { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(12) : "The slice reducer for key \"" + key + "\" returned undefined during initialization. " + "If the state passed to the reducer is undefined, you must " + "explicitly return the initial state. The initial state may " + "not be undefined. If you don't want to set a value for this reducer, " + "you can use null instead of undefined."); + } -/* - * Sift 3.x + if (typeof reducer(undefined, { + type: ActionTypes.PROBE_UNKNOWN_ACTION() + }) === 'undefined') { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(13) : "The slice reducer for key \"" + key + "\" returned undefined when probed with a random type. " + ("Don't try to handle '" + ActionTypes.INIT + "' or other actions in \"redux/*\" ") + "namespace. They are considered private. Instead, you must return the " + "current state for any unknown actions, unless it is undefined, " + "in which case you must return the initial state, regardless of the " + "action type. The initial state may not be undefined, but can be null."); + } + }); +} +/** + * Turns an object whose values are different reducer functions, into a single + * reducer function. It will call every child reducer, and gather their results + * into a single state object, whose keys correspond to the keys of the passed + * reducer functions. * - * Copryright 2015, Craig Condon - * Licensed under MIT + * @param {Object} reducers An object whose values correspond to different + * reducer functions that need to be combined into one. One handy way to obtain + * it is to use ES6 `import * as reducers` syntax. The reducers may never return + * undefined for any action. Instead, they should return their initial state + * if the state passed to them was undefined, and the current state for any + * unrecognized action. * - * Filter JavaScript objects with mongodb queries + * @returns {Function} A reducer function that invokes every reducer inside the + * passed object, and builds a state object with the same shape. */ -(function() { - - 'use strict'; - - /** - */ - - function isFunction(value) { - return typeof value === 'function'; - } - - /** - */ - function isArray(value) { - return Object.prototype.toString.call(value) === '[object Array]'; - } +function combineReducers(reducers) { + var reducerKeys = Object.keys(reducers); + var finalReducers = {}; - /** - */ + for (var i = 0; i < reducerKeys.length; i++) { + var key = reducerKeys[i]; - function comparable(value) { - if (value instanceof Date) { - return value.getTime(); - } else if (isArray(value)) { - return value.map(comparable); - } else if (value && typeof value.toJSON === 'function') { - return value.toJSON(); - } else { - return value; + if (process.env.NODE_ENV !== 'production') { + if (typeof reducers[key] === 'undefined') { + warning("No reducer provided for key \"" + key + "\""); + } } - } - - function get(obj, key) { - return isFunction(obj.get) ? obj.get(key) : obj[key]; - } - - /** - */ - function or(validator) { - return function(a, b) { - if (!isArray(b) || !b.length) { - return validator(a, b); - } - for (var i = 0, n = b.length; i < n; i++) { - if (validator(a, get(b,i))) return true; - } - return false; + if (typeof reducers[key] === 'function') { + finalReducers[key] = reducers[key]; } } - /** - */ + var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same + // keys multiple times. - function and(validator) { - return function(a, b) { - if (!isArray(b) || !b.length) { - return validator(a, b); - } - for (var i = 0, n = b.length; i < n; i++) { - if (!validator(a, get(b, i))) return false; - } - return true; - }; - } + var unexpectedKeyCache; - function validate(validator, b, k, o) { - return validator.v(validator.a, b, k, o); + if (process.env.NODE_ENV !== 'production') { + unexpectedKeyCache = {}; } - var OPERATORS = { - - /** - */ - - $eq: or(function(a, b) { - return a(b); - }), + var shapeAssertionError; - /** - */ + try { + assertReducerShape(finalReducers); + } catch (e) { + shapeAssertionError = e; + } - $ne: and(function(a, b) { - return !a(b); - }), + return function combination(state, action) { + if (state === void 0) { + state = {}; + } - /** - */ + if (shapeAssertionError) { + throw shapeAssertionError; + } - $gt: or(function(a, b) { - return sift.compare(comparable(b), a) > 0; - }), + if (process.env.NODE_ENV !== 'production') { + var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache); - /** - */ + if (warningMessage) { + warning(warningMessage); + } + } - $gte: or(function(a, b) { - return sift.compare(comparable(b), a) >= 0; - }), + var hasChanged = false; + var nextState = {}; - /** - */ + for (var _i = 0; _i < finalReducerKeys.length; _i++) { + var _key = finalReducerKeys[_i]; + var reducer = finalReducers[_key]; + var previousStateForKey = state[_key]; + var nextStateForKey = reducer(previousStateForKey, action); - $lt: or(function(a, b) { - return sift.compare(comparable(b), a) < 0; - }), + if (typeof nextStateForKey === 'undefined') { + var actionType = action && action.type; + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(14) : "When called with an action of type " + (actionType ? "\"" + String(actionType) + "\"" : '(unknown type)') + ", the slice reducer for key \"" + _key + "\" returned undefined. " + "To ignore an action, you must explicitly return the previous state. " + "If you want this reducer to hold no value, you can return null instead of undefined."); + } - /** - */ + nextState[_key] = nextStateForKey; + hasChanged = hasChanged || nextStateForKey !== previousStateForKey; + } - $lte: or(function(a, b) { - return sift.compare(comparable(b), a) <= 0; - }), + hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length; + return hasChanged ? nextState : state; + }; +} - /** - */ +function bindActionCreator(actionCreator, dispatch) { + return function () { + return dispatch(actionCreator.apply(this, arguments)); + }; +} +/** + * Turns an object whose values are action creators, into an object with the + * same keys, but with every function wrapped into a `dispatch` call so they + * may be invoked directly. This is just a convenience method, as you can call + * `store.dispatch(MyActionCreators.doSomething())` yourself just fine. + * + * For convenience, you can also pass an action creator as the first argument, + * and get a dispatch wrapped function in return. + * + * @param {Function|Object} actionCreators An object whose values are action + * creator functions. One handy way to obtain it is to use ES6 `import * as` + * syntax. You may also pass a single function. + * + * @param {Function} dispatch The `dispatch` function available on your Redux + * store. + * + * @returns {Function|Object} The object mimicking the original object, but with + * every action creator wrapped into the `dispatch` call. If you passed a + * function as `actionCreators`, the return value will also be a single + * function. + */ - $mod: or(function(a, b) { - return b % a[0] == a[1]; - }), - /** - */ +function bindActionCreators(actionCreators, dispatch) { + if (typeof actionCreators === 'function') { + return bindActionCreator(actionCreators, dispatch); + } - $in: function(a, b) { + if (typeof actionCreators !== 'object' || actionCreators === null) { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(16) : "bindActionCreators expected an object or a function, but instead received: '" + kindOf(actionCreators) + "'. " + "Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?"); + } - if (b instanceof Array) { - for (var i = b.length; i--;) { - if (~a.indexOf(comparable(get(b, i)))) { - return true; - } - } - } else { - var comparableB = comparable(b); - if (comparableB === b && typeof b === 'object') { - for (var i = a.length; i--;) { - if (String(a[i]) === String(b) && String(b) !== '[object Object]') { - return true; - } - } - } + var boundActionCreators = {}; - /* - Handles documents that are undefined, whilst also - having a 'null' element in the parameters to $in. - */ - if (typeof comparableB == 'undefined') { - for (var i = a.length; i--;) { - if (a[i] == null) { - return true; - } - } - } + for (var key in actionCreators) { + var actionCreator = actionCreators[key]; - /* - Handles the case of {'field': {$in: [/regexp1/, /regexp2/, ...]}} - */ - for (var i = a.length; i--;) { - var validator = createRootValidator(get(a, i), undefined); - var result = validate(validator, b, i, a); - if ((result) && (String(result) !== '[object Object]') && (String(b) !== '[object Object]')) { - return true; - } - } + if (typeof actionCreator === 'function') { + boundActionCreators[key] = bindActionCreator(actionCreator, dispatch); + } + } - return !!~a.indexOf(comparableB); - } + return boundActionCreators; +} - return false; - }, +/** + * Composes single-argument functions from right to left. The rightmost + * function can take multiple arguments as it provides the signature for + * the resulting composite function. + * + * @param {...Function} funcs The functions to compose. + * @returns {Function} A function obtained by composing the argument functions + * from right to left. For example, compose(f, g, h) is identical to doing + * (...args) => f(g(h(...args))). + */ +function compose() { + for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) { + funcs[_key] = arguments[_key]; + } - /** - */ + if (funcs.length === 0) { + return function (arg) { + return arg; + }; + } - $nin: function(a, b, k, o) { - return !OPERATORS.$in(a, b, k, o); - }, + if (funcs.length === 1) { + return funcs[0]; + } - /** - */ + return funcs.reduce(function (a, b) { + return function () { + return a(b.apply(void 0, arguments)); + }; + }); +} - $not: function(a, b, k, o) { - return !validate(a, b, k, o); - }, +/** + * Creates a store enhancer that applies middleware to the dispatch method + * of the Redux store. This is handy for a variety of tasks, such as expressing + * asynchronous actions in a concise manner, or logging every action payload. + * + * See `redux-thunk` package as an example of the Redux middleware. + * + * Because middleware is potentially asynchronous, this should be the first + * store enhancer in the composition chain. + * + * Note that each middleware will be given the `dispatch` and `getState` functions + * as named arguments. + * + * @param {...Function} middlewares The middleware chain to be applied. + * @returns {Function} A store enhancer applying the middleware. + */ - /** - */ +function applyMiddleware() { + for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) { + middlewares[_key] = arguments[_key]; + } - $type: function(a, b) { - return b != void 0 ? b instanceof a || b.constructor == a : false; - }, + return function (createStore) { + return function () { + var store = createStore.apply(void 0, arguments); - /** - */ + var _dispatch = function dispatch() { + throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.'); + }; - $all: function(a, b, k, o) { - return OPERATORS.$and(a, b, k, o); - }, + var middlewareAPI = { + getState: store.getState, + dispatch: function dispatch() { + return _dispatch.apply(void 0, arguments); + } + }; + var chain = middlewares.map(function (middleware) { + return middleware(middlewareAPI); + }); + _dispatch = compose.apply(void 0, chain)(store.dispatch); + return (0,_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, store), {}, { + dispatch: _dispatch + }); + }; + }; +} - /** - */ +/* + * This is a dummy function to check if the function name has been altered by minification. + * If the function has been minified and NODE_ENV !== 'production', warn the user. + */ - $size: function(a, b) { - return b ? a === b.length : false; - }, +function isCrushed() {} - /** - */ +if (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') { + warning('You are currently using minified code outside of NODE_ENV === "production". ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or setting mode to production in webpack (https://webpack.js.org/concepts/mode/) ' + 'to ensure you have the correct code for your production build.'); +} - $or: function(a, b, k, o) { - for (var i = 0, n = a.length; i < n; i++) if (validate(get(a, i), b, k, o)) return true; - return false; - }, - /** - */ - $nor: function(a, b, k, o) { - return !OPERATORS.$or(a, b, k, o); - }, - /** - */ +/***/ }), +/* 707 */ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - $and: function(a, b, k, o) { - for (var i = 0, n = a.length; i < n; i++) { - if (!validate(get(a, i), b, k, o)) { - return false; - } - } - return true; - }, +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ _objectSpread2) +/* harmony export */ }); +/* harmony import */ var _defineProperty_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(708); - /** - */ - $regex: or(function(a, b) { - return typeof b === 'string' && a.test(b); - }), +function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); - /** - */ + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); - $where: function(a, b, k, o) { - return a.call(b, b, k, o); - }, + if (enumerableOnly) { + symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + } - /** - */ + keys.push.apply(keys, symbols); + } - $elemMatch: function(a, b, k, o) { - if (isArray(b)) { - return !!~search(b, a); - } - return validate(a, b, k, o); - }, + return keys; +} - /** - */ +function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; - $exists: function(a, b, k, o) { - return o.hasOwnProperty(k) === a; + if (i % 2) { + ownKeys(Object(source), true).forEach(function (key) { + (0,_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__["default"])(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(Object(source)).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); } - }; + } - /** - */ + return target; +} - var prepare = { +/***/ }), +/* 708 */ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - /** - */ +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ _defineProperty) +/* harmony export */ }); +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } - $eq: function(a) { + return obj; +} - if (a instanceof RegExp) { - return function(b) { - return typeof b === 'string' && a.test(b); - }; - } else if (a instanceof Function) { - return a; - } else if (isArray(a) && !a.length) { - // Special case of a == [] - return function(b) { - return (isArray(b) && !b.length); - }; - } else if (a === null){ - return function(b){ - //will match both null and undefined - return b == null; +/***/ }), +/* 709 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +function createThunkMiddleware(extraArgument) { + return function (_ref) { + var dispatch = _ref.dispatch, + getState = _ref.getState; + return function (next) { + return function (action) { + if (typeof action === 'function') { + return action(dispatch, getState, extraArgument); } - } - return function(b) { - return sift.compare(comparable(b), a) === 0; + return next(action); }; - }, - - /** - */ + }; + }; +} - $ne: function(a) { - return prepare.$eq(a); - }, +var thunk = createThunkMiddleware(); +thunk.withExtraArgument = createThunkMiddleware; - /** - */ +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (thunk); - $and: function(a) { - return a.map(parse); - }, +/***/ }), +/* 710 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - /** - */ +"use strict"; - $all: function(a) { - return prepare.$and(a); - }, - /** - */ +var _interopRequireDefault = __webpack_require__(524); - $or: function(a) { - return a.map(parse); - }, +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.extractAndMergeDocument = exports.getCollectionFromSlice = exports.getDocumentFromSlice = exports["default"] = exports.mergeDocumentsWithRelationships = void 0; - /** - */ +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); - $nor: function(a) { - return a.map(parse); - }, +var _keyBy = _interopRequireDefault(__webpack_require__(711)); - /** - */ +var _get = _interopRequireDefault(__webpack_require__(370)); - $not: function(a) { - return parse(a); - }, +var _isEqual = _interopRequireDefault(__webpack_require__(658)); - /** - */ +var _omit = _interopRequireDefault(__webpack_require__(625)); - $regex: function(a, query) { - return new RegExp(a, query.$options); - }, +var _logger = _interopRequireDefault(__webpack_require__(715)); - /** - */ +var _queries = __webpack_require__(735); - $where: function(a) { - return typeof a === 'string' ? new Function('obj', 'return ' + a) : a; - }, +var _dsl = __webpack_require__(619); - /** - */ +var _mutations = __webpack_require__(750); - $elemMatch: function(a) { - return parse(a); - }, +var _types = __webpack_require__(622); - /** - */ +var _helpers = __webpack_require__(751); - $exists: function(a) { - return !!a; - } - }; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - /** - */ +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - function search(array, validator) { +var storeDocument = function storeDocument(state, document) { + var type = document._type; - for (var i = 0; i < array.length; i++) { - var result = get(array, i); - if (validate(validator, get(array, i))) { - return i; - } + if (!type) { + if (process.env.NODE_ENV !== 'production') { + _logger.default.info('Document without _type', document); } - return -1; + throw new Error('Document without _type'); } - /** - */ + if (!(0, _helpers.properId)(document)) { + if (process.env.NODE_ENV !== 'production') { + _logger.default.info('Document without id', document); + } - function createValidator(a, validate) { - return { a: a, v: validate }; + throw new Error('Document without id'); } - /** - */ - - function nestedValidator(a, b) { - var values = []; - findValues(b, a.k, 0, b, values); - - if (values.length === 1) { - var first = values[0]; - return validate(a.nv, first[0], first[1], first[2]); - } + var existingDoc = (0, _get.default)(state, [type, (0, _helpers.properId)(document)]); - // If the query contains $ne, need to test all elements ANDed together - var inclusive = a && a.q && typeof a.q.$ne !== 'undefined'; - var allValid = inclusive; - for (var i = 0; i < values.length; i++) { - var result = values[i]; - var isValid = validate(a.nv, result[0], result[1], result[2]); - if (inclusive) { - allValid &= isValid; - } else { - allValid |= isValid; - } - } - return allValid; + if ((0, _isEqual.default)(existingDoc, document)) { + return state; + } else { + return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, type, _objectSpread(_objectSpread({}, state[type]), {}, (0, _defineProperty2.default)({}, (0, _helpers.properId)(document), mergeDocumentsWithRelationships(existingDoc, document))))); } +}; + +var mergeDocumentsWithRelationships = function mergeDocumentsWithRelationships() { + var prevDocument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var nextDocument = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; /** + * @type {CozyClientDocument} */ + var merged = _objectSpread(_objectSpread({}, prevDocument), nextDocument); - function findValues(current, keypath, index, object, values) { + if (prevDocument.relationships || nextDocument.relationships) merged.relationships = _objectSpread(_objectSpread({}, prevDocument.relationships), nextDocument.relationships); + return merged; +}; // reducer - if (index === keypath.length || current == void 0) { - values.push([current, keypath[index - 1], object]); - return; - } +exports.mergeDocumentsWithRelationships = mergeDocumentsWithRelationships; - var k = get(keypath, index); +var documents = function documents() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var action = arguments.length > 1 ? arguments[1] : undefined; - // ensure that if current is an array, that the current key - // is NOT an array index. This sort of thing needs to work: - // sift({'foo.0':42}, [{foo: [42]}]); - if (isArray(current) && isNaN(Number(k))) { - for (var i = 0, n = current.length; i < n; i++) { - findValues(get(current, i), keypath, index, current, values); - } - } else { - findValues(get(current, k), keypath, index + 1, current, values); - } + if (!(0, _queries.isReceivingData)(action) && !(0, _mutations.isReceivingMutationResult)(action)) { + return state; } - /** - */ - - function createNestedValidator(keypath, a, q) { - return { a: { k: keypath, nv: a, q: q }, v: nestedValidator }; + if (action && action.definition && action.definition.mutationType === _dsl.MutationTypes.DELETE_DOCUMENT) { + var docId = action.definition.document._id; + var _type = action.definition.document._type; + return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, _type, (0, _omit.default)(state[_type], docId))); } - /** - * flatten the query - */ + var _action$response = action.response, + data = _action$response.data, + included = _action$response.included; + if (!data || Array.isArray(data) && data.length === 0) return state; + var updatedStateWithIncluded = included ? included.reduce(storeDocument, state) : state; - function isVanillaObject(value) { - return value && value.constructor === Object; + if (!Array.isArray(data)) { + return storeDocument(updatedStateWithIncluded, data); } - function parse(query) { - query = comparable(query); + return extractAndMergeDocument(data, updatedStateWithIncluded); +}; - if (!query || !isVanillaObject(query)) { // cross browser support - query = { $eq: query }; - } +var _default = documents; // selector - var validators = []; +exports["default"] = _default; - for (var key in query) { - var a = query[key]; +var getDocumentFromSlice = function getDocumentFromSlice() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var doctype = arguments.length > 1 ? arguments[1] : undefined; + var id = arguments.length > 2 ? arguments[2] : undefined; - if (key === '$options') { - continue; - } + if (!doctype) { + throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined doctype'); + } - if (OPERATORS[key]) { - if (prepare[key]) a = prepare[key](a, query); - validators.push(createValidator(comparable(a), OPERATORS[key])); - } else { + if (!id) { + throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined id'); + } - if (key.charCodeAt(0) === 36) { - throw new Error('Unknown operation ' + key); - } - validators.push(createNestedValidator(key.split('.'), parse(a), a)); - } + if (!state[doctype]) { + if (process.env.NODE_ENV !== 'production') { + _logger.default.info("getDocumentFromSlice: ".concat(doctype, " is absent from the store's documents. State is"), state); } - return validators.length === 1 ? validators[0] : createValidator(validators, OPERATORS.$and); + return null; + } else if (!state[doctype][id]) { + if (process.env.NODE_ENV !== 'production') { + _logger.default.info("getDocumentFromSlice: ".concat(doctype, ":").concat(id, " is absent from the store documents. State is"), state); + } + + return null; } - /** - */ + return state[doctype][id]; +}; - function createRootValidator(query, getter) { - var validator = parse(query); - if (getter) { - validator = { - a: validator, - v: function(a, b, k, o) { - return validate(a, getter(b), k, o); - } - }; +exports.getDocumentFromSlice = getDocumentFromSlice; + +var getCollectionFromSlice = function getCollectionFromSlice() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var doctype = arguments.length > 1 ? arguments[1] : undefined; + + if (!doctype) { + throw new Error('getDocumentFromSlice: Cannot retrieve document with undefined doctype'); + } + + if (!state[doctype]) { + if (process.env.NODE_ENV !== 'production') { + _logger.default.info("getCollectionFromSlice: ".concat(doctype, " is absent from the store documents. State is"), state); } - return validator; + + return null; } - /** - */ + return Object.values(state[doctype]); +}; +/* + This method has been created in order to get a returned object + in `data` with the full set on information coming potentially from + `included` - function sift(query, array, getter) { + This method should be somewhere else. The `document` shall not be + dealt with included / data and so on. - if (isFunction(array)) { - getter = array; - array = void 0; - } + This method takes `data` and `included` and merge both sources + together. It should be always up-to-date. The returned object + will be as full of information as it can be. +*/ - var validator = createRootValidator(query, getter); - function filter(b, k, o) { - return validate(validator, b, k, o); - } +exports.getCollectionFromSlice = getCollectionFromSlice; - if (array) { - return array.filter(filter); - } +var extractAndMergeDocument = function extractAndMergeDocument(data, updatedStateWithIncluded) { + var doctype = data[0]._type; - return filter; + if (!doctype) { + _logger.default.info('Document without _type', data[0]); + + throw new Error('Document without _type'); } - /** - */ + var sortedData = (0, _keyBy.default)(data, _helpers.properId); + var mergedData = Object.assign({}, updatedStateWithIncluded); + mergedData[doctype] = Object.assign({}, updatedStateWithIncluded[doctype]); + Object.values(sortedData).map(function (data) { + var id = (0, _helpers.properId)(data); - sift.use = function(plugin) { - if (isFunction(plugin)) return plugin(sift); - for (var key in plugin) { - /* istanbul ignore else */ - if (key.charCodeAt(0) === 36) { - OPERATORS[key] = plugin[key]; - } + if (mergedData[doctype][id]) { + mergedData[doctype][id] = _objectSpread(_objectSpread({}, mergedData[doctype][id]), data); + } else { + mergedData[doctype][id] = data; } - }; + }); + return mergedData; +}; - /** - */ +exports.extractAndMergeDocument = extractAndMergeDocument; - sift.indexOf = function(query, array, getter) { - return search(array, createRootValidator(query, getter)); - }; +/***/ }), +/* 711 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - */ +var baseAssignValue = __webpack_require__(546), + createAggregator = __webpack_require__(712); - sift.compare = function(a, b) { - if(a===b) return 0; - if(typeof a === typeof b) { - if (a > b) { - return 1; - } - if (a < b) { - return -1; - } - } +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ +var keyBy = createAggregator(function(result, value, key) { + baseAssignValue(result, key, value); +}); + +module.exports = keyBy; + + +/***/ }), +/* 712 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var arrayAggregator = __webpack_require__(713), + baseAggregator = __webpack_require__(714), + baseIteratee = __webpack_require__(413), + isArray = __webpack_require__(55); + +/** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ +function createAggregator(setter, initializer) { + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, baseIteratee(iteratee, 2), accumulator); }; +} - /* istanbul ignore next */ - if ( true && typeof module.exports !== 'undefined') { - Object.defineProperty(exports, "__esModule", ({ - value: true - })); +module.exports = createAggregator; - module.exports = sift; - exports["default"] = module.exports["default"] = sift; - } - /* istanbul ignore next */ - if (typeof window !== 'undefined') { - window.sift = sift; +/***/ }), +/* 713 */ +/***/ ((module) => { + +/** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ +function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); } -})(); + return accumulator; +} + +module.exports = arrayAggregator; /***/ }), -/* 738 */ +/* 714 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseEach = __webpack_require__(567); + +/** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ +function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; +} + +module.exports = baseAggregator; + + +/***/ }), +/* 715 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.receiveMutationError = exports.receiveMutationResult = exports.initMutation = exports.isReceivingMutationResult = exports.isMutationAction = void 0; +exports["default"] = void 0; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _minilog = _interopRequireDefault(__webpack_require__(716)); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +var logger = (0, _minilog.default)('cozy-client'); -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +_minilog.default.suggest.deny('cozy-client', 'info'); -var INIT_MUTATION = 'INIT_MUTATION'; -var RECEIVE_MUTATION_RESULT = 'RECEIVE_MUTATION_RESULT'; -var RECEIVE_MUTATION_ERROR = 'RECEIVE_MUTATION_ERROR'; +var _default = logger; +exports["default"] = _default; -var isMutationAction = function isMutationAction(action) { - return [INIT_MUTATION, RECEIVE_MUTATION_RESULT, RECEIVE_MUTATION_ERROR].indexOf(action.type) !== -1; +/***/ }), +/* 716 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +module.exports = __webpack_require__(717); + +var consoleLogger = __webpack_require__(720); + +// if we are running inside Electron then use the web version of console.js +var isElectron = (typeof window !== 'undefined' && window.process && window.process.type === 'renderer'); +if (isElectron) { + consoleLogger = (__webpack_require__(729).minilog); +} + +// intercept the pipe method and transparently wrap the stringifier, if the +// destination is a Node core stream + +module.exports.Stringifier = __webpack_require__(733); + +var oldPipe = module.exports.pipe; +module.exports.pipe = function(dest) { + if(dest instanceof __webpack_require__(82)) { + return oldPipe.call(module.exports, new (module.exports.Stringifier)).pipe(dest); + } else { + return oldPipe.call(module.exports, dest); + } }; -exports.isMutationAction = isMutationAction; +module.exports.defaultBackend = consoleLogger; +module.exports.defaultFormatter = consoleLogger.formatMinilog; -var isReceivingMutationResult = function isReceivingMutationResult(action) { - return action.type === RECEIVE_MUTATION_RESULT; -}; // actions +module.exports.backends = { + redis: __webpack_require__(734), + nodeConsole: consoleLogger, + console: consoleLogger +}; -exports.isReceivingMutationResult = isReceivingMutationResult; +/***/ }), +/* 717 */ +/***/ ((module, exports, __webpack_require__) => { -var initMutation = function initMutation(mutationId, definition) { - return { - type: INIT_MUTATION, - mutationId: mutationId, - definition: definition - }; +var Transform = __webpack_require__(718), + Filter = __webpack_require__(719); + +var log = new Transform(), + slice = Array.prototype.slice; + +exports = module.exports = function create(name) { + var o = function() { log.write(name, undefined, slice.call(arguments)); return o; }; + o.debug = function() { log.write(name, 'debug', slice.call(arguments)); return o; }; + o.info = function() { log.write(name, 'info', slice.call(arguments)); return o; }; + o.warn = function() { log.write(name, 'warn', slice.call(arguments)); return o; }; + o.error = function() { log.write(name, 'error', slice.call(arguments)); return o; }; + o.group = function() { log.write(name, 'group', slice.call(arguments)); return o; }; + o.groupEnd = function() { log.write(name, 'groupEnd', slice.call(arguments)); return o; }; + o.log = o.debug; // for interface compliance with Node and browser consoles + o.suggest = exports.suggest; + o.format = log.format; + return o; }; -exports.initMutation = initMutation; +// filled in separately +exports.defaultBackend = exports.defaultFormatter = null; -var receiveMutationResult = function receiveMutationResult(mutationId, response) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var definition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; - return _objectSpread(_objectSpread({ - type: RECEIVE_MUTATION_RESULT, - mutationId: mutationId, - response: response - }, options), {}, { - definition: definition - }); +exports.pipe = function(dest) { + return log.pipe(dest); }; -exports.receiveMutationResult = receiveMutationResult; +exports.end = exports.unpipe = exports.disable = function(from) { + return log.unpipe(from); +}; -var receiveMutationError = function receiveMutationError(mutationId, error) { - var definition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - return { - type: RECEIVE_MUTATION_ERROR, - mutationId: mutationId, - error: error, - definition: definition - }; +exports.Transform = Transform; +exports.Filter = Filter; +// this is the default filter that's applied when .enable() is called normally +// you can bypass it completely and set up your own pipes +exports.suggest = new Filter(); + +exports.enable = function() { + if(exports.defaultFormatter) { + return log.pipe(exports.suggest) // filter + .pipe(exports.defaultFormatter) // formatter + .pipe(exports.defaultBackend); // backend + } + return log.pipe(exports.suggest) // filter + .pipe(exports.defaultBackend); // formatter }; -exports.receiveMutationError = receiveMutationError; + /***/ }), -/* 739 */ -/***/ ((__unused_webpack_module, exports) => { +/* 718 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; +var microee = __webpack_require__(570); +// Implements a subset of Node's stream.Transform - in a cross-platform manner. +function Transform() {} -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.properId = void 0; +microee.mixin(Transform); -var properId = function properId(doc) { - return doc.id || doc._id; +// The write() signature is different from Node's +// --> makes it much easier to work with objects in logs. +// One of the lessons from v1 was that it's better to target +// a good browser rather than the lowest common denominator +// internally. +// If you want to use external streams, pipe() to ./stringify.js first. +Transform.prototype.write = function(name, level, args) { + this.emit('item', name, level, args); }; -exports.properId = properId; - -/***/ }), -/* 740 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +Transform.prototype.end = function() { + this.emit('end'); + this.removeAllListeners(); +}; -"use strict"; +Transform.prototype.pipe = function(dest) { + var s = this; + // prevent double piping + s.emit('unpipe', dest); + // tell the dest that it's being piped to + dest.emit('pipe', s); + function onItem() { + dest.write.apply(dest, Array.prototype.slice.call(arguments)); + } + function onEnd() { !dest._isStdio && dest.end(); } -var _interopRequireDefault = __webpack_require__(512); + s.on('item', onItem); + s.on('end', onEnd); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + s.when('unpipe', function(from) { + var match = (from === dest) || typeof from == 'undefined'; + if(match) { + s.removeListener('item', onItem); + s.removeListener('end', onEnd); + dest.emit('unpipe'); + } + return match; + }); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + return dest; +}; -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +Transform.prototype.unpipe = function(from) { + this.emit('unpipe', from); + return this; +}; -var _types = __webpack_require__(610); +Transform.prototype.format = function(dest) { + throw new Error([ + 'Warning: .format() is deprecated in Minilog v2! Use .pipe() instead. For example:', + 'var Minilog = require(\'minilog\');', + 'Minilog', + ' .pipe(Minilog.backends.console.formatClean)', + ' .pipe(Minilog.backends.console);'].join('\n')); +}; -var _dsl = __webpack_require__(607); +Transform.mixin = function(dest) { + var o = Transform.prototype, k; + for (k in o) { + o.hasOwnProperty(k) && (dest.prototype[k] = o[k]); + } +}; -/** - * Associations are used by components to access related store documents that are - * linked in a document. They are also responsible for building the `QueryDefinition` that is - * used by the client to automatically fetch relationship data. - * - * Hydrated documents used by components come with Association instances. - * - * @interface - * - * @description - * Example: The schema defines an `author` relationship : - * - * ```js - * const BOOK_SCHEMA = { - * relationships: { - * author: 'has-one' - * } - * } - * ``` - * - * Hydrated `books` will have the `author` association instance under the `author` key. - * Accessing `hydratedBook.author.data` gives you the author from the store, for example : - * - * ```json - * { - * "name": "St-Exupery", - * "firstName": "Antoine", - * "_id": "antoine" - * } - * ``` - * - * It is the responsibility of the relationship to decide how the relationship data is stored. - * For example, here since we use the default `has-one` relationship, the relationship data - * is stored in the `relationships` attribute of the original document (in our case here, our book - * would be - * - * ```json - * { - * "title": "Le petit prince", - * "relationships": { - * "author": { - * "data": { - * "doctype": "io.cozy.authors", - * "_id": "antoine" - * } - * } - * } - * } - * ``` - * - * In the case of an "in-place" relationship, the relationship data is stored directly under the attribute named - * by the relationship (in our case `author`). Our book would be - * - * ```json - * { - * "title": "Le petit prince", - * "author": "antoine" - * } - * ``` - * - * --- - * - * Each different type of Association may change: - * - * - `get raw`: how the relationship data is stored (either as per the JSON API spec or - * in a custom way) - * - `get data`: how the store documents are then fetched from the store to be added to - * the hydrated document (.data method). View components will access - * `hydratedDoc[relationshipName].data`. - * - `get query`: how to build the query to fetch related documents - * - */ -var Association = /*#__PURE__*/function () { - /** - * @param {object} target - Original object containing raw data - * @param {string} name - Attribute under which the association is stored - * @param {string} doctype - Doctype of the documents managed by the association - * @param {object} options - Options passed from the client - * @param {Function} options.get - Get a document from the store - * @param {Function} options.query - Execute client query - * @param {Function} options.mutate - Execute client mutate - * @param {Function} options.save - Execute client save - * @param {Function} options.dispatch - Store's dispatch, comes from the client - */ - function Association(target, name, doctype, options) { - (0, _classCallCheck2.default)(this, Association); - var dispatch = options.dispatch, - get = options.get, - query = options.query, - mutate = options.mutate, - save = options.save; - /** - * The original document declaring the relationship - * - * @type {object} - */ +module.exports = Transform; - this.target = target; - /** - * The name of the relationship. - * - * @type {string} - * @example 'author' - */ - this.name = name; - /** - * Doctype of the relationship - * - * @type {string} - * @example 'io.cozy.authors' - */ +/***/ }), +/* 719 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.doctype = doctype; - /** - * Returns the document from the store - * - * @type {Function} - */ +// default filter +var Transform = __webpack_require__(718); - this.get = get; - /** - * Performs a query to retrieve relationship documents. - * - * @param {QueryDefinition} queryDefinition - * @function - */ +var levelMap = { debug: 1, info: 2, warn: 3, error: 4 }; - this.query = query; - /** - * Performs a mutation on the relationship. - * - * @function - */ +function Filter() { + this.enabled = true; + this.defaultResult = true; + this.clear(); +} - this.mutate = mutate; - /** - * Saves the relationship in store. - * - * @type {Function} - */ +Transform.mixin(Filter); - this.save = save; - /** - * Dispatch an action on the store. - * - * @type {Function} - */ +// allow all matching, with level >= given level +Filter.prototype.allow = function(name, level) { + this._white.push({ n: name, l: levelMap[level] }); + return this; +}; - this.dispatch = dispatch; - } - /** - * - * Returns the raw relationship data as stored in the original document - * - * For a document with relationships stored as JSON API spec: - * - * ```js - * const book = { - * title: 'Moby Dick', - * relationships: { - * author: { - * data: { - * doctype: 'io.cozy.authors', - * id: 'herman' - * } - * } - * } - * } - * ``` - * - * Raw value will be - * - * ```json - * { - * "doctype": "io.cozy.authors", - * "id": "herman" - * } - * ``` - * - * Derived `Association`s need to implement this method. - * - * @returns {object} - */ +// deny all matching, with level <= given level +Filter.prototype.deny = function(name, level) { + this._black.push({ n: name, l: levelMap[level] }); + return this; +}; +Filter.prototype.clear = function() { + this._white = []; + this._black = []; + return this; +}; - (0, _createClass2.default)(Association, [{ - key: "raw", - get: function get() { - throw new Error('A relationship must define its raw getter'); - } - /** - * Returns the document(s) from the store - * - * For document with relationships stored as JSON API spec : - * - * ```js - * const book = { - * title: 'Moby Dick', - * relationships: { - * author: { - * data: { - * doctype: 'io.cozy.authors', - * id: 'herman' - * } - * } - * } - * } - * ``` - * - * `data` will be - * - * ```json - * { - * "_id": "herman" - * "_type": "io.cozy.authors", - * "firstName": "herman", - * "name": "Melville" - * } - * ``` - * - * Derived `Association`s need to implement this method. - * - * @returns {object} - */ +function test(rule, name) { + // use .test for RegExps + return (rule.n.test ? rule.n.test(name) : rule.n == name); +}; - }, { - key: "data", - get: function get() { - throw new Error('A relationship must define its data getter'); +Filter.prototype.test = function(name, level) { + var i, len = Math.max(this._white.length, this._black.length); + for(i = 0; i < len; i++) { + if(this._white[i] && test(this._white[i], name) && levelMap[level] >= this._white[i].l) { + return true; } - /** - * Derived `Association`s need to implement this method. - * - * @param {CozyClientDocument} document - Document to query - * @param {object} client - The CozyClient instance - * @param {Association} assoc - Association containing info on how to build the query to fetch related documents - * - * @returns {CozyClientDocument | QueryDefinition } - */ - - }], [{ - key: "query", - value: function query(document, client, assoc) { - throw new Error('A custom relationship must define its query() function'); + if(this._black[i] && test(this._black[i], name) && levelMap[level] <= this._black[i].l) { + return false; } - }]); - return Association; -}(); - -var _default = Association; -exports["default"] = _default; + } + return this.defaultResult; +}; -/***/ }), -/* 741 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +Filter.prototype.write = function(name, level, args) { + if(!this.enabled || this.test(name, level)) { + return this.emit('item', name, level, args); + } +}; -"use strict"; +module.exports = Filter; -var _interopRequireDefault = __webpack_require__(512); +/***/ }), +/* 720 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = exports.updateRelationship = exports.updateHasManyItem = exports.removeHasManyItem = exports.setHasManyItem = exports.getHasManyItems = exports.getHasManyItem = void 0; +var Transform = __webpack_require__(718); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +function ConsoleBackend() { } -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +Transform.mixin(ConsoleBackend); -var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(594)); +ConsoleBackend.prototype.write = function() { + console.log.apply(console, arguments); +}; -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +var e = new ConsoleBackend(); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); +var levelMap = (__webpack_require__(721).levelMap); -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +e.filterEnv = function() { + console.error('Minilog.backends.console.filterEnv is deprecated in Minilog v2.'); + // return the instance of Minilog + return __webpack_require__(717); +}; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +e.formatters = [ + 'formatClean', 'formatColor', 'formatNpm', + 'formatLearnboost', 'formatMinilog', 'formatWithStack', 'formatTime' +]; -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); +e.formatClean = new (__webpack_require__(722)); +e.formatColor = new (__webpack_require__(723)); +e.formatNpm = new (__webpack_require__(724)); +e.formatLearnboost = new (__webpack_require__(725)); +e.formatMinilog = new (__webpack_require__(726)); +e.formatWithStack = new (__webpack_require__(727)); +e.formatTime = new (__webpack_require__(728)); -var _get = _interopRequireDefault(__webpack_require__(358)); +module.exports = e; -var _merge = _interopRequireDefault(__webpack_require__(742)); -var _dsl = __webpack_require__(607); +/***/ }), +/* 721 */ +/***/ ((__unused_webpack_module, exports) => { -var _store = __webpack_require__(693); +var styles = { + //styles + bold: ["\x1B[1m", "\x1B[22m"], + italic: ["\x1B[3m", "\x1B[23m"], + underline: ["\x1B[4m", "\x1B[24m"], + inverse: ["\x1B[7m", "\x1B[27m"], + //grayscale + white: ["\x1B[37m", "\x1B[39m"], + grey: ["\x1B[90m", "\x1B[39m"], + black: ["\x1B[30m", "\x1B[39m"], + //colors + blue: ["\x1B[34m", "\x1B[39m"], + cyan: ["\x1B[36m", "\x1B[39m"], + green: ["\x1B[32m", "\x1B[39m"], + magenta: ["\x1B[35m", "\x1B[39m"], + red: ["\x1B[31m", "\x1B[39m"], + yellow: ["\x1B[33m", "\x1B[39m"] +}; -var _types = __webpack_require__(610); +exports.levelMap = { debug: 1, info: 2, warn: 3, error: 4 }; -var _Association2 = _interopRequireDefault(__webpack_require__(740)); +exports.style = function(str, style) { + return styles[style][0] + str + styles[style][1]; +}; -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +/***/ }), +/* 722 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +var Transform = __webpack_require__(718); -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +function FormatClean() {} -/** - * @typedef {object} Relationship - * @property {string} relName - name of the relationship - * @property {string} relItemId - id of the relation - * @property {Relation} relItemAttrs - Attributes to be set (at least _id and _type) - */ +Transform.mixin(FormatClean); -/** - * @typedef {object} Relation - * @property {string} _id - id of the relation - * @property {string} _type - doctype of the relation - */ -var empty = function empty() { - return { - data: [], - next: true, - meta: { - count: 0 - } - }; +FormatClean.prototype.write = function(name, level, args) { + function pad(s) { return (s.toString().length == 1? '0'+s : s); } + this.emit('item', (name ? name + ' ' : '') + (level ? level + ' ' : '') + args.join(' ')); }; -var updateArray = function updateArray(array, indexArg, el) { - var index = indexArg === -1 ? array.length : indexArg; - return [].concat((0, _toConsumableArray2.default)(array.slice(0, index)), [el], (0, _toConsumableArray2.default)(array.slice(index + 1))); -}; -/** - * Related documents are stored in the relationships attribute of the object, - * following the JSON API spec. - * - * Responsible for - * - * - Creating relationships - * - Removing relationships - * - * @description - * - * ``` - * const schema = { - * todos: { - * doctype: 'io.cozy.todos', - * relationships: { - * tasks: { - * doctype: 'io.cozy.tasks', - * type: 'has-many' - * } - * } - * } - * } - * - * const todo = { - * label: "Protect people's privacy", - * relationships: { - * tasks: { - * data: [ - * {_id: 1, _type: 'io.cozy.tasks'}, - * {_id: 2, _type: 'io.cozy.tasks'} - * ] - * } - * } - * } - * ``` - */ +module.exports = FormatClean; -var HasMany = /*#__PURE__*/function (_Association) { - (0, _inherits2.default)(HasMany, _Association); +/***/ }), +/* 723 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var _super = _createSuper(HasMany); +var Transform = __webpack_require__(718), + style = (__webpack_require__(721).style); - function HasMany() { - var _this; +function FormatColor() {} - (0, _classCallCheck2.default)(this, HasMany); +Transform.mixin(FormatColor); - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } +FormatColor.prototype.write = function(name, level, args) { + var colors = { debug: 'magenta', info: 'cyan', warn: 'yellow', error: 'red' }; + function pad(s) { return (s.toString().length == 4? ' '+s : s); } + this.emit('item', (name ? name + ' ' : '') + + (level ? style('- ' + pad(level.toUpperCase()) + ' -', colors[level]) + ' ' : '') + + args.join(' ')); +}; - _this = _super.call.apply(_super, [this].concat(args)); - (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateRelationshipData", function (getUpdatedRelationshipData) { - return function (dispatch, getState) { - var previousRelationship = (0, _store.getDocumentFromState)(getState(), _this.target._type, _this.target._id); - dispatch((0, _store.receiveQueryResult)(null, { - data: _objectSpread(_objectSpread({}, previousRelationship), {}, { - relationships: _objectSpread(_objectSpread({}, previousRelationship.relationships), {}, (0, _defineProperty2.default)({}, _this.name, getUpdatedRelationshipData(previousRelationship.relationships[_this.name]))) - }) - })); - }; - }); - return _this; - } +module.exports = FormatColor; - (0, _createClass2.default)(HasMany, [{ - key: "fetchMore", - value: function fetchMore() { - throw 'Not implemented'; - } - }, { - key: "exists", - value: function exists(document) { - return this.existsById(document._id); - } - }, { - key: "containsById", - value: function containsById(id) { - return this.getRelationship().data.find(function (_ref) { - var _id = _ref._id; - return id === _id; - }) !== undefined; - } - }, { - key: "existsById", - value: function existsById(id) { - return Boolean(this.containsById(id) && this.get(this.doctype, id)); - } - /** - * Add the relationships to the target document - * - * @param {CozyClientDocument[]} docsArg - Documents to add as relationships - * @returns {CozyClientDocument} The saved target document - */ - }, { - key: "add", - value: function add(docsArg) { - var docs = Array.isArray(docsArg) ? docsArg : [docsArg]; - var ids = docs.map(function (doc) { - return doc._id; - }); - return this.addById(ids); - } - /** - * Remove the relationships from the target document - * - * @param {CozyClientDocument[]} docsArg - Documents to remove as relationships - * @returns {CozyClientDocument} The saved target document - */ +/***/ }), +/* 724 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - }, { - key: "remove", - value: function remove(docsArg) { - var docs = Array.isArray(docsArg) ? docsArg : [docsArg]; - var ids = docs.map(function (doc) { - return doc._id; - }); - return this.removeById(ids); - } - /** - * Update target document with relationships - * - * @param {string[]} idsArg - The ids to add as a relationship - */ +var Transform = __webpack_require__(718); - }, { - key: "addTargetRelationships", - value: function addTargetRelationships(idsArg) { - var _this2 = this, - _this$target$relation; +function FormatNpm() {} - if (!this.target.relationships) this.target.relationships = {}; +Transform.mixin(FormatNpm); - if (!this.target.relationships[this.name]) { - this.target.relationships[this.name] = { - data: [] - }; - } +FormatNpm.prototype.write = function(name, level, args) { + var out = { + debug: "\x1B[34;40m" + "debug" + "\x1B[39m ", + info: "\x1B[32m" + "info" + "\x1B[39m ", + warn: "\x1B[30;41m" + "WARN" + "\x1B[0m ", + error: "\x1B[31;40m" + "ERR!" + "\x1B[0m " + }; + this.emit( + "item", + (name ? "\x1B[37;40m" + name + "\x1B[0m " : "") + + (level && out[level] ? out[level] : "") + + args.join(" ") + ); +}; - var ids = Array.isArray(idsArg) ? idsArg : [idsArg]; - var newRelations = ids.filter(function (id) { - return !_this2.existsById(id); - }).map(function (id) { - return { - _id: id, - _type: _this2.doctype - }; - }); +module.exports = FormatNpm; - (_this$target$relation = this.target.relationships[this.name].data).push.apply(_this$target$relation, (0, _toConsumableArray2.default)(newRelations)); - this.updateMetaCount(); - } - /** - * Add a referenced document by id. You need to call save() - * in order to synchronize your document with the store. - * - * @todo We shouldn't create the array of relationship manually since - * it'll not be present in the store as well. - * We certainly should use something like `updateRelationship` - * - */ +/***/ }), +/* 725 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - }, { - key: "addById", - value: function addById(idsArg) { - this.addTargetRelationships(idsArg); - return this.save(this.target); - } - /** - * Remove relationships from target document - * - * @param {string[]} idsArg - The ids to remove from the target relationships - */ +var Transform = __webpack_require__(718), + style = (__webpack_require__(721).style); - }, { - key: "removeTargetRelationships", - value: function removeTargetRelationships(idsArg) { - var ids = Array.isArray(idsArg) ? idsArg : [idsArg]; - this.target.relationships[this.name].data = this.target.relationships[this.name].data.filter(function (_ref2) { - var _id = _ref2._id; - return !ids.includes(_id); - }); - this.updateMetaCount(); - } - }, { - key: "removeById", - value: function removeById(idsArg) { - this.removeTargetRelationships(idsArg); - return this.save(this.target); - } - }, { - key: "updateMetaCount", - value: function updateMetaCount() { - if ((0, _get.default)(this.target.relationships[this.name], 'meta.count') !== undefined) { - this.target.relationships[this.name].meta = _objectSpread(_objectSpread({}, this.target.relationships[this.name].meta), {}, { - count: this.target.relationships[this.name].data.length - }); - } - } - }, { - key: "getRelationship", - value: function getRelationship() { - var rawData = this.target[this.name]; - var relationship = (0, _get.default)(this.target, "relationships.".concat(this.name)); +function FormatLearnboost() {} - if (!relationship) { - if (rawData && rawData.length) { - console.warn("You're trying to access data on a relationship that appear to not be loaded yet. You may want to use 'include()' on your query"); - } +Transform.mixin(FormatLearnboost); - return empty(); - } +FormatLearnboost.prototype.write = function(name, level, args) { + var colors = { debug: 'grey', info: 'cyan', warn: 'yellow', error: 'red' }; + this.emit('item', (name ? style(name +' ', 'grey') : '') + + (level ? style(level, colors[level]) + ' ' : '') + + args.join(' ')); +}; - return relationship; - } - }, { - key: "updateTargetRelationship", - value: function updateTargetRelationship(store, updateFn) { - // TODO See if updateTargetRelationship is still used, removing it would enable us - // to remove store.readDocument and store.writeDocument and the StoreProxy - var prevTarget = store.readDocument(this.target._type, this.target._id); - store.writeDocument(this.updateRelationship(prevTarget, updateFn)); - } - }, { - key: "updateRelationship", - value: function updateRelationship(target, updateFn) { - return HasMany.updateRelationship(target, this.name, updateFn); - } - }, { - key: "dehydrate", - value: function dehydrate(doc) { - return _objectSpread(_objectSpread({}, doc), {}, { - relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, this.name, { - data: this.raw - })) - }); - } - /** - * @param {CozyClientDocument} document - Document to query - * @param {object} client - The CozyClient instance - * @param {Association} assoc - The query params - * - * @returns {CozyClientDocument | QueryDefinition} - */ +module.exports = FormatLearnboost; - }, { - key: "raw", - get: function get() { - return this.getRelationship().data; - } - /** - * Returns store documents - */ - }, { - key: "data", - get: function get() { - var _this3 = this; +/***/ }), +/* 726 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return this.getRelationship().data.map(function (_ref3) { - var _id = _ref3._id, - _type = _ref3._type; - return _this3.get(_type, _id); - }).filter(Boolean); - } - }, { - key: "hasMore", - get: function get() { - return this.getRelationship().next; - } - /** - * Returns the total number of documents in the relationship. - * Does not handle documents absent from the store. If you want - * to do that, you can use .data.length. - * - * @returns {number} - Total number of documents in the relationships - */ +var Transform = __webpack_require__(718), + style = (__webpack_require__(721).style), + util = __webpack_require__(64); - }, { - key: "count", - get: function get() { - var relationship = this.getRelationship(); - return relationship.meta ? relationship.meta.count : relationship.data.length; - } - }], [{ - key: "query", - value: function query(document, client, assoc) { - var relationships = (0, _get.default)(document, "relationships.".concat(assoc.name, ".data"), []); - var ids = relationships.map(function (assoc) { - return assoc._id; - }); - return new _dsl.QueryDefinition({ - doctype: assoc.doctype, - ids: ids - }); - } - }]); - return HasMany; -}(_Association2.default); -/** - * Gets a relationship item with the relationship name and id - * - * @param {object} doc - Document to be updated - * @param {string} relName - Name of the relationship - * @param {string} relItemId - Id of the relationship item - */ +function FormatMinilog() {} +Transform.mixin(FormatMinilog); -var getHasManyItem = HasMany.getHasManyItem = function (doc, relName, relItemId) { - var relData = (0, _get.default)(doc, "relationships.".concat(relName, ".data"), []); - return relData.find(function (rel) { - return rel._id == relItemId; - }); +FormatMinilog.prototype.write = function(name, level, args) { + var colors = { debug: 'blue', info: 'cyan', warn: 'yellow', error: 'red' }; + this.emit('item', (name ? style(name +' ', 'grey') : '') + + (level ? style(level, colors[level]) + ' ' : '') + + args.map(function(item) { + return (typeof item == 'string' ? item : util.inspect(item, null, 3, true)); + }).join(' ')); }; -exports.getHasManyItem = getHasManyItem; +module.exports = FormatMinilog; -var getHasManyItems = HasMany.getHasManyItems = function (doc, relName) { - return (0, _get.default)(doc, "relationships.".concat(relName, ".data"), []); -}; -/** - * Sets a relationship item with the relationship name and id - * - * @param {object} doc - Document to be updated - * @param {string} relName - Name of the relationship - * @param {string} relItemId - Id of the relationship item - * @param {object} relItemAttrs - Attributes to be set (at least _id and _type) - */ +/***/ }), +/* 727 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -exports.getHasManyItems = getHasManyItems; +var Transform = __webpack_require__(718), + style = (__webpack_require__(721).style); -var setHasManyItem = HasMany.setHasManyItem = function (doc, relName, relItemId, relItemAttrs) { - var relData = HasMany.getHasManyItems(doc, relName); - var relIndex = relData.findIndex(function (rel) { - return rel._id === relItemId; - }); - var updatedRelItem = (0, _merge.default)({}, relData[relIndex], relItemAttrs); - var updatedRelData = updateArray(relData, relIndex, updatedRelItem); - var updatedDocument = HasMany.updateRelationship(doc, relName, function (relationship) { - return (0, _merge.default)({}, relationship, { - data: updatedRelData - }); - }); - return updatedDocument; -}; -/** - * Remove one relationship item - * - * @param {object} doc - Document to be updated - * @param {string} relName - Name of the relationship - * @param {string} relItemId - Id of the relationship item - */ +function FormatNpm() {} +Transform.mixin(FormatNpm); -exports.setHasManyItem = setHasManyItem; +function noop(a){ + return a; +} -var removeHasManyItem = HasMany.removeHasManyItem = function (doc, relName, relItemId) { - var relData = HasMany.getHasManyItems(doc, relName); - var updatedRelData = relData.filter(function (rel) { - return rel._id !== relItemId; +var types = { + string: noop, + number: noop, + default: JSON.stringify.bind(JSON) +}; + +function stringify(args) { + return args.map(function(arg) { + return (types[typeof arg] || types.default)(arg); }); - var updatedDocument = HasMany.updateRelationship(doc, relName, function () { - return { - data: updatedRelData +} + +FormatNpm.prototype.write = function(name, level, args) { + var colors = { debug: 'magenta', info: 'cyan', warn: 'yellow', error: 'red' }; + function pad(s) { return (s.toString().length == 4? ' '+s : s); } + function getStack() { + var orig = Error.prepareStackTrace; + Error.prepareStackTrace = function (err, stack) { + return stack; }; - }); - return updatedDocument; + var err = new Error; + Error.captureStackTrace(err, arguments.callee); + var stack = err.stack; + Error.prepareStackTrace = orig; + return stack; + } + + var frame = getStack()[5], + fileName = FormatNpm.fullPath ? frame.getFileName() : frame.getFileName().replace(/^.*\/(.+)$/, '/$1'); + + this.emit('item', (name ? name + ' ' : '') + + (level ? style(pad(level), colors[level]) + ' ' : '') + + style(fileName + ":" + frame.getLineNumber(), 'grey') + + ' ' + + stringify(args).join(' ')); }; -/** - * Updates a relationship item with the relationship name and id - * - * @param {object} doc - Document to be updated - * @param {string} relName - Name of the relationship - * @param {string} relItemId - Id of the relationship item - * @param {Function} updater - receives the current relationship item and should - * return an updated version. Merge should be used in the updater - * if previous relationship item fields are to be kept. - */ +FormatNpm.fullPath = true; -exports.removeHasManyItem = removeHasManyItem; +module.exports = FormatNpm; -var updateHasManyItem = HasMany.updateHasManyItem = function (doc, relName, relItemId, updater) { - var relItem = HasMany.getHasManyItem(doc, relName, relItemId); - var updatedRelItem = updater(relItem); - return HasMany.setHasManyItem(doc, relName, relItemId, updatedRelItem); + + +/***/ }), +/* 728 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Transform = __webpack_require__(718), + style = (__webpack_require__(721).style), + util = __webpack_require__(64); + +function FormatTime() {} + +function timestamp() { + var d = new Date(); + return ('0' + d.getDate()).slice(-2) + '-' + + ('0' + (d.getMonth() + 1)).slice(-2) + '-' + + d.getFullYear() + ' ' + + ('0' + d.getHours()).slice(-2) + ':' + + ('0' + d.getMinutes()).slice(-2) + ':' + + ('0' + d.getSeconds()).slice(-2) + '.' + + ('00' + d.getMilliseconds()).slice(-3); +} + +Transform.mixin(FormatTime); + +FormatTime.prototype.write = function(name, level, args) { + var colors = { debug: 'blue', info: 'cyan', warn: 'yellow', error: 'red' }; + this.emit('item', style(timestamp() +' ', 'grey') + + (name ? style(name +' ', 'grey') : '') + + (level ? style(level, colors[level]) + ' ' : '') + + args.map(function(item) { + return (typeof item == 'string' ? item : util.inspect(item, null, 3, true)); + }).join(' ')); }; -exports.updateHasManyItem = updateHasManyItem; +module.exports = FormatTime; -var updateRelationship = HasMany.updateRelationship = function (doc, relName, updateFn) { - return _objectSpread(_objectSpread({}, doc), {}, { - relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, relName, _objectSpread(_objectSpread({}, doc.relationships ? doc.relationships[relName] : {}), updateFn(doc.relationships ? doc.relationships[relName] : {})))) - }); + +/***/ }), +/* 729 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Transform = __webpack_require__(718); + +var newlines = /\n+$/, + logger = new Transform(); + +logger.write = function(name, level, args) { + var i = args.length-1; + if (typeof console === 'undefined' || !console.log) { + return; + } + if(console.log.apply) { + return console.log.apply(console, [name, level].concat(args)); + } else if(JSON && JSON.stringify) { + // console.log.apply is undefined in IE8 and IE9 + // for IE8/9: make console.log at least a bit less awful + if(args[i] && typeof args[i] == 'string') { + args[i] = args[i].replace(newlines, ''); + } + try { + for(i = 0; i < args.length; i++) { + args[i] = JSON.stringify(args[i]); + } + } catch(e) {} + console.log(args.join(' ')); + } }; -exports.updateRelationship = updateRelationship; -var _default = HasMany; -exports["default"] = _default; +logger.formatters = ['color', 'minilog']; +logger.color = __webpack_require__(730); +logger.minilog = __webpack_require__(732); + +module.exports = logger; + /***/ }), -/* 742 */ +/* 730 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseMerge = __webpack_require__(743), - createAssigner = __webpack_require__(748); +var Transform = __webpack_require__(718), + color = __webpack_require__(731); -/** - * This method is like `_.assign` except that it recursively merges own and - * inherited enumerable string keyed properties of source objects into the - * destination object. Source properties that resolve to `undefined` are - * skipped if a destination value exists. Array and plain object properties - * are merged recursively. Other objects and value types are overridden by - * assignment. Source objects are applied from left to right. Subsequent - * sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * var object = { - * 'a': [{ 'b': 2 }, { 'd': 4 }] - * }; - * - * var other = { - * 'a': [{ 'c': 3 }, { 'e': 5 }] - * }; - * - * _.merge(object, other); - * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } - */ -var merge = createAssigner(function(object, source, srcIndex) { - baseMerge(object, source, srcIndex); -}); +var colors = { debug: ['cyan'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] }, + logger = new Transform(); -module.exports = merge; +logger.write = function(name, level, args) { + var fn = console.log; + if(console[level] && console[level].apply) { + fn = console[level]; + fn.apply(console, [ '%c'+name+' %c'+level, color('gray'), color.apply(color, colors[level])].concat(args)); + } +}; + +// NOP, because piping the formatted logs can only cause trouble. +logger.pipe = function() { }; + +module.exports = logger; /***/ }), -/* 743 */ +/* 731 */ +/***/ ((module) => { + +var hex = { + black: '#000', + red: '#c23621', + green: '#25bc26', + yellow: '#bbbb00', + blue: '#492ee1', + magenta: '#d338d3', + cyan: '#33bbc8', + gray: '#808080', + purple: '#708' +}; +function color(fg, isInverse) { + if(isInverse) { + return 'color: #fff; background: '+hex[fg]+';'; + } else { + return 'color: '+hex[fg]+';'; + } +} + +module.exports = color; + + +/***/ }), +/* 732 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var Stack = __webpack_require__(404), - assignMergeValue = __webpack_require__(744), - baseFor = __webpack_require__(537), - baseMergeDeep = __webpack_require__(745), - isObject = __webpack_require__(52), - keysIn = __webpack_require__(567), - safeGet = __webpack_require__(746); +var Transform = __webpack_require__(718), + color = __webpack_require__(731), + colors = { debug: ['gray'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] }, + logger = new Transform(); -/** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ -function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; +logger.write = function(name, level, args) { + var fn = console.log; + if(level != 'debug' && console[level]) { + fn = console[level]; } - baseFor(source, function(srcValue, key) { - stack || (stack = new Stack); - if (isObject(srcValue)) { - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) - : undefined; - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); + var subset = [], i = 0; + if(level != 'info') { + for(; i < args.length; i++) { + if(typeof args[i] != 'string') break; } - }, keysIn); -} + fn.apply(console, [ '%c'+name +' '+ args.slice(0, i).join(' '), color.apply(color, colors[level]) ].concat(args.slice(i))); + } else { + fn.apply(console, [ '%c'+name, color.apply(color, colors[level]) ].concat(args)); + } +}; -module.exports = baseMerge; +// NOP, because piping the formatted logs can only cause trouble. +logger.pipe = function() { }; + +module.exports = logger; /***/ }), -/* 744 */ +/* 733 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseAssignValue = __webpack_require__(534), - eq = __webpack_require__(385); +var Transform = __webpack_require__(718); -/** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); +function Stringify() {} + +Transform.mixin(Stringify); + +Stringify.prototype.write = function(name, level, args) { + var result = []; + if(name) result.push(name); + if(level) result.push(level); + result = result.concat(args); + for(var i = 0; i < result.length; i++) { + if(result[i] && typeof result[i] == 'object') { + // Buffers in Node.js look bad when stringified + if(result[i].constructor && result[i].constructor.isBuffer) { + result[i] = result[i].toString(); + } else { + try { + result[i] = JSON.stringify(result[i]); + } catch(stringifyError) { + // happens when an object has a circular structure + // do not throw an error, when printing, the toString() method of the object will be used + } + } + } else { + result[i] = result[i]; + } } + this.emit('item', result.join(' ') + '\n'); +}; + +module.exports = Stringify; + + +/***/ }), +/* 734 */ +/***/ ((module) => { + +function RedisBackend(options) { + this.client = options.client; + this.key = options.key; } -module.exports = assignMergeValue; +RedisBackend.prototype.write = function(str) { + this.client.rpush(this.key, str); +}; + +RedisBackend.prototype.end = function() {}; + +RedisBackend.prototype.clear = function(cb) { + this.client.del(this.key, cb); +}; + +module.exports = RedisBackend; /***/ }), -/* 745 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 735 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -var assignMergeValue = __webpack_require__(744), - cloneBuffer = __webpack_require__(570), - cloneTypedArray = __webpack_require__(583), - copyArray = __webpack_require__(571), - initCloneObject = __webpack_require__(584), - isArguments = __webpack_require__(432), - isArray = __webpack_require__(55), - isArrayLikeObject = __webpack_require__(552), - isBuffer = __webpack_require__(434), - isFunction = __webpack_require__(45), - isObject = __webpack_require__(52), - isPlainObject = __webpack_require__(619), - isTypedArray = __webpack_require__(437), - safeGet = __webpack_require__(746), - toPlainObject = __webpack_require__(747); +"use strict"; + + +var _interopRequireDefault = __webpack_require__(524); + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.QueryIDGenerator = exports.getQueryFromSlice = exports.receiveQueryError = exports.receiveQueryResult = exports.loadQuery = exports.initQuery = exports["default"] = exports.makeSorterFromDefinition = exports.mergeSelectorAndPartialIndex = exports.convert$gtNullSelectors = exports.isReceivingData = exports.isQueryAction = void 0; + +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); + +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); + +var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532)); + +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); + +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); + +var _mapValues = _interopRequireDefault(__webpack_require__(545)); + +var _groupBy = _interopRequireDefault(__webpack_require__(736)); + +var _difference = _interopRequireDefault(__webpack_require__(737)); + +var _intersection = _interopRequireDefault(__webpack_require__(739)); + +var _concat = _interopRequireDefault(__webpack_require__(742)); + +var _isPlainObject = _interopRequireDefault(__webpack_require__(631)); + +var _uniq = _interopRequireDefault(__webpack_require__(624)); + +var _orderBy = _interopRequireDefault(__webpack_require__(743)); + +var _isArray = _interopRequireDefault(__webpack_require__(55)); + +var _isString = _interopRequireDefault(__webpack_require__(54)); + +var _get = _interopRequireDefault(__webpack_require__(370)); + +var _sift = _interopRequireDefault(__webpack_require__(749)); + +var _cozyFlags = _interopRequireDefault(__webpack_require__(615)); + +var _documents = __webpack_require__(710); + +var _mutations = __webpack_require__(750); + +var _helpers = __webpack_require__(751); + +var _dsl = __webpack_require__(619); + +var _types = __webpack_require__(622); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +var INIT_QUERY = 'INIT_QUERY'; +var LOAD_QUERY = 'LOAD_QUERY'; +var RECEIVE_QUERY_RESULT = 'RECEIVE_QUERY_RESULT'; +var RECEIVE_QUERY_ERROR = 'RECEIVE_QUERY_ERROR'; // Read if the devtools are open to store the execution time +// This is done at runtime to not read the value everytime +// we receive a result. So you have to refresh your page +// in order to get the stats + +var executionStatsEnabled = (0, _cozyFlags.default)('debug'); + +var isQueryAction = function isQueryAction(action) { + return [INIT_QUERY, LOAD_QUERY, RECEIVE_QUERY_RESULT, RECEIVE_QUERY_ERROR].indexOf(action.type) !== -1; +}; + +exports.isQueryAction = isQueryAction; + +var isReceivingData = function isReceivingData(action) { + return action.type === RECEIVE_QUERY_RESULT; +}; +/** @type {QueryState} */ + + +exports.isReceivingData = isReceivingData; +var queryInitialState = { + id: null, + definition: null, + fetchStatus: 'pending', + lastFetch: null, + lastUpdate: null, + lastErrorUpdate: null, + lastError: null, + hasMore: false, + count: 0, + data: [], + bookmark: null +}; + +var updateQueryDataFromResponse = function updateQueryDataFromResponse(queryState, response, documents) { + var updatedIds = (0, _uniq.default)([].concat((0, _toConsumableArray2.default)(queryState.data), (0, _toConsumableArray2.default)(response.data.map(_helpers.properId)))); + + if (queryState.definition.sort) { + var sorter = makeSorterFromDefinition(queryState.definition); + var doctype = queryState.definition.doctype; + var allDocs = documents[doctype]; + var docs = allDocs ? updatedIds.map(function (_id) { + return allDocs[_id]; + }).filter(Boolean) : []; + var sortedDocs = sorter(docs); + updatedIds = sortedDocs.map(_helpers.properId); + } + return updatedIds; +}; /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. + * Reducer for a query slice * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. + * @param {QueryState} state - Current state + * @param {any} action - Redux action + * @param {DocumentsStateSlice} documents - Reference to the next documents slice + * @returns {QueryState} - Next state */ -function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = safeGet(object, key), - srcValue = safeGet(source, key), - stacked = stack.get(srcValue); - - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - var isCommon = newValue === undefined; - if (isCommon) { - var isArr = isArray(srcValue), - isBuff = !isArr && isBuffer(srcValue), - isTyped = !isArr && !isBuff && isTypedArray(srcValue); +var query = function query() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : queryInitialState; + var action = arguments.length > 1 ? arguments[1] : undefined; + var documents = arguments.length > 2 ? arguments[2] : undefined; - newValue = srcValue; - if (isArr || isBuff || isTyped) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else if (isBuff) { - isCommon = false; - newValue = cloneBuffer(srcValue, true); - } - else if (isTyped) { - isCommon = false; - newValue = cloneTypedArray(srcValue, true); - } - else { - newValue = []; + switch (action.type) { + case INIT_QUERY: + if (state.lastUpdate && state.id === action.queryId && state.definition === action.queryDefinition) { + return state; } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - newValue = objValue; - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); + + return _objectSpread(_objectSpread({}, state), {}, { + id: action.queryId, + definition: action.queryDefinition, + options: action.options, + // When the query is new, we set "fetchStatus" to "loading" + // directly since we know it will be loaded right away. + // This way, the loadQuery action will have no effect, and + // we save an additional render. + fetchStatus: state.lastUpdate ? state.fetchStatus : 'pending' + }); + + case LOAD_QUERY: + if (state.fetchStatus === 'loading') { + return state; } - else if (!isObject(objValue) || isFunction(objValue)) { - newValue = initCloneObject(srcValue); + + return _objectSpread(_objectSpread({}, state), {}, { + fetchStatus: 'loading' + }); + + case RECEIVE_QUERY_RESULT: + { + var response = action.response; + + if (!response.data) { + return state; + } + /** @type {Partial<QueryState>} */ + + + var common = _objectSpread({ + fetchStatus: 'loaded', + lastFetch: Date.now(), + lastUpdate: Date.now() + }, executionStatsEnabled && { + execution_stats: response.execution_stats + }); + + if (!Array.isArray(response.data)) { + return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, { + hasMore: false, + count: 1, + data: [(0, _helpers.properId)(response.data)] + }); + } + + return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, { + bookmark: response.bookmark || null, + hasMore: response.next !== undefined ? response.next : state.hasMore, + count: response.meta && response.meta.count ? response.meta.count : response.data.length, + data: updateQueryDataFromResponse(state, response, documents) + }); } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); + + case RECEIVE_QUERY_ERROR: + return _objectSpread(_objectSpread({}, state), {}, { + id: action.queryId, + fetchStatus: 'failed', + lastError: action.error, + lastErrorUpdate: Date.now() + }); + + default: + return state; } - assignMergeValue(object, key, newValue); -} +}; +/** + * Normalize sift selector + * + * @returns {object} + */ -module.exports = baseMergeDeep; +var convert$gtNullSelectors = function convert$gtNullSelectors(selector) { + var result = {}; -/***/ }), -/* 746 */ -/***/ ((module) => { + for (var _i = 0, _Object$entries = Object.entries(selector); _i < _Object$entries.length; _i++) { + var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2), + key = _Object$entries$_i[0], + value = _Object$entries$_i[1]; + + var convertedValue = (0, _isPlainObject.default)(value) ? convert$gtNullSelectors(value) : value; + var convertedKey = key === '$gt' && convertedValue === null ? '$gtnull' : key; + result[convertedKey] = convertedValue; + } + return result; +}; /** - * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * Merges query selectors with query partial indexes * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. + * @param {object} queryDefinition - A query definition + * @returns {object} A query definition selector */ -function safeGet(object, key) { - if (key === 'constructor' && typeof object[key] === 'function') { - return; - } - if (key == '__proto__') { - return; - } - return object[key]; -} +exports.convert$gtNullSelectors = convert$gtNullSelectors; -module.exports = safeGet; +var mergeSelectorAndPartialIndex = function mergeSelectorAndPartialIndex(queryDefinition) { + return _objectSpread(_objectSpread({}, queryDefinition.selector), (0, _get.default)(queryDefinition, 'partialFilter')); +}; +/** + * @param {QueryDefinition} queryDefinition - A query definition + * @returns {function(CozyClientDocument): boolean} + */ -/***/ }), -/* 747 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +exports.mergeSelectorAndPartialIndex = mergeSelectorAndPartialIndex; + +var getSelectorFilterFn = function getSelectorFilterFn(queryDefinition) { + if (queryDefinition.selector) { + var selectors = mergeSelectorAndPartialIndex(queryDefinition); // sift does not work like couchdb when using { $gt: null } as a selector, so we use a custom operator -var copyObject = __webpack_require__(565), - keysIn = __webpack_require__(567); + _sift.default.use({ + $gtnull: function $gtnull(_selectorValue, actualValue) { + return !!actualValue; + } + }); + return (0, _sift.default)(convert$gtNullSelectors(selectors)); + } else if (queryDefinition.id) { + /** @type {object} */ + var siftQuery = { + _id: queryDefinition.id + }; + return (0, _sift.default)(siftQuery); + } else if (queryDefinition.ids) { + /** @type {object} */ + var _siftQuery = { + _id: { + $in: queryDefinition.ids + } + }; + return (0, _sift.default)(_siftQuery); + } else { + return null; + } +}; /** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example + * Returns a predicate function that checks if a document should be + * included in the result of the query. * - * function Foo() { - * this.b = 2; - * } + * @param {QueryState} query - Definition of the query + * @returns {function(CozyClientDocument): boolean} Predicate function + */ + + +var getQueryDocumentsChecker = function getQueryDocumentsChecker(query) { + var qdoctype = query.definition.doctype; + var selectorFilterFn = getSelectorFilterFn(query.definition); + return function (datum) { + var ddoctype = datum._type; + if (ddoctype !== qdoctype) return false; + if (datum._deleted) return false; + if (!selectorFilterFn) return true; + return !!selectorFilterFn(datum); + }; +}; + +var makeCaseInsensitiveStringSorter = function makeCaseInsensitiveStringSorter(attrName) { + return function (item) { + var attrValue = (0, _get.default)(item, attrName); + return (0, _isString.default)(attrValue) ? attrValue.toLowerCase() : attrValue; + }; +}; +/** + * Creates a sort function from a definition. * - * Foo.prototype.c = 3; + * Used to sort query results inside the store when creating a file or + * receiving updates. * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } + * @param {QueryDefinition} definition - A query definition + * @returns {function(Array<CozyClientDocument>): Array<CozyClientDocument>} * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } + * @private */ -function toPlainObject(value) { - return copyObject(value, keysIn(value)); -} - -module.exports = toPlainObject; -/***/ }), -/* 748 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var baseRest = __webpack_require__(544), - isIterateeCall = __webpack_require__(749); +var makeSorterFromDefinition = function makeSorterFromDefinition(definition) { + var sort = definition.sort; + if (!sort) { + return function (docs) { + return docs; + }; + } else if (!(0, _isArray.default)(definition.sort)) { + console.warn('Correct update of queries with a sort that is not an array is not supported. Use an array as argument of QueryDefinition::sort'); + return function (docs) { + return docs; + }; + } else { + var attributeOrders = sort.map(function (x) { + return Object.entries(x)[0]; + }); + var attrs = attributeOrders.map(function (x) { + return x[0]; + }).map(makeCaseInsensitiveStringSorter); + var orders = attributeOrders.map(function (x) { + return x[1]; + }); + return function (docs) { + return (0, _orderBy.default)(docs, attrs, orders); + }; + } +}; /** - * Creates a function like `_.assign`. + * Updates query state when new data comes in * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. + * @param {QueryState} query - Current query state + * @param {Array<CozyClientDocument>} newData - New documents (in most case from the server) + * @param {DocumentsStateSlice} documents - A reference to the documents slice + * @returns {QueryState} - Updated query state */ -function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; +exports.makeSorterFromDefinition = makeSorterFromDefinition; + +var updateData = function updateData(query, newData, documents) { + var belongsToQuery = getQueryDocumentsChecker(query); + var res = (0, _mapValues.default)((0, _groupBy.default)(newData, belongsToQuery), function (docs) { + return docs.map(_helpers.properId); }); -} + var _res$true = res.true, + matchedIds = _res$true === void 0 ? [] : _res$true, + _res$false = res.false, + unmatchedIds = _res$false === void 0 ? [] : _res$false; + var originalIds = query.data; + var autoUpdate = query.options && query.options.autoUpdate; + var shouldRemove = !autoUpdate || autoUpdate.remove !== false; + var shouldAdd = !autoUpdate || autoUpdate.add !== false; + var shouldUpdate = !autoUpdate || autoUpdate.update !== false; + var toRemove = shouldRemove ? (0, _intersection.default)(originalIds, unmatchedIds) : []; + var toAdd = shouldAdd ? (0, _difference.default)(matchedIds, originalIds) : []; + var toUpdate = shouldUpdate ? (0, _intersection.default)(originalIds, matchedIds) : []; + var changed = toRemove.length || toAdd.length || toUpdate.length; // concat doesn't check duplicates (contrarily to union), which is ok as + // toAdd does not contain any id present in originalIds, by construction. + // It is also faster than union. -module.exports = createAssigner; + var updatedData = (0, _difference.default)((0, _concat.default)(originalIds, toAdd), toRemove); + + if (query.definition.sort && documents) { + var sorter = makeSorterFromDefinition(query.definition); + var allDocs = documents[query.definition.doctype]; + var docs = updatedData.map(function (_id) { + return allDocs[_id]; + }); + var sortedDocs = sorter(docs); + updatedData = sortedDocs.map(_helpers.properId); + } + + return _objectSpread(_objectSpread({}, query), {}, { + data: updatedData, + count: updatedData.length, + lastUpdate: changed ? Date.now() : query.lastUpdate + }); +}; +/** + * Creates a function that returns an updated query state + * from an action + * + * @param {object} action - A redux action + * @param {DocumentsStateSlice} documents - Reference to documents slice + * @returns {function(QueryState): QueryState} - Updater query state + */ -/***/ }), -/* 749 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var autoQueryUpdater = function autoQueryUpdater(action, documents) { + return function (query) { + var data = (0, _get.default)(action, 'response.data') || (0, _get.default)(action, 'definition.document'); + if (!data) return query; -var eq = __webpack_require__(385), - isArrayLike = __webpack_require__(446), - isIndex = __webpack_require__(436), - isObject = __webpack_require__(52); + if (!Array.isArray(data)) { + data = [data]; + } + + if (!data.length) { + return query; + } + if (query.definition.doctype !== data[0]._type) { + return query; + } + + return updateData(query, data, documents); + }; +}; /** - * Checks if the given arguments are from an iteratee call. + * Creates a function that returns an updated query state + * from an action * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. + * @param {object} action - A redux action + * @param {DocumentsStateSlice} documents - Reference to documents slice + * @returns {function(QueryState): QueryState} - Updater query state */ -function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; -} -module.exports = isIterateeCall; +var manualQueryUpdater = function manualQueryUpdater(action, documents) { + return function (query) { + var updateQueries = action.updateQueries; + var response = action.response; + var updater = updateQueries[query.id]; -/***/ }), -/* 750 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + if (!updater) { + return query; + } -"use strict"; + var doctype = query.definition.doctype; + var oldData = query.data; + var oldDocs = mapIdsToDocuments(documents, doctype, oldData); + var newData = updater(oldDocs, response); + var newDataIds = newData.map(_helpers.properId); + return _objectSpread(_objectSpread({}, query), {}, { + data: newDataIds, + count: newDataIds.length, + lastUpdate: Date.now() + }); + }; +}; +/** + * @param {QueriesStateSlice} state - Redux slice containing all the query states indexed by name + * @param {object} action - Income redux action + * @param {DocumentsStateSlice} documents - Reference to documents slice + * @param {boolean} haveDocumentsChanged - Has the document slice changed with current action + * @returns {QueriesStateSlice} + */ -var _interopRequireDefault = __webpack_require__(512); +var queries = function queries() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var action = arguments.length > 1 ? arguments[1] : undefined; + var documents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var haveDocumentsChanged = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + if (action.type == INIT_QUERY) { + var newQueryState = query(state[action.queryId], action, documents); // Do not create new object unnecessarily -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); + if (newQueryState === state[action.queryId]) { + return state; + } -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + return _objectSpread(_objectSpread({}, state), {}, (0, _defineProperty2.default)({}, action.queryId, newQueryState)); + } -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + if (isQueryAction(action)) { + var updater = autoQueryUpdater(action, documents); + return (0, _mapValues.default)(state, function (queryState) { + if (queryState.id == action.queryId) { + return query(queryState, action, documents); + } else if (haveDocumentsChanged) { + return updater(queryState); + } else { + return queryState; + } + }); + } -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); + if ((0, _mutations.isReceivingMutationResult)(action)) { + var _updater = action.updateQueries ? manualQueryUpdater(action, documents) : autoQueryUpdater(action, documents); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); + return (0, _mapValues.default)(state, _updater); + } -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + return state; +}; -var _get2 = _interopRequireDefault(__webpack_require__(358)); +var _default = queries; +/** + * Create the query states in the store. Queries are indexed + * in the store by queryId + * + * @param {string} queryId Name/id of the query + * @param {QueryDefinition} queryDefinition - Definition of the created query + * @param {QueryOptions} [options] - Options for the created query + */ -var _set = _interopRequireDefault(__webpack_require__(751)); +exports["default"] = _default; -var _dsl = __webpack_require__(607); +var initQuery = function initQuery(queryId, queryDefinition) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; -var _types = __webpack_require__(610); + if (!queryDefinition.doctype) { + throw new Error('Cannot init query with no doctype'); + } -var _Association2 = _interopRequireDefault(__webpack_require__(740)); + return { + type: INIT_QUERY, + queryId: queryId, + queryDefinition: queryDefinition, + options: options + }; +}; -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +exports.initQuery = initQuery; -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +var loadQuery = function loadQuery(queryId) { + return { + type: LOAD_QUERY, + queryId: queryId + }; +}; -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +exports.loadQuery = loadQuery; -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +var receiveQueryResult = function receiveQueryResult(queryId, response) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return _objectSpread({ + type: RECEIVE_QUERY_RESULT, + queryId: queryId, + response: response + }, options); +}; -var HasOne = /*#__PURE__*/function (_Association) { - (0, _inherits2.default)(HasOne, _Association); +exports.receiveQueryResult = receiveQueryResult; - var _super = _createSuper(HasOne); +var receiveQueryError = function receiveQueryError(queryId, error) { + return { + type: RECEIVE_QUERY_ERROR, + queryId: queryId, + error: error + }; +}; // selectors - function HasOne() { - (0, _classCallCheck2.default)(this, HasOne); - return _super.apply(this, arguments); - } - (0, _createClass2.default)(HasOne, [{ - key: "add", +exports.receiveQueryError = receiveQueryError; - /** - * Add the relationship to the target document - * - * @param {CozyClientDocument} doc - Document to add as a relationship - * @returns {CozyClientDocument} The saved target document - */ - value: function add(doc) { - this.setRelationship(doc); - return this.save(this.target); - } - /** - * Remove the relationship from the target document - * - * @returns {CozyClientDocument} The saved target document - */ +var mapIdsToDocuments = function mapIdsToDocuments(documents, doctype, ids) { + return ids.map(function (id) { + return (0, _documents.getDocumentFromSlice)(documents, doctype, id); + }); +}; - }, { - key: "remove", - value: function remove() { - this.setRelationship(undefined); - return this.save(this.target); - } - }, { - key: "setRelationship", - value: function setRelationship(doc) { - if (doc && doc._type !== this.doctype) { - throw new Error("Tried to associate a ".concat(doc._type, " document to a HasOne relationship on ").concat(this.doctype, " document")); - } +var getQueryFromSlice = function getQueryFromSlice(state, queryId, documents) { + if (!state || !state[queryId]) { + return _objectSpread(_objectSpread({}, queryInitialState), {}, { + id: queryId, + data: null + }); + } - var path = "relationships[".concat(this.name, "].data"); + var query = state[queryId]; + return documents ? _objectSpread(_objectSpread({}, query), {}, { + data: mapIdsToDocuments(documents, query.definition.doctype, query.data) + }) : query; +}; - if (doc) { - (0, _set.default)(this.target, path, { - _id: doc._id, - _type: doc._type - }); - } else { - (0, _set.default)(this.target, path, undefined); - } - } - }, { - key: "set", - value: function set(doc) { - console.warn('set is deprecated for has-one relationships. Use `add` instead.'); - this.setRelationship(doc); - } - }, { - key: "unset", - value: function unset() { - console.warn('unset is deprecated for has-one relationships. Use `remove` instead.'); - this.setRelationship(undefined); - } - }, { - key: "dehydrate", - value: function dehydrate(doc) { - if (!this.raw) { - return doc; - } +exports.getQueryFromSlice = getQueryFromSlice; - return _objectSpread(_objectSpread({}, doc), {}, { - relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, this.name, { - data: this.raw - })) - }); - } - }, { - key: "raw", - get: function get() { - return (0, _get2.default)(this.target, "relationships[".concat(this.name, "].data"), null); - } - }, { - key: "data", - get: function get() { - if (!this.raw) { - return null; - } +var QueryIDGenerator = /*#__PURE__*/function () { + function QueryIDGenerator() { + (0, _classCallCheck2.default)(this, QueryIDGenerator); + this.idCounter = 1; + } + /** + * Generates a random id for unamed queries + */ - return this.get(this.doctype, this.raw._id); + + (0, _createClass2.default)(QueryIDGenerator, [{ + key: "generateRandomId", + value: function generateRandomId() { + var id = this.idCounter; + this.idCounter++; + return id.toString(); } /** - * @param {CozyClientDocument} document - Document to query - * @param {object} client - The CozyClient instance - * @param {Association} assoc - The query params + * Generates an id for queries + * If the query is a getById only query, + * we can generate a name for it. * - * @returns {CozyClientDocument | QueryDefinition} + * If not, let's generate a random id + * + * @param {QueryDefinition} queryDefinition The query definition + * @returns {string} */ - }], [{ - key: "query", - value: function query(document, client, assoc) { - var relationship = (0, _get2.default)(document, "relationships.".concat(assoc.name, ".data"), {}); - - if (!relationship || !relationship._id) { - return null; + }, { + key: "generateId", + value: function generateId(queryDefinition) { + if (!(0, _dsl.isAGetByIdQuery)(queryDefinition)) { + return this.generateRandomId(); + } else { + var id = queryDefinition.id, + doctype = queryDefinition.doctype; + return "".concat(doctype, "/").concat(id); } - - return (0, _dsl.Q)(assoc.doctype).getById(relationship._id); } }]); - return HasOne; -}(_Association2.default); + return QueryIDGenerator; +}(); -exports["default"] = HasOne; +exports.QueryIDGenerator = QueryIDGenerator; +QueryIDGenerator.UNNAMED = 'unnamed'; /***/ }), -/* 751 */ +/* 736 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseSet = __webpack_require__(650); +var baseAssignValue = __webpack_require__(546), + createAggregator = __webpack_require__(712); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; /** - * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, - * it's created. Arrays are created for missing index properties while objects - * are created for all other missing properties. Use `_.setWith` to customize - * `path` creation. - * - * **Note:** This method mutates `object`. + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The order of grouped values + * is determined by the order they occur in `collection`. The corresponding + * value of each key is an array of elements responsible for generating the + * key. The iteratee is invoked with one argument: (value). * * @static * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @returns {Object} Returns `object`. + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. * @example * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.set(object, 'a[0].b.c', 4); - * console.log(object.a[0].b.c); - * // => 4 + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } * - * _.set(object, ['x', '0', 'y', 'z'], 5); - * console.log(object.x[0].y.z); - * // => 5 + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } */ -function set(object, path, value) { - return object == null ? object : baseSet(object, path, value); -} +var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + baseAssignValue(result, key, [value]); + } +}); -module.exports = set; +module.exports = groupBy; /***/ }), -/* 752 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.BelongsToInPlace = exports["default"] = void 0; - -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); - -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); - -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +/* 737 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _Association2 = _interopRequireDefault(__webpack_require__(740)); +var baseDifference = __webpack_require__(738), + baseFlatten = __webpack_require__(553), + baseRest = __webpack_require__(556), + isArrayLikeObject = __webpack_require__(564); -var _dsl = __webpack_require__(607); +/** + * Creates an array of `array` values not included in the other given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * **Note:** Unlike `_.pullAll`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.without, _.xor + * @example + * + * _.difference([2, 1], [2, 3]); + * // => [1] + */ +var difference = baseRest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) + : []; +}); -var _types = __webpack_require__(610); +module.exports = difference; -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +/***/ }), +/* 738 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +var SetCache = __webpack_require__(425), + arrayIncludes = __webpack_require__(476), + arrayIncludesWith = __webpack_require__(481), + arrayMap = __webpack_require__(410), + baseUnary = __webpack_require__(452), + cacheHas = __webpack_require__(429); -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; /** - * Here the id of the document is directly set in the attribute - * of the document, not in the relationships attribute + * The base implementation of methods like `_.difference` without support + * for excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. */ -var HasOneInPlace = /*#__PURE__*/function (_Association) { - (0, _inherits2.default)(HasOneInPlace, _Association); - - var _super = _createSuper(HasOneInPlace); +function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; - function HasOneInPlace() { - (0, _classCallCheck2.default)(this, HasOneInPlace); - return _super.apply(this, arguments); + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee == null ? value : iteratee(value); - (0, _createClass2.default)(HasOneInPlace, [{ - key: "dehydrate", - value: function dehydrate(doc) { - return _objectSpread(_objectSpread({}, doc), {}, (0, _defineProperty2.default)({}, this.name, this.raw || undefined)); - } - }, { - key: "raw", - get: function get() { - return this.target[this.name]; + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); } - }, { - key: "data", - get: function get() { - return this.get(this.doctype, this.raw); + else if (!includes(values, computed, comparator)) { + result.push(value); } - /** - * @param {CozyClientDocument} document - Document to query - * @param {object} client - The CozyClient instance - * @param {Association} assoc - The query params - * - * @returns {CozyClientDocument | QueryDefinition} - */ + } + return result; +} - }], [{ - key: "query", - value: function query(document, client, assoc) { - var id = document[assoc.name]; - return client.getDocumentFromState(assoc.doctype, id) || (0, _dsl.Q)(assoc.doctype).getById(id); - } - }]); - return HasOneInPlace; -}(_Association2.default); +module.exports = baseDifference; -exports["default"] = HasOneInPlace; -var BelongsToInPlace = HasOneInPlace; -exports.BelongsToInPlace = BelongsToInPlace; /***/ }), -/* 753 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; +/* 739 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var arrayMap = __webpack_require__(410), + baseIntersection = __webpack_require__(740), + baseRest = __webpack_require__(556), + castArrayLikeObject = __webpack_require__(741); -var _interopRequireDefault = __webpack_require__(512); +/** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [2, 3]); + * // => [2] + */ +var intersection = baseRest(function(arrays) { + var mapped = arrayMap(arrays, castArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; +}); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +module.exports = intersection; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +/***/ }), +/* 740 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var SetCache = __webpack_require__(425), + arrayIncludes = __webpack_require__(476), + arrayIncludesWith = __webpack_require__(481), + arrayMap = __webpack_require__(410), + baseUnary = __webpack_require__(452), + cacheHas = __webpack_require__(429); -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); +/** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ +function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; -var _dsl = __webpack_require__(607); + var index = -1, + seen = caches[0]; -var _types = __webpack_require__(610); + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; -var _Association2 = _interopRequireDefault(__webpack_require__(740)); + value = (comparator || value !== 0) ? value : 0; + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +module.exports = baseIntersection; -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +/***/ }), +/* 741 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +var isArrayLikeObject = __webpack_require__(564); /** + * Casts `value` to an empty array if it's not an array like object. * - * Used when related documents are stored directly under the attribute with - * only the ids. - * - * @property {Function} get - * - * @description - * - * An example document representing a TODO. See as the related - * tasks are represented via ids. - * - * ```js - * const todo = { - * label: "Protect people's privacy", - * tasks: [1, 2] - * } - * ``` - * - * Here is the `Schema` that would represent this kind of document. - * Components receiving todos via `Query`s would have an instance of `HasManyInPlace` - * as their `tasks` attribute. - * - * ```js - * const schema = { - * todos: { - * doctype: 'io.cozy.todos', - * relationships: { - * tasks: { - * doctype: 'io.cozy.tasks', - * type: 'has-many-in-place' - * } - * } - * } - * } - * - * const todo = { - * label: "Get rich", - * tasks: [1, 2] - * } - * ``` - * + * @private + * @param {*} value The value to inspect. + * @returns {Array|Object} Returns the cast array-like object. */ -var HasManyInPlace = /*#__PURE__*/function (_Association) { - (0, _inherits2.default)(HasManyInPlace, _Association); - - var _super = _createSuper(HasManyInPlace); +function castArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; +} - function HasManyInPlace() { - (0, _classCallCheck2.default)(this, HasManyInPlace); - return _super.apply(this, arguments); - } +module.exports = castArrayLikeObject; - (0, _createClass2.default)(HasManyInPlace, [{ - key: "addById", - value: function addById(id) { - var rel = this.getRelationship(); - rel.push(id); - } - }, { - key: "removeById", - value: function removeById(id) { - var rel = this.getRelationship(); - var index = rel.indexOf(id); - if (index !== -1) { - rel.splice(index, 1); - } - } - }, { - key: "existsById", - value: function existsById(id) { - var rel = this.getRelationship(); - return rel.indexOf(id) !== -1; - } - }, { - key: "getRelationship", - value: function getRelationship() { - this.target[this.name] = this.target[this.name] || []; - return this.target[this.name]; - } - }, { - key: "dehydrate", - value: function dehydrate(doc) { - return _objectSpread(_objectSpread({}, doc), {}, (0, _defineProperty2.default)({}, this.name, this.raw || [])); - } - }, { - key: "raw", +/***/ }), +/* 742 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Raw property - * - * @type {Array<string>} - */ - get: function get() { - return this.target[this.name]; - } - }, { - key: "data", - get: function get() { - var _this = this; +var arrayPush = __webpack_require__(437), + baseFlatten = __webpack_require__(553), + copyArray = __webpack_require__(583), + isArray = __webpack_require__(55); - var doctype = this.doctype; - return (this.raw || []).map(function (_id) { - return _this.get(doctype, _id); - }); - } - /** - * @param {CozyClientDocument} document - Document to query - * @param {object} client - The CozyClient instance - * @param {Association} assoc - The query params - * - * @returns {CozyClientDocument | QueryDefinition} - */ +/** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ +function concat() { + var length = arguments.length; + if (!length) { + return []; + } + var args = Array(length - 1), + array = arguments[0], + index = length; - }], [{ - key: "query", - value: function query(document, client, assoc) { - var ids = document[assoc.name]; + while (index--) { + args[index - 1] = arguments[index]; + } + return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); +} - if (ids && ids > 0) { - return (0, _dsl.Q)(assoc.doctype).getByIds(ids); - } else { - return null; - } - } - }]); - return HasManyInPlace; -}(_Association2.default); +module.exports = concat; -var _default = HasManyInPlace; -exports["default"] = _default; /***/ }), -/* 754 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/* 743 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; +var baseOrderBy = __webpack_require__(744), + isArray = __webpack_require__(55); +/** + * This method is like `_.sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] + * The iteratees to sort by. + * @param {string[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // Sort by `user` in ascending order and by `age` in descending order. + * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] + */ +function orderBy(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + orders = guard ? undefined : orders; + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseOrderBy(collection, iteratees, orders); +} -var _interopRequireDefault = __webpack_require__(512); +module.exports = orderBy; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +/***/ }), +/* 744 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var arrayMap = __webpack_require__(410), + baseGet = __webpack_require__(371), + baseIteratee = __webpack_require__(413), + baseMap = __webpack_require__(745), + baseSortBy = __webpack_require__(746), + baseUnary = __webpack_require__(452), + compareMultiple = __webpack_require__(747), + identity = __webpack_require__(471), + isArray = __webpack_require__(55); -var _get2 = _interopRequireDefault(__webpack_require__(670)); +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = arrayMap(iteratees, function(iteratee) { + if (isArray(iteratee)) { + return function(value) { + return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity]; + } -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); + var index = -1; + iteratees = arrayMap(iteratees, baseUnary(baseIteratee)); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); +} -var _HasMany2 = _interopRequireDefault(__webpack_require__(741)); +module.exports = baseOrderBy; -var _dsl = __webpack_require__(607); -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } +/***/ }), +/* 745 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +var baseEach = __webpack_require__(567), + isArrayLike = __webpack_require__(458); -var TRIGGERS_DOCTYPE = 'io.cozy.triggers'; /** - * Association used for konnectors to retrieve all their related triggers. + * The base implementation of `_.map` without support for iteratee shorthands. * - * @augments HasMany + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. */ +function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; -var HasManyTriggers = /*#__PURE__*/function (_HasMany) { - (0, _inherits2.default)(HasManyTriggers, _HasMany); + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} - var _super = _createSuper(HasManyTriggers); +module.exports = baseMap; - function HasManyTriggers() { - (0, _classCallCheck2.default)(this, HasManyTriggers); - return _super.apply(this, arguments); - } - (0, _createClass2.default)(HasManyTriggers, [{ - key: "data", - get: function get() { - var _this = this; +/***/ }), +/* 746 */ +/***/ ((module) => { - return (0, _get2.default)((0, _getPrototypeOf2.default)(HasManyTriggers.prototype), "data", this).filter(function (_ref) { - var slug = _ref.slug; - return slug === _this.target.slug; - }); - } - /** - * In this association the query is special, we need to fetch all the triggers - * having for the 'konnector' worker, and then filter them based on their - * `message.konnector` attribute - */ +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; - }], [{ - key: "query", - value: function query(doc, client) { - return (0, _dsl.Q)(TRIGGERS_DOCTYPE).where({ - worker: 'konnector' - }); - } - }]); - return HasManyTriggers; -}(_HasMany2.default); + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} -var _default = HasManyTriggers; -exports["default"] = _default; +module.exports = baseSortBy; -/***/ }), -/* 755 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -"use strict"; +/***/ }), +/* 747 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var compareAscending = __webpack_require__(748); -var _interopRequireDefault = __webpack_require__(512); +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.getReferencedById = exports.getReferencedBy = exports.isReferencedById = exports.isReferencedBy = exports.create = exports.resolveClass = exports.attachRelationships = exports.responseToRelationship = exports.pickTypeAndId = void 0; + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +module.exports = compareMultiple; -var _pick = _interopRequireDefault(__webpack_require__(664)); -var _pickBy = _interopRequireDefault(__webpack_require__(648)); +/***/ }), +/* 748 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _Association = _interopRequireDefault(__webpack_require__(740)); +var isSymbol = __webpack_require__(374); -var _HasOne = _interopRequireDefault(__webpack_require__(750)); +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = isSymbol(value); -var _HasOneInPlace = _interopRequireDefault(__webpack_require__(752)); + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = isSymbol(other); -var _HasMany = _interopRequireDefault(__webpack_require__(741)); + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} -var _HasManyInPlace = _interopRequireDefault(__webpack_require__(753)); +module.exports = compareAscending; -var _HasManyFiles = _interopRequireDefault(__webpack_require__(692)); -var _types = __webpack_require__(610); +/***/ }), +/* 749 */ +/***/ ((module, exports) => { -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +/* + * Sift 3.x + * + * Copryright 2015, Craig Condon + * Licensed under MIT + * + * Filter JavaScript objects with mongodb queries + */ -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +(function() { -var pickTypeAndId = function pickTypeAndId(x) { - return (0, _pick.default)(x, '_type', '_id'); -}; + 'use strict'; -exports.pickTypeAndId = pickTypeAndId; + /** + */ -var applyHelper = function applyHelper(fn, objOrArr) { - return Array.isArray(objOrArr) ? objOrArr.map(fn) : fn(objOrArr); -}; + function isFunction(value) { + return typeof value === 'function'; + } -var responseToRelationship = function responseToRelationship(response) { - return (0, _pickBy.default)({ - data: applyHelper(pickTypeAndId, response.data), - meta: response.meta, - next: response.next, - skip: response.skip, - bookmark: response.bookmark - }); -}; + /** + */ -exports.responseToRelationship = responseToRelationship; + function isArray(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + } -var attachRelationship = function attachRelationship(doc, relationships) { - return _objectSpread(_objectSpread({}, doc), {}, { - relationships: _objectSpread(_objectSpread({}, doc.relationships), relationships) - }); -}; + /** + */ -var attachRelationships = function attachRelationships(response, relationshipsByDocId) { - if (Array.isArray(response.data)) { - return _objectSpread(_objectSpread({}, response), {}, { - data: response.data.map(function (doc) { - return attachRelationship(doc, relationshipsByDocId[doc._id]); - }) - }); - } else { - var doc = response.data; - return _objectSpread(_objectSpread({}, response), {}, { - data: attachRelationship(doc, relationshipsByDocId[doc._id]) - }); + function comparable(value) { + if (value instanceof Date) { + return value.getTime(); + } else if (isArray(value)) { + return value.map(comparable); + } else if (value && typeof value.toJSON === 'function') { + return value.toJSON(); + } else { + return value; + } } -}; - -exports.attachRelationships = attachRelationships; -var aliases = { - 'io.cozy.files:has-many': _HasManyFiles.default, - 'has-many': _HasMany.default, - 'belongs-to-in-place': _HasOneInPlace.default, - 'has-one': _HasOne.default, - 'has-one-in-place': _HasOneInPlace.default, - 'has-many-in-place': _HasManyInPlace.default -}; -/** - * Returns the relationship class for a given doctype/type. - * - * In the schema definition, some classes have string aliases - * so you do not have to import directly the association. - * - * Some doctypes can have built-in overriden relationships. - * - * @private - */ -var resolveClass = function resolveClass(doctype, type) { - if (type === undefined) { - throw new Error('Undefined type for ' + doctype); + function get(obj, key) { + return isFunction(obj.get) ? obj.get(key) : obj[key]; } - if (typeof type !== 'string') { - return type; - } else { - var qualified = "".concat(doctype, ":").concat(type); - var cls = aliases[qualified] || aliases[type]; + /** + */ - if (!cls) { - throw new Error("Unknown association '".concat(type, "'")); - } else { - return cls; + function or(validator) { + return function(a, b) { + if (!isArray(b) || !b.length) { + return validator(a, b); + } + for (var i = 0, n = b.length; i < n; i++) { + if (validator(a, get(b,i))) return true; + } + return false; } } -}; -exports.resolveClass = resolveClass; + /** + */ -var create = function create(target, _ref, accessors) { - var name = _ref.name, - type = _ref.type, - doctype = _ref.doctype; + function and(validator) { + return function(a, b) { + if (!isArray(b) || !b.length) { + return validator(a, b); + } + for (var i = 0, n = b.length; i < n; i++) { + if (!validator(a, get(b, i))) return false; + } + return true; + }; + } - if (target[name] instanceof _Association.default) { - throw new Error("Association ".concat(name, " already exists")); + function validate(validator, b, k, o) { + return validator.v(validator.a, b, k, o); } - return new type(target, name, doctype, accessors); -}; -/** - * Checks if the file is referenced by a specific doctype - * - * @param {IOCozyFile} file - io.cozy.files document - * @param {Doctype} referencedBy - Doctype where document is referenced - * @returns {boolean} If a reference is found - */ + var OPERATORS = { + /** + */ -exports.create = create; + $eq: or(function(a, b) { + return a(b); + }), -var isReferencedBy = function isReferencedBy(file, referencedBy) { - var _file$relationships, _file$relationships$r; + /** + */ - var references = (file === null || file === void 0 ? void 0 : (_file$relationships = file.relationships) === null || _file$relationships === void 0 ? void 0 : (_file$relationships$r = _file$relationships.referenced_by) === null || _file$relationships$r === void 0 ? void 0 : _file$relationships$r.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || []; - return references.some(function (reference) { - return reference.type === referencedBy; - }); -}; -/** - * Checks if the file is referenced by a specific doctype and a specific Id of that reference - * - * @param {IOCozyFile} file - io.cozy.files document - * @param {Doctype} referencedBy - Doctype where document is referenced - * @param {string} referencedId - Id of the referenced document - * @returns {boolean} If a reference is found - */ + $ne: and(function(a, b) { + return !a(b); + }), + /** + */ -exports.isReferencedBy = isReferencedBy; + $gt: or(function(a, b) { + return sift.compare(comparable(b), a) > 0; + }), -var isReferencedById = function isReferencedById(file, referencedBy, referencedId) { - var _file$relationships2, _file$relationships2$; + /** + */ - var references = (file === null || file === void 0 ? void 0 : (_file$relationships2 = file.relationships) === null || _file$relationships2 === void 0 ? void 0 : (_file$relationships2$ = _file$relationships2.referenced_by) === null || _file$relationships2$ === void 0 ? void 0 : _file$relationships2$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || []; - return references.some(function (reference) { - return reference.type === referencedBy && reference.id === referencedId; - }); -}; -/** - * Get array of reference by an specific doctype - * - * @param {IOCozyFile} file - io.cozy.files document - * @param {Doctype} referencedBy - Doctype where document is referenced - * @returns {Reference[]} Array of references found - */ + $gte: or(function(a, b) { + return sift.compare(comparable(b), a) >= 0; + }), + /** + */ -exports.isReferencedById = isReferencedById; + $lt: or(function(a, b) { + return sift.compare(comparable(b), a) < 0; + }), -var getReferencedBy = function getReferencedBy(file, referencedBy) { - var _file$relationships3, _file$relationships3$; + /** + */ - var references = (file === null || file === void 0 ? void 0 : (_file$relationships3 = file.relationships) === null || _file$relationships3 === void 0 ? void 0 : (_file$relationships3$ = _file$relationships3.referenced_by) === null || _file$relationships3$ === void 0 ? void 0 : _file$relationships3$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || []; - return references.filter(function (reference) { - return reference.type === referencedBy; - }); -}; -/** - * Get array of reference by an specific doctype and a specific Id of that reference - * - * @param {IOCozyFile} file - io.cozy.files document - * @param {Doctype} referencedBy - Doctype where document is referenced - * @param {string} referencedId - Id of the referenced document - * @returns {Reference[]} Array of the reference found - */ + $lte: or(function(a, b) { + return sift.compare(comparable(b), a) <= 0; + }), + /** + */ -exports.getReferencedBy = getReferencedBy; + $mod: or(function(a, b) { + return b % a[0] == a[1]; + }), -var getReferencedById = function getReferencedById(file, referencedBy, referencedId) { - var _file$relationships4, _file$relationships4$; + /** + */ - var references = (file === null || file === void 0 ? void 0 : (_file$relationships4 = file.relationships) === null || _file$relationships4 === void 0 ? void 0 : (_file$relationships4$ = _file$relationships4.referenced_by) === null || _file$relationships4$ === void 0 ? void 0 : _file$relationships4$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || []; - return references.filter(function (reference) { - return reference.type === referencedBy && reference.id === referencedId; - }); -}; + $in: function(a, b) { -exports.getReferencedById = getReferencedById; + if (b instanceof Array) { + for (var i = b.length; i--;) { + if (~a.indexOf(comparable(get(b, i)))) { + return true; + } + } + } else { + var comparableB = comparable(b); + if (comparableB === b && typeof b === 'object') { + for (var i = a.length; i--;) { + if (String(a[i]) === String(b) && String(b) !== '[object Object]') { + return true; + } + } + } -/***/ }), -/* 756 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + /* + Handles documents that are undefined, whilst also + having a 'null' element in the parameters to $in. + */ + if (typeof comparableB == 'undefined') { + for (var i = a.length; i--;) { + if (a[i] == null) { + return true; + } + } + } -"use strict"; + /* + Handles the case of {'field': {$in: [/regexp1/, /regexp2/, ...]}} + */ + for (var i = a.length; i--;) { + var validator = createRootValidator(get(a, i), undefined); + var result = validate(validator, b, i, a); + if ((result) && (String(result) !== '[object Object]') && (String(b) !== '[object Object]')) { + return true; + } + } + return !!~a.indexOf(comparableB); + } -var _interopRequireDefault = __webpack_require__(512); + return false; + }, -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.rootCozyUrl = exports.InvalidCozyUrlError = exports.InvalidProtocolError = exports.generateWebLink = exports.dehydrate = void 0; + /** + */ -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); + $nin: function(a, b, k, o) { + return !OPERATORS.$in(a, b, k, o); + }, -var _toArray2 = _interopRequireDefault(__webpack_require__(514)); + /** + */ -var _regenerator = _interopRequireDefault(__webpack_require__(527)); + $not: function(a, b, k, o) { + return !validate(a, b, k, o); + }, -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); + /** + */ -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + $type: function(a, b) { + return b != void 0 ? b instanceof a || b.constructor == a : false; + }, -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); + /** + */ -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); + $all: function(a, b, k, o) { + return OPERATORS.$and(a, b, k, o); + }, -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); + /** + */ -var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(652)); + $size: function(a, b) { + return b ? a === b.length : false; + }, -var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520)); + /** + */ -var _associations = __webpack_require__(691); + $or: function(a, b, k, o) { + for (var i = 0, n = a.length; i < n; i++) if (validate(get(a, i), b, k, o)) return true; + return false; + }, -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } + /** + */ -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + $nor: function(a, b, k, o) { + return !OPERATORS.$or(a, b, k, o); + }, -function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + /** + */ -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + $and: function(a, b, k, o) { + for (var i = 0, n = a.length; i < n; i++) { + if (!validate(get(a, i), b, k, o)) { + return false; + } + } + return true; + }, -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + /** + */ -var dehydrate = function dehydrate(document) { - var dehydrated = Object.entries(document).reduce(function (documentArg, _ref) { - var _ref2 = (0, _slicedToArray2.default)(_ref, 2), - key = _ref2[0], - value = _ref2[1]; + $regex: or(function(a, b) { + return typeof b === 'string' && a.test(b); + }), - var document = documentArg; + /** + */ - if (!(value instanceof _associations.Association)) { - document[key] = value; // @ts-ignore - } else if (value.dehydrate) { - // @ts-ignore - document = value.dehydrate(document); - } else { - throw new Error("Association on key ".concat(key, " should have a dehydrate method")); + $where: function(a, b, k, o) { + return a.call(b, b, k, o); + }, + + /** + */ + + $elemMatch: function(a, b, k, o) { + if (isArray(b)) { + return !!~search(b, a); + } + return validate(a, b, k, o); + }, + + /** + */ + + $exists: function(a, b, k, o) { + return o.hasOwnProperty(k) === a; } + }; - return document; - }, {}); - return dehydrated; -}; + /** + */ -exports.dehydrate = dehydrate; + var prepare = { -var ensureFirstSlash = function ensureFirstSlash(path) { - if (!path) { - return '/'; - } else { - return path.startsWith('/') ? path : '/' + path; - } -}; -/** - * generateWebLink - Construct a link to a web app - * - * This function does not get its cozy url from a CozyClient instance so it can - * be used to build urls that point to other Cozies than the user's own Cozy. - * This is useful when pointing to the Cozy of the owner of a shared note for - * example. - * - * @param {object} options Object of options - * @param {string} options.cozyUrl Base URL of the cozy, eg. cozy.tools or test.mycozy.cloud - * @param {Array} [options.searchParams] Array of search parameters as [key, value] arrays, eg. ['username', 'bob'] - * @param {string} [options.pathname] Path to a specific part of the app, eg. /public - * @param {string} [options.hash] Path inside the app, eg. /files/test.jpg - * @param {string} [options.slug] Slug of the app - * @param {string} [options.subDomainType] Whether the cozy is using flat or nested subdomains. Defaults to flat. - * - * @returns {string} Generated URL - */ + /** + */ + $eq: function(a) { -var generateWebLink = function generateWebLink(_ref3) { - var cozyUrl = _ref3.cozyUrl, - searchParamsOption = _ref3.searchParams, - pathname = _ref3.pathname, - hash = _ref3.hash, - slug = _ref3.slug, - subDomainType = _ref3.subDomainType; - var searchParams = searchParamsOption || []; - var url = new URL(cozyUrl); - url.host = subDomainType === 'nested' ? "".concat(slug, ".").concat(url.host) : url.host.split('.').map(function (x, i) { - return i === 0 ? x + '-' + slug : x; - }).join('.'); - url.pathname = pathname; - url.hash = ensureFirstSlash(hash); + if (a instanceof RegExp) { + return function(b) { + return typeof b === 'string' && a.test(b); + }; + } else if (a instanceof Function) { + return a; + } else if (isArray(a) && !a.length) { + // Special case of a == [] + return function(b) { + return (isArray(b) && !b.length); + }; + } else if (a === null){ + return function(b){ + //will match both null and undefined + return b == null; + } + } - var _iterator = _createForOfIteratorHelper(searchParams), - _step; + return function(b) { + return sift.compare(comparable(b), a) === 0; + }; + }, - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - var _step$value = (0, _slicedToArray2.default)(_step.value, 2), - param = _step$value[0], - value = _step$value[1]; + /** + */ - url.searchParams.set(param, value); - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } + $ne: function(a) { + return prepare.$eq(a); + }, - return url.toString(); -}; + /** + */ -exports.generateWebLink = generateWebLink; + $and: function(a) { + return a.map(parse); + }, -var InvalidProtocolError = /*#__PURE__*/function (_Error) { - (0, _inherits2.default)(InvalidProtocolError, _Error); + /** + */ - var _super = _createSuper(InvalidProtocolError); + $all: function(a) { + return prepare.$and(a); + }, - function InvalidProtocolError(url) { - var _this; + /** + */ - (0, _classCallCheck2.default)(this, InvalidProtocolError); - _this = _super.call(this, "Invalid URL protocol ".concat(url.protocol)); - _this.url = url; - return _this; - } + $or: function(a) { + return a.map(parse); + }, - return InvalidProtocolError; -}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); + /** + */ -exports.InvalidProtocolError = InvalidProtocolError; + $nor: function(a) { + return a.map(parse); + }, -var InvalidCozyUrlError = /*#__PURE__*/function (_Error2) { - (0, _inherits2.default)(InvalidCozyUrlError, _Error2); + /** + */ - var _super2 = _createSuper(InvalidCozyUrlError); + $not: function(a) { + return parse(a); + }, - function InvalidCozyUrlError(url) { - var _this2; + /** + */ - (0, _classCallCheck2.default)(this, InvalidCozyUrlError); - _this2 = _super2.call(this, "URL ".concat(url.toString(), " does not seem to be a valid Cozy URL")); - _this2.url = url; - return _this2; - } + $regex: function(a, query) { + return new RegExp(a, query.$options); + }, - return InvalidCozyUrlError; -}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); -/* uri - Returns a well formed URL origin from a protocol, a hostname and a port - * - * If the protocol and/or port are omitted from the argument, the function will - * default to HTTPS and omit the port in the returned origin. - * - * @param {object} url Object of URL elements - * @param {string} url.protocol Protocol to use in the origin (e.g. http) - * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud) - * @param {string} url.port Port to use in the origin (e.g. 8080) - * - * @returns {string} Generated URL origin - */ + /** + */ + $where: function(a) { + return typeof a === 'string' ? new Function('obj', 'return ' + a) : a; + }, -exports.InvalidCozyUrlError = InvalidCozyUrlError; + /** + */ -var uri = function uri(_ref4) { - var protocol = _ref4.protocol, - hostname = _ref4.hostname, - port = _ref4.port; - return (protocol !== '' ? "".concat(protocol, "//") : 'https://') + hostname + (port !== '' ? ":".concat(port) : ''); -}; -/* wellKnownUrl - Returns a valid URL string to a Well Known password change page - * - * The built URL will point to the origin generated from the given protocol, - * hostname and port. - * - * @param {object} url Object of URL elements - * @param {string} url.protocol Protocol to use in the origin (e.g. http) - * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud) - * @param {string} url.port Port to use in the origin (e.g. 8080) - * - * @returns {string} Generated Well Known password change URL string - */ + $elemMatch: function(a) { + return parse(a); + }, + /** + */ -var wellKnownUrl = function wellKnownUrl(url) { - return uri(url) + '/.well-known/change-password'; -}; -/* isValidOrigin - Checks whether a given URL is a valid Cozy origin - * - * This method tries to fetch the Well Known change password page of the Cozy - * supposedly at the given origin. This allows us to determine whether the given - * origin is the root URL of a Cozy or not via the status of the response: - * - a 200 response status means there's an actual Well Known password change - * page accessible from the given origin so we suppose it's a valid Cozy - * origin (i.e. it could be another site altogether though) - * - a 401 response status means the pointed page requires authentication so the - * origin is probably pointing to a Cozy app - * - another status means there aren't any Cozy behind to the given origin - * - * @param {object} url Object of URL elements - * @param {string} url.protocol Protocol to use in the origin (e.g. http) - * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud) - * @param {string} url.port Port to use in the origin (e.g. 8080) - * - * @returns {Promise<boolean>} True if we believe there's a Cozy behind the given origin - * @throws {InvalidCozyUrlError} Thrown when we know for sure there aren't any Cozy behind the given origin - */ + $exists: function(a) { + return !!a; + } + }; + /** + */ -var isValidOrigin = /*#__PURE__*/function () { - var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) { - var _yield$fetch, status; + function search(array, validator) { - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return fetch(wellKnownUrl(url)); + for (var i = 0; i < array.length; i++) { + var result = get(array, i); + if (validate(validator, get(array, i))) { + return i; + } + } - case 2: - _yield$fetch = _context.sent; - status = _yield$fetch.status; + return -1; + } - if (!(status === 404)) { - _context.next = 6; - break; - } + /** + */ - throw new InvalidCozyUrlError(url); + function createValidator(a, validate) { + return { a: a, v: validate }; + } - case 6: - return _context.abrupt("return", status === 200); + /** + */ - case 7: - case "end": - return _context.stop(); - } + function nestedValidator(a, b) { + var values = []; + findValues(b, a.k, 0, b, values); + + if (values.length === 1) { + var first = values[0]; + return validate(a.nv, first[0], first[1], first[2]); + } + + // If the query contains $ne, need to test all elements ANDed together + var inclusive = a && a.q && typeof a.q.$ne !== 'undefined'; + var allValid = inclusive; + for (var i = 0; i < values.length; i++) { + var result = values[i]; + var isValid = validate(a.nv, result[0], result[1], result[2]); + if (inclusive) { + allValid &= isValid; + } else { + allValid |= isValid; } - }, _callee); - })); + } + return allValid; + } - return function isValidOrigin(_x) { - return _ref5.apply(this, arguments); - }; -}(); -/** - * rootCozyUrl - Get the root URL of a Cozy from more precise ones - * - * The goal is to allow users to use any URL copied from their browser as their - * Cozy URL rather than trying to explain to them what we expect (e.g. when - * requesting the Cozy URL to connect an app). - * If we can't get the root URL either because there's no Cozy or the domain - * does not exist or anything else, we'll throw an InvalidCozyUrlError. - * Also, since we communicate only via HTTP or HTTPS, we'll throw an - * InvalidProtocolError if any other protocol is used. - * - * This function expects a fully qualified URL thus with a protocol and a valid - * hostname. If your application accepts Cozy intances as input (e.g. `claude` - * when the Cozy can be found at `https://claude.mycozy.cloud`), it is your - * responsibility to add the appropriate domain to the hostname before calling - * this function. - * - * Examples: - * - * 1. getting the root URL when your user gives you its instance name - * - * const userInput = 'claude' - * const rootUrl = await rootCozyUrl(new URL(`https://${userInput}.mycozy.cloud`)) - * // → returns new URL('https://claude.mycozy.cloud') - * - * 2. getting the root URL when your user gives you a Cozy Drive URL - * - * const userInput = 'https://claude-drive.mycozy.cloud/#/folder/io.cozy.files.root-dir' - * const rootUrl = await rootCozyUrl(new URL(userInput)) - * // → returns new URL('https://claude.mycozy.cloud') - * - * 3. getting the root URL when the Cozy uses nested sub-domains - * - * const userInput = 'http://photos.camille.nimbus.com:8080/#/album/1234567890' - * const rootCozyUrl = await rootCozyUrl(new URL(userInput)) - * // → returns new URL('http://camille.nimbus.com:8080') - * - * @param {URL} url The URL from which we'll try to get the root Cozy URL - * - * @returns {Promise<URL>} The root Cozy URL - */ + /** + */ + + function findValues(current, keypath, index, object, values) { + + if (index === keypath.length || current == void 0) { + + values.push([current, keypath[index - 1], object]); + return; + } + + var k = get(keypath, index); + + // ensure that if current is an array, that the current key + // is NOT an array index. This sort of thing needs to work: + // sift({'foo.0':42}, [{foo: [42]}]); + if (isArray(current) && isNaN(Number(k))) { + for (var i = 0, n = current.length; i < n; i++) { + findValues(get(current, i), keypath, index, current, values); + } + } else { + findValues(get(current, k), keypath, index + 1, current, values); + } + } + /** + */ -var rootCozyUrl = /*#__PURE__*/function () { - var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(url) { - var _url$hostname$split, _url$hostname$split2, subDomain, domain, _hostname, hostname; + function createNestedValidator(keypath, a, q) { + return { a: { k: keypath, nv: a, q: q }, v: nestedValidator }; + } - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - if (['http:', 'https:'].includes(url.protocol)) { - _context2.next = 2; - break; - } + /** + * flatten the query + */ - throw new InvalidProtocolError(url); + function isVanillaObject(value) { + return value && value.constructor === Object; + } - case 2: - _context2.next = 4; - return isValidOrigin(url); + function parse(query) { + query = comparable(query); - case 4: - if (!_context2.sent) { - _context2.next = 6; - break; - } + if (!query || !isVanillaObject(query)) { // cross browser support + query = { $eq: query }; + } - return _context2.abrupt("return", url); + var validators = []; - case 6: - if (!/^[^.-][^.]+-[^.-]+\./.test(url.hostname)) { - _context2.next = 13; - break; - } + for (var key in query) { + var a = query[key]; - _url$hostname$split = url.hostname.split('.'), _url$hostname$split2 = (0, _toArray2.default)(_url$hostname$split), subDomain = _url$hostname$split2[0], domain = _url$hostname$split2.slice(1); - _hostname = [subDomain.replace(/-.+/, '')].concat((0, _toConsumableArray2.default)(domain)).join('.'); - _context2.next = 11; - return isValidOrigin({ - protocol: url.protocol, - hostname: _hostname, - port: url.port - }); + if (key === '$options') { + continue; + } - case 11: - if (!_context2.sent) { - _context2.next = 13; - break; - } + if (OPERATORS[key]) { + if (prepare[key]) a = prepare[key](a, query); + validators.push(createValidator(comparable(a), OPERATORS[key])); + } else { - return _context2.abrupt("return", new URL(uri({ - protocol: url.protocol, - hostname: _hostname, - port: url.port - }))); + if (key.charCodeAt(0) === 36) { + throw new Error('Unknown operation ' + key); + } + validators.push(createNestedValidator(key.split('.'), parse(a), a)); + } + } - case 13: - // Try to remove the first sub-domain in case its a nested app name - // eslint-disable-next-line no-unused-vars - hostname = url.hostname.split('.').splice(1).join('.'); - _context2.next = 16; - return isValidOrigin({ - protocol: url.protocol, - hostname: hostname, - port: url.port - }); + return validators.length === 1 ? validators[0] : createValidator(validators, OPERATORS.$and); + } - case 16: - if (!_context2.sent) { - _context2.next = 18; - break; - } + /** + */ - return _context2.abrupt("return", new URL(uri({ - protocol: url.protocol, - hostname: hostname, - port: url.port - }))); + function createRootValidator(query, getter) { + var validator = parse(query); + if (getter) { + validator = { + a: validator, + v: function(a, b, k, o) { + return validate(a, getter(b), k, o); + } + }; + } + return validator; + } - case 18: - throw new InvalidCozyUrlError(url); + /** + */ - case 19: - case "end": - return _context2.stop(); - } + function sift(query, array, getter) { + + if (isFunction(array)) { + getter = array; + array = void 0; + } + + var validator = createRootValidator(query, getter); + + function filter(b, k, o) { + return validate(validator, b, k, o); + } + + if (array) { + return array.filter(filter); + } + + return filter; + } + + /** + */ + + sift.use = function(plugin) { + if (isFunction(plugin)) return plugin(sift); + for (var key in plugin) { + /* istanbul ignore else */ + if (key.charCodeAt(0) === 36) { + OPERATORS[key] = plugin[key]; } - }, _callee2); - })); + } + }; - return function rootCozyUrl(_x2) { - return _ref6.apply(this, arguments); + /** + */ + + sift.indexOf = function(query, array, getter) { + return search(array, createRootValidator(query, getter)); }; -}(); -exports.rootCozyUrl = rootCozyUrl; + /** + */ + + sift.compare = function(a, b) { + if(a===b) return 0; + if(typeof a === typeof b) { + if (a > b) { + return 1; + } + if (a < b) { + return -1; + } + } + }; + + /* istanbul ignore next */ + if ( true && typeof module.exports !== 'undefined') { + Object.defineProperty(exports, "__esModule", ({ + value: true + })); + + module.exports = sift; + exports["default"] = module.exports["default"] = sift; + } + + /* istanbul ignore next */ + if (typeof window !== 'undefined') { + window.sift = sift; + } +})(); + /***/ }), -/* 757 */ +/* 750 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.authFunction = exports.authenticateWithCordova = void 0; +exports.receiveMutationError = exports.receiveMutationResult = exports.initMutation = exports.isReceivingMutationResult = exports.isMutationAction = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -var _const = __webpack_require__(685); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var _cozyDeviceHelper = __webpack_require__(758); +var INIT_MUTATION = 'INIT_MUTATION'; +var RECEIVE_MUTATION_RESULT = 'RECEIVE_MUTATION_RESULT'; +var RECEIVE_MUTATION_ERROR = 'RECEIVE_MUTATION_ERROR'; -var _types = __webpack_require__(610); +var isMutationAction = function isMutationAction(action) { + return [INIT_MUTATION, RECEIVE_MUTATION_RESULT, RECEIVE_MUTATION_ERROR].indexOf(action.type) !== -1; +}; -/* global prompt */ +exports.isMutationAction = isMutationAction; -/** - * @type {CordovaWindow} - */ -// @ts-ignore -var win = typeof window !== 'undefined' ? window : null; -/** - * Open a SafariView Controller and resolve with the URL containing the token - * - * @param {string} url - * @returns {Promise} - */ +var isReceivingMutationResult = function isReceivingMutationResult(action) { + return action.type === RECEIVE_MUTATION_RESULT; +}; // actions -var authenticateWithSafari = function authenticateWithSafari(url) { - return new Promise(function (resolve, reject) { - win.SafariViewController.show({ - url: url, - transition: 'curl' // (this only works in iOS 9.1/9.2 and lower) unless animated is false you can choose from: curl, flip, fade, slide (default) - // enterReaderModeIfAvailable: readerMode, // default false - // tintColor: "#00ffff", // default is ios blue - // barColor: "#0000ff", // on iOS 10+ you can change the background color as well - // controlTintColor: "#ffffff" // on iOS 10+ you can override the default tintColor - }, // this success handler will be invoked for the lifecycle events 'opened', 'loaded' and 'closed' - function (result) { - if (result.event === 'closed') { - reject(new Error(_const.REGISTRATION_ABORT)); - } - }, function (error) { - console.log('KO: ' + error); - reject(new Error(_const.REGISTRATION_ABORT)); - }); - var handle = win.handleOpenURL; +exports.isReceivingMutationResult = isReceivingMutationResult; - win.handleOpenURL = function (url) { - win.SafariViewController.hide(); - resolve(url); +var initMutation = function initMutation(mutationId, definition) { + return { + type: INIT_MUTATION, + mutationId: mutationId, + definition: definition + }; +}; - if (handle) { - win.handleOpenURL = handle; - } - }; +exports.initMutation = initMutation; + +var receiveMutationResult = function receiveMutationResult(mutationId, response) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var definition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + return _objectSpread(_objectSpread({ + type: RECEIVE_MUTATION_RESULT, + mutationId: mutationId, + response: response + }, options), {}, { + definition: definition }); }; -/** - * Opens an InAppBrowser and resolves with the URL containing the token - * - * @param {string} url - * @returns {Promise} - */ +exports.receiveMutationResult = receiveMutationResult; -var authenticateWithInAppBrowser = function authenticateWithInAppBrowser(url) { - return new Promise(function (resolve, reject) { - var target = '_blank'; - var options = 'clearcache=yes,zoom=no'; - var inAppBrowser = win.cordova.InAppBrowser.open(url, target, options); +var receiveMutationError = function receiveMutationError(mutationId, error) { + var definition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return { + type: RECEIVE_MUTATION_ERROR, + mutationId: mutationId, + error: error, + definition: definition + }; +}; - var removeListener = function removeListener() { - inAppBrowser.removeEventListener('loadstart', onLoadStart); - inAppBrowser.removeEventListener('exit', onExit); - }; +exports.receiveMutationError = receiveMutationError; - var onLoadStart = function onLoadStart(_ref) { - var url = _ref.url; - var accessCode = /\?access_code=(.+)$/.test(url); - var state = /\?state=(.+)$/.test(url); +/***/ }), +/* 751 */ +/***/ ((__unused_webpack_module, exports) => { - if (accessCode || state) { - resolve(url); - removeListener(); - inAppBrowser.close(); - } - }; +"use strict"; - var onExit = function onExit() { - reject(new Error(_const.REGISTRATION_ABORT)); - removeListener(); - inAppBrowser.close(); - }; - inAppBrowser.addEventListener('loadstart', onLoadStart); - inAppBrowser.addEventListener('exit', onExit); - }); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.properId = void 0; + +var properId = function properId(doc) { + return doc.id || doc._id; }; -var authenticateWithCordova = /*#__PURE__*/function () { - var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) { - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.t0 = (0, _cozyDeviceHelper.isIOSApp)(); +exports.properId = properId; - if (!_context.t0) { - _context.next = 5; - break; - } +/***/ }), +/* 752 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - _context.next = 4; - return (0, _cozyDeviceHelper.hasSafariPlugin)(); +"use strict"; - case 4: - _context.t0 = _context.sent; - case 5: - if (!_context.t0) { - _context.next = 9; - break; - } +var _interopRequireDefault = __webpack_require__(524); - return _context.abrupt("return", authenticateWithSafari(url)); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - case 9: - if (!(0, _cozyDeviceHelper.hasInAppBrowserPlugin)()) { - _context.next = 13; - break; - } +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - return _context.abrupt("return", authenticateWithInAppBrowser(url)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - case 13: - /** - * for dev purpose: - * In oauth workflow, the server displays an authorization page - * User must accept to give permission then the server gives an url - * with query parameters used by cozy-client-js to initialize itself. - * - * This hack let developers open the authorization page in a new tab - * then get the "access_code" url and paste it in the prompt to let the - * application initialize and redirect to other pages. - */ - console.log(url); // Useful for dev (see above). +var _types = __webpack_require__(622); - return _context.abrupt("return", new Promise(function (resolve) { - setTimeout(function () { - var token = prompt('Paste the url here:'); - resolve(token); - }, 5000); - })); +var _dsl = __webpack_require__(619); - case 15: - case "end": - return _context.stop(); - } - } - }, _callee); - })); +/** + * Associations are used by components to access related store documents that are + * linked in a document. They are also responsible for building the `QueryDefinition` that is + * used by the client to automatically fetch relationship data. + * + * Hydrated documents used by components come with Association instances. + * + * @interface + * + * @description + * Example: The schema defines an `author` relationship : + * + * ```js + * const BOOK_SCHEMA = { + * relationships: { + * author: 'has-one' + * } + * } + * ``` + * + * Hydrated `books` will have the `author` association instance under the `author` key. + * Accessing `hydratedBook.author.data` gives you the author from the store, for example : + * + * ```json + * { + * "name": "St-Exupery", + * "firstName": "Antoine", + * "_id": "antoine" + * } + * ``` + * + * It is the responsibility of the relationship to decide how the relationship data is stored. + * For example, here since we use the default `has-one` relationship, the relationship data + * is stored in the `relationships` attribute of the original document (in our case here, our book + * would be + * + * ```json + * { + * "title": "Le petit prince", + * "relationships": { + * "author": { + * "data": { + * "doctype": "io.cozy.authors", + * "_id": "antoine" + * } + * } + * } + * } + * ``` + * + * In the case of an "in-place" relationship, the relationship data is stored directly under the attribute named + * by the relationship (in our case `author`). Our book would be + * + * ```json + * { + * "title": "Le petit prince", + * "author": "antoine" + * } + * ``` + * + * --- + * + * Each different type of Association may change: + * + * - `get raw`: how the relationship data is stored (either as per the JSON API spec or + * in a custom way) + * - `get data`: how the store documents are then fetched from the store to be added to + * the hydrated document (.data method). View components will access + * `hydratedDoc[relationshipName].data`. + * - `get query`: how to build the query to fetch related documents + * + */ +var Association = /*#__PURE__*/function () { + /** + * @param {object} target - Original object containing raw data + * @param {string} name - Attribute under which the association is stored + * @param {string} doctype - Doctype of the documents managed by the association + * @param {object} options - Options passed from the client + * @param {Function} options.get - Get a document from the store + * @param {Function} options.query - Execute client query + * @param {Function} options.mutate - Execute client mutate + * @param {Function} options.save - Execute client save + * @param {Function} options.dispatch - Store's dispatch, comes from the client + */ + function Association(target, name, doctype, options) { + (0, _classCallCheck2.default)(this, Association); + var dispatch = options.dispatch, + get = options.get, + query = options.query, + mutate = options.mutate, + save = options.save; + /** + * The original document declaring the relationship + * + * @type {object} + */ - return function authenticateWithCordova(_x) { - return _ref2.apply(this, arguments); - }; + this.target = target; + /** + * The name of the relationship. + * + * @type {string} + * @example 'author' + */ + + this.name = name; + /** + * Doctype of the relationship + * + * @type {string} + * @example 'io.cozy.authors' + */ + + this.doctype = doctype; + /** + * Returns the document from the store + * + * @type {Function} + */ + + this.get = get; + /** + * Performs a query to retrieve relationship documents. + * + * @param {QueryDefinition} queryDefinition + * @function + */ + + this.query = query; + /** + * Performs a mutation on the relationship. + * + * @function + */ + + this.mutate = mutate; + /** + * Saves the relationship in store. + * + * @type {Function} + */ + + this.save = save; + /** + * Dispatch an action on the store. + * + * @type {Function} + */ + + this.dispatch = dispatch; + } + /** + * + * Returns the raw relationship data as stored in the original document + * + * For a document with relationships stored as JSON API spec: + * + * ```js + * const book = { + * title: 'Moby Dick', + * relationships: { + * author: { + * data: { + * doctype: 'io.cozy.authors', + * id: 'herman' + * } + * } + * } + * } + * ``` + * + * Raw value will be + * + * ```json + * { + * "doctype": "io.cozy.authors", + * "id": "herman" + * } + * ``` + * + * Derived `Association`s need to implement this method. + * + * @returns {object} + */ + + + (0, _createClass2.default)(Association, [{ + key: "raw", + get: function get() { + throw new Error('A relationship must define its raw getter'); + } + /** + * Returns the document(s) from the store + * + * For document with relationships stored as JSON API spec : + * + * ```js + * const book = { + * title: 'Moby Dick', + * relationships: { + * author: { + * data: { + * doctype: 'io.cozy.authors', + * id: 'herman' + * } + * } + * } + * } + * ``` + * + * `data` will be + * + * ```json + * { + * "_id": "herman" + * "_type": "io.cozy.authors", + * "firstName": "herman", + * "name": "Melville" + * } + * ``` + * + * Derived `Association`s need to implement this method. + * + * @returns {object} + */ + + }, { + key: "data", + get: function get() { + throw new Error('A relationship must define its data getter'); + } + /** + * Derived `Association`s need to implement this method. + * + * @param {CozyClientDocument} document - Document to query + * @param {object} client - The CozyClient instance + * @param {Association} assoc - Association containing info on how to build the query to fetch related documents + * + * @returns {CozyClientDocument | QueryDefinition } + */ + + }], [{ + key: "query", + value: function query(document, client, assoc) { + throw new Error('A custom relationship must define its query() function'); + } + }]); + return Association; }(); -exports.authenticateWithCordova = authenticateWithCordova; -var authFunction = authenticateWithCordova; -exports.authFunction = authFunction; +var _default = Association; +exports["default"] = _default; /***/ }), -/* 758 */ +/* 753 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; +var _interopRequireDefault = __webpack_require__(524); + Object.defineProperty(exports, "__esModule", ({ value: true })); -Object.defineProperty(exports, "getPlatform", ({ - enumerable: true, - get: function get() { - return _platform.getPlatform; - } -})); -Object.defineProperty(exports, "isIOSApp", ({ - enumerable: true, - get: function get() { - return _platform.isIOSApp; - } -})); -Object.defineProperty(exports, "isAndroidApp", ({ - enumerable: true, - get: function get() { - return _platform.isAndroidApp; - } -})); -Object.defineProperty(exports, "isWebApp", ({ - enumerable: true, - get: function get() { - return _platform.isWebApp; - } -})); -Object.defineProperty(exports, "isMobileApp", ({ - enumerable: true, - get: function get() { - return _platform.isMobileApp; - } -})); -Object.defineProperty(exports, "isAndroid", ({ - enumerable: true, - get: function get() { - return _platform.isAndroid; - } -})); -Object.defineProperty(exports, "isIOS", ({ - enumerable: true, - get: function get() { - return _platform.isIOS; - } -})); -Object.defineProperty(exports, "isMobile", ({ - enumerable: true, - get: function get() { - return _platform.isMobile; - } -})); -Object.defineProperty(exports, "getDeviceName", ({ - enumerable: true, - get: function get() { - return _device.getDeviceName; - } -})); -Object.defineProperty(exports, "checkApp", ({ - enumerable: true, - get: function get() { - return _apps.checkApp; - } -})); -Object.defineProperty(exports, "startApp", ({ - enumerable: true, - get: function get() { - return _apps.startApp; - } -})); -Object.defineProperty(exports, "hasDevicePlugin", ({ - enumerable: true, - get: function get() { - return _plugins.hasDevicePlugin; - } -})); -Object.defineProperty(exports, "hasInAppBrowserPlugin", ({ - enumerable: true, - get: function get() { - return _plugins.hasInAppBrowserPlugin; - } -})); -Object.defineProperty(exports, "hasSafariPlugin", ({ - enumerable: true, - get: function get() { - return _plugins.hasSafariPlugin; - } -})); -Object.defineProperty(exports, "hasNetworkInformationPlugin", ({ - enumerable: true, - get: function get() { - return _plugins.hasNetworkInformationPlugin; - } -})); -Object.defineProperty(exports, "isCordova", ({ - enumerable: true, - get: function get() { - return _cordova.isCordova; - } -})); -Object.defineProperty(exports, "nativeLinkOpen", ({ - enumerable: true, - get: function get() { - return _link.nativeLinkOpen; - } -})); -Object.defineProperty(exports, "openDeeplinkOrRedirect", ({ - enumerable: true, - get: function get() { - return _deeplink.openDeeplinkOrRedirect; - } -})); +exports["default"] = exports.updateRelationship = exports.updateHasManyItem = exports.removeHasManyItem = exports.setHasManyItem = exports.getHasManyItems = exports.getHasManyItem = void 0; -var _platform = __webpack_require__(759); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _device = __webpack_require__(761); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _apps = __webpack_require__(771); +var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(606)); -var _plugins = __webpack_require__(770); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -var _cordova = __webpack_require__(760); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var _link = __webpack_require__(772); +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var _deeplink = __webpack_require__(773); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -/***/ }), -/* 759 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); -"use strict"; +var _get = _interopRequireDefault(__webpack_require__(370)); +var _merge = _interopRequireDefault(__webpack_require__(754)); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.isMobile = exports.isIOS = exports.isAndroid = exports.isMobileApp = exports.isWebApp = exports.isAndroidApp = exports.isIOSApp = exports.getPlatform = void 0; +var _dsl = __webpack_require__(619); -var _cordova = __webpack_require__(760); +var _store = __webpack_require__(705); -var WEB_PLATFORM = 'web'; -var IOS_PLATFORM = 'ios'; -var ANDROID_PLATFORM = 'android'; +var _types = __webpack_require__(622); -var getPlatform = function getPlatform() { - return (0, _cordova.isCordova)() ? window.cordova.platformId : WEB_PLATFORM; -}; +var _Association2 = _interopRequireDefault(__webpack_require__(752)); -exports.getPlatform = getPlatform; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -var isPlatform = function isPlatform(platform) { - return getPlatform() === platform; -}; +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var isIOSApp = function isIOSApp() { - return isPlatform(IOS_PLATFORM); -}; +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -exports.isIOSApp = isIOSApp; +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -var isAndroidApp = function isAndroidApp() { - return isPlatform(ANDROID_PLATFORM); -}; +/** + * @typedef {object} Relationship + * @property {string} relName - name of the relationship + * @property {string} relItemId - id of the relation + * @property {Relation} relItemAttrs - Attributes to be set (at least _id and _type) + */ -exports.isAndroidApp = isAndroidApp; +/** + * @typedef {object} Relation + * @property {string} _id - id of the relation + * @property {string} _type - doctype of the relation + */ +var empty = function empty() { + return { + data: [], + next: true, + meta: { + count: 0 + } + }; +}; -var isWebApp = function isWebApp() { - return isPlatform(WEB_PLATFORM); +var updateArray = function updateArray(array, indexArg, el) { + var index = indexArg === -1 ? array.length : indexArg; + return [].concat((0, _toConsumableArray2.default)(array.slice(0, index)), [el], (0, _toConsumableArray2.default)(array.slice(index + 1))); }; +/** + * Related documents are stored in the relationships attribute of the object, + * following the JSON API spec. + * + * Responsible for + * + * - Creating relationships + * - Removing relationships + * + * @description + * + * ``` + * const schema = { + * todos: { + * doctype: 'io.cozy.todos', + * relationships: { + * tasks: { + * doctype: 'io.cozy.tasks', + * type: 'has-many' + * } + * } + * } + * } + * + * const todo = { + * label: "Protect people's privacy", + * relationships: { + * tasks: { + * data: [ + * {_id: 1, _type: 'io.cozy.tasks'}, + * {_id: 2, _type: 'io.cozy.tasks'} + * ] + * } + * } + * } + * ``` + */ -exports.isWebApp = isWebApp; -var isMobileApp = function isMobileApp() { - return (0, _cordova.isCordova)(); -}; // return if is on an Android Device (native or browser) +var HasMany = /*#__PURE__*/function (_Association) { + (0, _inherits2.default)(HasMany, _Association); + var _super = _createSuper(HasMany); -exports.isMobileApp = isMobileApp; + function HasMany() { + var _this; -var isAndroid = function isAndroid() { - return window.navigator.userAgent && window.navigator.userAgent.indexOf('Android') >= 0; -}; // return if is on an iOS Device (native or browser) + (0, _classCallCheck2.default)(this, HasMany); + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } -exports.isAndroid = isAndroid; + _this = _super.call.apply(_super, [this].concat(args)); + (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateRelationshipData", function (getUpdatedRelationshipData) { + return function (dispatch, getState) { + var previousRelationship = (0, _store.getDocumentFromState)(getState(), _this.target._type, _this.target._id); + dispatch((0, _store.receiveQueryResult)(null, { + data: _objectSpread(_objectSpread({}, previousRelationship), {}, { + relationships: _objectSpread(_objectSpread({}, previousRelationship.relationships), {}, (0, _defineProperty2.default)({}, _this.name, getUpdatedRelationshipData(previousRelationship.relationships[_this.name]))) + }) + })); + }; + }); + return _this; + } -var isIOS = function isIOS() { - return window.navigator.userAgent && /iPad|iPhone|iPod/.test(window.navigator.userAgent); -}; // isMobile checks if the user is on a smartphone : native app or browser + (0, _createClass2.default)(HasMany, [{ + key: "fetchMore", + value: function fetchMore() { + throw 'Not implemented'; + } + }, { + key: "exists", + value: function exists(document) { + return this.existsById(document._id); + } + }, { + key: "containsById", + value: function containsById(id) { + return this.getRelationship().data.find(function (_ref) { + var _id = _ref._id; + return id === _id; + }) !== undefined; + } + }, { + key: "existsById", + value: function existsById(id) { + return Boolean(this.containsById(id) && this.get(this.doctype, id)); + } + /** + * Add the relationships to the target document + * + * @param {CozyClientDocument[]} docsArg - Documents to add as relationships + * @returns {CozyClientDocument} The saved target document + */ + }, { + key: "add", + value: function add(docsArg) { + var docs = Array.isArray(docsArg) ? docsArg : [docsArg]; + var ids = docs.map(function (doc) { + return doc._id; + }); + return this.addById(ids); + } + /** + * Remove the relationships from the target document + * + * @param {CozyClientDocument[]} docsArg - Documents to remove as relationships + * @returns {CozyClientDocument} The saved target document + */ -exports.isIOS = isIOS; + }, { + key: "remove", + value: function remove(docsArg) { + var docs = Array.isArray(docsArg) ? docsArg : [docsArg]; + var ids = docs.map(function (doc) { + return doc._id; + }); + return this.removeById(ids); + } + /** + * Update target document with relationships + * + * @param {string[]} idsArg - The ids to add as a relationship + */ -var isMobile = function isMobile() { - return isAndroid() || isIOS(); -}; + }, { + key: "addTargetRelationships", + value: function addTargetRelationships(idsArg) { + var _this2 = this, + _this$target$relation; -exports.isMobile = isMobile; + if (!this.target.relationships) this.target.relationships = {}; -/***/ }), -/* 760 */ -/***/ ((__unused_webpack_module, exports) => { + if (!this.target.relationships[this.name]) { + this.target.relationships[this.name] = { + data: [] + }; + } -"use strict"; + var ids = Array.isArray(idsArg) ? idsArg : [idsArg]; + var newRelations = ids.filter(function (id) { + return !_this2.existsById(id); + }).map(function (id) { + return { + _id: id, + _type: _this2.doctype + }; + }); + (_this$target$relation = this.target.relationships[this.name].data).push.apply(_this$target$relation, (0, _toConsumableArray2.default)(newRelations)); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.isCordova = void 0; + this.updateMetaCount(); + } + /** + * Add a referenced document by id. You need to call save() + * in order to synchronize your document with the store. + * + * @todo We shouldn't create the array of relationship manually since + * it'll not be present in the store as well. + * We certainly should use something like `updateRelationship` + * + */ -// cordova -var isCordova = function isCordova() { - return typeof window !== 'undefined' && window.cordova !== undefined; -}; + }, { + key: "addById", + value: function addById(idsArg) { + this.addTargetRelationships(idsArg); + return this.save(this.target); + } + /** + * Remove relationships from target document + * + * @param {string[]} idsArg - The ids to remove from the target relationships + */ -exports.isCordova = isCordova; + }, { + key: "removeTargetRelationships", + value: function removeTargetRelationships(idsArg) { + var ids = Array.isArray(idsArg) ? idsArg : [idsArg]; + this.target.relationships[this.name].data = this.target.relationships[this.name].data.filter(function (_ref2) { + var _id = _ref2._id; + return !ids.includes(_id); + }); + this.updateMetaCount(); + } + }, { + key: "removeById", + value: function removeById(idsArg) { + this.removeTargetRelationships(idsArg); + return this.save(this.target); + } + }, { + key: "updateMetaCount", + value: function updateMetaCount() { + if ((0, _get.default)(this.target.relationships[this.name], 'meta.count') !== undefined) { + this.target.relationships[this.name].meta = _objectSpread(_objectSpread({}, this.target.relationships[this.name].meta), {}, { + count: this.target.relationships[this.name].data.length + }); + } + } + }, { + key: "getRelationship", + value: function getRelationship() { + var rawData = this.target[this.name]; + var relationship = (0, _get.default)(this.target, "relationships.".concat(this.name)); -/***/ }), -/* 761 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + if (!relationship) { + if (rawData && rawData.length) { + console.warn("You're trying to access data on a relationship that appear to not be loaded yet. You may want to use 'include()' on your query"); + } -"use strict"; + return empty(); + } + return relationship; + } + }, { + key: "updateTargetRelationship", + value: function updateTargetRelationship(store, updateFn) { + // TODO See if updateTargetRelationship is still used, removing it would enable us + // to remove store.readDocument and store.writeDocument and the StoreProxy + var prevTarget = store.readDocument(this.target._type, this.target._id); + store.writeDocument(this.updateRelationship(prevTarget, updateFn)); + } + }, { + key: "updateRelationship", + value: function updateRelationship(target, updateFn) { + return HasMany.updateRelationship(target, this.name, updateFn); + } + }, { + key: "dehydrate", + value: function dehydrate(doc) { + return _objectSpread(_objectSpread({}, doc), {}, { + relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, this.name, { + data: this.raw + })) + }); + } + /** + * @param {CozyClientDocument} document - Document to query + * @param {object} client - The CozyClient instance + * @param {Association} assoc - The query params + * + * @returns {CozyClientDocument | QueryDefinition} + */ -var _interopRequireDefault = __webpack_require__(512); + }, { + key: "raw", + get: function get() { + return this.getRelationship().data; + } + /** + * Returns store documents + */ -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.getDeviceName = void 0; + }, { + key: "data", + get: function get() { + var _this3 = this; -var _capitalize = _interopRequireDefault(__webpack_require__(762)); + return this.getRelationship().data.map(function (_ref3) { + var _id = _ref3._id, + _type = _ref3._type; + return _this3.get(_type, _id); + }).filter(Boolean); + } + }, { + key: "hasMore", + get: function get() { + return this.getRelationship().next; + } + /** + * Returns the total number of documents in the relationship. + * Does not handle documents absent from the store. If you want + * to do that, you can use .data.length. + * + * @returns {number} - Total number of documents in the relationships + */ -var _cordova = __webpack_require__(760); + }, { + key: "count", + get: function get() { + var relationship = this.getRelationship(); + return relationship.meta ? relationship.meta.count : relationship.data.length; + } + }], [{ + key: "query", + value: function query(document, client, assoc) { + var relationships = (0, _get.default)(document, "relationships.".concat(assoc.name, ".data"), []); + var ids = relationships.map(function (assoc) { + return assoc._id; + }); + return new _dsl.QueryDefinition({ + doctype: assoc.doctype, + ids: ids + }); + } + }]); + return HasMany; +}(_Association2.default); +/** + * Gets a relationship item with the relationship name and id + * + * @param {object} doc - Document to be updated + * @param {string} relName - Name of the relationship + * @param {string} relItemId - Id of the relationship item + */ -var _plugins = __webpack_require__(770); -var _platform = __webpack_require__(759); +var getHasManyItem = HasMany.getHasManyItem = function (doc, relName, relItemId) { + var relData = (0, _get.default)(doc, "relationships.".concat(relName, ".data"), []); + return relData.find(function (rel) { + return rel._id == relItemId; + }); +}; -var DEFAULT_DEVICE = 'Device'; // device +exports.getHasManyItem = getHasManyItem; -var getAppleModel = function getAppleModel(identifier) { - var devices = ['iPhone', 'iPad', 'Watch', 'AppleTV']; +var getHasManyItems = HasMany.getHasManyItems = function (doc, relName) { + return (0, _get.default)(doc, "relationships.".concat(relName, ".data"), []); +}; +/** + * Sets a relationship item with the relationship name and id + * + * @param {object} doc - Document to be updated + * @param {string} relName - Name of the relationship + * @param {string} relItemId - Id of the relationship item + * @param {object} relItemAttrs - Attributes to be set (at least _id and _type) + */ - for (var _i = 0, _devices = devices; _i < _devices.length; _i++) { - var device = _devices[_i]; - if (identifier.match(new RegExp(device))) { - return device; - } - } +exports.getHasManyItems = getHasManyItems; - return DEFAULT_DEVICE; +var setHasManyItem = HasMany.setHasManyItem = function (doc, relName, relItemId, relItemAttrs) { + var relData = HasMany.getHasManyItems(doc, relName); + var relIndex = relData.findIndex(function (rel) { + return rel._id === relItemId; + }); + var updatedRelItem = (0, _merge.default)({}, relData[relIndex], relItemAttrs); + var updatedRelData = updateArray(relData, relIndex, updatedRelItem); + var updatedDocument = HasMany.updateRelationship(doc, relName, function (relationship) { + return (0, _merge.default)({}, relationship, { + data: updatedRelData + }); + }); + return updatedDocument; }; +/** + * Remove one relationship item + * + * @param {object} doc - Document to be updated + * @param {string} relName - Name of the relationship + * @param {string} relItemId - Id of the relationship item + */ -var getDeviceName = function getDeviceName() { - if (!(0, _plugins.hasDevicePlugin)()) { - if ((0, _cordova.isCordova)()) { - console.warn('You should install `cordova-plugin-device`.'); // eslint-disable-line no-console - } - return DEFAULT_DEVICE; - } +exports.setHasManyItem = setHasManyItem; - var _window$device = window.device, - manufacturer = _window$device.manufacturer, - originalModel = _window$device.model; - var model = (0, _platform.isIOSApp)() ? getAppleModel(originalModel) : originalModel; - return "".concat((0, _capitalize.default)(manufacturer), " ").concat(model); +var removeHasManyItem = HasMany.removeHasManyItem = function (doc, relName, relItemId) { + var relData = HasMany.getHasManyItems(doc, relName); + var updatedRelData = relData.filter(function (rel) { + return rel._id !== relItemId; + }); + var updatedDocument = HasMany.updateRelationship(doc, relName, function () { + return { + data: updatedRelData + }; + }); + return updatedDocument; }; +/** + * Updates a relationship item with the relationship name and id + * + * @param {object} doc - Document to be updated + * @param {string} relName - Name of the relationship + * @param {string} relItemId - Id of the relationship item + * @param {Function} updater - receives the current relationship item and should + * return an updated version. Merge should be used in the updater + * if previous relationship item fields are to be kept. + */ -exports.getDeviceName = getDeviceName; -/***/ }), -/* 762 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +exports.removeHasManyItem = removeHasManyItem; -var toString = __webpack_require__(396), - upperFirst = __webpack_require__(763); +var updateHasManyItem = HasMany.updateHasManyItem = function (doc, relName, relItemId, updater) { + var relItem = HasMany.getHasManyItem(doc, relName, relItemId); + var updatedRelItem = updater(relItem); + return HasMany.setHasManyItem(doc, relName, relItemId, updatedRelItem); +}; -/** - * Converts the first character of `string` to upper case and the remaining - * to lower case. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to capitalize. - * @returns {string} Returns the capitalized string. - * @example - * - * _.capitalize('FRED'); - * // => 'Fred' - */ -function capitalize(string) { - return upperFirst(toString(string).toLowerCase()); -} +exports.updateHasManyItem = updateHasManyItem; -module.exports = capitalize; +var updateRelationship = HasMany.updateRelationship = function (doc, relName, updateFn) { + return _objectSpread(_objectSpread({}, doc), {}, { + relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, relName, _objectSpread(_objectSpread({}, doc.relationships ? doc.relationships[relName] : {}), updateFn(doc.relationships ? doc.relationships[relName] : {})))) + }); +}; +exports.updateRelationship = updateRelationship; +var _default = HasMany; +exports["default"] = _default; /***/ }), -/* 763 */ +/* 754 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var createCaseFirst = __webpack_require__(764); +var baseMerge = __webpack_require__(755), + createAssigner = __webpack_require__(760); /** - * Converts the first character of `string` to upper case. + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. * * @static * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the converted string. + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. * @example * - * _.upperFirst('fred'); - * // => 'Fred' + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; * - * _.upperFirst('FRED'); - * // => 'FRED' + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } */ -var upperFirst = createCaseFirst('toUpperCase'); +var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); +}); -module.exports = upperFirst; +module.exports = merge; /***/ }), -/* 764 */ +/* 755 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var castSlice = __webpack_require__(765), - hasUnicode = __webpack_require__(766), - stringToArray = __webpack_require__(767), - toString = __webpack_require__(396); +var Stack = __webpack_require__(416), + assignMergeValue = __webpack_require__(756), + baseFor = __webpack_require__(549), + baseMergeDeep = __webpack_require__(757), + isObject = __webpack_require__(52), + keysIn = __webpack_require__(579), + safeGet = __webpack_require__(758); /** - * Creates a function like `_.lowerFirst`. + * The base implementation of `_.merge` without support for multiple sources. * * @private - * @param {string} methodName The name of the `String` case method to use. - * @returns {Function} Returns the new case function. + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. */ -function createCaseFirst(methodName) { - return function(string) { - string = toString(string); - - var strSymbols = hasUnicode(string) - ? stringToArray(string) - : undefined; - - var chr = strSymbols - ? strSymbols[0] - : string.charAt(0); - - var trailing = strSymbols - ? castSlice(strSymbols, 1).join('') - : string.slice(1); +function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; - return chr[methodName]() + trailing; - }; + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); } -module.exports = createCaseFirst; +module.exports = baseMerge; /***/ }), -/* 765 */ +/* 756 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseSlice = __webpack_require__(617); +var baseAssignValue = __webpack_require__(546), + eq = __webpack_require__(397); /** - * Casts `array` to a slice if it's needed. + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. * * @private - * @param {Array} array The array to inspect. - * @param {number} start The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the cast slice. + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. */ -function castSlice(array, start, end) { - var length = array.length; - end = end === undefined ? length : end; - return (!start && end >= length) ? array : baseSlice(array, start, end); +function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } } -module.exports = castSlice; +module.exports = assignMergeValue; /***/ }), -/* 766 */ -/***/ ((module) => { - -/** Used to compose unicode character classes. */ -var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, - rsVarRange = '\\ufe0e\\ufe0f'; - -/** Used to compose unicode capture groups. */ -var rsZWJ = '\\u200d'; +/* 757 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ -var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); +var assignMergeValue = __webpack_require__(756), + cloneBuffer = __webpack_require__(582), + cloneTypedArray = __webpack_require__(595), + copyArray = __webpack_require__(583), + initCloneObject = __webpack_require__(596), + isArguments = __webpack_require__(444), + isArray = __webpack_require__(55), + isArrayLikeObject = __webpack_require__(564), + isBuffer = __webpack_require__(446), + isFunction = __webpack_require__(45), + isObject = __webpack_require__(52), + isPlainObject = __webpack_require__(631), + isTypedArray = __webpack_require__(449), + safeGet = __webpack_require__(758), + toPlainObject = __webpack_require__(759); /** - * Checks if `string` contains Unicode symbols. + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. * * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a symbol is found, else `false`. + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. */ -function hasUnicode(string) { - return reHasUnicode.test(string); -} - -module.exports = hasUnicode; +function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; -/***/ }), -/* 767 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + var isCommon = newValue === undefined; -var asciiToArray = __webpack_require__(768), - hasUnicode = __webpack_require__(766), - unicodeToArray = __webpack_require__(769); + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); -/** - * Converts `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ -function stringToArray(string) { - return hasUnicode(string) - ? unicodeToArray(string) - : asciiToArray(string); + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); } -module.exports = stringToArray; +module.exports = baseMergeDeep; /***/ }), -/* 768 */ +/* 758 */ /***/ ((module) => { /** - * Converts an ASCII `string` to an array. + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". * * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. */ -function asciiToArray(string) { - return string.split(''); -} - -module.exports = asciiToArray; +function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + if (key == '__proto__') { + return; + } -/***/ }), -/* 769 */ -/***/ ((module) => { + return object[key]; +} -/** Used to compose unicode character classes. */ -var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, - rsVarRange = '\\ufe0e\\ufe0f'; +module.exports = safeGet; -/** Used to compose unicode capture groups. */ -var rsAstral = '[' + rsAstralRange + ']', - rsCombo = '[' + rsComboRange + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsZWJ = '\\u200d'; -/** Used to compose unicode regexes. */ -var reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange + ']?', - rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; +/***/ }), +/* 759 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ -var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); +var copyObject = __webpack_require__(577), + keysIn = __webpack_require__(579); /** - * Converts a Unicode `string` to an array. + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } */ -function unicodeToArray(string) { - return string.match(reUnicode) || []; +function toPlainObject(value) { + return copyObject(value, keysIn(value)); } -module.exports = unicodeToArray; +module.exports = toPlainObject; /***/ }), -/* 770 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; +/* 760 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var baseRest = __webpack_require__(556), + isIterateeCall = __webpack_require__(761); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.hasNetworkInformationPlugin = exports.hasSafariPlugin = exports.hasInAppBrowserPlugin = exports.hasDevicePlugin = void 0; +/** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; -var _cordova = __webpack_require__(760); + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; -var hasDevicePlugin = function hasDevicePlugin() { - return (0, _cordova.isCordova)() && window.device !== undefined; -}; + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); +} -exports.hasDevicePlugin = hasDevicePlugin; +module.exports = createAssigner; -var hasInAppBrowserPlugin = function hasInAppBrowserPlugin() { - return (0, _cordova.isCordova)() && window.cordova.InAppBrowser !== undefined; -}; -exports.hasInAppBrowserPlugin = hasInAppBrowserPlugin; +/***/ }), +/* 761 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var hasSafariPlugin = function hasSafariPlugin() { - return new Promise(function (resolve) { - if (!(0, _cordova.isCordova)() || window.SafariViewController === undefined) { - resolve(false); - return; - } +var eq = __webpack_require__(397), + isArrayLike = __webpack_require__(458), + isIndex = __webpack_require__(448), + isObject = __webpack_require__(52); - window.SafariViewController.isAvailable(function (available) { - return resolve(available); - }); - }); -}; /** - * Check if the Cordova's cordova-plugin-network-information plugin is installed - * @see https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-network-information/ - * @returns {boolean} + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; +} +module.exports = isIterateeCall; -exports.hasSafariPlugin = hasSafariPlugin; - -var hasNetworkInformationPlugin = function hasNetworkInformationPlugin() { - return (0, _cordova.isCordova)() && window.navigator.connection !== undefined; -}; - -exports.hasNetworkInformationPlugin = hasNetworkInformationPlugin; /***/ }), -/* 771 */ +/* 762 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports.startApp = exports.checkApp = void 0; +exports["default"] = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _platform = __webpack_require__(759); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var cordovaPluginIsInstalled = function cordovaPluginIsInstalled() { - return window.startApp; -}; -/** - * Normalize startApp params for Android and iOS - */ +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var getParams = function getParams(_ref) { - var appId = _ref.appId, - uri = _ref.uri; +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); - if ((0, _platform.isAndroidApp)()) { - return { - package: appId - }; - } else { - return uri; - } -}; +var _get2 = _interopRequireDefault(__webpack_require__(370)); -var exported = {}; -/** - * Start an application if it is installed on the phone - * @returns Promise - False if the application was not able to be started - */ +var _set = _interopRequireDefault(__webpack_require__(763)); -var startApp = exported.startApp = /*#__PURE__*/function () { - var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(appInfo) { - var startAppPlugin, isAppInstalled, params; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - startAppPlugin = window.startApp; - _context.next = 3; - return exported.checkApp(appInfo); +var _dsl = __webpack_require__(619); - case 3: - isAppInstalled = _context.sent; +var _types = __webpack_require__(622); - if (!isAppInstalled) { - _context.next = 9; - break; - } +var _Association2 = _interopRequireDefault(__webpack_require__(752)); - params = getParams(appInfo); - return _context.abrupt("return", new Promise(function (resolve, reject) { - if (!cordovaPluginIsInstalled()) { - reject(new Error("Cordova plugin 'com.lampa.startapp' is not installed. This plugin is needed to start a native app. Required by cozy-bar")); - return; - } +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - startAppPlugin.set(params).start(resolve, reject); - })); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - case 9: - return _context.abrupt("return", false); +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } - case 10: - case "end": - return _context.stop(); - } - } - }, _callee); - })); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - return function (_x) { - return _ref2.apply(this, arguments); - }; -}(); -/** - * Check that an application is installed on the phone - * @returns Promise - Promise containing information on the application - * - * @example - * > checkApp({ appId: 'io.cozy.drive.mobile', uri: 'cozydrive://' }) - * Promise.resolve({ - * versionName: "0.9.2", - * packageName: "io.cozy.drive.mobile", - * versionCode: 902, - * applicationInfo: "ApplicationInfo{70aa0ef io.cozy.drive.mobile}" - * }) - */ +var HasOne = /*#__PURE__*/function (_Association) { + (0, _inherits2.default)(HasOne, _Association); + var _super = _createSuper(HasOne); -exports.startApp = startApp; + function HasOne() { + (0, _classCallCheck2.default)(this, HasOne); + return _super.apply(this, arguments); + } -var checkApp = exported.checkApp = /*#__PURE__*/function () { - var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(appInfo) { - var startAppPlugin, params; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - startAppPlugin = window.startApp; - params = getParams(appInfo); - return _context2.abrupt("return", new Promise(function (resolve, reject) { - if (!cordovaPluginIsInstalled()) { - reject(new Error("Cordova plugin 'com.lampa.startapp' is not installed.")); - return; - } + (0, _createClass2.default)(HasOne, [{ + key: "add", - startAppPlugin.set(params).check(function (infos) { - resolve(infos === 'OK' ? true : infos); - }, function (error) { - if (error === false || error.indexOf('NameNotFoundException') === 0) { - // Plugin returns an error 'NameNotFoundException' on Android and - // false on iOS when an application is not found. - // We prefer to always return false - resolve(false); - } else { - reject(error); - } - }); - })); + /** + * Add the relationship to the target document + * + * @param {CozyClientDocument} doc - Document to add as a relationship + * @returns {CozyClientDocument} The saved target document + */ + value: function add(doc) { + this.setRelationship(doc); + return this.save(this.target); + } + /** + * Remove the relationship from the target document + * + * @returns {CozyClientDocument} The saved target document + */ - case 3: - case "end": - return _context2.stop(); - } + }, { + key: "remove", + value: function remove() { + this.setRelationship(undefined); + return this.save(this.target); + } + }, { + key: "setRelationship", + value: function setRelationship(doc) { + if (doc && doc._type !== this.doctype) { + throw new Error("Tried to associate a ".concat(doc._type, " document to a HasOne relationship on ").concat(this.doctype, " document")); } - }, _callee2); - })); - - return function (_x2) { - return _ref3.apply(this, arguments); - }; -}(); - -exports.checkApp = checkApp; -var _default = exported; -exports["default"] = _default; - -/***/ }), -/* 772 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.nativeLinkOpen = void 0; - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); - -var _plugins = __webpack_require__(770); - -var nativeLinkOpen = /*#__PURE__*/function () { - var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) { - var url, target, options; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - url = _ref.url; - _context.next = 3; - return (0, _plugins.hasSafariPlugin)(); - - case 3: - _context.t0 = _context.sent; - if (!_context.t0) { - _context.next = 6; - break; - } + var path = "relationships[".concat(this.name, "].data"); - _context.t0 = window.SafariViewController; + if (doc) { + (0, _set.default)(this.target, path, { + _id: doc._id, + _type: doc._type + }); + } else { + (0, _set.default)(this.target, path, undefined); + } + } + }, { + key: "set", + value: function set(doc) { + console.warn('set is deprecated for has-one relationships. Use `add` instead.'); + this.setRelationship(doc); + } + }, { + key: "unset", + value: function unset() { + console.warn('unset is deprecated for has-one relationships. Use `remove` instead.'); + this.setRelationship(undefined); + } + }, { + key: "dehydrate", + value: function dehydrate(doc) { + if (!this.raw) { + return doc; + } - case 6: - if (!_context.t0) { - _context.next = 10; - break; - } + return _objectSpread(_objectSpread({}, doc), {}, { + relationships: _objectSpread(_objectSpread({}, doc.relationships), {}, (0, _defineProperty2.default)({}, this.name, { + data: this.raw + })) + }); + } + }, { + key: "raw", + get: function get() { + return (0, _get2.default)(this.target, "relationships[".concat(this.name, "].data"), null); + } + }, { + key: "data", + get: function get() { + if (!this.raw) { + return null; + } - window.SafariViewController.show({ - url: url, - transition: 'curl' - }, function (result) { - if (result.event === 'closed') { - window.SafariViewController.hide(); - } - }, function () { - window.SafariViewController.hide(); - }); - _context.next = 11; - break; + return this.get(this.doctype, this.raw._id); + } + /** + * @param {CozyClientDocument} document - Document to query + * @param {object} client - The CozyClient instance + * @param {Association} assoc - The query params + * + * @returns {CozyClientDocument | QueryDefinition} + */ - case 10: - if ((0, _plugins.hasInAppBrowserPlugin)()) { - target = '_blank'; - options = 'clearcache=yes,zoom=no'; - window.cordova.InAppBrowser.open(url, target, options); - } else { - window.location = url; - } + }], [{ + key: "query", + value: function query(document, client, assoc) { + var relationship = (0, _get2.default)(document, "relationships.".concat(assoc.name, ".data"), {}); - case 11: - case "end": - return _context.stop(); - } + if (!relationship || !relationship._id) { + return null; } - }, _callee); - })); - return function nativeLinkOpen(_x) { - return _ref2.apply(this, arguments); - }; -}(); + return (0, _dsl.Q)(assoc.doctype).getById(relationship._id); + } + }]); + return HasOne; +}(_Association2.default); -exports.nativeLinkOpen = nativeLinkOpen; +exports["default"] = HasOne; /***/ }), -/* 773 */ -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - +/* 763 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.openDeeplinkOrRedirect = void 0; +var baseSet = __webpack_require__(662); /** - * This file is used to open the native app from a webapp - * if this native app is installed + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. * - * From a webapp, we don't have any clue if a native app is installed. - * The only way to know that, is to try to open the custom link - * (aka cozydrive://) and if nothing happens (no blur) we redirect to - * the callback + * **Note:** This method mutates `object`. * - * Firefox tries to open custom link, so we need to create an iframe - * to detect if this is supported or not - */ -var _createHiddenIframe = function _createHiddenIframe(target, uri, randomId) { - var iframe = document.createElement('iframe'); - iframe.src = uri; - iframe.id = "hiddenIframe_".concat(randomId); - iframe.style.display = 'none'; - target.appendChild(iframe); - return iframe; -}; - -var openUriWithHiddenFrame = function openUriWithHiddenFrame(uri, failCb) { - var randomId = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5); - window.addEventListener('blur', onBlur); - - var iframe = _createHiddenIframe(document.body, 'about:blank', randomId); - - var timeout = setTimeout(function () { - failCb(); - window.removeEventListener('blur', onBlur); - iframe.parentElement.removeChild(iframe); - }, 500); - - function onBlur() { - clearTimeout(timeout); - window.removeEventListener('blur', onBlur); - iframe.parentElement.removeChild(iframe); - } - - iframe.contentWindow.location.href = uri; -}; - -var openUriWithTimeoutHack = function openUriWithTimeoutHack(uri, failCb) { - var timeout = setTimeout(function () { - failCb(); - target.removeEventListener('blur', onBlur); - }, 500); // handle page running in an iframe (blur must be registered with top level window) - - var target = window; - - while (target != target.parent) { - target = target.parent; - } - - target.addEventListener('blur', onBlur); - - function onBlur() { - clearTimeout(timeout); - target.removeEventListener('blur', onBlur); - } - - window.location = uri; -}; - -var openUriWithMsLaunchUri = function openUriWithMsLaunchUri(uri, failCb) { - navigator.msLaunchUri(uri, undefined, failCb); -}; - -var checkBrowser = function checkBrowser() { - var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; - var ua = navigator.userAgent.toLowerCase(); - var isSafari = ua.includes('safari') && !ua.includes('chrome') || Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; - var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; - var isIOS122 = isIOS && (ua.includes('os 12_2') || ua.includes('os 12_3')); - return { - isOpera: isOpera, - isFirefox: typeof InstallTrigger !== 'undefined', - isSafari: isSafari, - isChrome: !!window.chrome && !isOpera, - isIOS122: isIOS122, - isIOS: isIOS - }; -}; -/** + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example * - * @param {String} deeplink (cozydrive://) - * @param {String} failCb (http://drive.cozy.ios) + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 */ +function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); +} +module.exports = set; -var openDeeplinkOrRedirect = function openDeeplinkOrRedirect(deeplink, failCb) { - if (navigator.msLaunchUri) { - // for IE and Edge in Win 8 and Win 10 - openUriWithMsLaunchUri(deeplink, failCb); - } else { - var browser = checkBrowser(); - - if (browser.isChrome || browser.isIOS && !browser.isIOS122) { - openUriWithTimeoutHack(deeplink, failCb); - } else if (browser.isSafari && !browser.isIOS122 || browser.isFirefox) { - openUriWithHiddenFrame(deeplink, failCb); - } else { - failCb(); - } - } -}; - -exports.openDeeplinkOrRedirect = openDeeplinkOrRedirect; /***/ }), -/* 774 */ +/* 764 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = void 0; - -var _mapValues = _interopRequireDefault(__webpack_require__(533)); - -var _groupBy2 = _interopRequireDefault(__webpack_require__(724)); - -var _flatten = _interopRequireDefault(__webpack_require__(540)); - -var _isEqual = _interopRequireDefault(__webpack_require__(646)); +exports.BelongsToInPlace = exports["default"] = void 0; -var _uniq = _interopRequireDefault(__webpack_require__(612)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _uniqWith = _interopRequireDefault(__webpack_require__(775)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _dsl = __webpack_require__(607); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var isIdQuery = function isIdQuery(query) { - return query.id || query.ids; -}; -/** - * Optimize queries on a single doctype - * - * @param {QueryDefinition[]} queries - Queries of a same doctype - * @returns {QueryDefinition[]} Optimized queries - * @private - */ +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var optimizeDoctypeQueries = function optimizeDoctypeQueries(queries) { - var _groupBy = (0, _groupBy2.default)(queries, function (q) { - return isIdQuery(q) ? 'idQueries' : 'others'; - }), - _groupBy$idQueries = _groupBy.idQueries, - idQueries = _groupBy$idQueries === void 0 ? [] : _groupBy$idQueries, - _groupBy$others = _groupBy.others, - others = _groupBy$others === void 0 ? [] : _groupBy$others; +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); - var groupedIdQueries = idQueries.length > 0 ? new _dsl.QueryDefinition({ - doctype: queries[0].doctype, - ids: (0, _uniq.default)((0, _flatten.default)(idQueries.map(function (q) { - return q.id || q.ids; - }))) - }) : []; // Deduplicate before concataining +var _Association2 = _interopRequireDefault(__webpack_require__(752)); - return (0, _uniqWith.default)(others, _isEqual.default).concat(groupedIdQueries); -}; -/** - * Reduce the number of queries used to fetch documents. - * - * - Deduplication of queries - * - Groups id queries - * - * @param {QueryDefinition[]} queries - Queries to optimized - * @returns {QueryDefinition[]} Optimized queries - * @private - */ +var _dsl = __webpack_require__(619); +var _types = __webpack_require__(622); -var optimizeQueries = function optimizeQueries(queries) { - var byDoctype = (0, _groupBy2.default)(queries, function (q) { - return q.doctype; - }); - return (0, _flatten.default)(Object.values((0, _mapValues.default)(byDoctype, optimizeDoctypeQueries))); -}; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -var _default = optimizeQueries; -exports["default"] = _default; +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -/***/ }), -/* 775 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -var baseUniq = __webpack_require__(463); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } /** - * This method is like `_.uniq` except that it accepts `comparator` which - * is invoked to compare elements of `array`. The order of result values is - * determined by the order they occur in the array.The comparator is invoked - * with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.uniqWith(objects, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] + * Here the id of the document is directly set in the attribute + * of the document, not in the relationships attribute */ -function uniqWith(array, comparator) { - comparator = typeof comparator == 'function' ? comparator : undefined; - return (array && array.length) ? baseUniq(array, undefined, comparator) : []; -} - -module.exports = uniqWith; - - -/***/ }), -/* 776 */ -/***/ ((__unused_webpack_module, exports) => { +var HasOneInPlace = /*#__PURE__*/function (_Association) { + (0, _inherits2.default)(HasOneInPlace, _Association); -"use strict"; + var _super = _createSuper(HasOneInPlace); + function HasOneInPlace() { + (0, _classCallCheck2.default)(this, HasOneInPlace); + return _super.apply(this, arguments); + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + (0, _createClass2.default)(HasOneInPlace, [{ + key: "dehydrate", + value: function dehydrate(doc) { + return _objectSpread(_objectSpread({}, doc), {}, (0, _defineProperty2.default)({}, this.name, this.raw || undefined)); + } + }, { + key: "raw", + get: function get() { + return this.target[this.name]; + } + }, { + key: "data", + get: function get() { + return this.get(this.doctype, this.raw); + } + /** + * @param {CozyClientDocument} document - Document to query + * @param {object} client - The CozyClient instance + * @param {Association} assoc - The query params + * + * @returns {CozyClientDocument | QueryDefinition} + */ -/** - * Use those fetch policies with `<Query />` to limit the number of re-fetch. - * - * @example - * ``` - * import { fetchPolicies } from 'cozy-client' - * const olderThan30s = fetchPolicies.olderThan(30 * 1000) - * <Query fetchPolicy={olderThan30s} /> - * ``` - */ -var fetchPolicies = { - /** - * Returns a fetchPolicy that will only re-fetch queries that are older - * than `<delay>` ms. - * - * @param {number} delay - Milliseconds since the query has been fetched - * @returns {Function} Fetch policy to be used with `<Query />` - */ - olderThan: function olderThan(delay) { - return function (queryState) { - if (!queryState || !queryState.lastUpdate) { - return true; - } else { - var elapsed = Date.now() - queryState.lastUpdate; - return elapsed > delay; - } - }; - }, + }], [{ + key: "query", + value: function query(document, client, assoc) { + var id = document[assoc.name]; + return client.getDocumentFromState(assoc.doctype, id) || (0, _dsl.Q)(assoc.doctype).getById(id); + } + }]); + return HasOneInPlace; +}(_Association2.default); - /** - * Fetch policy that deactivates any fetching. - */ - noFetch: function noFetch() { - return false; - } -}; -var _default = fetchPolicies; -exports["default"] = _default; +exports["default"] = HasOneInPlace; +var BelongsToInPlace = HasOneInPlace; +exports.BelongsToInPlace = BelongsToInPlace; /***/ }), -/* 777 */ +/* 765 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports["default"] = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _keyBy = _interopRequireDefault(__webpack_require__(699)); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -var _mapValues = _interopRequireDefault(__webpack_require__(533)); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -var _merge = _interopRequireDefault(__webpack_require__(742)); +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -var _size = _interopRequireDefault(__webpack_require__(778)); +var _dsl = __webpack_require__(619); -var _intersectionBy = _interopRequireDefault(__webpack_require__(782)); +var _types = __webpack_require__(622); -var _associations = __webpack_require__(691); +var _Association2 = _interopRequireDefault(__webpack_require__(752)); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -/** - * @typedef {object} DoctypeSchema - */ +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -/** - * @typedef {Record<string, DoctypeSchema>} SchemaDefinition - */ +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } /** - * Returns a normalized schema object from the schema definition. * - * - Relationships are resolved to classes if needed - * - The name of the relationship (its key in the schema definition) - * is included in the relationship - * - Empty relationships are nulled + * Used when related documents are stored directly under the attribute with + * only the ids. * - * @private - */ -var normalizeDoctypeSchema = function normalizeDoctypeSchema(doctypeSchema) { - var relationships = (0, _mapValues.default)(doctypeSchema.relationships || {}, function (v, k) { - return _objectSpread(_objectSpread({}, v), {}, { - name: k, - type: (0, _associations.resolveClass)(v.doctype, v.type) - }); - }); - return _objectSpread(_objectSpread({}, doctypeSchema), {}, { - relationships: (0, _size.default)(relationships) > 0 ? (0, _keyBy.default)(relationships, 'name') : null - }); -}; - -var assert = function assert(predicate, errorMessage) { - if (!predicate) throw new Error(errorMessage); -}; - -var ensureCanBeAdded = function ensureCanBeAdded(newSchemas, existingSchemas) { - var sameNames = (0, _intersectionBy.default)(newSchemas, existingSchemas, function (x) { - return x.name; - }); - assert(sameNames.length === 0, "Duplicated names in schemas being added: ".concat(sameNames.map(function (x) { - return x.name; - }).join(', '))); - var sameDoctypes = (0, _intersectionBy.default)(newSchemas, existingSchemas, function (x) { - return x.doctype; - }); - assert(sameDoctypes.length === 0, "Duplicated doctypes in schemas being added: ".concat(sameDoctypes.map(function (x) { - return x.name; - }).join(', '))); -}; -/** - * Stores information on a particular doctype. + * @property {Function} get * - * - Attribute validation - * - Relationship access + * @description + * + * An example document representing a TODO. See as the related + * tasks are represented via ids. * * ```js - * const schema = new Schema({ + * const todo = { + * label: "Protect people's privacy", + * tasks: [1, 2] + * } + * ``` + * + * Here is the `Schema` that would represent this kind of document. + * Components receiving todos via `Query`s would have an instance of `HasManyInPlace` + * as their `tasks` attribute. + * + * ```js + * const schema = { * todos: { - * attributes: { - * label: { - * unique: true - * } - * }, - * relationships: { - * author: 'has-one-in-place' - * } - * } - * }, cozyStackClient) + * doctype: 'io.cozy.todos', + * relationships: { + * tasks: { + * doctype: 'io.cozy.tasks', + * type: 'has-many-in-place' + * } + * } + * } + * } + * + * const todo = { + * label: "Get rich", + * tasks: [1, 2] + * } * ``` + * */ +var HasManyInPlace = /*#__PURE__*/function (_Association) { + (0, _inherits2.default)(HasManyInPlace, _Association); + var _super = _createSuper(HasManyInPlace); -var Schema = /*#__PURE__*/function () { - /** - * @param {SchemaDefinition} schemaDefinition - Schema for the application documents - * @param {object} client - An instance of cozy client (optional) - */ - function Schema() { - var schemaDefinition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var client = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - (0, _classCallCheck2.default)(this, Schema); - this.byDoctype = {}; - this.add(schemaDefinition); - this.client = client; + function HasManyInPlace() { + (0, _classCallCheck2.default)(this, HasManyInPlace); + return _super.apply(this, arguments); } - /** - * @param {SchemaDefinition} schemaDefinition - Additional schema to merge to current schema - */ + (0, _createClass2.default)(HasManyInPlace, [{ + key: "addById", + value: function addById(id) { + var rel = this.getRelationship(); + rel.push(id); + } + }, { + key: "removeById", + value: function removeById(id) { + var rel = this.getRelationship(); + var index = rel.indexOf(id); - (0, _createClass2.default)(Schema, [{ - key: "add", - value: function add() { - var schemaDefinition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var normalizedSchemaDefinition = (0, _mapValues.default)(schemaDefinition, function (obj, name) { - return _objectSpread({ - name: name - }, normalizeDoctypeSchema(obj)); - }); - ensureCanBeAdded(Object.values(normalizedSchemaDefinition), Object.values(this.byDoctype)); - (0, _merge.default)(this.byDoctype, (0, _keyBy.default)(normalizedSchemaDefinition, function (x) { - return x.doctype; - })); + if (index !== -1) { + rel.splice(index, 1); + } + } + }, { + key: "existsById", + value: function existsById(id) { + var rel = this.getRelationship(); + return rel.indexOf(id) !== -1; + } + }, { + key: "getRelationship", + value: function getRelationship() { + this.target[this.name] = this.target[this.name] || []; + return this.target[this.name]; + } + }, { + key: "dehydrate", + value: function dehydrate(doc) { + return _objectSpread(_objectSpread({}, doc), {}, (0, _defineProperty2.default)({}, this.name, this.raw || [])); } + }, { + key: "raw", + /** - * Returns the schema for a doctype - * - * Creates an empty schema implicitly if it does not exist + * Raw property * - * @param {string} doctype - Doctype + * @type {Array<string>} */ - + get: function get() { + return this.target[this.name]; + } }, { - key: "getDoctypeSchema", - value: function getDoctypeSchema(doctype) { - var schema = this.byDoctype[doctype]; - - if (!schema) { - schema = normalizeDoctypeSchema({ - name: doctype, - doctype: doctype - }); - this.byDoctype[doctype] = schema; - } + key: "data", + get: function get() { + var _this = this; - return schema; + var doctype = this.doctype; + return (this.raw || []).map(function (_id) { + return _this.get(doctype, _id); + }); } /** - * Returns the relationship for a given doctype/name + * @param {CozyClientDocument} document - Document to query + * @param {object} client - The CozyClient instance + * @param {Association} assoc - The query params * - * @param {string} doctype - Doctype - * @param {string} relationshipName - Relationship name + * @returns {CozyClientDocument | QueryDefinition} */ - }, { - key: "getRelationship", - value: function getRelationship(doctype, relationshipName) { - if (!doctype) { - throw new TypeError("Invalid doctype ".concat(doctype)); - } - - var schema = this.getDoctypeSchema(doctype); - - if (!schema) { - throw new Error("Cannot find doctype ".concat(doctype, " in schema")); - } + }], [{ + key: "query", + value: function query(document, client, assoc) { + var ids = document[assoc.name]; - if (!schema.relationships) { - throw new Error("Schema for doctype ".concat(doctype, " has no relationships")); + if (ids && ids > 0) { + return (0, _dsl.Q)(assoc.doctype).getByIds(ids); + } else { + return null; } - - return schema.relationships[relationshipName]; } - /** - * Validates a document considering the descriptions in schema.attributes. - */ + }]); + return HasManyInPlace; +}(_Association2.default); - }, { - key: "validate", - value: function () { - var _validate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(document) { - var errors, schema, n, ret; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - errors = {}; - schema = this.byDoctype[document._type]; +var _default = HasManyInPlace; +exports["default"] = _default; - if (schema) { - _context.next = 4; - break; - } +/***/ }), +/* 766 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - return _context.abrupt("return", true); +"use strict"; - case 4: - if (schema.attributes) { - _context.next = 6; - break; - } - return _context.abrupt("return", true); +var _interopRequireDefault = __webpack_require__(524); - case 6: - _context.t0 = _regenerator.default.keys(schema.attributes); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - case 7: - if ((_context.t1 = _context.t0()).done) { - _context.next = 15; - break; - } +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - n = _context.t1.value; - _context.next = 11; - return this.validateAttribute(document, n, schema.attributes[n]); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - case 11: - ret = _context.sent; - if (ret !== true) errors[n] = ret; - _context.next = 7; - break; +var _get2 = _interopRequireDefault(__webpack_require__(682)); - case 15: - if (!(Object.keys(errors).length === 0)) { - _context.next = 17; - break; - } +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); - return _context.abrupt("return", true); +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); - case 17: - return _context.abrupt("return", errors); +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); - case 18: - case "end": - return _context.stop(); - } - } - }, _callee, this); - })); +var _HasMany2 = _interopRequireDefault(__webpack_require__(753)); - function validate(_x) { - return _validate.apply(this, arguments); - } +var _dsl = __webpack_require__(619); - return validate; - }() - }, { - key: "validateAttribute", - value: function () { - var _validateAttribute = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(document, attrName, attrProps) { - var ret; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - if (!(attrProps.unique && this.client)) { - _context2.next = 6; - break; - } +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } - _context2.next = 3; - return this.client.collection(document._type).checkUniquenessOf(attrName, document[attrName]); +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - case 3: - ret = _context2.sent; +var TRIGGERS_DOCTYPE = 'io.cozy.triggers'; +/** + * Association used for konnectors to retrieve all their related triggers. + * + * @augments HasMany + */ - if (!(ret !== true)) { - _context2.next = 6; - break; - } +var HasManyTriggers = /*#__PURE__*/function (_HasMany) { + (0, _inherits2.default)(HasManyTriggers, _HasMany); - return _context2.abrupt("return", 'must be unique'); + var _super = _createSuper(HasManyTriggers); - case 6: - return _context2.abrupt("return", true); + function HasManyTriggers() { + (0, _classCallCheck2.default)(this, HasManyTriggers); + return _super.apply(this, arguments); + } - case 7: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); + (0, _createClass2.default)(HasManyTriggers, [{ + key: "data", + get: function get() { + var _this = this; - function validateAttribute(_x2, _x3, _x4) { - return _validateAttribute.apply(this, arguments); - } + return (0, _get2.default)((0, _getPrototypeOf2.default)(HasManyTriggers.prototype), "data", this).filter(function (_ref) { + var slug = _ref.slug; + return slug === _this.target.slug; + }); + } + /** + * In this association the query is special, we need to fetch all the triggers + * having for the 'konnector' worker, and then filter them based on their + * `message.konnector` attribute + */ - return validateAttribute; - }() + }], [{ + key: "query", + value: function query(doc, client) { + return (0, _dsl.Q)(TRIGGERS_DOCTYPE).where({ + worker: 'konnector' + }); + } }]); - return Schema; -}(); + return HasManyTriggers; +}(_HasMany2.default); -var _default = Schema; +var _default = HasManyTriggers; exports["default"] = _default; /***/ }), -/* 778 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var baseKeys = __webpack_require__(442), - getTag = __webpack_require__(447), - isArrayLike = __webpack_require__(446), - isString = __webpack_require__(54), - stringSize = __webpack_require__(779); - -/** `Object#toString` result references. */ -var mapTag = '[object Map]', - setTag = '[object Set]'; +/* 767 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -/** - * Gets the size of `collection` by returning its length for array-like - * values or the number of own enumerable string keyed properties for objects. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns the collection size. - * @example - * - * _.size([1, 2, 3]); - * // => 3 - * - * _.size({ 'a': 1, 'b': 2 }); - * // => 2 - * - * _.size('pebbles'); - * // => 7 - */ -function size(collection) { - if (collection == null) { - return 0; - } - if (isArrayLike(collection)) { - return isString(collection) ? stringSize(collection) : collection.length; - } - var tag = getTag(collection); - if (tag == mapTag || tag == setTag) { - return collection.size; - } - return baseKeys(collection).length; -} +"use strict"; -module.exports = size; +var _interopRequireDefault = __webpack_require__(524); -/***/ }), -/* 779 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getReferencedById = exports.getReferencedBy = exports.isReferencedById = exports.isReferencedBy = exports.create = exports.resolveClass = exports.attachRelationships = exports.responseToRelationship = exports.pickTypeAndId = void 0; -var asciiSize = __webpack_require__(780), - hasUnicode = __webpack_require__(766), - unicodeSize = __webpack_require__(781); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -/** - * Gets the number of symbols in `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the string size. - */ -function stringSize(string) { - return hasUnicode(string) - ? unicodeSize(string) - : asciiSize(string); -} +var _pick = _interopRequireDefault(__webpack_require__(676)); -module.exports = stringSize; +var _pickBy = _interopRequireDefault(__webpack_require__(660)); +var _Association = _interopRequireDefault(__webpack_require__(752)); -/***/ }), -/* 780 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _HasOne = _interopRequireDefault(__webpack_require__(762)); -var baseProperty = __webpack_require__(461); +var _HasOneInPlace = _interopRequireDefault(__webpack_require__(764)); -/** - * Gets the size of an ASCII `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ -var asciiSize = baseProperty('length'); +var _HasMany = _interopRequireDefault(__webpack_require__(753)); -module.exports = asciiSize; +var _HasManyInPlace = _interopRequireDefault(__webpack_require__(765)); +var _HasManyFiles = _interopRequireDefault(__webpack_require__(704)); -/***/ }), -/* 781 */ -/***/ ((module) => { +var _types = __webpack_require__(622); -/** Used to compose unicode character classes. */ -var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, - rsVarRange = '\\ufe0e\\ufe0f'; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } -/** Used to compose unicode capture groups. */ -var rsAstral = '[' + rsAstralRange + ']', - rsCombo = '[' + rsComboRange + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsZWJ = '\\u200d'; +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -/** Used to compose unicode regexes. */ -var reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange + ']?', - rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; +var pickTypeAndId = function pickTypeAndId(x) { + return (0, _pick.default)(x, '_type', '_id'); +}; -/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ -var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); +exports.pickTypeAndId = pickTypeAndId; -/** - * Gets the size of a Unicode `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ -function unicodeSize(string) { - var result = reUnicode.lastIndex = 0; - while (reUnicode.test(string)) { - ++result; - } - return result; -} +var applyHelper = function applyHelper(fn, objOrArr) { + return Array.isArray(objOrArr) ? objOrArr.map(fn) : fn(objOrArr); +}; -module.exports = unicodeSize; +var responseToRelationship = function responseToRelationship(response) { + return (0, _pickBy.default)({ + data: applyHelper(pickTypeAndId, response.data), + meta: response.meta, + next: response.next, + skip: response.skip, + bookmark: response.bookmark + }); +}; +exports.responseToRelationship = responseToRelationship; -/***/ }), -/* 782 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var attachRelationship = function attachRelationship(doc, relationships) { + return _objectSpread(_objectSpread({}, doc), {}, { + relationships: _objectSpread(_objectSpread({}, doc.relationships), relationships) + }); +}; -var arrayMap = __webpack_require__(398), - baseIntersection = __webpack_require__(728), - baseIteratee = __webpack_require__(401), - baseRest = __webpack_require__(544), - castArrayLikeObject = __webpack_require__(729), - last = __webpack_require__(615); +var attachRelationships = function attachRelationships(response, relationshipsByDocId) { + if (Array.isArray(response.data)) { + return _objectSpread(_objectSpread({}, response), {}, { + data: response.data.map(function (doc) { + return attachRelationship(doc, relationshipsByDocId[doc._id]); + }) + }); + } else { + var doc = response.data; + return _objectSpread(_objectSpread({}, response), {}, { + data: attachRelationship(doc, relationshipsByDocId[doc._id]) + }); + } +}; +exports.attachRelationships = attachRelationships; +var aliases = { + 'io.cozy.files:has-many': _HasManyFiles.default, + 'has-many': _HasMany.default, + 'belongs-to-in-place': _HasOneInPlace.default, + 'has-one': _HasOne.default, + 'has-one-in-place': _HasOneInPlace.default, + 'has-many-in-place': _HasManyInPlace.default +}; /** - * This method is like `_.intersection` except that it accepts `iteratee` - * which is invoked for each element of each `arrays` to generate the criterion - * by which they're compared. The order and references of result values are - * determined by the first array. The iteratee is invoked with one argument: - * (value). + * Returns the relationship class for a given doctype/type. * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of intersecting values. - * @example + * In the schema definition, some classes have string aliases + * so you do not have to import directly the association. * - * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [2.1] + * Some doctypes can have built-in overriden relationships. * - * // The `_.property` iteratee shorthand. - * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }] + * @private */ -var intersectionBy = baseRest(function(arrays) { - var iteratee = last(arrays), - mapped = arrayMap(arrays, castArrayLikeObject); - if (iteratee === last(mapped)) { - iteratee = undefined; - } else { - mapped.pop(); +var resolveClass = function resolveClass(doctype, type) { + if (type === undefined) { + throw new Error('Undefined type for ' + doctype); } - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped, baseIteratee(iteratee, 2)) - : []; -}); - -module.exports = intersectionBy; - - -/***/ }), -/* 783 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); + if (typeof type !== 'string') { + return type; + } else { + var qualified = "".concat(doctype, ":").concat(type); + var cls = aliases[qualified] || aliases[type]; -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); + if (!cls) { + throw new Error("Unknown association '".concat(type, "'")); + } else { + return cls; + } + } +}; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +exports.resolveClass = resolveClass; -var _get = _interopRequireDefault(__webpack_require__(358)); +var create = function create(target, _ref, accessors) { + var name = _ref.name, + type = _ref.type, + doctype = _ref.doctype; -var _store = __webpack_require__(693); + if (target[name] instanceof _Association.default) { + throw new Error("Association ".concat(name, " already exists")); + } + return new type(target, name, doctype, accessors); +}; /** - * ObservableQueries are the glue between the store and observers - * of the store. They have the responsibility to hydrate the documents - * before passing them to the React component. + * Checks if the file is referenced by a specific doctype + * + * @param {IOCozyFile} file - io.cozy.files document + * @param {Doctype} referencedBy - Doctype where document is referenced + * @returns {boolean} If a reference is found */ -var hasOwn = Object.prototype.hasOwnProperty; - -var ObservableQuery = /*#__PURE__*/function () { - function ObservableQuery(queryId, definition, client, options) { - var _this = this; - - (0, _classCallCheck2.default)(this, ObservableQuery); - (0, _defineProperty2.default)(this, "handleStoreChange", function () { - var nextResult = _this.currentRawResult(); - - if (!shallowEqual(nextResult, _this.lastResult)) { - _this.lastResult = nextResult; - - _this.notifyObservers(); - } - }); - - if (!queryId || !definition || !client) { - throw new Error('ObservableQuery takes 3 arguments: queryId, definition and client'); - } - - this.queryId = queryId; - this.definition = definition; - this.client = client; - this.observers = {}; - this.idCounter = 1; - this.lastResult = this.currentRawResult(); - this.options = options; - } - - (0, _createClass2.default)(ObservableQuery, [{ - key: "currentResult", - /** - * Returns the query from the store with hydrated documents. - * - * @typedef {object} HydratedQueryState - * - * @returns {HydratedQueryState} - */ - value: function currentResult() { - return this.client.getQueryFromState(this.queryId, { - hydrated: (0, _get.default)(this.options, 'hydrated', true), - singleDocData: true - }); - } - }, { - key: "fetch", - value: function fetch() { - return this.client.query(this.definition, { - as: this.queryId - }); - } - /** - * Generates and executes a query that is offsetted by the number of documents - * we have in the store. - */ - }, { - key: "fetchMore", - value: function fetchMore() { - var rawResult = this.currentRawResult(); - return rawResult.bookmark ? this.client.query(this.definition.offsetBookmark(rawResult.bookmark), { - as: this.queryId - }) : this.client.query(this.definition.offset(rawResult.data.length), { - as: this.queryId - }); - } - }, { - key: "currentRawResult", - value: function currentRawResult() { - return (0, _store.getRawQueryFromState)(this.getStore().getState(), this.queryId); - } - }, { - key: "notifyObservers", - value: function notifyObservers() { - var _this2 = this; +exports.create = create; - Object.keys(this.observers).forEach(function (id) { - return _this2.observers[id](); - }); - } - }, { - key: "subscribeToStore", - value: function subscribeToStore() { - if (this._unsubscribeStore) { - throw new Error('ObservableQuery instance is already subscribed to store.'); - } +var isReferencedBy = function isReferencedBy(file, referencedBy) { + var _file$relationships, _file$relationships$r; - this._unsubscribeStore = this.getStore().subscribe(this.handleStoreChange); - } - }, { - key: "unsubscribeFromStore", - value: function unsubscribeFromStore() { - if (!this._unsubscribeStore) { - throw new Error('ObservableQuery instance is not subscribed to store'); - } + var references = (file === null || file === void 0 ? void 0 : (_file$relationships = file.relationships) === null || _file$relationships === void 0 ? void 0 : (_file$relationships$r = _file$relationships.referenced_by) === null || _file$relationships$r === void 0 ? void 0 : _file$relationships$r.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || []; + return references.some(function (reference) { + return reference.type === referencedBy; + }); +}; +/** + * Checks if the file is referenced by a specific doctype and a specific Id of that reference + * + * @param {IOCozyFile} file - io.cozy.files document + * @param {Doctype} referencedBy - Doctype where document is referenced + * @param {string} referencedId - Id of the referenced document + * @returns {boolean} If a reference is found + */ - this._unsubscribeStore(); - } - }, { - key: "subscribe", - value: function subscribe(callback) { - var _this3 = this; - var callbackId = this.idCounter; - this.idCounter++; - this.observers[callbackId] = callback; +exports.isReferencedBy = isReferencedBy; - if (Object.keys(this.observers).length === 1) { - this.subscribeToStore(); - } +var isReferencedById = function isReferencedById(file, referencedBy, referencedId) { + var _file$relationships2, _file$relationships2$; - return function () { - return _this3.unsubscribe(callbackId); - }; - } - }, { - key: "unsubscribe", - value: function unsubscribe(callbackId) { - if (!this.observers[callbackId]) { - throw new Error("Cannot unsubscribe unknown callbackId ".concat(callbackId)); - } + var references = (file === null || file === void 0 ? void 0 : (_file$relationships2 = file.relationships) === null || _file$relationships2 === void 0 ? void 0 : (_file$relationships2$ = _file$relationships2.referenced_by) === null || _file$relationships2$ === void 0 ? void 0 : _file$relationships2$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || []; + return references.some(function (reference) { + return reference.type === referencedBy && reference.id === referencedId; + }); +}; +/** + * Get array of reference by an specific doctype + * + * @param {IOCozyFile} file - io.cozy.files document + * @param {Doctype} referencedBy - Doctype where document is referenced + * @returns {Reference[]} Array of references found + */ - delete this.observers[callbackId]; - if (Object.keys(this.observers).length === 0) { - this.unsubscribeFromStore(); - this._unsubscribeStore = null; - } - } - }, { - key: "getStore", - value: function getStore() { - return this.client.store; - } - }]); - return ObservableQuery; -}(); +exports.isReferencedById = isReferencedById; -exports["default"] = ObservableQuery; +var getReferencedBy = function getReferencedBy(file, referencedBy) { + var _file$relationships3, _file$relationships3$; -function is(x, y) { - if (x === y) { - return x !== 0 || y !== 0 || 1 / x === 1 / y; - } else { - return x !== x && y !== y; - } -} + var references = (file === null || file === void 0 ? void 0 : (_file$relationships3 = file.relationships) === null || _file$relationships3 === void 0 ? void 0 : (_file$relationships3$ = _file$relationships3.referenced_by) === null || _file$relationships3$ === void 0 ? void 0 : _file$relationships3$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || []; + return references.filter(function (reference) { + return reference.type === referencedBy; + }); +}; +/** + * Get array of reference by an specific doctype and a specific Id of that reference + * + * @param {IOCozyFile} file - io.cozy.files document + * @param {Doctype} referencedBy - Doctype where document is referenced + * @param {string} referencedId - Id of the referenced document + * @returns {Reference[]} Array of the reference found + */ -function shallowEqual(objA, objB) { - if (is(objA, objB)) return true; - if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { - return false; - } +exports.getReferencedBy = getReferencedBy; - var keysA = Object.keys(objA); - var keysB = Object.keys(objB); - if (keysA.length !== keysB.length) return false; +var getReferencedById = function getReferencedById(file, referencedBy, referencedId) { + var _file$relationships4, _file$relationships4$; - for (var i = 0; i < keysA.length; i++) { - if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { - return false; - } - } + var references = (file === null || file === void 0 ? void 0 : (_file$relationships4 = file.relationships) === null || _file$relationships4 === void 0 ? void 0 : (_file$relationships4$ = _file$relationships4.referenced_by) === null || _file$relationships4$ === void 0 ? void 0 : _file$relationships4$.data) || (file === null || file === void 0 ? void 0 : file.referenced_by) || []; + return references.filter(function (reference) { + return reference.type === referencedBy && reference.id === referencedId; + }); +}; - return true; -} +exports.getReferencedById = getReferencedById; /***/ }), -/* 784 */ +/* 768 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.CozyClient = void 0; +exports.rootCozyUrl = exports.InvalidCozyUrlError = exports.InvalidProtocolError = exports.generateWebLink = exports.dehydrate = void 0; + +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); + +var _toArray2 = _interopRequireDefault(__webpack_require__(526)); -var _inherits2 = _interopRequireDefault(__webpack_require__(591)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(593)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(595)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); + +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); + +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); + +var _wrapNativeSuper2 = _interopRequireDefault(__webpack_require__(664)); + +var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532)); + +var _associations = __webpack_require__(703); function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -var SnapshotObject = function SnapshotObject(attrs) { - (0, _classCallCheck2.default)(this, SnapshotObject); - Object.assign(this, attrs); +function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + +var dehydrate = function dehydrate(document) { + var dehydrated = Object.entries(document).reduce(function (documentArg, _ref) { + var _ref2 = (0, _slicedToArray2.default)(_ref, 2), + key = _ref2[0], + value = _ref2[1]; + + var document = documentArg; + + if (!(value instanceof _associations.Association)) { + document[key] = value; // @ts-ignore + } else if (value.dehydrate) { + // @ts-ignore + document = value.dehydrate(document); + } else { + throw new Error("Association on key ".concat(key, " should have a dehydrate method")); + } + + return document; + }, {}); + return dehydrated; }; -var CozyClient = /*#__PURE__*/function (_SnapshotObject) { - (0, _inherits2.default)(CozyClient, _SnapshotObject); +exports.dehydrate = dehydrate; - var _super = _createSuper(CozyClient); +var ensureFirstSlash = function ensureFirstSlash(path) { + if (!path) { + return '/'; + } else { + return path.startsWith('/') ? path : '/' + path; + } +}; +/** + * generateWebLink - Construct a link to a web app + * + * This function does not get its cozy url from a CozyClient instance so it can + * be used to build urls that point to other Cozies than the user's own Cozy. + * This is useful when pointing to the Cozy of the owner of a shared note for + * example. + * + * @param {object} options Object of options + * @param {string} options.cozyUrl Base URL of the cozy, eg. cozy.tools or test.mycozy.cloud + * @param {Array} [options.searchParams] Array of search parameters as [key, value] arrays, eg. ['username', 'bob'] + * @param {string} [options.pathname] Path to a specific part of the app, eg. /public + * @param {string} [options.hash] Path inside the app, eg. /files/test.jpg + * @param {string} [options.slug] Slug of the app + * @param {string} [options.subDomainType] Whether the cozy is using flat or nested subdomains. Defaults to flat. + * + * @returns {string} Generated URL + */ - function CozyClient() { - (0, _classCallCheck2.default)(this, CozyClient); - return _super.apply(this, arguments); + +var generateWebLink = function generateWebLink(_ref3) { + var cozyUrl = _ref3.cozyUrl, + searchParamsOption = _ref3.searchParams, + pathname = _ref3.pathname, + hash = _ref3.hash, + slug = _ref3.slug, + subDomainType = _ref3.subDomainType; + var searchParams = searchParamsOption || []; + var url = new URL(cozyUrl); + url.host = subDomainType === 'nested' ? "".concat(slug, ".").concat(url.host) : url.host.split('.').map(function (x, i) { + return i === 0 ? x + '-' + slug : x; + }).join('.'); + url.pathname = pathname; + url.hash = ensureFirstSlash(hash); + + var _iterator = _createForOfIteratorHelper(searchParams), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _step$value = (0, _slicedToArray2.default)(_step.value, 2), + param = _step$value[0], + value = _step$value[1]; + + url.searchParams.set(param, value); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); } - return CozyClient; -}(SnapshotObject); + return url.toString(); +}; -exports.CozyClient = CozyClient; +exports.generateWebLink = generateWebLink; -/***/ }), -/* 785 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var InvalidProtocolError = /*#__PURE__*/function (_Error) { + (0, _inherits2.default)(InvalidProtocolError, _Error); -var json = typeof JSON !== 'undefined' ? JSON : __webpack_require__(786); + var _super = _createSuper(InvalidProtocolError); -module.exports = function (obj, opts) { - if (!opts) opts = {}; - if (typeof opts === 'function') opts = { cmp: opts }; - var space = opts.space || ''; - if (typeof space === 'number') space = Array(space+1).join(' '); - var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false; - var replacer = opts.replacer || function(key, value) { return value; }; + function InvalidProtocolError(url) { + var _this; - var cmp = opts.cmp && (function (f) { - return function (node) { - return function (a, b) { - var aobj = { key: a, value: node[a] }; - var bobj = { key: b, value: node[b] }; - return f(aobj, bobj); - }; - }; - })(opts.cmp); + (0, _classCallCheck2.default)(this, InvalidProtocolError); + _this = _super.call(this, "Invalid URL protocol ".concat(url.protocol)); + _this.url = url; + return _this; + } - var seen = []; - return (function stringify (parent, key, node, level) { - var indent = space ? ('\n' + new Array(level + 1).join(space)) : ''; - var colonSeparator = space ? ': ' : ':'; + return InvalidProtocolError; +}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); - if (node && node.toJSON && typeof node.toJSON === 'function') { - node = node.toJSON(); - } +exports.InvalidProtocolError = InvalidProtocolError; - node = replacer.call(parent, key, node); +var InvalidCozyUrlError = /*#__PURE__*/function (_Error2) { + (0, _inherits2.default)(InvalidCozyUrlError, _Error2); - if (node === undefined) { - return; - } - if (typeof node !== 'object' || node === null) { - return json.stringify(node); - } - if (isArray(node)) { - var out = []; - for (var i = 0; i < node.length; i++) { - var item = stringify(node, i, node[i], level+1) || json.stringify(null); - out.push(indent + space + item); - } - return '[' + out.join(',') + indent + ']'; - } - else { - if (seen.indexOf(node) !== -1) { - if (cycles) return json.stringify('__cycle__'); - throw new TypeError('Converting circular structure to JSON'); - } - else seen.push(node); + var _super2 = _createSuper(InvalidCozyUrlError); - var keys = objectKeys(node).sort(cmp && cmp(node)); - var out = []; - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - var value = stringify(node, key, node[key], level+1); + function InvalidCozyUrlError(url) { + var _this2; - if(!value) continue; + (0, _classCallCheck2.default)(this, InvalidCozyUrlError); + _this2 = _super2.call(this, "URL ".concat(url.toString(), " does not seem to be a valid Cozy URL")); + _this2.url = url; + return _this2; + } - var keyValue = json.stringify(key) - + colonSeparator - + value; - ; - out.push(indent + space + keyValue); - } - seen.splice(seen.indexOf(node), 1); - return '{' + out.join(',') + indent + '}'; - } - })({ '': obj }, '', obj, 0); -}; + return InvalidCozyUrlError; +}( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error)); +/* uri - Returns a well formed URL origin from a protocol, a hostname and a port + * + * If the protocol and/or port are omitted from the argument, the function will + * default to HTTPS and omit the port in the returned origin. + * + * @param {object} url Object of URL elements + * @param {string} url.protocol Protocol to use in the origin (e.g. http) + * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud) + * @param {string} url.port Port to use in the origin (e.g. 8080) + * + * @returns {string} Generated URL origin + */ -var isArray = Array.isArray || function (x) { - return {}.toString.call(x) === '[object Array]'; + +exports.InvalidCozyUrlError = InvalidCozyUrlError; + +var uri = function uri(_ref4) { + var protocol = _ref4.protocol, + hostname = _ref4.hostname, + port = _ref4.port; + return (protocol !== '' ? "".concat(protocol, "//") : 'https://') + hostname + (port !== '' ? ":".concat(port) : ''); }; +/* wellKnownUrl - Returns a valid URL string to a Well Known password change page + * + * The built URL will point to the origin generated from the given protocol, + * hostname and port. + * + * @param {object} url Object of URL elements + * @param {string} url.protocol Protocol to use in the origin (e.g. http) + * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud) + * @param {string} url.port Port to use in the origin (e.g. 8080) + * + * @returns {string} Generated Well Known password change URL string + */ -var objectKeys = Object.keys || function (obj) { - var has = Object.prototype.hasOwnProperty || function () { return true }; - var keys = []; - for (var key in obj) { - if (has.call(obj, key)) keys.push(key); - } - return keys; + +var wellKnownUrl = function wellKnownUrl(url) { + return uri(url) + '/.well-known/change-password'; }; +/* isValidOrigin - Checks whether a given URL is a valid Cozy origin + * + * This method tries to fetch the Well Known change password page of the Cozy + * supposedly at the given origin. This allows us to determine whether the given + * origin is the root URL of a Cozy or not via the status of the response: + * - a 200 response status means there's an actual Well Known password change + * page accessible from the given origin so we suppose it's a valid Cozy + * origin (i.e. it could be another site altogether though) + * - a 401 response status means the pointed page requires authentication so the + * origin is probably pointing to a Cozy app + * - another status means there aren't any Cozy behind to the given origin + * + * @param {object} url Object of URL elements + * @param {string} url.protocol Protocol to use in the origin (e.g. http) + * @param {string} url.hostname Hostname to use in the origin (e.g. claude.mycozy.cloud) + * @param {string} url.port Port to use in the origin (e.g. 8080) + * + * @returns {Promise<boolean>} True if we believe there's a Cozy behind the given origin + * @throws {InvalidCozyUrlError} Thrown when we know for sure there aren't any Cozy behind the given origin + */ -/***/ }), -/* 786 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +var isValidOrigin = /*#__PURE__*/function () { + var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) { + var _yield$fetch, status; -exports.parse = __webpack_require__(787); -exports.stringify = __webpack_require__(788); + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return fetch(wellKnownUrl(url)); + case 2: + _yield$fetch = _context.sent; + status = _yield$fetch.status; -/***/ }), -/* 787 */ -/***/ ((module) => { + if (!(status === 404)) { + _context.next = 6; + break; + } -var at, // The index of the current character - ch, // The current character - escapee = { - '"': '"', - '\\': '\\', - '/': '/', - b: '\b', - f: '\f', - n: '\n', - r: '\r', - t: '\t' - }, - text, + throw new InvalidCozyUrlError(url); - error = function (m) { - // Call error when something is wrong. - throw { - name: 'SyntaxError', - message: m, - at: at, - text: text - }; - }, - - next = function (c) { - // If a c parameter is provided, verify that it matches the current character. - if (c && c !== ch) { - error("Expected '" + c + "' instead of '" + ch + "'"); - } - - // Get the next character. When there are no more characters, - // return the empty string. - - ch = text.charAt(at); - at += 1; - return ch; - }, - - number = function () { - // Parse a number value. - var number, - string = ''; - - if (ch === '-') { - string = '-'; - next('-'); - } - while (ch >= '0' && ch <= '9') { - string += ch; - next(); + case 6: + return _context.abrupt("return", status === 200); + + case 7: + case "end": + return _context.stop(); } - if (ch === '.') { - string += '.'; - while (next() && ch >= '0' && ch <= '9') { - string += ch; + } + }, _callee); + })); + + return function isValidOrigin(_x) { + return _ref5.apply(this, arguments); + }; +}(); +/** + * rootCozyUrl - Get the root URL of a Cozy from more precise ones + * + * The goal is to allow users to use any URL copied from their browser as their + * Cozy URL rather than trying to explain to them what we expect (e.g. when + * requesting the Cozy URL to connect an app). + * If we can't get the root URL either because there's no Cozy or the domain + * does not exist or anything else, we'll throw an InvalidCozyUrlError. + * Also, since we communicate only via HTTP or HTTPS, we'll throw an + * InvalidProtocolError if any other protocol is used. + * + * This function expects a fully qualified URL thus with a protocol and a valid + * hostname. If your application accepts Cozy intances as input (e.g. `claude` + * when the Cozy can be found at `https://claude.mycozy.cloud`), it is your + * responsibility to add the appropriate domain to the hostname before calling + * this function. + * + * Examples: + * + * 1. getting the root URL when your user gives you its instance name + * + * const userInput = 'claude' + * const rootUrl = await rootCozyUrl(new URL(`https://${userInput}.mycozy.cloud`)) + * // → returns new URL('https://claude.mycozy.cloud') + * + * 2. getting the root URL when your user gives you a Cozy Drive URL + * + * const userInput = 'https://claude-drive.mycozy.cloud/#/folder/io.cozy.files.root-dir' + * const rootUrl = await rootCozyUrl(new URL(userInput)) + * // → returns new URL('https://claude.mycozy.cloud') + * + * 3. getting the root URL when the Cozy uses nested sub-domains + * + * const userInput = 'http://photos.camille.nimbus.com:8080/#/album/1234567890' + * const rootCozyUrl = await rootCozyUrl(new URL(userInput)) + * // → returns new URL('http://camille.nimbus.com:8080') + * + * @param {URL} url The URL from which we'll try to get the root Cozy URL + * + * @returns {Promise<URL>} The root Cozy URL + */ + + +var rootCozyUrl = /*#__PURE__*/function () { + var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(url) { + var _url$hostname$split, _url$hostname$split2, subDomain, domain, _hostname, hostname; + + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (['http:', 'https:'].includes(url.protocol)) { + _context2.next = 2; + break; } - } - if (ch === 'e' || ch === 'E') { - string += ch; - next(); - if (ch === '-' || ch === '+') { - string += ch; - next(); + + throw new InvalidProtocolError(url); + + case 2: + _context2.next = 4; + return isValidOrigin(url); + + case 4: + if (!_context2.sent) { + _context2.next = 6; + break; } - while (ch >= '0' && ch <= '9') { - string += ch; - next(); + + return _context2.abrupt("return", url); + + case 6: + if (!/^[^.-][^.]+-[^.-]+\./.test(url.hostname)) { + _context2.next = 13; + break; } - } - number = +string; - if (!isFinite(number)) { - error("Bad number"); - } else { - return number; - } - }, - - string = function () { - // Parse a string value. - var hex, - i, - string = '', - uffff; - - // When parsing for string values, we must look for " and \ characters. - if (ch === '"') { - while (next()) { - if (ch === '"') { - next(); - return string; - } else if (ch === '\\') { - next(); - if (ch === 'u') { - uffff = 0; - for (i = 0; i < 4; i += 1) { - hex = parseInt(next(), 16); - if (!isFinite(hex)) { - break; - } - uffff = uffff * 16 + hex; - } - string += String.fromCharCode(uffff); - } else if (typeof escapee[ch] === 'string') { - string += escapee[ch]; - } else { - break; - } - } else { - string += ch; - } + + _url$hostname$split = url.hostname.split('.'), _url$hostname$split2 = (0, _toArray2.default)(_url$hostname$split), subDomain = _url$hostname$split2[0], domain = _url$hostname$split2.slice(1); + _hostname = [subDomain.replace(/-.+/, '')].concat((0, _toConsumableArray2.default)(domain)).join('.'); + _context2.next = 11; + return isValidOrigin({ + protocol: url.protocol, + hostname: _hostname, + port: url.port + }); + + case 11: + if (!_context2.sent) { + _context2.next = 13; + break; } - } - error("Bad string"); - }, - white = function () { + return _context2.abrupt("return", new URL(uri({ + protocol: url.protocol, + hostname: _hostname, + port: url.port + }))); -// Skip whitespace. + case 13: + // Try to remove the first sub-domain in case its a nested app name + // eslint-disable-next-line no-unused-vars + hostname = url.hostname.split('.').splice(1).join('.'); + _context2.next = 16; + return isValidOrigin({ + protocol: url.protocol, + hostname: hostname, + port: url.port + }); - while (ch && ch <= ' ') { - next(); - } - }, + case 16: + if (!_context2.sent) { + _context2.next = 18; + break; + } - word = function () { + return _context2.abrupt("return", new URL(uri({ + protocol: url.protocol, + hostname: hostname, + port: url.port + }))); -// true, false, or null. + case 18: + throw new InvalidCozyUrlError(url); - switch (ch) { - case 't': - next('t'); - next('r'); - next('u'); - next('e'); - return true; - case 'f': - next('f'); - next('a'); - next('l'); - next('s'); - next('e'); - return false; - case 'n': - next('n'); - next('u'); - next('l'); - next('l'); - return null; + case 19: + case "end": + return _context2.stop(); } - error("Unexpected '" + ch + "'"); - }, + } + }, _callee2); + })); - value, // Place holder for the value function. + return function rootCozyUrl(_x2) { + return _ref6.apply(this, arguments); + }; +}(); - array = function () { +exports.rootCozyUrl = rootCozyUrl; -// Parse an array value. +/***/ }), +/* 769 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - var array = []; +"use strict"; - if (ch === '[') { - next('['); - white(); - if (ch === ']') { - next(']'); - return array; // empty array - } - while (ch) { - array.push(value()); - white(); - if (ch === ']') { - next(']'); - return array; - } - next(','); - white(); - } - } - error("Bad array"); - }, - object = function () { +var _interopRequireDefault = __webpack_require__(524); -// Parse an object value. +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.authFunction = exports.authenticateWithCordova = void 0; - var key, - object = {}; +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - if (ch === '{') { - next('{'); - white(); - if (ch === '}') { - next('}'); - return object; // empty object - } - while (ch) { - key = string(); - white(); - next(':'); - if (Object.hasOwnProperty.call(object, key)) { - error('Duplicate key "' + key + '"'); - } - object[key] = value(); - white(); - if (ch === '}') { - next('}'); - return object; - } - next(','); - white(); - } - } - error("Bad object"); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); + +var _const = __webpack_require__(697); + +var _cozyDeviceHelper = __webpack_require__(770); + +var _types = __webpack_require__(622); + +/* global prompt */ + +/** + * @type {CordovaWindow} + */ +// @ts-ignore +var win = typeof window !== 'undefined' ? window : null; +/** + * Open a SafariView Controller and resolve with the URL containing the token + * + * @param {string} url + * @returns {Promise} + */ + +var authenticateWithSafari = function authenticateWithSafari(url) { + return new Promise(function (resolve, reject) { + win.SafariViewController.show({ + url: url, + transition: 'curl' // (this only works in iOS 9.1/9.2 and lower) unless animated is false you can choose from: curl, flip, fade, slide (default) + // enterReaderModeIfAvailable: readerMode, // default false + // tintColor: "#00ffff", // default is ios blue + // barColor: "#0000ff", // on iOS 10+ you can change the background color as well + // controlTintColor: "#ffffff" // on iOS 10+ you can override the default tintColor + + }, // this success handler will be invoked for the lifecycle events 'opened', 'loaded' and 'closed' + function (result) { + if (result.event === 'closed') { + reject(new Error(_const.REGISTRATION_ABORT)); + } + }, function (error) { + console.log('KO: ' + error); + reject(new Error(_const.REGISTRATION_ABORT)); + }); + var handle = win.handleOpenURL; + + win.handleOpenURL = function (url) { + win.SafariViewController.hide(); + resolve(url); + + if (handle) { + win.handleOpenURL = handle; + } }; + }); +}; +/** + * Opens an InAppBrowser and resolves with the URL containing the token + * + * @param {string} url + * @returns {Promise} + */ -value = function () { -// Parse a JSON value. It could be an object, an array, a string, a number, -// or a word. +var authenticateWithInAppBrowser = function authenticateWithInAppBrowser(url) { + return new Promise(function (resolve, reject) { + var target = '_blank'; + var options = 'clearcache=yes,zoom=no'; + var inAppBrowser = win.cordova.InAppBrowser.open(url, target, options); - white(); - switch (ch) { - case '{': - return object(); - case '[': - return array(); - case '"': - return string(); - case '-': - return number(); - default: - return ch >= '0' && ch <= '9' ? number() : word(); - } + var removeListener = function removeListener() { + inAppBrowser.removeEventListener('loadstart', onLoadStart); + inAppBrowser.removeEventListener('exit', onExit); + }; + + var onLoadStart = function onLoadStart(_ref) { + var url = _ref.url; + var accessCode = /\?access_code=(.+)$/.test(url); + var state = /\?state=(.+)$/.test(url); + + if (accessCode || state) { + resolve(url); + removeListener(); + inAppBrowser.close(); + } + }; + + var onExit = function onExit() { + reject(new Error(_const.REGISTRATION_ABORT)); + removeListener(); + inAppBrowser.close(); + }; + + inAppBrowser.addEventListener('loadstart', onLoadStart); + inAppBrowser.addEventListener('exit', onExit); + }); }; -// Return the json_parse function. It will have access to all of the above -// functions and variables. +var authenticateWithCordova = /*#__PURE__*/function () { + var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) { + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.t0 = (0, _cozyDeviceHelper.isIOSApp)(); -module.exports = function (source, reviver) { - var result; - - text = source; - at = 0; - ch = ' '; - result = value(); - white(); - if (ch) { - error("Syntax error"); - } + if (!_context.t0) { + _context.next = 5; + break; + } - // If there is a reviver function, we recursively walk the new structure, - // passing each name/value pair to the reviver function for possible - // transformation, starting with a temporary root object that holds the result - // in an empty key. If there is not a reviver function, we simply return the - // result. + _context.next = 4; + return (0, _cozyDeviceHelper.hasSafariPlugin)(); - return typeof reviver === 'function' ? (function walk(holder, key) { - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } + case 4: + _context.t0 = _context.sent; + + case 5: + if (!_context.t0) { + _context.next = 9; + break; + } + + return _context.abrupt("return", authenticateWithSafari(url)); + + case 9: + if (!(0, _cozyDeviceHelper.hasInAppBrowserPlugin)()) { + _context.next = 13; + break; } + + return _context.abrupt("return", authenticateWithInAppBrowser(url)); + + case 13: + /** + * for dev purpose: + * In oauth workflow, the server displays an authorization page + * User must accept to give permission then the server gives an url + * with query parameters used by cozy-client-js to initialize itself. + * + * This hack let developers open the authorization page in a new tab + * then get the "access_code" url and paste it in the prompt to let the + * application initialize and redirect to other pages. + */ + console.log(url); // Useful for dev (see above). + + return _context.abrupt("return", new Promise(function (resolve) { + setTimeout(function () { + var token = prompt('Paste the url here:'); + resolve(token); + }, 5000); + })); + + case 15: + case "end": + return _context.stop(); } - return reviver.call(holder, key, value); - }({'': result}, '')) : result; -}; + } + }, _callee); + })); + + return function authenticateWithCordova(_x) { + return _ref2.apply(this, arguments); + }; +}(); +exports.authenticateWithCordova = authenticateWithCordova; +var authFunction = authenticateWithCordova; +exports.authFunction = authFunction; /***/ }), -/* 788 */ -/***/ ((module) => { +/* 770 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, - rep; +"use strict"; -function quote(string) { - // If the string contains no control characters, no quote characters, and no - // backslash characters, then we can safely slap some quotes around it. - // Otherwise we must also replace the offending characters with safe escape - // sequences. - - escapable.lastIndex = 0; - return escapable.test(string) ? '"' + string.replace(escapable, function (a) { - var c = meta[a]; - return typeof c === 'string' ? c : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : '"' + string + '"'; -} -function str(key, holder) { - // Produce a string from holder[key]. - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - - // If the value has a toJSON method, call it to obtain a replacement value. - if (value && typeof value === 'object' && - typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - - // If we were called with a replacer function, then call the replacer to - // obtain a replacement value. - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - - // What happens next depends on the value's type. - switch (typeof value) { - case 'string': - return quote(value); - - case 'number': - // JSON numbers must be finite. Encode non-finite numbers as null. - return isFinite(value) ? String(value) : 'null'; - - case 'boolean': - case 'null': - // If the value is a boolean or null, convert it to a string. Note: - // typeof null does not produce 'null'. The case is included here in - // the remote chance that this gets fixed someday. - return String(value); - - case 'object': - if (!value) return 'null'; - gap += indent; - partial = []; - - // Array.isArray - if (Object.prototype.toString.apply(value) === '[object Array]') { - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - - // Join all of the elements together, separated with commas, and - // wrap them in brackets. - v = partial.length === 0 ? '[]' : gap ? - '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : - '[' + partial.join(',') + ']'; - gap = mind; - return v; - } - - // If the replacer is an array, use it to select the members to be - // stringified. - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - k = rep[i]; - if (typeof k === 'string') { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - else { - // Otherwise, iterate through all of the keys in the object. - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - - // Join all of the member texts together, separated with commas, - // and wrap them in braces. +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "checkApp", ({ + enumerable: true, + get: function get() { + return _apps.checkApp; + } +})); +Object.defineProperty(exports, "getDeviceName", ({ + enumerable: true, + get: function get() { + return _device.getDeviceName; + } +})); +Object.defineProperty(exports, "getFlagshipMetadata", ({ + enumerable: true, + get: function get() { + return _flagship.getFlagshipMetadata; + } +})); +Object.defineProperty(exports, "getPlatform", ({ + enumerable: true, + get: function get() { + return _platform.getPlatform; + } +})); +Object.defineProperty(exports, "hasDevicePlugin", ({ + enumerable: true, + get: function get() { + return _plugins.hasDevicePlugin; + } +})); +Object.defineProperty(exports, "hasInAppBrowserPlugin", ({ + enumerable: true, + get: function get() { + return _plugins.hasInAppBrowserPlugin; + } +})); +Object.defineProperty(exports, "hasNetworkInformationPlugin", ({ + enumerable: true, + get: function get() { + return _plugins.hasNetworkInformationPlugin; + } +})); +Object.defineProperty(exports, "hasSafariPlugin", ({ + enumerable: true, + get: function get() { + return _plugins.hasSafariPlugin; + } +})); +Object.defineProperty(exports, "isAndroid", ({ + enumerable: true, + get: function get() { + return _platform.isAndroid; + } +})); +Object.defineProperty(exports, "isAndroidApp", ({ + enumerable: true, + get: function get() { + return _platform.isAndroidApp; + } +})); +Object.defineProperty(exports, "isCordova", ({ + enumerable: true, + get: function get() { + return _cordova.isCordova; + } +})); +Object.defineProperty(exports, "isFlagshipApp", ({ + enumerable: true, + get: function get() { + return _flagship.isFlagshipApp; + } +})); +Object.defineProperty(exports, "isIOS", ({ + enumerable: true, + get: function get() { + return _platform.isIOS; + } +})); +Object.defineProperty(exports, "isIOSApp", ({ + enumerable: true, + get: function get() { + return _platform.isIOSApp; + } +})); +Object.defineProperty(exports, "isMobile", ({ + enumerable: true, + get: function get() { + return _platform.isMobile; + } +})); +Object.defineProperty(exports, "isMobileApp", ({ + enumerable: true, + get: function get() { + return _platform.isMobileApp; + } +})); +Object.defineProperty(exports, "isWebApp", ({ + enumerable: true, + get: function get() { + return _platform.isWebApp; + } +})); +Object.defineProperty(exports, "nativeLinkOpen", ({ + enumerable: true, + get: function get() { + return _link.nativeLinkOpen; + } +})); +Object.defineProperty(exports, "openDeeplinkOrRedirect", ({ + enumerable: true, + get: function get() { + return _deeplink.openDeeplinkOrRedirect; + } +})); +Object.defineProperty(exports, "startApp", ({ + enumerable: true, + get: function get() { + return _apps.startApp; + } +})); - v = partial.length === 0 ? '{}' : gap ? - '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : - '{' + partial.join(',') + '}'; - gap = mind; - return v; - } -} +var _platform = __webpack_require__(771); -module.exports = function (value, replacer, space) { - var i; - gap = ''; - indent = ''; - - // If the space parameter is a number, make an indent string containing that - // many spaces. - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - } - // If the space parameter is a string, it will be used as the indent string. - else if (typeof space === 'string') { - indent = space; - } +var _device = __webpack_require__(773); - // If there is a replacer, it must be a function or an array. - // Otherwise, throw an error. - rep = replacer; - if (replacer && typeof replacer !== 'function' - && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { - throw new Error('JSON.stringify'); - } - - // Make a fake root object containing our value under the key of ''. - // Return the result of stringifying the value. - return str('', {'': value}); -}; +var _apps = __webpack_require__(783); +var _plugins = __webpack_require__(782); + +var _cordova = __webpack_require__(772); + +var _link = __webpack_require__(784); + +var _deeplink = __webpack_require__(785); + +var _flagship = __webpack_require__(786); /***/ }), -/* 789 */ +/* 771 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); - Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = void 0; - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); - -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); - -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); - -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); - -/** - * Caches promises while they are pending - * Serves to dedupe equal queries requested at the same time - */ -var PromiseCache = /*#__PURE__*/function () { - function PromiseCache() { - (0, _classCallCheck2.default)(this, PromiseCache); +exports.isWebApp = exports.isMobileApp = exports.isMobile = exports.isIOSApp = exports.isIOS = exports.isAndroidApp = exports.isAndroid = exports.getPlatform = void 0; - /** - * Holds pending promises - * - * @type {Object.<string, Promise>} - */ - this.pending = {}; - } - /** - * Tries to find a pending promise corresponding to the result of keyFunc - * - If not found, promiseFunc is executed and the resulting promise is stored while it's pending - * - If found, it is immediately returned - * - * @template T - * @param {function(): Promise<T>} promiseFunc - Not executed only if an "equal" promise is already pending. - * @param {function(): string} keyFunc - Returns a key to find in cache to find a pending promise. - * @returns {Promise<T>} - */ +var _cordova = __webpack_require__(772); +var ANDROID_PLATFORM = 'android'; +var IOS_PLATFORM = 'ios'; +var WEB_PLATFORM = 'web'; - (0, _createClass2.default)(PromiseCache, [{ - key: "exec", - value: function () { - var _exec = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(promiseFunc, keyFunc) { - var key, already, prom, response; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - key = keyFunc(); - already = this.pending[key]; +var getPlatform = function getPlatform() { + return (0, _cordova.isCordova)() ? window.cordova.platformId : WEB_PLATFORM; +}; - if (already) { - prom = already; - } else { - prom = promiseFunc(); - this.pending[key] = prom; - } +exports.getPlatform = getPlatform; - _context.prev = 3; - _context.next = 6; - return prom; +var isPlatform = function isPlatform(platform) { + return getPlatform() === platform; +}; - case 6: - response = _context.sent; - return _context.abrupt("return", response); +var isIOSApp = function isIOSApp() { + return isPlatform(IOS_PLATFORM); +}; - case 8: - _context.prev = 8; - this.pending[key] = null; - return _context.finish(8); +exports.isIOSApp = isIOSApp; - case 11: - case "end": - return _context.stop(); - } - } - }, _callee, this, [[3,, 8, 11]]); - })); +var isAndroidApp = function isAndroidApp() { + return isPlatform(ANDROID_PLATFORM); +}; - function exec(_x, _x2) { - return _exec.apply(this, arguments); - } +exports.isAndroidApp = isAndroidApp; - return exec; - }() - /** - * - * @param {function(): string} keyFunc - Returns a key to find in cache to find a pending promise. - * @returns {Promise | null} - */ +var isWebApp = function isWebApp() { + return isPlatform(WEB_PLATFORM); +}; - }, { - key: "get", - value: function get(keyFunc) { - var key = keyFunc(); - var already = this.pending[key]; - if (already) return already; - return null; - } - }]); - return PromiseCache; -}(); +exports.isWebApp = isWebApp; -var _default = PromiseCache; -exports["default"] = _default; +var isMobileApp = function isMobileApp() { + return (0, _cordova.isCordova)(); +}; // return if is on an Android Device (native or browser) -/***/ }), -/* 790 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -"use strict"; +exports.isMobileApp = isMobileApp; +var isAndroid = function isAndroid() { + return window.navigator.userAgent && window.navigator.userAgent.indexOf('Android') >= 0; +}; // return if is on an iOS Device (native or browser) -var _interopRequireDefault = __webpack_require__(512); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.certifyFlagship = void 0; +exports.isAndroid = isAndroid; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var isIOS = function isIOS() { + return window.navigator.userAgent && /iPad|iPhone|iPod/.test(window.navigator.userAgent); +}; // isMobile checks if the user is on a smartphone : native app or browser -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); -var _CozyClient = _interopRequireDefault(__webpack_require__(513)); +exports.isIOS = isIOS; -var _logger = _interopRequireDefault(__webpack_require__(703)); +var isMobile = function isMobile() { + return isAndroid() || isIOS(); +}; -var _storeAttestation = __webpack_require__(791); +exports.isMobile = isMobile; -/** - * Request a challenge from the Stack that can be used to request the app attestation from the app store - * - * @param {CozyClient} client - the CozyClient instance - * @returns {Promise<string>} - the Nonce string returned by the stack - */ -var getStackChallenge = /*#__PURE__*/function () { - var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client) { - var stackClient, result; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.prev = 0; - stackClient = client.getStackClient(); - _context.next = 4; - return stackClient.fetchJSON('POST', "/auth/clients/".concat(stackClient.oauthOptions.clientID, "/challenge"), null, { - headers: { - Authorization: stackClient.registrationAccessTokenToAuthHeader() - } - }); +/***/ }), +/* 772 */ +/***/ ((__unused_webpack_module, exports) => { - case 4: - result = _context.sent; - return _context.abrupt("return", result.nonce); +"use strict"; - case 8: - _context.prev = 8; - _context.t0 = _context["catch"](0); - throw new Error('[FLAGSHIP_CERTIFICATION] Something went wrong while requesting a challenge from CozyStack:\n' + _context.t0.message); - case 11: - case "end": - return _context.stop(); - } - } - }, _callee, null, [[0, 8]]); - })); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.isCordova = void 0; - return function getStackChallenge(_x) { - return _ref.apply(this, arguments); - }; -}(); -/** - * Give the app attestation to the Stack - * - * @param {AttestationResult} appAttestation - the app attestation that was returned by the app store - * @param {string} nonce - the Nonce string retrieved from the stack - * @param {CozyClient} client - the CozyClient instance - */ +// cordova +var isCordova = function isCordova() { + return typeof window !== 'undefined' && window.cordova !== undefined; +}; +exports.isCordova = isCordova; -var giveAppAttestationToStack = /*#__PURE__*/function () { - var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(appAttestation, nonce, client) { - var platform, attestation, keyId, stackClient; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _context2.prev = 0; - platform = appAttestation.platform, attestation = appAttestation.attestation, keyId = appAttestation.keyId; - stackClient = client.getStackClient(); - _context2.next = 5; - return stackClient.fetchJSON('POST', "/auth/clients/".concat(stackClient.oauthOptions.clientID, "/attestation"), { - platform: platform, - attestation: attestation, - challenge: nonce, - keyId: keyId - }, { - headers: { - Authorization: stackClient.registrationAccessTokenToAuthHeader() - } - }); +/***/ }), +/* 773 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - case 5: - _context2.next = 10; - break; +"use strict"; - case 7: - _context2.prev = 7; - _context2.t0 = _context2["catch"](0); - throw new Error('[FLAGSHIP_CERTIFICATION] Something went wrong while giving attestation to CozyStack:\n' + _context2.t0.message); - case 10: - case "end": - return _context2.stop(); - } - } - }, _callee2, null, [[0, 7]]); - })); +var _interopRequireDefault = __webpack_require__(524); - return function giveAppAttestationToStack(_x2, _x3, _x4) { - return _ref2.apply(this, arguments); - }; -}(); -/** - * Verify app's identity and integrity so the Stack can trust it - * Verification is done on Stack side by using information from the app's store (Google Play or Apple AppStore) - * - * @param {CertificationConfig} certificationConfig - the required configuration to access the stores API - * @param {CozyClient} client - the CozyClient instance - */ +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getDeviceName = void 0; +var _capitalize = _interopRequireDefault(__webpack_require__(774)); -var certifyFlagship = /*#__PURE__*/function () { - var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(certificationConfig, client) { - var stackChallengeNonce, appAttestation; - return _regenerator.default.wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - if (certificationConfig) { - _context3.next = 2; - break; - } +var _cordova = __webpack_require__(772); - throw new Error('[FLAGSHIP_CERTIFICATION] Certification configuration is not set'); +var _plugins = __webpack_require__(782); - case 2: - _context3.prev = 2; - _context3.next = 5; - return getStackChallenge(client); +var _platform = __webpack_require__(771); - case 5: - stackChallengeNonce = _context3.sent; - _context3.next = 8; - return (0, _storeAttestation.getAppAttestationFromStore)(stackChallengeNonce, certificationConfig); +var DEFAULT_DEVICE = 'Device'; - case 8: - appAttestation = _context3.sent; - _context3.next = 11; - return giveAppAttestationToStack(appAttestation, stackChallengeNonce, client); +// device +var getAppleModel = function getAppleModel(identifier) { + var devices = ['iPhone', 'iPad', 'Watch', 'AppleTV']; - case 11: - _context3.next = 17; - break; + for (var _i = 0, _devices = devices; _i < _devices.length; _i++) { + var _device = _devices[_i]; - case 13: - _context3.prev = 13; - _context3.t0 = _context3["catch"](2); + if (identifier.match(new RegExp(_device))) { + return _device; + } + } - _logger.default.warn('[FLAGSHIP_CERTIFICATION] Certification failed but the cozy-stack will continue with 2FA certification'); + return DEFAULT_DEVICE; +}; - _logger.default.warn(_context3.t0.message); +var getDeviceName = function getDeviceName() { + if (!(0, _plugins.hasDevicePlugin)()) { + if ((0, _cordova.isCordova)()) { + console.warn('You should install `cordova-plugin-device`.'); // eslint-disable-line no-console + } - case 17: - case "end": - return _context3.stop(); - } - } - }, _callee3, null, [[2, 13]]); - })); + return DEFAULT_DEVICE; + } - return function certifyFlagship(_x5, _x6) { - return _ref3.apply(this, arguments); - }; -}(); + var _window$device = window.device, + manufacturer = _window$device.manufacturer, + originalModel = _window$device.model; + var model = (0, _platform.isIOSApp)() ? getAppleModel(originalModel) : originalModel; + return "".concat((0, _capitalize.default)(manufacturer), " ").concat(model); +}; -exports.certifyFlagship = certifyFlagship; +exports.getDeviceName = getDeviceName; /***/ }), -/* 791 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -var _interopRequireDefault = __webpack_require__(512); - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.getAppAttestationFromStore = void 0; - -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +/* 774 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var toString = __webpack_require__(408), + upperFirst = __webpack_require__(775); /** - * Retrieve the app's attestation from the app's store - * /!\ This is a mock implementation that should never be called + * Converts the first character of `string` to upper case and the remaining + * to lower case. * - * @param {string} nonce - the Nonce string retrieved from the stack - * @param {CertificationConfig} certificationConfig - Configuration to access the stores certification API - * @returns {Promise<AttestationResult>} the app's attestation + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' */ -var validateAppMock = /*#__PURE__*/function () { - var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(nonce, certificationConfig) { - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - throw new Error("getAppAttestationFromStore can only be called from a React Native container"); - - case 1: - case "end": - return _context.stop(); - } - } - }, _callee); - })); +function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); +} - return function validateAppMock(_x, _x2) { - return _ref.apply(this, arguments); - }; -}(); +module.exports = capitalize; -var getAppAttestationFromStore = validateAppMock; -exports.getAppAttestationFromStore = getAppAttestationFromStore; /***/ }), -/* 792 */ +/* 775 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var createFlow = __webpack_require__(793); +var createCaseFirst = __webpack_require__(776); /** - * Creates a function that returns the result of invoking the given functions - * with the `this` binding of the created function, where each successive - * invocation is supplied the return value of the previous. + * Converts the first character of `string` to upper case. * * @static * @memberOf _ - * @since 3.0.0 - * @category Util - * @param {...(Function|Function[])} [funcs] The functions to invoke. - * @returns {Function} Returns the new composite function. - * @see _.flowRight + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. * @example * - * function square(n) { - * return n * n; - * } + * _.upperFirst('fred'); + * // => 'Fred' * - * var addSquare = _.flow([_.add, square]); - * addSquare(1, 2); - * // => 9 + * _.upperFirst('FRED'); + * // => 'FRED' */ -var flow = createFlow(); +var upperFirst = createCaseFirst('toUpperCase'); -module.exports = flow; +module.exports = upperFirst; /***/ }), -/* 793 */ +/* 776 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var LodashWrapper = __webpack_require__(794), - flatRest = __webpack_require__(620), - getData = __webpack_require__(796), - getFuncName = __webpack_require__(798), - isArray = __webpack_require__(55), - isLaziable = __webpack_require__(800); - -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; - -/** Used to compose bitmasks for function metadata. */ -var WRAP_CURRY_FLAG = 8, - WRAP_PARTIAL_FLAG = 32, - WRAP_ARY_FLAG = 128, - WRAP_REARG_FLAG = 256; +var castSlice = __webpack_require__(777), + hasUnicode = __webpack_require__(778), + stringToArray = __webpack_require__(779), + toString = __webpack_require__(408); /** - * Creates a `_.flow` or `_.flowRight` function. + * Creates a function like `_.lowerFirst`. * * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new flow function. + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new case function. */ -function createFlow(fromRight) { - return flatRest(function(funcs) { - var length = funcs.length, - index = length, - prereq = LodashWrapper.prototype.thru; - - if (fromRight) { - funcs.reverse(); - } - while (index--) { - var func = funcs[index]; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (prereq && !wrapper && getFuncName(func) == 'wrapper') { - var wrapper = new LodashWrapper([], true); - } - } - index = wrapper ? index : length; - while (++index < length) { - func = funcs[index]; +function createCaseFirst(methodName) { + return function(string) { + string = toString(string); - var funcName = getFuncName(func), - data = funcName == 'wrapper' ? getData(func) : undefined; + var strSymbols = hasUnicode(string) + ? stringToArray(string) + : undefined; - if (data && isLaziable(data[0]) && - data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && - !data[4].length && data[9] == 1 - ) { - wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); - } else { - wrapper = (func.length == 1 && isLaziable(func)) - ? wrapper[funcName]() - : wrapper.thru(func); - } - } - return function() { - var args = arguments, - value = args[0]; + var chr = strSymbols + ? strSymbols[0] + : string.charAt(0); - if (wrapper && args.length == 1 && isArray(value)) { - return wrapper.plant(value).value(); - } - var index = 0, - result = length ? funcs[index].apply(this, args) : value; + var trailing = strSymbols + ? castSlice(strSymbols, 1).join('') + : string.slice(1); - while (++index < length) { - result = funcs[index].call(this, result); - } - return result; - }; - }); + return chr[methodName]() + trailing; + }; } -module.exports = createFlow; +module.exports = createCaseFirst; /***/ }), -/* 794 */ +/* 777 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseCreate = __webpack_require__(585), - baseLodash = __webpack_require__(795); +var baseSlice = __webpack_require__(629); /** - * The base constructor for creating `lodash` wrapper objects. + * Casts `array` to a slice if it's needed. * * @private - * @param {*} value The value to wrap. - * @param {boolean} [chainAll] Enable explicit method chain sequences. + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. */ -function LodashWrapper(value, chainAll) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__chain__ = !!chainAll; - this.__index__ = 0; - this.__values__ = undefined; +function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); } -LodashWrapper.prototype = baseCreate(baseLodash.prototype); -LodashWrapper.prototype.constructor = LodashWrapper; - -module.exports = LodashWrapper; +module.exports = castSlice; /***/ }), -/* 795 */ +/* 778 */ /***/ ((module) => { +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + /** - * The function whose prototype chain sequence wrappers inherit from. + * Checks if `string` contains Unicode symbols. * * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. */ -function baseLodash() { - // No operation performed. +function hasUnicode(string) { + return reHasUnicode.test(string); } -module.exports = baseLodash; +module.exports = hasUnicode; /***/ }), -/* 796 */ +/* 779 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var metaMap = __webpack_require__(797), - noop = __webpack_require__(471); +var asciiToArray = __webpack_require__(780), + hasUnicode = __webpack_require__(778), + unicodeToArray = __webpack_require__(781); /** - * Gets metadata for `func`. + * Converts `string` to an array. * * @private - * @param {Function} func The function to query. - * @returns {*} Returns the metadata for `func`. + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. */ -var getData = !metaMap ? noop : function(func) { - return metaMap.get(func); -}; +function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); +} -module.exports = getData; +module.exports = stringToArray; /***/ }), -/* 797 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var WeakMap = __webpack_require__(451); +/* 780 */ +/***/ ((module) => { -/** Used to store function metadata. */ -var metaMap = WeakMap && new WeakMap; +/** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function asciiToArray(string) { + return string.split(''); +} -module.exports = metaMap; +module.exports = asciiToArray; /***/ }), -/* 798 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 781 */ +/***/ ((module) => { -var realNames = __webpack_require__(799); +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; -/** Used for built-in method references. */ -var objectProto = Object.prototype; +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + rsAstralRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ = '\\u200d'; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); /** - * Gets the name of `func`. + * Converts a Unicode `string` to an array. * * @private - * @param {Function} func The function to query. - * @returns {string} Returns the function name. + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. */ -function getFuncName(func) { - var result = (func.name + ''), - array = realNames[result], - length = hasOwnProperty.call(realNames, result) ? array.length : 0; - - while (length--) { - var data = array[length], - otherFunc = data.func; - if (otherFunc == null || otherFunc == func) { - return data.name; - } - } - return result; +function unicodeToArray(string) { + return string.match(reUnicode) || []; } -module.exports = getFuncName; +module.exports = unicodeToArray; /***/ }), -/* 799 */ -/***/ ((module) => { +/* 782 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -/** Used to lookup unminified function names. */ -var realNames = {}; +"use strict"; -module.exports = realNames; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.hasSafariPlugin = exports.hasNetworkInformationPlugin = exports.hasInAppBrowserPlugin = exports.hasDevicePlugin = void 0; + +var _cordova = __webpack_require__(772); -/***/ }), -/* 800 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var hasDevicePlugin = function hasDevicePlugin() { + return (0, _cordova.isCordova)() && window.device !== undefined; +}; + +exports.hasDevicePlugin = hasDevicePlugin; + +var hasInAppBrowserPlugin = function hasInAppBrowserPlugin() { + return (0, _cordova.isCordova)() && window.cordova.InAppBrowser !== undefined; +}; + +exports.hasInAppBrowserPlugin = hasInAppBrowserPlugin; -var LazyWrapper = __webpack_require__(801), - getData = __webpack_require__(796), - getFuncName = __webpack_require__(798), - lodash = __webpack_require__(802); +var hasSafariPlugin = function hasSafariPlugin() { + return new Promise(function (resolve) { + if (!(0, _cordova.isCordova)() || window.SafariViewController === undefined) { + resolve(false); + return; + } + window.SafariViewController.isAvailable(function (available) { + return resolve(available); + }); + }); +}; /** - * Checks if `func` has a lazy counterpart. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` has a lazy counterpart, - * else `false`. + * Check if the Cordova's cordova-plugin-network-information plugin is installed + * @see https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-network-information/ + * @returns {boolean} */ -function isLaziable(func) { - var funcName = getFuncName(func), - other = lodash[funcName]; - if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { - return false; - } - if (func === other) { - return true; - } - var data = getData(other); - return !!data && func === data[0]; -} -module.exports = isLaziable; +exports.hasSafariPlugin = hasSafariPlugin; + +var hasNetworkInformationPlugin = function hasNetworkInformationPlugin() { + return (0, _cordova.isCordova)() && window.navigator.connection !== undefined; +}; +exports.hasNetworkInformationPlugin = hasNetworkInformationPlugin; /***/ }), -/* 801 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 783 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -var baseCreate = __webpack_require__(585), - baseLodash = __webpack_require__(795); +"use strict"; -/** Used as references for the maximum length and index of an array. */ -var MAX_ARRAY_LENGTH = 4294967295; + +var _interopRequireDefault = __webpack_require__(524); + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.startApp = exports["default"] = exports.checkApp = void 0; + +var _regenerator = _interopRequireDefault(__webpack_require__(539)); + +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); + +var _platform = __webpack_require__(771); + +var cordovaPluginIsInstalled = function cordovaPluginIsInstalled() { + return window.startApp; +}; /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. - * - * @private - * @constructor - * @param {*} value The value to wrap. + * Normalize startApp params for Android and iOS */ -function LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__dir__ = 1; - this.__filtered__ = false; - this.__iteratees__ = []; - this.__takeCount__ = MAX_ARRAY_LENGTH; - this.__views__ = []; -} +var getParams = function getParams(_ref) { + var appId = _ref.appId, + uri = _ref.uri; -// Ensure `LazyWrapper` is an instance of `baseLodash`. -LazyWrapper.prototype = baseCreate(baseLodash.prototype); -LazyWrapper.prototype.constructor = LazyWrapper; + if ((0, _platform.isAndroidApp)()) { + return { + package: appId + }; + } else { + return uri; + } +}; -module.exports = LazyWrapper; +var exported = {}; +/** + * Start an application if it is installed on the phone + * @returns Promise - False if the application was not able to be started + */ +var startApp = exported.startApp = /*#__PURE__*/function () { + var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(appInfo) { + var startAppPlugin, isAppInstalled, params; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + startAppPlugin = window.startApp; + _context.next = 3; + return exported.checkApp(appInfo); -/***/ }), -/* 802 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 3: + isAppInstalled = _context.sent; -var LazyWrapper = __webpack_require__(801), - LodashWrapper = __webpack_require__(794), - baseLodash = __webpack_require__(795), - isArray = __webpack_require__(55), - isObjectLike = __webpack_require__(53), - wrapperClone = __webpack_require__(803); + if (!isAppInstalled) { + _context.next = 9; + break; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + params = getParams(appInfo); + return _context.abrupt("return", new Promise(function (resolve, reject) { + if (!cordovaPluginIsInstalled()) { + reject(new Error("Cordova plugin 'com.lampa.startapp' is not installed. This plugin is needed to start a native app. Required by cozy-bar")); + return; + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + startAppPlugin.set(params).start(resolve, reject); + })); + + case 9: + return _context.abrupt("return", false); + case 10: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function (_x) { + return _ref2.apply(this, arguments); + }; +}(); /** - * Creates a `lodash` object which wraps `value` to enable implicit method - * chain sequences. Methods that operate on and return arrays, collections, - * and functions can be chained together. Methods that retrieve a single value - * or may return a primitive value will automatically end the chain sequence - * and return the unwrapped value. Otherwise, the value must be unwrapped - * with `_#value`. - * - * Explicit chain sequences, which must be unwrapped with `_#value`, may be - * enabled using `_.chain`. - * - * The execution of chained methods is lazy, that is, it's deferred until - * `_#value` is implicitly or explicitly called. - * - * Lazy evaluation allows several methods to support shortcut fusion. - * Shortcut fusion is an optimization to merge iteratee calls; this avoids - * the creation of intermediate arrays and can greatly reduce the number of - * iteratee executions. Sections of a chain sequence qualify for shortcut - * fusion if the section is applied to an array and iteratees accept only - * one argument. The heuristic for whether a section qualifies for shortcut - * fusion is subject to change. - * - * Chaining is supported in custom builds as long as the `_#value` method is - * directly or indirectly included in the build. - * - * In addition to lodash methods, wrappers have `Array` and `String` methods. - * - * The wrapper `Array` methods are: - * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` - * - * The wrapper `String` methods are: - * `replace` and `split` - * - * The wrapper methods that support shortcut fusion are: - * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, - * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, - * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` - * - * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, - * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, - * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, - * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, - * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, - * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, - * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, - * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, - * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, - * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, - * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, - * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, - * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, - * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, - * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, - * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, - * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, - * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, - * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, - * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, - * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, - * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, - * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, - * `zipObject`, `zipObjectDeep`, and `zipWith` - * - * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, - * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, - * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, - * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, - * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, - * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, - * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, - * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, - * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, - * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, - * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, - * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, - * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, - * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, - * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, - * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, - * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, - * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, - * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, - * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, - * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, - * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, - * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, - * `upperFirst`, `value`, and `words` - * - * @name _ - * @constructor - * @category Seq - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2, 3]); - * - * // Returns an unwrapped value. - * wrapped.reduce(_.add); - * // => 6 - * - * // Returns a wrapped value. - * var squares = wrapped.map(square); - * - * _.isArray(squares); - * // => false + * Check that an application is installed on the phone + * @returns Promise - Promise containing information on the application * - * _.isArray(squares.value()); - * // => true - */ -function lodash(value) { - if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { - if (value instanceof LodashWrapper) { - return value; - } - if (hasOwnProperty.call(value, '__wrapped__')) { - return wrapperClone(value); - } - } - return new LodashWrapper(value); -} - -// Ensure wrappers are instances of `baseLodash`. -lodash.prototype = baseLodash.prototype; -lodash.prototype.constructor = lodash; + * @example + * > checkApp({ appId: 'io.cozy.drive.mobile', uri: 'cozydrive://' }) + * Promise.resolve({ + * versionName: "0.9.2", + * packageName: "io.cozy.drive.mobile", + * versionCode: 902, + * applicationInfo: "ApplicationInfo{70aa0ef io.cozy.drive.mobile}" + * }) + */ -module.exports = lodash; +exports.startApp = startApp; -/***/ }), -/* 803 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var checkApp = exported.checkApp = /*#__PURE__*/function () { + var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(appInfo) { + var startAppPlugin, params; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + startAppPlugin = window.startApp; + params = getParams(appInfo); + return _context2.abrupt("return", new Promise(function (resolve, reject) { + if (!cordovaPluginIsInstalled()) { + reject(new Error("Cordova plugin 'com.lampa.startapp' is not installed.")); + return; + } -var LazyWrapper = __webpack_require__(801), - LodashWrapper = __webpack_require__(794), - copyArray = __webpack_require__(571); + startAppPlugin.set(params).check(function (infos) { + return resolve(infos === 'OK' ? true : infos); + }, function (error) { + if (error === false || error.indexOf('NameNotFoundException') === 0) { + // Plugin returns an error 'NameNotFoundException' on Android and + // false on iOS when an application is not found. + // We prefer to always return false + resolve(false); + } else { + reject(error); + } + }); + })); -/** - * Creates a clone of `wrapper`. - * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. - */ -function wrapperClone(wrapper) { - if (wrapper instanceof LazyWrapper) { - return wrapper.clone(); - } - var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); - result.__actions__ = copyArray(wrapper.__actions__); - result.__index__ = wrapper.__index__; - result.__values__ = wrapper.__values__; - return result; -} + case 3: + case "end": + return _context2.stop(); + } + } + }, _callee2); + })); -module.exports = wrapperClone; + return function (_x2) { + return _ref3.apply(this, arguments); + }; +}(); +exports.checkApp = checkApp; +var _default = exported; +exports["default"] = _default; /***/ }), -/* 804 */ -/***/ ((__unused_webpack_module, exports) => { +/* 784 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; +var _interopRequireDefault = __webpack_require__(524); + Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.hasQueryBeenLoaded = exports.isQueryLoading = exports.cancelable = void 0; +exports.nativeLinkOpen = void 0; -/** - * @typedef {Promise} CancelablePromise - * @property {Function} cancel - Cancel the promise - */ +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -/** - * Wraps a promise so that it can be canceled - * - * Rejects with canceled: true as soon as cancel is called - * - * @param {Promise} promise - Promise - * @returns {CancelablePromise} - Promise with .cancel method - */ -var cancelable = function cancelable(promise) { - var _reject; +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - var wrapped = new Promise(function (resolve, reject) { - _reject = reject; - promise.then(resolve); - promise.catch(reject); - }); // @ts-ignore +var _plugins = __webpack_require__(782); - wrapped.cancel = function () { - _reject({ - canceled: true - }); - }; +var nativeLinkOpen = /*#__PURE__*/function () { + var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) { + var url, target, options; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + url = _ref.url; + _context.next = 3; + return (0, _plugins.hasSafariPlugin)(); - return wrapped; -}; + case 3: + _context.t0 = _context.sent; -exports.cancelable = cancelable; + if (!_context.t0) { + _context.next = 6; + break; + } -/** - * Returns whether the result of a query (given via queryConnect or Query) - * is loading. - */ -var isQueryLoading = function isQueryLoading(col) { - if (!col) { - console.warn('isQueryLoading called on falsy value.'); // eslint-disable-line no-console + _context.t0 = window.SafariViewController; - return false; - } + case 6: + if (!_context.t0) { + _context.next = 10; + break; + } - return col.fetchStatus === 'loading' || col.fetchStatus === 'pending'; -}; -/** - * Returns whether a query has been loaded at least once - */ + window.SafariViewController.show({ + url: url, + transition: 'curl' + }, function (result) { + if (result.event === 'closed') { + window.SafariViewController.hide(); + } + }, function () { + window.SafariViewController.hide(); + }); + _context.next = 11; + break; + case 10: + if ((0, _plugins.hasInAppBrowserPlugin)()) { + target = '_blank'; + options = 'clearcache=yes,zoom=no'; + window.cordova.InAppBrowser.open(url, target, options); + } else { + window.location = url; + } -exports.isQueryLoading = isQueryLoading; + case 11: + case "end": + return _context.stop(); + } + } + }, _callee); + })); -var hasQueryBeenLoaded = function hasQueryBeenLoaded(col) { - return col.lastFetch; -}; + return function nativeLinkOpen(_x) { + return _ref2.apply(this, arguments); + }; +}(); -exports.hasQueryBeenLoaded = hasQueryBeenLoaded; +exports.nativeLinkOpen = nativeLinkOpen; /***/ }), -/* 805 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/* 785 */ +/***/ ((__unused_webpack_module, exports) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); - Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.sanitizeCategories = sanitizeCategories; -exports.areTermsValid = areTermsValid; -exports.isPartnershipValid = isPartnershipValid; -exports.sanitize = sanitize; +exports.openDeeplinkOrRedirect = void 0; + +/** + * This file is used to open the native app from a webapp + * if this native app is installed + * + * From a webapp, we don't have any clue if a native app is installed. + * The only way to know that, is to try to open the custom link + * (aka cozydrive://) and if nothing happens (no blur) we redirect to + * the callback + * + * Firefox tries to open custom link, so we need to create an iframe + * to detect if this is supported or not + */ +var _createHiddenIframe = function _createHiddenIframe(target, uri, randomId) { + var iframe = document.createElement('iframe'); + iframe.src = uri; + iframe.id = "hiddenIframe_".concat(randomId); + iframe.style.display = 'none'; + target.appendChild(iframe); + return iframe; +}; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var openUriWithHiddenFrame = function openUriWithHiddenFrame(uri, failCb) { + var randomId = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5); + window.addEventListener('blur', onBlur); -var _types = __webpack_require__(610); + var iframe = _createHiddenIframe(document.body, 'about:blank', randomId); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + var timeout = setTimeout(function () { + failCb(); + window.removeEventListener('blur', onBlur); + iframe.parentElement.removeChild(iframe); + }, 500); -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + function onBlur() { + clearTimeout(timeout); + window.removeEventListener('blur', onBlur); + iframe.parentElement.removeChild(iframe); + } -var APP_CATEGORIES = ['banking', 'cozy', 'energy', 'health', 'host_provider', 'insurance', 'isp', 'mes_infos', 'online_services', 'others', 'partners', 'press', 'productivity', 'ptnb', 'public_service', 'shopping', 'social', 'telecom', 'transport']; -/** Filters unauthorized categories. Defaults to ['others'] if no suitable category. */ + iframe.contentWindow.location.href = uri; +}; -function sanitizeCategories(categories) { - if (!categories) return ['others']; - var filteredList = categories.filter(function (c) { - return APP_CATEGORIES.includes(c); - }); - if (!filteredList.length) return ['others']; - return filteredList; -} +var openUriWithTimeoutHack = function openUriWithTimeoutHack(uri, failCb) { + var timeout = setTimeout(function () { + failCb(); + target.removeEventListener('blur', onBlur); + }, 500); // handle page running in an iframe (blur must be registered with top level window) -function areTermsValid(terms) { - return Boolean(terms && terms.id && terms.url && terms.version); -} + var target = window; -function isPartnershipValid(partnership) { - return Boolean(partnership && partnership.description); -} + while (target != target.parent) { + target = target.parent; + } + + target.addEventListener('blur', onBlur); + + function onBlur() { + clearTimeout(timeout); + target.removeEventListener('blur', onBlur); + } // Why is an uri assigned to location object? + + + window.location = uri; +}; + +var openUriWithMsLaunchUri = function openUriWithMsLaunchUri(uri, failCb) { + navigator.msLaunchUri(uri, undefined, failCb); +}; + +var checkBrowser = function checkBrowser() { + var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; + var ua = navigator.userAgent.toLowerCase(); + var isSafari = ua.includes('safari') && !ua.includes('chrome') || Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; + var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; + var isIOS122 = isIOS && (ua.includes('os 12_2') || ua.includes('os 12_3')); + return { + isOpera: isOpera, + isFirefox: typeof window.InstallTrigger !== 'undefined', + isSafari: isSafari, + isChrome: !!window.chrome && !isOpera, + isIOS122: isIOS122, + isIOS: isIOS + }; +}; /** - * Normalize app manifest, retrocompatibility for old manifests * - * @param {Manifest} manifest - * @returns {Manifest} + * @param {String} deeplink (cozydrive://) + * @param {String} failCb (http://drive.cozy.ios) */ -function sanitize(manifest) { - var sanitized = _objectSpread({}, manifest); // Make categories an array and delete category attribute if it exists - +var openDeeplinkOrRedirect = function openDeeplinkOrRedirect(deeplink, failCb) { + if (navigator.msLaunchUri) { + // for IE and Edge in Win 8 and Win 10 + openUriWithMsLaunchUri(deeplink, failCb); + } else { + var browser = checkBrowser(); - if (!manifest.categories && manifest.category && typeof manifest.category === 'string') { - sanitized.categories = [manifest.category]; - delete sanitized.category; + if (browser.isChrome || browser.isIOS && !browser.isIOS122) { + openUriWithTimeoutHack(deeplink, failCb); + } else if (browser.isSafari && !browser.isIOS122 || browser.isFirefox) { + openUriWithHiddenFrame(deeplink, failCb); + } else { + failCb(); + } } +}; - sanitized.categories = sanitizeCategories(sanitized.categories); // manifest name is not an object +exports.openDeeplinkOrRedirect = openDeeplinkOrRedirect; - if (typeof manifest.name === 'object') sanitized.name = manifest.name.en; // Fix camelCase from cozy-stack +/***/ }), +/* 786 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - if (manifest.available_version) { - sanitized.availableVersion = manifest.available_version; - delete sanitized.available_version; - } // Fix camelCase from cozy-stack +"use strict"; - if (manifest.latest_version) { - sanitized.latestVersion = manifest.latestVersion; - delete sanitized.latest_version; - } // Remove invalid terms +var _interopRequireDefault = __webpack_require__(524); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.isFlagshipApp = exports.getFlagshipMetadata = exports.FlagshipRoutes = void 0; - if (sanitized.terms && !areTermsValid(sanitized.terms)) { - delete sanitized.terms; - } // Remove invalid partnership +var _cozyLogger = _interopRequireDefault(__webpack_require__(354)); +var FlagshipRoutes; +exports.FlagshipRoutes = FlagshipRoutes; - if (sanitized.partnership && !isPartnershipValid(sanitized.partnership)) { - delete sanitized.partnership; +(function (FlagshipRoutes) { + FlagshipRoutes["Home"] = "home"; + FlagshipRoutes["Cozyapp"] = "cozyapp"; + FlagshipRoutes["Authenticate"] = "authenticate"; + FlagshipRoutes["Onboarding"] = "onboarding"; + FlagshipRoutes["Stack"] = "stack"; +})(FlagshipRoutes || (exports.FlagshipRoutes = FlagshipRoutes = {})); + +var getGlobalWindow = function getGlobalWindow() { + if (typeof window !== 'undefined') return window;else { + (0, _cozyLogger.default)('error', "\"window\" is not defined. This means that getGlobalWindow() shouldn't have been called and investigation should be done to prevent this call"); + return undefined; } +}; - return sanitized; -} +var getFlagshipMetadata = function getFlagshipMetadata() { + var _getGlobalWindow, _getGlobalWindow$cozy; + + return ((_getGlobalWindow = getGlobalWindow()) === null || _getGlobalWindow === void 0 ? void 0 : (_getGlobalWindow$cozy = _getGlobalWindow.cozy) === null || _getGlobalWindow$cozy === void 0 ? void 0 : _getGlobalWindow$cozy.flagship) || {}; +}; + +exports.getFlagshipMetadata = getFlagshipMetadata; + +var isFlagshipApp = function isFlagshipApp() { + var _getGlobalWindow2, _getGlobalWindow2$coz; + + return ((_getGlobalWindow2 = getGlobalWindow()) === null || _getGlobalWindow2 === void 0 ? void 0 : (_getGlobalWindow2$coz = _getGlobalWindow2.cozy) === null || _getGlobalWindow2$coz === void 0 ? void 0 : _getGlobalWindow2$coz.flagship) !== undefined; +}; + +exports.isFlagshipApp = isFlagshipApp; /***/ }), -/* 806 */ +/* 787 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.createMockClient = void 0; +exports["default"] = void 0; -var _slicedToArray2 = _interopRequireDefault(__webpack_require__(520)); +var _mapValues = _interopRequireDefault(__webpack_require__(545)); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _groupBy2 = _interopRequireDefault(__webpack_require__(736)); -var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(525)); +var _flatten = _interopRequireDefault(__webpack_require__(552)); -var _CozyClient = _interopRequireDefault(__webpack_require__(513)); +var _isEqual = _interopRequireDefault(__webpack_require__(658)); -var _store = __webpack_require__(693); +var _uniq = _interopRequireDefault(__webpack_require__(624)); -var _cozyStackClient = __webpack_require__(559); +var _uniqWith = _interopRequireDefault(__webpack_require__(788)); -var _dsl = __webpack_require__(607); +var _dsl = __webpack_require__(619); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +var isIdQuery = function isIdQuery(query) { + return query.id || query.ids; +}; +/** + * Optimize queries on a single doctype + * + * @param {QueryDefinition[]} queries - Queries of a same doctype + * @returns {QueryDefinition[]} Optimized queries + * @private + */ -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var fillQueryInsideClient = function fillQueryInsideClient(client, queryName, queryOptions) { - var definition = queryOptions.definition, - doctype = queryOptions.doctype, - data = queryOptions.data, - queryResult = (0, _objectWithoutProperties2.default)(queryOptions, ["definition", "doctype", "data"]); - client.store.dispatch((0, _store.initQuery)(queryName, definition || (0, _dsl.Q)(doctype))); - client.store.dispatch((0, _store.receiveQueryResult)(queryName, _objectSpread({ - data: data ? data.map(function (doc) { - return (0, _cozyStackClient.normalizeDoc)(doc, doctype); - }) : data - }, queryResult))); +var optimizeDoctypeQueries = function optimizeDoctypeQueries(queries) { + var _groupBy = (0, _groupBy2.default)(queries, function (q) { + return isIdQuery(q) ? 'idQueries' : 'others'; + }), + _groupBy$idQueries = _groupBy.idQueries, + idQueries = _groupBy$idQueries === void 0 ? [] : _groupBy$idQueries, + _groupBy$others = _groupBy.others, + others = _groupBy$others === void 0 ? [] : _groupBy$others; + + var groupedIdQueries = idQueries.length > 0 ? new _dsl.QueryDefinition({ + doctype: queries[0].doctype, + ids: (0, _uniq.default)((0, _flatten.default)(idQueries.map(function (q) { + return q.id || q.ids; + }))) + }) : []; // Deduplicate before concataining + + return (0, _uniqWith.default)(others, _isEqual.default).concat(groupedIdQueries); }; +/** + * Reduce the number of queries used to fetch documents. + * + * - Deduplication of queries + * - Groups id queries + * + * @param {QueryDefinition[]} queries - Queries to optimized + * @returns {QueryDefinition[]} Optimized queries + * @private + */ -var mockedQueryFromMockedRemoteData = function mockedQueryFromMockedRemoteData(remoteData) { - return function (qdef) { - if (!remoteData) { - return { - data: null - }; - } - if (remoteData[qdef.doctype]) { - return { - data: remoteData[qdef.doctype] - }; - } else { - return { - data: [] - }; - } - }; +var optimizeQueries = function optimizeQueries(queries) { + var byDoctype = (0, _groupBy2.default)(queries, function (q) { + return q.doctype; + }); + return (0, _flatten.default)(Object.values((0, _mapValues.default)(byDoctype, optimizeDoctypeQueries))); }; + +var _default = optimizeQueries; +exports["default"] = _default; + +/***/ }), +/* 788 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseUniq = __webpack_require__(475); + /** - * Creates a client suitable for use in tests + * This method is like `_.uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The order of result values is + * determined by the order they occur in the array.The comparator is invoked + * with two arguments: (arrVal, othVal). * - * - client.{query,save} are mocked - * - client.stackClient.fetchJSON is mocked + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example * - * @param {object} options Options - * @param {object} [options.queries] Prefill queries inside the store - * @param {object} [options.remote] Mock data from the server - * @param {object} [options.clientOptions] Options passed to the client - * @returns {CozyClient} + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.uniqWith(objects, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] */ +function uniqWith(array, comparator) { + comparator = typeof comparator == 'function' ? comparator : undefined; + return (array && array.length) ? baseUniq(array, undefined, comparator) : []; +} +module.exports = uniqWith; -var createMockClient = function createMockClient(_ref) { - var queries = _ref.queries, - remote = _ref.remote, - clientOptions = _ref.clientOptions; - var client = new _CozyClient.default(clientOptions || {}); - client.ensureStore(); - for (var _i = 0, _Object$entries = Object.entries(queries || {}); _i < _Object$entries.length; _i++) { - var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2), - queryName = _Object$entries$_i[0], - queryOptions = _Object$entries$_i[1]; +/***/ }), +/* 789 */ +/***/ ((__unused_webpack_module, exports) => { - fillQueryInsideClient(client, queryName, queryOptions); - } +"use strict"; - client.query = jest.fn().mockImplementation(mockedQueryFromMockedRemoteData(remote)); - client.save = jest.fn(); - client.saveAll = jest.fn(); - client.stackClient.fetchJSON = jest.fn(); - return client; -}; -exports.createMockClient = createMockClient; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +/** + * Use those fetch policies with `<Query />` to limit the number of re-fetch. + * + * @example + * ``` + * import { fetchPolicies } from 'cozy-client' + * const olderThan30s = fetchPolicies.olderThan(30 * 1000) + * <Query fetchPolicy={olderThan30s} /> + * ``` + */ +var fetchPolicies = { + /** + * Returns a fetchPolicy that will only re-fetch queries that are older + * than `<delay>` ms. + * + * @param {number} delay - Milliseconds since the query has been fetched + * @returns {Function} Fetch policy to be used with `<Query />` + */ + olderThan: function olderThan(delay) { + return function (queryState) { + if (!queryState || !queryState.lastUpdate) { + return true; + } else { + var elapsed = Date.now() - queryState.lastUpdate; + return elapsed > delay; + } + }; + }, + + /** + * Fetch policy that deactivates any fetching. + */ + noFetch: function noFetch() { + return false; + } +}; +var _default = fetchPolicies; +exports["default"] = _default; /***/ }), -/* 807 */ -/***/ ((module, exports, __webpack_require__) => { +/* 790 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -/* module decorator */ module = __webpack_require__.nmd(module); -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.createClientInteractive = void 0; +exports["default"] = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _http = _interopRequireDefault(__webpack_require__(80)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _open = _interopRequireDefault(__webpack_require__(808)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _fs = _interopRequireDefault(__webpack_require__(149)); +var _keyBy = _interopRequireDefault(__webpack_require__(711)); + +var _mapValues = _interopRequireDefault(__webpack_require__(545)); -var _merge = _interopRequireDefault(__webpack_require__(742)); +var _merge = _interopRequireDefault(__webpack_require__(754)); -var _serverDestroy = _interopRequireDefault(__webpack_require__(812)); +var _size = _interopRequireDefault(__webpack_require__(791)); -var _CozyClient = _interopRequireDefault(__webpack_require__(513)); +var _intersectionBy = _interopRequireDefault(__webpack_require__(795)); -var _cozyLogger = _interopRequireDefault(__webpack_require__(813)); +var _associations = __webpack_require__(703); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -var log = _cozyLogger.default.namespace('create-cli-client'); +/** + * @typedef {object} DoctypeSchema + */ -var nodeFetch = __webpack_require__(481); +/** + * @typedef {Record<string, DoctypeSchema>} SchemaDefinition + */ -var btoa = __webpack_require__(478); /** - * Creates and starts and HTTP server suitable for OAuth authentication - * - * @param {object} serverOptions - OAuth callback server options - * @param {Function} serverOptions.onAuthentication - Additional callback called - * when the user authenticates - * @param {string} serverOptions.route - Route used for authentication - * @param {number} serverOptions.port - Port on which the server will listen - * @param {Function} serverOptions.onListen - Callback called when the - * server starts - * - * @typedef {object} DestroyableServer - * @function destroy + * Returns a normalized schema object from the schema definition. * - * @returns {DestroyableServer} + * - Relationships are resolved to classes if needed + * - The name of the relationship (its key in the schema definition) + * is included in the relationship + * - Empty relationships are nulled * * @private */ +var normalizeDoctypeSchema = function normalizeDoctypeSchema(doctypeSchema) { + var relationships = (0, _mapValues.default)(doctypeSchema.relationships || {}, function (v, k) { + return _objectSpread(_objectSpread({}, v), {}, { + name: k, + type: (0, _associations.resolveClass)(v.doctype, v.type) + }); + }); + return _objectSpread(_objectSpread({}, doctypeSchema), {}, { + relationships: (0, _size.default)(relationships) > 0 ? (0, _keyBy.default)(relationships, 'name') : null + }); +}; +var assert = function assert(predicate, errorMessage) { + if (!predicate) throw new Error(errorMessage); +}; -var createCallbackServer = function createCallbackServer(serverOptions) { - var route = serverOptions.route, - onListen = serverOptions.onListen, - onAuthentication = serverOptions.onAuthentication, - port = serverOptions.port; - - var server = _http.default.createServer(function (request, response) { - if (request.url.indexOf(route) === 0) { - onAuthentication(request.url); - response.write('Authentication successful, you can close this page.'); - response.end(); - } +var ensureCanBeAdded = function ensureCanBeAdded(newSchemas, existingSchemas) { + var sameNames = (0, _intersectionBy.default)(newSchemas, existingSchemas, function (x) { + return x.name; }); - - server.listen(port, function () { - onListen(); + assert(sameNames.length === 0, "Duplicated names in schemas being added: ".concat(sameNames.map(function (x) { + return x.name; + }).join(', '))); + var sameDoctypes = (0, _intersectionBy.default)(newSchemas, existingSchemas, function (x) { + return x.doctype; }); - (0, _serverDestroy.default)(server); - return server; + assert(sameDoctypes.length === 0, "Duplicated doctypes in schemas being added: ".concat(sameDoctypes.map(function (x) { + return x.name; + }).join(', '))); }; /** - * Creates a function suitable for usage with CozyClient::startOAuthFlow - * - * Starts a local server. The stack upon user authentication will - * redirect to this local server with a URL containing credentials. - * The callback resolves with this authenticationURL which continues - * the authentication flow inside startOAuthFlow. - * - * When the server is started, the authentication page is opened on the - * desktop browser of the user. + * Stores information on a particular doctype. * - * @param {object} serverOptions - Options for the OAuth callback server - * @param {number} serverOptions.port - Port used for the OAuth callback server - * @param {Function} serverOptions.onAuthentication - Callback when the user authenticates - * @param {Function} serverOptions.onListen - Callback called with the authentication URL - * @param {string} serverOptions.route - Route used for authentication - * @param {boolean} serverOptions.shouldOpenAuthenticationPage - Whether the authentication - * page should be automatically opened (default: true) + * - Attribute validation + * - Relationship access * - * @private + * ```js + * const schema = new Schema({ + * todos: { + * attributes: { + * label: { + * unique: true + * } + * }, + * relationships: { + * author: 'has-one-in-place' + * } + * } + * }, cozyStackClient) + * ``` */ -var mkServerFlowCallback = function mkServerFlowCallback(serverOptions) { - return function (authenticationURL) { - return new Promise(function (resolve, reject) { - var rejectTimeout, successTimeout; - var server = createCallbackServer(_objectSpread(_objectSpread({}, serverOptions), {}, { - onAuthentication: function onAuthentication(callbackURL) { - log('debug', 'Authenticated, Shutting server down'); - successTimeout = setTimeout(function () { - // Is there a way to call destroy only after all requests have - // been completely served ? Otherwise we close the server while - // the successful oauth page is being served and the page does - // not get loaded on the client side. - server.destroy(); - resolve('http://localhost:8000/' + callbackURL); - clearTimeout(rejectTimeout); - }, 300); - }, - onListen: function onListen() { - log('debug', 'OAuth callback server started, waiting for authentication'); +var Schema = /*#__PURE__*/function () { + /** + * @param {SchemaDefinition} schemaDefinition - Schema for the application documents + * @param {object} client - An instance of cozy client (optional) + */ + function Schema() { + var schemaDefinition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var client = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + (0, _classCallCheck2.default)(this, Schema); + this.byDoctype = {}; + this.add(schemaDefinition); + this.client = client; + } + /** + * @param {SchemaDefinition} schemaDefinition - Additional schema to merge to current schema + */ - if (serverOptions.shouldOpenAuthenticationPage !== false) { - (0, _open.default)(authenticationURL, { - wait: false - }); - } - if (serverOptions.onListen) { - serverOptions.onListen({ - authenticationURL: authenticationURL - }); - } - } + (0, _createClass2.default)(Schema, [{ + key: "add", + value: function add() { + var schemaDefinition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var normalizedSchemaDefinition = (0, _mapValues.default)(schemaDefinition, function (obj, name) { + return _objectSpread({ + name: name + }, normalizeDoctypeSchema(obj)); + }); + ensureCanBeAdded(Object.values(normalizedSchemaDefinition), Object.values(this.byDoctype)); + (0, _merge.default)(this.byDoctype, (0, _keyBy.default)(normalizedSchemaDefinition, function (x) { + return x.doctype; })); - rejectTimeout = setTimeout(function () { - clearTimeout(successTimeout); - server.destroy(); - reject('Timeout for authentication'); - }, 30 * 1000); - }); - }; -}; - -var hashCode = function hashCode(str) { - var hash = 0, - i, - chr; - if (str.length === 0) return hash; + } + /** + * Returns the schema for a doctype + * + * Creates an empty schema implicitly if it does not exist + * + * @param {string} doctype - Doctype + */ - for (i = 0; i < str.length; i++) { - chr = str.charCodeAt(i); - hash = (hash << 5) - hash + chr; - hash |= 0; // Convert to 32bit integer - } + }, { + key: "getDoctypeSchema", + value: function getDoctypeSchema(doctype) { + var schema = this.byDoctype[doctype]; - return hash; -}; + if (!schema) { + schema = normalizeDoctypeSchema({ + name: doctype, + doctype: doctype + }); + this.byDoctype[doctype] = schema; + } -var DEFAULT_SERVER_OPTIONS = { - port: 3333, - route: '/do_access', - getSavedCredentials: function getSavedCredentials(clientOptions) { - if (!clientOptions.oauth.softwareID) { - throw new Error('Please provide oauth.softwareID in your clientOptions.'); + return schema; } + /** + * Returns the relationship for a given doctype/name + * + * @param {string} doctype - Doctype + * @param {string} relationshipName - Relationship name + */ - var doctypeHash = Math.abs(hashCode(JSON.stringify(clientOptions.scope))); - var sluggedURI = clientOptions.uri.replace(/https?:\/\//, '').replace(/\./g, '-'); - return "/tmp/cozy-client-oauth-".concat(sluggedURI, "-").concat(clientOptions.oauth.softwareID, "-").concat(doctypeHash, ".json"); - } -}; + }, { + key: "getRelationship", + value: function getRelationship(doctype, relationshipName) { + if (!doctype) { + throw new TypeError("Invalid doctype ".concat(doctype)); + } -var writeJSON = function writeJSON(fs, filename, data) { - fs.writeFileSync(filename, JSON.stringify(data)); -}; -/** - * Parses a JSON from a file - * Returns null in case of error - * - * @private - */ + var schema = this.getDoctypeSchema(doctype); + + if (!schema) { + throw new Error("Cannot find doctype ".concat(doctype, " in schema")); + } + if (!schema.relationships) { + throw new Error("Schema for doctype ".concat(doctype, " has no relationships")); + } -var readJSON = function readJSON(fs, filename) { - try { - if (!fs.existsSync(filename)) { - return null; + return schema.relationships[relationshipName]; } + /** + * Validates a document considering the descriptions in schema.attributes. + */ - var res = JSON.parse(fs.readFileSync(filename).toString()); - return res; - } catch (e) { - console.warn("Could not load ".concat(filename, " (").concat(e.message, ")")); - return null; - } -}; -/** - * Creates a client with interactive authentication. - * - * - Will start an OAuth flow and open an authentication page - * - Starts a local server to listen for the oauth callback - * - Resolves with the client after user authentication - * - * @param {object} clientOptions Same as CozyClient::constructor. - * - * @example - * ``` - * import { createClientInteractive } from 'cozy-client/dist/cli' - * await createClientInteractive({ - * uri: 'http://cozy.tools:8080', - * scope: ['io.cozy.bills'], - * oauth: { - * softwareID: 'my-cli-application-using-bills' - * } - * }) - * ``` - * - * @returns {Promise<CozyClient>} - A client that is ready with a token - */ + }, { + key: "validate", + value: function () { + var _validate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(document) { + var errors, schema, n, ret; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + errors = {}; + schema = this.byDoctype[document._type]; + if (schema) { + _context.next = 4; + break; + } -var createClientInteractive = function createClientInteractive(clientOptions, serverOpts) { - global.fetch = nodeFetch; - global.btoa = btoa; - var serverOptions = (0, _merge.default)(DEFAULT_SERVER_OPTIONS, serverOpts); - var createClientFS = serverOptions.fs || _fs.default; - var mergedClientOptions = (0, _merge.default)({ - oauth: { - clientName: 'cli-client', - redirectURI: "http://localhost:".concat(serverOptions.port).concat(serverOptions.route) - } - }, clientOptions); + return _context.abrupt("return", true); - if (!clientOptions.scope) { - throw new Error('scope must be provided in client options'); - } + case 4: + if (schema.attributes) { + _context.next = 6; + break; + } - var getSavedCredentials = serverOptions.getSavedCredentials; - var savedCredentialsFilename = getSavedCredentials(mergedClientOptions); - var savedCredentials = readJSON(createClientFS, savedCredentialsFilename); - log('debug', "Starting OAuth flow"); - return new Promise( /*#__PURE__*/function () { - var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(resolve, reject) { - var client; - return _regenerator.default.wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - client = new _CozyClient.default(mergedClientOptions); + return _context.abrupt("return", true); - if (!savedCredentials) { + case 6: + _context.t0 = _regenerator.default.keys(schema.attributes); + + case 7: + if ((_context.t1 = _context.t0()).done) { + _context.next = 15; + break; + } + + n = _context.t1.value; + _context.next = 11; + return this.validateAttribute(document, n, schema.attributes[n]); + + case 11: + ret = _context.sent; + if (ret !== true) errors[n] = ret; _context.next = 7; break; - } - log('debug', "Using saved credentials in ".concat(savedCredentialsFilename)); - client.stackClient.setToken(savedCredentials.token); - client.stackClient.setOAuthOptions(savedCredentials.oauthOptions); - resolve(client); - return _context.abrupt("return"); + case 15: + if (!(Object.keys(errors).length === 0)) { + _context.next = 17; + break; + } - case 7: - _context.next = 9; - return client.startOAuthFlow(mkServerFlowCallback(serverOptions)); + return _context.abrupt("return", true); - case 9: - resolve(client); - log('debug', "Saving credentials to ".concat(savedCredentialsFilename)); - writeJSON(createClientFS, savedCredentialsFilename, { - oauthOptions: client.stackClient.oauthOptions, - token: client.stackClient.token - }); + case 17: + return _context.abrupt("return", errors); - case 12: - case "end": - return _context.stop(); + case 18: + case "end": + return _context.stop(); + } } - } - }, _callee); - })); + }, _callee, this); + })); - return function (_x, _x2) { - return _ref.apply(this, arguments); - }; - }()); -}; + function validate(_x) { + return _validate.apply(this, arguments); + } -exports.createClientInteractive = createClientInteractive; + return validate; + }() + }, { + key: "validateAttribute", + value: function () { + var _validateAttribute = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(document, attrName, attrProps) { + var ret; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (!(attrProps.unique && this.client)) { + _context2.next = 6; + break; + } -var main = /*#__PURE__*/function () { - var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { - var client; - return _regenerator.default.wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _context2.next = 2; - return createClientInteractive({ - scope: ['io.cozy.files'], - uri: 'http://cozy.tools:8080', - oauth: { - softwareID: 'io.cozy.client.cli' - } - }); + _context2.next = 3; + return this.client.collection(document._type).checkUniquenessOf(attrName, document[attrName]); - case 2: - client = _context2.sent; - console.log(client.toJSON()); + case 3: + ret = _context2.sent; - case 4: - case "end": - return _context2.stop(); - } + if (!(ret !== true)) { + _context2.next = 6; + break; + } + + return _context2.abrupt("return", 'must be unique'); + + case 6: + return _context2.abrupt("return", true); + + case 7: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function validateAttribute(_x2, _x3, _x4) { + return _validateAttribute.apply(this, arguments); } - }, _callee2); - })); - return function main() { - return _ref2.apply(this, arguments); - }; -}(); + return validateAttribute; + }() + }]); + return Schema; +}(); + +var _default = Schema; +exports["default"] = _default; + +/***/ }), +/* 791 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseKeys = __webpack_require__(454), + getTag = __webpack_require__(459), + isArrayLike = __webpack_require__(458), + isString = __webpack_require__(54), + stringSize = __webpack_require__(792); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if (isArrayLike(collection)) { + return isString(collection) ? stringSize(collection) : collection.length; + } + var tag = getTag(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return baseKeys(collection).length; +} + +module.exports = size; -if (__webpack_require__.c[__webpack_require__.s] === module) { - main().catch(function (e) { - console.error(e); - process.exit(1); - }); -} /***/ }), -/* 808 */ +/* 792 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -"use strict"; - -const {promisify} = __webpack_require__(64); -const path = __webpack_require__(142); -const childProcess = __webpack_require__(809); -const fs = __webpack_require__(149); -const isWsl = __webpack_require__(810); -const isDocker = __webpack_require__(811); - -const pAccess = promisify(fs.access); -const pReadFile = promisify(fs.readFile); - -// Path to included `xdg-open`. -const localXdgOpenPath = path.join(__dirname, 'xdg-open'); +var asciiSize = __webpack_require__(793), + hasUnicode = __webpack_require__(778), + unicodeSize = __webpack_require__(794); /** -Get the mount point for fixed drives in WSL. + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return hasUnicode(string) + ? unicodeSize(string) + : asciiSize(string); +} -@inner -@returns {string} The mount point. -*/ -const getWslDrivesMountPoint = (() => { - // Default value for "root" param - // according to https://docs.microsoft.com/en-us/windows/wsl/wsl-config - const defaultMountPoint = '/mnt/'; +module.exports = stringSize; - let mountPoint; - return async function () { - if (mountPoint) { - // Return memoized mount point value - return mountPoint; - } +/***/ }), +/* 793 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - const configFilePath = '/etc/wsl.conf'; +var baseProperty = __webpack_require__(473); - let isConfigFileExists = false; - try { - await pAccess(configFilePath, fs.constants.F_OK); - isConfigFileExists = true; - } catch (_) {} +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = baseProperty('length'); - if (!isConfigFileExists) { - return defaultMountPoint; - } +module.exports = asciiSize; - const configContent = await pReadFile(configFilePath, {encoding: 'utf8'}); - const configMountPoint = /root\s*=\s*(.*)/g.exec(configContent); - if (!configMountPoint) { - return defaultMountPoint; - } +/***/ }), +/* 794 */ +/***/ ((module) => { - mountPoint = configMountPoint[1].trim(); - mountPoint = mountPoint.endsWith('/') ? mountPoint : mountPoint + '/'; +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; - return mountPoint; - }; -})(); +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + rsAstralRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ = '\\u200d'; -module.exports = async (target, options) => { - if (typeof target !== 'string') { - throw new TypeError('Expected a `target`'); - } +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - options = { - wait: false, - background: false, - allowNonzeroExitCode: false, - ...options - }; +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - let command; - let {app} = options; - let appArguments = []; - const cliArguments = []; - const childProcessOptions = {}; +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} - if (Array.isArray(app)) { - appArguments = app.slice(1); - app = app[0]; - } +module.exports = unicodeSize; - if (process.platform === 'darwin') { - command = 'open'; - if (options.wait) { - cliArguments.push('--wait-apps'); - } +/***/ }), +/* 795 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (options.background) { - cliArguments.push('--background'); - } +var arrayMap = __webpack_require__(410), + baseIntersection = __webpack_require__(740), + baseIteratee = __webpack_require__(413), + baseRest = __webpack_require__(556), + castArrayLikeObject = __webpack_require__(741), + last = __webpack_require__(627); - if (app) { - cliArguments.push('-a', app); - } - } else if (process.platform === 'win32' || (isWsl && !isDocker())) { - const mountPoint = await getWslDrivesMountPoint(); +/** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ +var intersectionBy = baseRest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); - command = isWsl ? - `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` : - `${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`; + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, baseIteratee(iteratee, 2)) + : []; +}); - cliArguments.push( - '-NoProfile', - '-NonInteractive', - '–ExecutionPolicy', - 'Bypass', - '-EncodedCommand' - ); +module.exports = intersectionBy; - if (!isWsl) { - childProcessOptions.windowsVerbatimArguments = true; - } - const encodedArguments = ['Start']; +/***/ }), +/* 796 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - if (options.wait) { - encodedArguments.push('-Wait'); - } +"use strict"; - if (app) { - // Double quote with double quotes to ensure the inner quotes are passed through. - // Inner quotes are delimited for PowerShell interpretation with backticks. - encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList'); - appArguments.unshift(target); - } else { - encodedArguments.push(`"${target}"`); - } - if (appArguments.length > 0) { - appArguments = appArguments.map(arg => `"\`"${arg}\`""`); - encodedArguments.push(appArguments.join(',')); - } +var _interopRequireDefault = __webpack_require__(524); - // Using Base64-encoded command, accepted by PowerShell, to allow special characters. - target = Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64'); - } else { - if (app) { - command = app; - } else { - // When bundled by Webpack, there's no actual package file path and no local `xdg-open`. - const isBundled = false || __dirname === '/'; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - // Check if local `xdg-open` exists and is executable. - let exeLocalXdgOpen = false; - try { - await pAccess(localXdgOpenPath, fs.constants.X_OK); - exeLocalXdgOpen = true; - } catch (_) {} +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - const useSystemXdgOpen = process.versions.electron || - process.platform === 'android' || isBundled || !exeLocalXdgOpen; - command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath; - } +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); - if (appArguments.length > 0) { - cliArguments.push(...appArguments); - } +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); - if (!options.wait) { - // `xdg-open` will block the process unless stdio is ignored - // and it's detached from the parent even if it's unref'd. - childProcessOptions.stdio = 'ignore'; - childProcessOptions.detached = true; - } - } +var _get = _interopRequireDefault(__webpack_require__(370)); - cliArguments.push(target); +var _store = __webpack_require__(705); - if (process.platform === 'darwin' && appArguments.length > 0) { - cliArguments.push('--args', ...appArguments); - } +/** + * ObservableQueries are the glue between the store and observers + * of the store. They have the responsibility to hydrate the documents + * before passing them to the React component. + */ +var hasOwn = Object.prototype.hasOwnProperty; - const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions); +var ObservableQuery = /*#__PURE__*/function () { + function ObservableQuery(queryId, definition, client, options) { + var _this = this; - if (options.wait) { - return new Promise((resolve, reject) => { - subprocess.once('error', reject); + (0, _classCallCheck2.default)(this, ObservableQuery); + (0, _defineProperty2.default)(this, "handleStoreChange", function () { + var nextResult = _this.currentRawResult(); - subprocess.once('close', exitCode => { - if (options.allowNonzeroExitCode && exitCode > 0) { - reject(new Error(`Exited with code ${exitCode}`)); - return; - } + if (!shallowEqual(nextResult, _this.lastResult)) { + _this.lastResult = nextResult; - resolve(subprocess); - }); - }); - } + _this.notifyObservers(); + } + }); - subprocess.unref(); + if (!queryId || !definition || !client) { + throw new Error('ObservableQuery takes 3 arguments: queryId, definition and client'); + } - return subprocess; -}; + this.queryId = queryId; + this.definition = definition; + this.client = client; + this.observers = {}; + this.idCounter = 1; + this.lastResult = this.currentRawResult(); + this.options = options; + } + (0, _createClass2.default)(ObservableQuery, [{ + key: "currentResult", -/***/ }), -/* 809 */ -/***/ ((module) => { + /** + * Returns the query from the store with hydrated documents. + * + * @typedef {object} HydratedQueryState + * + * @returns {HydratedQueryState} + */ + value: function currentResult() { + return this.client.getQueryFromState(this.queryId, { + hydrated: (0, _get.default)(this.options, 'hydrated', true), + singleDocData: true + }); + } + }, { + key: "fetch", + value: function fetch() { + return this.client.query(this.definition, { + as: this.queryId + }); + } + /** + * Generates and executes a query that is offsetted by the number of documents + * we have in the store. + */ -"use strict"; -module.exports = require("child_process"); + }, { + key: "fetchMore", + value: function fetchMore() { + var rawResult = this.currentRawResult(); + return rawResult.bookmark ? this.client.query(this.definition.offsetBookmark(rawResult.bookmark), { + as: this.queryId + }) : this.client.query(this.definition.offset(rawResult.data.length), { + as: this.queryId + }); + } + }, { + key: "currentRawResult", + value: function currentRawResult() { + return (0, _store.getRawQueryFromState)(this.getStore().getState(), this.queryId); + } + }, { + key: "notifyObservers", + value: function notifyObservers() { + var _this2 = this; -/***/ }), -/* 810 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + Object.keys(this.observers).forEach(function (id) { + return _this2.observers[id](); + }); + } + }, { + key: "subscribeToStore", + value: function subscribeToStore() { + if (this._unsubscribeStore) { + throw new Error('ObservableQuery instance is already subscribed to store.'); + } -"use strict"; + this._unsubscribeStore = this.getStore().subscribe(this.handleStoreChange); + } + }, { + key: "unsubscribeFromStore", + value: function unsubscribeFromStore() { + if (!this._unsubscribeStore) { + throw new Error('ObservableQuery instance is not subscribed to store'); + } -const os = __webpack_require__(252); -const fs = __webpack_require__(149); -const isDocker = __webpack_require__(811); + this._unsubscribeStore(); + } + }, { + key: "subscribe", + value: function subscribe(callback) { + var _this3 = this; -const isWsl = () => { - if (process.platform !== 'linux') { - return false; - } + var callbackId = this.idCounter; + this.idCounter++; + this.observers[callbackId] = callback; - if (os.release().toLowerCase().includes('microsoft')) { - if (isDocker()) { - return false; - } + if (Object.keys(this.observers).length === 1) { + this.subscribeToStore(); + } - return true; - } + return function () { + return _this3.unsubscribe(callbackId); + }; + } + }, { + key: "unsubscribe", + value: function unsubscribe(callbackId) { + if (!this.observers[callbackId]) { + throw new Error("Cannot unsubscribe unknown callbackId ".concat(callbackId)); + } - try { - return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ? - !isDocker() : false; - } catch (_) { - return false; - } -}; + delete this.observers[callbackId]; -if (process.env.__IS_WSL_TEST__) { - module.exports = isWsl; -} else { - module.exports = isWsl(); -} + if (Object.keys(this.observers).length === 0) { + this.unsubscribeFromStore(); + this._unsubscribeStore = null; + } + } + }, { + key: "getStore", + value: function getStore() { + return this.client.store; + } + }]); + return ObservableQuery; +}(); +exports["default"] = ObservableQuery; -/***/ }), -/* 811 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +function is(x, y) { + if (x === y) { + return x !== 0 || y !== 0 || 1 / x === 1 / y; + } else { + return x !== x && y !== y; + } +} -"use strict"; +function shallowEqual(objA, objB) { + if (is(objA, objB)) return true; -const fs = __webpack_require__(149); + if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { + return false; + } -let isDocker; + var keysA = Object.keys(objA); + var keysB = Object.keys(objB); + if (keysA.length !== keysB.length) return false; -function hasDockerEnv() { - try { - fs.statSync('/.dockerenv'); - return true; - } catch (_) { - return false; - } -} + for (var i = 0; i < keysA.length; i++) { + if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { + return false; + } + } -function hasDockerCGroup() { - try { - return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker'); - } catch (_) { - return false; - } + return true; } -module.exports = () => { - if (isDocker === undefined) { - isDocker = hasDockerEnv() || hasDockerCGroup(); - } - - return isDocker; -}; - - /***/ }), -/* 812 */ -/***/ ((module) => { +/* 797 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -module.exports = enableDestroy; +"use strict"; -function enableDestroy(server) { - var connections = {} - server.on('connection', function(conn) { - var key = conn.remoteAddress + ':' + conn.remotePort; - connections[key] = conn; - conn.on('close', function() { - delete connections[key]; - }); - }); +var _interopRequireDefault = __webpack_require__(524); - server.destroy = function(cb) { - server.close(cb); - for (var key in connections) - connections[key].destroy(); - }; -} +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.CozyClient = void 0; +var _inherits2 = _interopRequireDefault(__webpack_require__(603)); -/***/ }), -/* 813 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(605)); -const { filterLevel, filterSecrets } = __webpack_require__(814) -const Secret = __webpack_require__(815) -const { LOG_LEVEL } = process.env -let level = LOG_LEVEL || 'debug' -const format = __webpack_require__(816) -const filters = [filterLevel, filterSecrets] +var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(607)); -const filterOut = function() { - for (const filter of filters) { - if (filter.apply(null, arguments) === false) { - return true - } - } - return false -} +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -/** - * Use it to log messages in your konnector. Typical types are - * - * - `debug` - * - `warning` - * - `info` - * - `error` - * - `ok` - * - * - * @example - * - * They will be colored in development mode. In production mode, those logs are formatted in JSON to be interpreted by the stack and possibly sent to the client. `error` will stop the konnector. - * - * ```js - * logger = log('my-namespace') - * logger('debug', '365 bills') - * // my-namespace : debug : 365 bills - * logger('info', 'Page fetched') - * // my-namespace : info : Page fetched - * ``` - * @param {string} type - * @param {string} message - * @param {string} label - * @param {string} namespace - */ -function log(type, message, label, namespace) { - if (filterOut(level, type, message, label, namespace)) { - return - } - // eslint-disable-next-line no-console - console.log(format(type, message, label, namespace)) -} +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } -log.addFilter = function(filter) { - return filters.push(filter) -} +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } -log.setLevel = function(lvl) { - level = lvl -} +var SnapshotObject = function SnapshotObject(attrs) { + (0, _classCallCheck2.default)(this, SnapshotObject); + Object.assign(this, attrs); +}; -// Short-hands -const methods = ['debug', 'info', 'warn', 'error', 'ok', 'critical'] -methods.forEach(level => { - log[level] = function(message, label, namespace) { - return log(level, message, label, namespace) - } -}) +var CozyClient = /*#__PURE__*/function (_SnapshotObject) { + (0, _inherits2.default)(CozyClient, _SnapshotObject); -module.exports = log + var _super = _createSuper(CozyClient); -log.setNoRetry = obj => { - if (obj) obj.no_retry = true - else obj = { no_retry: true } - return obj.no_retry -} -log.Secret = Secret -log.namespace = function(namespace) { - return function(type, message, label, ns = namespace) { - log(type, message, label, ns) + function CozyClient() { + (0, _classCallCheck2.default)(this, CozyClient); + return _super.apply(this, arguments); } -} + return CozyClient; +}(SnapshotObject); + +exports.CozyClient = CozyClient; /***/ }), -/* 814 */ +/* 798 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const levels = { - secret: 0, - debug: 10, - info: 20, - warn: 30, - error: 40, - ok: 50, - critical: 50 -} +var json = typeof JSON !== 'undefined' ? JSON : __webpack_require__(799); -const Secret = __webpack_require__(815) +module.exports = function (obj, opts) { + if (!opts) opts = {}; + if (typeof opts === 'function') opts = { cmp: opts }; + var space = opts.space || ''; + if (typeof space === 'number') space = Array(space+1).join(' '); + var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false; + var replacer = opts.replacer || function(key, value) { return value; }; -const filterSecrets = function(level, type, message) { - if (type !== 'secret' && message instanceof Secret) { - throw new Error('You should log a secret with log.secret') - } -} + var cmp = opts.cmp && (function (f) { + return function (node) { + return function (a, b) { + var aobj = { key: a, value: node[a] }; + var bobj = { key: b, value: node[b] }; + return f(aobj, bobj); + }; + }; + })(opts.cmp); -const filterLevel = function(level, type) { - return levels[type] >= levels[level] -} + var seen = []; + return (function stringify (parent, key, node, level) { + var indent = space ? ('\n' + new Array(level + 1).join(space)) : ''; + var colonSeparator = space ? ': ' : ':'; -module.exports = { - filterSecrets, - filterLevel -} + if (node && node.toJSON && typeof node.toJSON === 'function') { + node = node.toJSON(); + } + node = replacer.call(parent, key, node); -/***/ }), -/* 815 */ -/***/ ((module) => { + if (node === undefined) { + return; + } + if (typeof node !== 'object' || node === null) { + return json.stringify(node); + } + if (isArray(node)) { + var out = []; + for (var i = 0; i < node.length; i++) { + var item = stringify(node, i, node[i], level+1) || json.stringify(null); + out.push(indent + space + item); + } + return '[' + out.join(',') + indent + ']'; + } + else { + if (seen.indexOf(node) !== -1) { + if (cycles) return json.stringify('__cycle__'); + throw new TypeError('Converting circular structure to JSON'); + } + else seen.push(node); -const Secret = function(data) { - Object.assign(this, data) - return this -} + var keys = objectKeys(node).sort(cmp && cmp(node)); + var out = []; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = stringify(node, key, node[key], level+1); -Secret.prototype.toString = function() { - throw new Error('Cannot convert Secret to string') -} + if(!value) continue; -module.exports = Secret + var keyValue = json.stringify(key) + + colonSeparator + + value; + ; + out.push(indent + space + keyValue); + } + seen.splice(seen.indexOf(node), 1); + return '{' + out.join(',') + indent + '}'; + } + })({ '': obj }, '', obj, 0); +}; +var isArray = Array.isArray || function (x) { + return {}.toString.call(x) === '[object Array]'; +}; -/***/ }), -/* 816 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +var objectKeys = Object.keys || function (obj) { + var has = Object.prototype.hasOwnProperty || function () { return true }; + var keys = []; + for (var key in obj) { + if (has.call(obj, key)) keys.push(key); + } + return keys; +}; -const prodFormat = __webpack_require__(817) -const devFormat = __webpack_require__(818) -switch (process.env.NODE_ENV) { - case 'production': - module.exports = prodFormat - break - case 'development': - module.exports = devFormat - break - case 'standalone': - module.exports = devFormat - break - case 'test': - module.exports = devFormat - break - default: - module.exports = prodFormat -} +/***/ }), +/* 799 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +exports.parse = __webpack_require__(800); +exports.stringify = __webpack_require__(801); /***/ }), -/* 817 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/* 800 */ +/***/ ((module) => { -const stringify = __webpack_require__(75) +var at, // The index of the current character + ch, // The current character + escapee = { + '"': '"', + '\\': '\\', + '/': '/', + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: '\t' + }, + text, -const LOG_LENGTH_LIMIT = 64 * 1024 - 1 + error = function (m) { + // Call error when something is wrong. + throw { + name: 'SyntaxError', + message: m, + at: at, + text: text + }; + }, + + next = function (c) { + // If a c parameter is provided, verify that it matches the current character. + if (c && c !== ch) { + error("Expected '" + c + "' instead of '" + ch + "'"); + } + + // Get the next character. When there are no more characters, + // return the empty string. + + ch = text.charAt(at); + at += 1; + return ch; + }, + + number = function () { + // Parse a number value. + var number, + string = ''; + + if (ch === '-') { + string = '-'; + next('-'); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + if (ch === '.') { + string += '.'; + while (next() && ch >= '0' && ch <= '9') { + string += ch; + } + } + if (ch === 'e' || ch === 'E') { + string += ch; + next(); + if (ch === '-' || ch === '+') { + string += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + } + number = +string; + if (!isFinite(number)) { + error("Bad number"); + } else { + return number; + } + }, + + string = function () { + // Parse a string value. + var hex, + i, + string = '', + uffff; + + // When parsing for string values, we must look for " and \ characters. + if (ch === '"') { + while (next()) { + if (ch === '"') { + next(); + return string; + } else if (ch === '\\') { + next(); + if (ch === 'u') { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(next(), 16); + if (!isFinite(hex)) { + break; + } + uffff = uffff * 16 + hex; + } + string += String.fromCharCode(uffff); + } else if (typeof escapee[ch] === 'string') { + string += escapee[ch]; + } else { + break; + } + } else { + string += ch; + } + } + } + error("Bad string"); + }, -function prodFormat(type, message, label, namespace) { - const log = { time: new Date(), type, label, namespace } + white = function () { - if (typeof message === 'object') { - if (message && message.no_retry) { - log.no_retry = message.no_retry - } - if (message && message.message) { - log.message = message.message - } - } else { - log.message = message - } +// Skip whitespace. - // properly display error messages - if (log.message && log.message.stack) { - log.message = log.message.stack - } + while (ch && ch <= ' ') { + next(); + } + }, - // cut the string to avoid a fail in the stack - let result = log - try { - result = stringify(log).substr(0, LOG_LENGTH_LIMIT) - } catch (err) { - // eslint-disable-next-line no-console - console.log(err.message, 'cozy-logger: Failed to convert message to JSON') - } - return result -} + word = function () { -module.exports = prodFormat +// true, false, or null. + + switch (ch) { + case 't': + next('t'); + next('r'); + next('u'); + next('e'); + return true; + case 'f': + next('f'); + next('a'); + next('l'); + next('s'); + next('e'); + return false; + case 'n': + next('n'); + next('u'); + next('l'); + next('l'); + return null; + } + error("Unexpected '" + ch + "'"); + }, + value, // Place holder for the value function. -/***/ }), -/* 818 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + array = function () { -const util = __webpack_require__(64) -const chalk = __webpack_require__(819) +// Parse an array value. -if (util && util.inspect && util.inspect.defaultOptions) { - util.inspect.defaultOptions.maxArrayLength = null - util.inspect.defaultOptions.depth = 2 - util.inspect.defaultOptions.colors = true -} + var array = []; -const type2color = { - debug: 'cyan', - warn: 'yellow', - info: 'blue', - error: 'red', - ok: 'green', - secret: 'red', - critical: 'red' -} + if (ch === '[') { + next('['); + white(); + if (ch === ']') { + next(']'); + return array; // empty array + } + while (ch) { + array.push(value()); + white(); + if (ch === ']') { + next(']'); + return array; + } + next(','); + white(); + } + } + error("Bad array"); + }, -function devFormat(type, message, label, namespace) { - let formatmessage = message + object = function () { - if (typeof formatmessage !== 'string') { - formatmessage = util.inspect(formatmessage) - } +// Parse an object value. - let formatlabel = label ? ` : "${label}" ` : '' - let formatnamespace = namespace ? chalk.magenta(`${namespace}: `) : '' + var key, + object = {}; - let color = type2color[type] - let formattype = color ? chalk[color](type) : type + if (ch === '{') { + next('{'); + white(); + if (ch === '}') { + next('}'); + return object; // empty object + } + while (ch) { + key = string(); + white(); + next(':'); + if (Object.hasOwnProperty.call(object, key)) { + error('Duplicate key "' + key + '"'); + } + object[key] = value(); + white(); + if (ch === '}') { + next('}'); + return object; + } + next(','); + white(); + } + } + error("Bad object"); + }; - return `${formatnamespace}${formattype}${formatlabel} : ${formatmessage}` -} +value = function () { -module.exports = devFormat +// Parse a JSON value. It could be an object, an array, a string, a number, +// or a word. + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } +}; -/***/ }), -/* 819 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +// Return the json_parse function. It will have access to all of the above +// functions and variables. -"use strict"; +module.exports = function (source, reviver) { + var result; + + text = source; + at = 0; + ch = ' '; + result = value(); + white(); + if (ch) { + error("Syntax error"); + } -const escapeStringRegexp = __webpack_require__(349); -const ansiStyles = __webpack_require__(820); -const stdoutColor = (__webpack_require__(825).stdout); + // If there is a reviver function, we recursively walk the new structure, + // passing each name/value pair to the reviver function for possible + // transformation, starting with a temporary root object that holds the result + // in an empty key. If there is not a reviver function, we simply return the + // result. -const template = __webpack_require__(827); + return typeof reviver === 'function' ? (function walk(holder, key) { + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + }({'': result}, '')) : result; +}; -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; +/***/ }), +/* 801 */ +/***/ ((module) => { -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); +var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; -const styles = Object.create(null); +function quote(string) { + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe escape + // sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; +} -function applyOptions(obj, options) { - options = options || {}; +function str(key, holder) { + // Produce a string from holder[key]. + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + + // If the value has a toJSON method, call it to obtain a replacement value. + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + + // If we were called with a replacer function, then call the replacer to + // obtain a replacement value. + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + + // What happens next depends on the value's type. + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + // JSON numbers must be finite. Encode non-finite numbers as null. + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + // If the value is a boolean or null, convert it to a string. Note: + // typeof null does not produce 'null'. The case is included here in + // the remote chance that this gets fixed someday. + return String(value); + + case 'object': + if (!value) return 'null'; + gap += indent; + partial = []; + + // Array.isArray + if (Object.prototype.toString.apply(value) === '[object Array]') { + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + + // Join all of the elements together, separated with commas, and + // wrap them in brackets. + v = partial.length === 0 ? '[]' : gap ? + '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + + // If the replacer is an array, use it to select the members to be + // stringified. + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + else { + // Otherwise, iterate through all of the keys in the object. + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + + // Join all of the member texts together, separated with commas, + // and wrap them in braces. - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; + v = partial.length === 0 ? '{}' : gap ? + '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : + '{' + partial.join(',') + '}'; + gap = mind; + return v; + } } -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); +module.exports = function (value, replacer, space) { + var i; + gap = ''; + indent = ''; + + // If the space parameter is a number, make an indent string containing that + // many spaces. + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + } + // If the space parameter is a string, it will be used as the indent string. + else if (typeof space === 'string') { + indent = space; + } - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; + // If there is a replacer, it must be a function or an array. + // Otherwise, throw an error. + rep = replacer; + if (replacer && typeof replacer !== 'function' + && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + + // Make a fake root object containing our value under the key of ''. + // Return the result of stringifying the value. + return str('', {'': value}); +}; - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - chalk.template.constructor = Chalk; +/***/ }), +/* 802 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - return chalk.template; - } +"use strict"; - applyOptions(this, options); -} -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; -} +var _interopRequireDefault = __webpack_require__(524); -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - styles[key] = { - get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; -} +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } -}; +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } +/** + * Caches promises while they are pending + * Serves to dedupe equal queries requested at the same time + */ +var PromiseCache = /*#__PURE__*/function () { + function PromiseCache() { + (0, _classCallCheck2.default)(this, PromiseCache); - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} + /** + * Holds pending promises + * + * @type {Object.<string, Promise>} + */ + this.pending = {}; + } + /** + * Tries to find a pending promise corresponding to the result of keyFunc + * - If not found, promiseFunc is executed and the resulting promise is stored while it's pending + * - If found, it is immediately returned + * + * @template T + * @param {function(): Promise<T>} promiseFunc - Not executed only if an "equal" promise is already pending. + * @param {function(): string} keyFunc - Returns a key to find in cache to find a pending promise. + * @returns {Promise<T>} + */ -const proto = Object.defineProperties(() => {}, styles); -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; + (0, _createClass2.default)(PromiseCache, [{ + key: "exec", + value: function () { + var _exec = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(promiseFunc, keyFunc) { + var key, already, prom, response; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + key = keyFunc(); + already = this.pending[key]; - builder._styles = _styles; - builder._empty = _empty; + if (already) { + prom = already; + } else { + prom = promiseFunc(); + this.pending[key] = prom; + } - const self = this; + _context.prev = 3; + _context.next = 6; + return prom; - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); + case 6: + response = _context.sent; + return _context.abrupt("return", response); - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); + case 8: + _context.prev = 8; + this.pending[key] = null; + return _context.finish(8); - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; + case 11: + case "end": + return _context.stop(); + } + } + }, _callee, this, [[3,, 8, 11]]); + })); - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto + function exec(_x, _x2) { + return _exec.apply(this, arguments); + } - return builder; -} + return exec; + }() + /** + * + * @param {function(): string} keyFunc - Returns a key to find in cache to find a pending promise. + * @returns {Promise | null} + */ -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); + }, { + key: "get", + value: function get(keyFunc) { + var key = keyFunc(); + var already = this.pending[key]; + if (already) return already; + return null; + } + }]); + return PromiseCache; +}(); - if (argsLen === 0) { - return ''; - } +var _default = PromiseCache; +exports["default"] = _default; - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } +/***/ }), +/* 803 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } +"use strict"; - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; +var _interopRequireDefault = __webpack_require__(524); - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.certifyFlagship = void 0; - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - return str; -} +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } +var _CozyClient = _interopRequireDefault(__webpack_require__(525)); - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; +var _logger = _interopRequireDefault(__webpack_require__(715)); - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); - } +var _storeAttestation = __webpack_require__(804); - return template(chalk, parts.join('')); -} +/** + * Request a challenge from the Stack that can be used to request the app attestation from the app store + * + * @param {CozyClient} client - the CozyClient instance + * @returns {Promise<string>} - the Nonce string returned by the stack + */ +var getStackChallenge = /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client) { + var stackClient, result; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.prev = 0; + stackClient = client.getStackClient(); + _context.next = 4; + return stackClient.fetchJSON('POST', "/auth/clients/".concat(stackClient.oauthOptions.clientID, "/challenge"), null, { + headers: { + Authorization: stackClient.registrationAccessTokenToAuthHeader() + } + }); -Object.defineProperties(Chalk.prototype, styles); + case 4: + result = _context.sent; + return _context.abrupt("return", result.nonce); -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports["default"] = module.exports; // For TypeScript + case 8: + _context.prev = 8; + _context.t0 = _context["catch"](0); + throw new Error('[FLAGSHIP_CERTIFICATION] Something went wrong while requesting a challenge from CozyStack:\n' + _context.t0.message); + case 11: + case "end": + return _context.stop(); + } + } + }, _callee, null, [[0, 8]]); + })); -/***/ }), -/* 820 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + return function getStackChallenge(_x) { + return _ref.apply(this, arguments); + }; +}(); +/** + * Give the app attestation to the Stack + * + * @param {AttestationResult} appAttestation - the app attestation that was returned by the app store + * @param {string} nonce - the Nonce string retrieved from the stack + * @param {CozyClient} client - the CozyClient instance + */ -"use strict"; -/* module decorator */ module = __webpack_require__.nmd(module); -const colorConvert = __webpack_require__(821); +var giveAppAttestationToStack = /*#__PURE__*/function () { + var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(appAttestation, nonce, client) { + var platform, attestation, keyId, stackClient; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.prev = 0; + platform = appAttestation.platform, attestation = appAttestation.attestation, keyId = appAttestation.keyId; + stackClient = client.getStackClient(); + _context2.next = 5; + return stackClient.fetchJSON('POST', "/auth/clients/".concat(stackClient.oauthOptions.clientID, "/attestation"), { + platform: platform, + attestation: attestation, + challenge: nonce, + keyId: keyId + }, { + headers: { + Authorization: stackClient.registrationAccessTokenToAuthHeader() + } + }); + + case 5: + _context2.next = 10; + break; -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${code + offset}m`; -}; + case 7: + _context2.prev = 7; + _context2.t0 = _context2["catch"](0); + throw new Error('[FLAGSHIP_CERTIFICATION] Something went wrong while giving attestation to CozyStack:\n' + _context2.t0.message); -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};5;${code}m`; -}; + case 10: + case "end": + return _context2.stop(); + } + } + }, _callee2, null, [[0, 7]]); + })); -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; + return function giveAppAttestationToStack(_x2, _x3, _x4) { + return _ref2.apply(this, arguments); + }; +}(); +/** + * Verify app's identity and integrity so the Stack can trust it + * Verification is done on Stack side by using information from the app's store (Google Play or Apple AppStore) + * + * @param {CertificationConfig} certificationConfig - the required configuration to access the stores API + * @param {CozyClient} client - the CozyClient instance + */ -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], - // Bright color - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], +var certifyFlagship = /*#__PURE__*/function () { + var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(certificationConfig, client) { + var stackChallengeNonce, appAttestation; + return _regenerator.default.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (certificationConfig) { + _context3.next = 2; + break; + } - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; + throw new Error('[FLAGSHIP_CERTIFICATION] Certification configuration is not set'); - // Fix humans - styles.color.grey = styles.color.gray; + case 2: + _context3.prev = 2; + _context3.next = 5; + return getStackChallenge(client); - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; + case 5: + stackChallengeNonce = _context3.sent; + _context3.next = 8; + return (0, _storeAttestation.getAppAttestationFromStore)(stackChallengeNonce, certificationConfig); - for (const styleName of Object.keys(group)) { - const style = group[styleName]; + case 8: + appAttestation = _context3.sent; + _context3.next = 11; + return giveAppAttestationToStack(appAttestation, stackChallengeNonce, client); - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; + case 11: + _context3.next = 17; + break; - group[styleName] = styles[styleName]; + case 13: + _context3.prev = 13; + _context3.t0 = _context3["catch"](2); - codes.set(style[0], style[1]); - } + _logger.default.warn('[FLAGSHIP_CERTIFICATION] Certification failed but the cozy-stack will continue with 2FA certification'); - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); + _logger.default.warn(_context3.t0.message); - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - } + case 17: + case "end": + return _context3.stop(); + } + } + }, _callee3, null, [[2, 13]]); + })); - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; + return function certifyFlagship(_x5, _x6) { + return _ref3.apply(this, arguments); + }; +}(); - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; +exports.certifyFlagship = certifyFlagship; - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; +/***/ }), +/* 804 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; +"use strict"; - for (let key of Object.keys(colorConvert)) { - if (typeof colorConvert[key] !== 'object') { - continue; - } - const suite = colorConvert[key]; +var _interopRequireDefault = __webpack_require__(524); - if (key === 'ansi16') { - key = 'ansi'; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getAppAttestationFromStore = void 0; - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } - } +/** + * Retrieve the app's attestation from the app's store + * /!\ This is a mock implementation that should never be called + * + * @param {string} nonce - the Nonce string retrieved from the stack + * @param {CertificationConfig} certificationConfig - Configuration to access the stores certification API + * @returns {Promise<AttestationResult>} the app's attestation + */ +var validateAppMock = /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(nonce, certificationConfig) { + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + throw new Error("getAppAttestationFromStore can only be called from a React Native container"); - return styles; -} + case 1: + case "end": + return _context.stop(); + } + } + }, _callee); + })); -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); + return function validateAppMock(_x, _x2) { + return _ref.apply(this, arguments); + }; +}(); +var getAppAttestationFromStore = validateAppMock; +exports.getAppAttestationFromStore = getAppAttestationFromStore; /***/ }), -/* 821 */ +/* 805 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var conversions = __webpack_require__(822); -var route = __webpack_require__(824); - -var convert = {}; +var createFlow = __webpack_require__(806); -var models = Object.keys(conversions); +/** + * Creates a function that returns the result of invoking the given functions + * with the `this` binding of the created function, where each successive + * invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Util + * @param {...(Function|Function[])} [funcs] The functions to invoke. + * @returns {Function} Returns the new composite function. + * @see _.flowRight + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow([_.add, square]); + * addSquare(1, 2); + * // => 9 + */ +var flow = createFlow(); -function wrapRaw(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } +module.exports = flow; - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - return fn(args); - }; +/***/ }), +/* 806 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } +var LodashWrapper = __webpack_require__(807), + flatRest = __webpack_require__(632), + getData = __webpack_require__(809), + getFuncName = __webpack_require__(811), + isArray = __webpack_require__(55), + isLaziable = __webpack_require__(813); - return wrappedFn; -} +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; -function wrapRounded(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } +/** Used to compose bitmasks for function metadata. */ +var WRAP_CURRY_FLAG = 8, + WRAP_PARTIAL_FLAG = 32, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256; - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } +/** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ +function createFlow(fromRight) { + return flatRest(function(funcs) { + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; - var result = fn(args); + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? index : length; + while (++index < length) { + func = funcs[index]; - // we're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (var len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; - return result; - }; + if (data && isLaziable(data[0]) && + data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) + ? wrapper[funcName]() + : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } + if (wrapper && args.length == 1 && isArray(value)) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; - return wrappedFn; + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }); } -models.forEach(function (fromModel) { - convert[fromModel] = {}; - - Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); - Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); - - var routes = route(fromModel); - var routeModels = Object.keys(routes); - - routeModels.forEach(function (toModel) { - var fn = routes[toModel]; - - convert[fromModel][toModel] = wrapRounded(fn); - convert[fromModel][toModel].raw = wrapRaw(fn); - }); -}); - -module.exports = convert; +module.exports = createFlow; /***/ }), -/* 822 */ +/* 807 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/* MIT license */ -var cssKeywords = __webpack_require__(823); - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) +var baseCreate = __webpack_require__(597), + baseLodash = __webpack_require__(808); -var reverseKeywords = {}; -for (var key in cssKeywords) { - if (cssKeywords.hasOwnProperty(key)) { - reverseKeywords[cssKeywords[key]] = key; - } +/** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable explicit method chain sequences. + */ +function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; } -var convert = module.exports = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; +LodashWrapper.prototype = baseCreate(baseLodash.prototype); +LodashWrapper.prototype.constructor = LodashWrapper; -// hide .channels and .labels properties -for (var model in convert) { - if (convert.hasOwnProperty(model)) { - if (!('channels' in convert[model])) { - throw new Error('missing channels property: ' + model); - } +module.exports = LodashWrapper; - if (!('labels' in convert[model])) { - throw new Error('missing channel labels property: ' + model); - } - if (convert[model].labels.length !== convert[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } +/***/ }), +/* 808 */ +/***/ ((module) => { - var channels = convert[model].channels; - var labels = convert[model].labels; - delete convert[model].channels; - delete convert[model].labels; - Object.defineProperty(convert[model], 'channels', {value: channels}); - Object.defineProperty(convert[model], 'labels', {value: labels}); - } +/** + * The function whose prototype chain sequence wrappers inherit from. + * + * @private + */ +function baseLodash() { + // No operation performed. } -convert.rgb.hsl = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var delta = max - min; - var h; - var s; - var l; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); +module.exports = baseLodash; - if (h < 0) { - h += 360; - } - l = (min + max) / 2; +/***/ }), +/* 809 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } +var metaMap = __webpack_require__(810), + noop = __webpack_require__(483); - return [h, s * 100, l * 100]; +/** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ +var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); }; -convert.rgb.hsv = function (rgb) { - var rdif; - var gdif; - var bdif; - var h; - var s; +module.exports = getData; - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var v = Math.max(r, g, b); - var diff = v - Math.min(r, g, b); - var diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; - if (diff === 0) { - h = s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); +/***/ }), +/* 810 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - } +var WeakMap = __webpack_require__(463); - return [ - h * 360, - s * 100, - v * 100 - ]; -}; +/** Used to store function metadata. */ +var metaMap = WeakMap && new WeakMap; -convert.rgb.hwb = function (rgb) { - var r = rgb[0]; - var g = rgb[1]; - var b = rgb[2]; - var h = convert.rgb.hsl(rgb)[0]; - var w = 1 / 255 * Math.min(r, Math.min(g, b)); +module.exports = metaMap; - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - return [h, w * 100, b * 100]; -}; +/***/ }), +/* 811 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -convert.rgb.cmyk = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var c; - var m; - var y; - var k; +var realNames = __webpack_require__(812); - k = Math.min(1 - r, 1 - g, 1 - b); - c = (1 - r - k) / (1 - k) || 0; - m = (1 - g - k) / (1 - k) || 0; - y = (1 - b - k) / (1 - k) || 0; +/** Used for built-in method references. */ +var objectProto = Object.prototype; - return [c * 100, m * 100, y * 100, k * 100]; -}; +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; /** - * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - * */ -function comparativeDistance(x, y) { - return ( - Math.pow(x[0] - y[0], 2) + - Math.pow(x[1] - y[1], 2) + - Math.pow(x[2] - y[2], 2) - ); -} - -convert.rgb.keyword = function (rgb) { - var reversed = reverseKeywords[rgb]; - if (reversed) { - return reversed; - } + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ +function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; - var currentClosestDistance = Infinity; - var currentClosestKeyword; + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; +} - for (var keyword in cssKeywords) { - if (cssKeywords.hasOwnProperty(keyword)) { - var value = cssKeywords[keyword]; +module.exports = getFuncName; - // Compute comparative distance - var distance = comparativeDistance(rgb, value); - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } - } +/***/ }), +/* 812 */ +/***/ ((module) => { - return currentClosestKeyword; -}; +/** Used to lookup unminified function names. */ +var realNames = {}; -convert.keyword.rgb = function (keyword) { - return cssKeywords[keyword]; -}; +module.exports = realNames; -convert.rgb.xyz = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - // assume sRGB - r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); +/***/ }), +/* 813 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); +var LazyWrapper = __webpack_require__(814), + getData = __webpack_require__(809), + getFuncName = __webpack_require__(811), + lodash = __webpack_require__(815); - return [x * 100, y * 100, z * 100]; -}; +/** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, + * else `false`. + */ +function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; -convert.rgb.lab = function (rgb) { - var xyz = convert.rgb.xyz(rgb); - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; +} - x /= 95.047; - y /= 100; - z /= 108.883; +module.exports = isLaziable; - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); +/***/ }), +/* 814 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return [l, a, b]; -}; +var baseCreate = __webpack_require__(597), + baseLodash = __webpack_require__(808); -convert.hsl.rgb = function (hsl) { - var h = hsl[0] / 360; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var t1; - var t2; - var t3; - var rgb; - var val; +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295; - if (s === 0) { - val = l * 255; - return [val, val, val]; - } +/** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ +function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; +} - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } +// Ensure `LazyWrapper` is an instance of `baseLodash`. +LazyWrapper.prototype = baseCreate(baseLodash.prototype); +LazyWrapper.prototype.constructor = LazyWrapper; - t1 = 2 * l - t2; +module.exports = LazyWrapper; - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } - if (t3 > 1) { - t3--; - } - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } +/***/ }), +/* 815 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - rgb[i] = val * 255; - } +var LazyWrapper = __webpack_require__(814), + LodashWrapper = __webpack_require__(807), + baseLodash = __webpack_require__(808), + isArray = __webpack_require__(55), + isObjectLike = __webpack_require__(53), + wrapperClone = __webpack_require__(816); - return rgb; -}; +/** Used for built-in method references. */ +var objectProto = Object.prototype; -convert.hsl.hsv = function (hsl) { - var h = hsl[0]; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var smin = s; - var lmin = Math.max(l, 0.01); - var sv; - var v; +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - v = (l + s) / 2; - sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); +/** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chain sequences. Methods that operate on and return arrays, collections, + * and functions can be chained together. Methods that retrieve a single value + * or may return a primitive value will automatically end the chain sequence + * and return the unwrapped value. Otherwise, the value must be unwrapped + * with `_#value`. + * + * Explicit chain sequences, which must be unwrapped with `_#value`, may be + * enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. + * Shortcut fusion is an optimization to merge iteratee calls; this avoids + * the creation of intermediate arrays and can greatly reduce the number of + * iteratee executions. Sections of a chain sequence qualify for shortcut + * fusion if the section is applied to an array and iteratees accept only + * one argument. The heuristic for whether a section qualifies for shortcut + * fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, + * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, + * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, + * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, + * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, + * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, + * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, + * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, + * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, + * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, + * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, + * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, + * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, + * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, + * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, + * `zipObject`, `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, + * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, + * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, + * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, + * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, + * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, + * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, + * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, + * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, + * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, + * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, + * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, + * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, + * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, + * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, + * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, + * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, + * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, + * `upperFirst`, `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ +function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); +} - return [h, sv * 100, v * 100]; -}; +// Ensure wrappers are instances of `baseLodash`. +lodash.prototype = baseLodash.prototype; +lodash.prototype.constructor = lodash; -convert.hsv.rgb = function (hsv) { - var h = hsv[0] / 60; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var hi = Math.floor(h) % 6; +module.exports = lodash; - var f = h - Math.floor(h); - var p = 255 * v * (1 - s); - var q = 255 * v * (1 - (s * f)); - var t = 255 * v * (1 - (s * (1 - f))); - v *= 255; - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; +/***/ }), +/* 816 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -convert.hsv.hsl = function (hsv) { - var h = hsv[0]; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var vmin = Math.max(v, 0.01); - var lmin; - var sl; - var l; +var LazyWrapper = __webpack_require__(814), + LodashWrapper = __webpack_require__(807), + copyArray = __webpack_require__(583); - l = (2 - s) * v; - lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; +/** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ +function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; +} - return [h, sl * 100, l * 100]; -}; +module.exports = wrapperClone; -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert.hwb.rgb = function (hwb) { - var h = hwb[0] / 360; - var wh = hwb[1] / 100; - var bl = hwb[2] / 100; - var ratio = wh + bl; - var i; - var v; - var f; - var n; - // wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } +/***/ }), +/* 817 */ +/***/ ((__unused_webpack_module, exports) => { - i = Math.floor(6 * h); - v = 1 - bl; - f = 6 * h - i; +"use strict"; - if ((i & 0x01) !== 0) { - f = 1 - f; - } - n = wh + f * (v - wh); // linear interpolation +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.hasQueryBeenLoaded = exports.isQueryLoading = exports.cancelable = void 0; - var r; - var g; - var b; - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } +/** + * @typedef {Promise} CancelablePromise + * @property {Function} cancel - Cancel the promise + */ - return [r * 255, g * 255, b * 255]; -}; +/** + * Wraps a promise so that it can be canceled + * + * Rejects with canceled: true as soon as cancel is called + * + * @param {Promise} promise - Promise + * @returns {CancelablePromise} - Promise with .cancel method + */ +var cancelable = function cancelable(promise) { + var _reject; -convert.cmyk.rgb = function (cmyk) { - var c = cmyk[0] / 100; - var m = cmyk[1] / 100; - var y = cmyk[2] / 100; - var k = cmyk[3] / 100; - var r; - var g; - var b; + var wrapped = new Promise(function (resolve, reject) { + _reject = reject; + promise.then(resolve); + promise.catch(reject); + }); // @ts-ignore - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); + wrapped.cancel = function () { + _reject({ + canceled: true + }); + }; - return [r * 255, g * 255, b * 255]; + return wrapped; }; -convert.xyz.rgb = function (xyz) { - var x = xyz[0] / 100; - var y = xyz[1] / 100; - var z = xyz[2] / 100; - var r; - var g; - var b; +exports.cancelable = cancelable; - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); +/** + * Returns whether the result of a query (given via queryConnect or Query) + * is loading. + */ +var isQueryLoading = function isQueryLoading(col) { + if (!col) { + console.warn('isQueryLoading called on falsy value.'); // eslint-disable-line no-console - // assume sRGB - r = r > 0.0031308 - ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) - : r * 12.92; + return false; + } - g = g > 0.0031308 - ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) - : g * 12.92; + return col.fetchStatus === 'loading' || col.fetchStatus === 'pending'; +}; +/** + * Returns whether a query has been loaded at least once + */ - b = b > 0.0031308 - ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) - : b * 12.92; - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); +exports.isQueryLoading = isQueryLoading; - return [r * 255, g * 255, b * 255]; +var hasQueryBeenLoaded = function hasQueryBeenLoaded(col) { + return col.lastFetch; }; -convert.xyz.lab = function (xyz) { - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; +exports.hasQueryBeenLoaded = hasQueryBeenLoaded; - x /= 95.047; - y /= 100; - z /= 108.883; +/***/ }), +/* 818 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); +"use strict"; - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - return [l, a, b]; -}; +var _interopRequireDefault = __webpack_require__(524); -convert.lab.xyz = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var x; - var y; - var z; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.sanitizeCategories = sanitizeCategories; +exports.areTermsValid = areTermsValid; +exports.isPartnershipValid = isPartnershipValid; +exports.sanitize = sanitize; - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); - var y2 = Math.pow(y, 3); - var x2 = Math.pow(x, 3); - var z2 = Math.pow(z, 3); - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; +var _types = __webpack_require__(622); - x *= 95.047; - y *= 100; - z *= 108.883; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - return [x, y, z]; -}; +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } -convert.lab.lch = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var hr; - var h; - var c; +var APP_CATEGORIES = ['banking', 'cozy', 'energy', 'health', 'host_provider', 'insurance', 'isp', 'mes_infos', 'online_services', 'others', 'partners', 'press', 'productivity', 'ptnb', 'public_service', 'shopping', 'social', 'telecom', 'transport']; +/** Filters unauthorized categories. Defaults to ['others'] if no suitable category. */ - hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; +function sanitizeCategories(categories) { + if (!categories) return ['others']; + var filteredList = categories.filter(function (c) { + return APP_CATEGORIES.includes(c); + }); + if (!filteredList.length) return ['others']; + return filteredList; +} - if (h < 0) { - h += 360; - } +function areTermsValid(terms) { + return Boolean(terms && terms.id && terms.url && terms.version); +} - c = Math.sqrt(a * a + b * b); +function isPartnershipValid(partnership) { + return Boolean(partnership && partnership.description); +} +/** + * Normalize app manifest, retrocompatibility for old manifests + * + * @param {Manifest} manifest + * @returns {Manifest} + */ - return [l, c, h]; -}; -convert.lch.lab = function (lch) { - var l = lch[0]; - var c = lch[1]; - var h = lch[2]; - var a; - var b; - var hr; +function sanitize(manifest) { + var sanitized = _objectSpread({}, manifest); // Make categories an array and delete category attribute if it exists - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); - return [l, a, b]; -}; + if (!manifest.categories && manifest.category && typeof manifest.category === 'string') { + sanitized.categories = [manifest.category]; + delete sanitized.category; + } -convert.rgb.ansi16 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization + sanitized.categories = sanitizeCategories(sanitized.categories); // manifest name is not an object - value = Math.round(value / 50); + if (typeof manifest.name === 'object') sanitized.name = manifest.name.en; // Fix camelCase from cozy-stack - if (value === 0) { - return 30; - } + if (manifest.available_version) { + sanitized.availableVersion = manifest.available_version; + delete sanitized.available_version; + } // Fix camelCase from cozy-stack - var ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); - if (value === 2) { - ansi += 60; - } + if (manifest.latest_version) { + sanitized.latestVersion = manifest.latestVersion; + delete sanitized.latest_version; + } // Remove invalid terms - return ansi; -}; -convert.hsv.ansi16 = function (args) { - // optimization here; we already know the value and don't need to get - // it converted for us. - return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); -}; + if (sanitized.terms && !areTermsValid(sanitized.terms)) { + delete sanitized.terms; + } // Remove invalid partnership -convert.rgb.ansi256 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - // we use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } + if (sanitized.partnership && !isPartnershipValid(sanitized.partnership)) { + delete sanitized.partnership; + } - if (r > 248) { - return 231; - } + return sanitized; +} - return Math.round(((r - 8) / 247) * 24) + 232; - } +/***/ }), +/* 819 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - var ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); +"use strict"; - return ansi; -}; -convert.ansi16.rgb = function (args) { - var color = args % 10; +var _interopRequireDefault = __webpack_require__(524); - // handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.createMockClient = void 0; - color = color / 10.5 * 255; +var _slicedToArray2 = _interopRequireDefault(__webpack_require__(532)); - return [color, color, color]; - } +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); - var mult = (~~(args > 50) + 1) * 0.5; - var r = ((color & 1) * mult) * 255; - var g = (((color >> 1) & 1) * mult) * 255; - var b = (((color >> 2) & 1) * mult) * 255; +var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(537)); - return [r, g, b]; -}; +var _CozyClient = _interopRequireDefault(__webpack_require__(525)); -convert.ansi256.rgb = function (args) { - // handle greyscale - if (args >= 232) { - var c = (args - 232) * 10 + 8; - return [c, c, c]; - } +var _store = __webpack_require__(705); - args -= 16; +var _cozyStackClient = __webpack_require__(571); - var rem; - var r = Math.floor(args / 36) / 5 * 255; - var g = Math.floor((rem = args % 36) / 6) / 5 * 255; - var b = (rem % 6) / 5 * 255; +var _dsl = __webpack_require__(619); - return [r, g, b]; +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +var fillQueryInsideClient = function fillQueryInsideClient(client, queryName, queryOptions) { + var definition = queryOptions.definition, + doctype = queryOptions.doctype, + data = queryOptions.data, + queryResult = (0, _objectWithoutProperties2.default)(queryOptions, ["definition", "doctype", "data"]); + client.store.dispatch((0, _store.initQuery)(queryName, definition || (0, _dsl.Q)(doctype))); + client.store.dispatch((0, _store.receiveQueryResult)(queryName, _objectSpread({ + data: data ? data.map(function (doc) { + return (0, _cozyStackClient.normalizeDoc)(doc, doctype); + }) : data + }, queryResult))); }; -convert.rgb.hex = function (args) { - var integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); +var mockedQueryFromMockedRemoteData = function mockedQueryFromMockedRemoteData(remoteData) { + return function (qdef) { + if (!remoteData) { + return { + data: null + }; + } - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; + if (remoteData[qdef.doctype]) { + return { + data: remoteData[qdef.doctype] + }; + } else { + return { + data: [] + }; + } + }; }; +/** + * Creates a client suitable for use in tests + * + * - client.{query,save} are mocked + * - client.stackClient.fetchJSON is mocked + * + * @param {object} options Options + * @param {object} [options.queries] Prefill queries inside the store + * @param {object} [options.remote] Mock data from the server + * @param {object} [options.clientOptions] Options passed to the client + * @returns {CozyClient} + */ -convert.hex.rgb = function (args) { - var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } - var colorString = match[0]; +var createMockClient = function createMockClient(_ref) { + var queries = _ref.queries, + remote = _ref.remote, + clientOptions = _ref.clientOptions; + var client = new _CozyClient.default(clientOptions || {}); + client.ensureStore(); - if (match[0].length === 3) { - colorString = colorString.split('').map(function (char) { - return char + char; - }).join(''); - } + for (var _i = 0, _Object$entries = Object.entries(queries || {}); _i < _Object$entries.length; _i++) { + var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2), + queryName = _Object$entries$_i[0], + queryOptions = _Object$entries$_i[1]; - var integer = parseInt(colorString, 16); - var r = (integer >> 16) & 0xFF; - var g = (integer >> 8) & 0xFF; - var b = integer & 0xFF; + fillQueryInsideClient(client, queryName, queryOptions); + } - return [r, g, b]; + client.query = jest.fn().mockImplementation(mockedQueryFromMockedRemoteData(remote)); + client.save = jest.fn(); + client.saveAll = jest.fn(); + client.stackClient.fetchJSON = jest.fn(); + return client; }; -convert.rgb.hcg = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var max = Math.max(Math.max(r, g), b); - var min = Math.min(Math.min(r, g), b); - var chroma = (max - min); - var grayscale; - var hue; +exports.createMockClient = createMockClient; - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } +/***/ }), +/* 820 */ +/***/ ((module, exports, __webpack_require__) => { - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma + 4; - } +"use strict"; +/* module decorator */ module = __webpack_require__.nmd(module); - hue /= 6; - hue %= 1; - return [hue * 360, chroma * 100, grayscale * 100]; -}; +var _interopRequireDefault = __webpack_require__(524); -convert.hsl.hcg = function (hsl) { - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var c = 1; - var f = 0; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.createClientInteractive = void 0; - if (l < 0.5) { - c = 2.0 * s * l; - } else { - c = 2.0 * s * (1.0 - l); - } +var _regenerator = _interopRequireDefault(__webpack_require__(539)); - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); - return [hsl[0], c * 100, f * 100]; -}; +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -convert.hsv.hcg = function (hsv) { - var s = hsv[1] / 100; - var v = hsv[2] / 100; +var _http = _interopRequireDefault(__webpack_require__(80)); - var c = s * v; - var f = 0; +var _open = _interopRequireDefault(__webpack_require__(821)); - if (c < 1.0) { - f = (v - c) / (1 - c); - } +var _fs = _interopRequireDefault(__webpack_require__(149)); - return [hsv[0], c * 100, f * 100]; -}; +var _merge = _interopRequireDefault(__webpack_require__(754)); -convert.hcg.rgb = function (hcg) { - var h = hcg[0] / 360; - var c = hcg[1] / 100; - var g = hcg[2] / 100; +var _serverDestroy = _interopRequireDefault(__webpack_require__(825)); - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } +var _CozyClient = _interopRequireDefault(__webpack_require__(525)); - var pure = [0, 0, 0]; - var hi = (h % 1) * 6; - var v = hi % 1; - var w = 1 - v; - var mg = 0; +var _cozyLogger = _interopRequireDefault(__webpack_require__(354)); - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - mg = (1.0 - c) * g; +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; +var log = _cozyLogger.default.namespace('create-cli-client'); + +var nodeFetch = __webpack_require__(493); + +var btoa = __webpack_require__(490); +/** + * Creates and starts and HTTP server suitable for OAuth authentication + * + * @param {object} serverOptions - OAuth callback server options + * @param {Function} serverOptions.onAuthentication - Additional callback called + * when the user authenticates + * @param {string} serverOptions.route - Route used for authentication + * @param {number} serverOptions.port - Port on which the server will listen + * @param {Function} serverOptions.onListen - Callback called when the + * server starts + * + * @typedef {object} DestroyableServer + * @function destroy + * + * @returns {DestroyableServer} + * + * @private + */ -convert.hcg.hsv = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - var v = c + g * (1.0 - c); - var f = 0; +var createCallbackServer = function createCallbackServer(serverOptions) { + var route = serverOptions.route, + onListen = serverOptions.onListen, + onAuthentication = serverOptions.onAuthentication, + port = serverOptions.port; - if (v > 0.0) { - f = c / v; - } + var server = _http.default.createServer(function (request, response) { + if (request.url.indexOf(route) === 0) { + onAuthentication(request.url); + response.write('Authentication successful, you can close this page.'); + response.end(); + } + }); - return [hcg[0], f * 100, v * 100]; + server.listen(port, function () { + onListen(); + }); + (0, _serverDestroy.default)(server); + return server; }; +/** + * Creates a function suitable for usage with CozyClient::startOAuthFlow + * + * Starts a local server. The stack upon user authentication will + * redirect to this local server with a URL containing credentials. + * The callback resolves with this authenticationURL which continues + * the authentication flow inside startOAuthFlow. + * + * When the server is started, the authentication page is opened on the + * desktop browser of the user. + * + * @param {object} serverOptions - Options for the OAuth callback server + * @param {number} serverOptions.port - Port used for the OAuth callback server + * @param {Function} serverOptions.onAuthentication - Callback when the user authenticates + * @param {Function} serverOptions.onListen - Callback called with the authentication URL + * @param {string} serverOptions.route - Route used for authentication + * @param {boolean} serverOptions.shouldOpenAuthenticationPage - Whether the authentication + * page should be automatically opened (default: true) + * + * @private + */ -convert.hcg.hsl = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - var l = g * (1.0 - c) + 0.5 * c; - var s = 0; - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } +var mkServerFlowCallback = function mkServerFlowCallback(serverOptions) { + return function (authenticationURL) { + return new Promise(function (resolve, reject) { + var rejectTimeout, successTimeout; + var server = createCallbackServer(_objectSpread(_objectSpread({}, serverOptions), {}, { + onAuthentication: function onAuthentication(callbackURL) { + log('debug', 'Authenticated, Shutting server down'); + successTimeout = setTimeout(function () { + // Is there a way to call destroy only after all requests have + // been completely served ? Otherwise we close the server while + // the successful oauth page is being served and the page does + // not get loaded on the client side. + server.destroy(); + resolve('http://localhost:8000/' + callbackURL); + clearTimeout(rejectTimeout); + }, 300); + }, + onListen: function onListen() { + log('debug', 'OAuth callback server started, waiting for authentication'); - return [hcg[0], s * 100, l * 100]; -}; + if (serverOptions.shouldOpenAuthenticationPage !== false) { + (0, _open.default)(authenticationURL, { + wait: false + }); + } -convert.hcg.hwb = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - var v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; + if (serverOptions.onListen) { + serverOptions.onListen({ + authenticationURL: authenticationURL + }); + } + } + })); + rejectTimeout = setTimeout(function () { + clearTimeout(successTimeout); + server.destroy(); + reject('Timeout for authentication'); + }, 30 * 1000); + }); + }; }; -convert.hwb.hcg = function (hwb) { - var w = hwb[1] / 100; - var b = hwb[2] / 100; - var v = 1 - b; - var c = v - w; - var g = 0; +var hashCode = function hashCode(str) { + var hash = 0, + i, + chr; + if (str.length === 0) return hash; - if (c < 1) { - g = (v - c) / (1 - c); - } + for (i = 0; i < str.length; i++) { + chr = str.charCodeAt(i); + hash = (hash << 5) - hash + chr; + hash |= 0; // Convert to 32bit integer + } - return [hwb[0], c * 100, g * 100]; + return hash; }; -convert.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; +var DEFAULT_SERVER_OPTIONS = { + port: 3333, + route: '/do_access', + getSavedCredentials: function getSavedCredentials(clientOptions) { + if (!clientOptions.oauth.softwareID) { + throw new Error('Please provide oauth.softwareID in your clientOptions.'); + } -convert.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; + var doctypeHash = Math.abs(hashCode(JSON.stringify(clientOptions.scope))); + var sluggedURI = clientOptions.uri.replace(/https?:\/\//, '').replace(/\./g, '-'); + return "/tmp/cozy-client-oauth-".concat(sluggedURI, "-").concat(clientOptions.oauth.softwareID, "-").concat(doctypeHash, ".json"); + } }; -convert.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +var writeJSON = function writeJSON(fs, filename, data) { + fs.writeFileSync(filename, JSON.stringify(data)); }; +/** + * Parses a JSON from a file + * Returns null in case of error + * + * @private + */ -convert.gray.hsl = convert.gray.hsv = function (args) { - return [0, 0, args[0]]; -}; -convert.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; +var readJSON = function readJSON(fs, filename) { + try { + if (!fs.existsSync(filename)) { + return null; + } -convert.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; + var res = JSON.parse(fs.readFileSync(filename).toString()); + return res; + } catch (e) { + console.warn("Could not load ".concat(filename, " (").concat(e.message, ")")); + return null; + } }; +/** + * Creates a client with interactive authentication. + * + * - Will start an OAuth flow and open an authentication page + * - Starts a local server to listen for the oauth callback + * - Resolves with the client after user authentication + * + * @param {object} clientOptions Same as CozyClient::constructor. + * + * @example + * ``` + * import { createClientInteractive } from 'cozy-client/dist/cli' + * await createClientInteractive({ + * uri: 'http://cozy.tools:8080', + * scope: ['io.cozy.bills'], + * oauth: { + * softwareID: 'my-cli-application-using-bills' + * } + * }) + * ``` + * + * @returns {Promise<CozyClient>} - A client that is ready with a token + */ -convert.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; -convert.gray.hex = function (gray) { - var val = Math.round(gray[0] / 100 * 255) & 0xFF; - var integer = (val << 16) + (val << 8) + val; +var createClientInteractive = function createClientInteractive(clientOptions, serverOpts) { + global.fetch = nodeFetch; + global.btoa = btoa; + var serverOptions = (0, _merge.default)(DEFAULT_SERVER_OPTIONS, serverOpts); + var createClientFS = serverOptions.fs || _fs.default; + var mergedClientOptions = (0, _merge.default)({ + oauth: { + clientName: 'cli-client', + redirectURI: "http://localhost:".concat(serverOptions.port).concat(serverOptions.route) + } + }, clientOptions); - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; + if (!clientOptions.scope) { + throw new Error('scope must be provided in client options'); + } -convert.rgb.gray = function (rgb) { - var val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; + var getSavedCredentials = serverOptions.getSavedCredentials; + var savedCredentialsFilename = getSavedCredentials(mergedClientOptions); + var savedCredentials = readJSON(createClientFS, savedCredentialsFilename); + log('debug', "Starting OAuth flow"); + return new Promise( /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(resolve, reject) { + var client; + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + client = new _CozyClient.default(mergedClientOptions); + if (!savedCredentials) { + _context.next = 7; + break; + } -/***/ }), -/* 823 */ -/***/ ((module) => { + log('debug', "Using saved credentials in ".concat(savedCredentialsFilename)); + client.stackClient.setToken(savedCredentials.token); + client.stackClient.setOAuthOptions(savedCredentials.oauthOptions); + resolve(client); + return _context.abrupt("return"); -"use strict"; - - -module.exports = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; + case 7: + _context.next = 9; + return client.startOAuthFlow(mkServerFlowCallback(serverOptions)); + case 9: + resolve(client); + log('debug', "Saving credentials to ".concat(savedCredentialsFilename)); + writeJSON(createClientFS, savedCredentialsFilename, { + oauthOptions: client.stackClient.oauthOptions, + token: client.stackClient.token + }); -/***/ }), -/* 824 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + case 12: + case "end": + return _context.stop(); + } + } + }, _callee); + })); -var conversions = __webpack_require__(822); + return function (_x, _x2) { + return _ref.apply(this, arguments); + }; + }()); +}; -/* - this function routes a model to all other models. +exports.createClientInteractive = createClientInteractive; - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). +var main = /*#__PURE__*/function () { + var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() { + var client; + return _regenerator.default.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return createClientInteractive({ + scope: ['io.cozy.files'], + uri: 'http://cozy.tools:8080', + oauth: { + softwareID: 'io.cozy.client.cli' + } + }); - conversions that are not possible simply are not included. -*/ + case 2: + client = _context2.sent; + console.log(client.toJSON()); -function buildGraph() { - var graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - var models = Object.keys(conversions); + case 4: + case "end": + return _context2.stop(); + } + } + }, _callee2); + })); - for (var len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } + return function main() { + return _ref2.apply(this, arguments); + }; +}(); - return graph; +if (__webpack_require__.c[__webpack_require__.s] === module) { + main().catch(function (e) { + console.error(e); + process.exit(1); + }); } -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS(fromModel) { - var graph = buildGraph(); - var queue = [fromModel]; // unshift -> queue -> pop - - graph[fromModel].distance = 0; +/***/ }), +/* 821 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - while (queue.length) { - var current = queue.pop(); - var adjacents = Object.keys(conversions[current]); +"use strict"; - for (var len = adjacents.length, i = 0; i < len; i++) { - var adjacent = adjacents[i]; - var node = graph[adjacent]; +const {promisify} = __webpack_require__(64); +const path = __webpack_require__(142); +const childProcess = __webpack_require__(822); +const fs = __webpack_require__(149); +const isWsl = __webpack_require__(823); +const isDocker = __webpack_require__(824); - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } +const pAccess = promisify(fs.access); +const pReadFile = promisify(fs.readFile); - return graph; -} +// Path to included `xdg-open`. +const localXdgOpenPath = path.join(__dirname, 'xdg-open'); -function link(from, to) { - return function (args) { - return to(from(args)); - }; -} +/** +Get the mount point for fixed drives in WSL. -function wrapConversion(toModel, graph) { - var path = [graph[toModel].parent, toModel]; - var fn = conversions[graph[toModel].parent][toModel]; +@inner +@returns {string} The mount point. +*/ +const getWslDrivesMountPoint = (() => { + // Default value for "root" param + // according to https://docs.microsoft.com/en-us/windows/wsl/wsl-config + const defaultMountPoint = '/mnt/'; - var cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link(conversions[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } + let mountPoint; - fn.conversion = path; - return fn; -} + return async function () { + if (mountPoint) { + // Return memoized mount point value + return mountPoint; + } -module.exports = function (fromModel) { - var graph = deriveBFS(fromModel); - var conversion = {}; + const configFilePath = '/etc/wsl.conf'; - var models = Object.keys(graph); - for (var len = models.length, i = 0; i < len; i++) { - var toModel = models[i]; - var node = graph[toModel]; + let isConfigFileExists = false; + try { + await pAccess(configFilePath, fs.constants.F_OK); + isConfigFileExists = true; + } catch (_) {} - if (node.parent === null) { - // no possible conversion, or this node is the source model. - continue; + if (!isConfigFileExists) { + return defaultMountPoint; } - conversion[toModel] = wrapConversion(toModel, graph); - } + const configContent = await pReadFile(configFilePath, {encoding: 'utf8'}); + const configMountPoint = /root\s*=\s*(.*)/g.exec(configContent); - return conversion; -}; + if (!configMountPoint) { + return defaultMountPoint; + } + mountPoint = configMountPoint[1].trim(); + mountPoint = mountPoint.endsWith('/') ? mountPoint : mountPoint + '/'; + return mountPoint; + }; +})(); -/***/ }), -/* 825 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +module.exports = async (target, options) => { + if (typeof target !== 'string') { + throw new TypeError('Expected a `target`'); + } -"use strict"; + options = { + wait: false, + background: false, + allowNonzeroExitCode: false, + ...options + }; -const os = __webpack_require__(252); -const hasFlag = __webpack_require__(826); + let command; + let {app} = options; + let appArguments = []; + const cliArguments = []; + const childProcessOptions = {}; -const env = process.env; + if (Array.isArray(app)) { + appArguments = app.slice(1); + app = app[0]; + } -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} + if (process.platform === 'darwin') { + command = 'open'; -function translateLevel(level) { - if (level === 0) { - return false; - } + if (options.wait) { + cliArguments.push('--wait-apps'); + } - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} + if (options.background) { + cliArguments.push('--background'); + } -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } + if (app) { + cliArguments.push('-a', app); + } + } else if (process.platform === 'win32' || (isWsl && !isDocker())) { + const mountPoint = await getWslDrivesMountPoint(); - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } + command = isWsl ? + `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` : + `${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`; - if (hasFlag('color=256')) { - return 2; - } + cliArguments.push( + '-NoProfile', + '-NonInteractive', + '–ExecutionPolicy', + 'Bypass', + '-EncodedCommand' + ); - if (stream && !stream.isTTY && forceColor !== true) { - return 0; - } + if (!isWsl) { + childProcessOptions.windowsVerbatimArguments = true; + } - const min = forceColor ? 1 : 0; + const encodedArguments = ['Start']; - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; + if (options.wait) { + encodedArguments.push('-Wait'); } - return 1; - } + if (app) { + // Double quote with double quotes to ensure the inner quotes are passed through. + // Inner quotes are delimited for PowerShell interpretation with backticks. + encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList'); + appArguments.unshift(target); + } else { + encodedArguments.push(`"${target}"`); + } - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; + if (appArguments.length > 0) { + appArguments = appArguments.map(arg => `"\`"${arg}\`""`); + encodedArguments.push(appArguments.join(',')); } - return min; - } + // Using Base64-encoded command, accepted by PowerShell, to allow special characters. + target = Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64'); + } else { + if (app) { + command = app; + } else { + // When bundled by Webpack, there's no actual package file path and no local `xdg-open`. + const isBundled = false || __dirname === '/'; - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } + // Check if local `xdg-open` exists and is executable. + let exeLocalXdgOpen = false; + try { + await pAccess(localXdgOpenPath, fs.constants.X_OK); + exeLocalXdgOpen = true; + } catch (_) {} - if (env.COLORTERM === 'truecolor') { - return 3; - } + const useSystemXdgOpen = process.versions.electron || + process.platform === 'android' || isBundled || !exeLocalXdgOpen; + command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath; + } - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + if (appArguments.length > 0) { + cliArguments.push(...appArguments); + } - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default + if (!options.wait) { + // `xdg-open` will block the process unless stdio is ignored + // and it's detached from the parent even if it's unref'd. + childProcessOptions.stdio = 'ignore'; + childProcessOptions.detached = true; } } - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } + cliArguments.push(target); - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; + if (process.platform === 'darwin' && appArguments.length > 0) { + cliArguments.push('--args', ...appArguments); } - if ('COLORTERM' in env) { - return 1; - } + const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions); - if (env.TERM === 'dumb') { - return min; - } + if (options.wait) { + return new Promise((resolve, reject) => { + subprocess.once('error', reject); - return min; -} + subprocess.once('close', exitCode => { + if (options.allowNonzeroExitCode && exitCode > 0) { + reject(new Error(`Exited with code ${exitCode}`)); + return; + } -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); -} + resolve(subprocess); + }); + }); + } -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) + subprocess.unref(); + + return subprocess; }; /***/ }), -/* 826 */ +/* 822 */ /***/ ((module) => { "use strict"; - -module.exports = (flag, argv) => { - argv = argv || process.argv; - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const pos = argv.indexOf(prefix + flag); - const terminatorPos = argv.indexOf('--'); - return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); -}; - +module.exports = require("child_process"); /***/ }), -/* 827 */ -/***/ ((module) => { +/* 823 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); +const os = __webpack_require__(253); +const fs = __webpack_require__(149); +const isDocker = __webpack_require__(824); -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); +const isWsl = () => { + if (process.platform !== 'linux') { + return false; } - return ESCAPES.get(c) || c; -} + if (os.release().toLowerCase().includes('microsoft')) { + if (isDocker()) { + return false; + } -function parseArguments(name, args) { - const results = []; - const chunks = args.trim().split(/\s*,\s*/g); - let matches; + return true; + } - for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } + try { + return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ? + !isDocker() : false; + } catch (_) { + return false; } +}; - return results; +if (process.env.__IS_WSL_TEST__) { + module.exports = isWsl; +} else { + module.exports = isWsl(); } -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; - - const results = []; - let matches; - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; +/***/ }), +/* 824 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } +"use strict"; - return results; -} +const fs = __webpack_require__(149); -function buildStyle(chalk, styles) { - const enabled = {}; +let isDocker; - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } +function hasDockerEnv() { + try { + fs.statSync('/.dockerenv'); + return true; + } catch (_) { + return false; } +} - let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } +function hasDockerCGroup() { + try { + return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker'); + } catch (_) { + return false; + } +} - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } +module.exports = () => { + if (isDocker === undefined) { + isDocker = hasDockerEnv() || hasDockerCGroup(); } - return current; -} + return isDocker; +}; -module.exports = (chalk, tmp) => { - const styles = []; - const chunks = []; - let chunk = []; - // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); - } else if (style) { - const str = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } +/***/ }), +/* 825 */ +/***/ ((module) => { - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); +module.exports = enableDestroy; - chunks.push(chunk.join('')); +function enableDestroy(server) { + var connections = {} - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); - } + server.on('connection', function(conn) { + var key = conn.remoteAddress + ':' + conn.remotePort; + connections[key] = conn; + conn.on('close', function() { + delete connections[key]; + }); + }); - return chunks.join(''); -}; + server.destroy = function(cb) { + server.close(cb); + for (var key in connections) + connections[key].destroy(); + }; +} /***/ }), -/* 828 */ +/* 826 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireWildcard = __webpack_require__(510); +var _interopRequireWildcard = __webpack_require__(522); Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.timeseries = exports.document = exports.contact = exports.utils = exports.permission = exports.note = exports.account = exports.folder = exports.file = exports.applications = exports.instance = exports.trigger = exports.accounts = exports.triggers = void 0; +exports.dacc = exports.sharing = exports.timeseries = exports.document = exports.contact = exports.utils = exports.permission = exports.note = exports.account = exports.folder = exports.file = exports.applications = exports.instance = exports.trigger = exports.accounts = exports.triggers = void 0; -var trigger = _interopRequireWildcard(__webpack_require__(829)); +var trigger = _interopRequireWildcard(__webpack_require__(827)); exports.trigger = trigger; -var instance = _interopRequireWildcard(__webpack_require__(831)); +var instance = _interopRequireWildcard(__webpack_require__(829)); exports.instance = instance; -var applications = _interopRequireWildcard(__webpack_require__(832)); +var applications = _interopRequireWildcard(__webpack_require__(830)); exports.applications = applications; -var file = _interopRequireWildcard(__webpack_require__(833)); +var file = _interopRequireWildcard(__webpack_require__(831)); exports.file = file; -var folder = _interopRequireWildcard(__webpack_require__(839)); +var folder = _interopRequireWildcard(__webpack_require__(837)); exports.folder = folder; -var account = _interopRequireWildcard(__webpack_require__(830)); +var account = _interopRequireWildcard(__webpack_require__(828)); exports.account = account; -var note = _interopRequireWildcard(__webpack_require__(841)); +var note = _interopRequireWildcard(__webpack_require__(839)); exports.note = note; -var permission = _interopRequireWildcard(__webpack_require__(842)); +var permission = _interopRequireWildcard(__webpack_require__(840)); exports.permission = permission; -var utils = _interopRequireWildcard(__webpack_require__(843)); +var utils = _interopRequireWildcard(__webpack_require__(841)); exports.utils = utils; -var contact = _interopRequireWildcard(__webpack_require__(844)); +var contact = _interopRequireWildcard(__webpack_require__(842)); exports.contact = contact; -var document = _interopRequireWildcard(__webpack_require__(846)); +var document = _interopRequireWildcard(__webpack_require__(844)); exports.document = document; -var timeseries = _interopRequireWildcard(__webpack_require__(908)); +var timeseries = _interopRequireWildcard(__webpack_require__(906)); exports.timeseries = timeseries; + +var sharing = _interopRequireWildcard(__webpack_require__(907)); + +exports.sharing = sharing; + +var dacc = _interopRequireWildcard(__webpack_require__(908)); + +exports.dacc = dacc; // For backward compatibility before 9.0.0 var triggers = trigger; exports.triggers = triggers; @@ -125133,22 +125164,22 @@ var accounts = account; exports.accounts = accounts; /***/ }), -/* 829 */ +/* 827 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.triggers = exports.triggerStates = void 0; -var _get = _interopRequireDefault(__webpack_require__(358)); +var _get = _interopRequireDefault(__webpack_require__(370)); -var _account = __webpack_require__(830); +var _account = __webpack_require__(828); var actionableErrors = ['CHALLENGE_ASKED', 'DISK_QUOTA_EXCEEDED', 'TERMS_VERSION_MISMATCH', 'USER_ACTION_NEEDED', 'USER_ACTION_NEEDED.CHANGE_PASSWORD', 'USER_ACTION_NEEDED.ACCOUNT_REMOVED', 'USER_ACTION_NEEDED.WEBAUTH_REQUIRED', 'USER_ACTION_NEEDED.SCA_REQUIRED', 'LOGIN_FAILED']; /** Trigger states come from /jobs/triggers */ @@ -125256,26 +125287,26 @@ var triggers = { exports.triggers = triggers; /***/ }), -/* 830 */ +/* 828 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.setContractSyncStatusInAccount = exports.getContractSyncStatusFromAccount = exports.muteError = exports.getMutedErrors = void 0; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _get = _interopRequireDefault(__webpack_require__(358)); +var _get = _interopRequireDefault(__webpack_require__(370)); -var _merge = _interopRequireDefault(__webpack_require__(742)); +var _merge = _interopRequireDefault(__webpack_require__(754)); -var _HasMany = __webpack_require__(741); +var _HasMany = __webpack_require__(753); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } @@ -125361,20 +125392,20 @@ var setContractSyncStatusInAccount = function setContractSyncStatusInAccount(acc exports.setContractSyncStatusInAccount = setContractSyncStatusInAccount; /***/ }), -/* 831 */ +/* 829 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.buildPremiumLink = exports.hasAnOffer = exports.shouldDisplayOffers = exports.getUuid = exports.isFreemiumUser = exports.arePremiumLinksEnabled = exports.isSelfHosted = void 0; -var _get = _interopRequireDefault(__webpack_require__(358)); +var _get = _interopRequireDefault(__webpack_require__(370)); var GB = 1000 * 1000 * 1000; var PREMIUM_QUOTA = 50 * GB; @@ -125463,20 +125494,20 @@ var buildPremiumLink = function buildPremiumLink(instanceInfo) { exports.buildPremiumLink = buildPremiumLink; /***/ }), -/* 832 */ +/* 830 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getAppDisplayName = exports.getUrl = exports.isInstalled = exports.getStoreInstallationURL = exports.getStoreURL = void 0; -var _get = _interopRequireDefault(__webpack_require__(358)); +var _get = _interopRequireDefault(__webpack_require__(370)); var STORE_SLUG = 'store'; /** @@ -125578,13 +125609,13 @@ var getAppDisplayName = function getAppDisplayName(app, lang) { exports.getAppDisplayName = getAppDisplayName; /***/ }), -/* 833 */ +/* 831 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true @@ -125592,31 +125623,31 @@ Object.defineProperty(exports, "__esModule", ({ exports.normalize = normalize; exports.ensureFilePath = ensureFilePath; exports.getParentFolderId = getParentFolderId; -exports.fetchBlobFileById = exports.isFromKonnector = exports.hasCertifications = exports.hasQualifications = exports.isPlainText = exports.doMobileUpload = exports.readMobileFile = exports.uploadFileWithConflictStrategy = exports.generateFileNameForRevision = exports.generateNewFileNameOnConflict = exports.overrideFileForPath = exports.move = exports.getFullpath = exports.hasMetadataAttribute = exports.isReferencedByAlbum = exports.fetchFilesByQualificationRules = exports.saveFileQualification = exports.isSharingShorcutNew = exports.isSharingShortcutNew = exports.isSharingShorcut = exports.isSharingShortcut = exports.getSharingShortcutTargetDoctype = exports.getSharingShortcutTargetMime = exports.getSharingShortcutStatus = exports.isShortcut = exports.shouldBeOpenedByOnlyOffice = exports.isOnlyOfficeFile = exports.isNote = exports.isDirectory = exports.isFile = exports.splitFilename = exports.ALBUMS_DOCTYPE = void 0; +exports.fetchBlobFileById = exports.isFromKonnector = exports.hasCertifications = exports.hasQualifications = exports.isPlainText = exports.doMobileUpload = exports.readMobileFile = exports.uploadFileWithConflictStrategy = exports.generateFileNameForRevision = exports.generateNewFileNameOnConflict = exports.overrideFileForPath = exports.move = exports.getFullpath = exports.hasMetadataAttribute = exports.isReferencedByAlbum = exports.fetchFilesByQualificationRules = exports.saveFileQualification = exports.isSharingShorcutNew = exports.isSharingShortcutNew = exports.isSharingShorcut = exports.isSharingShortcut = exports.getSharingShortcutTargetDoctype = exports.getSharingShortcutTargetMime = exports.getSharingShortcutStatus = exports.isShortcut = exports.shouldBeOpenedByOnlyOffice = exports.isOnlyOfficeFile = exports.isEncrypted = exports.isNote = exports.isDirectory = exports.isFile = exports.splitFilename = exports.ALBUMS_DOCTYPE = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _get = _interopRequireDefault(__webpack_require__(358)); +var _get = _interopRequireDefault(__webpack_require__(370)); var _isString = _interopRequireDefault(__webpack_require__(54)); -var _has = _interopRequireDefault(__webpack_require__(662)); +var _has = _interopRequireDefault(__webpack_require__(674)); -var _trimEnd = _interopRequireDefault(__webpack_require__(834)); +var _trimEnd = _interopRequireDefault(__webpack_require__(832)); -var _qualification = __webpack_require__(836); +var _qualification = __webpack_require__(834); -var _dsl = __webpack_require__(607); +var _dsl = __webpack_require__(619); -var _types = __webpack_require__(610); +var _types = __webpack_require__(622); -var _const = __webpack_require__(685); +var _const = __webpack_require__(697); -var _CozyClient = _interopRequireDefault(__webpack_require__(513)); +var _CozyClient = _interopRequireDefault(__webpack_require__(525)); function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } @@ -125693,6 +125724,19 @@ var isNote = function isNote(file) { if (file && file.name && file.name.endsWith('.cozy-note') && file.type === FILE_TYPE && file.metadata && file.metadata.content !== undefined && file.metadata.schema !== undefined && file.metadata.title !== undefined && file.metadata.version !== undefined) return true; return false; }; +/** + * Whether the file is client-side encrypted + * + * @param {IOCozyFile} file - io.cozy.files document + * @returns {boolean} + */ + + +exports.isNote = isNote; + +var isEncrypted = function isEncrypted(file) { + return !!file.encrypted; +}; /** * Whether the file is supported by Only Office * @@ -125701,7 +125745,7 @@ var isNote = function isNote(file) { */ -exports.isNote = isNote; +exports.isEncrypted = isEncrypted; var isOnlyOfficeFile = function isOnlyOfficeFile(file) { return isFile(file) && !isNote(file) && (file.class === 'text' || file.class === 'spreadsheet' || file.class === 'slide'); @@ -126652,15 +126696,15 @@ var fetchBlobFileById = /*#__PURE__*/function () { exports.fetchBlobFileById = fetchBlobFileById; /***/ }), -/* 834 */ +/* 832 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseToString = __webpack_require__(397), - castSlice = __webpack_require__(765), - charsEndIndex = __webpack_require__(835), - stringToArray = __webpack_require__(767), - toString = __webpack_require__(396), - trimmedEndIndex = __webpack_require__(628); +var baseToString = __webpack_require__(409), + castSlice = __webpack_require__(777), + charsEndIndex = __webpack_require__(833), + stringToArray = __webpack_require__(779), + toString = __webpack_require__(408), + trimmedEndIndex = __webpack_require__(640); /** * Removes trailing whitespace or specified characters from `string`. @@ -126699,10 +126743,10 @@ module.exports = trimEnd; /***/ }), -/* 835 */ +/* 833 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseIndexOf = __webpack_require__(465); +var baseIndexOf = __webpack_require__(477); /** * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol @@ -126724,30 +126768,30 @@ module.exports = charsEndIndex; /***/ }), -/* 836 */ +/* 834 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireWildcard = __webpack_require__(510); +var _interopRequireWildcard = __webpack_require__(522); -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getQualification = exports.setQualification = exports.Qualification = void 0; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _classCallCheck2 = _interopRequireDefault(__webpack_require__(530)); +var _classCallCheck2 = _interopRequireDefault(__webpack_require__(542)); -var _createClass2 = _interopRequireDefault(__webpack_require__(531)); +var _createClass2 = _interopRequireDefault(__webpack_require__(543)); -var _lodash = __webpack_require__(837); +var _lodash = __webpack_require__(835); -var qualificationModel = _interopRequireWildcard(__webpack_require__(838)); +var qualificationModel = _interopRequireWildcard(__webpack_require__(836)); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } @@ -126994,7 +127038,7 @@ var getQualification = function getQualification(document) { exports.getQualification = getQualification; /***/ }), -/* 837 */ +/* 835 */ /***/ (function(module, exports, __webpack_require__) { /* module decorator */ module = __webpack_require__.nmd(module); @@ -144202,37 +144246,37 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/** /***/ }), -/* 838 */ +/* 836 */ /***/ ((module) => { "use strict"; module.exports = JSON.parse('{"qualifications":[{"label":"identity_photo","purpose":"attestation","subjects":["identity"]},{"label":"national_id_card","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["identity"]},{"label":"passport","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["identity"]},{"label":"residence_permit","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"immigration","subjects":["permit","identity"]},{"label":"family_record_book","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["family"]},{"label":"birth_certificate","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["identity","family"]},{"label":"driver_license","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"transport","subjects":["permit","driving"]},{"label":"other_identity_document","purpose":"attestation","subjects":["identity"]},{"label":"wedding","purpose":"contract","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["family"]},{"label":"pacs","purpose":"contract","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["family"]},{"label":"divorce","purpose":"contract","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["family"]},{"label":"large_family_card","purpose":"attestation","sourceCategory":"transport","subjects":["right"]},{"label":"caf","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"family","subjects":["right"]},{"label":"other_family_document","subjects":["family"]},{"label":"diploma","purpose":"attestation","sourceCategory":"education","subjects":["achievement"]},{"label":"work_contract","purpose":"contract","sourceCategory":"employer","subjects":["work","employment"]},{"label":"pay_sheet","purpose":"attestation","sourceCategory":"employer","subjects":["work","revenues"]},{"label":"unemployment_benefit","purpose":"attestation","sourceCategory":"gov","subjects":["revenues"]},{"label":"pension","purpose":"attestation","sourceCategory":"gov","subjects":["revenues"]},{"label":"other_revenue","purpose":"attestation","subjects":["revenues"]},{"label":"gradebook","purpose":"report","sourceCategory":"education","subjects":["history"]},{"label":"student_card","purpose":"attestation","sourceCategory":"education","subjects":["identity","right","employment","education"]},{"label":"resume","purpose":"description","subjects":["employment"]},{"label":"motivation_letter","purpose":"description","subjects":["employment"]},{"label":"other_work_document","purpose":"employment"},{"label":"health_book","purpose":"attestation","sourceCategory":"health","subjects":["capacity","vaccine"]},{"label":"health_certificate","purpose":"attestation","sourceCategory":"health","subjects":["capacity","vaccine"]},{"label":"pregnancy_medical_certificate","purpose":"attestation","sourceCategory":"health","subjects":["pregnancy"]},{"label":"work_disability_recognition","purpose":"attestation","sourceCategory":"health","subjects":["right"]},{"label":"national_health_insurance_card","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"health","subjects":["insurance"]},{"label":"national_health_insurance_right_certificate","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"health","subjects":["right","insurance"]},{"label":"health_insurance_card","purpose":"attestation","sourceCategory":"insurance","sourceSubCategory":"health","subjects":["insurance"]},{"label":"prescription","purpose":"attestation","sourceCategory":"health","subjects":["right","medecine"]},{"label":"health_invoice","purpose":"invoice","sourceCategory":"health"},{"label":"other_health_document","subjects":["health"]},{"label":"vehicle_registration","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"transport","subjects":["vehicule","identity","right"]},{"label":"car_insurance","purpose":"attestation","sourceCategory":"insurance","sourceSubCategory":"transport","subjects":["insurance","car"]},{"label":"mechanic_invoice","purpose":"invoice","sourceCategory":"transport"},{"label":"transport_invoice","purpose":"invoice","sourceCategory":"transport"},{"label":"other_transport_document","sourceCategory":"transport"},{"label":"house_sale_agreeement","purpose":"contract","sourceCategory":"real_estate","subjects":["house"]},{"label":"building_permit","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"real_estate","subjects":["permit","house"]},{"label":"technical_diagnostic_record","purpose":"report","sourceCategory":"real_estate","subjects":["compliance","house"]},{"label":"lease","purpose":"contract","sourceCategory":"real_estate","subjects":["house"]},{"label":"rent_receipt","purpose":"invoice","sourceCategory":"real_estate","subjects":["house"]},{"label":"house_insurance","purpose":"contract","sourceCategory":"insurance","sourceSubCategory":"real_estate","subjects":["insurance","house"]},{"label":"work_quote","purpose":"description","sourceCategory":"building","subjects":["building","house"]},{"label":"work_invoice","purpose":"invoice","sourceCategory":"building","subjects":["building","house"]},{"label":"other_house_document","subjects":["house"]},{"label":"phone_invoice","purpose":"invoice","sourceCategory":"telecom","sourceSubCategory":"mobile"},{"label":"isp_invoice","purpose":"invoice","sourceCategory":"telecom","sourceSubCategory":"internet","subjects":["subscription"]},{"label":"telecom_invoice","purpose":"invoice","sourceCategory":"telecom"},{"label":"energy_invoice","purpose":"invoice","sourceCategory":"energy"},{"label":"water_invoice","purpose":"invoice","sourceCategory":"water"},{"label":"appliance_invoice","purpose":"invoice","sourceCategory":"retail"},{"label":"web_service_invoice","purpose":"invoice","sourceCategory":"web"},{"label":"restaurant_invoice","purpose":"invoice","sourceCategory":"alimentation"},{"label":"grocery_invoice","purpose":"invoice","sourceCategory":"shopping"},{"label":"other_invoice","purpose":"invoice"},{"label":"tax_return","purpose":"report","sourceCategory":"gov","sourceSubCategory":"tax","subjects":["tax"]},{"label":"tax_notice","purpose":"invoice","sourceCategory":"gov","sourceSubCategory":"tax","subjects":["tax"]},{"label":"tax_timetable","purpose":"report","sourceCategory":"gov","sourceSubCategory":"tax","subjects":["tax"]},{"label":"other_tax_document","subjects":["tax"]},{"label":"bank_details","purpose":"attestation","sourceCategory":"bank","subjects":["bank_account"]},{"label":"bank_statement","purpose":"report","sourceCategory":"bank","subjects":["history"]},{"label":"loan_agreement","purpose":"contract","sourceCategory":"bank"},{"label":"other_bank_document","sourceCategory":"bank"},{"label":"receipt","purpose":"report"},{"label":"payment_proof_family_allowance","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"tax","subjects":["subvention"]},{"label":"school_attendance_certificate","purpose":"attestation","sourceCategory":"education","subjects":["identity","right","education"]},{"label":"unfit_for_habitation_declaration","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"real_estate","subjects":["compliance"]},{"label":"accommodation_proof","purpose":"attestation","sourceCategory":"individual","subjects":["address"]},{"label":"citizen_registration_certificate","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"civil_registration","subjects":["achievement","education"]},{"label":"personal_sporting_licence","purpose":"attestation","sourceCategory":"gov","sourceSubCategory":"sport","subjects":["permit","invoice"]},{"label":"other_activity_document","sourceSubCategory":"sport","subjects":["permit","invoice"]}],"purposeKnownValues":["attestation","contract","invoice","report","description","evaluation","employment"],"sourceCategoryKnownValues":["bank","insurance","retail","telecom","energy","water","health","gov","association","education","employer","transport","goods","alimentation","building","real_estate","web","individual","shopping"],"sourceSubCategoryKnownValues":["civil_registration","immigration","transport","family","tax","health","real_estate","mobile","internet","citizen","sport"],"subjectsKnownValues":["identity","permit","family","address","driving","right","subvention","achievement","degree","work","employment","revenues","history","insurance","medical_act","vehicule","car","moto","truck","boat","subscription","buy/sale","house","compliance","building","food","real_estate","tax","address","education","statement","course","internet","phone","vaccine","capacity","health","drugs","child","pregnancy","bank_account"]}'); /***/ }), -/* 839 */ +/* 837 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getReferencedFolder = exports.createFolderWithReference = exports.ensureMagicFolder = exports.MAGIC_FOLDERS = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _sortBy = _interopRequireDefault(__webpack_require__(840)); +var _sortBy = _interopRequireDefault(__webpack_require__(838)); -var _CozyClient = _interopRequireDefault(__webpack_require__(513)); +var _CozyClient = _interopRequireDefault(__webpack_require__(525)); -var _types = __webpack_require__(610); +var _types = __webpack_require__(622); -var _const = __webpack_require__(685); +var _const = __webpack_require__(697); var APP_DOCTYPE = 'io.cozy.apps'; var administrative = 'administrative'; @@ -144420,13 +144464,13 @@ var getReferencedFolder = /*#__PURE__*/function () { exports.getReferencedFolder = getReferencedFolder; /***/ }), -/* 840 */ +/* 838 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseFlatten = __webpack_require__(541), - baseOrderBy = __webpack_require__(732), - baseRest = __webpack_require__(544), - isIterateeCall = __webpack_require__(749); +var baseFlatten = __webpack_require__(553), + baseOrderBy = __webpack_require__(744), + baseRest = __webpack_require__(556), + isIterateeCall = __webpack_require__(761); /** * Creates an array of elements, sorted in ascending order by the results of @@ -144474,24 +144518,24 @@ module.exports = sortBy; /***/ }), -/* 841 */ +/* 839 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.fetchURL = exports.generateUrlForNote = exports.generatePrivateUrl = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _helpers = __webpack_require__(756); +var _helpers = __webpack_require__(768); /** * @@ -144592,13 +144636,13 @@ var fetchURL = /*#__PURE__*/function () { exports.fetchURL = fetchURL; /***/ }), -/* 842 */ +/* 840 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true @@ -144609,25 +144653,25 @@ exports.isForType = isForType; exports.isDocumentReadOnly = isDocumentReadOnly; exports.isShortcutCreatedOnTheRecipientCozy = void 0; -var _defineProperty2 = _interopRequireDefault(__webpack_require__(532)); +var _defineProperty2 = _interopRequireDefault(__webpack_require__(544)); -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(522)); +var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(534)); -var _intersection = _interopRequireDefault(__webpack_require__(727)); +var _intersection = _interopRequireDefault(__webpack_require__(739)); -var _get = _interopRequireDefault(__webpack_require__(358)); +var _get = _interopRequireDefault(__webpack_require__(370)); -var _CozyClient = _interopRequireDefault(__webpack_require__(513)); +var _CozyClient = _interopRequireDefault(__webpack_require__(525)); -var _dsl = __webpack_require__(607); +var _dsl = __webpack_require__(619); -var _file = __webpack_require__(833); +var _file = __webpack_require__(831); -var _const = __webpack_require__(685); +var _const = __webpack_require__(697); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } @@ -145024,20 +145068,20 @@ var isShortcutCreatedOnTheRecipientCozy = function isShortcutCreatedOnTheRecipie exports.isShortcutCreatedOnTheRecipientCozy = isShortcutCreatedOnTheRecipientCozy; /***/ }), -/* 843 */ +/* 841 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getCreatedByApp = exports.hasBeenUpdatedByApp = void 0; -var _get = _interopRequireDefault(__webpack_require__(358)); +var _get = _interopRequireDefault(__webpack_require__(370)); var hasBeenUpdatedByApp = function hasBeenUpdatedByApp(doc, appSlug) { var updatedByApps = (0, _get.default)(doc, 'cozyMetadata.updatedByApps'); @@ -145055,22 +145099,22 @@ var getCreatedByApp = function getCreatedByApp(doc) { exports.getCreatedByApp = getCreatedByApp; /***/ }), -/* 844 */ +/* 842 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getIndexByFamilyNameGivenNameEmailCozyUrl = exports.getDefaultSortIndexValue = exports.makeDefaultSortIndexValue = exports.getDisplayName = exports.makeDisplayName = exports.getFullname = exports.makeFullname = exports.getPrimaryAddress = exports.getPrimaryPhone = exports.getPrimaryCozyDomain = exports.getPrimaryCozy = exports.getPrimaryEmail = exports.getInitials = exports.getPrimaryOrFirst = void 0; -var _get = _interopRequireDefault(__webpack_require__(358)); +var _get = _interopRequireDefault(__webpack_require__(370)); -var _isEmpty = _interopRequireDefault(__webpack_require__(845)); +var _isEmpty = _interopRequireDefault(__webpack_require__(843)); var getPrimaryOrFirst = function getPrimaryOrFirst(property) { return function (obj) { @@ -145321,17 +145365,17 @@ var getIndexByFamilyNameGivenNameEmailCozyUrl = function getIndexByFamilyNameGiv exports.getIndexByFamilyNameGivenNameEmailCozyUrl = getIndexByFamilyNameGivenNameEmailCozyUrl; /***/ }), -/* 845 */ +/* 843 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseKeys = __webpack_require__(442), - getTag = __webpack_require__(447), - isArguments = __webpack_require__(432), +var baseKeys = __webpack_require__(454), + getTag = __webpack_require__(459), + isArguments = __webpack_require__(444), isArray = __webpack_require__(55), - isArrayLike = __webpack_require__(446), - isBuffer = __webpack_require__(434), - isPrototype = __webpack_require__(443), - isTypedArray = __webpack_require__(437); + isArrayLike = __webpack_require__(458), + isBuffer = __webpack_require__(446), + isPrototype = __webpack_require__(455), + isTypedArray = __webpack_require__(449); /** `Object#toString` result references. */ var mapTag = '[object Map]', @@ -145404,13 +145448,13 @@ module.exports = isEmpty; /***/ }), -/* 846 */ +/* 844 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireWildcard = __webpack_require__(510); +var _interopRequireWildcard = __webpack_require__(522); Object.defineProperty(exports, "__esModule", ({ value: true @@ -145435,35 +145479,35 @@ Object.defineProperty(exports, "getQualification", ({ })); exports.helpers = exports.themes = exports.locales = void 0; -var _qualification = __webpack_require__(836); +var _qualification = __webpack_require__(834); -var locales = _interopRequireWildcard(__webpack_require__(847)); +var locales = _interopRequireWildcard(__webpack_require__(845)); exports.locales = locales; -var themes = _interopRequireWildcard(__webpack_require__(906)); +var themes = _interopRequireWildcard(__webpack_require__(904)); exports.themes = themes; -var helpers = _interopRequireWildcard(__webpack_require__(907)); +var helpers = _interopRequireWildcard(__webpack_require__(905)); exports.helpers = helpers; /***/ }), -/* 847 */ +/* 845 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getBoundT = void 0; -var _nodePolyglot = _interopRequireDefault(__webpack_require__(848)); +var _nodePolyglot = _interopRequireDefault(__webpack_require__(846)); var polyglots = {}; var langs = ['fr', 'en']; @@ -145473,7 +145517,7 @@ for (var _i = 0, _langs = langs; _i < _langs.length; _i++) { var locales = {}; try { - locales = __webpack_require__(903)("./".concat(lang, ".json")); + locales = __webpack_require__(901)("./".concat(lang, ".json")); } catch (e) {// eslint-disable-line no-empty-block } @@ -145496,7 +145540,7 @@ var getBoundT = function getBoundT(lang) { exports.getBoundT = getBoundT; /***/ }), -/* 848 */ +/* 846 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -145519,11 +145563,11 @@ exports.getBoundT = getBoundT; -var forEach = __webpack_require__(849); -var entries = __webpack_require__(894); -var warning = __webpack_require__(898); -var has = __webpack_require__(637); -var trim = __webpack_require__(899); +var forEach = __webpack_require__(847); +var entries = __webpack_require__(892); +var warning = __webpack_require__(896); +var has = __webpack_require__(649); +var trim = __webpack_require__(897); var warn = function warn(message) { warning(false, message); @@ -145932,21 +145976,21 @@ module.exports = Polyglot; /***/ }), -/* 849 */ +/* 847 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var define = __webpack_require__(850); -var callBind = __webpack_require__(639); -var callBound = __webpack_require__(638); -var RequireObjectCoercible = __webpack_require__(854); +var define = __webpack_require__(848); +var callBind = __webpack_require__(651); +var callBound = __webpack_require__(650); +var RequireObjectCoercible = __webpack_require__(852); -var implementation = __webpack_require__(856); -var getPolyfill = __webpack_require__(891); +var implementation = __webpack_require__(854); +var getPolyfill = __webpack_require__(889); var polyfill = getPolyfill(); -var shim = __webpack_require__(893); +var shim = __webpack_require__(891); var $slice = callBound('Array.prototype.slice'); @@ -145967,13 +146011,13 @@ module.exports = boundCoercible; /***/ }), -/* 850 */ +/* 848 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var keys = __webpack_require__(851); +var keys = __webpack_require__(849); var hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol'; var toStr = Object.prototype.toString; @@ -146032,17 +146076,17 @@ module.exports = defineProperties; /***/ }), -/* 851 */ +/* 849 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; var slice = Array.prototype.slice; -var isArgs = __webpack_require__(852); +var isArgs = __webpack_require__(850); var origKeys = Object.keys; -var keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(853); +var keysShim = origKeys ? function keys(o) { return origKeys(o); } : __webpack_require__(851); var originalKeys = Object.keys; @@ -146071,7 +146115,7 @@ module.exports = keysShim; /***/ }), -/* 852 */ +/* 850 */ /***/ ((module) => { "use strict"; @@ -146095,7 +146139,7 @@ module.exports = function isArguments(value) { /***/ }), -/* 853 */ +/* 851 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -146106,7 +146150,7 @@ if (!Object.keys) { // modified from https://github.com/es-shims/es5-shim var has = Object.prototype.hasOwnProperty; var toStr = Object.prototype.toString; - var isArgs = __webpack_require__(852); // eslint-disable-line global-require + var isArgs = __webpack_require__(850); // eslint-disable-line global-require var isEnumerable = Object.prototype.propertyIsEnumerable; var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString'); var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype'); @@ -146224,23 +146268,23 @@ module.exports = keysShim; /***/ }), -/* 854 */ +/* 852 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -module.exports = __webpack_require__(855); +module.exports = __webpack_require__(853); /***/ }), -/* 855 */ +/* 853 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $TypeError = GetIntrinsic('%TypeError%'); @@ -146255,25 +146299,25 @@ module.exports = function CheckObjectCoercible(value, optMessage) { /***/ }), -/* 856 */ +/* 854 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); -var callBound = __webpack_require__(638); +var GetIntrinsic = __webpack_require__(644); +var callBound = __webpack_require__(650); var $TypeError = GetIntrinsic('%TypeError%'); -var Call = __webpack_require__(857); -var Get = __webpack_require__(859); -var HasProperty = __webpack_require__(863); -var IsCallable = __webpack_require__(864); -var LengthOfArrayLike = __webpack_require__(866); -var ToObject = __webpack_require__(888); -var ToString = __webpack_require__(889); +var Call = __webpack_require__(855); +var Get = __webpack_require__(857); +var HasProperty = __webpack_require__(861); +var IsCallable = __webpack_require__(862); +var LengthOfArrayLike = __webpack_require__(864); +var ToObject = __webpack_require__(886); +var ToString = __webpack_require__(887); -var isString = __webpack_require__(890); +var isString = __webpack_require__(888); var $split = callBound('String.prototype.split'); @@ -146312,18 +146356,18 @@ module.exports = function forEach(callbackfn) { /***/ }), -/* 857 */ +/* 855 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); -var callBound = __webpack_require__(638); +var GetIntrinsic = __webpack_require__(644); +var callBound = __webpack_require__(650); var $TypeError = GetIntrinsic('%TypeError%'); -var IsArray = __webpack_require__(858); +var IsArray = __webpack_require__(856); var $apply = GetIntrinsic('%Reflect.apply%', true) || callBound('%Function.prototype.apply%'); @@ -146339,18 +146383,18 @@ module.exports = function Call(F, V) { /***/ }), -/* 858 */ +/* 856 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $Array = GetIntrinsic('%Array%'); // eslint-disable-next-line global-require -var toStr = !$Array.isArray && __webpack_require__(638)('Object.prototype.toString'); +var toStr = !$Array.isArray && __webpack_require__(650)('Object.prototype.toString'); // https://ecma-international.org/ecma-262/6.0/#sec-isarray @@ -146360,20 +146404,20 @@ module.exports = $Array.isArray || function IsArray(argument) { /***/ }), -/* 859 */ +/* 857 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $TypeError = GetIntrinsic('%TypeError%'); -var inspect = __webpack_require__(640); +var inspect = __webpack_require__(652); -var IsPropertyKey = __webpack_require__(860); -var Type = __webpack_require__(861); +var IsPropertyKey = __webpack_require__(858); +var Type = __webpack_require__(859); /** * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p @@ -146397,7 +146441,7 @@ module.exports = function Get(O, P) { /***/ }), -/* 860 */ +/* 858 */ /***/ ((module) => { "use strict"; @@ -146411,13 +146455,13 @@ module.exports = function IsPropertyKey(argument) { /***/ }), -/* 861 */ +/* 859 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var ES5Type = __webpack_require__(862); +var ES5Type = __webpack_require__(860); // https://262.ecma-international.org/11.0/#sec-ecmascript-data-types-and-values @@ -146433,7 +146477,7 @@ module.exports = function Type(x) { /***/ }), -/* 862 */ +/* 860 */ /***/ ((module) => { "use strict"; @@ -146464,18 +146508,18 @@ module.exports = function Type(x) { /***/ }), -/* 863 */ +/* 861 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $TypeError = GetIntrinsic('%TypeError%'); -var IsPropertyKey = __webpack_require__(860); -var Type = __webpack_require__(861); +var IsPropertyKey = __webpack_require__(858); +var Type = __webpack_require__(859); // https://ecma-international.org/ecma-262/6.0/#sec-hasproperty @@ -146491,7 +146535,7 @@ module.exports = function HasProperty(O, P) { /***/ }), -/* 864 */ +/* 862 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -146499,11 +146543,11 @@ module.exports = function HasProperty(O, P) { // http://262.ecma-international.org/5.1/#sec-9.11 -module.exports = __webpack_require__(865); +module.exports = __webpack_require__(863); /***/ }), -/* 865 */ +/* 863 */ /***/ ((module) => { "use strict"; @@ -146584,19 +146628,19 @@ module.exports = reflectApply /***/ }), -/* 866 */ +/* 864 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $TypeError = GetIntrinsic('%TypeError%'); -var Get = __webpack_require__(859); -var ToLength = __webpack_require__(867); -var Type = __webpack_require__(861); +var Get = __webpack_require__(857); +var ToLength = __webpack_require__(865); +var Type = __webpack_require__(859); // https://262.ecma-international.org/11.0/#sec-lengthofarraylike @@ -146611,15 +146655,15 @@ module.exports = function LengthOfArrayLike(obj) { /***/ }), -/* 867 */ +/* 865 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var MAX_SAFE_INTEGER = __webpack_require__(868); +var MAX_SAFE_INTEGER = __webpack_require__(866); -var ToIntegerOrInfinity = __webpack_require__(869); +var ToIntegerOrInfinity = __webpack_require__(867); module.exports = function ToLength(argument) { var len = ToIntegerOrInfinity(argument); @@ -146630,13 +146674,13 @@ module.exports = function ToLength(argument) { /***/ }), -/* 868 */ +/* 866 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $Math = GetIntrinsic('%Math%'); var $Number = GetIntrinsic('%Number%'); @@ -146645,15 +146689,15 @@ module.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1; /***/ }), -/* 869 */ +/* 867 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var ES5ToInteger = __webpack_require__(870); +var ES5ToInteger = __webpack_require__(868); -var ToNumber = __webpack_require__(880); +var ToNumber = __webpack_require__(878); // https://www.ecma-international.org/ecma-262/11.0/#sec-tointeger @@ -146667,19 +146711,19 @@ module.exports = function ToInteger(value) { /***/ }), -/* 870 */ +/* 868 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var abs = __webpack_require__(871); -var floor = __webpack_require__(872); -var ToNumber = __webpack_require__(873); +var abs = __webpack_require__(869); +var floor = __webpack_require__(870); +var ToNumber = __webpack_require__(871); -var $isNaN = __webpack_require__(877); -var $isFinite = __webpack_require__(878); -var $sign = __webpack_require__(879); +var $isNaN = __webpack_require__(875); +var $isFinite = __webpack_require__(876); +var $sign = __webpack_require__(877); // http://262.ecma-international.org/5.1/#sec-9.4 @@ -146692,13 +146736,13 @@ module.exports = function ToInteger(value) { /***/ }), -/* 871 */ +/* 869 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $abs = GetIntrinsic('%Math.abs%'); @@ -146710,7 +146754,7 @@ module.exports = function abs(x) { /***/ }), -/* 872 */ +/* 870 */ /***/ ((module) => { "use strict"; @@ -146728,13 +146772,13 @@ module.exports = function floor(x) { /***/ }), -/* 873 */ +/* 871 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var ToPrimitive = __webpack_require__(874); +var ToPrimitive = __webpack_require__(872); // http://262.ecma-international.org/5.1/#sec-9.3 @@ -146755,7 +146799,7 @@ module.exports = function ToNumber(value) { /***/ }), -/* 874 */ +/* 872 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -146763,11 +146807,11 @@ module.exports = function ToNumber(value) { // http://262.ecma-international.org/5.1/#sec-9.1 -module.exports = __webpack_require__(875); +module.exports = __webpack_require__(873); /***/ }), -/* 875 */ +/* 873 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -146775,9 +146819,9 @@ module.exports = __webpack_require__(875); var toStr = Object.prototype.toString; -var isPrimitive = __webpack_require__(876); +var isPrimitive = __webpack_require__(874); -var isCallable = __webpack_require__(865); +var isCallable = __webpack_require__(863); // http://ecma-international.org/ecma-262/5.1/#sec-8.12.8 var ES5internalSlots = { @@ -146819,7 +146863,7 @@ module.exports = function ToPrimitive(input) { /***/ }), -/* 876 */ +/* 874 */ /***/ ((module) => { "use strict"; @@ -146831,7 +146875,7 @@ module.exports = function isPrimitive(value) { /***/ }), -/* 877 */ +/* 875 */ /***/ ((module) => { "use strict"; @@ -146843,7 +146887,7 @@ module.exports = Number.isNaN || function isNaN(a) { /***/ }), -/* 878 */ +/* 876 */ /***/ ((module) => { "use strict"; @@ -146855,7 +146899,7 @@ module.exports = Number.isFinite || function (x) { return typeof x === 'number' /***/ }), -/* 879 */ +/* 877 */ /***/ ((module) => { "use strict"; @@ -146867,22 +146911,22 @@ module.exports = function sign(number) { /***/ }), -/* 880 */ +/* 878 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $TypeError = GetIntrinsic('%TypeError%'); var $Number = GetIntrinsic('%Number%'); var $RegExp = GetIntrinsic('%RegExp%'); var $parseInteger = GetIntrinsic('%parseInt%'); -var callBound = __webpack_require__(638); -var regexTester = __webpack_require__(881); -var isPrimitive = __webpack_require__(882); +var callBound = __webpack_require__(650); +var regexTester = __webpack_require__(879); +var isPrimitive = __webpack_require__(880); var $strSlice = callBound('String.prototype.slice'); var isBinary = regexTester(/^0b[01]+$/i); @@ -146905,7 +146949,7 @@ var $trim = function (value) { return $replace(value, trimRegex, ''); }; -var ToPrimitive = __webpack_require__(883); +var ToPrimitive = __webpack_require__(881); // https://ecma-international.org/ecma-262/6.0/#sec-tonumber @@ -146936,17 +146980,17 @@ module.exports = function ToNumber(argument) { /***/ }), -/* 881 */ +/* 879 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $test = GetIntrinsic('RegExp.prototype.test'); -var callBind = __webpack_require__(639); +var callBind = __webpack_require__(651); module.exports = function regexTester(regex) { return callBind($test, regex); @@ -146954,7 +146998,7 @@ module.exports = function regexTester(regex) { /***/ }), -/* 882 */ +/* 880 */ /***/ ((module) => { "use strict"; @@ -146966,13 +147010,13 @@ module.exports = function isPrimitive(value) { /***/ }), -/* 883 */ +/* 881 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var toPrimitive = __webpack_require__(884); +var toPrimitive = __webpack_require__(882); // https://ecma-international.org/ecma-262/6.0/#sec-toprimitive @@ -146985,7 +147029,7 @@ module.exports = function ToPrimitive(input) { /***/ }), -/* 884 */ +/* 882 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -146993,10 +147037,10 @@ module.exports = function ToPrimitive(input) { var hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol'; -var isPrimitive = __webpack_require__(876); -var isCallable = __webpack_require__(865); -var isDate = __webpack_require__(885); -var isSymbol = __webpack_require__(887); +var isPrimitive = __webpack_require__(874); +var isCallable = __webpack_require__(863); +var isDate = __webpack_require__(883); +var isSymbol = __webpack_require__(885); var ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) { if (typeof O === 'undefined' || O === null) { @@ -147067,7 +147111,7 @@ module.exports = function ToPrimitive(input) { /***/ }), -/* 885 */ +/* 883 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -147085,7 +147129,7 @@ var tryDateObject = function tryDateGetDayCall(value) { var toStr = Object.prototype.toString; var dateClass = '[object Date]'; -var hasToStringTag = __webpack_require__(886)(); +var hasToStringTag = __webpack_require__(884)(); module.exports = function isDateObject(value) { if (typeof value !== 'object' || value === null) { @@ -147096,13 +147140,13 @@ module.exports = function isDateObject(value) { /***/ }), -/* 886 */ +/* 884 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var hasSymbols = __webpack_require__(634); +var hasSymbols = __webpack_require__(646); module.exports = function hasToStringTagShams() { return hasSymbols() && !!Symbol.toStringTag; @@ -147110,14 +147154,14 @@ module.exports = function hasToStringTagShams() { /***/ }), -/* 887 */ +/* 885 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; var toStr = Object.prototype.toString; -var hasSymbols = __webpack_require__(633)(); +var hasSymbols = __webpack_require__(645)(); if (hasSymbols) { var symToStr = Symbol.prototype.toString; @@ -147152,17 +147196,17 @@ if (hasSymbols) { /***/ }), -/* 888 */ +/* 886 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $Object = GetIntrinsic('%Object%'); -var RequireObjectCoercible = __webpack_require__(854); +var RequireObjectCoercible = __webpack_require__(852); // https://ecma-international.org/ecma-262/6.0/#sec-toobject @@ -147173,13 +147217,13 @@ module.exports = function ToObject(value) { /***/ }), -/* 889 */ +/* 887 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var GetIntrinsic = __webpack_require__(632); +var GetIntrinsic = __webpack_require__(644); var $String = GetIntrinsic('%String%'); var $TypeError = GetIntrinsic('%TypeError%'); @@ -147195,7 +147239,7 @@ module.exports = function ToString(argument) { /***/ }), -/* 890 */ +/* 888 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -147212,7 +147256,7 @@ var tryStringObject = function tryStringObject(value) { }; var toStr = Object.prototype.toString; var strClass = '[object String]'; -var hasToStringTag = __webpack_require__(886)(); +var hasToStringTag = __webpack_require__(884)(); module.exports = function isString(value) { if (typeof value === 'string') { @@ -147226,15 +147270,15 @@ module.exports = function isString(value) { /***/ }), -/* 891 */ +/* 889 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var arrayMethodBoxesProperly = __webpack_require__(892); +var arrayMethodBoxesProperly = __webpack_require__(890); -var implementation = __webpack_require__(856); +var implementation = __webpack_require__(854); module.exports = function getPolyfill() { var method = Array.prototype.forEach; @@ -147243,7 +147287,7 @@ module.exports = function getPolyfill() { /***/ }), -/* 892 */ +/* 890 */ /***/ ((module) => { module.exports = function properlyBoxed(method) { @@ -147279,14 +147323,14 @@ module.exports = function properlyBoxed(method) { /***/ }), -/* 893 */ +/* 891 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var define = __webpack_require__(850); -var getPolyfill = __webpack_require__(891); +var define = __webpack_require__(848); +var getPolyfill = __webpack_require__(889); module.exports = function shimForEach() { var polyfill = getPolyfill(); @@ -147300,18 +147344,18 @@ module.exports = function shimForEach() { /***/ }), -/* 894 */ +/* 892 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var define = __webpack_require__(850); -var callBind = __webpack_require__(639); +var define = __webpack_require__(848); +var callBind = __webpack_require__(651); -var implementation = __webpack_require__(895); -var getPolyfill = __webpack_require__(896); -var shim = __webpack_require__(897); +var implementation = __webpack_require__(893); +var getPolyfill = __webpack_require__(894); +var shim = __webpack_require__(895); var polyfill = callBind(getPolyfill(), Object); @@ -147325,14 +147369,14 @@ module.exports = polyfill; /***/ }), -/* 895 */ +/* 893 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var RequireObjectCoercible = __webpack_require__(854); -var callBound = __webpack_require__(638); +var RequireObjectCoercible = __webpack_require__(852); +var callBound = __webpack_require__(650); var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable'); var $push = callBound('Array.prototype.push'); @@ -147349,13 +147393,13 @@ module.exports = function entries(O) { /***/ }), -/* 896 */ +/* 894 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var implementation = __webpack_require__(895); +var implementation = __webpack_require__(893); module.exports = function getPolyfill() { return typeof Object.entries === 'function' ? Object.entries : implementation; @@ -147363,14 +147407,14 @@ module.exports = function getPolyfill() { /***/ }), -/* 897 */ +/* 895 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var getPolyfill = __webpack_require__(896); -var define = __webpack_require__(850); +var getPolyfill = __webpack_require__(894); +var define = __webpack_require__(848); module.exports = function shimEntries() { var polyfill = getPolyfill(); @@ -147384,7 +147428,7 @@ module.exports = function shimEntries() { /***/ }), -/* 898 */ +/* 896 */ /***/ ((module) => { "use strict"; @@ -147453,18 +147497,18 @@ module.exports = warning; /***/ }), -/* 899 */ +/* 897 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var callBind = __webpack_require__(639); -var define = __webpack_require__(850); +var callBind = __webpack_require__(651); +var define = __webpack_require__(848); -var implementation = __webpack_require__(900); -var getPolyfill = __webpack_require__(901); -var shim = __webpack_require__(902); +var implementation = __webpack_require__(898); +var getPolyfill = __webpack_require__(899); +var shim = __webpack_require__(900); var boundTrim = callBind(getPolyfill()); @@ -147478,15 +147522,15 @@ module.exports = boundTrim; /***/ }), -/* 900 */ +/* 898 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var RequireObjectCoercible = __webpack_require__(854); -var ToString = __webpack_require__(889); -var callBound = __webpack_require__(638); +var RequireObjectCoercible = __webpack_require__(852); +var ToString = __webpack_require__(887); +var callBound = __webpack_require__(650); var $replace = callBound('String.prototype.replace'); /* eslint-disable no-control-regex */ @@ -147501,13 +147545,13 @@ module.exports = function trim() { /***/ }), -/* 901 */ +/* 899 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var implementation = __webpack_require__(900); +var implementation = __webpack_require__(898); var zeroWidthSpace = '\u200b'; @@ -147520,14 +147564,14 @@ module.exports = function getPolyfill() { /***/ }), -/* 902 */ +/* 900 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var define = __webpack_require__(850); -var getPolyfill = __webpack_require__(901); +var define = __webpack_require__(848); +var getPolyfill = __webpack_require__(899); module.exports = function shimStringTrim() { var polyfill = getPolyfill(); @@ -147541,12 +147585,12 @@ module.exports = function shimStringTrim() { /***/ }), -/* 903 */ +/* 901 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { var map = { - "./en.json": 904, - "./fr.json": 905 + "./en.json": 902, + "./fr.json": 903 }; @@ -147567,24 +147611,24 @@ webpackContext.keys = function webpackContextKeys() { }; webpackContext.resolve = webpackContextResolve; module.exports = webpackContext; -webpackContext.id = 903; +webpackContext.id = 901; /***/ }), -/* 904 */ +/* 902 */ /***/ ((module) => { "use strict"; module.exports = JSON.parse('{"Scan":{"scan_a_doc":"Scan a doc","save_doc":"Save the doc","filename":"Filename","save":"Save","cancel":"Cancel","qualify":"Describe","apply":"Apply","error":{"offline":"You are currently offline and you can\'t use this functionality. Please, try again later.","uploading":"You are already uploading a file. Please wait until the end of this upload and try again.","generic":"Something went wrong. Please try again."},"successful":{"qualified_ok":"You just have successfully described your file! "},"items":{"identity":"Identity","family":"Family","work_study":"Work & Study","health":"Health","home":"Home","transport":"Transport","invoice":"Invoice","others":"Others","identity_photo":"Identity photo","national_id_card":"ID card","passport":"Passeport","residence_permit":"Residence permit","family_record_book":"Family record book","birth_certificate":"Birth certificate","citizen_registration_certificate":"Certificate of citizen registration","driver_license":"Driving license","other_identity_document":"Other document of identity","wedding":"Wedding contract","pacs":"Civil union","divorce":"Divorce","large_family_card":" Large Family Card","caf":"Social benefit rate","payment_proof_family_allowance":"family allowance payment proof","other_family_document":"Other family document","diploma":"Diploma","work_contract":"Work contract","pay_sheet":"Pay sheet","unemployment_benefit":"Unemployment benefit","pension":"Pension","other_revenue":"Other revenues","gradebook":"Gradebook","student_card":"Student card","school_attendance_certificate":"Certificate of school attendance","resume":"Resume","motivation_letter":"Motivation letter","other_work_document":"Other work document","health_book":"Health book","health_certificate":"Health/Vaccination certificate","disability_recognition":"Recognition of disability","pregnancy_medical_certificate":"Certificate of pregnancy","national_health_insurance_card":"National health insurance card","national_health_insurance_right_certificate":"National health insurance right certificate","health_insurance_card":"Insurance card","prescription":"Prescription","health_invoice":"Health invoice","other_health_document":"Other health document","vehicle_registration":"Vehicle registration","car_insurance":"Car insurance certificate","mechanic_invoice":"Repair bill","transport_invoice":"Transport invoice","other_transport_document":"Other transport document","phone_invoice":"Phone invoice","isp_invoice":"ISP invoice","telecom_invoice":"Telecom invoice","energy_invoice":"Energy invoice","water_invoice":"Water invoice","web_service_invoice":"Web service invoice","appliance_invoice":"Appliance invoice","restaurant_invoice":"Restaurant invoice","grocery_invoice":"Grocery invoice","house_sale_agreeement":"House sale agreement","building_permit":"Building permit","technical_diagnostic_record":"Technical diagnostic record","lease":"Lease","house_insurance":"Home insurance","unfit_for_habitation_declaration":"Declaration of unfit for habitation","rent_receipt":"Rent receipt","accommodation_proof":"Proof of accommodation","work_quote":"Work quote","work_invoice":"Work invoice","other_house_document":"Other house document","tax_return":"Tax return","tax_notice":"Tax notice","tax_timetable":"Payment Plans Installment Agreements","receipt":"Receipt","other_tax_document":"Other tax document","bank_details":"IBAN","bank_statement":"Bank statement","loan_agreement":"Loan agreement","other_bank_document":"Other banking document","invoices":"Invoices","personal_sporting_licence":"Sporting licence","other_invoice":"Other invoice","other_activity_document":"Other sports document"},"themes":{"identity":"Identity","family":"Family","work_study":"Work & Study","health":"Health","home":"Home","transport":"Transport","invoice":"Invoice","others":"Others","undefined":"Undefined","finance":"Finance","activity":"Activities"}}}'); /***/ }), -/* 905 */ +/* 903 */ /***/ ((module) => { "use strict"; module.exports = JSON.parse('{"Scan":{"scan_a_doc":"Numériser un doc","save_doc":"Enregistrer le document","filename":"Nom du fichier","save":"Sauvegarder","cancel":"Annuler","qualify":"Qualifier","apply":"Appliquer","error":{"offline":"Vous êtes actuellement déconnecté, vous ne pouvez donc pas utiliser cette fonctionnalité. Connectez-vous à internet et recommencez. ","uploading":"Vous avez déjà un fichier en cours de téléchargement. Attendez la fin et recommencez.","generic":"Un problème est survenu. Veuillez réessayer. "},"successful":{"qualified_ok":"Vous venez de qualifier votre fichier avec succès !"},"items":{"identity":"Identité","family":"Famille","work_study":"Travail & Études","health":"Santé","home":"Logement","transport":"Transport","invoice":"Factures","others":"Autres","identity_photo":"Photo d\'identité","national_id_card":"Carte d\'identité","passport":"Passeport","residence_permit":"Titre de séjour","family_record_book":"Livret de famille","birth_certificate":"Certificat de naissance","citizen_registration_certificate":"Attestation de recensement citoyen","driver_license":"Permis","other_identity_document":"Autre document d\'identité","wedding":"Contrat de mariage","pacs":"Attestation de PACS","divorce":"Attestation de divorce","large_family_card":"Carte famille nombreuse","caf":"Attestation de quotient familial (CAF)","payment_proof_family_allowance":"Attestation de paiement CAF","other_family_document":"Autre document de famille","diploma":"Diplôme","work_contract":"Contrat de travail","pay_sheet":"Fiche de paie","unemployment_benefit":"Allocations chômage","pension":"Retraite","other_revenue":"Autres revenus","gradebook":"Bulletin de notes","student_card":"Carte d\'étudiant","school_attendance_certificate":"Certificat de scolarité","resume":"CV","motivation_letter":"Lettre de motivation","other_work_document":"Autre document de travail","health_book":"Carnet de santé","health_certificate":"Certificat de santé/vaccination","work_disability_recognition":"Reconnaissance de handicap - RQTH","pregnancy_medical_certificate":"Certificat de grossesse","national_health_insurance_card":"Carte vitale","national_health_insurance_right_certificate":"Attestation de droits de l\'Assurance Maladie (vitale)","health_insurance_card":"Carte de mutuelle","prescription":"Ordonnance","health_invoice":"Facture médicale","other_health_document":"Autre document de santé","vehicle_registration":"Carte grise","car_insurance":"Attestation d\'assurance auto","mechanic_invoice":"Facture de réparation","transport_invoice":"Facture de transport","other_transport_document":"Autre document de transport","phone_invoice":"Facture de téléphone","isp_invoice":"Facture d\'internet","telecom_invoice":"Facture de télécom","energy_invoice":"Facture d\'énergie","water_invoice":"Facture d\'eau","web_service_invoice":"Facture de service web","appliance_invoice":"Facture d\'électroménager","restaurant_invoice":"Facture de restaurant","grocery_invoice":"Facture de courses","house_sale_agreeement":"Compromis de vente","building_permit":"Permis de construire","technical_diagnostic_record":"Dossier de diagnostic technique","lease":"Bail","unfit_for_habitation_declaration":"Arrêté d\'insalubrité","house_insurance":"Assurance logement","rent_receipt":"Quittance de loyer","accommodation_proof":"Attestation d\'hébergement","work_quote":"Devis de travaux","work_invoice":"Facture de travaux","other_house_document":"Autre document de logement","tax_return":"Impôts - Déclaration de revenus","tax_notice":"Impôts - Avis d\'imposition","tax_timetable":"Impôts - Echéancier","receipt":"Accusé de réception","other_tax_document":"Impôts - Autre document","bank_details":"IBAN","bank_statement":"Relevé de compte","loan_agreement":"Contrat de prêt","other_bank_document":"Autre document bancaire","invoices":"Factures","personal_sporting_licence":"Licences sportives","other_invoice":"Autre facture","other_activity_document":"Autre document sportif"},"themes":{"identity":"Identité","family":"Famille","work_study":"Travail & Études","health":"Santé","home":"Logement","transport":"Transport","invoice":"Factures","others":"Autres","undefined":"Indéfini","finance":"Finances","activity":"Activités & loisirs"}}}'); /***/ }), -/* 906 */ +/* 904 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; @@ -147595,9 +147639,9 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.themesList = void 0; -var _qualification = __webpack_require__(836); +var _qualification = __webpack_require__(834); -var _types = __webpack_require__(610); +var _types = __webpack_require__(622); /** * @@ -147719,7 +147763,7 @@ var themesList = [{ exports.themesList = themesList; /***/ }), -/* 907 */ +/* 905 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; @@ -147730,9 +147774,9 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.getThemeByItem = void 0; -var _types = __webpack_require__(610); +var _types = __webpack_require__(622); -var _documentTypeData = __webpack_require__(906); +var _documentTypeData = __webpack_require__(904); /** * @param {QualificationAttributes} item - Qualification item @@ -147766,26 +147810,26 @@ var getThemeByItem = function getThemeByItem(item) { exports.getThemeByItem = getThemeByItem; /***/ }), -/* 908 */ +/* 906 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -var _interopRequireDefault = __webpack_require__(512); +var _interopRequireDefault = __webpack_require__(524); Object.defineProperty(exports, "__esModule", ({ value: true })); exports.fetchTimeSeriesByIntervalAndSource = exports.saveTimeSeries = void 0; -var _regenerator = _interopRequireDefault(__webpack_require__(527)); +var _regenerator = _interopRequireDefault(__webpack_require__(539)); -var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(529)); +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); -var _dsl = __webpack_require__(607); +var _dsl = __webpack_require__(619); -var _types = __webpack_require__(610); +var _types = __webpack_require__(622); var validateTimeSeriesFormat = function validateTimeSeriesFormat(timeseries) { if (!timeseries.startDate || !timeseries.endDate) { @@ -147927,6 +147971,203 @@ var fetchTimeSeriesByIntervalAndSource = /*#__PURE__*/function () { exports.fetchTimeSeriesByIntervalAndSource = fetchTimeSeriesByIntervalAndSource; +/***/ }), +/* 907 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(524); + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getSharingLink = void 0; + +var _regenerator = _interopRequireDefault(__webpack_require__(539)); + +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); + +var _const = __webpack_require__(697); + +var _CozyClient = _interopRequireDefault(__webpack_require__(525)); + +var _helpers = __webpack_require__(768); + +/** + * Generate Sharing link for one or many files + * + * @param {CozyClient} client - Instance of CozyClient + * @param {string[]} filesIds - Array of io.cozy.files ids + * @param {boolean} [isFlatDomain] - + * @returns {Promise<string>} Shared link + */ +var getSharingLink = /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, filesIds, isFlatDomain) { + var _sharedLink$attribute, _sharedLink$attribute2; + + var PERMS, _yield$client$save, sharedLink, webLink; + + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + PERMS = { + _type: _const.DOCTYPE_PERMISSIONS, + permissions: { + files: { + type: _const.DOCTYPE_FILES, + values: filesIds, + verbs: ['GET'] + } + } + }; + _context.next = 3; + return client.save(PERMS); + + case 3: + _yield$client$save = _context.sent; + sharedLink = _yield$client$save.data; + webLink = (0, _helpers.generateWebLink)({ + cozyUrl: client.getStackClient().uri, + searchParams: [['sharecode', sharedLink === null || sharedLink === void 0 ? void 0 : (_sharedLink$attribute = sharedLink.attributes) === null || _sharedLink$attribute === void 0 ? void 0 : (_sharedLink$attribute2 = _sharedLink$attribute.shortcodes) === null || _sharedLink$attribute2 === void 0 ? void 0 : _sharedLink$attribute2.code]], + pathname: '/public', + slug: 'drive', + subDomainType: isFlatDomain ? 'flat' : 'nested' + }); + return _context.abrupt("return", webLink); + + case 7: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function getSharingLink(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +exports.getSharingLink = getSharingLink; + +/***/ }), +/* 908 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(524); + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.sendMeasureToDACC = exports.checkMeasureParams = void 0; + +var _regenerator = _interopRequireDefault(__webpack_require__(539)); + +var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(541)); + +var _cozyLogger = _interopRequireDefault(__webpack_require__(354)); + +var _types = __webpack_require__(622); + +/** + * Throw an errror if a DACC parameter is incorrect. + * + * @param { DACCMeasure} measure - The DACC measure + */ +var checkMeasureParams = function checkMeasureParams(measure) { + var createdBy = measure.createdBy, + measureName = measure.measureName, + startDate = measure.startDate, + value = measure.value, + group1 = measure.group1, + group2 = measure.group2, + group3 = measure.group3; + + if (!createdBy || typeof createdBy !== 'string') { + throw new Error('Missing or wrong type parameter: createdBy'); + } + + if (!measureName || typeof measureName !== 'string') { + throw new Error('Missing or wrong type parameter: measureName'); + } + + if (!startDate) { + throw new Error('Missing parameter: startDate'); + } + + var parsedDate = new Date(Date.parse(startDate)); + + if (!parsedDate.toISOString().startsWith(startDate)) { + throw new Error('Date should be in YYYY-MM-DD format'); + } + + if (typeof value !== 'number') { + throw new Error('Missing or wrong type parameter: value'); + } + + if (group1 && (typeof group1 !== 'object' || Object.keys(group1).length === 0) || group2 && (typeof group2 !== 'object' || Object.keys(group2).length === 0) || group3 && (typeof group3 !== 'object' || Object.keys(group3).length === 0)) { + throw new Error('Groups should be key-value objects'); + } + + if (group3 && (!group2 || !group1) || group2 && !group1) { + throw new Error('Group order must be respected'); + } +}; +/** + * Send measures to a DACC through a remote doctype + * + * @param {object} client - The CozyClient instance + * @param {string} remoteDoctype - The remote doctype to use + * @param {DACCMeasure} measure - The DACC measure + */ + + +exports.checkMeasureParams = checkMeasureParams; + +var sendMeasureToDACC = /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, remoteDoctype, measure) { + return _regenerator.default.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.prev = 0; + checkMeasureParams(measure); + _context.next = 4; + return client.getStackClient().fetchJSON('POST', "/remote/".concat(remoteDoctype), { + data: JSON.stringify(measure) + }); + + case 4: + _context.next = 10; + break; + + case 6: + _context.prev = 6; + _context.t0 = _context["catch"](0); + (0, _cozyLogger.default)('error', "Error while sending measure to remote doctype: ".concat(_context.t0.message)); + throw _context.t0; + + case 10: + case "end": + return _context.stop(); + } + } + }, _callee, null, [[0, 6]]); + })); + + return function sendMeasureToDACC(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +}(); + +exports.sendMeasureToDACC = sendMeasureToDACC; + /***/ }), /* 909 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { @@ -148006,7 +148247,7 @@ const fs = __webpack_require__(149); const path = __webpack_require__(142); -const log = (__webpack_require__(342).namespace)('cozy-client-js-stub'); +const log = (__webpack_require__(354).namespace)('cozy-client-js-stub'); const mimetypes = __webpack_require__(139); @@ -148014,7 +148255,7 @@ const low = __webpack_require__(911); const lodashId = __webpack_require__(913); -const get = __webpack_require__(358); +const get = __webpack_require__(370); const FileSync = __webpack_require__(914); @@ -148028,7 +148269,7 @@ const sleep = (__webpack_require__(64).promisify)(global.setTimeout); const { models -} = __webpack_require__(509); +} = __webpack_require__(521); const newCozyClient = { models @@ -148382,7 +148623,7 @@ async function waitForFileEnd(file, finalPath, writeStream) { "use strict"; -var lodash = __webpack_require__(837); +var lodash = __webpack_require__(835); var isPromise = __webpack_require__(912); module.exports = function (adapter) { @@ -154373,8 +154614,8 @@ module.exports = range; /***/ ((module, __unused_webpack_exports, __webpack_require__) => { var baseRange = __webpack_require__(961), - isIterateeCall = __webpack_require__(749), - toFinite = __webpack_require__(625); + isIterateeCall = __webpack_require__(761), + toFinite = __webpack_require__(637); /** * Creates a `_.range` or `_.rangeRight` function. @@ -173308,7 +173549,7 @@ const { createModel: createLocalModel } = __webpack_require__(1237); -const logger = __webpack_require__(342); +const logger = __webpack_require__(354); const log = logger.namespace('categorization'); /** @@ -173348,7 +173589,7 @@ const log = logger.namespace('categorization'); * } */ -async function createCategorizer(options) { +async function createCategorizer(options = {}) { const { useGlobalModel = true, customTransactionFetcher, @@ -173595,7 +173836,7 @@ const { const maxBy = __webpack_require__(1234); -const logger = __webpack_require__(342); +const logger = __webpack_require__(354); const log = logger.namespace('categorization/globalModel'); @@ -173638,7 +173879,7 @@ module.exports = { /* 1230 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const cozyClient = __webpack_require__(473); +const cozyClient = __webpack_require__(485); async function fetchParameters() { const parameters = await cozyClient.fetchJSON('GET', '/remote/assets/bank_classifier_nb_and_voc'); @@ -178993,7 +179234,7 @@ PI = new Decimal(PI); var baseExtremum = __webpack_require__(1235), baseGt = __webpack_require__(1236), - baseIteratee = __webpack_require__(401); + baseIteratee = __webpack_require__(413); /** * This method is like `_.max` except that it accepts `iteratee` which is @@ -179031,7 +179272,7 @@ module.exports = maxBy; /* 1235 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var isSymbol = __webpack_require__(362); +var isSymbol = __webpack_require__(374); /** * The base implementation of methods like `_.max` and `_.min` which accepts a @@ -179116,7 +179357,7 @@ const { const maxBy = __webpack_require__(1234); -const logger = __webpack_require__(342); +const logger = __webpack_require__(354); const { LOCAL_MODEL_CATEG_FALLBACK, @@ -179204,7 +179445,7 @@ const { getLabelWithTags } = __webpack_require__(1227); -const logger = __webpack_require__(342); +const logger = __webpack_require__(354); const log = logger.namespace('categorization/localModel/classifier'); const ALPHA_MIN = 2; @@ -179348,11 +179589,11 @@ module.exports = { /* 1240 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const cozyClient = __webpack_require__(473); +const cozyClient = __webpack_require__(485); const { Q -} = __webpack_require__(509); +} = __webpack_require__(521); async function fetchTransactionsWithManualCat() { const client = cozyClient.new; @@ -179376,7 +179617,7 @@ module.exports = { /* 1241 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const uniq = __webpack_require__(612); +const uniq = __webpack_require__(624); const getUniqueCategories = transactions => { return uniq(transactions.map(t => t.manualCategoryId)); @@ -179420,7 +179661,7 @@ module.exports = { /* 1243 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const log = (__webpack_require__(342).namespace)('cozy-konnector-libs'); +const log = (__webpack_require__(354).namespace)('cozy-konnector-libs'); module.exports = log; @@ -179428,13 +179669,13 @@ module.exports = log; /* 1244 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const cozy = __webpack_require__(473); +const cozy = __webpack_require__(485); -const log = (__webpack_require__(342).namespace)('BaseKonnector'); +const log = (__webpack_require__(354).namespace)('BaseKonnector'); const { Secret -} = __webpack_require__(342); +} = __webpack_require__(354); const manifest = __webpack_require__(909); @@ -179444,14 +179685,16 @@ const saveFiles = __webpack_require__(1246); const signin = __webpack_require__(1286); -const get = __webpack_require__(358); +const get = __webpack_require__(370); -const omit = __webpack_require__(613); +const omit = __webpack_require__(625); const updateOrCreate = __webpack_require__(1289); const saveIdentity = __webpack_require__(1290); +const fs = (__webpack_require__(149).promises); + const { wrapIfSentrySetUp, captureExceptionAndDie @@ -179604,6 +179847,40 @@ class BaseKonnector { throw new Error('CANNOT_FIND_ACCOUNT'); } } + /** + * Read an eventual payload from COZY_PAYLOAD env var, wether it is a JSON string or a reference + * to a file containing a JSON string + * + * @returns Promise<{Object|null}> result of JSON.parse from the JSON string or null if no payload + */ + + + async readPayload() { + const cozyPayload = process.env.COZY_PAYLOAD; + + if (cozyPayload == null) { + return null; + } + + const isFileReference = get(cozyPayload, '[0]') === '@'; + + if (isFileReference) { + const filePath = cozyPayload.substr(1); + + try { + const fileContent = await fs.readFile(filePath); + return JSON.parse(fileContent); + } catch (err) { + throw new Error(`Error while reading file ${filePath} payload: ${err.message}`); + } + } else { + try { + return JSON.parse(cozyPayload); + } catch (err) { + throw new Error('Could not parse JSON in COZY_PAYLOAD: ' + cozyPayload); + } + } + } /** * Initializes konnector attributes that will be used during its lifetime * @@ -179969,21 +180246,21 @@ module.exports = BaseKonnector; * * @module saveBills */ -const utils = __webpack_require__(472); +const utils = __webpack_require__(484); const saveFiles = __webpack_require__(1246); -const hydrateAndFilter = __webpack_require__(341); +const hydrateAndFilter = __webpack_require__(353); const addData = __webpack_require__(1266); -const log = (__webpack_require__(342).namespace)('saveBills'); +const log = (__webpack_require__(354).namespace)('saveBills'); const linkBankOperations = __webpack_require__(1267); const DOCTYPE = 'io.cozy.bills'; -const _ = __webpack_require__(837); +const _ = __webpack_require__(835); const manifest = __webpack_require__(909); @@ -180274,19 +180551,19 @@ const path = __webpack_require__(142); const requestFactory = __webpack_require__(2); -const omit = __webpack_require__(613); +const omit = __webpack_require__(625); -const get = __webpack_require__(358); +const get = __webpack_require__(370); -const log = (__webpack_require__(342).namespace)('saveFiles'); +const log = (__webpack_require__(354).namespace)('saveFiles'); const manifest = __webpack_require__(909); -const cozy = __webpack_require__(473); +const cozy = __webpack_require__(485); const { queryAll -} = __webpack_require__(472); +} = __webpack_require__(484); const mkdirp = __webpack_require__(1249); @@ -181099,7 +181376,7 @@ const { join } = (__webpack_require__(142).posix); -const cozyClient = __webpack_require__(473); +const cozyClient = __webpack_require__(485); /** * Creates a directory and its missing ancestors as needed. * @@ -184444,9 +184721,9 @@ module.exports = { */ const bluebird = __webpack_require__(5); -const omit = __webpack_require__(613); +const omit = __webpack_require__(625); -const log = (__webpack_require__(342).namespace)('addData'); +const log = (__webpack_require__(354).namespace)('addData'); const { getCozyMetadata @@ -184485,7 +184762,7 @@ const { const addData = (entries, doctype, options = {}) => { - const cozy = __webpack_require__(473); + const cozy = __webpack_require__(485); return bluebird.mapSeries(entries, async entry => { log('debug', entry, 'Adding this entry'); @@ -184517,7 +184794,7 @@ module.exports = addData; */ const bluebird = __webpack_require__(5); -const log = (__webpack_require__(342).namespace)('linkBankOperations'); +const log = (__webpack_require__(354).namespace)('linkBankOperations'); const { findDebitOperation, @@ -184528,9 +184805,9 @@ const fs = __webpack_require__(149); const defaults = __webpack_require__(1279); -const groupBy = __webpack_require__(724); +const groupBy = __webpack_require__(736); -const flatten = __webpack_require__(540); +const flatten = __webpack_require__(552); const sumBy = __webpack_require__(1275); @@ -184540,7 +184817,7 @@ const { format } = __webpack_require__(962); -const cozyClient = __webpack_require__(473); +const cozyClient = __webpack_require__(485); const DOCTYPE_OPERATIONS = 'io.cozy.bank.operations'; const DEFAULT_AMOUNT_DELTA = 0.001; @@ -184842,7 +185119,7 @@ const linkBankOperations = async (bills, doctype, fields, options = {}) => { options.identifiers = [fields.bank_identifier]; } - const cozyClient = __webpack_require__(473); + const cozyClient = __webpack_require__(485); const linker = new Linker(cozyClient); @@ -185069,10 +185346,10 @@ module.exports = { /* 1270 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseIndexOf = __webpack_require__(465), - isArrayLike = __webpack_require__(446), +var baseIndexOf = __webpack_require__(477), + isArrayLike = __webpack_require__(458), isString = __webpack_require__(54), - toInteger = __webpack_require__(624), + toInteger = __webpack_require__(636), values = __webpack_require__(1271); /* Built-in method references for those with the same name as other `lodash` methods. */ @@ -185129,7 +185406,7 @@ module.exports = includes; /***/ ((module, __unused_webpack_exports, __webpack_require__) => { var baseValues = __webpack_require__(1272), - keys = __webpack_require__(429); + keys = __webpack_require__(441); /** * Creates an array of the own enumerable string keyed property values of `object`. @@ -185168,7 +185445,7 @@ module.exports = values; /* 1272 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var arrayMap = __webpack_require__(398); +var arrayMap = __webpack_require__(410); /** * The base implementation of `_.values` and `_.valuesIn` which creates an @@ -185193,11 +185470,11 @@ module.exports = baseValues; /* 1273 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var arraySome = __webpack_require__(416), - baseIteratee = __webpack_require__(401), +var arraySome = __webpack_require__(428), + baseIteratee = __webpack_require__(413), baseSome = __webpack_require__(1274), isArray = __webpack_require__(55), - isIterateeCall = __webpack_require__(749); + isIterateeCall = __webpack_require__(761); /** * Checks if `predicate` returns truthy for **any** element of `collection`. @@ -185250,7 +185527,7 @@ module.exports = some; /* 1274 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseEach = __webpack_require__(555); +var baseEach = __webpack_require__(567); /** * The base implementation of `_.some` without support for iteratee shorthands. @@ -185278,7 +185555,7 @@ module.exports = baseSome; /* 1275 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseIteratee = __webpack_require__(401), +var baseIteratee = __webpack_require__(413), baseSum = __webpack_require__(1276); /** @@ -185347,7 +185624,7 @@ module.exports = baseSum; /* 1277 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const sortBy = __webpack_require__(840); +const sortBy = __webpack_require__(838); const { addDays, @@ -185526,10 +185803,10 @@ module.exports = { /* 1279 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseRest = __webpack_require__(544), - eq = __webpack_require__(385), - isIterateeCall = __webpack_require__(749), - keysIn = __webpack_require__(567); +var baseRest = __webpack_require__(556), + eq = __webpack_require__(397), + isIterateeCall = __webpack_require__(761), + keysIn = __webpack_require__(579); /** Used for built-in method references. */ var objectProto = Object.prototype; @@ -186077,11 +186354,11 @@ const errors = __webpack_require__(1250); const rerrors = __webpack_require__(1287); -const log = (__webpack_require__(342).namespace)('cozy-konnector-libs'); +const log = (__webpack_require__(354).namespace)('cozy-konnector-libs'); const requestFactory = __webpack_require__(2); -const cheerio = __webpack_require__(255); +const cheerio = __webpack_require__(256); /** * Provides an handy method to log the user in, * on HTML form pages. On success, it resolves to a promise with a parsed body. @@ -186301,11 +186578,11 @@ module.exports = __webpack_require__(44); */ const bluebird = __webpack_require__(5); -const log = (__webpack_require__(342).namespace)('updateOrCreate'); +const log = (__webpack_require__(354).namespace)('updateOrCreate'); -const cozy = __webpack_require__(473); +const cozy = __webpack_require__(485); -const get = __webpack_require__(358); +const get = __webpack_require__(370); const { getCozyMetadata @@ -186363,7 +186640,7 @@ module.exports = updateOrCreate; * * @module saveIdentity */ -const log = (__webpack_require__(342).namespace)('saveIdentity'); +const log = (__webpack_require__(354).namespace)('saveIdentity'); const updateOrCreate = __webpack_require__(1289); /** @@ -186473,7 +186750,7 @@ module.exports = saveIdentity; /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* global __APP_VERSION__ */ -const log = __webpack_require__(342); +const log = __webpack_require__(354); const Raven = __webpack_require__(1292); @@ -186650,7 +186927,7 @@ extend(Raven.prototype, { this.raw_dsn = dsn; this.dsn = utils.parseDSN(dsn); this.name = - options.name || global.process.env.SENTRY_NAME || (__webpack_require__(252).hostname)(); + options.name || global.process.env.SENTRY_NAME || (__webpack_require__(253).hostname)(); this.root = options.root || global.process.cwd(); this.transport = options.transport || transports[this.dsn.protocol]; this.sendTimeout = options.sendTimeout || 1; @@ -189405,7 +189682,7 @@ module.exports = once; /* 1322 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var toInteger = __webpack_require__(624); +var toInteger = __webpack_require__(636); /** Error message constants. */ var FUNC_ERROR_TEXT = 'Expected a function'; @@ -189451,7 +189728,7 @@ module.exports = before; /* 1323 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const log = (__webpack_require__(342).namespace)('Error Interception'); +const log = (__webpack_require__(354).namespace)('Error Interception'); const handleUncaughtException = err => { log('critical', err.message, 'uncaught exception'); @@ -189511,7 +189788,7 @@ module.exports = { /* 1324 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const log = (__webpack_require__(342).namespace)('CookieKonnector'); +const log = (__webpack_require__(354).namespace)('CookieKonnector'); const BaseKonnector = __webpack_require__(1244); @@ -189986,7 +190263,7 @@ module.exports = { const isEqualWith = __webpack_require__(1327); -const omit = __webpack_require__(613); +const omit = __webpack_require__(625); const maybeToISO = date => { try { @@ -190051,7 +190328,7 @@ module.exports = Document; /* 1327 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var baseIsEqual = __webpack_require__(410); +var baseIsEqual = __webpack_require__(422); /** * This method is like `_.isEqual` except that it accepts `customizer` which @@ -190098,7 +190375,7 @@ module.exports = isEqualWith; /* 1328 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -const log = (__webpack_require__(342).namespace)('scrape'); +const log = (__webpack_require__(354).namespace)('scrape'); /** * Declarative scraping. * @@ -190292,7 +190569,7 @@ module.exports = normalizeFilename; * * @module solveCaptcha */ -const log = (__webpack_require__(342).namespace)('solveCaptcha'); +const log = (__webpack_require__(354).namespace)('solveCaptcha'); const errors = __webpack_require__(1250); @@ -194218,7 +194495,7 @@ module.exports = require("tty"); "use strict"; -const os = __webpack_require__(252); +const os = __webpack_require__(253); const tty = __webpack_require__(1363); const hasFlag = __webpack_require__(1365); diff --git a/package.json b/package.json index c0bfb26..eb3c5f8 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "axios": "^0.27.2", - "cozy-konnector-libs": "4.52.1", + "cozy-konnector-libs": "4.54.0", "easy-soap-request": "^4.7.0", "jest": "^28.1.3", "moment": "^2.29.3", @@ -49,8 +49,8 @@ "xml2js": "^0.4.23" }, "devDependencies": { - "cozy-jobs-cli": "1.17.6", - "cozy-konnector-build": "1.3.1", + "cozy-jobs-cli": "1.18.2", + "cozy-konnector-build": "1.3.4", "eslint-config-cozy-app": "1.3.3", "eslint-plugin-prettier": "^4.0.0", "git-directory-deploy": "1.5.1", -- GitLab