cozy-pouch-link 57.6.0 → 57.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -109,8 +109,7 @@ var doNothing = function doNothing(operation) {
109
109
  var result = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
110
110
  };
111
111
  /**
112
- * @typedef {import('cozy-client/src/types').CozyClientDocument} CozyClientDocument
113
- *
112
+ * @typedef {import('cozy-client/src/types').CozyClientDocument & { cozyPouchData: any }} CozyPouchDocument *
114
113
  * @typedef {"idle"|"replicating"} ReplicationStatus
115
114
  */
116
115
 
@@ -929,9 +928,9 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
929
928
  markName,
930
929
  sanitizedDoc,
931
930
  engine,
931
+ pouch,
932
932
  resp,
933
933
  oldDoc,
934
- pouch,
935
934
  _args9 = arguments;
936
935
  return _regenerator.default.wrap(function _callee9$(_context9) {
937
936
  while (1) {
@@ -946,47 +945,60 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
946
945
  _context9.prev = 3;
947
946
  sanitizedDoc.cozyLocalOnly = true;
948
947
  engine = this.getQueryEngineFromDoctype(doc._type);
949
- _context9.next = 8;
948
+ pouch = this.getPouch(doc._type);
949
+ _context9.next = 9;
950
950
  return (0, _helpers2.getExistingDocument)(engine, sanitizedDoc._id);
951
951
 
952
- case 8:
952
+ case 9:
953
953
  resp = _context9.sent;
954
+
955
+ if (!(!(resp !== null && resp !== void 0 && resp.data) || Object.keys(resp === null || resp === void 0 ? void 0 : resp.data).length < 1)) {
956
+ _context9.next = 12;
957
+ break;
958
+ }
959
+
960
+ return _context9.abrupt("return", pouch.put(sanitizedDoc));
961
+
962
+ case 12:
954
963
  oldDoc = (0, jsonapi.sanitizeJsonApi)(resp.data);
955
964
 
956
965
  if (!(0, _helpers2.areDocsEqual)(oldDoc, sanitizedDoc)) {
957
- _context9.next = 12;
966
+ _context9.next = 15;
958
967
  break;
959
968
  }
960
969
 
961
970
  return _context9.abrupt("return");
962
971
 
963
- case 12:
972
+ case 15:
964
973
  sanitizedDoc._rev = oldDoc._rev;
965
- pouch = this.getPouch(doc._type);
966
- _context9.next = 16;
974
+ _context9.next = 18;
967
975
  return pouch.put(sanitizedDoc);
968
976
 
969
- case 16:
970
- _context9.next = 21;
977
+ case 18:
978
+ _context9.next = 24;
971
979
  break;
972
980
 
973
- case 18:
974
- _context9.prev = 18;
981
+ case 20:
982
+ _context9.prev = 20;
975
983
  _context9.t0 = _context9["catch"](3);
984
+
985
+ _logger.default.error("PersistCozyData failed: with ".concat(_context9.t0)); // Do nothing on catch, to avoid throwing a read query
986
+
987
+
976
988
  return _context9.abrupt("return", null);
977
989
 
978
- case 21:
990
+ case 24:
979
991
  this.performanceApi.measure({
980
992
  markName: markName,
981
993
  category: 'CozyPouchLink'
982
994
  });
983
995
 
984
- case 22:
996
+ case 25:
985
997
  case "end":
986
998
  return _context9.stop();
987
999
  }
988
1000
  }
989
- }, _callee9, this, [[3, 18]]);
1001
+ }, _callee9, this, [[3, 20]]);
990
1002
  }));
991
1003
 
992
1004
  function persistCozyData(_x9) {
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.areDocsEqual = exports.getExistingDocument = void 0;
8
+ exports.getCozyPouchData = exports.areDocsEqual = exports.getExistingDocument = void 0;
9
9
 
10
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
11
 
@@ -102,5 +102,27 @@ var areDocsEqual = /*#__PURE__*/function () {
102
102
  return _ref2.apply(this, arguments);
103
103
  };
104
104
  }();
105
+ /**
106
+ * Get cozyPouchData from a document
107
+ *
108
+ * Sometimes, queries are transformed by Collections and they call a dedicated
109
+ * cozy-stack route. When this is the case, we want to be able to replicate the same
110
+ * query from cozy-pouch-link. It is not possible as-is because the received data
111
+ * is not the same as the one stored in the Couch database
112
+ * To handle this, we store the received data in the Pouch with a dedicated id and
113
+ * we store the query result in a `cozyPouchData` attribute
114
+ * So when `cozyPouchData` attribute exists, we know that we want to return its content
115
+ * as the result of the query
116
+ *
117
+ * @param {import('../CozyPouchLink').CozyPouchDocument} doc - The PouchDB doc
118
+ * @returns { Array<import('cozy-client/types/types').CozyClientDocument>} The formatted docs
119
+ */
120
+
121
+
122
+ exports.areDocsEqual = areDocsEqual;
123
+
124
+ var getCozyPouchData = function getCozyPouchData(doc) {
125
+ return doc.cozyPouchData;
126
+ };
105
127
 
