ts-patch-mongoose 1.0.1

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 (95) hide show
  1. package/.eslintignore +4 -0
  2. package/.eslintrc +91 -0
  3. package/.swcrc +21 -0
  4. package/LICENSE +21 -0
  5. package/README.md +66 -0
  6. package/dist/cjs/em.d.ts +7 -0
  7. package/dist/cjs/em.d.ts.map +1 -0
  8. package/dist/cjs/em.js +9 -0
  9. package/dist/cjs/em.js.map +1 -0
  10. package/dist/cjs/interfaces/IContext.d.ts +12 -0
  11. package/dist/cjs/interfaces/IContext.d.ts.map +1 -0
  12. package/dist/cjs/interfaces/IContext.js +3 -0
  13. package/dist/cjs/interfaces/IContext.js.map +1 -0
  14. package/dist/cjs/interfaces/IHistory.d.ts +13 -0
  15. package/dist/cjs/interfaces/IHistory.d.ts.map +1 -0
  16. package/dist/cjs/interfaces/IHistory.js +3 -0
  17. package/dist/cjs/interfaces/IHistory.js.map +1 -0
  18. package/dist/cjs/interfaces/IHookContext.d.ts +8 -0
  19. package/dist/cjs/interfaces/IHookContext.d.ts.map +1 -0
  20. package/dist/cjs/interfaces/IHookContext.js +3 -0
  21. package/dist/cjs/interfaces/IHookContext.js.map +1 -0
  22. package/dist/cjs/interfaces/IPluginOptions.d.ts +13 -0
  23. package/dist/cjs/interfaces/IPluginOptions.d.ts.map +1 -0
  24. package/dist/cjs/interfaces/IPluginOptions.js +3 -0
  25. package/dist/cjs/interfaces/IPluginOptions.js.map +1 -0
  26. package/dist/cjs/models/History.d.ts +29 -0
  27. package/dist/cjs/models/History.d.ts.map +1 -0
  28. package/dist/cjs/models/History.js +36 -0
  29. package/dist/cjs/models/History.js.map +1 -0
  30. package/dist/cjs/plugin.d.ts +45 -0
  31. package/dist/cjs/plugin.d.ts.map +1 -0
  32. package/dist/cjs/plugin.js +224 -0
  33. package/dist/cjs/plugin.js.map +1 -0
  34. package/dist/esm/em.d.ts +7 -0
  35. package/dist/esm/em.d.ts.map +1 -0
  36. package/dist/esm/em.js +6 -0
  37. package/dist/esm/em.js.map +1 -0
  38. package/dist/esm/interfaces/IContext.d.ts +12 -0
  39. package/dist/esm/interfaces/IContext.d.ts.map +1 -0
  40. package/dist/esm/interfaces/IContext.js +2 -0
  41. package/dist/esm/interfaces/IContext.js.map +1 -0
  42. package/dist/esm/interfaces/IHistory.d.ts +13 -0
  43. package/dist/esm/interfaces/IHistory.d.ts.map +1 -0
  44. package/dist/esm/interfaces/IHistory.js +2 -0
  45. package/dist/esm/interfaces/IHistory.js.map +1 -0
  46. package/dist/esm/interfaces/IHookContext.d.ts +8 -0
  47. package/dist/esm/interfaces/IHookContext.d.ts.map +1 -0
  48. package/dist/esm/interfaces/IHookContext.js +2 -0
  49. package/dist/esm/interfaces/IHookContext.js.map +1 -0
  50. package/dist/esm/interfaces/IPluginOptions.d.ts +13 -0
  51. package/dist/esm/interfaces/IPluginOptions.d.ts.map +1 -0
  52. package/dist/esm/interfaces/IPluginOptions.js +2 -0
  53. package/dist/esm/interfaces/IPluginOptions.js.map +1 -0
  54. package/dist/esm/models/History.d.ts +29 -0
  55. package/dist/esm/models/History.d.ts.map +1 -0
  56. package/dist/esm/models/History.js +34 -0
  57. package/dist/esm/models/History.js.map +1 -0
  58. package/dist/esm/plugin.d.ts +45 -0
  59. package/dist/esm/plugin.d.ts.map +1 -0
  60. package/dist/esm/plugin.js +219 -0
  61. package/dist/esm/plugin.js.map +1 -0
  62. package/dist/types/em.d.ts +7 -0
  63. package/dist/types/em.d.ts.map +1 -0
  64. package/dist/types/interfaces/IContext.d.ts +12 -0
  65. package/dist/types/interfaces/IContext.d.ts.map +1 -0
  66. package/dist/types/interfaces/IHistory.d.ts +13 -0
  67. package/dist/types/interfaces/IHistory.d.ts.map +1 -0
  68. package/dist/types/interfaces/IHookContext.d.ts +8 -0
  69. package/dist/types/interfaces/IHookContext.d.ts.map +1 -0
  70. package/dist/types/interfaces/IPluginOptions.d.ts +13 -0
  71. package/dist/types/interfaces/IPluginOptions.d.ts.map +1 -0
  72. package/dist/types/models/History.d.ts +29 -0
  73. package/dist/types/models/History.d.ts.map +1 -0
  74. package/dist/types/plugin.d.ts +45 -0
  75. package/dist/types/plugin.d.ts.map +1 -0
  76. package/jest-mongodb-config.ts +10 -0
  77. package/jest.config.ts +35 -0
  78. package/package.json +101 -0
  79. package/src/em.ts +6 -0
  80. package/src/interfaces/IContext.ts +13 -0
  81. package/src/interfaces/IHistory.ts +14 -0
  82. package/src/interfaces/IHookContext.ts +6 -0
  83. package/src/interfaces/IPluginOptions.ts +14 -0
  84. package/src/models/History.ts +39 -0
  85. package/src/modules/omit-deep.d.ts +3 -0
  86. package/src/modules/power-assign.d.ts +3 -0
  87. package/src/plugin.ts +267 -0
  88. package/tests/constants/events.ts +3 -0
  89. package/tests/em.test.ts +16 -0
  90. package/tests/interfaces/IUser.ts +8 -0
  91. package/tests/models/User.ts +29 -0
  92. package/tests/mongose.test.ts +28 -0
  93. package/tests/plugin.test.ts +243 -0
  94. package/tests/utils/filesystem.ts +13 -0
  95. package/tsconfig.json +44 -0
