@rytass/wms-module-graphql 0.4.0 → 0.6.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 +56 -3
- package/adapters/event-emitter.d.ts +29 -0
- package/adapters/event-emitter.js +41 -0
- package/adapters/member-base.d.ts +11 -0
- package/adapters/member-base.js +17 -1
- package/docs/README.md +3 -0
- package/docs/api-reference.md +60 -0
- package/docs/events.md +500 -0
- package/docs/integration-guide.md +111 -2
- package/index.cjs.js +154 -1
- package/index.d.ts +2 -0
- package/index.js +3 -0
- package/lib/events/index.d.ts +5 -0
- package/lib/events/operation-result-map.d.ts +77 -0
- package/lib/events/typed-maps.d.ts +73 -0
- package/lib/events/wms-mutation-event.constants.d.ts +12 -0
- package/lib/events/wms-mutation-event.constants.js +4 -0
- package/lib/events/wms-mutation-event.decorator.d.ts +15 -0
- package/lib/events/wms-mutation-event.decorator.js +20 -0
- package/lib/events/wms-mutation.interceptor.d.ts +21 -0
- package/lib/events/wms-mutation.interceptor.js +90 -0
- package/lib/graphql.module.d.ts +24 -5
- package/lib/graphql.module.js +16 -2
- package/lib/mutations/allocate-inventory-order.mutation.js +5 -0
- package/lib/mutations/hold-inventory-order.mutation.js +5 -0
- package/lib/mutations/loader.mutation.js +7 -0
- package/lib/mutations/location.mutation.js +4 -0
- package/lib/mutations/material.mutation.js +4 -0
- package/lib/mutations/merge-batch.mutation.js +3 -0
- package/lib/mutations/quality-inspection-order.mutation.js +3 -0
- package/lib/mutations/receive-inventory-order.mutation.js +5 -0
- package/lib/mutations/reclassify-inventory-order.mutation.js +3 -0
- package/lib/mutations/scrape-order.mutation.js +3 -0
- package/lib/mutations/ship-inventory-order.mutation.js +6 -0
- package/lib/mutations/split-batch.mutation.js +3 -0
- package/lib/mutations/transfer-customer-order.mutation.js +5 -0
- package/lib/mutations/transfer-order.mutation.js +6 -0
- package/lib/mutations/transfer-vendor-order.mutation.js +5 -0
- package/lib/mutations/warehouse-map.mutation.js +3 -0
- package/package.json +13 -3
package/index.cjs.js
CHANGED
|
@@ -10,6 +10,7 @@ var typeorm = require('typeorm');
|
|
|
10
10
|
var DataLoader = require('dataloader');
|
|
11
11
|
var graphql = require('@nestjs/graphql');
|
|
12
12
|
var core = require('@nestjs/core');
|
|
13
|
+
var rxjs = require('rxjs');
|
|
13
14
|
var wmsBaseNestjsModule = require('@rytass/wms-base-nestjs-module');
|
|
14
15
|
var warehouseMap_entity = require('@rytass/wms-base-nestjs-module/models/warehouse-map.entity');
|
|
15
16
|
|
|
@@ -304,6 +305,105 @@ exports.WmsAuthGuard = tslib.__decorate([
|
|
|
304
305
|
*/
|
|
305
306
|
const WmsOperation = (requirement) => common.applyDecorators(common.SetMetadata(WMS_OPERATION_METADATA, requirement), common.SetMetadata(HOST_SKIP_METADATA_KEY, true), common.UseGuards(exports.WmsAuthGuard));
|
|
306
307
|
|
|
308
|
+
/** Reflector metadata key carrying the {@link WmsMutationEventConfig}. */
|
|
309
|
+
const WMS_MUTATION_EVENT_METADATA = 'wms:mutation-event';
|
|
310
|
+
|
|
311
|
+
const defaultResolveId = (result, args) => {
|
|
312
|
+
if (result &&
|
|
313
|
+
typeof result === 'object' &&
|
|
314
|
+
'id' in result &&
|
|
315
|
+
typeof result.id === 'string') {
|
|
316
|
+
return result.id;
|
|
317
|
+
}
|
|
318
|
+
const argId = args['id'];
|
|
319
|
+
return typeof argId === 'string' ? argId : null;
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* Wraps each `@WmsMutationEvent` mutation in a dispatch scope:
|
|
323
|
+
* 1. runs the before-hook (throw -> veto, before any transaction);
|
|
324
|
+
* 2. executes the resolver (services collect stock events into the scope);
|
|
325
|
+
* 3. emits the operation event after the handler resolves (post-commit);
|
|
326
|
+
* 4. flushes the whole buffer to after-listeners + emitter bridge.
|
|
327
|
+
*
|
|
328
|
+
* When no hook/listener/bridge is configured it passes through untouched.
|
|
329
|
+
*/
|
|
330
|
+
exports.WmsMutationInterceptor = class WmsMutationInterceptor {
|
|
331
|
+
reflector;
|
|
332
|
+
dispatcher;
|
|
333
|
+
actorExtractor;
|
|
334
|
+
constructor(reflector, dispatcher, actorExtractor = null) {
|
|
335
|
+
this.reflector = reflector;
|
|
336
|
+
this.dispatcher = dispatcher;
|
|
337
|
+
this.actorExtractor = actorExtractor;
|
|
338
|
+
}
|
|
339
|
+
resolveActor(context) {
|
|
340
|
+
if (!this.actorExtractor) {
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
try {
|
|
344
|
+
return this.actorExtractor(context);
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
// Fail-open on actor resolution: never break a mutation over audit metadata.
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
async intercept(context, next) {
|
|
352
|
+
const config = this.reflector.get(WMS_MUTATION_EVENT_METADATA, context.getHandler());
|
|
353
|
+
if (!config || !this.dispatcher.isActive()) {
|
|
354
|
+
return next.handle();
|
|
355
|
+
}
|
|
356
|
+
const args = graphql.GqlExecutionContext.create(context).getArgs() ??
|
|
357
|
+
{};
|
|
358
|
+
const actor = this.resolveActor(context);
|
|
359
|
+
// Before-hook runs before any DB work; a throw vetoes with zero side effects.
|
|
360
|
+
await this.dispatcher.runBeforeHook({
|
|
361
|
+
event: config.event,
|
|
362
|
+
args,
|
|
363
|
+
executionContext: context,
|
|
364
|
+
actor,
|
|
365
|
+
});
|
|
366
|
+
const { result, events } = await wmsModuleCore.runInDispatchScope(async () => {
|
|
367
|
+
const handlerResult = await rxjs.firstValueFrom(next.handle());
|
|
368
|
+
const id = config.resolveId
|
|
369
|
+
? config.resolveId(handlerResult, args)
|
|
370
|
+
: defaultResolveId(handlerResult, args);
|
|
371
|
+
const operationEvent = {
|
|
372
|
+
name: config.event,
|
|
373
|
+
payload: { id, result: handlerResult, args, actor },
|
|
374
|
+
};
|
|
375
|
+
wmsModuleCore.collectToScope(operationEvent);
|
|
376
|
+
return handlerResult;
|
|
377
|
+
});
|
|
378
|
+
if (events) {
|
|
379
|
+
await this.dispatcher.flush(events);
|
|
380
|
+
}
|
|
381
|
+
return rxjs.of(result);
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
exports.WmsMutationInterceptor = tslib.__decorate([
|
|
385
|
+
common.Injectable(),
|
|
386
|
+
tslib.__param(2, common.Optional()),
|
|
387
|
+
tslib.__param(2, common.Inject(wmsModuleCore.WMS_ACTOR_EXTRACTOR)),
|
|
388
|
+
tslib.__metadata("design:paramtypes", [core.Reflector,
|
|
389
|
+
wmsModuleCore.WmsEventDispatcher, Object])
|
|
390
|
+
], exports.WmsMutationInterceptor);
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Declares the operation event for a WMS root mutation and wires the
|
|
394
|
+
* {@link WmsMutationInterceptor} that runs before-hooks (veto) and flushes
|
|
395
|
+
* collected events post-commit. Apply alongside `@WmsOperation` on each mutation.
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* ```ts
|
|
399
|
+
* @Mutation(() => ShipInventoryOrderDto)
|
|
400
|
+
* @WmsOperation({ resource: 'ship-inventory-order', action: 'ship' })
|
|
401
|
+
* @WmsMutationEvent({ event: 'ship-inventory-order.shipped' })
|
|
402
|
+
* ship(@Args() args: ShipArgs): Promise<boolean> { ... }
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
const WmsMutationEvent = (config) => common.applyDecorators(common.SetMetadata(WMS_MUTATION_EVENT_METADATA, config), common.UseInterceptors(exports.WmsMutationInterceptor));
|
|
406
|
+
|
|
307
407
|
const IdGenFunction = (input) => {
|
|
308
408
|
const hash = crypto.createHash('sha256');
|
|
309
409
|
hash.update(input);
|
|
@@ -1633,6 +1733,7 @@ let LoaderMutation = class LoaderMutation {
|
|
|
1633
1733
|
tslib.__decorate([
|
|
1634
1734
|
graphql.Mutation(() => [LoaderDto]),
|
|
1635
1735
|
WmsOperation({ resource: 'loader', action: 'create' }),
|
|
1736
|
+
WmsMutationEvent({ event: 'loader.created' }),
|
|
1636
1737
|
tslib.__param(0, graphql.Args()),
|
|
1637
1738
|
tslib.__metadata("design:type", Function),
|
|
1638
1739
|
tslib.__metadata("design:paramtypes", [CreateLoaderArgs]),
|
|
@@ -1641,6 +1742,7 @@ tslib.__decorate([
|
|
|
1641
1742
|
tslib.__decorate([
|
|
1642
1743
|
graphql.Mutation(() => [LoaderDto]),
|
|
1643
1744
|
WmsOperation({ resource: 'loader', action: 'create' }),
|
|
1745
|
+
WmsMutationEvent({ event: 'loader.batch-created' }),
|
|
1644
1746
|
tslib.__param(0, graphql.Args('items', { type: () => [CreateLoadersArgs] })),
|
|
1645
1747
|
tslib.__metadata("design:type", Function),
|
|
1646
1748
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -1649,6 +1751,7 @@ tslib.__decorate([
|
|
|
1649
1751
|
tslib.__decorate([
|
|
1650
1752
|
graphql.Mutation(() => LoaderDto),
|
|
1651
1753
|
WmsOperation({ resource: 'loader', action: 'update' }),
|
|
1754
|
+
WmsMutationEvent({ event: 'loader.updated' }),
|
|
1652
1755
|
tslib.__param(0, graphql.Args()),
|
|
1653
1756
|
tslib.__metadata("design:type", Function),
|
|
1654
1757
|
tslib.__metadata("design:paramtypes", [UpdateLoaderArgs]),
|
|
@@ -1657,6 +1760,7 @@ tslib.__decorate([
|
|
|
1657
1760
|
tslib.__decorate([
|
|
1658
1761
|
graphql.Mutation(() => LoaderTypeDto),
|
|
1659
1762
|
WmsOperation({ resource: 'loader', action: 'create' }),
|
|
1763
|
+
WmsMutationEvent({ event: 'loader.type-created' }),
|
|
1660
1764
|
tslib.__param(0, graphql.Args()),
|
|
1661
1765
|
tslib.__metadata("design:type", Function),
|
|
1662
1766
|
tslib.__metadata("design:paramtypes", [CreateLoaderTypeArgs]),
|
|
@@ -1665,6 +1769,7 @@ tslib.__decorate([
|
|
|
1665
1769
|
tslib.__decorate([
|
|
1666
1770
|
graphql.Mutation(() => LoaderTypeDto),
|
|
1667
1771
|
WmsOperation({ resource: 'loader', action: 'update' }),
|
|
1772
|
+
WmsMutationEvent({ event: 'loader.type-updated' }),
|
|
1668
1773
|
tslib.__param(0, graphql.Args()),
|
|
1669
1774
|
tslib.__metadata("design:type", Function),
|
|
1670
1775
|
tslib.__metadata("design:paramtypes", [UpdateLoaderTypeArgs]),
|
|
@@ -2028,6 +2133,7 @@ let MaterialMutation = class MaterialMutation {
|
|
|
2028
2133
|
tslib.__decorate([
|
|
2029
2134
|
graphql.Mutation(() => MaterialDto),
|
|
2030
2135
|
WmsOperation({ resource: 'material', action: 'create' }),
|
|
2136
|
+
WmsMutationEvent({ event: 'material.created' }),
|
|
2031
2137
|
tslib.__param(0, graphql.Args()),
|
|
2032
2138
|
tslib.__metadata("design:type", Function),
|
|
2033
2139
|
tslib.__metadata("design:paramtypes", [CreateMaterialArgs]),
|
|
@@ -2036,6 +2142,7 @@ tslib.__decorate([
|
|
|
2036
2142
|
tslib.__decorate([
|
|
2037
2143
|
graphql.Mutation(() => MaterialDto),
|
|
2038
2144
|
WmsOperation({ resource: 'material', action: 'update' }),
|
|
2145
|
+
WmsMutationEvent({ event: 'material.updated' }),
|
|
2039
2146
|
tslib.__param(0, graphql.Args()),
|
|
2040
2147
|
tslib.__metadata("design:type", Function),
|
|
2041
2148
|
tslib.__metadata("design:paramtypes", [UpdateMaterialArgs]),
|
|
@@ -2431,6 +2538,7 @@ let ReceiveInventoryOrderMutation = class ReceiveInventoryOrderMutation {
|
|
|
2431
2538
|
tslib.__decorate([
|
|
2432
2539
|
graphql.Mutation(() => ReceiveInventoryOrderDto),
|
|
2433
2540
|
WmsOperation({ resource: 'receive-inventory-order', action: 'create' }),
|
|
2541
|
+
WmsMutationEvent({ event: 'receive-inventory-order.created' }),
|
|
2434
2542
|
tslib.__param(0, graphql.Args()),
|
|
2435
2543
|
tslib.__metadata("design:type", Function),
|
|
2436
2544
|
tslib.__metadata("design:paramtypes", [CreateReceiveInventoryOrderArgs]),
|
|
@@ -2439,6 +2547,7 @@ tslib.__decorate([
|
|
|
2439
2547
|
tslib.__decorate([
|
|
2440
2548
|
graphql.Mutation(() => ReceiveInventoryOrderDto),
|
|
2441
2549
|
WmsOperation({ resource: 'receive-inventory-order', action: 'update' }),
|
|
2550
|
+
WmsMutationEvent({ event: 'receive-inventory-order.updated' }),
|
|
2442
2551
|
tslib.__param(0, graphql.Args()),
|
|
2443
2552
|
tslib.__metadata("design:type", Function),
|
|
2444
2553
|
tslib.__metadata("design:paramtypes", [UpdateReceiveInventoryOrderArgs]),
|
|
@@ -2447,6 +2556,7 @@ tslib.__decorate([
|
|
|
2447
2556
|
tslib.__decorate([
|
|
2448
2557
|
graphql.Mutation(() => Boolean),
|
|
2449
2558
|
WmsOperation({ resource: 'receive-inventory-order', action: 'receive' }),
|
|
2559
|
+
WmsMutationEvent({ event: 'receive-inventory-order.received' }),
|
|
2450
2560
|
tslib.__param(0, graphql.Args('items', { type: () => [ReceiveOrderArgs] })),
|
|
2451
2561
|
tslib.__metadata("design:type", Function),
|
|
2452
2562
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -2790,6 +2900,7 @@ let ShipInventoryOrderMutation = class ShipInventoryOrderMutation {
|
|
|
2790
2900
|
tslib.__decorate([
|
|
2791
2901
|
graphql.Mutation(() => ShipInventoryOrderDto),
|
|
2792
2902
|
WmsOperation({ resource: 'ship-inventory-order', action: 'create' }),
|
|
2903
|
+
WmsMutationEvent({ event: 'ship-inventory-order.created' }),
|
|
2793
2904
|
tslib.__param(0, graphql.Args()),
|
|
2794
2905
|
tslib.__metadata("design:type", Function),
|
|
2795
2906
|
tslib.__metadata("design:paramtypes", [CreateShipInventoryOrderArgs]),
|
|
@@ -2798,6 +2909,7 @@ tslib.__decorate([
|
|
|
2798
2909
|
tslib.__decorate([
|
|
2799
2910
|
graphql.Mutation(() => ShipInventoryOrderDto),
|
|
2800
2911
|
WmsOperation({ resource: 'ship-inventory-order', action: 'update' }),
|
|
2912
|
+
WmsMutationEvent({ event: 'ship-inventory-order.updated' }),
|
|
2801
2913
|
tslib.__param(0, graphql.Args()),
|
|
2802
2914
|
tslib.__metadata("design:type", Function),
|
|
2803
2915
|
tslib.__metadata("design:paramtypes", [UpdateShipInventoryOrderArgs]),
|
|
@@ -2806,6 +2918,7 @@ tslib.__decorate([
|
|
|
2806
2918
|
tslib.__decorate([
|
|
2807
2919
|
graphql.Mutation(() => Boolean),
|
|
2808
2920
|
WmsOperation({ resource: 'ship-inventory-order', action: 'ship' }),
|
|
2921
|
+
WmsMutationEvent({ event: 'ship-inventory-order.shipped' }),
|
|
2809
2922
|
tslib.__param(0, graphql.Args('items', { type: () => [ShipOrderArgs] })),
|
|
2810
2923
|
tslib.__metadata("design:type", Function),
|
|
2811
2924
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -2814,6 +2927,7 @@ tslib.__decorate([
|
|
|
2814
2927
|
tslib.__decorate([
|
|
2815
2928
|
graphql.Mutation(() => Boolean),
|
|
2816
2929
|
WmsOperation({ resource: 'ship-inventory-order', action: 'cancel' }),
|
|
2930
|
+
WmsMutationEvent({ event: 'ship-inventory-order.ship-cancelled' }),
|
|
2817
2931
|
tslib.__param(0, graphql.Args('items', { type: () => [CancelShipOrderArgs] })),
|
|
2818
2932
|
tslib.__metadata("design:type", Function),
|
|
2819
2933
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -3469,6 +3583,7 @@ let WarehouseMapMutation = class WarehouseMapMutation {
|
|
|
3469
3583
|
tslib.__decorate([
|
|
3470
3584
|
graphql.Mutation(() => MapDataDto),
|
|
3471
3585
|
WmsOperation({ resource: 'warehouse-map', action: 'update' }),
|
|
3586
|
+
WmsMutationEvent({ event: 'warehouse-map.updated' }),
|
|
3472
3587
|
tslib.__param(0, graphql.Args()),
|
|
3473
3588
|
tslib.__metadata("design:type", Function),
|
|
3474
3589
|
tslib.__metadata("design:paramtypes", [UpdateWarehouseMapArgs]),
|
|
@@ -3650,6 +3765,7 @@ let LocationMutation = class LocationMutation {
|
|
|
3650
3765
|
tslib.__decorate([
|
|
3651
3766
|
graphql.Mutation(() => LocationDto),
|
|
3652
3767
|
WmsOperation({ resource: 'location', action: 'create' }),
|
|
3768
|
+
WmsMutationEvent({ event: 'location.created' }),
|
|
3653
3769
|
tslib.__param(0, graphql.Args()),
|
|
3654
3770
|
tslib.__metadata("design:type", Function),
|
|
3655
3771
|
tslib.__metadata("design:paramtypes", [CreateLocationArgs]),
|
|
@@ -3658,6 +3774,7 @@ tslib.__decorate([
|
|
|
3658
3774
|
tslib.__decorate([
|
|
3659
3775
|
graphql.Mutation(() => LocationDto),
|
|
3660
3776
|
WmsOperation({ resource: 'location', action: 'update' }),
|
|
3777
|
+
WmsMutationEvent({ event: 'location.updated' }),
|
|
3661
3778
|
tslib.__param(0, graphql.Args()),
|
|
3662
3779
|
tslib.__metadata("design:type", Function),
|
|
3663
3780
|
tslib.__metadata("design:paramtypes", [UpdateLocationArgs]),
|
|
@@ -3961,6 +4078,7 @@ let TransferOrderMutation = class TransferOrderMutation {
|
|
|
3961
4078
|
tslib.__decorate([
|
|
3962
4079
|
graphql.Mutation(() => TransferOrderDto),
|
|
3963
4080
|
WmsOperation({ resource: 'transfer-order', action: 'create' }),
|
|
4081
|
+
WmsMutationEvent({ event: 'transfer-order.created' }),
|
|
3964
4082
|
tslib.__param(0, graphql.Args()),
|
|
3965
4083
|
tslib.__metadata("design:type", Function),
|
|
3966
4084
|
tslib.__metadata("design:paramtypes", [CreateTransferOrderArgs]),
|
|
@@ -3969,6 +4087,7 @@ tslib.__decorate([
|
|
|
3969
4087
|
tslib.__decorate([
|
|
3970
4088
|
graphql.Mutation(() => TransferOrderDto),
|
|
3971
4089
|
WmsOperation({ resource: 'transfer-order', action: 'update' }),
|
|
4090
|
+
WmsMutationEvent({ event: 'transfer-order.updated' }),
|
|
3972
4091
|
tslib.__param(0, graphql.Args()),
|
|
3973
4092
|
tslib.__metadata("design:type", Function),
|
|
3974
4093
|
tslib.__metadata("design:paramtypes", [UpdateTransferOrderArgs]),
|
|
@@ -3977,6 +4096,7 @@ tslib.__decorate([
|
|
|
3977
4096
|
tslib.__decorate([
|
|
3978
4097
|
graphql.Mutation(() => Boolean),
|
|
3979
4098
|
WmsOperation({ resource: 'transfer-order', action: 'transfer' }),
|
|
4099
|
+
WmsMutationEvent({ event: 'transfer-order.transferred' }),
|
|
3980
4100
|
tslib.__param(0, graphql.Args('items', { type: () => [TransferOrderArgs] })),
|
|
3981
4101
|
tslib.__metadata("design:type", Function),
|
|
3982
4102
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -3985,6 +4105,7 @@ tslib.__decorate([
|
|
|
3985
4105
|
tslib.__decorate([
|
|
3986
4106
|
graphql.Mutation(() => Boolean),
|
|
3987
4107
|
WmsOperation({ resource: 'transfer-order', action: 'cancel' }),
|
|
4108
|
+
WmsMutationEvent({ event: 'transfer-order.transfer-cancelled' }),
|
|
3988
4109
|
tslib.__param(0, graphql.Args('items', { type: () => [CancelTransferOrderArgs] })),
|
|
3989
4110
|
tslib.__metadata("design:type", Function),
|
|
3990
4111
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -4436,6 +4557,7 @@ let HoldInventoryOrderMutation = class HoldInventoryOrderMutation {
|
|
|
4436
4557
|
tslib.__decorate([
|
|
4437
4558
|
graphql.Mutation(() => HoldInventoryOrderDto),
|
|
4438
4559
|
WmsOperation({ resource: 'hold-inventory-order', action: 'create' }),
|
|
4560
|
+
WmsMutationEvent({ event: 'hold-inventory-order.created' }),
|
|
4439
4561
|
tslib.__param(0, graphql.Args()),
|
|
4440
4562
|
tslib.__metadata("design:type", Function),
|
|
4441
4563
|
tslib.__metadata("design:paramtypes", [CreateHoldInventoryOrderArgs]),
|
|
@@ -4444,6 +4566,7 @@ tslib.__decorate([
|
|
|
4444
4566
|
tslib.__decorate([
|
|
4445
4567
|
graphql.Mutation(() => HoldInventoryOrderDto),
|
|
4446
4568
|
WmsOperation({ resource: 'hold-inventory-order', action: 'update' }),
|
|
4569
|
+
WmsMutationEvent({ event: 'hold-inventory-order.updated' }),
|
|
4447
4570
|
tslib.__param(0, graphql.Args()),
|
|
4448
4571
|
tslib.__metadata("design:type", Function),
|
|
4449
4572
|
tslib.__metadata("design:paramtypes", [UpdateHoldInventoryOrderArgs]),
|
|
@@ -4452,6 +4575,7 @@ tslib.__decorate([
|
|
|
4452
4575
|
tslib.__decorate([
|
|
4453
4576
|
graphql.Mutation(() => Boolean),
|
|
4454
4577
|
WmsOperation({ resource: 'hold-inventory-order', action: 'release' }),
|
|
4578
|
+
WmsMutationEvent({ event: 'hold-inventory-order.released' }),
|
|
4455
4579
|
tslib.__param(0, graphql.Args('items', { type: () => [ReleaseOrderArgs] })),
|
|
4456
4580
|
tslib.__metadata("design:type", Function),
|
|
4457
4581
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -4970,6 +5094,7 @@ let AllocateInventoryOrderMutation = class AllocateInventoryOrderMutation {
|
|
|
4970
5094
|
tslib.__decorate([
|
|
4971
5095
|
graphql.Mutation(() => AllocateInventoryOrderDto),
|
|
4972
5096
|
WmsOperation({ resource: 'allocate-inventory-order', action: 'create' }),
|
|
5097
|
+
WmsMutationEvent({ event: 'allocate-inventory-order.created' }),
|
|
4973
5098
|
tslib.__param(0, graphql.Args()),
|
|
4974
5099
|
tslib.__metadata("design:type", Function),
|
|
4975
5100
|
tslib.__metadata("design:paramtypes", [CreateAllocateInventoryOrderArgs]),
|
|
@@ -4978,6 +5103,7 @@ tslib.__decorate([
|
|
|
4978
5103
|
tslib.__decorate([
|
|
4979
5104
|
graphql.Mutation(() => AllocateInventoryOrderDto),
|
|
4980
5105
|
WmsOperation({ resource: 'allocate-inventory-order', action: 'update' }),
|
|
5106
|
+
WmsMutationEvent({ event: 'allocate-inventory-order.updated' }),
|
|
4981
5107
|
tslib.__param(0, graphql.Args()),
|
|
4982
5108
|
tslib.__metadata("design:type", Function),
|
|
4983
5109
|
tslib.__metadata("design:paramtypes", [UpdateAllocateInventoryOrderArgs]),
|
|
@@ -4986,6 +5112,7 @@ tslib.__decorate([
|
|
|
4986
5112
|
tslib.__decorate([
|
|
4987
5113
|
graphql.Mutation(() => Boolean),
|
|
4988
5114
|
WmsOperation({ resource: 'allocate-inventory-order', action: 'deallocate' }),
|
|
5115
|
+
WmsMutationEvent({ event: 'allocate-inventory-order.deallocated' }),
|
|
4989
5116
|
tslib.__param(0, graphql.Args('items', { type: () => [DeallocateOrderArgs] })),
|
|
4990
5117
|
tslib.__metadata("design:type", Function),
|
|
4991
5118
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -5442,6 +5569,7 @@ let SplitBatchMutation = class SplitBatchMutation {
|
|
|
5442
5569
|
tslib.__decorate([
|
|
5443
5570
|
graphql.Mutation(() => SplitBatchOrderDto),
|
|
5444
5571
|
WmsOperation({ resource: 'batch', action: 'split' }),
|
|
5572
|
+
WmsMutationEvent({ event: 'batch.splitted' }),
|
|
5445
5573
|
tslib.__param(0, graphql.Args()),
|
|
5446
5574
|
tslib.__metadata("design:type", Function),
|
|
5447
5575
|
tslib.__metadata("design:paramtypes", [SplitBatchArgs]),
|
|
@@ -5561,6 +5689,7 @@ let MergeBatchMutation = class MergeBatchMutation {
|
|
|
5561
5689
|
tslib.__decorate([
|
|
5562
5690
|
graphql.Mutation(() => MergeBatchOrderDto),
|
|
5563
5691
|
WmsOperation({ resource: 'batch', action: 'merge' }),
|
|
5692
|
+
WmsMutationEvent({ event: 'batch.merged' }),
|
|
5564
5693
|
tslib.__param(0, graphql.Args()),
|
|
5565
5694
|
tslib.__metadata("design:type", Function),
|
|
5566
5695
|
tslib.__metadata("design:paramtypes", [MergeBatchArgs]),
|
|
@@ -5686,6 +5815,7 @@ let ReclassifyInventoryOrderMutation = class ReclassifyInventoryOrderMutation {
|
|
|
5686
5815
|
tslib.__decorate([
|
|
5687
5816
|
graphql.Mutation(() => ReclassifyInventoryOrderDto),
|
|
5688
5817
|
WmsOperation({ resource: 'reclassify-inventory-order', action: 'reclassify' }),
|
|
5818
|
+
WmsMutationEvent({ event: 'reclassify-inventory-order.reclassified' }),
|
|
5689
5819
|
tslib.__param(0, graphql.Args()),
|
|
5690
5820
|
tslib.__metadata("design:type", Function),
|
|
5691
5821
|
tslib.__metadata("design:paramtypes", [ReclassifyInventoryOrderArgs]),
|
|
@@ -5859,6 +5989,7 @@ let TransferCustomerOrderMutation = class TransferCustomerOrderMutation {
|
|
|
5859
5989
|
tslib.__decorate([
|
|
5860
5990
|
graphql.Mutation(() => TransferCustomerOrderDto),
|
|
5861
5991
|
WmsOperation({ resource: 'transfer-customer-order', action: 'create' }),
|
|
5992
|
+
WmsMutationEvent({ event: 'transfer-customer-order.created' }),
|
|
5862
5993
|
tslib.__param(0, graphql.Args()),
|
|
5863
5994
|
tslib.__metadata("design:type", Function),
|
|
5864
5995
|
tslib.__metadata("design:paramtypes", [CreateTransferCustomerOrderArgs]),
|
|
@@ -5867,6 +5998,7 @@ tslib.__decorate([
|
|
|
5867
5998
|
tslib.__decorate([
|
|
5868
5999
|
graphql.Mutation(() => TransferCustomerOrderDto),
|
|
5869
6000
|
WmsOperation({ resource: 'transfer-customer-order', action: 'update' }),
|
|
6001
|
+
WmsMutationEvent({ event: 'transfer-customer-order.updated' }),
|
|
5870
6002
|
tslib.__param(0, graphql.Args()),
|
|
5871
6003
|
tslib.__metadata("design:type", Function),
|
|
5872
6004
|
tslib.__metadata("design:paramtypes", [UpdateTransferCustomerOrderArgs]),
|
|
@@ -5875,6 +6007,7 @@ tslib.__decorate([
|
|
|
5875
6007
|
tslib.__decorate([
|
|
5876
6008
|
graphql.Mutation(() => Boolean),
|
|
5877
6009
|
WmsOperation({ resource: 'transfer-customer-order', action: 'return' }),
|
|
6010
|
+
WmsMutationEvent({ event: 'transfer-customer-order.returned' }),
|
|
5878
6011
|
tslib.__param(0, graphql.Args('items', { type: () => [ReturnTransferCustomerOrderArgs] })),
|
|
5879
6012
|
tslib.__metadata("design:type", Function),
|
|
5880
6013
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -6067,6 +6200,7 @@ let TransferVendorOrderMutation = class TransferVendorOrderMutation {
|
|
|
6067
6200
|
tslib.__decorate([
|
|
6068
6201
|
graphql.Mutation(() => TransferVendorOrderDto),
|
|
6069
6202
|
WmsOperation({ resource: 'transfer-vendor-order', action: 'create' }),
|
|
6203
|
+
WmsMutationEvent({ event: 'transfer-vendor-order.created' }),
|
|
6070
6204
|
tslib.__param(0, graphql.Args()),
|
|
6071
6205
|
tslib.__metadata("design:type", Function),
|
|
6072
6206
|
tslib.__metadata("design:paramtypes", [CreateTransferVendorOrderArgs]),
|
|
@@ -6075,6 +6209,7 @@ tslib.__decorate([
|
|
|
6075
6209
|
tslib.__decorate([
|
|
6076
6210
|
graphql.Mutation(() => TransferVendorOrderDto),
|
|
6077
6211
|
WmsOperation({ resource: 'transfer-vendor-order', action: 'update' }),
|
|
6212
|
+
WmsMutationEvent({ event: 'transfer-vendor-order.updated' }),
|
|
6078
6213
|
tslib.__param(0, graphql.Args()),
|
|
6079
6214
|
tslib.__metadata("design:type", Function),
|
|
6080
6215
|
tslib.__metadata("design:paramtypes", [UpdateTransferVendorOrderArgs]),
|
|
@@ -6083,6 +6218,7 @@ tslib.__decorate([
|
|
|
6083
6218
|
tslib.__decorate([
|
|
6084
6219
|
graphql.Mutation(() => Boolean),
|
|
6085
6220
|
WmsOperation({ resource: 'transfer-vendor-order', action: 'return' }),
|
|
6221
|
+
WmsMutationEvent({ event: 'transfer-vendor-order.returned' }),
|
|
6086
6222
|
tslib.__param(0, graphql.Args('items', { type: () => [ReturnTransferVendorOrderArgs] })),
|
|
6087
6223
|
tslib.__metadata("design:type", Function),
|
|
6088
6224
|
tslib.__metadata("design:paramtypes", [Array]),
|
|
@@ -6205,6 +6341,7 @@ let ScrapeMutation = class ScrapeMutation {
|
|
|
6205
6341
|
tslib.__decorate([
|
|
6206
6342
|
graphql.Mutation(() => ScrapeOrderDto),
|
|
6207
6343
|
WmsOperation({ resource: 'scrape-order', action: 'scrape' }),
|
|
6344
|
+
WmsMutationEvent({ event: 'scrape-order.scraped' }),
|
|
6208
6345
|
tslib.__param(0, graphql.Args()),
|
|
6209
6346
|
tslib.__metadata("design:type", Function),
|
|
6210
6347
|
tslib.__metadata("design:paramtypes", [ScrapeOrderArgs]),
|
|
@@ -6288,6 +6425,7 @@ let QualityInspectionOrderMutation = class QualityInspectionOrderMutation {
|
|
|
6288
6425
|
tslib.__decorate([
|
|
6289
6426
|
graphql.Mutation(() => QualityInspectionOrderDto),
|
|
6290
6427
|
WmsOperation({ resource: 'quality-inspection-order', action: 'inspect' }),
|
|
6428
|
+
WmsMutationEvent({ event: 'quality-inspection-order.inspected' }),
|
|
6291
6429
|
tslib.__param(0, graphql.Args()),
|
|
6292
6430
|
tslib.__metadata("design:type", Function),
|
|
6293
6431
|
tslib.__metadata("design:paramtypes", [CreateQualityInspectionOrderArgs]),
|
|
@@ -6401,13 +6539,26 @@ const exportDependencies = [
|
|
|
6401
6539
|
];
|
|
6402
6540
|
exports.WmsModuleGraphqlModule = WmsModuleGraphqlModule_1 = class WmsModuleGraphqlModule {
|
|
6403
6541
|
static forRootAsync(options) {
|
|
6404
|
-
const { authChecker, ...coreOptions } = options;
|
|
6542
|
+
const { authChecker, beforeHooks, afterListeners, actorExtractor, eventEmitterBridge, ...coreOptions } = options;
|
|
6543
|
+
// coreOptions still carries `enrichStockEvents`, forwarded to the core module.
|
|
6405
6544
|
const coreModule = wmsModuleCore.WmsModuleCoreModule.forRootAsync(coreOptions);
|
|
6406
6545
|
const authOptions = { authChecker };
|
|
6546
|
+
// The typed hook maps are a compile-time refinement of the core maps; at
|
|
6547
|
+
// runtime the dispatched payload IS the concrete result type, so handing the
|
|
6548
|
+
// refined maps to the (looser) core option contract is sound.
|
|
6549
|
+
const eventOptions = {
|
|
6550
|
+
beforeHooks: beforeHooks,
|
|
6551
|
+
afterListeners: afterListeners,
|
|
6552
|
+
};
|
|
6407
6553
|
const providers = [
|
|
6408
6554
|
...exportDependencies,
|
|
6409
6555
|
exports.WmsAuthGuard,
|
|
6410
6556
|
{ provide: WMS_AUTH_OPTIONS, useValue: authOptions },
|
|
6557
|
+
{ provide: wmsModuleCore.WMS_EVENT_OPTIONS, useValue: eventOptions },
|
|
6558
|
+
{ provide: wmsModuleCore.WMS_ACTOR_EXTRACTOR, useValue: actorExtractor ?? null },
|
|
6559
|
+
wmsModuleCore.WmsEventDispatcher,
|
|
6560
|
+
exports.WmsMutationInterceptor,
|
|
6561
|
+
...(eventEmitterBridge ? [eventEmitterBridge] : []),
|
|
6411
6562
|
];
|
|
6412
6563
|
return {
|
|
6413
6564
|
module: WmsModuleGraphqlModule_1,
|
|
@@ -6425,6 +6576,8 @@ exports.WmsModuleGraphqlModule = WmsModuleGraphqlModule_1 = tslib.__decorate([
|
|
|
6425
6576
|
|
|
6426
6577
|
exports.HOST_SKIP_METADATA_KEY = HOST_SKIP_METADATA_KEY;
|
|
6427
6578
|
exports.WMS_AUTH_OPTIONS = WMS_AUTH_OPTIONS;
|
|
6579
|
+
exports.WMS_MUTATION_EVENT_METADATA = WMS_MUTATION_EVENT_METADATA;
|
|
6428
6580
|
exports.WMS_OPERATION_METADATA = WMS_OPERATION_METADATA;
|
|
6581
|
+
exports.WmsMutationEvent = WmsMutationEvent;
|
|
6429
6582
|
exports.WmsOperation = WmsOperation;
|
|
6430
6583
|
exports.createWmsLoaders = createWmsLoaders;
|
package/index.d.ts
CHANGED
|
@@ -5,3 +5,5 @@ export type { LoaderType } from './lib/helpers/dataloader.type';
|
|
|
5
5
|
export { createWmsLoaders, type WmsLoaders, } from './lib/helpers/create-wms-loaders';
|
|
6
6
|
export { HOST_SKIP_METADATA_KEY, WmsAuthGuard, WmsOperation, WMS_AUTH_OPTIONS, WMS_OPERATION_METADATA, type WmsAuthChecker, type WmsAuthModuleOptions, type WmsOperationRequirement, } from './lib/auth';
|
|
7
7
|
export type { WmsModuleGraphqlModuleAsyncOptions } from './lib/graphql.module';
|
|
8
|
+
export { WmsMutationEvent, WmsMutationInterceptor, WMS_MUTATION_EVENT_METADATA, type WmsMutationEventConfig, type WmsOperationResultMap, type WmsEventPayloadFor, type WmsTypedAfterEventContext, type WmsTypedAfterListenerMap, type WmsTypedBeforeHookContext, type WmsTypedBeforeHookMap, } from './lib/events';
|
|
9
|
+
export type { WmsActor, WmsActorExtractor, WmsAfterEventContext, WmsAfterListener, WmsAfterListenerMap, WmsBeforeHook, WmsBeforeHookContext, WmsBeforeHookMap, WmsDomainEvent, WmsEventModuleOptions, WmsEventName, WmsEventPayloadMap, WmsOperationEventName, WmsOperationEventPayload, WmsStockEventName, WmsStockEventPayload, } from '@rytass/wms-module-core';
|
package/index.js
CHANGED
|
@@ -5,3 +5,6 @@ export { HOST_SKIP_METADATA_KEY } from './lib/auth/host-skip.constant.js';
|
|
|
5
5
|
export { WmsAuthGuard } from './lib/auth/wms-auth.guard.js';
|
|
6
6
|
export { WmsOperation } from './lib/auth/wms-operation.decorator.js';
|
|
7
7
|
export { WMS_AUTH_OPTIONS, WMS_OPERATION_METADATA } from './lib/auth/wms-auth.types.js';
|
|
8
|
+
export { WmsMutationEvent } from './lib/events/wms-mutation-event.decorator.js';
|
|
9
|
+
export { WMS_MUTATION_EVENT_METADATA } from './lib/events/wms-mutation-event.constants.js';
|
|
10
|
+
export { WmsMutationInterceptor } from './lib/events/wms-mutation.interceptor.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { WmsMutationEvent } from './wms-mutation-event.decorator';
|
|
2
|
+
export { WMS_MUTATION_EVENT_METADATA, type WmsMutationEventConfig, } from './wms-mutation-event.constants';
|
|
3
|
+
export { WmsMutationInterceptor } from './wms-mutation.interceptor';
|
|
4
|
+
export type { WmsOperationResultMap } from './operation-result-map';
|
|
5
|
+
export type { WmsEventPayloadFor, WmsTypedAfterEventContext, WmsTypedAfterListenerMap, WmsTypedBeforeHookContext, WmsTypedBeforeHookMap, } from './typed-maps';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file operation-result-map.ts
|
|
3
|
+
* Typed overlay that maps every {@link WmsOperationEventName} to the concrete
|
|
4
|
+
* DTO (or `boolean`) returned by that mutation. Used by {@link WmsEventPayloadFor}
|
|
5
|
+
* and the consumer-facing typed hook/listener maps in `typed-maps.ts`.
|
|
6
|
+
*
|
|
7
|
+
* `WmsOperationResultMap` extends `Record<WmsOperationEventName, unknown>` so
|
|
8
|
+
* the compiler rejects any key that is not a valid operation-event name, and
|
|
9
|
+
* flags missing keys at the interface level — every new mutation must add an
|
|
10
|
+
* entry here.
|
|
11
|
+
*/
|
|
12
|
+
import type { WmsOperationEventName } from '@rytass/wms-module-core';
|
|
13
|
+
import type { AllocateInventoryOrderDto, HoldInventoryOrderDto, LoaderDto, LoaderTypeDto, MaterialDto, QualityInspectionOrderDto, ReceiveInventoryOrderDto, ScrapeOrderDto, ShipInventoryOrderDto, TransferCustomerOrderDto, TransferOrderDto, TransferVendorOrderDto } from '../dto';
|
|
14
|
+
import type { LocationDto } from '../dto/location.dto';
|
|
15
|
+
import type { MapDataDto } from '../dto/warehouse-map.dto';
|
|
16
|
+
import type { MergeBatchOrderDto } from '../dto/merge-batch-order.dto';
|
|
17
|
+
import type { ReclassifyInventoryOrderDto } from '../dto/reclassify-inventory-order.dto';
|
|
18
|
+
import type { SplitBatchOrderDto } from '../dto/split-batch-order.dto';
|
|
19
|
+
/**
|
|
20
|
+
* Maps every {@link WmsOperationEventName} to the concrete type returned by
|
|
21
|
+
* the corresponding mutation resolver.
|
|
22
|
+
*
|
|
23
|
+
* - **DTO-returning mutations (29)**: the resolved DTO class.
|
|
24
|
+
* - **Action mutations (9)**: `boolean` (success flag; real intent is in
|
|
25
|
+
* `WmsOperationEventPayload.args` and the accompanying stock events).
|
|
26
|
+
*
|
|
27
|
+
* Maintenance: for every new `@Mutation`, add the matching entry here.
|
|
28
|
+
*/
|
|
29
|
+
export interface WmsOperationResultMap extends Record<WmsOperationEventName, unknown> {
|
|
30
|
+
'material.created': MaterialDto;
|
|
31
|
+
'material.updated': MaterialDto;
|
|
32
|
+
'location.created': LocationDto;
|
|
33
|
+
'location.updated': LocationDto;
|
|
34
|
+
'warehouse-map.updated': MapDataDto;
|
|
35
|
+
'loader.created': LoaderDto[];
|
|
36
|
+
'loader.batch-created': LoaderDto[];
|
|
37
|
+
'loader.updated': LoaderDto;
|
|
38
|
+
'loader.type-created': LoaderTypeDto;
|
|
39
|
+
'loader.type-updated': LoaderTypeDto;
|
|
40
|
+
'receive-inventory-order.created': ReceiveInventoryOrderDto;
|
|
41
|
+
'receive-inventory-order.updated': ReceiveInventoryOrderDto;
|
|
42
|
+
/** Action mutation — result is a success flag; use args + stock.received. */
|
|
43
|
+
'receive-inventory-order.received': boolean;
|
|
44
|
+
'allocate-inventory-order.created': AllocateInventoryOrderDto;
|
|
45
|
+
'allocate-inventory-order.updated': AllocateInventoryOrderDto;
|
|
46
|
+
/** Action mutation — result is a success flag; use args + stock.deallocated. */
|
|
47
|
+
'allocate-inventory-order.deallocated': boolean;
|
|
48
|
+
'hold-inventory-order.created': HoldInventoryOrderDto;
|
|
49
|
+
'hold-inventory-order.updated': HoldInventoryOrderDto;
|
|
50
|
+
/** Action mutation — result is a success flag; use args + stock.released. */
|
|
51
|
+
'hold-inventory-order.released': boolean;
|
|
52
|
+
'reclassify-inventory-order.reclassified': ReclassifyInventoryOrderDto;
|
|
53
|
+
'ship-inventory-order.created': ShipInventoryOrderDto;
|
|
54
|
+
'ship-inventory-order.updated': ShipInventoryOrderDto;
|
|
55
|
+
/** Action mutation — result is a success flag; use args + stock.shipped. */
|
|
56
|
+
'ship-inventory-order.shipped': boolean;
|
|
57
|
+
/** Action mutation — result is a success flag; use args + stock.shipped (negative). */
|
|
58
|
+
'ship-inventory-order.ship-cancelled': boolean;
|
|
59
|
+
'batch.merged': MergeBatchOrderDto;
|
|
60
|
+
'batch.splitted': SplitBatchOrderDto;
|
|
61
|
+
'scrape-order.scraped': ScrapeOrderDto;
|
|
62
|
+
'quality-inspection-order.inspected': QualityInspectionOrderDto;
|
|
63
|
+
'transfer-order.created': TransferOrderDto;
|
|
64
|
+
'transfer-order.updated': TransferOrderDto;
|
|
65
|
+
/** Action mutation — result is a success flag; use args + stock.transferred. */
|
|
66
|
+
'transfer-order.transferred': boolean;
|
|
67
|
+
/** Action mutation — result is a success flag; use args + stock.in-transfer reversal. */
|
|
68
|
+
'transfer-order.transfer-cancelled': boolean;
|
|
69
|
+
'transfer-customer-order.created': TransferCustomerOrderDto;
|
|
70
|
+
'transfer-customer-order.updated': TransferCustomerOrderDto;
|
|
71
|
+
/** Action mutation — result is a success flag; use args + stock.customer-returned. */
|
|
72
|
+
'transfer-customer-order.returned': boolean;
|
|
73
|
+
'transfer-vendor-order.created': TransferVendorOrderDto;
|
|
74
|
+
'transfer-vendor-order.updated': TransferVendorOrderDto;
|
|
75
|
+
/** Action mutation — result is a success flag; use args + stock.vendor-returned. */
|
|
76
|
+
'transfer-vendor-order.returned': boolean;
|
|
77
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file typed-maps.ts
|
|
3
|
+
* Consumer-facing typed hook/listener maps for the WMS mutation event system.
|
|
4
|
+
*
|
|
5
|
+
* These types give consumers per-event type safety when wiring `beforeHooks`
|
|
6
|
+
* and `afterListeners` in `WmsModuleGraphqlModule.forRootAsync(...)`. They
|
|
7
|
+
* layer on top of the runtime-erased core contracts without introducing any
|
|
8
|
+
* runtime dependency — everything here is `import type` only.
|
|
9
|
+
*
|
|
10
|
+
* Key exports
|
|
11
|
+
* -----------
|
|
12
|
+
* - {@link WmsEventPayloadFor} — resolves the payload type for a given event name
|
|
13
|
+
* - {@link WmsTypedAfterEventContext} — ctx passed to after-listeners
|
|
14
|
+
* - {@link WmsTypedBeforeHookContext} — ctx passed to before-hooks (pre-DB)
|
|
15
|
+
* - {@link WmsTypedAfterListenerMap} — `afterListeners` option with typed callbacks
|
|
16
|
+
* - {@link WmsTypedBeforeHookMap} — `beforeHooks` option with typed callbacks
|
|
17
|
+
*/
|
|
18
|
+
import type { WmsActor, WmsEventName, WmsOperationEventName, WmsOperationEventPayload, WmsStockEventPayload } from '@rytass/wms-module-core';
|
|
19
|
+
import type { ExecutionContext } from '@nestjs/common';
|
|
20
|
+
import type { WmsOperationResultMap } from './operation-result-map';
|
|
21
|
+
/**
|
|
22
|
+
* Resolves the full event payload type for a given {@link WmsEventName}.
|
|
23
|
+
*
|
|
24
|
+
* - Operation events (`WmsOperationEventName`): `WmsOperationEventPayload`
|
|
25
|
+
* parameterised with the concrete result type from {@link WmsOperationResultMap}.
|
|
26
|
+
* - Stock events (`WmsStockEventName`): `WmsStockEventPayload` (ids-only by
|
|
27
|
+
* default; enriched when `enrichStockEvents: true`).
|
|
28
|
+
*/
|
|
29
|
+
export type WmsEventPayloadFor<N extends WmsEventName> = N extends WmsOperationEventName ? WmsOperationEventPayload<WmsOperationResultMap[N]> : WmsStockEventPayload;
|
|
30
|
+
/**
|
|
31
|
+
* Context passed to an after-listener. Runs post-commit with the full
|
|
32
|
+
* typed event payload.
|
|
33
|
+
*/
|
|
34
|
+
export interface WmsTypedAfterEventContext<N extends WmsEventName> {
|
|
35
|
+
readonly event: N;
|
|
36
|
+
readonly payload: WmsEventPayloadFor<N>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Context passed to a before-hook. Runs *before* any DB work, so
|
|
40
|
+
* `payload` / `result` are not yet available — only the raw GraphQL
|
|
41
|
+
* arguments (`args`) and the resolved actor. Throwing from a before-hook
|
|
42
|
+
* vetoes the mutation with zero side effects.
|
|
43
|
+
*/
|
|
44
|
+
export interface WmsTypedBeforeHookContext<N extends WmsEventName> {
|
|
45
|
+
readonly event: N;
|
|
46
|
+
/** Raw GraphQL arguments — the mutation intent (per §3.4 of the design doc). */
|
|
47
|
+
readonly args: Readonly<Record<string, unknown>>;
|
|
48
|
+
/** The NestJS execution context at the time of the mutation call. */
|
|
49
|
+
readonly executionContext: ExecutionContext;
|
|
50
|
+
/** Who performed the mutation; `null` when no `actorExtractor` is configured. */
|
|
51
|
+
readonly actor: WmsActor | null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Typed `afterListeners` map. Each key is an optional per-event callback
|
|
55
|
+
* that receives a fully typed {@link WmsTypedAfterEventContext}.
|
|
56
|
+
*
|
|
57
|
+
* Pass an instance of this type as `afterListeners` in
|
|
58
|
+
* `WmsModuleGraphqlModule.forRootAsync(...)` to get per-event type safety.
|
|
59
|
+
*/
|
|
60
|
+
export type WmsTypedAfterListenerMap = {
|
|
61
|
+
readonly [N in WmsEventName]?: (ctx: WmsTypedAfterEventContext<N>) => void | Promise<void>;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Typed `beforeHooks` map. Each key is an optional per-event callback
|
|
65
|
+
* that receives a fully typed {@link WmsTypedBeforeHookContext}.
|
|
66
|
+
*
|
|
67
|
+
* Throwing inside a before-hook vetoes the mutation before any transaction
|
|
68
|
+
* is opened. Pass an instance of this type as `beforeHooks` in
|
|
69
|
+
* `WmsModuleGraphqlModule.forRootAsync(...)`.
|
|
70
|
+
*/
|
|
71
|
+
export type WmsTypedBeforeHookMap = {
|
|
72
|
+
readonly [N in WmsEventName]?: (ctx: WmsTypedBeforeHookContext<N>) => void | Promise<void>;
|
|
73
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { WmsOperationEventName } from '@rytass/wms-module-core';
|
|
2
|
+
/** Reflector metadata key carrying the {@link WmsMutationEventConfig}. */
|
|
3
|
+
export declare const WMS_MUTATION_EVENT_METADATA = "wms:mutation-event";
|
|
4
|
+
export interface WmsMutationEventConfig {
|
|
5
|
+
/** The operation event emitted for this mutation (post-commit). */
|
|
6
|
+
readonly event: WmsOperationEventName;
|
|
7
|
+
/**
|
|
8
|
+
* Optional override for deriving the operation's primary id from the handler
|
|
9
|
+
* result and/or arguments. Defaults to `result.id ?? args.id ?? null`.
|
|
10
|
+
*/
|
|
11
|
+
readonly resolveId?: (result: unknown, args: Readonly<Record<string, unknown>>) => string | null;
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type WmsMutationEventConfig } from './wms-mutation-event.constants';
|
|
2
|
+
/**
|
|
3
|
+
* Declares the operation event for a WMS root mutation and wires the
|
|
4
|
+
* {@link WmsMutationInterceptor} that runs before-hooks (veto) and flushes
|
|
5
|
+
* collected events post-commit. Apply alongside `@WmsOperation` on each mutation.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* @Mutation(() => ShipInventoryOrderDto)
|
|
10
|
+
* @WmsOperation({ resource: 'ship-inventory-order', action: 'ship' })
|
|
11
|
+
* @WmsMutationEvent({ event: 'ship-inventory-order.shipped' })
|
|
12
|
+
* ship(@Args() args: ShipArgs): Promise<boolean> { ... }
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare const WmsMutationEvent: (config: WmsMutationEventConfig) => MethodDecorator;
|