106
- exports.areDocsEqual = areDocsEqual;
128
+ exports.getCozyPouchData = getCozyPouchData;
@@ -13,6 +13,8 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
13
13
 
14
14
  var _jsonapi = require("../../jsonapi");
15
15
 
16
+ var _helpers = require("../helpers");
17
+
16
18
  var MANGO_TO_SQL_OP = {
17
19
  $eq: '=',
18
20
  $ne: '!=',
@@ -67,13 +69,22 @@ var parseResults = function parseResults(client, result, doctype) {
67
69
  _ref$skip = _ref.skip,
68
70
  skip = _ref$skip === void 0 ? 0 : _ref$skip,
69
71
  _ref$limit = _ref.limit,
70
- limit = _ref$limit === void 0 ? null : _ref$limit;
72
+ limit = _ref$limit === void 0 ? -1 : _ref$limit;
71
73
 
72
74
  var parsedResults = [];
73
75
 
74
76
  for (var i = 0; i < result.rows.length; i++) {
75
77
  var item = result.rows.item(i);
76
- var doc = JSON.parse(item['data']);
78
+ var doc = JSON.parse(item['data']); // Handle special case for docs with `cozyPouchData`
79
+
80
+ var cozyPouchData = (0, _helpers.getCozyPouchData)(doc);
81
+
82
+ if (cozyPouchData) {
83
+ return {
84
+ data: cozyPouchData
85
+ };
86
+ }
87
+
77
88
  doc._id = item.doc_id;
78
89
  doc._rev = item.rev;
79
90
  doc._type = doctype;
@@ -105,7 +116,12 @@ var parseResults = function parseResults(client, result, doctype) {
105
116
  // query should have less results than the limit, thanks to the offset
106
117
 
107
118
 
108
- var next = limit ? parsedResults.length >= limit : false;
119
+ var next = false;
120
+
121
+ if (limit !== -1 && parsedResults.length >= limit) {
122
+ next = true;
123
+ }
124
+
109
125
  return {
110
126
  data: parsedResults,
111
127
  meta: {
@@ -225,12 +241,13 @@ var makeSQLQueryFromMango = function makeSQLQueryFromMango(_ref2) {
225
241
  var selector = _ref2.selector,
226
242
  sort = _ref2.sort,
227
243
  indexName = _ref2.indexName,
228
- limit = _ref2.limit,
244
+ _ref2$limit = _ref2.limit,
245
+ limit = _ref2$limit === void 0 ? -1 : _ref2$limit,
229
246
  _ref2$skip = _ref2.skip,
230
247
  skip = _ref2$skip === void 0 ? 0 : _ref2$skip;
231
248
  var whereClause = makeWhereClause(selector);
232
249
  var sortClause = makeSortClause(sort);
233
- var sql = ["SELECT json AS data, doc_id, rev", "FROM 'by-sequence' INDEXED BY ".concat(indexName), "WHERE ".concat(whereClause), "LIMIT ".concat(limit)].join(' ');
250
+ var sql = ["SELECT json AS data, doc_id, rev", "FROM 'by-sequence' INDEXED BY ".concat(indexName), "WHERE ".concat(whereClause)].join(' ');
234
251
 
235
252
  if (skip > 0) {
236
253
  sql += " OFFSET ".concat(skip);
@@ -240,6 +257,7 @@ var makeSQLQueryFromMango = function makeSQLQueryFromMango(_ref2) {
240
257
  sql += " ORDER BY ".concat(sortClause);
241
258
  }
242
259
 
260
+ sql += " LIMIT ".concat(limit);
243
261
  sql += ';';
244
262
  return sql;
245
263
  };
@@ -382,27 +400,13 @@ exports.deleteIndex = deleteIndex;
382
400
 
383
401
  var executeSQL = /*#__PURE__*/function () {
384
402
  var _ref8 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(db, sql) {
385
- var result;
386
403
  return _regenerator.default.wrap(function _callee3$(_context3) {
387
404
  while (1) {
388
405
  switch (_context3.prev = _context3.next) {
389
406
  case 0:
390
- _context3.next = 2;
391
- return new Promise(function (resolve, reject) {
392
- db.transaction(function (tx) {
393
- tx.executeAsync(sql).then(function (res) {
394
- resolve(res);
395
- }).catch(function (err) {
396
- reject(err);
397
- });
398
- });
399
- });
400
-
401
- case 2:
402
- result = _context3.sent;
403
- return _context3.abrupt("return", result);
407
+ return _context3.abrupt("return", db.executeAsync(sql));
404
408
 
405
- case 4:
409
+ case 1:
406
410
  case "end":
407
411
  return _context3.stop();
408
412
  }
@@ -171,8 +171,8 @@ describe('makeSQLQueryFromMango', () => {
171
171
  `SELECT json AS data, doc_id, rev`,
172
172
  `FROM 'by-sequence' INDEXED BY by_name`,
173
173
  `WHERE DELETED = 0 AND json_extract(data, '$.date') > '2025-01-01'`,
174
- `LIMIT 100`,
175
- `ORDER BY json_extract(data, '$.date') ASC;`
174
+ `ORDER BY json_extract(data, '$.date') ASC`,
175
+ `LIMIT 100;`
176
176
  ].join(' ')
177
177
  expect(sql).toEqual(expectedSql)
178
178
  })
@@ -193,8 +193,8 @@ describe('makeSQLQueryFromMango', () => {
193
193
  `SELECT json AS data, doc_id, rev`,
194
194
  `FROM 'by-sequence' INDEXED BY by_name`,
195
195
  `WHERE DELETED = 0 AND json_extract(data, '$.date') > '2025-01-01'`,
196
- `LIMIT 200`,
197
- `OFFSET 100;`
196
+ `OFFSET 100`,
197
+ `LIMIT 200;`
198
198
  ].join(' ')
199
199
  expect(sql).toEqual(expectedSql)
200
200
  })
@@ -338,6 +338,62 @@ describe('parseResults', () => {
338
338
  expect(parsed.data.length).toBe(3)
339
339
  })
340
340
 
341
+ it('should set next=true when there is as much docs as specified limit ', () => {
342
+ const result = {
343
+ rows: {
344
+ length: 3,
345
+ item: jest.fn().mockImplementation(i => ({
346
+ data: JSON.stringify({ name: `doc${i}` }),
347
+ doc_id: `id${i}`,
348
+ rev: `rev${i}`
349
+ }))
350
+ }
351
+ }
352
+
353
+ const parsed = parseResults(client, result, doctype, { limit: 3 })
354
+
355
+ expect(parsed.next).toBe(true)
356
+ expect(parsed.data.length).toBe(3)
357
+ })
358
+
359
+ it('should set next=false when there are less docs than specified limit', () => {
360
+ const result = {
361
+ rows: {
362
+ length: 3,
363
+ item: jest.fn().mockImplementation(i => ({
364
+ data: JSON.stringify({ name: `doc${i}` }),
365
+ doc_id: `id${i}`,
366
+ rev: `rev${i}`
367
+ }))
368
+ }
369
+ }
370
+
371
+ const parsed = parseResults(client, result, doctype, { limit: 4 })
372
+
373
+ expect(parsed.next).toBe(false)
374
+ expect(parsed.data.length).toBe(3)
375
+ })
376
+
377
+ it('should set next=false when there is no limit', () => {
378
+ const result = {
379
+ rows: {
380
+ length: 3,
381
+ item: jest.fn().mockImplementation(i => ({
382
+ data: JSON.stringify({ name: `doc${i}` }),
383
+ doc_id: `id${i}`,
384
+ rev: `rev${i}`
385
+ }))
386
+ }
387
+ }
388
+
389
+ const parsed1 = parseResults(client, result, doctype, { limit: -1 })
390
+ expect(parsed1.next).toBe(false)
391
+ expect(parsed1.data.length).toBe(3)
392
+ const parsed2 = parseResults(client, result, doctype)
393
+ expect(parsed2.next).toBe(false)
394
+ expect(parsed2.data.length).toBe(3)
395
+ })
396
+
341
397
  it('should handle single document correctly', () => {
342
398
  const result = {
343
399
  rows: {
@@ -7,14 +7,8 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.default = void 0;
9
9
 
10
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
-
12
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
-
14
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
11
 
16
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
17
-
18
12
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
19
13
 
20
14
  var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
@@ -23,16 +17,6 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
23
17
 
24
18
  var _dbInterface = _interopRequireDefault(require("../dbInterface"));
25
19
 
26
- var _opSqlite = require("@op-engineering/op-sqlite");
27
-
28
- var _sql = require("./sql");
29
-
30
- var _mango = require("../../mango");
31
-
32
- var _errors = require("../../errors");
33
-
34
- var _logger = _interopRequireDefault(require("../../logger"));
35
-
36
20
  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); }; }
37
21
 
38
22
  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; } }
@@ -47,272 +31,10 @@ var SQLiteQueryEngine = /*#__PURE__*/function (_DatabaseQueryEngine) {
47
31
 
48
32
  (0, _classCallCheck2.default)(this, SQLiteQueryEngine);
49
33
  _this = _super.call(this);
50
- _this.db = null;
51
- _this.client = pouchManager === null || pouchManager === void 0 ? void 0 : pouchManager.client;
52
- _this.doctype = doctype;
34
+ throw new Error('SQLiteQueryEngine is not implemented for non-native environments');
53
35
  return _this;
54
36
  }
55
37
 
56
- (0, _createClass2.default)(SQLiteQueryEngine, [{
57
- key: "openDB",
58
- value: function openDB(dbName) {
59
- var fileDbName = "".concat(dbName, ".sqlite");
60
-
61
- try {
62
- this.db = (0, _opSqlite.open)({
63
- name: fileDbName
64
- }); // Create index at db opening if needed
65
-
66
- var docIdIndexSql = (0, _sql.makeSQLCreateDocIDIndex)();
67
- var deletedIndexSql = (0, _sql.makeSQLCreateDeletedIndex)();
68
- (0, _sql.executeSQL)(this.db, docIdIndexSql);
69
- (0, _sql.executeSQL)(this.db, deletedIndexSql);
70
- } catch (err) {
71
- _logger.default.error(err);
72
- }
73
-
74
- return this.db;
75
- }
76
- }, {
77
- key: "allDocs",
78
- value: function () {
79
- var _allDocs = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
80
- var _ref,
81
- _ref$limit,
82
- limit,
83
- _ref$skip,
84
- skip,
85
- sql,
86
- result,
87
- docs,
88
- _args = arguments;
89
-
90
- return _regenerator.default.wrap(function _callee$(_context) {
91
- while (1) {
92
- switch (_context.prev = _context.next) {
93
- case 0:
94
- _ref = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}, _ref$limit = _ref.limit, limit = _ref$limit === void 0 ? null : _ref$limit, _ref$skip = _ref.skip, skip = _ref$skip === void 0 ? 0 : _ref$skip;
95
- _context.prev = 1;
96
- sql = (0, _sql.makeSQLQueryAll)({
97
- limit: limit,
98
- skip: skip
99
- });
100
- _context.next = 5;
101
- return (0, _sql.executeSQL)(this.db, sql);
102
-
103
- case 5:
104
- result = _context.sent;
105
- docs = (0, _sql.parseResults)(this.client, result, this.doctype, {
106
- limit: limit,
107
- skip: skip
108
- });
109
- return _context.abrupt("return", docs);
110
-
111
- case 10:
112
- _context.prev = 10;
113
- _context.t0 = _context["catch"](1);
114
-
115
- _logger.default.error(_context.t0);
116
-
117
- return _context.abrupt("return", null);
118
-
119
- case 14:
120
- case "end":
121
- return _context.stop();
122
- }
123
- }
124
- }, _callee, this, [[1, 10]]);
125
- }));
126
-
127
- function allDocs() {
128
- return _allDocs.apply(this, arguments);
129
- }
130
-
131
- return allDocs;
132
- }()
133
- }, {
134
- key: "getById",
135
- value: function () {
136
- var _getById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) {
137
- var sql, result, doc;
138
- return _regenerator.default.wrap(function _callee2$(_context2) {
139
- while (1) {
140
- switch (_context2.prev = _context2.next) {
141
- case 0:
142
- _context2.prev = 0;
143
- sql = (0, _sql.makeSQLQueryForId)(id);
144
- _context2.next = 4;
145
- return (0, _sql.executeSQL)(this.db, sql);
146
-
147
- case 4:
148
- result = _context2.sent;
149
- doc = (0, _sql.parseResults)(this.client, result, this.doctype, {
150
- isSingleDoc: true
151
- });
152
- return _context2.abrupt("return", doc);
153
-
154
- case 9:
155
- _context2.prev = 9;
156
- _context2.t0 = _context2["catch"](0);
157
-
158
- _logger.default.error(_context2.t0);
159
-
160
- return _context2.abrupt("return", null);
161
-
162
- case 13:
163
- case "end":
164
- return _context2.stop();
165
- }
166
- }
167
- }, _callee2, this, [[0, 9]]);
168
- }));
169
-
170
- function getById(_x) {
171
- return _getById.apply(this, arguments);
172
- }
173
-
174
- return getById;
175
- }()
176
- }, {
177
- key: "getByIds",
178
- value: function () {
179
- var _getByIds = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(ids) {
180
- var sql, result, docs;
181
- return _regenerator.default.wrap(function _callee3$(_context3) {
182
- while (1) {
183
- switch (_context3.prev = _context3.next) {
184
- case 0:
185
- _context3.prev = 0;
186
- sql = (0, _sql.makeSQLQueryForIds)(ids);
187
- _context3.next = 4;
188
- return (0, _sql.executeSQL)(this.db, sql);
189
-
190
- case 4:
191
- result = _context3.sent;
192
- docs = (0, _sql.parseResults)(this.client, result, this.doctype);
193
- return _context3.abrupt("return", docs);
194
-
195
- case 9:
196
- _context3.prev = 9;
197
- _context3.t0 = _context3["catch"](0);
198
-
199
- _logger.default.error(_context3.t0);
200
-
201
- return _context3.abrupt("return", null);
202
-
203
- case 13:
204
- case "end":
205
- return _context3.stop();
206
- }
207
- }
208
- }, _callee3, this, [[0, 9]]);
209
- }));
210
-
211
- function getByIds(_x2) {
212
- return _getByIds.apply(this, arguments);
213
- }
214
-
215
- return getByIds;
216
- }()
217
- }, {
218
- key: "find",
219
- value: function () {
220
- var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(options) {
221
- var selector, sort, partialFilter, limit, recreateIndex, skip, indexedFields, indexName, sql, result, docs;
222
- return _regenerator.default.wrap(function _callee4$(_context4) {
223
- while (1) {
224
- switch (_context4.prev = _context4.next) {
225
- case 0:
226
- selector = options.selector, sort = options.sort, partialFilter = options.partialFilter, limit = options.limit, recreateIndex = options.recreateIndex, skip = options.skip;
227
- indexedFields = options.indexedFields;
228
- indexedFields = (0, _mango.getIndexFields)({
229
- indexedFields: indexedFields,
230
- selector: selector,
231
- sort: sort,
232
- partialFilter: partialFilter
233
- });
234
- indexName = (0, _mango.getIndexName)({
235
- selector: selector,
236
- sort: sort,
237
- partialFilter: partialFilter,
238
- indexedFields: indexedFields
239
- });
240
- sql = (0, _sql.makeSQLQueryFromMango)({
241
- selector: selector,
242
- sort: sort,
243
- indexName: indexName,
244
- limit: limit,
245
- skip: skip
246
- });
247
-
248
- if (!recreateIndex) {
249
- _context4.next = 8;
250
- break;
251
- }
252
-
253
- _context4.next = 8;
254
- return (0, _sql.deleteIndex)(this.db, indexName);
255
-
256
- case 8:
257
- _context4.prev = 8;
258
- _context4.next = 11;
259
- return (0, _sql.executeSQL)(this.db, sql);
260
-
261
- case 11:
262
- result = _context4.sent;
263
- _context4.next = 26;
264
- break;
265
-
266
- case 14:
267
- _context4.prev = 14;
268
- _context4.t0 = _context4["catch"](8);
269
-
270
- if (!(0, _errors.isMissingSQLiteIndexError)(_context4.t0)) {
271
- _context4.next = 24;
272
- break;
273
- }
274
-
275
- _context4.next = 19;
276
- return (0, _sql.createMangoIndex)(this.db, indexName, indexedFields, {
277
- partialFilter: partialFilter
278
- });
279
-
280
- case 19:
281
- _context4.next = 21;
282
- return (0, _sql.executeSQL)(this.db, sql);
283
-
284
- case 21:
285
- result = _context4.sent;
286
- _context4.next = 26;
287
- break;
288
-
289
- case 24:
290
- _logger.default.error(_context4.t0);
291
-
292
- return _context4.abrupt("return", null);
293
-
294
- case 26:
295
- docs = (0, _sql.parseResults)(this.client, result, this.doctype, {
296
- skip: skip,
297
- limit: limit
298
- });
299
- return _context4.abrupt("return", docs);
300
-
301
- case 28:
302
- case "end":
303
- return _context4.stop();
304
- }
305
- }
306
- }, _callee4, this, [[8, 14]]);
307
- }));
308
-
309
- function find(_x3) {
310
- return _find.apply(this, arguments);
311
- }
312
-
313
- return find;
314
- }()
315
- }]);
316
38
  return SQLiteQueryEngine;