@@ -0,0 +1,219 @@
1
+ import _ from 'lodash';
2
+ import omit from 'omit-deep';
3
+ import jsonpatch from 'fast-json-patch';
4
+ import { assign } from 'power-assign';
5
+ import em from './em';
6
+ import History from './models/History';
7
+ const options = {
8
+ document: false,
9
+ query: true
10
+ };
11
+ function getObjects(opts, current, original) {
12
+ let currentObject = JSON.parse(JSON.stringify(current));
13
+ let originalObject = JSON.parse(JSON.stringify(original));
14
+ if (opts.omit) {
15
+ currentObject = omit(currentObject, opts.omit);
16
+ originalObject = omit(originalObject, opts.omit);
17
+ }
18
+ return { currentObject, originalObject };
19
+ }
20
+ async function bulkPatch(opts, context) {
21
+ const chunks = _.chunk(context.deletedDocs, 1000);
22
+ for await (const chunk of chunks) {
23
+ const bulk = [];
24
+ for (const oldDoc of chunk) {
25
+ if (opts.eventDeleted) {
26
+ em.emit(opts.eventDeleted, { oldDoc });
27
+ }
28
+ if (!opts.patchHistoryDisabled) {
29
+ bulk.push({
30
+ insertOne: {
31
+ document: {
32
+ op: context.op,
33
+ modelName: context.modelName,
34
+ collectionName: context.collectionName,
35
+ collectionId: oldDoc._id,
36
+ doc: oldDoc,
37
+ version: 0
38
+ }
39
+ }
40
+ });
41
+ }
42
+ }
43
+ if (opts.patchHistoryDisabled)
44
+ continue;
45
+ await History.bulkWrite(bulk, { ordered: false }).catch((err) => {
46
+ console.error(err);
47
+ });
48
+ }
49
+ }
50
+ async function updatePatch(opts, context, current, original) {
51
+ const { currentObject, originalObject } = getObjects(opts, current, original);
52
+ if (_.isEmpty(originalObject) || _.isEmpty(currentObject))
53
+ return;
54
+ const patch = jsonpatch.compare(originalObject, currentObject, true);
55
+ if (_.isEmpty(patch))
56
+ return;
57
+ if (opts.eventUpdated) {
58
+ em.emit(opts.eventUpdated, { oldDoc: original, doc: current, patch });
59
+ }
60
+ if (opts.patchHistoryDisabled)
61
+ return;
62
+ let version = 0;
63
+ const lastHistory = await History.findOne({ collectionId: original._id }).sort('-version').exec();
64
+ if (lastHistory && lastHistory.version >= 0) {
65
+ version = lastHistory.version + 1;
66
+ }
67
+ await History.create({
68
+ op: context.op,
69
+ modelName: context.modelName,
70
+ collectionName: context.collectionName,
71
+ collectionId: original._id,
72
+ patch,
73
+ version
74
+ });
75
+ }
76
+ async function createPatch(opts, context, current) {
77
+ if (opts.patchHistoryDisabled)
78
+ return;
79
+ await History.create({
80
+ op: context.op,
81
+ modelName: context.modelName,
82
+ collectionName: context.collectionName,
83
+ collectionId: current._id,
84
+ doc: current
85
+ });
86
+ }
87
+ export const patchEventEmitter = em;
88
+ export const patchHistoryPlugin = function plugin(schema, opts) {
89
+ schema.pre('save', async function (next) {
90
+ const current = this.toObject({ depopulate: true });
91
+ const model = this.constructor;
92
+ const context = {
93
+ op: this.isNew ? 'create' : 'update',
94
+ modelName: opts.modelName ?? model.modelName,
95
+ collectionName: opts.collectionName ?? model.collection.collectionName
96
+ };
97
+ try {
98
+ if (this.isNew) {
99
+ if (opts.eventCreated) {
100
+ em.emit(opts.eventCreated, { doc: current });
101
+ }
102
+ await createPatch(opts, context, current);
103
+ }
104
+ else {
105
+ const original = await model.findById(current._id).exec();
106
+ if (original) {
107
+ await updatePatch(opts, context, current, original);
108
+ }
109
+ }
110
+ next();
111
+ }
112
+ catch (error) {
113
+ next(error);
114
+ }
115
+ });
116
+ schema.pre(['findOneAndUpdate', 'update', 'updateOne', 'updateMany'], async function (next) {
117
+ const filter = this.getFilter();
118
+ const update = this.getUpdate();
119
+ const options = this.getOptions();
120
+ const count = await this.model.count(filter).exec();
121
+ const commands = [];
122
+ const context = {
123
+ op: this.op,
124
+ modelName: opts.modelName ?? this.model.modelName,
125
+ collectionName: opts.collectionName ?? this.model.collection.collectionName,
126
+ isNew: options.upsert && count === 0
127
+ };
128
+ this._context = context;
129
+ try {
130
+ const keys = _.keys(update).filter((key) => key.startsWith('$'));
131
+ if (update && !_.isEmpty(keys)) {
132
+ _.forEach(keys, (key) => {
133
+ commands.push({ [key]: update[key] });
134
+ delete update[key];
135
+ });
136
+ }
137
+ const cursor = this.model.find(filter).cursor();
138
+ await cursor.eachAsync(async (doc) => {
139
+ let current = doc.toObject({ depopulate: true });
140
+ current = assign(current, update);
141
+ _.forEach(commands, (command) => {
142
+ try {
143
+ current = assign(current, command);
144
+ }
145
+ catch (error) {
146
+ }
147
+ });
148
+ await updatePatch(opts, context, current, doc.toObject({ depopulate: true }));
149
+ });
150
+ next();
151
+ }
152
+ catch (error) {
153
+ next(error);
154
+ }
155
+ });
156
+ schema.post(['findOneAndUpdate', 'update', 'updateOne', 'updateMany'], async function () {
157
+ const update = this.getUpdate();
158
+ if (update && this._context.isNew) {
159
+ const cursor = this.model.findOne(update).cursor();
160
+ await cursor.eachAsync(async (current) => {
161
+ if (opts.eventCreated) {
162
+ em.emit(opts.eventCreated, { doc: current });
163
+ }
164
+ await createPatch(opts, this._context, current);
165
+ });
166
+ }
167
+ });
168
+ schema.pre('updateMany', options, async function (next) {
169
+ const filter = this.getFilter();
170
+ const options = this.getOptions();
171
+ const ignore = options.__ignore;
172
+ const context = {
173
+ op: this.op,
174
+ modelName: opts.modelName ?? this.model.modelName,
175
+ collectionName: opts.collectionName ?? this.model.collection.collectionName,
176
+ isNew: options.upsert
177
+ };
178
+ if (!ignore) {
179
+ const ids = await this.model.distinct('_id', filter).exec();
180
+ context.updatedIds = ids;
181
+ }
182
+ this._context = context;
183
+ next();
184
+ });
185
+ schema.post('updateMany', options, async function () {
186
+ if (this._context.updatedIds?.length)
187
+ return;
188
+ const cursor = this.model.find({ _id: { $in: this._context.updatedIds } }).cursor();
189
+ await cursor.eachAsync((current) => {
190
+ if (opts.eventUpdated) {
191
+ em.emit(opts.eventUpdated, { doc: current });
192
+ }
193
+ });
194
+ });
195
+ schema.pre(['remove', 'findOneAndDelete', 'findOneAndRemove', 'deleteOne', 'deleteMany'], options, async function (next) {
196
+ const filter = this.getFilter();
197
+ const options = this.getOptions();
198
+ const ignore = options.__ignore;
199
+ const context = {
200
+ op: this.op,
201
+ modelName: opts.modelName ?? this.model.modelName,
202
+ collectionName: opts.collectionName ?? this.model.collection.collectionName
203
+ };
204
+ if (!ignore) {
205
+ context.deletedDocs = await this.model.find(filter).exec();
206
+ if (opts.preDeleteManyCallback) {
207
+ await opts.preDeleteManyCallback(context.deletedDocs);
208
+ }
209
+ }
210
+ this._context = context;
211
+ next();
212
+ });
213
+ schema.post(['remove', 'findOneAndDelete', 'findOneAndRemove', 'deleteOne', 'deleteMany'], options, async function () {
214
+ if (_.isEmpty(this._context.deletedDocs))
215
+ return;
216
+ await bulkPatch(opts, this._context);
217
+ });
218
+ };
219
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAA;AACtB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAQrC,OAAO,EAAE,MAAM,MAAM,CAAA;AACrB,OAAO,OAAO,MAAM,kBAAkB,CAAA;AAEtC,MAAM,OAAO,GAAG;IACd,QAAQ,EAAE,KAAK;IACf,KAAK,EAAE,IAAI;CACZ,CAAA;AAED,SAAS,UAAU,CAAK,IAAuB,EAAE,OAA4B,EAAE,QAA6B;IAC1G,IAAI,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAe,CAAA;IACrE,IAAI,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAe,CAAA;IAEvE,IAAI,IAAI,CAAC,IAAI,EAAE;QACb,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9C,cAAc,GAAG,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;KACjD;IAED,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,CAAA;AAC1C,CAAC;AAED,KAAK,UAAU,SAAS,CAAK,IAAuB,EAAE,OAAoB;IACxE,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACjD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE;QAChC,MAAM,IAAI,GAAG,EAAE,CAAA;QACf,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE;YAC1B,IAAI,IAAI,CAAC,YAAY,EAAE;gBACrB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;aACvC;YACD,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE;gBAC9B,IAAI,CAAC,IAAI,CAAC;oBACR,SAAS,EAAE;wBACT,QAAQ,EAAE;4BACR,EAAE,EAAE,OAAO,CAAC,EAAE;4BACd,SAAS,EAAE,OAAO,CAAC,SAAS;4BAC5B,cAAc,EAAE,OAAO,CAAC,cAAc;4BACtC,YAAY,EAAE,MAAM,CAAC,GAAqB;4BAC1C,GAAG,EAAE,MAAM;4BACX,OAAO,EAAE,CAAC;yBACX;qBACF;iBACF,CAAC,CAAA;aACH;SACF;QAED,IAAI,IAAI,CAAC,oBAAoB;YAAE,SAAQ;QACvC,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAkB,EAAE,EAAE;YAC7E,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACpB,CAAC,CAAC,CAAA;KACH;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAK,IAAuB,EAAE,OAAoB,EAAE,OAA4B,EAAE,QAA6B;IACvI,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;IAE7E,IAAI,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;QAAE,OAAM;IAEjE,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE,aAAa,EAAE,IAAI,CAAC,CAAA;IAEpE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAM;IAE5B,IAAI,IAAI,CAAC,YAAY,EAAE;QACrB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;KACtE;IAED,IAAI,IAAI,CAAC,oBAAoB;QAAE,OAAM;IAErC,IAAI,OAAO,GAAG,CAAC,CAAA;IAEf,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,GAAqB,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAA;IAEnH,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,IAAI,CAAC,EAAE;QAC3C,OAAO,GAAG,WAAW,CAAC,OAAO,GAAG,CAAC,CAAA;KAClC;IAED,MAAM,OAAO,CAAC,MAAM,CAAC;QACnB,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,YAAY,EAAE,QAAQ,CAAC,GAAqB;QAC5C,KAAK;QACL,OAAO;KACR,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,WAAW,CAAK,IAAuB,EAAE,OAAoB,EAAE,OAA4B;IACxG,IAAI,IAAI,CAAC,oBAAoB;QAAE,OAAM;IAErC,MAAM,OAAO,CAAC,MAAM,CAAC;QACnB,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,YAAY,EAAE,OAAO,CAAC,GAAqB;QAC3C,GAAG,EAAE,OAAO;KACb,CAAC,CAAA;AACJ,CAAC;AAKD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAQnC,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,MAAM,CAAK,MAAiB,EAAE,IAAuB;IAC9F,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,WAAW,IAAI;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAwB,CAAA;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,WAAuB,CAAA;QAE1C,MAAM,OAAO,GAAgB;YAC3B,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;YACpC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS;YAC5C,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,UAAU,CAAC,cAAc;SACvE,CAAA;QAED,IAAI;YACF,IAAI,IAAI,CAAC,KAAK,EAAE;gBACd,IAAI,IAAI,CAAC,YAAY,EAAE;oBACrB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;iBAC7C;gBACD,MAAM,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;aAC1C;iBAAM;gBACL,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;gBACzD,IAAI,QAAQ,EAAE;oBACZ,MAAM,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;iBACpD;aACF;YACD,IAAI,EAAE,CAAA;SACP;QAAC,OAAO,KAAK,EAAE;YACd,IAAI,CAAC,KAAsB,CAAC,CAAA;SAC7B;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,GAAG,CAAC,CAAC,kBAAkB,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,KAAK,WAAkC,IAAI;QAC/G,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAuC,CAAA;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAA;QAEjC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;QACnD,MAAM,QAAQ,GAAiC,EAAE,CAAA;QAEjD,MAAM,OAAO,GAAgB;YAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS;YACjD,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc;YAC3E,KAAK,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,KAAK,CAAC;SACrC,CAAA;QAED,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QAEvB,IAAI;YACF,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;YAChE,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAC9B,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;oBACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;oBAErC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;gBACpB,CAAC,CAAC,CAAA;aACH;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAA;YAC/C,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAwB,EAAE,EAAE;gBACxD,IAAI,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAwB,CAAA;gBACvE,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;gBACjC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE;oBAC9B,IAAI;wBACF,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;qBACnC;oBAAC,OAAO,KAAK,EAAE;qBAEf;gBACH,CAAC,CAAC,CAAA;gBACF,MAAM,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAwB,CAAC,CAAA;YACtG,CAAC,CAAC,CAAA;YACF,IAAI,EAAE,CAAA;SACP;QAAC,OAAO,KAAK,EAAE;YACd,IAAI,CAAC,KAAsB,CAAC,CAAA;SAC7B;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,CAAC,CAAC,kBAAkB,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,KAAK;QAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;QAE/B,IAAI,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAA;YAClD,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,OAA4B,EAAE,EAAE;gBAC5D,IAAI,IAAI,CAAC,YAAY,EAAE;oBACrB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;iBAC7C;gBACD,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YACjD,CAAC,CAAC,CAAA;SACH;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,WAAkC,IAAI;QAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAA;QACjC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAmB,CAAA;QAE1C,MAAM,OAAO,GAAgB;YAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS;YACjD,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc;YAC3E,KAAK,EAAE,OAAO,CAAC,MAAM;SACtB,CAAA;QAED,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAiB,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;YAC3E,OAAO,CAAC,UAAU,GAAG,GAAG,CAAA;SACzB;QAED,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QAEvB,IAAI,EAAE,CAAA;IACR,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK;QACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM;YAAE,OAAM;QAE5C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAA;QACnF,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,OAA4B,EAAE,EAAE;YACtD,IAAI,IAAI,CAAC,YAAY,EAAE;gBACrB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;aAC7C;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,OAAO,EAAE,KAAK,WAAkC,IAAI;QAC5I,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAA;QACjC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAmB,CAAA;QAE1C,MAAM,OAAO,GAAgB;YAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS;YACjD,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc;SAC5E,CAAA;QAED,IAAI,CAAC,MAAM,EAAE;YACX,OAAO,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;YAC1D,IAAI,IAAI,CAAC,qBAAqB,EAAE;gBAC9B,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;aACtD;SACF;QAED,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QACvB,IAAI,EAAE,CAAA;IACR,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,OAAO,EAAE,KAAK;QACvG,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAM;QAEhD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ /// <reference types="node" />
2
+ import EventEmitter from 'events';
3
+ declare class PatchEventEmitter extends EventEmitter {
4
+ }
5
+ declare const em: PatchEventEmitter;
6
+ export default em;
7
+ //# sourceMappingURL=em.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"em.d.ts","sourceRoot":"","sources":["../../src/em.ts"],"names":[],"mappings":";AAAA,OAAO,YAAY,MAAM,QAAQ,CAAA;AAEjC,cAAM,iBAAkB,SAAQ,YAAY;CAAG;AAC/C,QAAA,MAAM,EAAE,mBAA0B,CAAA;AAElC,eAAe,EAAE,CAAA"}
@@ -0,0 +1,12 @@
1
+ import type { HydratedDocument, Types } from 'mongoose';
2
+ interface IContext<T> {
3
+ op: string;
4
+ modelName: string;
5
+ collectionName: string;
6
+ isNew?: boolean;
7
+ oldDoc?: HydratedDocument<T>;
8
+ deletedDocs?: HydratedDocument<T>[];
9
+ updatedIds?: Types.ObjectId[];
10
+ }
11
+ export default IContext;
12
+ //# sourceMappingURL=IContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IContext.d.ts","sourceRoot":"","sources":["../../../src/interfaces/IContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAEvD,UAAU,QAAQ,CAAC,CAAC;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC5B,WAAW,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAA;IACnC,UAAU,CAAC,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAA;CAC9B;AAED,eAAe,QAAQ,CAAA"}
@@ -0,0 +1,13 @@
1
+ import type { Types } from 'mongoose';
2
+ import type { Operation } from 'fast-json-patch';
3
+ interface IHistory {
4
+ op: string;
5
+ modelName: string;
6
+ collectionName: string;
7
+ collectionId: Types.ObjectId;
8
+ version: number;
9
+ doc?: object;
10
+ patch?: Operation[];
11
+ }
12
+ export default IHistory;
13
+ //# sourceMappingURL=IHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IHistory.d.ts","sourceRoot":"","sources":["../../../src/interfaces/IHistory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,SAAS,EAAE,CAAA;CACpB;AAED,eAAe,QAAQ,CAAA"}
@@ -0,0 +1,8 @@
1
+ import type { Query } from 'mongoose';
2
+ import type IContext from './IContext';
3
+ type IHookContext<T> = Query<T, T> & {
4
+ op: string;
5
+ _context: IContext<T>;
6
+ };
7
+ export default IHookContext;
8
+ //# sourceMappingURL=IHookContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IHookContext.d.ts","sourceRoot":"","sources":["../../../src/interfaces/IHookContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAA;AAEtC,KAAK,YAAY,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;CAAE,CAAA;AAE1E,eAAe,YAAY,CAAA"}
@@ -0,0 +1,13 @@
1
+ import type { HydratedDocument } from 'mongoose';
2
+ interface IPluginOptions<T> {
3
+ modelName?: string;
4
+ collectionName?: string;
5
+ eventUpdated?: string;
6
+ eventCreated?: string;
7
+ eventDeleted?: string;
8
+ patchHistoryDisabled?: boolean;
9
+ preDeleteManyCallback?: (docs: HydratedDocument<T>[]) => Promise<void>;
10
+ omit?: string[];
11
+ }
12
+ export default IPluginOptions;
13
+ //# sourceMappingURL=IPluginOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IPluginOptions.d.ts","sourceRoot":"","sources":["../../../src/interfaces/IPluginOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEhD,UAAU,cAAc,CAAC,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,eAAe,cAAc,CAAA"}
@@ -0,0 +1,29 @@
1
+ /// <reference types="mongoose/types/aggregate" />
2
+ /// <reference types="mongoose/types/callback" />
3
+ /// <reference types="mongoose/types/collection" />
4
+ /// <reference types="mongoose/types/connection" />
5
+ /// <reference types="mongoose/types/cursor" />
6
+ /// <reference types="mongoose/types/document" />
7
+ /// <reference types="mongoose/types/error" />
8
+ /// <reference types="mongoose/types/expressions" />
9
+ /// <reference types="mongoose/types/helpers" />
10
+ /// <reference types="mongoose/types/middlewares" />
11
+ /// <reference types="mongoose/types/indexes" />
12
+ /// <reference types="mongoose/types/models" />
13
+ /// <reference types="mongoose/types/mongooseoptions" />
14
+ /// <reference types="mongoose/types/pipelinestage" />
15
+ /// <reference types="mongoose/types/populate" />
16
+ /// <reference types="mongoose/types/query" />
17
+ /// <reference types="mongoose/types/schemaoptions" />
18
+ /// <reference types="mongoose/types/schematypes" />
19
+ /// <reference types="mongoose/types/session" />
20
+ /// <reference types="mongoose/types/types" />
21
+ /// <reference types="mongoose/types/utility" />
22
+ /// <reference types="mongoose/types/validation" />
23
+ /// <reference types="mongoose/types/virtuals" />
24
+ /// <reference types="mongoose/types/inferschematype" />
25
+ import { Schema } from 'mongoose';
26
+ import type IHistory from '../interfaces/IHistory';
27
+ declare const History: import("mongoose").Model<IHistory, {}, {}, {}, Schema<IHistory, import("mongoose").Model<IHistory, any, any, any, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, IHistory>>;
28
+ export default History;
29
+ //# sourceMappingURL=History.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"History.d.ts","sourceRoot":"","sources":["../../../src/models/History.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAS,MAAM,UAAU,CAAA;AAExC,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAA;AAkClD,QAAA,MAAM,OAAO,6LAA6C,CAAA;AAE1D,eAAe,OAAO,CAAA"}
@@ -0,0 +1,45 @@
1
+ /// <reference types="mongoose/types/aggregate" />
2
+ /// <reference types="mongoose/types/callback" />
3
+ /// <reference types="mongoose/types/collection" />
4
+ /// <reference types="mongoose/types/connection" />
5
+ /// <reference types="mongoose/types/cursor" />
6
+ /// <reference types="mongoose/types/document" />
7
+ /// <reference types="mongoose/types/error" />
8
+ /// <reference types="mongoose/types/expressions" />
9
+ /// <reference types="mongoose/types/helpers" />
10
+ /// <reference types="mongoose/types/middlewares" />
11
+ /// <reference types="mongoose/types/indexes" />
12
+ /// <reference types="mongoose/types/models" />
13
+ /// <reference types="mongoose/types/mongooseoptions" />
14
+ /// <reference types="mongoose/types/pipelinestage" />
15
+ /// <reference types="mongoose/types/populate" />
16
+ /// <reference types="mongoose/types/query" />
17
+ /// <reference types="mongoose/types/schemaoptions" />
18
+ /// <reference types="mongoose/types/schematypes" />
19
+ /// <reference types="mongoose/types/session" />
20
+ /// <reference types="mongoose/types/types" />
21
+ /// <reference types="mongoose/types/utility" />
22
+ /// <reference types="mongoose/types/validation" />
23
+ /// <reference types="mongoose/types/virtuals" />
24
+ /// <reference types="mongoose/types/inferschematype" />
25
+ import type { Model, Schema } from 'mongoose';
26
+ import type IPluginOptions from './interfaces/IPluginOptions';
27
+ export declare const patchEventEmitter: {
28
+ addListener(eventName: string | symbol, listener: (...args: any[]) => void): any;
29
+ on(eventName: string | symbol, listener: (...args: any[]) => void): any;
30
+ once(eventName: string | symbol, listener: (...args: any[]) => void): any;
31
+ removeListener(eventName: string | symbol, listener: (...args: any[]) => void): any;
32
+ off(eventName: string | symbol, listener: (...args: any[]) => void): any;
33
+ removeAllListeners(event?: string | symbol | undefined): any;
34
+ setMaxListeners(n: number): any;
35
+ getMaxListeners(): number;
36
+ listeners(eventName: string | symbol): Function[];
37
+ rawListeners(eventName: string | symbol): Function[];
38
+ emit(eventName: string | symbol, ...args: any[]): boolean;
39
+ listenerCount(eventName: string | symbol): number;
40
+ prependListener(eventName: string | symbol, listener: (...args: any[]) => void): any;
41
+ prependOnceListener(eventName: string | symbol, listener: (...args: any[]) => void): any;
42
+ eventNames(): (string | symbol)[];
43
+ };
44
+ export declare const patchHistoryPlugin: <T>(schema: Schema<T, Model<T, any, any, any, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, import("mongoose").ObtainDocumentType<any, T, import("mongoose").DefaultSchemaOptions>>, opts: IPluginOptions<T>) => void;
45
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAKA,OAAO,KAAK,EAAmC,KAAK,EAAiB,MAAM,EAAS,MAAM,UAAU,CAAA;AAEpG,OAAO,KAAK,cAAc,MAAM,6BAA6B,CAAA;AAuG7D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;CAAK,CAAA;AAQnC,eAAO,MAAM,kBAAkB,oOAAoE,IAoJlG,CAAA"}
@@ -0,0 +1,10 @@
1
+ export default {
2
+ mongodbMemoryServerOptions: {
3
+ binary: {
4
+ skipMD5: true
5
+ },
6
+ autoStart: false,
7
+ instance: {}
8
+ },
9
+ useSharedDBForAllJestWorkers: false
10
+ }
package/jest.config.ts ADDED
@@ -0,0 +1,35 @@
1
+ // For a detailed explanation regarding each configuration property, visit:
2
+ // https://jestjs.io/docs/en/configuration.html
3
+ import { recursive } from 'merge'
4
+ import mongo from '@shelf/jest-mongodb/jest-preset'
5
+
6
+ const config = recursive(mongo, {
7
+ roots: [
8
+ '<rootDir>/src/',
9
+ '<rootDir>/tests/'
10
+ ],
11
+ clearMocks: true,
12
+ collectCoverage: true,
13
+ collectCoverageFrom: [
14
+ 'src/**/*.[jt]s?(x)',
15
+ '!src/bin.ts',
16
+ '!src/**/*.d.ts',
17
+ '!src/interfaces/**/*.[jt]s?(x)',
18
+ '!src/template.ts'
19
+ ],
20
+ coverageDirectory: 'coverage',
21
+ testMatch: [
22
+ '<rootDir>/tests/**/*.test.ts'
23
+ ],
24
+ transform: {
25
+ '^.+\\.tsx?$': '@swc/jest'
26
+ },
27
+ testPathIgnorePatterns: [
28
+ 'node_modules'
29
+ ],
30
+ watchPathIgnorePatterns: [
31
+ 'globalConfig'
32
+ ]
33
+ })
34
+
35
+ export default config
package/package.json ADDED
@@ -0,0 +1,101 @@
1
+ {
2
+ "name": "ts-patch-mongoose",
3
+ "version": "1.0.1",
4
+ "description": "Patch history & events for mongoose models",
5
+ "author": "Alex Eagle",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git://github.com/ilovepixelart/ts-patch-mongoose.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/ilovepixelart/ts-patch-mongoose/issues"
13
+ },
14
+ "homepage": "https://github.com/ilovepixelart/ts-patch-mongoose#readme",
15
+ "directories": {
16
+ "examples": "examples"
17
+ },
18
+ "keywords": [
19
+ "mongoose",
20
+ "plugin",
21
+ "mongo",
22
+ "schema",
23
+ "db",
24
+ "nosql",
25
+ "ts",
26
+ "typescript",
27
+ "swc",
28
+ "patch",
29
+ "history",
30
+ "event",
31
+ "emit",
32
+ "create",
33
+ "update",
34
+ "delete"
35
+ ],
36
+ "engines": {
37
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
38
+ },
39
+ "files": [
40
+ "dist",
41
+ "src",
42
+ "tests",
43
+ ".swcrc",
44
+ "tsconfig.json",
45
+ "jest.config.ts",
46
+ "jest-mongodb-config.ts",
47
+ ".eslintrc",
48
+ ".eslintignore"
49
+ ],
50
+ "main": "dist/cjs/plugin.js",
51
+ "module": "dist/esm/plugin.js",
52
+ "types": "dist/types/plugin.d.js",
53
+ "scripts": {
54
+ "lint": "eslint . --ext .js,.ts",
55
+ "lint:fix": "eslint . --fix --ext .js,.ts",
56
+ "cleanup": "node -r @swc/register tools/cleanup.ts",
57
+ "build": "npm run build:cjs && npm run build:esm && npm run build:types",
58
+ "build:cjs": "npm run cleanup cjs && tsc -p config/tsconfig.cjs.json",
59
+ "build:esm": "npm run cleanup esm && tsc -p config/tsconfig.esm.json",
60
+ "build:types": "npm run cleanup types && tsc -p config/tsconfig.types.json",
61
+ "package": "npm run build && npm pack",
62
+ "test": "jest --config jest.config.ts --detectOpenHandles --coverage",
63
+ "test:open": "npm run test && open-cli coverage/lcov-report/index.html"
64
+ },
65
+ "dependencies": {
66
+ "fast-json-patch": "^3.1.1",
67
+ "lodash": "^4.17.21",
68
+ "omit-deep": "^0.3.0",
69
+ "power-assign": "^0.2.10"
70
+ },
71
+ "devDependencies": {
72
+ "@shelf/jest-mongodb": "4.1.7",
73
+ "@swc/cli": "0.1.62",
74
+ "@swc/core": "1.3.46",
75
+ "@swc/helpers": "0.5.0",
76
+ "@swc/jest": "0.2.24",
77
+ "@swc/register": "0.1.10",
78
+ "@types/jest": "29.5.0",
79
+ "@types/lodash": "^4.14.192",
80
+ "@types/node": "18.15.11",
81
+ "@typescript-eslint/eslint-plugin": "5.57.1",
82
+ "@typescript-eslint/parser": "5.57.1",
83
+ "eslint": "8.38.0",
84
+ "eslint-config-standard": "17.0.0",
85
+ "eslint-plugin-import": "2.27.5",
86
+ "eslint-plugin-jest": "27.2.1",
87
+ "eslint-plugin-jest-formatting": "3.1.0",
88
+ "eslint-plugin-n": "15.7.0",
89
+ "eslint-plugin-node": "11.1.0",
90
+ "eslint-plugin-promise": "6.1.1",
91
+ "jest": "29.5.0",
92
+ "merge": "2.1.1",
93
+ "mongoose": "6.10.5",
94
+ "open-cli": "7.2.0",
95
+ "ts-node": "10.9.1",
96
+ "typescript": "5.0.4"
97
+ },
98
+ "peerDependencies": {
99
+ "mongoose": ">=6.10.5"
100
+ }
101
+ }
package/src/em.ts ADDED
@@ -0,0 +1,6 @@
1
+ import EventEmitter from 'events'
2
+
3
+ class PatchEventEmitter extends EventEmitter {}
4
+ const em = new PatchEventEmitter()
5
+
6
+ export default em
@@ -0,0 +1,13 @@
1
+ import type { HydratedDocument, Types } from 'mongoose'
2
+
3
+ interface IContext<T> {
4
+ op: string
5
+ modelName: string
6
+ collectionName: string
7
+ isNew?: boolean
8
+ oldDoc?: HydratedDocument<T>
9
+ deletedDocs?: HydratedDocument<T>[]
10
+ updatedIds?: Types.ObjectId[]
11
+ }
12
+
13
+ export default IContext
@@ -0,0 +1,14 @@
1
+ import type { Types } from 'mongoose'
2
+ import type { Operation } from 'fast-json-patch'
3
+
4
+ interface IHistory {
5
+ op: string
6
+ modelName: string,
7
+ collectionName: string
8
+ collectionId: Types.ObjectId
9
+ version: number
10
+ doc?: object
11
+ patch?: Operation[]
12
+ }
13
+
14
+ export default IHistory
@@ -0,0 +1,6 @@
1
+ import type { Query } from 'mongoose'
2
+ import type IContext from './IContext'
3
+
4
+ type IHookContext<T> = Query<T, T> & { op: string, _context: IContext<T> }
5
+
6
+ export default IHookContext
@@ -0,0 +1,14 @@
1
+ import type { HydratedDocument } from 'mongoose'
2
+
3
+ interface IPluginOptions<T> {
4
+ modelName?: string
5
+ collectionName?: string
6
+ eventUpdated?: string
7
+ eventCreated?: string
8
+ eventDeleted?: string
9
+ patchHistoryDisabled?: boolean
10
+ preDeleteManyCallback?: (docs: HydratedDocument<T>[]) => Promise<void>
11
+ omit?: string[]
12
+ }
13
+
14
+ export default IPluginOptions
@@ -0,0 +1,39 @@
1
+ import { Schema, model } from 'mongoose'
2
+
3
+ import type IHistory from '../interfaces/IHistory'
4
+
5
+ const HistorySchema = new Schema<IHistory>({
6
+ op: {
7
+ type: String,
8
+ required: true
9
+ },
10
+ modelName: {
11
+ type: String,
12
+ required: true
13
+ },
14
+ collectionName: {
15
+ type: String,
16
+ required: true
17
+ },
18
+ collectionId: {
19
+ type: Schema.Types.ObjectId,
20
+ required: true
21
+ },
22
+ doc: {
23
+ type: Object
24
+ },
25
+ patch: {
26
+ type: Array
27
+ },
28
+ version: {
29
+ type: Number,
30
+ min: 0,
31
+ default: 0
32
+ }
33
+ }, { timestamps: true })
34
+
35
+ HistorySchema.index({ op: 1, modelName: 1, collectionName: 1, collectionId: 1, version: 1 })
36
+
37
+ const History = model('History', HistorySchema, 'history')
38
+
39
+ export default History
@@ -0,0 +1,3 @@
1
+ declare module 'omit-deep' {
2
+ export default function omitDeep<T>(value: T, keys: string[]): Partial<T>
3
+ }