@declaro/data 2.0.0-beta.138 → 2.0.0-beta.139
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/dist/browser/index.js +14 -14
- package/dist/browser/index.js.map +5 -5
- package/dist/node/index.cjs +22 -10
- package/dist/node/index.cjs.map +5 -5
- package/dist/node/index.js +22 -10
- package/dist/node/index.js.map +5 -5
- package/dist/ts/domain/events/event-types.d.ts +3 -0
- package/dist/ts/domain/events/event-types.d.ts.map +1 -1
- package/dist/ts/domain/events/mutation-event.d.ts +32 -0
- package/dist/ts/domain/events/mutation-event.d.ts.map +1 -1
- package/dist/ts/domain/services/model-service.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/domain/events/event-types.ts +3 -0
- package/src/domain/events/mutation-event.ts +37 -0
- package/src/domain/services/model-service.test.ts +226 -7
- package/src/domain/services/model-service.ts +86 -19
|
@@ -15,6 +15,9 @@ export declare enum ModelMutationAction {
|
|
|
15
15
|
Update = "update",
|
|
16
16
|
BeforeUpdate = "beforeUpdate",
|
|
17
17
|
AfterUpdate = "afterUpdate",
|
|
18
|
+
Duplicate = "duplicate",
|
|
19
|
+
BeforeDuplicate = "beforeDuplicate",
|
|
20
|
+
AfterDuplicate = "afterDuplicate",
|
|
18
21
|
Remove = "remove",
|
|
19
22
|
BeforeRemove = "beforeRemove",
|
|
20
23
|
AfterRemove = "afterRemove",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-types.d.ts","sourceRoot":"","sources":["../../../../src/domain/events/event-types.ts"],"names":[],"mappings":"AAAA,oBAAY,eAAe;IACvB,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,UAAU,eAAe;CAC5B;AAED,oBAAY,mBAAmB;IAC3B,MAAM,WAAW;IACjB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,MAAM,WAAW;IACjB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,MAAM,WAAW;IACjB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,OAAO,YAAY;IACnB,aAAa,kBAAkB;IAC/B,YAAY,iBAAiB;IAC7B,UAAU,eAAe;IACzB,gBAAgB,qBAAqB;IACrC,eAAe,oBAAoB;IACnC,0BAA0B,+BAA+B;IACzD,gCAAgC,qCAAqC;IACrE,+BAA+B,oCAAoC;IACnE,iBAAiB,sBAAsB;IACvC,uBAAuB,4BAA4B;IACnD,sBAAsB,2BAA2B;CACpD"}
|
|
1
|
+
{"version":3,"file":"event-types.d.ts","sourceRoot":"","sources":["../../../../src/domain/events/event-types.ts"],"names":[],"mappings":"AAAA,oBAAY,eAAe;IACvB,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,UAAU,eAAe;CAC5B;AAED,oBAAY,mBAAmB;IAC3B,MAAM,WAAW;IACjB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,MAAM,WAAW;IACjB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,SAAS,cAAc;IACvB,eAAe,oBAAoB;IACnC,cAAc,mBAAmB;IACjC,MAAM,WAAW;IACjB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,OAAO,YAAY;IACnB,aAAa,kBAAkB;IAC/B,YAAY,iBAAiB;IAC7B,UAAU,eAAe;IACzB,gBAAgB,qBAAqB;IACrC,eAAe,oBAAoB;IACnC,0BAA0B,+BAA+B;IACzD,gCAAgC,qCAAqC;IACrE,+BAA+B,oCAAoC;IACnE,iBAAiB,sBAAsB;IACvC,uBAAuB,4BAA4B;IACnD,sBAAsB,2BAA2B;CACpD"}
|
|
@@ -3,6 +3,38 @@ import { RequestEvent, type IRequestEventMeta } from './request-event';
|
|
|
3
3
|
export interface IMutationEventMeta<TResult> extends IRequestEventMeta {
|
|
4
4
|
existing?: TResult;
|
|
5
5
|
}
|
|
6
|
+
export interface ICreateEventMeta<TResult, TInput> extends IMutationEventMeta<TResult> {
|
|
7
|
+
args?: {
|
|
8
|
+
input: TInput;
|
|
9
|
+
options?: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface IUpdateEventMeta<TResult, TLookup, TInput> extends IMutationEventMeta<TResult> {
|
|
13
|
+
args?: {
|
|
14
|
+
lookup: TLookup;
|
|
15
|
+
input: TInput;
|
|
16
|
+
options?: Record<string, unknown>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface IRemoveEventMeta<TResult, TLookup> extends IMutationEventMeta<TResult> {
|
|
20
|
+
args?: {
|
|
21
|
+
lookup: TLookup;
|
|
22
|
+
options?: Record<string, unknown>;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface IRestoreEventMeta<TResult, TLookup> extends IMutationEventMeta<TResult> {
|
|
26
|
+
args?: {
|
|
27
|
+
lookup: TLookup;
|
|
28
|
+
options?: Record<string, unknown>;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface IDuplicateEventMeta<TResult, TLookup, TInput> extends IMutationEventMeta<TResult> {
|
|
32
|
+
args?: {
|
|
33
|
+
lookup: TLookup;
|
|
34
|
+
overrides?: Partial<TInput>;
|
|
35
|
+
options?: Record<string, unknown>;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
6
38
|
export declare class MutationEvent<TResult, TInput, TMeta extends IMutationEventMeta<TResult> = IMutationEventMeta<TResult>> extends RequestEvent<TResult, TInput, TMeta> {
|
|
7
39
|
constructor(descriptor: IActionDescriptorInput, input: TInput, meta?: TMeta);
|
|
8
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutation-event.d.ts","sourceRoot":"","sources":["../../../../src/domain/events/mutation-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEtE,MAAM,WAAW,kBAAkB,CAAC,OAAO,CAAE,SAAQ,iBAAiB;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,qBAAa,aAAa,CACtB,OAAO,EACP,MAAM,EACN,KAAK,SAAS,kBAAkB,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,CACzE,SAAQ,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;gBAC9B,UAAU,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,KAAmB;CAG3F"}
|
|
1
|
+
{"version":3,"file":"mutation-event.d.ts","sourceRoot":"","sources":["../../../../src/domain/events/mutation-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEtE,MAAM,WAAW,kBAAkB,CAAC,OAAO,CAAE,SAAQ,iBAAiB;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAE,SAAQ,kBAAkB,CAAC,OAAO,CAAC;IAClF,IAAI,CAAC,EAAE;QACH,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;CACJ;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAE,SAAQ,kBAAkB,CAAC,OAAO,CAAC;IAC3F,IAAI,CAAC,EAAE;QACH,MAAM,EAAE,OAAO,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;CACJ;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAE,SAAQ,kBAAkB,CAAC,OAAO,CAAC;IACnF,IAAI,CAAC,EAAE;QACH,MAAM,EAAE,OAAO,CAAA;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;CACJ;AAED,MAAM,WAAW,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAE,SAAQ,kBAAkB,CAAC,OAAO,CAAC;IACpF,IAAI,CAAC,EAAE;QACH,MAAM,EAAE,OAAO,CAAA;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;CACJ;AAED,MAAM,WAAW,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAE,SAAQ,kBAAkB,CAAC,OAAO,CAAC;IAC9F,IAAI,CAAC,EAAE;QACH,MAAM,EAAE,OAAO,CAAA;QACf,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;QAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;CACJ;AAED,qBAAa,aAAa,CACtB,OAAO,EACP,MAAM,EACN,KAAK,SAAS,kBAAkB,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,CACzE,SAAQ,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;gBAC9B,UAAU,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,KAAmB;CAG3F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-service.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/model-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAgC,MAAM,eAAe,CAAA;AACnG,OAAO,KAAK,EACR,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,YAAY,EACf,MAAM,qCAAqC,CAAA;
|
|
1
|
+
{"version":3,"file":"model-service.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/model-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@declaro/data",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.139",
|
|
4
4
|
"description": "A data-mapper framework for managing application data across integrated systems.",
|
|
5
5
|
"main": "dist/node/index.cjs",
|
|
6
6
|
"module": "dist/node/index.js",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"@declaro/zod": "^2.0.0-beta.51"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@declaro/auth": "^2.0.0-beta.
|
|
26
|
-
"@declaro/core": "^2.0.0-beta.
|
|
27
|
-
"@declaro/zod": "^2.0.0-beta.
|
|
25
|
+
"@declaro/auth": "^2.0.0-beta.139",
|
|
26
|
+
"@declaro/core": "^2.0.0-beta.139",
|
|
27
|
+
"@declaro/zod": "^2.0.0-beta.139",
|
|
28
28
|
"crypto-browserify": "^3.12.1",
|
|
29
29
|
"typescript": "^5.8.3",
|
|
30
30
|
"uuid": "^11.1.0",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"browser": "./dist/browser/index.js",
|
|
45
45
|
"default": "./dist/node/index.js"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "0f58755975fc8dfa4b3769e2a69f5bbc7e67445f"
|
|
48
48
|
}
|
|
@@ -16,6 +16,9 @@ export enum ModelMutationAction {
|
|
|
16
16
|
Update = 'update',
|
|
17
17
|
BeforeUpdate = 'beforeUpdate',
|
|
18
18
|
AfterUpdate = 'afterUpdate',
|
|
19
|
+
Duplicate = 'duplicate',
|
|
20
|
+
BeforeDuplicate = 'beforeDuplicate',
|
|
21
|
+
AfterDuplicate = 'afterDuplicate',
|
|
19
22
|
Remove = 'remove',
|
|
20
23
|
BeforeRemove = 'beforeRemove',
|
|
21
24
|
AfterRemove = 'afterRemove',
|
|
@@ -5,6 +5,43 @@ export interface IMutationEventMeta<TResult> extends IRequestEventMeta {
|
|
|
5
5
|
existing?: TResult
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
export interface ICreateEventMeta<TResult, TInput> extends IMutationEventMeta<TResult> {
|
|
9
|
+
args?: {
|
|
10
|
+
input: TInput
|
|
11
|
+
options?: Record<string, unknown>
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface IUpdateEventMeta<TResult, TLookup, TInput> extends IMutationEventMeta<TResult> {
|
|
16
|
+
args?: {
|
|
17
|
+
lookup: TLookup
|
|
18
|
+
input: TInput
|
|
19
|
+
options?: Record<string, unknown>
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface IRemoveEventMeta<TResult, TLookup> extends IMutationEventMeta<TResult> {
|
|
24
|
+
args?: {
|
|
25
|
+
lookup: TLookup
|
|
26
|
+
options?: Record<string, unknown>
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface IRestoreEventMeta<TResult, TLookup> extends IMutationEventMeta<TResult> {
|
|
31
|
+
args?: {
|
|
32
|
+
lookup: TLookup
|
|
33
|
+
options?: Record<string, unknown>
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface IDuplicateEventMeta<TResult, TLookup, TInput> extends IMutationEventMeta<TResult> {
|
|
38
|
+
args?: {
|
|
39
|
+
lookup: TLookup
|
|
40
|
+
overrides?: Partial<TInput>
|
|
41
|
+
options?: Record<string, unknown>
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
8
45
|
export class MutationEvent<
|
|
9
46
|
TResult,
|
|
10
47
|
TInput,
|
|
@@ -26,6 +26,8 @@ describe('ModelService', () => {
|
|
|
26
26
|
const afterRemoveSpy = mock((event) => {})
|
|
27
27
|
const beforeRestoreSpy = mock((event) => {})
|
|
28
28
|
const afterRestoreSpy = mock((event) => {})
|
|
29
|
+
const beforeDuplicateSpy = mock((event) => {})
|
|
30
|
+
const afterDuplicateSpy = mock((event) => {})
|
|
29
31
|
|
|
30
32
|
beforeEach(() => {
|
|
31
33
|
emitter.on('books::book.beforeCreate', beforeCreateSpy)
|
|
@@ -36,6 +38,8 @@ describe('ModelService', () => {
|
|
|
36
38
|
emitter.on('books::book.afterRemove', afterRemoveSpy)
|
|
37
39
|
emitter.on('books::book.beforeRestore', beforeRestoreSpy)
|
|
38
40
|
emitter.on('books::book.afterRestore', afterRestoreSpy)
|
|
41
|
+
emitter.on('books::book.beforeDuplicate', beforeDuplicateSpy)
|
|
42
|
+
emitter.on('books::book.afterDuplicate', afterDuplicateSpy)
|
|
39
43
|
|
|
40
44
|
beforeCreateSpy.mockClear()
|
|
41
45
|
afterCreateSpy.mockClear()
|
|
@@ -45,6 +49,8 @@ describe('ModelService', () => {
|
|
|
45
49
|
afterRemoveSpy.mockClear()
|
|
46
50
|
beforeRestoreSpy.mockClear()
|
|
47
51
|
afterRestoreSpy.mockClear()
|
|
52
|
+
beforeDuplicateSpy.mockClear()
|
|
53
|
+
afterDuplicateSpy.mockClear()
|
|
48
54
|
})
|
|
49
55
|
|
|
50
56
|
it('should create a record', async () => {
|
|
@@ -1042,15 +1048,21 @@ describe('ModelService', () => {
|
|
|
1042
1048
|
await expect(service.duplicate({ id: 999 })).rejects.toThrow()
|
|
1043
1049
|
})
|
|
1044
1050
|
|
|
1045
|
-
it('should trigger
|
|
1051
|
+
it('should trigger beforeDuplicate and afterDuplicate events alongside create events', async () => {
|
|
1046
1052
|
const original = { id: 42, title: 'Original Book', author: 'Author Name', publishedDate: new Date() }
|
|
1047
1053
|
await repository.create(original)
|
|
1048
1054
|
|
|
1049
|
-
beforeCreateSpy.mockClear()
|
|
1050
|
-
afterCreateSpy.mockClear()
|
|
1051
|
-
|
|
1052
1055
|
await service.duplicate({ id: 42 })
|
|
1053
1056
|
|
|
1057
|
+
expect(beforeDuplicateSpy).toHaveBeenCalledTimes(1)
|
|
1058
|
+
expect(beforeDuplicateSpy).toHaveBeenCalledWith(
|
|
1059
|
+
expect.objectContaining({ type: 'books::book.beforeDuplicate' }),
|
|
1060
|
+
)
|
|
1061
|
+
expect(afterDuplicateSpy).toHaveBeenCalledTimes(1)
|
|
1062
|
+
expect(afterDuplicateSpy).toHaveBeenCalledWith(
|
|
1063
|
+
expect.objectContaining({ type: 'books::book.afterDuplicate' }),
|
|
1064
|
+
)
|
|
1065
|
+
// create events also fire since a record is genuinely being created
|
|
1054
1066
|
expect(beforeCreateSpy).toHaveBeenCalledTimes(1)
|
|
1055
1067
|
expect(afterCreateSpy).toHaveBeenCalledTimes(1)
|
|
1056
1068
|
})
|
|
@@ -1105,11 +1117,11 @@ describe('ModelService', () => {
|
|
|
1105
1117
|
const original = { id: 42, title: 'Original Book', author: 'Author Name', publishedDate: new Date() }
|
|
1106
1118
|
await repository.create(original)
|
|
1107
1119
|
|
|
1108
|
-
beforeCreateSpy.mockClear()
|
|
1109
|
-
afterCreateSpy.mockClear()
|
|
1110
|
-
|
|
1111
1120
|
await service.duplicate({ id: 42 }, undefined, { doNotDispatchEvents: true })
|
|
1112
1121
|
|
|
1122
|
+
expect(beforeDuplicateSpy).not.toHaveBeenCalled()
|
|
1123
|
+
expect(afterDuplicateSpy).not.toHaveBeenCalled()
|
|
1124
|
+
// create events are also suppressed when doNotDispatchEvents is set
|
|
1113
1125
|
expect(beforeCreateSpy).not.toHaveBeenCalled()
|
|
1114
1126
|
expect(afterCreateSpy).not.toHaveBeenCalled()
|
|
1115
1127
|
})
|
|
@@ -1394,4 +1406,211 @@ describe('ModelService', () => {
|
|
|
1394
1406
|
})
|
|
1395
1407
|
})
|
|
1396
1408
|
})
|
|
1409
|
+
|
|
1410
|
+
describe('event meta (existing and args)', () => {
|
|
1411
|
+
const input = { id: 42, title: 'Test Book', author: 'Author Name', publishedDate: new Date('2024-01-01') }
|
|
1412
|
+
|
|
1413
|
+
describe('create events', () => {
|
|
1414
|
+
it('beforeCreate event includes args with input and options', async () => {
|
|
1415
|
+
let capturedEvent: any
|
|
1416
|
+
|
|
1417
|
+
emitter.on('books::book.beforeCreate', (event) => {
|
|
1418
|
+
capturedEvent = event
|
|
1419
|
+
})
|
|
1420
|
+
|
|
1421
|
+
const options = { doNotDispatchEvents: false }
|
|
1422
|
+
await service.create(input, options)
|
|
1423
|
+
|
|
1424
|
+
expect(capturedEvent.meta.args.input).toEqual(input)
|
|
1425
|
+
expect(capturedEvent.meta.args.options).toEqual(options)
|
|
1426
|
+
})
|
|
1427
|
+
|
|
1428
|
+
it('afterCreate event includes args and result', async () => {
|
|
1429
|
+
let capturedEvent: any
|
|
1430
|
+
|
|
1431
|
+
emitter.on('books::book.afterCreate', (event) => {
|
|
1432
|
+
capturedEvent = event
|
|
1433
|
+
})
|
|
1434
|
+
|
|
1435
|
+
await service.create(input)
|
|
1436
|
+
|
|
1437
|
+
expect(capturedEvent.meta.args.input).toEqual(input)
|
|
1438
|
+
expect(capturedEvent.data).toBeDefined()
|
|
1439
|
+
expect(capturedEvent.data.id).toBe(42)
|
|
1440
|
+
})
|
|
1441
|
+
})
|
|
1442
|
+
|
|
1443
|
+
describe('update events', () => {
|
|
1444
|
+
beforeEach(async () => {
|
|
1445
|
+
await repository.create(input)
|
|
1446
|
+
})
|
|
1447
|
+
|
|
1448
|
+
it('beforeUpdate event includes existing record and args', async () => {
|
|
1449
|
+
let capturedEvent: any
|
|
1450
|
+
|
|
1451
|
+
emitter.on('books::book.beforeUpdate', (event) => {
|
|
1452
|
+
capturedEvent = event
|
|
1453
|
+
})
|
|
1454
|
+
|
|
1455
|
+
const updateInput = { title: 'Updated Book', author: 'Updated Author', publishedDate: new Date() }
|
|
1456
|
+
await service.update({ id: 42 }, updateInput)
|
|
1457
|
+
|
|
1458
|
+
expect(capturedEvent.meta.existing).toBeDefined()
|
|
1459
|
+
expect(capturedEvent.meta.existing.id).toBe(42)
|
|
1460
|
+
expect(capturedEvent.meta.existing.title).toBe('Test Book')
|
|
1461
|
+
expect(capturedEvent.meta.args.lookup).toEqual({ id: 42 })
|
|
1462
|
+
expect(capturedEvent.meta.args.input).toEqual(updateInput)
|
|
1463
|
+
})
|
|
1464
|
+
|
|
1465
|
+
it('afterUpdate event includes existing record, args, and result', async () => {
|
|
1466
|
+
let capturedEvent: any
|
|
1467
|
+
|
|
1468
|
+
emitter.on('books::book.afterUpdate', (event) => {
|
|
1469
|
+
capturedEvent = event
|
|
1470
|
+
})
|
|
1471
|
+
|
|
1472
|
+
const updateInput = { title: 'Updated Book', author: 'Updated Author', publishedDate: new Date() }
|
|
1473
|
+
await service.update({ id: 42 }, updateInput)
|
|
1474
|
+
|
|
1475
|
+
expect(capturedEvent.meta.existing).toBeDefined()
|
|
1476
|
+
expect(capturedEvent.meta.existing.id).toBe(42)
|
|
1477
|
+
expect(capturedEvent.meta.args.lookup).toEqual({ id: 42 })
|
|
1478
|
+
expect(capturedEvent.data).toBeDefined()
|
|
1479
|
+
expect(capturedEvent.data.title).toBe('Updated Book')
|
|
1480
|
+
})
|
|
1481
|
+
})
|
|
1482
|
+
|
|
1483
|
+
describe('remove events', () => {
|
|
1484
|
+
beforeEach(async () => {
|
|
1485
|
+
await repository.create(input)
|
|
1486
|
+
})
|
|
1487
|
+
|
|
1488
|
+
it('beforeRemove event includes args with lookup and options', async () => {
|
|
1489
|
+
let capturedEvent: any
|
|
1490
|
+
|
|
1491
|
+
emitter.on('books::book.beforeRemove', (event) => {
|
|
1492
|
+
capturedEvent = event
|
|
1493
|
+
})
|
|
1494
|
+
|
|
1495
|
+
await service.remove({ id: 42 })
|
|
1496
|
+
|
|
1497
|
+
expect(capturedEvent.meta.args.lookup).toEqual({ id: 42 })
|
|
1498
|
+
})
|
|
1499
|
+
|
|
1500
|
+
it('afterRemove event includes args and result', async () => {
|
|
1501
|
+
let capturedEvent: any
|
|
1502
|
+
|
|
1503
|
+
emitter.on('books::book.afterRemove', (event) => {
|
|
1504
|
+
capturedEvent = event
|
|
1505
|
+
})
|
|
1506
|
+
|
|
1507
|
+
await service.remove({ id: 42 })
|
|
1508
|
+
|
|
1509
|
+
expect(capturedEvent.meta.args.lookup).toEqual({ id: 42 })
|
|
1510
|
+
expect(capturedEvent.data).toBeDefined()
|
|
1511
|
+
expect(capturedEvent.data.id).toBe(42)
|
|
1512
|
+
})
|
|
1513
|
+
})
|
|
1514
|
+
|
|
1515
|
+
describe('restore events', () => {
|
|
1516
|
+
beforeEach(async () => {
|
|
1517
|
+
await repository.create(input)
|
|
1518
|
+
await repository.remove({ id: 42 })
|
|
1519
|
+
})
|
|
1520
|
+
|
|
1521
|
+
it('beforeRestore event includes args with lookup', async () => {
|
|
1522
|
+
let capturedEvent: any
|
|
1523
|
+
|
|
1524
|
+
emitter.on('books::book.beforeRestore', (event) => {
|
|
1525
|
+
capturedEvent = event
|
|
1526
|
+
})
|
|
1527
|
+
|
|
1528
|
+
await service.restore({ id: 42 })
|
|
1529
|
+
|
|
1530
|
+
expect(capturedEvent.meta.args.lookup).toEqual({ id: 42 })
|
|
1531
|
+
})
|
|
1532
|
+
|
|
1533
|
+
it('afterRestore event includes args and result', async () => {
|
|
1534
|
+
let capturedEvent: any
|
|
1535
|
+
|
|
1536
|
+
emitter.on('books::book.afterRestore', (event) => {
|
|
1537
|
+
capturedEvent = event
|
|
1538
|
+
})
|
|
1539
|
+
|
|
1540
|
+
await service.restore({ id: 42 })
|
|
1541
|
+
|
|
1542
|
+
expect(capturedEvent.meta.args.lookup).toEqual({ id: 42 })
|
|
1543
|
+
expect(capturedEvent.data).toBeDefined()
|
|
1544
|
+
expect(capturedEvent.data.id).toBe(42)
|
|
1545
|
+
})
|
|
1546
|
+
})
|
|
1547
|
+
|
|
1548
|
+
describe('duplicate events', () => {
|
|
1549
|
+
beforeEach(async () => {
|
|
1550
|
+
await repository.create(input)
|
|
1551
|
+
})
|
|
1552
|
+
|
|
1553
|
+
it('beforeDuplicate event includes existing record and args', async () => {
|
|
1554
|
+
let capturedEvent: any
|
|
1555
|
+
|
|
1556
|
+
emitter.on('books::book.beforeDuplicate', (event) => {
|
|
1557
|
+
capturedEvent = event
|
|
1558
|
+
})
|
|
1559
|
+
|
|
1560
|
+
const overrides = { title: 'Duplicate Title' }
|
|
1561
|
+
await service.duplicate({ id: 42 }, overrides)
|
|
1562
|
+
|
|
1563
|
+
expect(capturedEvent.meta.existing).toBeDefined()
|
|
1564
|
+
expect(capturedEvent.meta.existing.id).toBe(42)
|
|
1565
|
+
expect(capturedEvent.meta.existing.title).toBe('Test Book')
|
|
1566
|
+
expect(capturedEvent.meta.args.lookup).toEqual({ id: 42 })
|
|
1567
|
+
expect(capturedEvent.meta.args.overrides).toEqual(overrides)
|
|
1568
|
+
})
|
|
1569
|
+
|
|
1570
|
+
it('afterDuplicate event includes existing, args, and the new record as result', async () => {
|
|
1571
|
+
let capturedEvent: any
|
|
1572
|
+
|
|
1573
|
+
emitter.on('books::book.afterDuplicate', (event) => {
|
|
1574
|
+
capturedEvent = event
|
|
1575
|
+
})
|
|
1576
|
+
|
|
1577
|
+
const overrides = { title: 'Duplicate Title' }
|
|
1578
|
+
await service.duplicate({ id: 42 }, overrides)
|
|
1579
|
+
|
|
1580
|
+
expect(capturedEvent.meta.existing).toBeDefined()
|
|
1581
|
+
expect(capturedEvent.meta.existing.id).toBe(42)
|
|
1582
|
+
expect(capturedEvent.meta.args.lookup).toEqual({ id: 42 })
|
|
1583
|
+
expect(capturedEvent.meta.args.overrides).toEqual(overrides)
|
|
1584
|
+
expect(capturedEvent.data).toBeDefined()
|
|
1585
|
+
expect(capturedEvent.data.title).toBe('Duplicate Title')
|
|
1586
|
+
expect(capturedEvent.data.id).not.toBe(42)
|
|
1587
|
+
})
|
|
1588
|
+
|
|
1589
|
+
it('beforeDuplicate input is the finalInput (with overrides applied, without primary key)', async () => {
|
|
1590
|
+
let capturedEvent: any
|
|
1591
|
+
|
|
1592
|
+
emitter.on('books::book.beforeDuplicate', (event) => {
|
|
1593
|
+
capturedEvent = event
|
|
1594
|
+
})
|
|
1595
|
+
|
|
1596
|
+
await service.duplicate({ id: 42 }, { title: 'Override Title' })
|
|
1597
|
+
|
|
1598
|
+
expect(capturedEvent.input.title).toBe('Override Title')
|
|
1599
|
+
expect(capturedEvent.input.id).toBeUndefined()
|
|
1600
|
+
})
|
|
1601
|
+
|
|
1602
|
+
it('duplicate without overrides has undefined overrides in args', async () => {
|
|
1603
|
+
let capturedEvent: any
|
|
1604
|
+
|
|
1605
|
+
emitter.on('books::book.beforeDuplicate', (event) => {
|
|
1606
|
+
capturedEvent = event
|
|
1607
|
+
})
|
|
1608
|
+
|
|
1609
|
+
await service.duplicate({ id: 42 })
|
|
1610
|
+
|
|
1611
|
+
expect(capturedEvent.meta.args.overrides).toBeUndefined()
|
|
1612
|
+
expect(capturedEvent.meta.existing.title).toBe('Test Book')
|
|
1613
|
+
})
|
|
1614
|
+
})
|
|
1615
|
+
})
|
|
1397
1616
|
})
|
|
@@ -7,7 +7,14 @@ import type {
|
|
|
7
7
|
InferSummary,
|
|
8
8
|
} from '../../shared/utils/schema-inference'
|
|
9
9
|
import { ModelMutationAction, ModelQueryEvent } from '../events/event-types'
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
MutationEvent,
|
|
12
|
+
type ICreateEventMeta,
|
|
13
|
+
type IUpdateEventMeta,
|
|
14
|
+
type IRemoveEventMeta,
|
|
15
|
+
type IRestoreEventMeta,
|
|
16
|
+
type IDuplicateEventMeta,
|
|
17
|
+
} from '../events/mutation-event'
|
|
11
18
|
import type { IModelServiceArgs } from './model-service-args'
|
|
12
19
|
import { ReadOnlyModelService, type ILoadOptions } from './read-only-model-service'
|
|
13
20
|
import type { IActionOptions } from './base-model-service'
|
|
@@ -111,8 +118,36 @@ export class ModelService<TSchema extends AnyModelSchema> extends ReadOnlyModelS
|
|
|
111
118
|
// Merge optional overrides
|
|
112
119
|
const finalInput = overrides ? Object.assign({}, input, overrides) : input
|
|
113
120
|
|
|
114
|
-
//
|
|
115
|
-
|
|
121
|
+
// Emit the before duplicate event
|
|
122
|
+
if (!options?.doNotDispatchEvents) {
|
|
123
|
+
const beforeDuplicateEvent = new MutationEvent<
|
|
124
|
+
InferDetail<TSchema>,
|
|
125
|
+
InferInput<TSchema>,
|
|
126
|
+
IDuplicateEventMeta<InferDetail<TSchema>, InferLookup<TSchema>, InferInput<TSchema>>
|
|
127
|
+
>(
|
|
128
|
+
this.getDescriptor(ModelMutationAction.BeforeDuplicate),
|
|
129
|
+
finalInput as InferInput<TSchema>,
|
|
130
|
+
).setMeta({ existing, args: { lookup, overrides, options: options as Record<string, unknown> } })
|
|
131
|
+
await this.emitter.emitAsync(beforeDuplicateEvent)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Create the new record (also emits beforeCreate/afterCreate)
|
|
135
|
+
const result = await this.create(finalInput as InferInput<TSchema>, options)
|
|
136
|
+
|
|
137
|
+
// Emit the after duplicate event
|
|
138
|
+
if (!options?.doNotDispatchEvents) {
|
|
139
|
+
const afterDuplicateEvent = new MutationEvent<
|
|
140
|
+
InferDetail<TSchema>,
|
|
141
|
+
InferInput<TSchema>,
|
|
142
|
+
IDuplicateEventMeta<InferDetail<TSchema>, InferLookup<TSchema>, InferInput<TSchema>>
|
|
143
|
+
>(
|
|
144
|
+
this.getDescriptor(ModelMutationAction.AfterDuplicate),
|
|
145
|
+
finalInput as InferInput<TSchema>,
|
|
146
|
+
).setMeta({ existing, args: { lookup, overrides, options: options as Record<string, unknown> } }).setResult(result)
|
|
147
|
+
await this.emitter.emitAsync(afterDuplicateEvent)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return result
|
|
116
151
|
}
|
|
117
152
|
|
|
118
153
|
/**
|
|
@@ -122,20 +157,28 @@ export class ModelService<TSchema extends AnyModelSchema> extends ReadOnlyModelS
|
|
|
122
157
|
*/
|
|
123
158
|
async remove(lookup: InferLookup<TSchema>, options?: ILoadOptions): Promise<InferSummary<TSchema>> {
|
|
124
159
|
// Emit the before remove event
|
|
125
|
-
const beforeRemoveEvent = new MutationEvent<
|
|
160
|
+
const beforeRemoveEvent = new MutationEvent<
|
|
161
|
+
InferSummary<TSchema>,
|
|
162
|
+
InferLookup<TSchema>,
|
|
163
|
+
IRemoveEventMeta<InferSummary<TSchema>, InferLookup<TSchema>>
|
|
164
|
+
>(
|
|
126
165
|
this.getDescriptor(ModelMutationAction.BeforeRemove),
|
|
127
166
|
lookup,
|
|
128
|
-
)
|
|
167
|
+
).setMeta({ args: { lookup, options: options as Record<string, unknown> } })
|
|
129
168
|
await this.emitter.emitAsync(beforeRemoveEvent)
|
|
130
169
|
|
|
131
170
|
// Perform the removal
|
|
132
171
|
const result = await this.repository.remove(lookup, options)
|
|
133
172
|
|
|
134
173
|
// Emit the after remove event
|
|
135
|
-
const afterRemoveEvent = new MutationEvent<
|
|
174
|
+
const afterRemoveEvent = new MutationEvent<
|
|
175
|
+
InferSummary<TSchema>,
|
|
176
|
+
InferLookup<TSchema>,
|
|
177
|
+
IRemoveEventMeta<InferSummary<TSchema>, InferLookup<TSchema>>
|
|
178
|
+
>(
|
|
136
179
|
this.getDescriptor(ModelMutationAction.AfterRemove),
|
|
137
180
|
lookup,
|
|
138
|
-
).setResult(result)
|
|
181
|
+
).setMeta({ args: { lookup, options: options as Record<string, unknown> } }).setResult(result)
|
|
139
182
|
await this.emitter.emitAsync(afterRemoveEvent)
|
|
140
183
|
|
|
141
184
|
// Return the results of the removal
|
|
@@ -150,20 +193,28 @@ export class ModelService<TSchema extends AnyModelSchema> extends ReadOnlyModelS
|
|
|
150
193
|
*/
|
|
151
194
|
async restore(lookup: InferLookup<TSchema>, options?: ILoadOptions): Promise<InferSummary<TSchema>> {
|
|
152
195
|
// Emit the before restore event
|
|
153
|
-
const beforeRestoreEvent = new MutationEvent<
|
|
196
|
+
const beforeRestoreEvent = new MutationEvent<
|
|
197
|
+
InferSummary<TSchema>,
|
|
198
|
+
InferLookup<TSchema>,
|
|
199
|
+
IRestoreEventMeta<InferSummary<TSchema>, InferLookup<TSchema>>
|
|
200
|
+
>(
|
|
154
201
|
this.getDescriptor(ModelMutationAction.BeforeRestore),
|
|
155
202
|
lookup,
|
|
156
|
-
)
|
|
203
|
+
).setMeta({ args: { lookup, options: options as Record<string, unknown> } })
|
|
157
204
|
await this.emitter.emitAsync(beforeRestoreEvent)
|
|
158
205
|
|
|
159
206
|
// Perform the restore operation
|
|
160
207
|
const result = await this.repository.restore(lookup, options)
|
|
161
208
|
|
|
162
209
|
// Emit the after restore event
|
|
163
|
-
const afterRestoreEvent = new MutationEvent<
|
|
210
|
+
const afterRestoreEvent = new MutationEvent<
|
|
211
|
+
InferSummary<TSchema>,
|
|
212
|
+
InferLookup<TSchema>,
|
|
213
|
+
IRestoreEventMeta<InferSummary<TSchema>, InferLookup<TSchema>>
|
|
214
|
+
>(
|
|
164
215
|
this.getDescriptor(ModelMutationAction.AfterRestore),
|
|
165
216
|
lookup,
|
|
166
|
-
).setResult(result)
|
|
217
|
+
).setMeta({ args: { lookup, options: options as Record<string, unknown> } }).setResult(result)
|
|
167
218
|
await this.emitter.emitAsync(afterRestoreEvent)
|
|
168
219
|
|
|
169
220
|
// Return the results of the restore operation
|
|
@@ -178,10 +229,14 @@ export class ModelService<TSchema extends AnyModelSchema> extends ReadOnlyModelS
|
|
|
178
229
|
|
|
179
230
|
// Emit the before create event
|
|
180
231
|
if (!options?.doNotDispatchEvents) {
|
|
181
|
-
const beforeCreateEvent = new MutationEvent<
|
|
232
|
+
const beforeCreateEvent = new MutationEvent<
|
|
233
|
+
InferDetail<TSchema>,
|
|
234
|
+
InferInput<TSchema>,
|
|
235
|
+
ICreateEventMeta<InferDetail<TSchema>, InferInput<TSchema>>
|
|
236
|
+
>(
|
|
182
237
|
this.getDescriptor(ModelMutationAction.BeforeCreate),
|
|
183
238
|
normalizedInput,
|
|
184
|
-
)
|
|
239
|
+
).setMeta({ args: { input: normalizedInput, options: options as Record<string, unknown> } })
|
|
185
240
|
await this.emitter.emitAsync(beforeCreateEvent)
|
|
186
241
|
}
|
|
187
242
|
|
|
@@ -190,10 +245,14 @@ export class ModelService<TSchema extends AnyModelSchema> extends ReadOnlyModelS
|
|
|
190
245
|
|
|
191
246
|
// Emit the after create event
|
|
192
247
|
if (!options?.doNotDispatchEvents) {
|
|
193
|
-
const afterCreateEvent = new MutationEvent<
|
|
248
|
+
const afterCreateEvent = new MutationEvent<
|
|
249
|
+
InferDetail<TSchema>,
|
|
250
|
+
InferInput<TSchema>,
|
|
251
|
+
ICreateEventMeta<InferDetail<TSchema>, InferInput<TSchema>>
|
|
252
|
+
>(
|
|
194
253
|
this.getDescriptor(ModelMutationAction.AfterCreate),
|
|
195
254
|
normalizedInput,
|
|
196
|
-
).setResult(result)
|
|
255
|
+
).setMeta({ args: { input: normalizedInput, options: options as Record<string, unknown> } }).setResult(result)
|
|
197
256
|
await this.emitter.emitAsync(afterCreateEvent)
|
|
198
257
|
}
|
|
199
258
|
|
|
@@ -215,10 +274,14 @@ export class ModelService<TSchema extends AnyModelSchema> extends ReadOnlyModelS
|
|
|
215
274
|
|
|
216
275
|
// Emit the before update event
|
|
217
276
|
if (!options?.doNotDispatchEvents) {
|
|
218
|
-
const beforeUpdateEvent = new MutationEvent<
|
|
277
|
+
const beforeUpdateEvent = new MutationEvent<
|
|
278
|
+
InferDetail<TSchema>,
|
|
279
|
+
InferInput<TSchema>,
|
|
280
|
+
IUpdateEventMeta<InferDetail<TSchema>, InferLookup<TSchema>, InferInput<TSchema>>
|
|
281
|
+
>(
|
|
219
282
|
this.getDescriptor(ModelMutationAction.BeforeUpdate),
|
|
220
283
|
normalizedInput,
|
|
221
|
-
)
|
|
284
|
+
).setMeta({ existing, args: { lookup, input, options: options as Record<string, unknown> } })
|
|
222
285
|
await this.emitter.emitAsync(beforeUpdateEvent)
|
|
223
286
|
}
|
|
224
287
|
|
|
@@ -227,10 +290,14 @@ export class ModelService<TSchema extends AnyModelSchema> extends ReadOnlyModelS
|
|
|
227
290
|
|
|
228
291
|
// Emit the after update event
|
|
229
292
|
if (!options?.doNotDispatchEvents) {
|
|
230
|
-
const afterUpdateEvent = new MutationEvent<
|
|
293
|
+
const afterUpdateEvent = new MutationEvent<
|
|
294
|
+
InferDetail<TSchema>,
|
|
295
|
+
InferInput<TSchema>,
|
|
296
|
+
IUpdateEventMeta<InferDetail<TSchema>, InferLookup<TSchema>, InferInput<TSchema>>
|
|
297
|
+
>(
|
|
231
298
|
this.getDescriptor(ModelMutationAction.AfterUpdate),
|
|
232
299
|
normalizedInput,
|
|
233
|
-
).setResult(result)
|
|
300
|
+
).setMeta({ existing, args: { lookup, input, options: options as Record<string, unknown> } }).setResult(result)
|
|
234
301
|
await this.emitter.emitAsync(afterUpdateEvent)
|
|
235
302
|
}
|
|
236
303
|
|