317
39
  }(_dbInterface.default);
318
40
 
@@ -0,0 +1,317 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
+
12
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
+
14
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
+
16
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
17
+
18
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
19
+
20
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
21
+
22
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
23
+
24
+ var _dbInterface = _interopRequireDefault(require("../dbInterface"));
25
+
26
+ var _opSqlite = require("@op-engineering/op-sqlite");
27
+
28
+ var _sql = require("./sql");
29
+
30
+ var _mango = require("../../mango");
31
+
32
+ var _errors = require("../../errors");
33
+
34
+ var _logger = _interopRequireDefault(require("../../logger"));
35
+
36
+ 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); }; }
37
+
38
+ 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; } }
39
+
40
+ var SQLiteQueryEngine = /*#__PURE__*/function (_DatabaseQueryEngine) {
41
+ (0, _inherits2.default)(SQLiteQueryEngine, _DatabaseQueryEngine);
42
+
43
+ var _super = _createSuper(SQLiteQueryEngine);
44
+
45
+ function SQLiteQueryEngine(pouchManager, doctype) {
46
+ var _this;
47
+
48
+ (0, _classCallCheck2.default)(this, SQLiteQueryEngine);
49
+ _this = _super.call(this);
50
+ _this.db = null;
51
+ _this.client = pouchManager === null || pouchManager === void 0 ? void 0 : pouchManager.client;
52
+ _this.doctype = doctype;
53
+ return _this;
54
+ }
55
+
56
+ (0, _createClass2.default)(SQLiteQueryEngine, [{
57
+ key: "openDB",
58
+ value: function openDB(dbName) {
59
+ var fileDbName = "".concat(dbName, ".sqlite");
60
+
61
+ try {
62
+ this.db = (0, _opSqlite.open)({
63
+ name: fileDbName
64
+ }); // Create index at db opening if needed
65
+
66
+ var docIdIndexSql = (0, _sql.makeSQLCreateDocIDIndex)();
67
+ var deletedIndexSql = (0, _sql.makeSQLCreateDeletedIndex)();
68
+ (0, _sql.executeSQL)(this.db, docIdIndexSql);
69
+ (0, _sql.executeSQL)(this.db, deletedIndexSql);
70
+ } catch (err) {
71
+ _logger.default.error(err);
72
+ }
73
+ }
74
+ }, {
75
+ key: "allDocs",
76
+ value: function () {
77
+ var _allDocs = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
78
+ var _ref,
79
+ _ref$limit,
80
+ limit,
81
+ _ref$skip,
82
+ skip,
83
+ sql,
84
+ result,
85
+ docs,
86
+ _args = arguments;
87
+
88
+ return _regenerator.default.wrap(function _callee$(_context) {
89
+ while (1) {
90
+ switch (_context.prev = _context.next) {
91
+ case 0:
92
+ _ref = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}, _ref$limit = _ref.limit, limit = _ref$limit === void 0 ? -1 : _ref$limit, _ref$skip = _ref.skip, skip = _ref$skip === void 0 ? 0 : _ref$skip;
93
+ _context.prev = 1;
94
+ sql = (0, _sql.makeSQLQueryAll)({
95
+ limit: limit,
96
+ skip: skip
97
+ });
98
+ _context.next = 5;
99
+ return (0, _sql.executeSQL)(this.db, sql);
100
+
101
+ case 5:
102
+ result = _context.sent;
103
+ docs = (0, _sql.parseResults)(this.client, result, this.doctype, {
104
+ limit: limit,
105
+ skip: skip
106
+ });
107
+ return _context.abrupt("return", docs);
108
+
109
+ case 10:
110
+ _context.prev = 10;
111
+ _context.t0 = _context["catch"](1);
112
+
113
+ _logger.default.error(_context.t0);
114
+
115
+ return _context.abrupt("return", null);
116
+
117
+ case 14:
118
+ case "end":
119
+ return _context.stop();
120
+ }
121
+ }
122
+ }, _callee, this, [[1, 10]]);
123
+ }));
124
+
125
+ function allDocs() {
126
+ return _allDocs.apply(this, arguments);
127
+ }
128
+
129
+ return allDocs;
130
+ }()
131
+ }, {
132
+ key: "getById",
133
+ value: function () {
134
+ var _getById = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(id) {
135
+ var sql, result, doc;
136
+ return _regenerator.default.wrap(function _callee2$(_context2) {
137
+ while (1) {
138
+ switch (_context2.prev = _context2.next) {
139
+ case 0:
140
+ _context2.prev = 0;
141
+ sql = (0, _sql.makeSQLQueryForId)(id);
142
+ _context2.next = 4;
143
+ return (0, _sql.executeSQL)(this.db, sql);
144
+
145
+ case 4:
146
+ result = _context2.sent;
147
+ doc = (0, _sql.parseResults)(this.client, result, this.doctype, {
148
+ isSingleDoc: true
149
+ });
150
+ return _context2.abrupt("return", doc);
151
+
152
+ case 9:
153
+ _context2.prev = 9;
154
+ _context2.t0 = _context2["catch"](0);
155
+
156
+ _logger.default.error(_context2.t0);
157
+
158
+ return _context2.abrupt("return", null);
159
+
160
+ case 13:
161
+ case "end":
162
+ return _context2.stop();
163
+ }
164
+ }
165
+ }, _callee2, this, [[0, 9]]);
166
+ }));
167
+
168
+ function getById(_x) {
169
+ return _getById.apply(this, arguments);
170
+ }
171
+
172
+ return getById;
173
+ }()
174
+ }, {
175
+ key: "getByIds",
176
+ value: function () {
177
+ var _getByIds = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(ids) {
178
+ var sql, result, docs;
179
+ return _regenerator.default.wrap(function _callee3$(_context3) {
180
+ while (1) {
181
+ switch (_context3.prev = _context3.next) {
182
+ case 0:
183
+ _context3.prev = 0;
184
+ sql = (0, _sql.makeSQLQueryForIds)(ids);
185
+ _context3.next = 4;
186
+ return (0, _sql.executeSQL)(this.db, sql);
187
+
188
+ case 4:
189
+ result = _context3.sent;
190
+ docs = (0, _sql.parseResults)(this.client, result, this.doctype);
191
+ return _context3.abrupt("return", docs);
192
+
193
+ case 9:
194
+ _context3.prev = 9;
195
+ _context3.t0 = _context3["catch"](0);
196
+
197
+ _logger.default.error(_context3.t0);
198
+
199
+ return _context3.abrupt("return", null);
200
+
201
+ case 13:
202
+ case "end":
203
+ return _context3.stop();
204
+ }
205
+ }
206
+ }, _callee3, this, [[0, 9]]);
207
+ }));
208
+
209
+ function getByIds(_x2) {
210
+ return _getByIds.apply(this, arguments);
211
+ }
212
+
213
+ return getByIds;
214
+ }()
215
+ }, {
216
+ key: "find",
217
+ value: function () {
218
+ var _find = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(options) {
219
+ var selector, sort, partialFilter, limit, recreateIndex, skip, indexedFields, indexName, sql, result, docs;
220
+ return _regenerator.default.wrap(function _callee4$(_context4) {
221
+ while (1) {
222
+ switch (_context4.prev = _context4.next) {
223
+ case 0:
224
+ selector = options.selector, sort = options.sort, partialFilter = options.partialFilter, limit = options.limit, recreateIndex = options.recreateIndex, skip = options.skip;
225
+ indexedFields = options.indexedFields;
226
+ indexedFields = (0, _mango.getIndexFields)({
227
+ indexedFields: indexedFields,
228
+ selector: selector,
229
+ sort: sort,
230
+ partialFilter: partialFilter
231
+ });
232
+ indexName = (0, _mango.getIndexName)({
233
+ selector: selector,
234
+ sort: sort,
235
+ partialFilter: partialFilter,
236
+ indexedFields: indexedFields
237
+ });
238
+ sql = (0, _sql.makeSQLQueryFromMango)({
239
+ selector: selector,
240
+ sort: sort,
241
+ indexName: indexName,
242
+ limit: limit,
243
+ skip: skip
244
+ });
245
+
246
+ if (!recreateIndex) {
247
+ _context4.next = 8;
248
+ break;
249
+ }
250
+
251
+ _context4.next = 8;
252
+ return (0, _sql.deleteIndex)(this.db, indexName);
253
+
254
+ case 8:
255
+ _context4.prev = 8;
256
+ _context4.next = 11;
257
+ return (0, _sql.executeSQL)(this.db, sql);
258
+
259
+ case 11:
260
+ result = _context4.sent;
261
+ _context4.next = 26;
262
+ break;
263
+
264
+ case 14:
265
+ _context4.prev = 14;
266
+ _context4.t0 = _context4["catch"](8);
267
+
268
+ if (!(0, _errors.isMissingSQLiteIndexError)(_context4.t0)) {
269
+ _context4.next = 24;
270
+ break;
271
+ }
272
+
273
+ _context4.next = 19;
274
+ return (0, _sql.createMangoIndex)(this.db, indexName, indexedFields, {
275
+ partialFilter: partialFilter
276
+ });
277
+
278
+ case 19:
279
+ _context4.next = 21;
280
+ return (0, _sql.executeSQL)(this.db, sql);
281
+
282
+ case 21:
283
+ result = _context4.sent;
284
+ _context4.next = 26;
285
+ break;
286
+
287
+ case 24:
288
+ _logger.default.error(_context4.t0);
289
+
290
+ return _context4.abrupt("return", null);
291
+
292
+ case 26:
293
+ docs = (0, _sql.parseResults)(this.client, result, this.doctype, {
294
+ skip: skip,
295
+ limit: limit
296
+ });
297
+ return _context4.abrupt("return", docs);
298
+
299
+ case 28:
300
+ case "end":
301
+ return _context4.stop();
302
+ }
303
+ }
304
+ }, _callee4, this, [[8, 14]]);
305
+ }));
306
+
307
+ function find(_x3) {
308
+ return _find.apply(this, arguments);
309
+ }
310
+
311
+ return find;
312
+ }()
313
+ }]);
314
+ return SQLiteQueryEngine;
315
+ }(_dbInterface.default);
316
+
317
+ exports.default = SQLiteQueryEngine;
package/dist/jsonapi.js CHANGED
@@ -17,6 +17,8 @@ var _omit = _interopRequireDefault(require("lodash/omit"));
17
17
 
