couchset 0.2.7 → 0.3.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.
Files changed (108) hide show
  1. package/README.md +284 -153
  2. package/dist/connection/connection.d.ts +68 -0
  3. package/dist/connection/connection.js +485 -0
  4. package/dist/connection/connection.js.map +1 -0
  5. package/dist/connection/env.d.ts +2 -0
  6. package/dist/connection/env.js +16 -0
  7. package/dist/connection/env.js.map +1 -0
  8. package/dist/connection/index.d.ts +3 -0
  9. package/dist/connection/index.js +25 -0
  10. package/dist/connection/index.js.map +1 -0
  11. package/dist/connection/types.d.ts +25 -0
  12. package/dist/connection/types.js +3 -0
  13. package/dist/connection/types.js.map +1 -0
  14. package/dist/database.d.ts +9 -0
  15. package/dist/database.js +196 -0
  16. package/dist/database.js.map +1 -0
  17. package/dist/index.d.ts +18 -6
  18. package/dist/index.js +53 -8
  19. package/dist/index.js.map +1 -1
  20. package/dist/legacy/connection.d.ts +2 -0
  21. package/dist/legacy/connection.js +24 -0
  22. package/dist/legacy/connection.js.map +1 -0
  23. package/dist/legacy/index.d.ts +10 -0
  24. package/dist/legacy/index.js +93 -0
  25. package/dist/legacy/index.js.map +1 -0
  26. package/dist/legacy/model.d.ts +55 -0
  27. package/dist/legacy/model.js +282 -0
  28. package/dist/legacy/model.js.map +1 -0
  29. package/dist/legacy/pagination/index.d.ts +1 -0
  30. package/dist/legacy/pagination/index.js +18 -0
  31. package/dist/legacy/pagination/index.js.map +1 -0
  32. package/dist/legacy/pagination/pagination.d.ts +12 -0
  33. package/dist/legacy/pagination/pagination.js +85 -0
  34. package/dist/legacy/pagination/pagination.js.map +1 -0
  35. package/dist/legacy/search/customQuery.d.ts +13 -0
  36. package/dist/legacy/search/customQuery.js +73 -0
  37. package/dist/legacy/search/customQuery.js.map +1 -0
  38. package/dist/legacy/search/index.d.ts +1 -0
  39. package/dist/legacy/search/index.js +18 -0
  40. package/dist/legacy/search/index.js.map +1 -0
  41. package/dist/model/default-scope.d.ts +10 -0
  42. package/dist/model/default-scope.js +47 -0
  43. package/dist/model/default-scope.js.map +1 -0
  44. package/dist/model/hydrated-document.d.ts +30 -0
  45. package/dist/model/hydrated-document.js +118 -0
  46. package/dist/model/hydrated-document.js.map +1 -0
  47. package/dist/model/include.d.ts +33 -0
  48. package/dist/model/include.js +250 -0
  49. package/dist/model/include.js.map +1 -0
  50. package/dist/model/index.d.ts +137 -51
  51. package/dist/model/index.js +519 -174
  52. package/dist/model/index.js.map +1 -1
  53. package/dist/model/indexes.d.ts +16 -0
  54. package/dist/model/indexes.js +155 -0
  55. package/dist/model/indexes.js.map +1 -0
  56. package/dist/model/keyspace.d.ts +9 -0
  57. package/dist/model/keyspace.js +28 -0
  58. package/dist/model/keyspace.js.map +1 -0
  59. package/dist/model/read-helpers.d.ts +36 -0
  60. package/dist/model/read-helpers.js +275 -0
  61. package/dist/model/read-helpers.js.map +1 -0
  62. package/dist/model/safe-query.d.ts +23 -0
  63. package/dist/model/safe-query.js +138 -0
  64. package/dist/model/safe-query.js.map +1 -0
  65. package/dist/model/ttl.d.ts +9 -0
  66. package/dist/model/ttl.js +73 -0
  67. package/dist/model/ttl.js.map +1 -0
  68. package/dist/model/validation.d.ts +5 -0
  69. package/dist/model/validation.js +104 -0
  70. package/dist/model/validation.js.map +1 -0
  71. package/dist/model/write-helpers.d.ts +31 -0
  72. package/dist/model/write-helpers.js +220 -0
  73. package/dist/model/write-helpers.js.map +1 -0
  74. package/dist/pagination/index.d.ts +1 -0
  75. package/dist/pagination/index.js +1 -0
  76. package/dist/pagination/index.js.map +1 -1
  77. package/dist/pagination/pagination.d.ts +1 -8
  78. package/dist/pagination/pagination.js +16 -29
  79. package/dist/pagination/pagination.js.map +1 -1
  80. package/dist/pagination/safe-pagination.d.ts +15 -0
  81. package/dist/pagination/safe-pagination.js +221 -0
  82. package/dist/pagination/safe-pagination.js.map +1 -0
  83. package/dist/pagination/types.d.ts +11 -0
  84. package/dist/pagination/types.js +3 -0
  85. package/dist/pagination/types.js.map +1 -0
  86. package/dist/search/customQuery.d.ts +10 -3
  87. package/dist/search/customQuery.js +17 -18
  88. package/dist/search/customQuery.js.map +1 -1
  89. package/dist/shared/common.model.js +2 -2
  90. package/dist/shared/common.model.js.map +1 -1
  91. package/dist/timeseries/index.d.ts +1 -0
  92. package/dist/timeseries/index.js +18 -0
  93. package/dist/timeseries/index.js.map +1 -0
  94. package/dist/timeseries/time-series-model.d.ts +60 -0
  95. package/dist/timeseries/time-series-model.js +267 -0
  96. package/dist/timeseries/time-series-model.js.map +1 -0
  97. package/dist/utils/awaitTo.d.ts +1 -1
  98. package/dist/utils/awaitTo.js +1 -1
  99. package/dist/utils/awaitTo.js.map +1 -1
  100. package/docs/beta-migration.md +175 -0
  101. package/legacy/index.js +1 -0
  102. package/legacy/package.json +4 -0
  103. package/next/index.js +1 -0
  104. package/next/package.json +4 -0
  105. package/package.json +13 -8
  106. package/dist/connection.d.ts +0 -42
  107. package/dist/connection.js +0 -156
  108. package/dist/connection.js.map +0 -1
