ts-patch-mongoose 2.8.2 → 2.9.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.
package/README.md CHANGED
@@ -81,20 +81,18 @@ export const BOOK_UPDATED = 'book-updated'
81
81
  export const BOOK_DELETED = 'book-deleted'
82
82
  ```
83
83
 
84
- Create your interface `IBook.ts`
84
+ Create your type `Book` in `types.ts`
85
85
 
86
86
  ```typescript
87
87
  import type { Types } from 'mongoose'
88
88
 
89
- interface IBook {
89
+ export type Book = {
90
90
  title: string
91
91
  description?: string
92
92
  authorId: Types.ObjectId
93
93
  createdAt?: Date
94
94
  updatedAt?: Date
95
95
  }
96
-
97
- export default IBook
98
96
  ```
99
97
 
100
98
  Setup your mongoose model `Book.ts`
@@ -103,7 +101,7 @@ Setup your mongoose model `Book.ts`
103
101
  import { Schema, model } from 'mongoose'
104
102
 
105
103
  import type { HydratedDocument, Types } from 'mongoose'
106
- import type IBook from '../interfaces/IBook'
104
+ import type { Book } from '../types'
107
105
 
108
106
  import { patchHistoryPlugin, setPatchHistoryTTL } from 'ts-patch-mongoose'
109
107
  import { BOOK_CREATED, BOOK_UPDATED, BOOK_DELETED } from '../constants/events'
@@ -114,7 +112,7 @@ import { BOOK_CREATED, BOOK_UPDATED, BOOK_DELETED } from '../constants/events'
114
112
  // Execute this method after you connected to you database somewhere in your application.
115
113
  setPatchHistoryTTL('1 month')
116
114
 
117
- const BookSchema = new Schema<IBook>({
115
+ const BookSchema = new Schema<Book>({
118
116
  name: {
119
117
  title: String,
120
118
  required: true
@@ -142,21 +140,21 @@ BookSchema.plugin(patchHistoryPlugin, {
142
140
 
143
141
  // Code bellow is abstract example, you can use any other way to get user, reason, metadata
144
142
  // These three properties will be added to patch history document automatically and give you flexibility to track who, why and when made changes to your documents
145
- getUser: async () => {
143
+ getUser: async (doc: HydratedDocument<Book>) => {
146
144
  // For example: get user from http context
147
145
  // You should return an object, in case you want to save user to patch history
148
146
  return httpContext.get('user') as Record<string, unknown>
149
147
  },
150
148
 
151
149
  // Reason of document (create/update/delete) like: 'Excel upload', 'Manual update', 'API call', etc.
152
- getReason: async () => {
150
+ getReason: async (doc: HydratedDocument<Book>) => {
153
151
  // For example: get reason from http context, or any other place of your application
154
152
  // You shout return a string, in case you want to save reason to patch history
155
153
  return httpContext.get('reason') as string
156
154
  },
157
155
 
158
156
  // You can provide any information you want to save in along with patch history
159
- getMetadata: async () => {
157
+ getMetadata: async (doc: HydratedDocument<Book>) => {
160
158
  // For example: get metadata from http context, or any other place of your application
161
159
  // You should return an object, in case you want to save metadata to patch history
162
160
  return httpContext.get('metadata') as Record<string, unknown>
package/dist/index.cjs CHANGED
@@ -108,29 +108,29 @@ function getObjectOmit(opts, doc) {
108
108
  }
109
109
  return doc;
110
110
  }
111
- async function getUser(opts) {
111
+ async function getUser(opts, doc) {
112
112
  if (_.isFunction(opts.getUser)) {
113
- return await opts.getUser();
113
+ return await opts.getUser(doc);
114
114
  }
115
115
  return void 0;
116
116
  }
117
- async function getReason(opts) {
117
+ async function getReason(opts, doc) {
118
118
  if (_.isFunction(opts.getReason)) {
119
- return await opts.getReason();
119
+ return await opts.getReason(doc);
120
120
  }
121
121
  return void 0;
122
122
  }
123
- async function getMetadata(opts) {
123
+ async function getMetadata(opts, doc) {
124
124
  if (_.isFunction(opts.getMetadata)) {
125
- return await opts.getMetadata();
125
+ return await opts.getMetadata(doc);
126
126
  }
127
127
  return void 0;
128
128
  }
129
129
  function getValue(item) {
130
130
  return item.status === "fulfilled" ? item.value : void 0;
131
131
  }
132
- async function getData(opts) {
133
- return Promise.allSettled([getUser(opts), getReason(opts), getMetadata(opts)]).then(([user, reason, metadata]) => {
132
+ async function getData(opts, doc) {
133
+ return Promise.allSettled([getUser(opts, doc), getReason(opts, doc), getMetadata(opts, doc)]).then(([user, reason, metadata]) => {
134
134
  return [getValue(user), getValue(reason), getValue(metadata)];
135
135
  });
136
136
  }
@@ -145,13 +145,13 @@ async function bulkPatch(opts, context, eventKey, docsKey) {
145
145
  const docs = context[docsKey];
146
146
  const key = eventKey === "eventCreated" ? "doc" : "oldDoc";
147
147
  if (_.isEmpty(docs) || !event && !history) return;
148
- const [user, reason, metadata] = await getData(opts);
149
148
  const chunks = _.chunk(docs, 1e3);
150
149
  for await (const chunk of chunks) {
151
150
  const bulk = [];
152
151
  for (const doc of chunk) {
153
152
  emitEvent(context, event, { [key]: doc });
154
153
  if (history) {
154
+ const [user, reason, metadata] = await getData(opts, doc);
155
155
  bulk.push({
156
156
  insertOne: {
157
157
  document: {
@@ -193,7 +193,7 @@ async function updatePatch(opts, context, current, original) {
193
193
  if (lastHistory && lastHistory.version >= 0) {
194
194
  version = lastHistory.version + 1;
195
195
  }
196
- const [user, reason, metadata] = await getData(opts);
196
+ const [user, reason, metadata] = await getData(opts, current);
197
197
  await HistoryModel.create({
198
198
  op: context.op,
199
199
  modelName: context.modelName,
package/dist/index.d.cts CHANGED
@@ -41,9 +41,9 @@ interface PluginOptions<T> {
41
41
  eventUpdated?: string;
42
42
  eventCreated?: string;
43
43
  eventDeleted?: string;
44
- getUser?: () => Promise<User> | User;
45
- getReason?: () => Promise<string> | string;
46
- getMetadata?: () => Promise<Metadata> | Metadata;
44
+ getUser?: (doc: HydratedDocument<T>) => Promise<User> | User;
45
+ getReason?: (doc: HydratedDocument<T>) => Promise<string> | string;
46
+ getMetadata?: (doc: HydratedDocument<T>) => Promise<Metadata> | Metadata;
47
47
  omit?: string[];
48
48
  patchHistoryDisabled?: boolean;
49
49
  preDelete?: (docs: HydratedDocument<T>[]) => Promise<void>;
package/dist/index.d.mts CHANGED
@@ -41,9 +41,9 @@ interface PluginOptions<T> {
41
41
  eventUpdated?: string;
42
42
  eventCreated?: string;
43
43
  eventDeleted?: string;
44
- getUser?: () => Promise<User> | User;
45
- getReason?: () => Promise<string> | string;
46
- getMetadata?: () => Promise<Metadata> | Metadata;
44
+ getUser?: (doc: HydratedDocument<T>) => Promise<User> | User;
45
+ getReason?: (doc: HydratedDocument<T>) => Promise<string> | string;
46
+ getMetadata?: (doc: HydratedDocument<T>) => Promise<Metadata> | Metadata;
47
47
  omit?: string[];
48
48
  patchHistoryDisabled?: boolean;
49
49
  preDelete?: (docs: HydratedDocument<T>[]) => Promise<void>;
package/dist/index.mjs CHANGED
@@ -106,29 +106,29 @@ function getObjectOmit(opts, doc) {
106
106
  }
107
107
  return doc;
108
108
  }
109
- async function getUser(opts) {
109
+ async function getUser(opts, doc) {
110
110
  if (_.isFunction(opts.getUser)) {
111
- return await opts.getUser();
111
+ return await opts.getUser(doc);
112
112
  }
113
113
  return void 0;
114
114
  }
115
- async function getReason(opts) {
115
+ async function getReason(opts, doc) {
116
116
  if (_.isFunction(opts.getReason)) {
117
- return await opts.getReason();
117
+ return await opts.getReason(doc);
118
118
  }
119
119
  return void 0;
120
120
  }
121
- async function getMetadata(opts) {
121
+ async function getMetadata(opts, doc) {
122
122
  if (_.isFunction(opts.getMetadata)) {
123
- return await opts.getMetadata();
123
+ return await opts.getMetadata(doc);
124
124
  }
125
125
  return void 0;
126
126
  }
127
127
  function getValue(item) {
128
128
  return item.status === "fulfilled" ? item.value : void 0;
129
129
  }
130
- async function getData(opts) {
131
- return Promise.allSettled([getUser(opts), getReason(opts), getMetadata(opts)]).then(([user, reason, metadata]) => {
130
+ async function getData(opts, doc) {
131
+ return Promise.allSettled([getUser(opts, doc), getReason(opts, doc), getMetadata(opts, doc)]).then(([user, reason, metadata]) => {
132
132
  return [getValue(user), getValue(reason), getValue(metadata)];
133
133
  });
134
134
  }
@@ -143,13 +143,13 @@ async function bulkPatch(opts, context, eventKey, docsKey) {
143
143
  const docs = context[docsKey];
144
144
  const key = eventKey === "eventCreated" ? "doc" : "oldDoc";
145
145
  if (_.isEmpty(docs) || !event && !history) return;
146
- const [user, reason, metadata] = await getData(opts);
147
146
  const chunks = _.chunk(docs, 1e3);
148
147
  for await (const chunk of chunks) {
149
148
  const bulk = [];
150
149
  for (const doc of chunk) {
151
150
  emitEvent(context, event, { [key]: doc });
152
151
  if (history) {
152
+ const [user, reason, metadata] = await getData(opts, doc);
153
153
  bulk.push({
154
154
  insertOne: {
155
155
  document: {
@@ -191,7 +191,7 @@ async function updatePatch(opts, context, current, original) {
191
191
  if (lastHistory && lastHistory.version >= 0) {
192
192
  version = lastHistory.version + 1;
193
193
  }
194
- const [user, reason, metadata] = await getData(opts);
194
+ const [user, reason, metadata] = await getData(opts, current);
195
195
  await HistoryModel.create({
196
196
  op: context.op,
197
197
  modelName: context.modelName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-patch-mongoose",
3
- "version": "2.8.2",
3
+ "version": "2.9.0",
4
4
  "description": "Patch history & events for mongoose models",
5
5
  "author": "ilovepixelart",
6
6
  "license": "MIT",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "devDependencies": {
85
85
  "@biomejs/biome": "1.9.4",
86
- "@types/node": "22.14.0",
86
+ "@types/node": "22.14.1",
87
87
  "@vitest/coverage-v8": "3.1.1",
88
88
  "mongodb-memory-server": "10.1.4",
89
89
  "mongoose": "8.13.2",
package/src/patch.ts CHANGED
@@ -30,23 +30,23 @@ export function getObjectOmit<T>(opts: PluginOptions<T>, doc: HydratedDocument<T
30
30
  return doc
31
31
  }
32
32
 
33
- export async function getUser<T>(opts: PluginOptions<T>): Promise<User | undefined> {
33
+ export async function getUser<T>(opts: PluginOptions<T>, doc: HydratedDocument<T>): Promise<User | undefined> {
34
34
  if (_.isFunction(opts.getUser)) {
35
- return await opts.getUser()
35
+ return await opts.getUser(doc)
36
36
  }
37
37
  return undefined
38
38
  }
39
39
 
40
- export async function getReason<T>(opts: PluginOptions<T>): Promise<string | undefined> {
40
+ export async function getReason<T>(opts: PluginOptions<T>, doc: HydratedDocument<T>): Promise<string | undefined> {
41
41
  if (_.isFunction(opts.getReason)) {
42
- return await opts.getReason()
42
+ return await opts.getReason(doc)
43
43
  }
44
44
  return undefined
45
45
  }
46
46
 
47
- export async function getMetadata<T>(opts: PluginOptions<T>): Promise<Metadata | undefined> {
47
+ export async function getMetadata<T>(opts: PluginOptions<T>, doc: HydratedDocument<T>): Promise<Metadata | undefined> {
48
48
  if (_.isFunction(opts.getMetadata)) {
49
- return await opts.getMetadata()
49
+ return await opts.getMetadata(doc)
50
50
  }
51
51
  return undefined
52
52
  }
@@ -55,8 +55,8 @@ export function getValue<T>(item: PromiseSettledResult<T>): T | undefined {
55
55
  return item.status === 'fulfilled' ? item.value : undefined
56
56
  }
57
57
 
58
- export async function getData<T>(opts: PluginOptions<T>): Promise<[User | undefined, string | undefined, Metadata | undefined]> {
59
- return Promise.allSettled([getUser(opts), getReason(opts), getMetadata(opts)]).then(([user, reason, metadata]) => {
58
+ export async function getData<T>(opts: PluginOptions<T>, doc: HydratedDocument<T>): Promise<[User | undefined, string | undefined, Metadata | undefined]> {
59
+ return Promise.allSettled([getUser(opts, doc), getReason(opts, doc), getMetadata(opts, doc)]).then(([user, reason, metadata]) => {
60
60
  return [getValue(user), getValue(reason), getValue(metadata)]
61
61
  })
62
62
  }
@@ -75,8 +75,6 @@ export async function bulkPatch<T>(opts: PluginOptions<T>, context: PatchContext
75
75
 
76
76
  if (_.isEmpty(docs) || (!event && !history)) return
77
77
 
78
- const [user, reason, metadata] = await getData(opts)
79
-
80
78
  const chunks = _.chunk(docs, 1000)
81
79
  for await (const chunk of chunks) {
82
80
  const bulk = []
@@ -85,6 +83,7 @@ export async function bulkPatch<T>(opts: PluginOptions<T>, context: PatchContext
85
83
  emitEvent(context, event, { [key]: doc })
86
84
 
87
85
  if (history) {
86
+ const [user, reason, metadata] = await getData(opts, doc)
88
87
  bulk.push({
89
88
  insertOne: {
90
89
  document: {
@@ -138,8 +137,7 @@ export async function updatePatch<T>(opts: PluginOptions<T>, context: PatchConte
138
137
  version = lastHistory.version + 1
139
138
  }
140
139
 
141
- const [user, reason, metadata] = await getData(opts)
142
-
140
+ const [user, reason, metadata] = await getData(opts, current)
143
141
  await HistoryModel.create({
144
142
  op: context.op,
145
143
  modelName: context.modelName,
package/src/types.ts CHANGED
@@ -43,9 +43,9 @@ export interface PluginOptions<T> {
43
43
  eventUpdated?: string
44
44
  eventCreated?: string
45
45
  eventDeleted?: string
46
- getUser?: () => Promise<User> | User
47
- getReason?: () => Promise<string> | string
48
- getMetadata?: () => Promise<Metadata> | Metadata
46
+ getUser?: (doc: HydratedDocument<T>) => Promise<User> | User
47
+ getReason?: (doc: HydratedDocument<T>) => Promise<string> | string
48
+ getMetadata?: (doc: HydratedDocument<T>) => Promise<Metadata> | Metadata
49
49
  omit?: string[]
50
50
  patchHistoryDisabled?: boolean
51
51
  preDelete?: (docs: HydratedDocument<T>[]) => Promise<void>