18
18
  var _startsWith = _interopRequireDefault(require("lodash/startsWith"));
19
19
 
20
+ var _helpers = require("./db/helpers");
21
+
20
22
  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; }
21
23
 
22
24
  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; }
@@ -26,7 +28,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
26
28
  *
27
29
  * @param {CozyClient} client - The CozyClient instance
28
30
  * @param {string} doctype - The document's doctype
29
- * @param {Array<import('./CozyPouchLink').CozyClientDocument>} docs - The documents to normalize
31
+ * @param {Array<import('./CozyPouchLink').CozyPouchDocument>} docs - The documents to normalize
30
32
  */
31
33
  var normalizeDocs = function normalizeDocs(client, doctype, docs) {
32
34
  for (var i = docs.length; i >= 0; i--) {
@@ -52,7 +54,7 @@ var normalizeDocs = function normalizeDocs(client, doctype, docs) {
52
54
  *
53
55
  * @param {CozyClient} client - The CozyClient instance
54
56
  * @param {string} doctype - The document's doctype
55
- * @param {import('./CozyPouchLink').CozyClientDocument} doc - The document to normalize
57
+ * @param {import('./CozyPouchLink').CozyPouchDocument} doc - The document to normalize
56
58
  */
57
59
 
58
60
 
@@ -115,19 +117,14 @@ var fromPouchResult = function fromPouchResult(_ref) {
115
117
 
116
118
  if (!res) {
117
119
  return null;
118
- } // Sometimes, queries are transformed by Collections and they call a dedicated
119
- // cozy-stack route. When this is the case, we want to be able to replicate the same
120
- // query from cozy-pouch-link. It is not possible as-is because the received data
121
- // is not the same as the one stored in the Couch database
122
- // To handle this, we store the received data in the Pouch with a dedicated id and
123
- // we store the query result in a `cozyPouchData` attribute
124
- // So when `cozyPouchData` attribute exists, we know that we want to return its content
125
- // as the result of the query
120
+ } // Handle special case for docs with `cozyPouchData`
121
+
126
122
 
123
+ var cozyPouchData = (0, _helpers.getCozyPouchData)(res);
127
124
 
128
- if (res.cozyPouchData) {
125
+ if (cozyPouchData) {
129
126
  return {
130
- data: res.cozyPouchData
127
+ data: cozyPouchData
131
128
  };
132
129
  }
133
130
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-pouch-link",
3
- "version": "57.6.0",
3
+ "version": "57.7.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "types/index.d.ts",
@@ -13,13 +13,14 @@
13
13
  "url": "git+https://github.com/cozy/cozy-client.git"
14
14
  },
15
15
  "dependencies": {
16
- "cozy-client": "^57.6.0",
16
+ "cozy-client": "^57.7.0",
17
17
  "pouchdb-browser": "^7.2.2",
18
18
  "pouchdb-find": "^7.2.2"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@babel/cli": "7.12.8",
22
22
  "@cozy/minilog": "1.0.0",
23
+ "@op-engineering/op-sqlite": "^11.4.8",
23
24
  "cozy-device-helper": "2.7.0",
24
25
  "jest-localstorage-mock": "2.4.19",
25
26
  "parcel": "2.13.3",
@@ -40,5 +41,5 @@
40
41
  "typecheck": "tsc -p tsconfig.json"
41
42
  },
42
43
  "sideEffects": false,
43
- "gitHead": "5a646c30c51b7a93ea7e65d309425799487b1968"
44
+ "gitHead": "4e22dfcf7f2549b631c9777126da3ffad690ca93"
44
45
  }
@@ -1,6 +1,6 @@
1
1
  export function getReplicationURL(uri: any, token: any, doctype: any): string;
2
2
  export default PouchLink;
3
- export type CozyClientDocument = any;
3
+ export type CozyPouchDocument = any;
4
4
  export type ReplicationStatus = "idle" | "replicating";
5
5
  export type PouchLinkOptions = {
6
6
  /**
@@ -41,8 +41,7 @@ export type PouchLinkOptions = {
41
41
  performanceApi?: any;
42
42
  };
43
43
  /**
44
- * @typedef {import('cozy-client/src/types').CozyClientDocument} CozyClientDocument
45
- *
44
+ * @typedef {import('cozy-client/src/types').CozyClientDocument & { cozyPouchData: any }} CozyPouchDocument *
46
45
  * @typedef {"idle"|"replicating"} ReplicationStatus
47
46
  */
48
47
  /**
@@ -1,3 +1,4 @@
1
1
  export function getExistingDocument(queryEngine: DatabaseQueryEngine, id: string, throwIfNotFound?: boolean): Promise<import('./dbInterface').QueryResponseSingleDoc>;
2
2
  export function areDocsEqual(oldDoc: any, newDoc: any): Promise<boolean>;
3
+ export function getCozyPouchData(doc: import('../CozyPouchLink').CozyPouchDocument): Array<import('cozy-client/types/types').CozyClientDocument>;
3
4
  import DatabaseQueryEngine from "./dbInterface";
@@ -2,7 +2,7 @@ export function keepDocWitHighestRev(docs: any): any;
2
2
  export function parseResults(client: any, result: any, doctype: any, { isSingleDoc, skip, limit }?: {
3
3
  isSingleDoc?: boolean;
4
4
  skip?: number;
5
- limit?: any;
5
+ limit?: number;
6
6
  }): {
7
7
  data: any;
8
8
  meta?: undefined;
@@ -23,7 +23,7 @@ export function makeSQLQueryFromMango({ selector, sort, indexName, limit, skip }
23
23
  selector: any;
24
24
  sort: any;
25
25
  indexName: any;
26
- limit: any;
26
+ limit?: number;
27
27
  skip?: number;
28
28
  }): string;
29
29
  export function makeSQLQueryForId(id: any): string;
@@ -1,7 +1,4 @@
1
1
  export default class SQLiteQueryEngine extends DatabaseQueryEngine {
2
2
  constructor(pouchManager: any, doctype: any);
3
- db: any;
4
- client: any;
5
- doctype: any;
6
3
  }
7
4
  import DatabaseQueryEngine from "../dbInterface";
@@ -0,0 +1,7 @@
1
+ export default class SQLiteQueryEngine extends DatabaseQueryEngine {
2
+ constructor(pouchManager: any, doctype: any);
3
+ db: import("@op-engineering/op-sqlite").DB;
4
+ client: any;
5
+ doctype: any;
6
+ }
7
+ import DatabaseQueryEngine from "../dbInterface";
@@ -1,5 +1,5 @@
1
- export function normalizeDocs(client: CozyClient, doctype: string, docs: Array<import('./CozyPouchLink').CozyClientDocument>): void;
2
- export function normalizeDoc(client: CozyClient, doctype: string, doc: any): void;
1
+ export function normalizeDocs(client: CozyClient, doctype: string, docs: Array<import('./CozyPouchLink').CozyPouchDocument>): void;
2
+ export function normalizeDoc(client: CozyClient, doctype: string, doc: import('./CozyPouchLink').CozyPouchDocument): void;
3
3
  export function fromPouchResult({ res, withRows, doctype, client }: {
4
4
  res: any;
5
5
  withRows: any;