@flipboxlabs/aws-audit-sdk 1.1.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.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/dist/audits.d.ts +188 -0
  4. package/dist/audits.d.ts.map +1 -0
  5. package/dist/audits.js +225 -0
  6. package/dist/batch/batch-processor.d.ts +81 -0
  7. package/dist/batch/batch-processor.d.ts.map +1 -0
  8. package/dist/batch/batch-processor.js +102 -0
  9. package/dist/batch/index.d.ts +2 -0
  10. package/dist/batch/index.d.ts.map +1 -0
  11. package/dist/batch/index.js +1 -0
  12. package/dist/config.d.ts +65 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/dist/config.js +44 -0
  15. package/dist/constants.d.ts +147 -0
  16. package/dist/constants.d.ts.map +1 -0
  17. package/dist/constants.js +191 -0
  18. package/dist/events/batch-handler.d.ts +62 -0
  19. package/dist/events/batch-handler.d.ts.map +1 -0
  20. package/dist/events/batch-handler.js +92 -0
  21. package/dist/events/bus.d.ts +79 -0
  22. package/dist/events/bus.d.ts.map +1 -0
  23. package/dist/events/bus.js +86 -0
  24. package/dist/events/index.d.ts +3 -0
  25. package/dist/events/index.d.ts.map +1 -0
  26. package/dist/events/index.js +2 -0
  27. package/dist/index.d.ts +9 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +8 -0
  30. package/dist/middleware/middy.d.ts +66 -0
  31. package/dist/middleware/middy.d.ts.map +1 -0
  32. package/dist/middleware/middy.js +105 -0
  33. package/dist/repository.d.ts +421 -0
  34. package/dist/repository.d.ts.map +1 -0
  35. package/dist/repository.js +486 -0
  36. package/dist/repository.utils.d.ts +37 -0
  37. package/dist/repository.utils.d.ts.map +1 -0
  38. package/dist/repository.utils.js +70 -0
  39. package/dist/schema/audit.d.ts +202 -0
  40. package/dist/schema/audit.d.ts.map +1 -0
  41. package/dist/schema/audit.js +48 -0
  42. package/dist/schema/common.d.ts +128 -0
  43. package/dist/schema/common.d.ts.map +1 -0
  44. package/dist/schema/common.js +148 -0
  45. package/dist/schema/index.d.ts +27 -0
  46. package/dist/schema/index.d.ts.map +1 -0
  47. package/dist/schema/index.js +26 -0
  48. package/dist/schema/log.d.ts +211 -0
  49. package/dist/schema/log.d.ts.map +1 -0
  50. package/dist/schema/log.js +179 -0
  51. package/dist/schema/model.d.ts +110 -0
  52. package/dist/schema/model.d.ts.map +1 -0
  53. package/dist/schema/model.js +86 -0
  54. package/dist/schema/service.d.ts +189 -0
  55. package/dist/schema/service.d.ts.map +1 -0
  56. package/dist/schema/service.js +89 -0
  57. package/dist/schema/storage.d.ts +105 -0
  58. package/dist/schema/storage.d.ts.map +1 -0
  59. package/dist/schema/storage.js +63 -0
  60. package/dist/service.d.ts +285 -0
  61. package/dist/service.d.ts.map +1 -0
  62. package/dist/service.js +237 -0
  63. package/dist/test-config.d.ts +56 -0
  64. package/dist/test-config.d.ts.map +1 -0
  65. package/dist/test-config.js +24 -0
  66. package/dist/types.d.ts +40 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +1 -0
  69. package/dist/utils.d.ts +231 -0
  70. package/dist/utils.d.ts.map +1 -0
  71. package/dist/utils.js +313 -0
  72. package/package.json +85 -0
