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 +7 -9
- package/dist/index.cjs +10 -10
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +10 -10
- package/package.json +2 -2
- package/src/patch.ts +10 -12
- package/src/types.ts +3 -3
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
|
|
84
|
+
Create your type `Book` in `types.ts`
|
|
85
85
|
|
|
86
86
|
```typescript
|
|
87
87
|
import type { Types } from 'mongoose'
|
|
88
88
|
|
|
89
|
-
|
|
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
|
|
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<
|
|
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.
|
|
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.
|
|
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>
|