@@ -57,40 +57,152 @@ var __rest = (this && this.__rest) || function (s, e) {
57
57
  }
58
58
  return t;
59
59
  };
60
+ var __read = (this && this.__read) || function (o, n) {
61
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
62
+ if (!m) return o;
63
+ var i = m.call(o), r, ar = [], e;
64
+ try {
65
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
66
+ }
67
+ catch (error) { e = { error: error }; }
68
+ finally {
69
+ try {
70
+ if (r && !r.done && (m = i["return"])) m.call(i);
71
+ }
72
+ finally { if (e) throw e.error; }
73
+ }
74
+ return ar;
75
+ };
76
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
77
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
78
+ if (ar || !(i in from)) {
79
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
80
+ ar[i] = from[i];
81
+ }
82
+ }
83
+ return to.concat(ar || Array.prototype.slice.call(from));
84
+ };
85
+ var __values = (this && this.__values) || function(o) {
86
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
87
+ if (m) return m.call(o);
88
+ if (o && typeof o.length === "number") return {
89
+ next: function () {
90
+ if (o && i >= o.length) o = void 0;
91
+ return { value: o && o[i++], done: !o };
92
+ }
93
+ };
94
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
95
+ };
60
96
  var __importDefault = (this && this.__importDefault) || function (mod) {
61
97
  return (mod && mod.__esModule) ? mod : { "default": mod };
62
98
  };
63
99
  Object.defineProperty(exports, "__esModule", { value: true });
64
100
  exports.Model = void 0;
65
- // import {AutomaticMethodOptions, AutomaticOutput, automateImplementation} from '../automate';
66
- var search_1 = require("../search");
67
101
  var utils_1 = require("../utils");
68
102
  var connection_1 = __importDefault(require("../connection"));