@@ -0,0 +1,65 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Input configuration for defining audit apps and resource types.
4
+ */
5
+ export interface AuditConfigInput {
6
+ readonly apps: readonly string[];
7
+ readonly resourceTypes: readonly string[];
8
+ readonly service?: string;
9
+ }
10
+ /**
11
+ * Creates an audit configuration object with typed schemas.
12
+ *
13
+ * The returned config object contains:
14
+ * - `service`: The service version (defaults to "v1")
15
+ * - `schemas.app`: Zod schema for validating app values
16
+ * - `schemas.resourceType`: Zod schema for validating resource type values
17
+ * - `schemas.resourceReference`: Zod schema for validating resource references
18
+ * - `_types`: Type helpers for extracting App and ResourceType union types
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const config = defineAuditConfig({
23
+ * apps: ['Orders', 'Inventory'] as const,
24
+ * resourceTypes: ['Order', 'Product'] as const,
25
+ * });
26
+ *
27
+ * // Extract types for use in application code
28
+ * type App = typeof config._types.App; // 'Orders' | 'Inventory'
29
+ * type ResourceType = typeof config._types.ResourceType; // 'Order' | 'Product'
30
+ *
31
+ * // Use schemas for validation
32
+ * config.schemas.app.parse('Orders'); // ✅
33
+ * config.schemas.app.parse('Invalid'); // ❌ throws
34
+ * ```
35
+ */
36
+ export declare function defineAuditConfig<const C extends AuditConfigInput>(input: C): {
37
+ service: string | undefined;
38
+ } & C & {
39
+ schemas: {
40
+ app: z.ZodEnum<{
41
+ [x: string]: string;
42
+ }>;
43
+ resourceType: z.ZodEnum<{
44
+ [x: string]: string;
45
+ }>;
46
+ resourceReference: z.ZodObject<{
47
+ app: z.ZodEnum<{
48
+ [x: string]: string;
49
+ }>;
50
+ type: z.ZodEnum<{
51
+ [x: string]: string;
52
+ }>;
53
+ id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
54
+ }, z.core.$strip>;
55
+ };
56
+ _types: {
57
+ App: C["apps"][number];
58
+ ResourceType: C["resourceTypes"][number];
59
+ };
60
+ };
61
+ /**
62
+ * Type representing the return value of defineAuditConfig.
63
+ */
64
+ export type AuditConfig = ReturnType<typeof defineAuditConfig>;
65
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,CAAC,SAAS,gBAAgB,EAAE,KAAK,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;YAkB5D;QACb,GAAG,oBAAM;QACT,YAAY,6BAAe;KAC3B;EAEF;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Creates an audit configuration object with typed schemas.
4
+ *
5
+ * The returned config object contains:
6
+ * - `service`: The service version (defaults to "v1")
7
+ * - `schemas.app`: Zod schema for validating app values
8
+ * - `schemas.resourceType`: Zod schema for validating resource type values
9
+ * - `schemas.resourceReference`: Zod schema for validating resource references
10
+ * - `_types`: Type helpers for extracting App and ResourceType union types
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const config = defineAuditConfig({
15
+ * apps: ['Orders', 'Inventory'] as const,
16
+ * resourceTypes: ['Order', 'Product'] as const,
17
+ * });
18
+ *
19
+ * // Extract types for use in application code
20
+ * type App = typeof config._types.App; // 'Orders' | 'Inventory'
21
+ * type ResourceType = typeof config._types.ResourceType; // 'Order' | 'Product'
22
+ *
23
+ * // Use schemas for validation
24
+ * config.schemas.app.parse('Orders'); // ✅
25
+ * config.schemas.app.parse('Invalid'); // ❌ throws
26
+ * ```
27
+ */
28
+ export function defineAuditConfig(input) {
29
+ const schemas = {
30
+ app: z.enum(input.apps),
31
+ resourceType: z.enum(input.resourceTypes),
32
+ resourceReference: z.object({
33
+ app: z.enum(input.apps),
34
+ type: z.enum(input.resourceTypes),
35
+ id: z.union([z.string(), z.number()]).optional(),
36
+ }),
37
+ };
38
+ return {
39
+ service: process.env.SERVICE,
40
+ ...input,
41
+ schemas,
42
+ _types: {},
43
+ };
44
+ }
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Identifier key used in CloudWatch structured logs to mark audit entries.
3
+ *
4
+ * When this key is present in a log object, it signals to log processors
5
+ * that the entry is an audit record that should be captured and stored.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const logEntry = {
10
+ * [AUDIT_LOG_IDENTIFIER]: true,
11
+ * operation: 'createUser',
12
+ * // ...audit data
13
+ * };
14
+ * ```
15
+ */
16
+ export declare const AUDIT_LOG_IDENTIFIER = "_audit";
17
+ /**
18
+ * SDK version string for debugging and compatibility checks.
19
+ */
20
+ export declare const SDK_VERSION = "1.0.0";
21
+ /**
22
+ * Configuration for generating resource names.
23
+ */
24
+ type NameConfig = {
25
+ /** Environment name (e.g., 'dev', 'staging', 'prod') */
26
+ env: string;
27
+ /** Service name used in naming resources */
28
+ service?: string;
29
+ };
30
+ /**
31
+ * Configuration for generating AWS resource ARNs.
32
+ * Extends NameConfig with AWS-specific identifiers.
33
+ */
34
+ type ARNConfig = NameConfig & {
35
+ /** AWS account and region information */
36
+ aws: {
37
+ /** AWS region (e.g., 'us-east-1') */
38
+ region: string;
39
+ /** AWS account ID */
40
+ account: string;
41
+ };
42
+ };
43
+ /**
44
+ * DynamoDB configuration constants for the audit table.
45
+ *
46
+ * Provides table naming, key definitions, index names, and attribute constants
47
+ * used throughout the audit SDK for DynamoDB operations.
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * // Get table name for production
52
+ * const tableName = DynamoDB.Table.Name({ env: 'prod' });
53
+ * // Returns: "PROD-v1-Audit"
54
+ *
55
+ * // Access key names
56
+ * const pk = DynamoDB.Keys.PARTITION_KEY; // "PK"
57
+ * const sk = DynamoDB.Keys.SORT_KEY; // "SK"
58
+ * ```
59
+ */
60
+ export declare const DynamoDB: {
61
+ /** Table name and ARN generators */
62
+ readonly Table: {
63
+ /** Generates the DynamoDB table name based on environment */
64
+ readonly Name: (config?: NameConfig) => string;
65
+ /** Generates the full DynamoDB table ARN */
66
+ readonly ARN: (config?: ARNConfig) => string;
67
+ };
68
+ /** DynamoDB key attribute names */
69
+ readonly Keys: {
70
+ /** Primary partition key */
71
+ readonly PARTITION_KEY: "PK";
72
+ /** Primary sort key */
73
+ readonly SORT_KEY: "SK";
74
+ /** GSI1 (String-String) partition key */
75
+ readonly GSI1_SS_PARTITION_KEY: "GSI1_SS_PK";
76
+ /** GSI1 (String-String) sort key */
77
+ readonly GSI1_SS_SORT_KEY: "GSI1_SS_SK";
78
+ /** GSI1 (String-Number) partition key */
79
+ readonly GSI1_SN_PARTITION_KEY: "GSI1_SN_PK";
80
+ /** GSI1 (String-Number) sort key */
81
+ readonly GSI1_SN_SORT_KEY: "GSI1_SN_SK";
82
+ /** LSI1 (String) sort key */
83
+ readonly LSI1_S_SORT_KEY: "LSI1_S_SK";
84
+ /** LSI1 (Numeric) sort key */
85
+ readonly LSI1_N_SORT_KEY: "LSI1_N_SK";
86
+ };
87
+ /** Secondary index names */
88
+ readonly Indexes: {
89
+ /** Global Secondary Index 1 - String partition, String sort */
90
+ readonly GSI1_SS: "GSI1_SS";
91
+ /** Global Secondary Index 1 - String partition, Numeric sort */
92
+ readonly GSI1_SN: "GSI1_SN";
93
+ /** Local Secondary Index 1 - String sort key */
94
+ readonly LSI1_S: "LSI1_S";
95
+ /** Local Secondary Index 1 - Numeric sort key */
96
+ readonly LSI1_N: "LSI1_N";
97
+ };
98
+ /** Special attribute names */
99
+ readonly Attributes: {
100
+ /** Time-to-live attribute for automatic item expiration */
101
+ readonly TTL: "ttl";
102
+ };
103
+ };
104
+ /**
105
+ * EventBridge configuration constants for the audit event bus.
106
+ *
107
+ * Provides bus naming, event source identifiers, and detail type constants
108
+ * used for publishing audit events to EventBridge.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // Get event bus name
113
+ * const busName = EventBridge.Bus.Name({ env: 'prod' });
114
+ * // Returns: "PROD-v1-Audit"
115
+ *
116
+ * // Use event types
117
+ * const event = {
118
+ * Source: EventBridge.Source,
119
+ * DetailType: EventBridge.DetailType.UPSERTED,
120
+ * Detail: JSON.stringify(auditData),
121
+ * };
122
+ * ```
123
+ */
124
+ export declare const EventBridge: {
125
+ /** Event bus name and ARN generators */
126
+ readonly Bus: {
127
+ /** Generates the EventBridge bus name based on environment */
128
+ readonly Name: (config?: NameConfig) => string;
129
+ /** Generates the full EventBridge bus ARN */
130
+ readonly ARN: (config?: ARNConfig) => string;
131
+ };
132
+ /** Source identifier for audit events */
133
+ readonly Source: "Audit";
134
+ /** Event detail types for different audit operations */
135
+ readonly DetailType: {
136
+ /** Emitted when an audit record is created or updated */
137
+ readonly UPSERTED: "Upserted";
138
+ /** Emitted when an audit record is deleted */
139
+ readonly DELETED: "Deleted";
140
+ };
141
+ };
142
+ /**
143
+ * Union type of all valid EventBridge detail types.
144
+ */
145
+ export type AnyEventBridgeDetailType = (typeof EventBridge.DetailType)[keyof typeof EventBridge.DetailType];
146
+ export {};
147
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC;;GAEG;AACH,KAAK,UAAU,GAAG;IACjB,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IAEZ,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,KAAK,SAAS,GAAG,UAAU,GAAG;IAC7B,yCAAyC;IACzC,GAAG,EAAE;QACJ,qCAAqC;QACrC,MAAM,EAAE,MAAM,CAAC;QACf,qBAAqB;QACrB,OAAO,EAAE,MAAM,CAAC;KAChB,CAAC;CACF,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,QAAQ;IACpB,oCAAoC;;QAEnC,6DAA6D;iCAC7C,UAAU;QAC1B,4CAA4C;gCAC7B,SAAS;;IAEzB,mCAAmC;;QAElC,4BAA4B;;QAE5B,uBAAuB;;QAGvB,yCAAyC;;QAEzC,oCAAoC;;QAGpC,yCAAyC;;QAEzC,oCAAoC;;QAGpC,6BAA6B;;QAE7B,8BAA8B;;;IAG/B,4BAA4B;;QAE3B,+DAA+D;;QAE/D,gEAAgE;;QAGhE,gDAAgD;;QAEhD,iDAAiD;;;IAGlD,8BAA8B;;QAE7B,2DAA2D;;;CAGnD,CAAC;AA4CX;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW;IACvB,wCAAwC;;QAEvC,8DAA8D;iCAC9C,UAAU;QAC1B,6CAA6C;gCAC9B,SAAS;;IAEzB,yCAAyC;;IAEzC,wDAAwD;;QAEvD,yDAAyD;;QAEzD,8CAA8C;;;CAGtC,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,wBAAwB,GACnC,CAAC,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Identifier key used in CloudWatch structured logs to mark audit entries.
3
+ *
4
+ * When this key is present in a log object, it signals to log processors
5
+ * that the entry is an audit record that should be captured and stored.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const logEntry = {
10
+ * [AUDIT_LOG_IDENTIFIER]: true,
11
+ * operation: 'createUser',
12
+ * // ...audit data
13
+ * };
14
+ * ```
15
+ */
16
+ export const AUDIT_LOG_IDENTIFIER = "_audit";
17
+ /**
18
+ * SDK version string for debugging and compatibility checks.
19
+ */
20
+ export const SDK_VERSION = "1.0.0";
21
+ /**
22
+ * DynamoDB configuration constants for the audit table.
23
+ *
24
+ * Provides table naming, key definitions, index names, and attribute constants
25
+ * used throughout the audit SDK for DynamoDB operations.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * // Get table name for production
30
+ * const tableName = DynamoDB.Table.Name({ env: 'prod' });
31
+ * // Returns: "PROD-v1-Audit"
32
+ *
33
+ * // Access key names
34
+ * const pk = DynamoDB.Keys.PARTITION_KEY; // "PK"
35
+ * const sk = DynamoDB.Keys.SORT_KEY; // "SK"
36
+ * ```
37
+ */
38
+ export const DynamoDB = {
39
+ /** Table name and ARN generators */
40
+ Table: {
41
+ /** Generates the DynamoDB table name based on environment */
42
+ Name: (config) => buildDynamoDBName(config),
43
+ /** Generates the full DynamoDB table ARN */
44
+ ARN: (config) => buildDynamoDBArn(config),
45
+ },
46
+ /** DynamoDB key attribute names */
47
+ Keys: {
48
+ /** Primary partition key */
49
+ PARTITION_KEY: "PK",
50
+ /** Primary sort key */
51
+ SORT_KEY: "SK",
52
+ /** GSI1 (String-String) partition key */
53
+ GSI1_SS_PARTITION_KEY: "GSI1_SS_PK",
54
+ /** GSI1 (String-String) sort key */
55
+ GSI1_SS_SORT_KEY: "GSI1_SS_SK",
56
+ /** GSI1 (String-Number) partition key */
57
+ GSI1_SN_PARTITION_KEY: "GSI1_SN_PK",
58
+ /** GSI1 (String-Number) sort key */
59
+ GSI1_SN_SORT_KEY: "GSI1_SN_SK",
60
+ /** LSI1 (String) sort key */
61
+ LSI1_S_SORT_KEY: "LSI1_S_SK",
62
+ /** LSI1 (Numeric) sort key */
63
+ LSI1_N_SORT_KEY: "LSI1_N_SK",
64
+ },
65
+ /** Secondary index names */
66
+ Indexes: {
67
+ /** Global Secondary Index 1 - String partition, String sort */
68
+ GSI1_SS: "GSI1_SS",
69
+ /** Global Secondary Index 1 - String partition, Numeric sort */
70
+ GSI1_SN: "GSI1_SN",
71
+ /** Local Secondary Index 1 - String sort key */
72
+ LSI1_S: "LSI1_S",
73
+ /** Local Secondary Index 1 - Numeric sort key */
74
+ LSI1_N: "LSI1_N",
75
+ },
76
+ /** Special attribute names */
77
+ Attributes: {
78
+ /** Time-to-live attribute for automatic item expiration */
79
+ TTL: "ttl",
80
+ },
81
+ };
82
+ /**
83
+ * Builds a DynamoDB table name from service name and configuration.
84
+ *
85
+ * Format: `{ENV}-{service}-Audit` (e.g., "PROD-v1-Audit")
86
+ *
87
+ * @param name - Service name to include in table name
88
+ * @param config - Environment configuration (defaults to process.env.ENVIRONMENT)
89
+ * @returns Formatted table name string
90
+ * @internal
91
+ */
92
+ function buildDynamoDBName(config = {
93
+ env: String(process.env.ENVIRONMENT),
94
+ service: process.env.SERVICE,
95
+ }) {
96
+ return [`${config.env.toUpperCase()}`, config.service, "Audit"]
97
+ .filter(Boolean)
98
+ .join("-");
99
+ }
100
+ /**
101
+ * Builds a DynamoDB table ARN from service name and AWS configuration.
102
+ *
103
+ * @param name - Service name to include in table name
104
+ * @param config - AWS and environment configuration
105
+ * @returns Full DynamoDB table ARN
106
+ * @internal
107
+ */
108
+ function buildDynamoDBArn(config = {
109
+ aws: {
110
+ region: String(process.env.AWS_REGION),
111
+ account: String(process.env.AWS_ACCOUNT),
112
+ },
113
+ env: String(process.env.ENVIRONMENT),
114
+ service: process.env.SERVICE,
115
+ }) {
116
+ return `arn:aws:dynamodb:${config.aws.region}:${config.aws.account}:table/${buildDynamoDBName({ env: config.env, service: config.service })}`;
117
+ }
118
+ /**
119
+ * EventBridge configuration constants for the audit event bus.
120
+ *
121
+ * Provides bus naming, event source identifiers, and detail type constants
122
+ * used for publishing audit events to EventBridge.
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * // Get event bus name
127
+ * const busName = EventBridge.Bus.Name({ env: 'prod' });
128
+ * // Returns: "PROD-v1-Audit"
129
+ *
130
+ * // Use event types
131
+ * const event = {
132
+ * Source: EventBridge.Source,
133
+ * DetailType: EventBridge.DetailType.UPSERTED,
134
+ * Detail: JSON.stringify(auditData),
135
+ * };
136
+ * ```
137
+ */
138
+ export const EventBridge = {
139
+ /** Event bus name and ARN generators */
140
+ Bus: {
141
+ /** Generates the EventBridge bus name based on environment */
142
+ Name: (config) => buildEventBridgeName(config),
143
+ /** Generates the full EventBridge bus ARN */
144
+ ARN: (config) => buildEventBridgeArn(config),
145
+ },
146
+ /** Source identifier for audit events */
147
+ Source: "Audit",
148
+ /** Event detail types for different audit operations */
149
+ DetailType: {
150
+ /** Emitted when an audit record is created or updated */
151
+ UPSERTED: "Upserted",
152
+ /** Emitted when an audit record is deleted */
153
+ DELETED: "Deleted",
154
+ },
155
+ };
156
+ /**
157
+ * Builds an EventBridge bus name from service name and configuration.
158
+ *
159
+ * Format: `{ENV}-{service}-Audit` (e.g., "PROD-v1-Audit")
160
+ *
161
+ * @param name - Service name to include in bus name
162
+ * @param config - Environment configuration (defaults to process.env.ENVIRONMENT)
163
+ * @returns Formatted bus name string
164
+ * @internal
165
+ */
166
+ function buildEventBridgeName(config = {
167
+ env: String(process.env.ENVIRONMENT),
168
+ service: process.env.SERVICE,
169
+ }) {
170
+ return [`${config.env.toUpperCase()}`, config.service, "Audit"]
171
+ .filter(Boolean)
172
+ .join("-");
173
+ }
174
+ /**
175
+ * Builds an EventBridge bus ARN from service name and AWS configuration.
176
+ *
177
+ * @param name - Service name to include in bus name
178
+ * @param config - AWS and environment configuration
179
+ * @returns Full EventBridge bus ARN
180
+ * @internal
181
+ */
182
+ function buildEventBridgeArn(config = {
183
+ aws: {
184
+ region: process.env.AWS_REGION ?? "us-east-1",
185
+ account: String(process.env.AWS_ACCOUNT),
186
+ },
187
+ env: String(process.env.ENVIRONMENT),
188
+ service: process.env.SERVICE,
189
+ }) {
190
+ return `arn:aws:events:${config.aws.region}:${config.aws.account}:event-bus/${buildEventBridgeName({ env: config.env, service: config.service })}`;
191
+ }
@@ -0,0 +1,62 @@
1
+ import type { Logger } from "@aws-lambda-powertools/logger";
2
+ import { type EventBridgeClient, type PutEventsRequestEntry, type PutEventsResultEntry } from "@aws-sdk/client-eventbridge";
3
+ /**
4
+ * Handles batched EventBridge event publishing with automatic chunking.
5
+ *
6
+ * Provides a wrapper around the EventBridge PutEvents API that automatically
7
+ * splits large event arrays into compliant batch sizes and handles errors gracefully.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const handler = new BatchHandler(logger, eventBridgeClient);
12
+ *
13
+ * const results = await handler.putEvents([
14
+ * { DetailType: 'OrderCreated', Detail: '{"orderId":"123"}', Source: 'orders' },
15
+ * { DetailType: 'OrderCreated', Detail: '{"orderId":"456"}', Source: 'orders' },
16
+ * ]);
17
+ * ```
18
+ */
19
+ export declare class BatchHandler {
20
+ private readonly logger;
21
+ private readonly client;
22
+ /**
23
+ * Creates a new BatchHandler instance.
24
+ *
25
+ * @param logger - Logger instance for debug and error logging
26
+ * @param client - EventBridge client for API calls
27
+ */
28
+ constructor(logger: Logger, client: EventBridgeClient);
29
+ /**
30
+ * Publishes events to EventBridge with automatic batching and error handling.
31
+ *
32
+ * Events are automatically chunked into batches of the specified size
33
+ * (default 10, the EventBridge maximum). On success, logs the results
34
+ * at debug level. On failure, logs at critical level and returns an empty array.
35
+ *
36
+ * @param entries - Array of EventBridge event entries to publish
37
+ * @param chunk - Batch size for chunking (default: 10)
38
+ * @returns Array of result entries from EventBridge, or empty array on error
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const results = await handler.putEvents(events);
43
+ * console.log(`Published ${results.length} events`);
44
+ * ```
45
+ */
46
+ putEvents(entries: PutEventsRequestEntry[], chunk?: number): Promise<PutEventsResultEntry[]>;
47
+ /**
48
+ * Sends events to EventBridge in batches.
49
+ *
50
+ * Iterates through the entries array in chunks, sending each batch
51
+ * via the PutEvents API and collecting the results.
52
+ *
53
+ * @param client - EventBridge client for API calls
54
+ * @param entries - Array of event entries to send
55
+ * @param chunk - Number of entries per batch
56
+ * @returns Combined array of result entries from all batches
57
+ *
58
+ * @internal
59
+ */
60
+ private sendEventsViaBatch;
61
+ }
62
+ //# sourceMappingURL=batch-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-handler.d.ts","sourceRoot":"","sources":["../../src/events/batch-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EACN,KAAK,iBAAiB,EAEtB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,MAAM,6BAA6B,CAAC;AAQrC;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,YAAY;IAQvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IARxB;;;;;OAKG;gBAEe,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,iBAAiB;IAG3C;;;;;;;;;;;;;;;;OAgBG;IACU,SAAS,CACrB,OAAO,EAAE,qBAAqB,EAAE,EAChC,KAAK,GAAE,MAAmB,GACxB,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAgBlC;;;;;;;;;;;;OAYG;YACW,kBAAkB;CAsBhC"}
@@ -0,0 +1,92 @@
1
+ import { PutEventsCommand, } from "@aws-sdk/client-eventbridge";
2
+ /**
3
+ * Default batch size for EventBridge PutEvents API calls.
4
+ * EventBridge allows a maximum of 10 entries per PutEvents call.
5
+ */
6
+ const CHUNK_SIZE = 10;
7
+ /**
8
+ * Handles batched EventBridge event publishing with automatic chunking.
9
+ *
10
+ * Provides a wrapper around the EventBridge PutEvents API that automatically
11
+ * splits large event arrays into compliant batch sizes and handles errors gracefully.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const handler = new BatchHandler(logger, eventBridgeClient);
16
+ *
17
+ * const results = await handler.putEvents([
18
+ * { DetailType: 'OrderCreated', Detail: '{"orderId":"123"}', Source: 'orders' },
19
+ * { DetailType: 'OrderCreated', Detail: '{"orderId":"456"}', Source: 'orders' },
20
+ * ]);
21
+ * ```
22
+ */
23
+ export class BatchHandler {
24
+ logger;
25
+ client;
26
+ /**
27
+ * Creates a new BatchHandler instance.
28
+ *
29
+ * @param logger - Logger instance for debug and error logging
30
+ * @param client - EventBridge client for API calls
31
+ */
32
+ constructor(logger, client) {
33
+ this.logger = logger;
34
+ this.client = client;
35
+ }
36
+ /**
37
+ * Publishes events to EventBridge with automatic batching and error handling.
38
+ *
39
+ * Events are automatically chunked into batches of the specified size
40
+ * (default 10, the EventBridge maximum). On success, logs the results
41
+ * at debug level. On failure, logs at critical level and returns an empty array.
42
+ *
43
+ * @param entries - Array of EventBridge event entries to publish
44
+ * @param chunk - Batch size for chunking (default: 10)
45
+ * @returns Array of result entries from EventBridge, or empty array on error
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const results = await handler.putEvents(events);
50
+ * console.log(`Published ${results.length} events`);
51
+ * ```
52
+ */
53
+ async putEvents(entries, chunk = CHUNK_SIZE) {
54
+ try {
55
+ const result = await this.sendEventsViaBatch(this.client, entries, chunk);
56
+ this.logger.debug("Pushed event bridge events", {
57
+ events: result,
58
+ });
59
+ return result;
60
+ }
61
+ catch (error) {
62
+ this.logger.critical("Error pushing event bridge events", error);
63
+ }
64
+ return [];
65
+ }
66
+ /**
67
+ * Sends events to EventBridge in batches.
68
+ *
69
+ * Iterates through the entries array in chunks, sending each batch
70
+ * via the PutEvents API and collecting the results.
71
+ *
72
+ * @param client - EventBridge client for API calls
73
+ * @param entries - Array of event entries to send
74
+ * @param chunk - Number of entries per batch
75
+ * @returns Combined array of result entries from all batches
76
+ *
77
+ * @internal
78
+ */
79
+ async sendEventsViaBatch(client, entries, chunk = CHUNK_SIZE) {
80
+ const result = [];
81
+ // Chunk into batches
82
+ for (let i = 0, j = entries.length; i < j; i += chunk) {
83
+ const output = await client.send(new PutEventsCommand({
84
+ Entries: entries.slice(i, i + chunk),
85
+ }));
86
+ if (output.Entries) {
87
+ result.concat(output.Entries);
88
+ }
89
+ }
90
+ return result;
91
+ }
92
+ }