@mbc-cqrs-serverless/core 1.3.3 → 1.3.5
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 +37 -0
- package/dist/app.module.js +2 -0
- package/dist/app.module.js.map +1 -1
- package/dist/auth/auth.module.d.ts +2 -0
- package/dist/auth/auth.module.js +30 -0
- package/dist/auth/auth.module.js.map +1 -0
- package/dist/auth/authz-bootstrap.service.d.ts +11 -0
- package/dist/auth/authz-bootstrap.service.js +47 -0
- package/dist/auth/authz-bootstrap.service.js.map +1 -0
- package/dist/auth/group-role-resolver.interface.d.ts +13 -0
- package/dist/auth/group-role-resolver.interface.js +3 -0
- package/dist/auth/group-role-resolver.interface.js.map +1 -0
- package/dist/auth/group-role-resolver.registry.d.ts +6 -0
- package/dist/auth/group-role-resolver.registry.js +26 -0
- package/dist/auth/group-role-resolver.registry.js.map +1 -0
- package/dist/auth/index.d.ts +4 -0
- package/dist/auth/index.js +21 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/command-events/data-sync.new.event.handler.js +25 -1
- package/dist/command-events/data-sync.new.event.handler.js.map +1 -1
- package/dist/commands/command.event.handler.d.ts +26 -1
- package/dist/commands/command.event.handler.js +165 -6
- package/dist/commands/command.event.handler.js.map +1 -1
- package/dist/commands/command.service.d.ts +3 -1
- package/dist/commands/command.service.js +40 -12
- package/dist/commands/command.service.js.map +1 -1
- package/dist/context/invoke.d.ts +1 -0
- package/dist/context/invoke.js +1 -1
- package/dist/context/invoke.js.map +1 -1
- package/dist/context/user.d.ts +4 -0
- package/dist/context/user.js +50 -0
- package/dist/context/user.js.map +1 -1
- package/dist/data-store/dynamodb.service.d.ts +3 -1
- package/dist/data-store/dynamodb.service.js +2 -1
- package/dist/data-store/dynamodb.service.js.map +1 -1
- package/dist/decorators/constants.d.ts +2 -0
- package/dist/decorators/constants.js +3 -1
- package/dist/decorators/constants.js.map +1 -1
- package/dist/decorators/data-sync-handler.decorator.d.ts +19 -0
- package/dist/decorators/data-sync-handler.decorator.js +19 -0
- package/dist/decorators/data-sync-handler.decorator.js.map +1 -1
- package/dist/decorators/group-role-resolver.decorator.d.ts +9 -0
- package/dist/decorators/group-role-resolver.decorator.js +17 -0
- package/dist/decorators/group-role-resolver.decorator.js.map +1 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +2 -0
- package/dist/decorators/index.js.map +1 -1
- package/dist/decorators/notification-transport.decorator.d.ts +6 -0
- package/dist/decorators/notification-transport.decorator.js +14 -0
- package/dist/decorators/notification-transport.decorator.js.map +1 -0
- package/dist/env.validation.d.ts +19 -0
- package/dist/env.validation.js +45 -2
- package/dist/env.validation.js.map +1 -1
- package/dist/guard/roles.guard.d.ts +11 -1
- package/dist/guard/roles.guard.js +44 -8
- package/dist/guard/roles.guard.js.map +1 -1
- package/dist/helpers/serializer.d.ts +1 -2
- package/dist/helpers/serializer.js +34 -7
- package/dist/helpers/serializer.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/command-module-options.interface.d.ts +11 -1
- package/dist/notification-env.validation.d.ts +8 -0
- package/dist/notification-env.validation.js +36 -0
- package/dist/notification-env.validation.js.map +1 -0
- package/dist/notifications/appsync-events.service.d.ts +44 -0
- package/dist/notifications/appsync-events.service.js +147 -0
- package/dist/notifications/appsync-events.service.js.map +1 -0
- package/dist/notifications/appsync.service.d.ts +3 -2
- package/dist/notifications/appsync.service.js +20 -12
- package/dist/notifications/appsync.service.js.map +1 -1
- package/dist/notifications/enums/index.d.ts +1 -0
- package/dist/notifications/enums/index.js +18 -0
- package/dist/notifications/enums/index.js.map +1 -0
- package/dist/notifications/enums/notification-transport.enum.d.ts +4 -0
- package/dist/notifications/enums/notification-transport.enum.js +9 -0
- package/dist/notifications/enums/notification-transport.enum.js.map +1 -0
- package/dist/notifications/event/notification.event.handler.d.ts +13 -5
- package/dist/notifications/event/notification.event.handler.js +31 -7
- package/dist/notifications/event/notification.event.handler.js.map +1 -1
- package/dist/notifications/index.d.ts +3 -0
- package/dist/notifications/index.js +3 -0
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/interfaces/index.d.ts +1 -0
- package/dist/notifications/interfaces/index.js +18 -0
- package/dist/notifications/interfaces/index.js.map +1 -0
- package/dist/notifications/interfaces/notification-transport.interface.d.ts +7 -0
- package/dist/notifications/interfaces/notification-transport.interface.js +5 -0
- package/dist/notifications/interfaces/notification-transport.interface.js.map +1 -0
- package/dist/notifications/notification.module.js +12 -2
- package/dist/notifications/notification.module.js.map +1 -1
- package/dist/services/explorer.service.d.ts +5 -0
- package/dist/services/explorer.service.js +12 -1
- package/dist/services/explorer.service.js.map +1 -1
- package/dist/services/mocks/group-role-resolver.mock.d.ts +4 -0
- package/dist/services/mocks/group-role-resolver.mock.js +20 -0
- package/dist/services/mocks/group-role-resolver.mock.js.map +1 -0
- package/dist/step-func/step-function.service.js +6 -1
- package/dist/step-func/step-function.service.js.map +1 -1
- package/package.json +4 -4
package/dist/env.validation.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ClassConstructor } from 'class-transformer';
|
|
2
|
+
export { BUILTIN_NOTIFICATION_TRANSPORT_ENV, parseNotificationTransports, validateBuiltinNotificationTransportEnv, } from './notification-env.validation';
|
|
2
3
|
export declare enum Environment {
|
|
3
4
|
Local = "local",
|
|
4
5
|
Development = "dev",
|
|
@@ -22,7 +23,25 @@ export declare class EnvironmentVariables {
|
|
|
22
23
|
SFN_COMMAND_ARN: string;
|
|
23
24
|
SNS_ENDPOINT: string;
|
|
24
25
|
SNS_REGION: string;
|
|
26
|
+
/**
|
|
27
|
+
* Comma-separated list of active notification transport names.
|
|
28
|
+
* Supported built-in values: 'appsync-graphql' | 'appsync-event'
|
|
29
|
+
* Defaults to 'appsync-graphql' when not set.
|
|
30
|
+
*
|
|
31
|
+
* Examples:
|
|
32
|
+
* NOTIFICATION_TRANSPORTS=appsync-graphql
|
|
33
|
+
* NOTIFICATION_TRANSPORTS=appsync-event
|
|
34
|
+
* NOTIFICATION_TRANSPORTS=appsync-graphql,appsync-event
|
|
35
|
+
*/
|
|
36
|
+
NOTIFICATION_TRANSPORTS: string;
|
|
25
37
|
APPSYNC_ENDPOINT: string;
|
|
38
|
+
APPSYNC_EVENTS_ENDPOINT: string;
|
|
39
|
+
/**
|
|
40
|
+
* Channel namespace name — must match the pre-created namespace in the
|
|
41
|
+
* AppSync Event API (segment 1 of every channel path).
|
|
42
|
+
* Defaults to 'default'.
|
|
43
|
+
*/
|
|
44
|
+
APPSYNC_EVENTS_NAMESPACE: string;
|
|
26
45
|
SES_ENDPOINT: string;
|
|
27
46
|
SES_REGION: string;
|
|
28
47
|
SES_FROM_EMAIL: string;
|
package/dist/env.validation.js
CHANGED
|
@@ -9,10 +9,16 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.EnvironmentVariables = exports.Environment = void 0;
|
|
12
|
+
exports.EnvironmentVariables = exports.Environment = exports.validateBuiltinNotificationTransportEnv = exports.parseNotificationTransports = exports.BUILTIN_NOTIFICATION_TRANSPORT_ENV = void 0;
|
|
13
13
|
exports.getValidateConfig = getValidateConfig;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
14
15
|
const class_transformer_1 = require("class-transformer");
|
|
15
16
|
const class_validator_1 = require("class-validator");
|
|
17
|
+
const notification_env_validation_1 = require("./notification-env.validation");
|
|
18
|
+
var notification_env_validation_2 = require("./notification-env.validation");
|
|
19
|
+
Object.defineProperty(exports, "BUILTIN_NOTIFICATION_TRANSPORT_ENV", { enumerable: true, get: function () { return notification_env_validation_2.BUILTIN_NOTIFICATION_TRANSPORT_ENV; } });
|
|
20
|
+
Object.defineProperty(exports, "parseNotificationTransports", { enumerable: true, get: function () { return notification_env_validation_2.parseNotificationTransports; } });
|
|
21
|
+
Object.defineProperty(exports, "validateBuiltinNotificationTransportEnv", { enumerable: true, get: function () { return notification_env_validation_2.validateBuiltinNotificationTransportEnv; } });
|
|
16
22
|
var Environment;
|
|
17
23
|
(function (Environment) {
|
|
18
24
|
Environment["Local"] = "local";
|
|
@@ -96,11 +102,26 @@ __decorate([
|
|
|
96
102
|
(0, class_validator_1.IsOptional)(),
|
|
97
103
|
__metadata("design:type", String)
|
|
98
104
|
], EnvironmentVariables.prototype, "SNS_REGION", void 0);
|
|
105
|
+
__decorate([
|
|
106
|
+
(0, class_validator_1.IsString)(),
|
|
107
|
+
(0, class_validator_1.IsOptional)(),
|
|
108
|
+
__metadata("design:type", String)
|
|
109
|
+
], EnvironmentVariables.prototype, "NOTIFICATION_TRANSPORTS", void 0);
|
|
99
110
|
__decorate([
|
|
100
111
|
(0, class_validator_1.IsString)(),
|
|
101
112
|
(0, class_validator_1.IsOptional)(),
|
|
102
113
|
__metadata("design:type", String)
|
|
103
114
|
], EnvironmentVariables.prototype, "APPSYNC_ENDPOINT", void 0);
|
|
115
|
+
__decorate([
|
|
116
|
+
(0, class_validator_1.IsString)(),
|
|
117
|
+
(0, class_validator_1.IsOptional)(),
|
|
118
|
+
__metadata("design:type", String)
|
|
119
|
+
], EnvironmentVariables.prototype, "APPSYNC_EVENTS_ENDPOINT", void 0);
|
|
120
|
+
__decorate([
|
|
121
|
+
(0, class_validator_1.IsString)(),
|
|
122
|
+
(0, class_validator_1.IsOptional)(),
|
|
123
|
+
__metadata("design:type", String)
|
|
124
|
+
], EnvironmentVariables.prototype, "APPSYNC_EVENTS_NAMESPACE", void 0);
|
|
104
125
|
__decorate([
|
|
105
126
|
(0, class_validator_1.IsString)(),
|
|
106
127
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -125,9 +146,30 @@ __decorate([
|
|
|
125
146
|
(0, class_validator_1.IsOptional)(),
|
|
126
147
|
__metadata("design:type", Number)
|
|
127
148
|
], EnvironmentVariables.prototype, "RYW_SESSION_TTL_MINUTES", void 0);
|
|
149
|
+
// Deprecated environment variable mappings: [oldName, newName]
|
|
150
|
+
const DEPRECATED_ENV_VARS = [
|
|
151
|
+
['COGNITO_USER_POLL_CLIENT_ID', 'COGNITO_USER_POOL_CLIENT_ID'],
|
|
152
|
+
];
|
|
153
|
+
/**
|
|
154
|
+
* Migrate deprecated environment variable names to their new names.
|
|
155
|
+
* If the old name is set and the new name is not, the value is copied
|
|
156
|
+
* to the new name and a deprecation warning is logged.
|
|
157
|
+
*/
|
|
158
|
+
function migrateDeprecatedEnvVars(config) {
|
|
159
|
+
const logger = new common_1.Logger('EnvValidation');
|
|
160
|
+
for (const [oldName, newName] of DEPRECATED_ENV_VARS) {
|
|
161
|
+
if (config[oldName] !== undefined && config[newName] === undefined) {
|
|
162
|
+
config[newName] = config[oldName];
|
|
163
|
+
logger.warn(`Environment variable "${oldName}" is deprecated. ` +
|
|
164
|
+
`Please use "${newName}" instead.`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return config;
|
|
168
|
+
}
|
|
128
169
|
function getValidateConfig(cls) {
|
|
129
170
|
return function validate(config) {
|
|
130
|
-
const
|
|
171
|
+
const migratedConfig = migrateDeprecatedEnvVars(config);
|
|
172
|
+
const validatedConfig = (0, class_transformer_1.plainToInstance)(cls || EnvironmentVariables, migratedConfig, {
|
|
131
173
|
enableImplicitConversion: true,
|
|
132
174
|
});
|
|
133
175
|
const errors = (0, class_validator_1.validateSync)(validatedConfig, {
|
|
@@ -136,6 +178,7 @@ function getValidateConfig(cls) {
|
|
|
136
178
|
if (errors.length > 0) {
|
|
137
179
|
throw new Error(errors.toString());
|
|
138
180
|
}
|
|
181
|
+
(0, notification_env_validation_1.validateBuiltinNotificationTransportEnv)(validatedConfig);
|
|
139
182
|
return validatedConfig;
|
|
140
183
|
};
|
|
141
184
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.validation.js","sourceRoot":"","sources":["../src/env.validation.ts"],"names":[],"mappings":";;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"env.validation.js","sourceRoot":"","sources":["../src/env.validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { CanActivate, ExecutionContext, Logger } from '@nestjs/common';
|
|
2
2
|
import { Reflector } from '@nestjs/core';
|
|
3
|
+
import { GroupRoleResolverRegistry } from '../auth/group-role-resolver.registry';
|
|
3
4
|
import { UserContext } from '../context';
|
|
4
5
|
export declare class RolesGuard implements CanActivate {
|
|
5
6
|
protected reflector: Reflector;
|
|
7
|
+
protected registry?: GroupRoleResolverRegistry;
|
|
6
8
|
protected readonly logger: Logger;
|
|
7
|
-
constructor(reflector: Reflector);
|
|
9
|
+
constructor(reflector: Reflector, registry?: GroupRoleResolverRegistry);
|
|
8
10
|
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
9
11
|
/**
|
|
10
12
|
* Verify tenant access.
|
|
@@ -59,6 +61,14 @@ export declare class RolesGuard implements CanActivate {
|
|
|
59
61
|
* This is a helper method that can be used by subclasses.
|
|
60
62
|
*/
|
|
61
63
|
protected getAuthorizerClaims(context: ExecutionContext): import("../context").JwtClaims;
|
|
64
|
+
protected hasAnyRole(requiredRoles: string[], userRoles: string[]): boolean;
|
|
65
|
+
protected resolveGroupRoles(context: ExecutionContext, groupIds: string[]): Promise<string[]>;
|
|
62
66
|
protected verifyRole(context: ExecutionContext): Promise<boolean>;
|
|
67
|
+
/**
|
|
68
|
+
* Returns the primary direct role string from JWT context.
|
|
69
|
+
*
|
|
70
|
+
* @deprecated Not invoked by `verifyRole`. For custom authorization, override
|
|
71
|
+
* `verifyRole`, `resolveGroupRoles`, or `canOverrideTenant` instead.
|
|
72
|
+
*/
|
|
63
73
|
protected getUserRole(context: ExecutionContext): Promise<string>;
|
|
64
74
|
}
|
|
@@ -8,17 +8,22 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
11
14
|
var RolesGuard_1;
|
|
12
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
16
|
exports.RolesGuard = void 0;
|
|
14
17
|
const common_1 = require("@nestjs/common");
|
|
15
18
|
const core_1 = require("@nestjs/core");
|
|
19
|
+
const group_role_resolver_registry_1 = require("../auth/group-role-resolver.registry");
|
|
16
20
|
const constants_1 = require("../constants");
|
|
17
21
|
const context_1 = require("../context");
|
|
18
22
|
const decorators_1 = require("../decorators");
|
|
19
23
|
let RolesGuard = RolesGuard_1 = class RolesGuard {
|
|
20
|
-
constructor(reflector) {
|
|
24
|
+
constructor(reflector, registry) {
|
|
21
25
|
this.reflector = reflector;
|
|
26
|
+
this.registry = registry;
|
|
22
27
|
this.logger = new common_1.Logger(RolesGuard_1.name);
|
|
23
28
|
}
|
|
24
29
|
async canActivate(context) {
|
|
@@ -113,22 +118,51 @@ let RolesGuard = RolesGuard_1 = class RolesGuard {
|
|
|
113
118
|
const invokeContext = (0, context_1.extractInvokeContext)(context);
|
|
114
119
|
return (0, context_1.getAuthorizerClaims)(invokeContext);
|
|
115
120
|
}
|
|
121
|
+
hasAnyRole(requiredRoles, userRoles) {
|
|
122
|
+
return requiredRoles.some((role) => userRoles.includes(role));
|
|
123
|
+
}
|
|
124
|
+
async resolveGroupRoles(context, groupIds) {
|
|
125
|
+
const resolver = this.registry?.get();
|
|
126
|
+
if (!resolver || !groupIds.length) {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
const userContext = (0, context_1.getUserContext)(context);
|
|
130
|
+
const claims = this.getAuthorizerClaims(context);
|
|
131
|
+
try {
|
|
132
|
+
return await resolver.resolveRoles({
|
|
133
|
+
tenantCode: userContext.tenantCode,
|
|
134
|
+
groupIds,
|
|
135
|
+
claims,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
this.logger.error('GroupRoleResolver.resolveRoles failed', err);
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
116
143
|
async verifyRole(context) {
|
|
117
144
|
const requiredRoles = this.reflector.getAllAndOverride(decorators_1.ROLE_METADATA, [context.getHandler(), context.getClass()]);
|
|
118
145
|
if (!requiredRoles || !requiredRoles.length) {
|
|
119
146
|
// all user can access
|
|
120
147
|
return true;
|
|
121
148
|
}
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
149
|
+
const userContext = (0, context_1.getUserContext)(context);
|
|
150
|
+
const { tenantRoles, tenantGroupIds } = userContext;
|
|
151
|
+
if (tenantRoles.includes(constants_1.ROLE_SYSTEM_ADMIN)) {
|
|
152
|
+
return true;
|
|
125
153
|
}
|
|
126
|
-
if (
|
|
154
|
+
if (this.hasAnyRole(requiredRoles, tenantRoles)) {
|
|
127
155
|
return true;
|
|
128
156
|
}
|
|
129
|
-
|
|
157
|
+
const groupRoles = await this.resolveGroupRoles(context, tenantGroupIds);
|
|
158
|
+
return this.hasAnyRole(requiredRoles, groupRoles);
|
|
130
159
|
}
|
|
131
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Returns the primary direct role string from JWT context.
|
|
162
|
+
*
|
|
163
|
+
* @deprecated Not invoked by `verifyRole`. For custom authorization, override
|
|
164
|
+
* `verifyRole`, `resolveGroupRoles`, or `canOverrideTenant` instead.
|
|
165
|
+
*/
|
|
132
166
|
async getUserRole(context) {
|
|
133
167
|
const userContext = (0, context_1.getUserContext)(context);
|
|
134
168
|
return userContext.tenantRole;
|
|
@@ -137,6 +171,8 @@ let RolesGuard = RolesGuard_1 = class RolesGuard {
|
|
|
137
171
|
exports.RolesGuard = RolesGuard;
|
|
138
172
|
exports.RolesGuard = RolesGuard = RolesGuard_1 = __decorate([
|
|
139
173
|
(0, common_1.Injectable)(),
|
|
140
|
-
|
|
174
|
+
__param(1, (0, common_1.Optional)()),
|
|
175
|
+
__metadata("design:paramtypes", [core_1.Reflector,
|
|
176
|
+
group_role_resolver_registry_1.GroupRoleResolverRegistry])
|
|
141
177
|
], RolesGuard);
|
|
142
178
|
//# sourceMappingURL=roles.guard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roles.guard.js","sourceRoot":"","sources":["../../src/guard/roles.guard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"roles.guard.js","sourceRoot":"","sources":["../../src/guard/roles.guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,10 +6,9 @@ export interface SerializerOptions {
|
|
|
6
6
|
/**
|
|
7
7
|
* Converts internal DynamoDB structure to external flat structure
|
|
8
8
|
* @param item Internal item (CommandEntity or DataEntity)
|
|
9
|
-
* @param options Serialization options
|
|
10
9
|
* @returns Flattened external structure
|
|
11
10
|
*/
|
|
12
|
-
export declare function serializeToExternal<T extends CommandEntity | DataEntity>(item: T | null | undefined
|
|
11
|
+
export declare function serializeToExternal<T extends CommandEntity | DataEntity>(item: T | null | undefined): Record<string, any> | null;
|
|
13
12
|
/**
|
|
14
13
|
* Converts external flat structure to internal DynamoDB structure
|
|
15
14
|
* @param data External flat structure
|
|
@@ -5,10 +5,9 @@ exports.deserializeToInternal = deserializeToInternal;
|
|
|
5
5
|
/**
|
|
6
6
|
* Converts internal DynamoDB structure to external flat structure
|
|
7
7
|
* @param item Internal item (CommandEntity or DataEntity)
|
|
8
|
-
* @param options Serialization options
|
|
9
8
|
* @returns Flattened external structure
|
|
10
9
|
*/
|
|
11
|
-
function serializeToExternal(item
|
|
10
|
+
function serializeToExternal(item) {
|
|
12
11
|
if (!item)
|
|
13
12
|
return null;
|
|
14
13
|
const result = {
|
|
@@ -17,7 +16,7 @@ function serializeToExternal(item, options = {}) {
|
|
|
17
16
|
name: item.name,
|
|
18
17
|
};
|
|
19
18
|
// Copy first level properties
|
|
20
|
-
Object.keys(item).forEach(key => {
|
|
19
|
+
Object.keys(item).forEach((key) => {
|
|
21
20
|
if (key !== 'attributes' && typeof item[key] !== 'undefined') {
|
|
22
21
|
result[key] = item[key];
|
|
23
22
|
}
|
|
@@ -46,15 +45,43 @@ function deserializeToInternal(data, EntityClass) {
|
|
|
46
45
|
entity.pk = pk;
|
|
47
46
|
entity.sk = sk || data.code;
|
|
48
47
|
entity.name = data.name;
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
[
|
|
49
|
+
'version',
|
|
50
|
+
'tenantCode',
|
|
51
|
+
'type',
|
|
52
|
+
'isDeleted',
|
|
53
|
+
'status',
|
|
54
|
+
'createdAt',
|
|
55
|
+
'updatedAt',
|
|
56
|
+
'createdBy',
|
|
57
|
+
'updatedBy',
|
|
58
|
+
'createdIp',
|
|
59
|
+
'updatedIp',
|
|
60
|
+
].forEach((key) => {
|
|
51
61
|
if (key in data) {
|
|
52
62
|
entity[key] = data[key];
|
|
53
63
|
}
|
|
54
64
|
});
|
|
55
65
|
// Separate remaining fields into attributes
|
|
56
|
-
Object.keys(data).forEach(key => {
|
|
57
|
-
if (![
|
|
66
|
+
Object.keys(data).forEach((key) => {
|
|
67
|
+
if (![
|
|
68
|
+
'id',
|
|
69
|
+
'code',
|
|
70
|
+
'pk',
|
|
71
|
+
'sk',
|
|
72
|
+
'name',
|
|
73
|
+
'version',
|
|
74
|
+
'tenantCode',
|
|
75
|
+
'type',
|
|
76
|
+
'isDeleted',
|
|
77
|
+
'status',
|
|
78
|
+
'createdAt',
|
|
79
|
+
'updatedAt',
|
|
80
|
+
'createdBy',
|
|
81
|
+
'updatedBy',
|
|
82
|
+
'createdIp',
|
|
83
|
+
'updatedIp',
|
|
84
|
+
].includes(key)) {
|
|
58
85
|
if (key in entity) {
|
|
59
86
|
entity[key] = data[key];
|
|
60
87
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../../src/helpers/serializer.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../../src/helpers/serializer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./app.module"), exports);
|
|
18
|
+
__exportStar(require("./auth"), exports);
|
|
18
19
|
__exportStar(require("./bootstrap"), exports);
|
|
19
20
|
__exportStar(require("./command-events"), exports);
|
|
20
21
|
__exportStar(require("./commands"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA4B;AAC5B,8CAA2B;AAC3B,mDAAgC;AAChC,6CAA0B;AAC1B,8CAA2B;AAC3B,4CAAyB;AACzB,+CAA4B;AAC5B,+CAA4B;AAC5B,mDAAgC;AAChC,2CAAwB;AACxB,+CAA4B;AAC5B,4CAAyB;AACzB,0CAAuB;AACvB,4CAAyB;AACzB,+CAA4B;AAC5B,kDAA+B;AAC/B,yCAAsB;AACtB,0CAAuB;AACvB,6CAA0B;AAC1B,8CAA2B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA4B;AAC5B,yCAAsB;AACtB,8CAA2B;AAC3B,mDAAgC;AAChC,6CAA0B;AAC1B,8CAA2B;AAC3B,4CAAyB;AACzB,+CAA4B;AAC5B,+CAA4B;AAC5B,mDAAgC;AAChC,2CAAwB;AACxB,+CAA4B;AAC5B,4CAAyB;AACzB,0CAAuB;AACvB,4CAAyB;AACzB,+CAA4B;AAC5B,kDAA+B;AAC/B,yCAAsB;AACtB,0CAAuB;AACvB,6CAA0B;AAC1B,8CAA2B"}
|
|
@@ -15,7 +15,17 @@ export interface CommandModuleOptions {
|
|
|
15
15
|
tableName: string;
|
|
16
16
|
/** If true, skips errors from previous command versions */
|
|
17
17
|
skipError?: boolean;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Custom handlers for syncing command data to read models.
|
|
20
|
+
*
|
|
21
|
+
* **Recommended (primary) registration path.**
|
|
22
|
+
* Classes listed here are automatically added as providers and resolved
|
|
23
|
+
* by the NestJS DI container. This path is explicit about module ownership
|
|
24
|
+
* and is fully covered by the duplicate-detection guard in CommandService.
|
|
25
|
+
*
|
|
26
|
+
* Avoid combining this with `@DataSyncHandler` decorator on the same class —
|
|
27
|
+
* that causes duplicate registration (detected and warned at startup).
|
|
28
|
+
*/
|
|
19
29
|
dataSyncHandlers?: Type<IDataSyncHandler>[];
|
|
20
30
|
/** If true, disables the default data sync handler */
|
|
21
31
|
disableDefaultHandler?: boolean;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Built-in transports and their required endpoint environment variables. */
|
|
2
|
+
export declare const BUILTIN_NOTIFICATION_TRANSPORT_ENV: Record<string, string>;
|
|
3
|
+
/**
|
|
4
|
+
* Parses NOTIFICATION_TRANSPORTS the same way as NotificationEventHandler.
|
|
5
|
+
* Defaults to appsync-graphql when unset or empty.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseNotificationTransports(raw: string | undefined): string[];
|
|
8
|
+
export declare function validateBuiltinNotificationTransportEnv(config: Record<string, unknown>): void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BUILTIN_NOTIFICATION_TRANSPORT_ENV = void 0;
|
|
4
|
+
exports.parseNotificationTransports = parseNotificationTransports;
|
|
5
|
+
exports.validateBuiltinNotificationTransportEnv = validateBuiltinNotificationTransportEnv;
|
|
6
|
+
const enums_1 = require("./notifications/enums");
|
|
7
|
+
/** Built-in transports and their required endpoint environment variables. */
|
|
8
|
+
exports.BUILTIN_NOTIFICATION_TRANSPORT_ENV = {
|
|
9
|
+
[enums_1.NotificationTransports.APPSYNC_GRAPHQL]: 'APPSYNC_ENDPOINT',
|
|
10
|
+
[enums_1.NotificationTransports.APPSYNC_EVENT]: 'APPSYNC_EVENTS_ENDPOINT',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Parses NOTIFICATION_TRANSPORTS the same way as NotificationEventHandler.
|
|
14
|
+
* Defaults to appsync-graphql when unset or empty.
|
|
15
|
+
*/
|
|
16
|
+
function parseNotificationTransports(raw) {
|
|
17
|
+
const names = (raw ?? '')
|
|
18
|
+
.split(',')
|
|
19
|
+
.map((s) => s.trim())
|
|
20
|
+
.filter(Boolean);
|
|
21
|
+
return names.length > 0 ? names : [enums_1.NotificationTransports.APPSYNC_GRAPHQL];
|
|
22
|
+
}
|
|
23
|
+
function validateBuiltinNotificationTransportEnv(config) {
|
|
24
|
+
const active = parseNotificationTransports(config.NOTIFICATION_TRANSPORTS);
|
|
25
|
+
for (const name of active) {
|
|
26
|
+
const envKey = exports.BUILTIN_NOTIFICATION_TRANSPORT_ENV[name];
|
|
27
|
+
if (!envKey) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const value = config[envKey];
|
|
31
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
32
|
+
throw new Error(`Notification transport "${name}" is enabled (NOTIFICATION_TRANSPORTS) but ${envKey} is not set.`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=notification-env.validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-env.validation.js","sourceRoot":"","sources":["../src/notification-env.validation.ts"],"names":[],"mappings":";;;AAYA,kEAMC;AAED,0FAoBC;AAxCD,iDAA8D;AAE9D,6EAA6E;AAChE,QAAA,kCAAkC,GAA2B;IACxE,CAAC,8BAAsB,CAAC,eAAe,CAAC,EAAE,kBAAkB;IAC5D,CAAC,8BAAsB,CAAC,aAAa,CAAC,EAAE,yBAAyB;CAClE,CAAA;AAED;;;GAGG;AACH,SAAgB,2BAA2B,CAAC,GAAuB;IACjE,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;SACtB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAA;IAClB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,8BAAsB,CAAC,eAAe,CAAC,CAAA;AAC5E,CAAC;AAED,SAAgB,uCAAuC,CACrD,MAA+B;IAE/B,MAAM,MAAM,GAAG,2BAA2B,CACxC,MAAM,CAAC,uBAA6C,CACrD,CAAA;IAED,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,0CAAkC,CAAC,IAAI,CAAC,CAAA;QACvD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,SAAQ;QACV,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;QAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CACb,2BAA2B,IAAI,8CAA8C,MAAM,cAAc,CAClG,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ConfigService } from '@nestjs/config';
|
|
2
|
+
import { INotification } from '../interfaces';
|
|
3
|
+
import { INotificationTransport } from './interfaces';
|
|
4
|
+
export declare class AppSyncEventsService implements INotificationTransport {
|
|
5
|
+
private readonly config;
|
|
6
|
+
private readonly logger;
|
|
7
|
+
private readonly url;
|
|
8
|
+
private readonly namespace;
|
|
9
|
+
private readonly signer;
|
|
10
|
+
constructor(config: ConfigService);
|
|
11
|
+
/**
|
|
12
|
+
* Publish INotification to an AppSync Events channel via IAM SigV4.
|
|
13
|
+
*
|
|
14
|
+
* Channel structure (max 5 segments, seg 1 = namespace):
|
|
15
|
+
* /{namespace}/{tenantCode}/{action}/{sanitizedId}
|
|
16
|
+
*
|
|
17
|
+
* Client subscription options (wildcard /* catches all sub-channels):
|
|
18
|
+
* /{namespace}/{tenantCode}/* — all events for tenant
|
|
19
|
+
* /{namespace}/{tenantCode}/{action}/* — filtered by action
|
|
20
|
+
* /{namespace}/{tenantCode}/{action}/{id} — specific command
|
|
21
|
+
*
|
|
22
|
+
* Requires: Lambda execution role must have appsync:EventPublish permission.
|
|
23
|
+
*/
|
|
24
|
+
sendMessage(notification: INotification): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Resolves the most specific channel path for a notification.
|
|
27
|
+
* Non-alphanumeric characters (e.g. #, @) are sanitized to dashes
|
|
28
|
+
* since AppSync Events channel segments only allow [a-zA-Z0-9-].
|
|
29
|
+
*/
|
|
30
|
+
resolveChannel(notification: INotification): string;
|
|
31
|
+
/**
|
|
32
|
+
* Formats a string to comply with AppSync Events API channel segment rules:
|
|
33
|
+
* 1. Only alphanumeric characters and dashes.
|
|
34
|
+
* 2. Cannot start or end with a dash.
|
|
35
|
+
* 3. Maximum length of 50 characters.
|
|
36
|
+
*/
|
|
37
|
+
private sanitizeSegment;
|
|
38
|
+
private postToChannel;
|
|
39
|
+
/**
|
|
40
|
+
* Builds and signs an HttpRequest for the given channel and notification.
|
|
41
|
+
* Separating signing from the fetch call makes each step independently testable.
|
|
42
|
+
*/
|
|
43
|
+
private signRequest;
|
|
44
|
+
}
|