69
- var pagination_1 = require("../pagination");
70
- var uuid_1 = require("../uuid");
103
+ var default_scope_1 = require("./default-scope");
104
+ var read_helpers_1 = require("./read-helpers");
105
+ var keyspace_1 = require("./keyspace");
106
+ var safe_query_1 = require("./safe-query");
107
+ var write_helpers_1 = require("./write-helpers");
108
+ var hydrated_document_1 = require("./hydrated-document");
109
+ var indexes_1 = require("./indexes");
110
+ var validation_1 = require("./validation");
71
111
  var Model = /** @class */ (function () {
72
112
  function Model(name, options) {
73
113
  this.scope = '_default';
114
+ this.defaultWhereMode = 'default';
115
+ this.softDelete = false;
116
+ this.indexes = [];
74
117
  this.schema = {
75
118
  createdAt: 'date',
76
119
  updatedAt: 'date',
77
120
  };
78
- this.graphqlType = null;
79
121
  // this.collection = CouchbaseConnection.Instance.getCollection();
80
122
  this.collectionName = name;
81
123
  if (options) {
82
- this.graphqlType = (options && options.graphqlType) || null;
124
+ var hasScope = Object.prototype.hasOwnProperty.call(options, 'scope');
125
+ var hasCollection = Object.prototype.hasOwnProperty.call(options, 'collection');
83
126
  this.scope = (options && options.scope) || '_default';
84
- this.schema = __assign(__assign({}, ((options && options.schema) || {})), { createdAt: 'date', updatedAt: 'date' });
127
+ this.scopeName = hasScope ? this.scope : undefined;
128
+ this.collectionTargetName = hasCollection
129
+ ? options.collection || '_default'
130
+ : undefined;
131
+ this.softDelete = !!options.softDelete;
132
+ this.defaultWhere = options.defaultWhere;
133
+ this.validateCreateHook = options.validateCreate;
134
+ this.validateReplaceHook = options.validateReplace;
135
+ this.parseHook = options.parse;
136
+ this.dateFields = options.dateFields;
137
+ this.indexes = options.indexes || [];
138
+ this.schema = __assign(__assign(__assign({}, ((options && options.schema) || {})), (0, validation_1.schemaFromDateFields)(options.dateFields)), { createdAt: 'date', updatedAt: 'date' });
139
+ }
140
+ if (this.indexes.length) {
141
+ Model.registeredModels.push(this);
85
142
  }
86
143
  }
87
144
  /**
88
- * Set setGraphqlType
89
- * setGraphqlType
145
+ * Ensure indexes for every constructed model with index declarations.
90
146
  */
91
- Model.prototype.setGraphqlType = function (gqlType) {
92
- this.graphqlType = gqlType;
93
- return this;
147
+ Model.ensureIndexes = function (options) {
148
+ return __awaiter(this, void 0, void 0, function () {
149
+ var queries, seenQueries, _loop_1, _a, _b, model, e_1_1;
150
+ var e_1, _c;
151
+ return __generator(this, function (_d) {
152
+ switch (_d.label) {
153
+ case 0:
154
+ queries = [];
155
+ seenQueries = new Set();
156
+ _loop_1 = function (model) {
157
+ var statements, pending;
158
+ return __generator(this, function (_e) {
159
+ switch (_e.label) {
160
+ case 0: return [4 /*yield*/, model.prepare()];
161
+ case 1:
162
+ _e.sent();
163
+ statements = model.indexStatements(options);
164
+ pending = statements.filter(function (query) { return !seenQueries.has(query); });
165
+ pending.forEach(function (query) { return seenQueries.add(query); });
166
+ return [4 /*yield*/, (0, indexes_1.ensureModelIndexes)(model.couchbaseConnection().cluster, model.keyspace(), model.indexes.filter(function (index, indexPosition) {
167
+ return pending.includes(statements[indexPosition]);
168
+ }), options)];
169
+ case 2:
170
+ _e.sent();
171
+ queries.push.apply(queries, __spreadArray([], __read(pending), false));
172
+ return [2 /*return*/];
173
+ }
174
+ });
175
+ };
176
+ _d.label = 1;
177
+ case 1:
178
+ _d.trys.push([1, 6, 7, 8]);
179
+ _a = __values(Model.registeredModels), _b = _a.next();
180
+ _d.label = 2;
181
+ case 2:
182
+ if (!!_b.done) return [3 /*break*/, 5];
183
+ model = _b.value;
184
+ return [5 /*yield**/, _loop_1(model)];
185
+ case 3:
186
+ _d.sent();
187
+ _d.label = 4;
188
+ case 4:
189
+ _b = _a.next();
190
+ return [3 /*break*/, 2];
191
+ case 5: return [3 /*break*/, 8];
192
+ case 6:
193
+ e_1_1 = _d.sent();
194
+ e_1 = { error: e_1_1 };
195
+ return [3 /*break*/, 8];
196
+ case 7:
197
+ try {
198
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
199
+ }
200
+ finally { if (e_1) throw e_1.error; }
201
+ return [7 /*endfinally*/];
202
+ case 8: return [2 /*return*/, queries];
203
+ }
204
+ });
205
+ });
94
206
  };
95
207
  /**
96
208
  * Refresh and get default collection from CouchbaseConnection
@@ -100,16 +212,70 @@ var Model = /** @class */ (function () {
100
212
  */
101
213
  Model.prototype.fresh = function () {
102
214
  // if couchbase connection has been init
103
- if (connection_1.default.Instance.bucketName) {
104
- this.collection = connection_1.default.Instance.getCollection();
215
+ if (connection_1.default.Instance.isConnected()) {
216
+ var target = this.collectionTarget();
217
+ this.collection = connection_1.default.Instance.getCollection(target.scopeName, target.collectionName);
105
218
  }
106
219
  };
220
+ Model.prototype.prepare = function () {
221
+ return __awaiter(this, void 0, void 0, function () {
222
+ var connection, target;
223
+ return __generator(this, function (_a) {
224
+ switch (_a.label) {
225
+ case 0:
226
+ connection = this.couchbaseConnection();
227
+ if (!!connection.bucket) return [3 /*break*/, 2];
228
+ return [4 /*yield*/, connection.ready()];
229
+ case 1:
230
+ _a.sent();
231
+ _a.label = 2;
232
+ case 2:
233
+ target = this.collectionTarget();
234
+ this.collection = connection.getCollection(target.scopeName, target.collectionName);
235
+ return [2 /*return*/];
236
+ }
237
+ });
238
+ });
239
+ };
240
+ Model.prototype.withConnection = function (operation) {
241
+ return __awaiter(this, void 0, void 0, function () {
242
+ var error_1, connection;
243
+ return __generator(this, function (_a) {
244
+ switch (_a.label) {
245
+ case 0: return [4 /*yield*/, this.prepare()];
246
+ case 1:
247
+ _a.sent();
248
+ _a.label = 2;
249
+ case 2:
250
+ _a.trys.push([2, 4, , 6]);
251
+ return [4 /*yield*/, operation()];
252
+ case 3: return [2 /*return*/, _a.sent()];
253
+ case 4:
254
+ error_1 = _a.sent();
255
+ connection = this.couchbaseConnection();
256
+ if (!connection.shouldReconnect(error_1)) {
257
+ throw error_1;
258
+ }
259
+ connection.markDisconnected(error_1);
260
+ return [4 /*yield*/, this.prepare()];
261
+ case 5:
262
+ _a.sent();
263
+ return [2 /*return*/, operation()];
264
+ case 6: return [2 /*return*/];
265
+ }
266
+ });
267
+ });
268
+ };
107
269
  /** Get this collection
108
270
  * getCollection
109
271
  */
110
272
  Model.prototype.getBucketName = function () {
111
273
  var _a;
112
- return (_a = connection_1.default.Instance) === null || _a === void 0 ? void 0 : _a.getBucket();
274
+ var bucketName = (_a = connection_1.default.Instance) === null || _a === void 0 ? void 0 : _a.getBucket();
275
+ if (!bucketName) {
276
+ throw new Error('couchset is not connected; call couchset(args) first');
277
+ }
278
+ return bucketName;
113
279
  };
114
280
  /** Get this collection
115
281
  * getCollection
@@ -124,215 +290,394 @@ var Model = /** @class */ (function () {
124
290
  this.fresh();
125
291
  return this.collection;
126
292
  };
293
+ Model.prototype.collectionTarget = function () {
294
+ if (!this.scopeName && !this.collectionTargetName) {
295
+ return {};
296
+ }
297
+ return {
298
+ scopeName: this.scopeName || '_default',
299
+ collectionName: this.collectionTargetName || '_default',
300
+ };
301
+ };
302
+ Model.prototype.queryResultKey = function () {
303
+ var target = this.collectionTarget();
304
+ return target.collectionName || this.getBucketName();
305
+ };
306
+ Model.prototype.readContext = function () {
307
+ var _this = this;
308
+ return {
309
+ bucketName: this.keyspace(),
310
+ collectionName: this.collectionName,
311
+ cluster: this.couchbaseConnection().cluster,
312
+ parse: function (data) { return _this.parse(data); },
313
+ resultKey: this.queryResultKey(),
314
+ };
315
+ };
316
+ Model.prototype.readArgs = function (args) {
317
+ if (args === void 0) { args = {}; }
318
+ return (0, default_scope_1.applyDefaultWhere)(args, {
319
+ defaultWhere: this.defaultWhere,
320
+ mode: this.defaultWhereMode,
321
+ softDelete: this.softDelete,
322
+ });
323
+ };
324
+ Model.prototype.writeContext = function () {
325
+ var _this = this;
326
+ return {
327
+ collection: this.getCollection(),
328
+ collectionName: this.collectionName,
329
+ scope: this.scope,
330
+ parse: function (data) { return _this.parse(data); },
331
+ validateCreate: this.validateCreateHook,
332
+ validateReplace: this.validateReplaceHook,
333
+ };
334
+ };
335
+ Model.prototype.cloneWithDefaultWhereMode = function (mode) {
336
+ var options = {
337
+ dateFields: this.dateFields,
338
+ defaultWhere: this.defaultWhere,
339
+ parse: this.parseHook,
340
+ schema: this.schema,
341
+ softDelete: this.softDelete,
342
+ validateCreate: this.validateCreateHook,
343
+ validateReplace: this.validateReplaceHook,
344
+ };
345
+ if (this.scopeName) {
346
+ options.scope = this.scopeName;
347
+ }
348
+ if (this.collectionTargetName) {
349
+ options.collection = this.collectionTargetName;
350
+ }
351
+ var model = new Model(this.collectionName, options);
352
+ model.defaultWhereMode = mode;
353
+ return model;
354
+ };
355
+ /**
356
+ * Return the active bucket as a SQL++ keyspace identifier.
357
+ */
358
+ Model.prototype.bucket = function () {
359
+ return (0, keyspace_1.bucketIdentifier)(this.getBucketName());
360
+ };
361
+ /**
362
+ * Return this model's SQL++ keyspace target.
363
+ */
364
+ Model.prototype.keyspace = function () {
365
+ var target = this.collectionTarget();
366
+ return (0, keyspace_1.keyspaceIdentifier)({
367
+ bucketName: this.getBucketName(),
368
+ scopeName: target.scopeName,
369
+ collectionName: target.collectionName,
370
+ });
371
+ };
372
+ /**
373
+ * Return a SQL++ FROM target for this model's current bucket.
374
+ */
375
+ Model.prototype.from = function (alias) {
376
+ return (0, keyspace_1.fromTarget)(this.keyspace(), alias);
377
+ };
378
+ /**
379
+ * Return CREATE INDEX statements for this model without executing them.
380
+ */
381
+ Model.prototype.indexStatements = function (options) {
382
+ var _this = this;
383
+ return this.indexes.map(function (index) { return (0, indexes_1.buildIndexQuery)(_this.keyspace(), index, options); });
384
+ };
127
385
  /**
128
- * create
386
+ * Create this model's declared indexes if Couchbase does not already have them.
129
387
  */
130
- Model.prototype.create = function (data, options) {
388
+ Model.prototype.ensureIndexes = function (options) {
131
389
  return __awaiter(this, void 0, void 0, function () {
132
- var id, createdData, error_1;
390
+ var _this = this;
133
391
  return __generator(this, function (_a) {
134
- switch (_a.label) {
135
- case 0:
136
- this.fresh();
137
- id = (0, uuid_1.generateUUID)();
138
- createdData = __assign(__assign({ id: id }, data), { createdAt: new Date(), updatedAt: new Date(), _type: this.collectionName, _scope: this.scope });
139
- _a.label = 1;
140
- case 1:
141
- _a.trys.push([1, 3, , 4]);
142
- return [4 /*yield*/, this.collection.upsert(createdData.id, createdData, options)];
143
- case 2:
144
- _a.sent();
145
- return [2 /*return*/, (0, utils_1.parseSchema)(this.schema, createdData)];
146
- case 3:
147
- error_1 = _a.sent();
148
- throw error_1;
149
- case 4: return [2 /*return*/];
150
- }
392
+ return [2 /*return*/, this.withConnection(function () {
393
+ return (0, indexes_1.ensureModelIndexes)(_this.couchbaseConnection().cluster, _this.keyspace(), _this.indexes, options);
394
+ })];
395
+ });
396
+ });
397
+ };
398
+ /**
399
+ * Run a SQL++ query and return rows directly.
400
+ */
401
+ Model.prototype.queryRows = function (query, params, options) {
402
+ return __awaiter(this, void 0, void 0, function () {
403
+ var _this = this;
404
+ return __generator(this, function (_a) {
405
+ return [2 /*return*/, this.withConnection(function () {
406
+ return (0, safe_query_1.runQueryRows)(_this.couchbaseConnection().cluster, query, params, options);
407
+ })];
151
408
  });
152
409
  });
153
410
  };
154
411
  /**
155
- * findById
412
+ * Run a SQL++ query and return the first row or null.
156
413
  */
157
- Model.prototype.findById = function (id, options) {
414
+ Model.prototype.queryOne = function (query, params, options) {
158
415
  return __awaiter(this, void 0, void 0, function () {
159
- var data, error_2;
416
+ var _this = this;
417
+ return __generator(this, function (_a) {
418
+ return [2 /*return*/, this.withConnection(function () {
419
+ return (0, safe_query_1.runQueryOne)(_this.couchbaseConnection().cluster, query, params, options);
420
+ })];
421
+ });
422
+ });
423
+ };
424
+ /**
425
+ * Run a SQL++ query using limit + 1 pagination.
426
+ */
427
+ Model.prototype.queryPage = function (query, params, options) {
428
+ return __awaiter(this, void 0, void 0, function () {
429
+ var _this = this;
430
+ return __generator(this, function (_a) {
431
+ return [2 /*return*/, this.withConnection(function () {
432
+ return (0, safe_query_1.runQueryPage)(_this.couchbaseConnection().cluster, query, params, options);
433
+ })];
434
+ });
435
+ });
436
+ };
437
+ /**
438
+ * Find many model-scoped documents.
439
+ */
440
+ Model.prototype.findMany = function () {
441
+ return __awaiter(this, arguments, void 0, function (args) {
442
+ var _this = this;
443
+ if (args === void 0) { args = {}; }
444
+ return __generator(this, function (_a) {
445
+ return [2 /*return*/, this.withConnection(function () { return (0, read_helpers_1.findMany)(_this.readContext(), _this.readArgs(args)); })];
446
+ });
447
+ });
448
+ };
449
+ /**
450
+ * Find the first matching model-scoped document.
451
+ */
452
+ Model.prototype.findOne = function () {
453
+ return __awaiter(this, arguments, void 0, function (args) {
454
+ var _this = this;
455
+ if (args === void 0) { args = {}; }
456
+ return __generator(this, function (_a) {
457
+ return [2 /*return*/, this.withConnection(function () { return (0, read_helpers_1.findOne)(_this.readContext(), _this.readArgs(args)); })];
458
+ });
459
+ });
460
+ };
461
+ /**
462
+ * Check whether at least one model-scoped document matches.
463
+ */
464
+ Model.prototype.exists = function () {
465
+ return __awaiter(this, arguments, void 0, function (args) {
466
+ var _this = this;
467
+ if (args === void 0) { args = {}; }
468
+ return __generator(this, function (_a) {
469
+ return [2 /*return*/, this.withConnection(function () { return (0, read_helpers_1.exists)(_this.readContext(), _this.readArgs(args)); })];
470
+ });
471
+ });
472
+ };
473
+ /**
474
+ * Count model-scoped documents.
475
+ */
476
+ Model.prototype.count = function () {
477
+ return __awaiter(this, arguments, void 0, function (args) {
478
+ var _this = this;
479
+ if (args === void 0) { args = {}; }
480
+ return __generator(this, function (_a) {
481
+ return [2 /*return*/, this.withConnection(function () { return (0, read_helpers_1.count)(_this.readContext(), _this.readArgs(args)); })];
482
+ });
483
+ });
484
+ };
485
+ /**
486
+ * Fetch a limit + 1 page of model-scoped documents.
487
+ */
488
+ Model.prototype.page = function () {
489
+ return __awaiter(this, arguments, void 0, function (args) {
490
+ var _this = this;
491
+ if (args === void 0) { args = {}; }
492
+ return __generator(this, function (_a) {
493
+ return [2 /*return*/, this.withConnection(function () { return (0, read_helpers_1.page)(_this.readContext(), _this.readArgs(args)); })];
494
+ });
495
+ });
496
+ };
497
+ Model.prototype.withDeleted = function () {
498
+ return this.cloneWithDefaultWhereMode('withDeleted');
499
+ };
500
+ Model.prototype.onlyDeleted = function () {
501
+ return this.cloneWithDefaultWhereMode('onlyDeleted');
502
+ };
503
+ Model.prototype.withoutDefaultWhere = function () {
504
+ return this.cloneWithDefaultWhereMode('none');
505
+ };
506
+ /**
507
+ * Insert a new document and fail if the id already exists.
508
+ */
509
+ Model.prototype.insert = function (data, options) {
510
+ return __awaiter(this, void 0, void 0, function () {
511
+ var _this = this;
512
+ return __generator(this, function (_a) {
513
+ return [2 /*return*/, this.withConnection(function () { return (0, write_helpers_1.insert)(_this.writeContext(), data, options); })];
514
+ });
515
+ });
516
+ };
517
+ /**
518
+ * Explicit insert-or-replace write.
519
+ */
520
+ Model.prototype.upsert = function (data, options) {
521
+ return __awaiter(this, void 0, void 0, function () {
522
+ var _this = this;
523
+ return __generator(this, function (_a) {
524
+ return [2 /*return*/, this.withConnection(function () { return (0, write_helpers_1.upsert)(_this.writeContext(), data, options); })];
525
+ });
526
+ });
527
+ };
528
+ Model.prototype.getById = function (id, options) {
529
+ return __awaiter(this, void 0, void 0, function () {
530
+ var _this = this;
531
+ return __generator(this, function (_a) {
532
+ return [2 /*return*/, this.withConnection(function () { return __awaiter(_this, void 0, void 0, function () {
533
+ var data;
534
+ return __generator(this, function (_a) {
535
+ switch (_a.label) {
536
+ case 0: return [4 /*yield*/, this.collection.get(id, options)];
537
+ case 1:
538
+ data = _a.sent();
539
+ return [2 /*return*/, this.parse(data.content)];
540
+ }
541
+ });
542
+ }); })];
543
+ });
544
+ });
545
+ };
546
+ Model.prototype.findDocById = function (id, options) {
547
+ return __awaiter(this, void 0, void 0, function () {
548
+ var data;
160
549
  return __generator(this, function (_a) {
161
550
  switch (_a.label) {
162
- case 0:
163
- this.fresh();
164
- _a.label = 1;
551
+ case 0: return [4 /*yield*/, this.getById(id, options)];
165
552
  case 1:
166
- _a.trys.push([1, 3, , 4]);
167
- return [4 /*yield*/, this.collection.get(id, options)];
168
- case 2:
169
553
  data = _a.sent();
170
- return [2 /*return*/, (0, utils_1.parseSchema)(this.schema, data.content)];
171
- case 3:
172
- error_2 = _a.sent();
173
- throw error_2;
174
- case 4: return [2 /*return*/];
554
+ return [2 /*return*/, this.hydrate(data)];
175
555
  }
176
556
  });
177
557
  });
178
558
  };
179
559
  /**
180
- * update
560
+ * Find a document with SDK metadata.
181
561
  */
182
- Model.prototype.updateById = function (id, data, opt) {
562
+ Model.prototype.findByIdWithMeta = function (id, options) {
183
563
  return __awaiter(this, void 0, void 0, function () {
184
- var _a, _b, silent, options, updatedDocument, error_3;
185
- return __generator(this, function (_c) {
186
- switch (_c.label) {
187
- case 0:
188
- this.fresh();
189
- _a = opt || {}, _b = _a.silent, silent = _b === void 0 ? false : _b, options = __rest(_a, ["silent"]);
190
- updatedDocument = __assign(__assign({}, data), { id: id, _type: this.collectionName, _scope: this.scope });
191
- if (!silent) {
192
- updatedDocument.updatedAt = new Date();
193
- }
194
- _c.label = 1;
195
- case 1:
196
- _c.trys.push([1, 3, , 4]);
197
- return [4 /*yield*/, this.collection.replace(id, updatedDocument, options)];
198
- case 2:
199
- _c.sent();
200
- return [2 /*return*/, (0, utils_1.parseSchema)(this.schema, updatedDocument)];
201
- case 3:
202
- error_3 = _c.sent();
203
- throw error_3;
204
- case 4: return [2 /*return*/];
205
- }
564
+ var _this = this;
565
+ return __generator(this, function (_a) {
566
+ return [2 /*return*/, this.withConnection(function () { return (0, write_helpers_1.findByIdWithMeta)(_this.writeContext(), id, options); })];
206
567
  });
207
568
  });
208
569
  };
209
570
  /**
210
- * save
571
+ * Explicit full-document replace.
211
572
  */
212
- Model.prototype.save = function (data, opt) {
573
+ Model.prototype.replaceById = function (id, data, options) {
213
574
  return __awaiter(this, void 0, void 0, function () {
214
- var id, _a, _b, silent, options, updatedDocument, error_4;
215
- return __generator(this, function (_c) {
216
- switch (_c.label) {
217
- case 0:
218
- this.fresh();
219
- id = data && data.id;
220
- _a = opt || {}, _b = _a.silent, silent = _b === void 0 ? false : _b, options = __rest(_a, ["silent"]);
221
- updatedDocument = __assign(__assign({}, data), { id: id, _type: this.collectionName, _scope: this.scope });
222
- if (!silent) {
223
- updatedDocument.updatedAt = new Date();
224
- }
225
- _c.label = 1;
226
- case 1:
227
- _c.trys.push([1, 3, , 4]);
228
- if (!id) {
229
- throw new Error('document must have id');
230
- }
231
- return [4 /*yield*/, this.collection.replace(id, updatedDocument, options)];
232
- case 2:
233
- _c.sent();
234
- return [2 /*return*/, (0, utils_1.parseSchema)(this.schema, updatedDocument)];
235
- case 3:
236
- error_4 = _c.sent();
237
- console.error(error_4);
238
- throw error_4;
239
- case 4: return [2 /*return*/];
240
- }
575
+ var _this = this;
576
+ return __generator(this, function (_a) {
577
+ return [2 /*return*/, this.withConnection(function () {
578
+ return (0, write_helpers_1.replaceById)(_this.writeContext(), id, data, options);
579
+ })];
241
580
  });
242
581
  });
243
582
  };
244
- Model.prototype.delete = function (id, options) {
583
+ /**
584
+ * Partial document mutation using common patch operators.
585
+ */
586
+ Model.prototype.patchById = function (id, patch, options) {
245
587
  return __awaiter(this, void 0, void 0, function () {
246
- var error_5;
588
+ var _this = this;
247
589
  return __generator(this, function (_a) {
248
- switch (_a.label) {
249
- case 0:
250
- this.fresh();
251
- _a.label = 1;
252
- case 1:
253
- _a.trys.push([1, 3, , 4]);
254
- return [4 /*yield*/, this.collection.remove(id, options)];
255
- case 2:
256
- _a.sent();
257
- return [2 /*return*/, true];
258
- case 3:
259
- error_5 = _a.sent();
260
- throw error_5;
261
- case 4: return [2 /*return*/];
262
- }
590
+ return [2 /*return*/, this.withConnection(function () {
591
+ return (0, write_helpers_1.patchById)(_this.writeContext(), id, patch, options);
592
+ })];
263
593
  });
264
594
  });
265
595
  };
266
596
  /**
267
- * Pagination
268
- *
269
- select = ['id', 'createdAt']
270
- where = {
271
- where: { owner: { $eq: "stoqey" }, _type: { $eq: "Trade" } },
272
- },
273
- page = 0,
274
- limit = 10,
275
- orderBy = { createdAt: "DESC" },
276
- * @param args PaginationArgs
277
- */
278
- Model.prototype.pagination = function (_a) {
279
- return __awaiter(this, arguments, void 0, function (_b) {
280
- var whereEx, bucketName, rows;
597
+ * Couchbase subdocument mutation escape hatch.
598
+ */
599
+ Model.prototype.mutateById = function (id, specs, options) {
600
+ return __awaiter(this, void 0, void 0, function () {
281
601
  var _this = this;
282
- var select = _b.select, where = _b.where, orderBy = _b.orderBy, limit = _b.limit, page = _b.page, _c = _b.customQuery, customQuery = _c === void 0 ? {} : _c;
283
- return __generator(this, function (_d) {
284
- switch (_d.label) {
285
- case 0:
286
- this.fresh(); // refresh
287
- whereEx = { _type: { $eq: this.collectionName } };
288
- if (where) {
289
- whereEx = __assign(__assign({}, whereEx), where);
290
- }
291
- bucketName = connection_1.default.Instance.bucketName;
292
- return [4 /*yield*/, (0, pagination_1.Pagination)({
293
- bucketName: bucketName,
294
- select: select,
295
- where: __assign({ where: whereEx }, customQuery),
296
- limit: limit,
297
- page: page,
298
- orderBy: orderBy,
299
- })];
300
- case 1:
301
- rows = _d.sent();
302
- return [2 /*return*/, rows.map(function (r) { return (0, utils_1.parseSchema)(_this.schema, r); })];
303
- }
602
+ return __generator(this, function (_a) {
603
+ return [2 /*return*/, this.withConnection(function () {
604
+ return (0, write_helpers_1.mutateById)(_this.writeContext(), id, specs, options);
605
+ })];
304
606
  });
305
607
  });
306
608
  };
307
609
  /**
308
- * Run a custom query with model parsing
309
- * @param { select, query }
310
- * @returns
610
+ * Atomic numeric field increment.
311
611
  */
312
- Model.prototype.customQuery = function (_a) {
313
- return __awaiter(this, arguments, void 0, function (_b) {
314
- var response;
315
- var params = _b.params, limit = _b.limit, query = _b.query;
612
+ Model.prototype.incrementById = function (id, field, delta, options) {
613
+ return __awaiter(this, void 0, void 0, function () {
614
+ var _this = this;
615
+ return __generator(this, function (_a) {
616
+ return [2 /*return*/, this.withConnection(function () {
617
+ return (0, write_helpers_1.incrementById)(_this.writeContext(), id, field, delta, options);
618
+ })];
619
+ });
620
+ });
621
+ };
622
+ Model.prototype.softDeleteById = function (id, options) {
623
+ return __awaiter(this, void 0, void 0, function () {
624
+ return __generator(this, function (_a) {
625
+ return [2 /*return*/, this.patchById(id, { $set: { deleted: true, deletedAt: new Date() } }, options)];
626
+ });
627
+ });
628
+ };
629
+ Model.prototype.restoreById = function (id, options) {
630
+ return __awaiter(this, void 0, void 0, function () {
631
+ return __generator(this, function (_a) {
632
+ return [2 /*return*/, this.patchById(id, { $unset: ['deleted', 'deletedAt'] }, options)];
633
+ });
634
+ });
635
+ };
636
+ Model.prototype.deleteById = function (id, options) {
637
+ return __awaiter(this, void 0, void 0, function () {
638
+ var _a, _b, hard, removeOptions;
639
+ var _this = this;
316
640
  return __generator(this, function (_c) {
317
- switch (_c.label) {
318
- case 0:
319
- this.fresh(); // refresh
320
- return [4 /*yield*/, (0, search_1.CustomQuery)({
321
- limit: limit,
322
- params: params,
323
- query: query,
324
- })];
641
+ _a = options || {}, _b = _a.hard, hard = _b === void 0 ? false : _b, removeOptions = __rest(_a, ["hard"]);
642
+ if (hard || !this.softDelete) {
643
+ return [2 /*return*/, this.withConnection(function () { return __awaiter(_this, void 0, void 0, function () {
644
+ return __generator(this, function (_a) {
645
+ switch (_a.label) {
646
+ case 0: return [4 /*yield*/, this.collection.remove(id, removeOptions)];
647
+ case 1:
648
+ _a.sent();
649
+ return [2 /*return*/, true];
650
+ }
651
+ });
652
+ }); })];
653
+ }
654
+ return [2 /*return*/, this.softDeleteById(id)];
655
+ });
656
+ });
657
+ };
658
+ Model.prototype.findDocOne = function () {
659
+ return __awaiter(this, arguments, void 0, function (args) {
660
+ var data;
661
+ if (args === void 0) { args = {}; }
662
+ return __generator(this, function (_a) {
663
+ switch (_a.label) {
664
+ case 0: return [4 /*yield*/, this.findOne(args)];
325
665
  case 1:
326
- response = _c.sent();
327
- return [2 /*return*/, response];
666
+ data = _a.sent();
667
+ return [2 /*return*/, data ? this.hydrate(data) : null];
328
668
  }
329
669
  });
330
670
  });
331
671
  };
672
+ Model.prototype.hydrate = function (data) {
673
+ return (0, hydrated_document_1.hydrate)(this, this.parse(data));
674
+ };
332
675
  Model.prototype.parse = function (data) {
333
- this.fresh(); // refresh
334
- return (0, utils_1.parseSchema)(this.schema, data);
676
+ var parsed = (0, utils_1.parseSchema)(this.schema, data);
677
+ var parsedDates = (0, validation_1.parseDateFields)(parsed, this.dateFields);
678
+ return this.parseHook ? this.parseHook(parsedDates) : parsedDates;
335
679
  };
680
+ Model.registeredModels = [];
336
681
  return Model;
337
682
  }());
338
683
  exports.Model = Model;