File size: 2,319 Bytes
9756872
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
91
92
93
94
95
96
97
98
99
'use strict';

const each = require('../helpers/each');

/*!
 * ignore
 */

module.exports = function saveSubdocs(schema) {
  const unshift = true;
  schema.s.hooks.pre('save', false, function saveSubdocsPreSave(next) {
    if (this.$isSubdocument) {
      next();
      return;
    }

    const _this = this;
    const subdocs = this.$getAllSubdocs();

    if (!subdocs.length) {
      next();
      return;
    }

    each(subdocs, function(subdoc, cb) {
      subdoc.$__schema.s.hooks.execPre('save', subdoc, function(err) {
        cb(err);
      });
    }, function(error) {
      if (error) {
        return _this.$__schema.s.hooks.execPost('save:error', _this, [_this], { error: error }, function(error) {
          next(error);
        });
      }
      next();
    });
  }, null, unshift);

  schema.s.hooks.post('save', async function saveSubdocsPostDeleteOne() {
    const removedSubdocs = this.$__.removedSubdocs;
    if (!removedSubdocs || !removedSubdocs.length) {
      return;
    }

    const promises = [];
    for (const subdoc of removedSubdocs) {
      promises.push(new Promise((resolve, reject) => {
        subdoc.$__schema.s.hooks.execPost('deleteOne', subdoc, [subdoc], function(err) {
          if (err) {
            return reject(err);
          }
          resolve();
        });
      }));
    }

    this.$__.removedSubdocs = null;
    await Promise.all(promises);
  });

  schema.s.hooks.post('save', async function saveSubdocsPostSave() {
    if (this.$isSubdocument) {
      return;
    }

    const _this = this;
    const subdocs = this.$getAllSubdocs();

    if (!subdocs.length) {
      return;
    }

    const promises = [];
    for (const subdoc of subdocs) {
      promises.push(new Promise((resolve, reject) => {
        subdoc.$__schema.s.hooks.execPost('save', subdoc, [subdoc], function(err) {
          if (err) {
            return reject(err);
          }
          resolve();
        });
      }));
    }

    try {
      await Promise.all(promises);
    } catch (error) {
      await new Promise((resolve, reject) => {
        this.$__schema.s.hooks.execPost('save:error', _this, [_this], { error: error }, function(error) {
          if (error) {
            return reject(error);
          }
          resolve();
        });
      });
    }
  }, null, unshift);
};