@bedrockio/model 0.5.4 → 0.6.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.
@@ -12,6 +12,7 @@ var _serialization = require("./serialization");
12
12
  var _slug = require("./slug");
13
13
  var _search = require("./search");
14
14
  var _assign = require("./assign");
15
+ var _upsert = require("./upsert");
15
16
  var _hydrate = require("./hydrate");
16
17
  var _include = require("./include");
17
18
  var _softDelete = require("./soft-delete");
@@ -57,6 +58,7 @@ function createSchema(definition, options = {}) {
57
58
  (0, _include.applyInclude)(schema);
58
59
  (0, _hydrate.applyHydrate)(schema);
59
60
  (0, _assign.applyAssign)(schema);
61
+ (0, _upsert.applyUpsert)(schema);
60
62
  (0, _slug.applySlug)(schema);
61
63
  return schema;
62
64
  }
@@ -26,6 +26,7 @@ function applySearch(schema, definition) {
26
26
  validateDefinition(definition);
27
27
  validateSearchFields(schema, definition);
28
28
  applySearchCache(schema, definition);
29
+ applySearchSync(schema, definition);
29
30
  const {
30
31
  query: searchQuery,
31
32
  fields: searchFields
@@ -391,6 +392,32 @@ function applyCacheHook(schema, definition) {
391
392
  this.assign(getUpdates(this, paths, definition));
392
393
  });
393
394
  }
395
+
396
+ // Search field syncing
397
+
398
+ function applySearchSync(schema, definition) {
399
+ if (!definition.search?.sync) {
400
+ return;
401
+ }
402
+ schema.post('save', async function postSave() {
403
+ for (let entry of definition.search.sync) {
404
+ const {
405
+ ref,
406
+ path
407
+ } = entry;
408
+ const Model = _mongoose.default.models[ref];
409
+ const docs = await Model.find({
410
+ [path]: this.id
411
+ });
412
+ await Promise.all(docs.map(async doc => {
413
+ await doc.save();
414
+ }));
415
+ }
416
+ });
417
+ }
418
+
419
+ // Utils
420
+
394
421
  function isForeignField(schema, path) {
395
422
  if (!path.includes('.')) {
396
423
  return false;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.applyUpsert = applyUpsert;
7
+ function applyUpsert(schema) {
8
+ // Note: Intentionally avoiding the findOneAndUpdate approach here
9
+ // as this will prevent hooks from being run on the document. This
10
+ // means however that we cannot always return a query here as the
11
+ // operations are inherently different.
12
+
13
+ schema.static('findOrCreate', async function findOrCreate(query, fields) {
14
+ fields ||= query;
15
+ let doc = await this.findOne(query);
16
+ if (!doc) {
17
+ doc = await this.create(fields);
18
+ }
19
+ return doc;
20
+ });
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bedrockio/model",
3
- "version": "0.5.4",
3
+ "version": "0.6.0",
4
4
  "description": "Bedrock utilities for model creation.",
5
5
  "type": "module",
6
6
  "scripts": {
package/src/schema.js CHANGED
@@ -7,6 +7,7 @@ import { serializeOptions } from './serialization';
7
7
  import { applySlug } from './slug';
8
8
  import { applySearch } from './search';
9
9
  import { applyAssign } from './assign';
10
+ import { applyUpsert } from './upsert';
10
11
  import { applyHydrate } from './hydrate';
11
12
  import { applyInclude } from './include';
12
13
  import { applySoftDelete } from './soft-delete';
@@ -61,6 +62,7 @@ export function createSchema(definition, options = {}) {
61
62
  applyInclude(schema);
62
63
  applyHydrate(schema);
63
64
  applyAssign(schema);
65
+ applyUpsert(schema);
64
66
  applySlug(schema);
65
67
 
66
68
  return schema;
package/src/search.js CHANGED
@@ -18,6 +18,7 @@ export function applySearch(schema, definition) {
18
18
  validateDefinition(definition);
19
19
  validateSearchFields(schema, definition);
20
20
  applySearchCache(schema, definition);
21
+ applySearchSync(schema, definition);
21
22
 
22
23
  const { query: searchQuery, fields: searchFields } = definition.search || {};
23
24
 
@@ -415,6 +416,32 @@ function applyCacheHook(schema, definition) {
415
416
  });
416
417
  }
417
418
 
419
+ // Search field syncing
420
+
421
+ function applySearchSync(schema, definition) {
422
+ if (!definition.search?.sync) {
423
+ return;
424
+ }
425
+
426
+ schema.post('save', async function postSave() {
427
+ for (let entry of definition.search.sync) {
428
+ const { ref, path } = entry;
429
+ const Model = mongoose.models[ref];
430
+ const docs = await Model.find({
431
+ [path]: this.id,
432
+ });
433
+
434
+ await Promise.all(
435
+ docs.map(async (doc) => {
436
+ await doc.save();
437
+ })
438
+ );
439
+ }
440
+ });
441
+ }
442
+
443
+ // Utils
444
+
418
445
  function isForeignField(schema, path) {
419
446
  if (!path.includes('.')) {
420
447
  return false;
package/src/upsert.js ADDED
@@ -0,0 +1,18 @@
1
+ export function applyUpsert(schema) {
2
+ // Note: Intentionally avoiding the findOneAndUpdate approach here
3
+ // as this will prevent hooks from being run on the document. This
4
+ // means however that we cannot always return a query here as the
5
+ // operations are inherently different.
6
+
7
+ schema.static('findOrCreate', async function findOrCreate(query, fields) {
8
+ fields ||= query;
9
+
10
+ let doc = await this.findOne(query);
11
+
12
+ if (!doc) {
13
+ doc = await this.create(fields);
14
+ }
15
+
16
+ return doc;
17
+ });
18
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.js"],"names":[],"mappings":"AAqBA;;;;;;;GAOG;AACH,yCAJW,MAAM,YACN,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAwChC;AAED,iEAsBC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.js"],"names":[],"mappings":"AAsBA;;;;;;;GAOG;AACH,yCAJW,MAAM,YACN,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAyChC;AAED,iEAsBC"}
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.js"],"names":[],"mappings":"AAgBA,gEAyDC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBC"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.js"],"names":[],"mappings":"AAgBA,gEA0DC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBC"}
@@ -0,0 +1,2 @@
1
+ export function applyUpsert(schema: any): void;
2
+ //# sourceMappingURL=upsert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../src/upsert.js"],"names":[],"mappings":"AAAA,+CAiBC"}