@arcraz/common 1.0.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 (174) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +373 -0
  3. package/dist/aws/bedrock/client-factory.d.ts +45 -0
  4. package/dist/aws/bedrock/client-factory.d.ts.map +1 -0
  5. package/dist/aws/bedrock/client-factory.js +113 -0
  6. package/dist/aws/bedrock/index.d.ts +3 -0
  7. package/dist/aws/bedrock/index.d.ts.map +1 -0
  8. package/dist/aws/bedrock/index.js +1 -0
  9. package/dist/aws/bedrock/types.d.ts +95 -0
  10. package/dist/aws/bedrock/types.d.ts.map +1 -0
  11. package/dist/aws/bedrock/types.js +1 -0
  12. package/dist/aws/cloudfront/index.d.ts +3 -0
  13. package/dist/aws/cloudfront/index.d.ts.map +1 -0
  14. package/dist/aws/cloudfront/index.js +1 -0
  15. package/dist/aws/cloudfront/signer-factory.d.ts +36 -0
  16. package/dist/aws/cloudfront/signer-factory.d.ts.map +1 -0
  17. package/dist/aws/cloudfront/signer-factory.js +75 -0
  18. package/dist/aws/cloudfront/types.d.ts +52 -0
  19. package/dist/aws/cloudfront/types.d.ts.map +1 -0
  20. package/dist/aws/cloudfront/types.js +1 -0
  21. package/dist/aws/s3/client-factory.d.ts +13 -0
  22. package/dist/aws/s3/client-factory.d.ts.map +1 -0
  23. package/dist/aws/s3/client-factory.js +25 -0
  24. package/dist/aws/s3/index.d.ts +4 -0
  25. package/dist/aws/s3/index.d.ts.map +1 -0
  26. package/dist/aws/s3/index.js +2 -0
  27. package/dist/aws/s3/operations.d.ts +106 -0
  28. package/dist/aws/s3/operations.d.ts.map +1 -0
  29. package/dist/aws/s3/operations.js +234 -0
  30. package/dist/aws/s3/types.d.ts +88 -0
  31. package/dist/aws/s3/types.d.ts.map +1 -0
  32. package/dist/aws/s3/types.js +1 -0
  33. package/dist/caches/api-cache.d.ts +40 -0
  34. package/dist/caches/api-cache.d.ts.map +1 -0
  35. package/dist/caches/api-cache.js +65 -0
  36. package/dist/caches/database-cache.d.ts +40 -0
  37. package/dist/caches/database-cache.d.ts.map +1 -0
  38. package/dist/caches/database-cache.js +65 -0
  39. package/dist/caches/index.d.ts +3 -0
  40. package/dist/caches/index.d.ts.map +1 -0
  41. package/dist/caches/index.js +2 -0
  42. package/dist/config/env-loader.d.ts +28 -0
  43. package/dist/config/env-loader.d.ts.map +1 -0
  44. package/dist/config/env-loader.js +39 -0
  45. package/dist/config/index.d.ts +5 -0
  46. package/dist/config/index.d.ts.map +1 -0
  47. package/dist/config/index.js +2 -0
  48. package/dist/config/schemas.d.ts +193 -0
  49. package/dist/config/schemas.d.ts.map +1 -0
  50. package/dist/config/schemas.js +92 -0
  51. package/dist/config/types.d.ts +23 -0
  52. package/dist/config/types.d.ts.map +1 -0
  53. package/dist/config/types.js +2 -0
  54. package/dist/constants/cache-durations.d.ts +29 -0
  55. package/dist/constants/cache-durations.d.ts.map +1 -0
  56. package/dist/constants/cache-durations.js +27 -0
  57. package/dist/constants/defaults.d.ts +50 -0
  58. package/dist/constants/defaults.d.ts.map +1 -0
  59. package/dist/constants/defaults.js +49 -0
  60. package/dist/constants/index.d.ts +4 -0
  61. package/dist/constants/index.d.ts.map +1 -0
  62. package/dist/constants/index.js +2 -0
  63. package/dist/database/base-repository.d.ts +45 -0
  64. package/dist/database/base-repository.d.ts.map +1 -0
  65. package/dist/database/base-repository.js +57 -0
  66. package/dist/database/helpers/converter-helper.d.ts +9 -0
  67. package/dist/database/helpers/converter-helper.d.ts.map +1 -0
  68. package/dist/database/helpers/converter-helper.js +20 -0
  69. package/dist/database/helpers/index.d.ts +3 -0
  70. package/dist/database/helpers/index.d.ts.map +1 -0
  71. package/dist/database/helpers/index.js +2 -0
  72. package/dist/database/helpers/paged-response-helper.d.ts +33 -0
  73. package/dist/database/helpers/paged-response-helper.d.ts.map +1 -0
  74. package/dist/database/helpers/paged-response-helper.js +64 -0
  75. package/dist/database/index.d.ts +6 -0
  76. package/dist/database/index.d.ts.map +1 -0
  77. package/dist/database/index.js +4 -0
  78. package/dist/database/pool-factory.d.ts +24 -0
  79. package/dist/database/pool-factory.d.ts.map +1 -0
  80. package/dist/database/pool-factory.js +91 -0
  81. package/dist/database/query-helpers.d.ts +36 -0
  82. package/dist/database/query-helpers.d.ts.map +1 -0
  83. package/dist/database/query-helpers.js +68 -0
  84. package/dist/database/types.d.ts +55 -0
  85. package/dist/database/types.d.ts.map +1 -0
  86. package/dist/database/types.js +1 -0
  87. package/dist/helpers/data-obscurer.d.ts +18 -0
  88. package/dist/helpers/data-obscurer.d.ts.map +1 -0
  89. package/dist/helpers/data-obscurer.js +29 -0
  90. package/dist/helpers/enum-converters.d.ts +27 -0
  91. package/dist/helpers/enum-converters.d.ts.map +1 -0
  92. package/dist/helpers/enum-converters.js +37 -0
  93. package/dist/helpers/index.d.ts +5 -0
  94. package/dist/helpers/index.d.ts.map +1 -0
  95. package/dist/helpers/index.js +3 -0
  96. package/dist/helpers/remove-sensitive-values.d.ts +20 -0
  97. package/dist/helpers/remove-sensitive-values.d.ts.map +1 -0
  98. package/dist/helpers/remove-sensitive-values.js +72 -0
  99. package/dist/index.d.ts +11 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +20 -0
  102. package/dist/logging/formatters.d.ts +19 -0
  103. package/dist/logging/formatters.d.ts.map +1 -0
  104. package/dist/logging/formatters.js +94 -0
  105. package/dist/logging/index.d.ts +4 -0
  106. package/dist/logging/index.d.ts.map +1 -0
  107. package/dist/logging/index.js +2 -0
  108. package/dist/logging/logger-factory.d.ts +8 -0
  109. package/dist/logging/logger-factory.d.ts.map +1 -0
  110. package/dist/logging/logger-factory.js +86 -0
  111. package/dist/logging/types.d.ts +52 -0
  112. package/dist/logging/types.d.ts.map +1 -0
  113. package/dist/logging/types.js +1 -0
  114. package/dist/rabbitmq/connection-factory.d.ts +8 -0
  115. package/dist/rabbitmq/connection-factory.d.ts.map +1 -0
  116. package/dist/rabbitmq/connection-factory.js +117 -0
  117. package/dist/rabbitmq/consumer.d.ts +44 -0
  118. package/dist/rabbitmq/consumer.d.ts.map +1 -0
  119. package/dist/rabbitmq/consumer.js +107 -0
  120. package/dist/rabbitmq/index.d.ts +6 -0
  121. package/dist/rabbitmq/index.d.ts.map +1 -0
  122. package/dist/rabbitmq/index.js +4 -0
  123. package/dist/rabbitmq/namespace-helpers.d.ts +33 -0
  124. package/dist/rabbitmq/namespace-helpers.d.ts.map +1 -0
  125. package/dist/rabbitmq/namespace-helpers.js +44 -0
  126. package/dist/rabbitmq/publisher.d.ts +27 -0
  127. package/dist/rabbitmq/publisher.d.ts.map +1 -0
  128. package/dist/rabbitmq/publisher.js +94 -0
  129. package/dist/rabbitmq/types.d.ts +94 -0
  130. package/dist/rabbitmq/types.d.ts.map +1 -0
  131. package/dist/rabbitmq/types.js +1 -0
  132. package/dist/redis/client-factory.d.ts +14 -0
  133. package/dist/redis/client-factory.d.ts.map +1 -0
  134. package/dist/redis/client-factory.js +98 -0
  135. package/dist/redis/index.d.ts +6 -0
  136. package/dist/redis/index.d.ts.map +1 -0
  137. package/dist/redis/index.js +4 -0
  138. package/dist/redis/namespace-helpers.d.ts +33 -0
  139. package/dist/redis/namespace-helpers.d.ts.map +1 -0
  140. package/dist/redis/namespace-helpers.js +43 -0
  141. package/dist/redis/operations/index.d.ts +3 -0
  142. package/dist/redis/operations/index.d.ts.map +1 -0
  143. package/dist/redis/operations/index.js +2 -0
  144. package/dist/redis/operations/list.d.ts +102 -0
  145. package/dist/redis/operations/list.d.ts.map +1 -0
  146. package/dist/redis/operations/list.js +136 -0
  147. package/dist/redis/operations/standard.d.ts +85 -0
  148. package/dist/redis/operations/standard.d.ts.map +1 -0
  149. package/dist/redis/operations/standard.js +136 -0
  150. package/dist/redis/types.d.ts +81 -0
  151. package/dist/redis/types.d.ts.map +1 -0
  152. package/dist/redis/types.js +8 -0
  153. package/dist/security/cors-factory.d.ts +28 -0
  154. package/dist/security/cors-factory.d.ts.map +1 -0
  155. package/dist/security/cors-factory.js +73 -0
  156. package/dist/security/helmet-factory.d.ts +14 -0
  157. package/dist/security/helmet-factory.d.ts.map +1 -0
  158. package/dist/security/helmet-factory.js +80 -0
  159. package/dist/security/index.d.ts +4 -0
  160. package/dist/security/index.d.ts.map +1 -0
  161. package/dist/security/index.js +2 -0
  162. package/dist/security/types.d.ts +103 -0
  163. package/dist/security/types.d.ts.map +1 -0
  164. package/dist/security/types.js +1 -0
  165. package/dist/types/custom-types.d.ts +102 -0
  166. package/dist/types/custom-types.d.ts.map +1 -0
  167. package/dist/types/custom-types.js +45 -0
  168. package/dist/types/enums.d.ts +26 -0
  169. package/dist/types/enums.d.ts.map +1 -0
  170. package/dist/types/enums.js +30 -0
  171. package/dist/types/index.d.ts +4 -0
  172. package/dist/types/index.d.ts.map +1 -0
  173. package/dist/types/index.js +2 -0
  174. package/package.json +154 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAGlC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ // Config
2
+ export * from './config/index.js';
3
+ // Constants
4
+ export * from './constants/index.js';
5
+ // Database
6
+ export * from './database/index.js';
7
+ // Redis
8
+ export * from './redis/index.js';
9
+ // RabbitMQ
10
+ export * from './rabbitmq/index.js';
11
+ // Caches
12
+ export * from './caches/index.js';
13
+ // Logging
14
+ export * from './logging/index.js';
15
+ // Security
16
+ export * from './security/index.js';
17
+ // Helpers
18
+ export * from './helpers/index.js';
19
+ // Types
20
+ export * from './types/index.js';
@@ -0,0 +1,19 @@
1
+ import type { LogEntry, LogFormat } from './types.js';
2
+ /**
3
+ * Formats a log entry as JSON
4
+ */
5
+ export declare function formatJson(entry: LogEntry): string;
6
+ /**
7
+ * Formats a log entry as logfmt
8
+ * Format: key=value key2=value2
9
+ */
10
+ export declare function formatLogfmt(entry: LogEntry): string;
11
+ /**
12
+ * Formats a log entry as pretty-printed output for development
13
+ */
14
+ export declare function formatPretty(entry: LogEntry): string;
15
+ /**
16
+ * Gets the appropriate formatter for the specified format
17
+ */
18
+ export declare function getFormatter(format: LogFormat): (entry: LogEntry) => string;
19
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/logging/formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEtD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAElD;AAaD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CA+BpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAuCpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,MAAM,CAW3E"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Formats a log entry as JSON
3
+ */
4
+ export function formatJson(entry) {
5
+ return JSON.stringify(entry);
6
+ }
7
+ /**
8
+ * Escapes a value for logfmt format
9
+ */
10
+ function escapeLogfmtValue(value) {
11
+ const str = String(value);
12
+ if (str.includes(' ') || str.includes('"') || str.includes('=')) {
13
+ return `"${str.replace(/"/g, '\\"')}"`;
14
+ }
15
+ return str;
16
+ }
17
+ /**
18
+ * Formats a log entry as logfmt
19
+ * Format: key=value key2=value2
20
+ */
21
+ export function formatLogfmt(entry) {
22
+ const parts = [];
23
+ if (entry.timestamp) {
24
+ parts.push(`ts=${entry.timestamp}`);
25
+ }
26
+ parts.push(`level=${entry.level}`);
27
+ if (entry.service) {
28
+ parts.push(`service=${escapeLogfmtValue(entry.service)}`);
29
+ }
30
+ parts.push(`msg=${escapeLogfmtValue(entry.message)}`);
31
+ if (entry.context) {
32
+ for (const [key, value] of Object.entries(entry.context)) {
33
+ if (value !== undefined && value !== null) {
34
+ parts.push(`${key}=${escapeLogfmtValue(value)}`);
35
+ }
36
+ }
37
+ }
38
+ if (entry.error) {
39
+ parts.push(`error=${escapeLogfmtValue(entry.error.message)}`);
40
+ if (entry.error.stack) {
41
+ parts.push(`stack=${escapeLogfmtValue(entry.error.stack)}`);
42
+ }
43
+ }
44
+ return parts.join(' ');
45
+ }
46
+ /**
47
+ * Formats a log entry as pretty-printed output for development
48
+ */
49
+ export function formatPretty(entry) {
50
+ const levelColors = {
51
+ debug: '\x1b[36m', // cyan
52
+ info: '\x1b[32m', // green
53
+ warn: '\x1b[33m', // yellow
54
+ error: '\x1b[31m', // red
55
+ fatal: '\x1b[35m' // magenta
56
+ };
57
+ const reset = '\x1b[0m';
58
+ const dim = '\x1b[2m';
59
+ const color = levelColors[entry.level] || '';
60
+ let output = '';
61
+ if (entry.timestamp) {
62
+ output += `${dim}${entry.timestamp}${reset} `;
63
+ }
64
+ output += `${color}${entry.level.toUpperCase().padEnd(5)}${reset} `;
65
+ if (entry.service) {
66
+ output += `${dim}[${entry.service}]${reset} `;
67
+ }
68
+ output += entry.message;
69
+ if (entry.context && Object.keys(entry.context).length > 0) {
70
+ output += ` ${dim}${JSON.stringify(entry.context)}${reset}`;
71
+ }
72
+ if (entry.error) {
73
+ output += `\n${color}Error: ${entry.error.message}${reset}`;
74
+ if (entry.error.stack) {
75
+ output += `\n${dim}${entry.error.stack}${reset}`;
76
+ }
77
+ }
78
+ return output;
79
+ }
80
+ /**
81
+ * Gets the appropriate formatter for the specified format
82
+ */
83
+ export function getFormatter(format) {
84
+ switch (format) {
85
+ case 'json':
86
+ return formatJson;
87
+ case 'logfmt':
88
+ return formatLogfmt;
89
+ case 'pretty':
90
+ return formatPretty;
91
+ default:
92
+ return formatJson;
93
+ }
94
+ }
@@ -0,0 +1,4 @@
1
+ export { createLogger } from './logger-factory.js';
2
+ export { formatJson, formatLogfmt, formatPretty, getFormatter } from './formatters.js';
3
+ export type { Logger, LoggerConfig, LogLevel, LogFormat, LogEntry } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACvF,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createLogger } from './logger-factory.js';
2
+ export { formatJson, formatLogfmt, formatPretty, getFormatter } from './formatters.js';
@@ -0,0 +1,8 @@
1
+ import type { Logger, LoggerConfig } from './types.js';
2
+ /**
3
+ * Creates a logger instance
4
+ * @param config Logger configuration
5
+ * @returns Logger instance
6
+ */
7
+ export declare function createLogger(config?: LoggerConfig): Logger;
8
+ //# sourceMappingURL=logger-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-factory.d.ts","sourceRoot":"","sources":["../../src/logging/logger-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAC;AAW3E;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAE,YAAiB,GAAG,MAAM,CAoF9D"}
@@ -0,0 +1,86 @@
1
+ import { getFormatter } from './formatters.js';
2
+ const LOG_LEVELS = {
3
+ debug: 0,
4
+ info: 1,
5
+ warn: 2,
6
+ error: 3,
7
+ fatal: 4
8
+ };
9
+ /**
10
+ * Creates a logger instance
11
+ * @param config Logger configuration
12
+ * @returns Logger instance
13
+ */
14
+ export function createLogger(config = {}) {
15
+ const { level = 'info', format = 'json', serviceName, defaultContext = {}, timestamps = true, includeStackTrace = true } = config;
16
+ const minLevel = LOG_LEVELS[level];
17
+ const formatter = getFormatter(format);
18
+ function shouldLog(logLevel) {
19
+ return LOG_LEVELS[logLevel] >= minLevel;
20
+ }
21
+ function formatError(error) {
22
+ if (!error)
23
+ return undefined;
24
+ if (error instanceof Error) {
25
+ return {
26
+ message: error.message,
27
+ name: error.name,
28
+ stack: includeStackTrace ? error.stack : undefined
29
+ };
30
+ }
31
+ return {
32
+ message: typeof error === 'string' ? error : JSON.stringify(error),
33
+ name: 'Error'
34
+ };
35
+ }
36
+ function log(logLevel, message, error, context) {
37
+ if (!shouldLog(logLevel))
38
+ return;
39
+ const entry = {
40
+ level: logLevel,
41
+ message,
42
+ timestamp: timestamps ? new Date().toISOString() : undefined,
43
+ service: serviceName,
44
+ context: { ...defaultContext, ...context },
45
+ error: formatError(error)
46
+ };
47
+ const output = formatter(entry);
48
+ if (logLevel === 'error' || logLevel === 'fatal') {
49
+ console.error(output);
50
+ }
51
+ else if (logLevel === 'warn') {
52
+ console.warn(output);
53
+ }
54
+ else {
55
+ console.log(output);
56
+ }
57
+ }
58
+ const logger = {
59
+ debug(message, context) {
60
+ log('debug', message, undefined, context);
61
+ },
62
+ info(message, context) {
63
+ log('info', message, undefined, context);
64
+ },
65
+ warn(message, context) {
66
+ log('warn', message, undefined, context);
67
+ },
68
+ error(message, error, context) {
69
+ log('error', message, error, context);
70
+ },
71
+ fatal(message, error, context) {
72
+ log('fatal', message, error, context);
73
+ },
74
+ child(childContext) {
75
+ return createLogger({
76
+ level,
77
+ format,
78
+ serviceName,
79
+ defaultContext: { ...defaultContext, ...childContext },
80
+ timestamps,
81
+ includeStackTrace
82
+ });
83
+ }
84
+ };
85
+ return logger;
86
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Log levels
3
+ */
4
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';
5
+ /**
6
+ * Log format types
7
+ */
8
+ export type LogFormat = 'json' | 'logfmt' | 'pretty';
9
+ /**
10
+ * Logger configuration
11
+ */
12
+ export interface LoggerConfig {
13
+ /** Minimum log level to output */
14
+ level?: LogLevel;
15
+ /** Output format */
16
+ format?: LogFormat;
17
+ /** Service name for log context */
18
+ serviceName?: string;
19
+ /** Additional default context fields */
20
+ defaultContext?: Record<string, unknown>;
21
+ /** Whether to include timestamps */
22
+ timestamps?: boolean;
23
+ /** Whether to include stack traces for errors */
24
+ includeStackTrace?: boolean;
25
+ }
26
+ /**
27
+ * Log entry structure
28
+ */
29
+ export interface LogEntry {
30
+ level: LogLevel;
31
+ message: string;
32
+ timestamp?: string;
33
+ service?: string;
34
+ context?: Record<string, unknown>;
35
+ error?: {
36
+ message: string;
37
+ name: string;
38
+ stack?: string;
39
+ };
40
+ }
41
+ /**
42
+ * Logger interface
43
+ */
44
+ export interface Logger {
45
+ debug(message: string, context?: Record<string, unknown>): void;
46
+ info(message: string, context?: Record<string, unknown>): void;
47
+ warn(message: string, context?: Record<string, unknown>): void;
48
+ error(message: string, error?: unknown, context?: Record<string, unknown>): void;
49
+ fatal(message: string, error?: unknown, context?: Record<string, unknown>): void;
50
+ child(context: Record<string, unknown>): Logger;
51
+ }
52
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/logging/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,oBAAoB;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,oCAAoC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACjF,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACjF,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;CACjD"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { RabbitMQConnection, RabbitMQConnectionConfig } from './types.js';
2
+ /**
3
+ * Creates a RabbitMQ connection
4
+ * @param config Connection configuration
5
+ * @returns RabbitMQConnection instance
6
+ */
7
+ export declare function createRabbitMQConnection(config: RabbitMQConnectionConfig): Promise<RabbitMQConnection>;
8
+ //# sourceMappingURL=connection-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-factory.d.ts","sourceRoot":"","sources":["../../src/rabbitmq/connection-factory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAkB/E;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0G5G"}
@@ -0,0 +1,117 @@
1
+ import * as amqplib from 'amqplib';
2
+ import { hostname } from 'node:os';
3
+ import { RABBITMQ_DEFAULTS } from '../constants/defaults.js';
4
+ /**
5
+ * Builds AMQP URL from configuration
6
+ */
7
+ function buildUrl(config) {
8
+ const protocol = config.protocol ?? 'amqp';
9
+ const host = config.host;
10
+ const port = config.port ?? RABBITMQ_DEFAULTS.PORT;
11
+ const vhost = encodeURIComponent(config.vhost ?? '/');
12
+ const username = encodeURIComponent(config.username);
13
+ const password = encodeURIComponent(config.password);
14
+ const heartbeat = config.heartbeat ?? RABBITMQ_DEFAULTS.HEARTBEAT;
15
+ return `${protocol}://${username}:${password}@${host}:${port}/${vhost}?heartbeat=${heartbeat}`;
16
+ }
17
+ /**
18
+ * Creates a RabbitMQ connection
19
+ * @param config Connection configuration
20
+ * @returns RabbitMQConnection instance
21
+ */
22
+ export async function createRabbitMQConnection(config) {
23
+ const namespace = config.namespace || process.env.NODE_ENV || 'local';
24
+ const appName = config.appName || 'Unknown';
25
+ const connectionName = `${hostname()}:${appName}`;
26
+ let connection;
27
+ let channel;
28
+ let connected = false;
29
+ let reconnecting = false;
30
+ async function connect() {
31
+ const url = buildUrl(config);
32
+ connection = await amqplib.connect(url, {
33
+ timeout: config.connectionTimeout ?? RABBITMQ_DEFAULTS.CONNECTION_TIMEOUT_MS,
34
+ clientProperties: {
35
+ connection_name: connectionName
36
+ }
37
+ });
38
+ channel = await connection.createChannel();
39
+ await channel.prefetch(RABBITMQ_DEFAULTS.PREFETCH_COUNT);
40
+ connected = true;
41
+ console.log(`RabbitMQ connected: ${connectionName}`);
42
+ connection.on('error', (err) => {
43
+ console.error('RabbitMQ connection error:', err);
44
+ connected = false;
45
+ });
46
+ connection.on('close', () => {
47
+ console.log('RabbitMQ connection closed');
48
+ connected = false;
49
+ if (!reconnecting) {
50
+ scheduleReconnect();
51
+ }
52
+ });
53
+ channel.on('error', (err) => {
54
+ console.error('RabbitMQ channel error:', err);
55
+ });
56
+ channel.on('close', () => {
57
+ console.log('RabbitMQ channel closed');
58
+ });
59
+ }
60
+ function scheduleReconnect() {
61
+ if (reconnecting)
62
+ return;
63
+ reconnecting = true;
64
+ setTimeout(async () => {
65
+ try {
66
+ await connect();
67
+ reconnecting = false;
68
+ }
69
+ catch (err) {
70
+ console.error('RabbitMQ reconnection failed:', err);
71
+ reconnecting = false;
72
+ scheduleReconnect();
73
+ }
74
+ }, config.connectionTimeout ?? RABBITMQ_DEFAULTS.RECONNECT_DELAY_MS);
75
+ }
76
+ async function closeConnection() {
77
+ try {
78
+ if (channel) {
79
+ await channel.close();
80
+ }
81
+ if (connection) {
82
+ await connection.close();
83
+ }
84
+ connected = false;
85
+ }
86
+ catch (err) {
87
+ console.error('Error closing RabbitMQ connection:', err);
88
+ }
89
+ }
90
+ // Initial connection
91
+ await connect();
92
+ // Cast to satisfy the interface - amqplib types don't match perfectly
93
+ const rabbitConnection = {
94
+ get connection() {
95
+ return connection;
96
+ },
97
+ get channel() {
98
+ return channel;
99
+ },
100
+ namespace,
101
+ appName,
102
+ close: closeConnection,
103
+ isConnected() {
104
+ return connected;
105
+ },
106
+ async reconnect() {
107
+ try {
108
+ await closeConnection();
109
+ }
110
+ catch {
111
+ // Ignore close errors during reconnect
112
+ }
113
+ await connect();
114
+ }
115
+ };
116
+ return rabbitConnection;
117
+ }
@@ -0,0 +1,44 @@
1
+ import type { ConsumeMessage } from 'amqplib';
2
+ import type { RabbitMQConnection, RabbitMQConsumer, MessageHandler, ConsumeOptions } from './types.js';
3
+ /**
4
+ * Creates a consumer for a queue
5
+ * @param conn RabbitMQ connection
6
+ * @param queue Queue name (will be namespaced)
7
+ * @param handler Message handler function
8
+ * @param options Consumer options
9
+ * @returns RabbitMQConsumer instance
10
+ */
11
+ export declare function consume(conn: RabbitMQConnection, queue: string, handler: MessageHandler, options?: ConsumeOptions): Promise<RabbitMQConsumer>;
12
+ /**
13
+ * Consumer class with retry logic and error handling
14
+ */
15
+ export declare class RabbitConsumer {
16
+ private conn;
17
+ private queue;
18
+ private consumer;
19
+ private _retryAttempts;
20
+ private _retryDelayMs;
21
+ onMessage?: MessageHandler;
22
+ onError?: (error: Error, message: ConsumeMessage) => void | Promise<void>;
23
+ constructor(conn: RabbitMQConnection, queue: string, options?: {
24
+ retryAttempts?: number;
25
+ retryDelayMs?: number;
26
+ });
27
+ /** Maximum retry attempts for reconnection */
28
+ get retryAttempts(): number;
29
+ /** Delay between retry attempts in milliseconds */
30
+ get retryDelayMs(): number;
31
+ /**
32
+ * Start consuming messages
33
+ */
34
+ start(): Promise<void>;
35
+ /**
36
+ * Stop consuming messages
37
+ */
38
+ stop(): Promise<void>;
39
+ /**
40
+ * Get the current consumer tag
41
+ */
42
+ get consumerTag(): string | null;
43
+ }
44
+ //# sourceMappingURL=consumer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consumer.d.ts","sourceRoot":"","sources":["../../src/rabbitmq/consumer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIvG;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgDvJ;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAS;IAEvB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;gBAG/E,IAAI,EAAE,kBAAkB,EACxB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QACP,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC;KAClB;IAQR,8CAA8C;IAC9C,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,mDAAmD;IACnD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,GAAG,IAAI,CAE/B;CACF"}
@@ -0,0 +1,107 @@
1
+ import { getNamespacedQueue } from './namespace-helpers.js';
2
+ import { RABBITMQ_DEFAULTS } from '../constants/defaults.js';
3
+ /**
4
+ * Creates a consumer for a queue
5
+ * @param conn RabbitMQ connection
6
+ * @param queue Queue name (will be namespaced)
7
+ * @param handler Message handler function
8
+ * @param options Consumer options
9
+ * @returns RabbitMQConsumer instance
10
+ */
11
+ export async function consume(conn, queue, handler, options = {}) {
12
+ const finalQueue = getNamespacedQueue(queue, conn.namespace);
13
+ // Set prefetch if specified
14
+ if (options.prefetch !== undefined) {
15
+ await conn.channel.prefetch(options.prefetch);
16
+ }
17
+ // Ensure queue exists
18
+ await conn.channel.assertQueue(finalQueue, {
19
+ durable: true
20
+ });
21
+ const wrappedHandler = async (msg) => {
22
+ if (!msg)
23
+ return;
24
+ try {
25
+ const content = JSON.parse(msg.content.toString());
26
+ await handler(msg, content);
27
+ if (!options.noAck) {
28
+ conn.channel.ack(msg);
29
+ }
30
+ }
31
+ catch (error) {
32
+ console.error(`Error processing message from ${finalQueue}:`, error);
33
+ if (!options.noAck) {
34
+ // Reject and don't requeue to avoid infinite loops
35
+ conn.channel.nack(msg, false, false);
36
+ }
37
+ }
38
+ };
39
+ const { consumerTag } = await conn.channel.consume(finalQueue, wrappedHandler, {
40
+ noAck: options.noAck ?? false,
41
+ consumerTag: options.consumerTag
42
+ });
43
+ console.log(`Consumer started on queue ${finalQueue} with tag ${consumerTag}`);
44
+ return {
45
+ queue: finalQueue,
46
+ consumerTag,
47
+ async cancel() {
48
+ await conn.channel.cancel(consumerTag);
49
+ console.log(`Consumer cancelled: ${consumerTag}`);
50
+ }
51
+ };
52
+ }
53
+ /**
54
+ * Consumer class with retry logic and error handling
55
+ */
56
+ export class RabbitConsumer {
57
+ conn;
58
+ queue;
59
+ consumer = null;
60
+ _retryAttempts;
61
+ _retryDelayMs;
62
+ onMessage;
63
+ onError;
64
+ constructor(conn, queue, options = {}) {
65
+ this.conn = conn;
66
+ this.queue = queue;
67
+ this._retryAttempts = options.retryAttempts ?? RABBITMQ_DEFAULTS.MAX_RECONNECT_ATTEMPTS;
68
+ this._retryDelayMs = options.retryDelayMs ?? RABBITMQ_DEFAULTS.RECONNECT_DELAY_MS;
69
+ }
70
+ /** Maximum retry attempts for reconnection */
71
+ get retryAttempts() {
72
+ return this._retryAttempts;
73
+ }
74
+ /** Delay between retry attempts in milliseconds */
75
+ get retryDelayMs() {
76
+ return this._retryDelayMs;
77
+ }
78
+ /**
79
+ * Start consuming messages
80
+ */
81
+ async start() {
82
+ const handler = async (msg, content) => {
83
+ if (this.onMessage) {
84
+ await this.onMessage(msg, content);
85
+ }
86
+ };
87
+ this.consumer = await consume(this.conn, this.queue, handler, {
88
+ noAck: false,
89
+ prefetch: RABBITMQ_DEFAULTS.PREFETCH_COUNT
90
+ });
91
+ }
92
+ /**
93
+ * Stop consuming messages
94
+ */
95
+ async stop() {
96
+ if (this.consumer) {
97
+ await this.consumer.cancel();
98
+ this.consumer = null;
99
+ }
100
+ }
101
+ /**
102
+ * Get the current consumer tag
103
+ */
104
+ get consumerTag() {
105
+ return this.consumer?.consumerTag ?? null;
106
+ }
107
+ }
@@ -0,0 +1,6 @@
1
+ export { createRabbitMQConnection } from './connection-factory.js';
2
+ export { getNamespacedQueue, getNamespacedExchange, stripQueueNamespace, extractQueueNamespace } from './namespace-helpers.js';
3
+ export { publish, publishWithDelay, publishToExchange } from './publisher.js';
4
+ export { consume, RabbitConsumer } from './consumer.js';
5
+ export type { RabbitMQConnection, RabbitMQConnectionConfig, RabbitMQConsumer, DelaySettings, PublishOptions, ConsumeOptions, MessageHandler } from './types.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rabbitmq/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/H,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE9E,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAExD,YAAY,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { createRabbitMQConnection } from './connection-factory.js';
2
+ export { getNamespacedQueue, getNamespacedExchange, stripQueueNamespace, extractQueueNamespace } from './namespace-helpers.js';
3
+ export { publish, publishWithDelay, publishToExchange } from './publisher.js';
4
+ export { consume, RabbitConsumer } from './consumer.js';
@@ -0,0 +1,33 @@
1
+ /**
2
+ * CRITICAL: RabbitMQ namespace pattern - NODE_ENV-queue
3
+ * This MUST be preserved for environment isolation in RabbitMQ
4
+ */
5
+ /**
6
+ * Gets the namespaced queue name with environment prefix
7
+ * Format: environment-queue
8
+ * @param queue The base queue name
9
+ * @param namespace Optional namespace override (defaults to NODE_ENV)
10
+ * @returns The namespaced queue name
11
+ */
12
+ export declare function getNamespacedQueue(queue: string, namespace?: string): string;
13
+ /**
14
+ * Gets the namespaced exchange name with environment prefix
15
+ * Format: environment-exchange
16
+ * @param exchange The base exchange name
17
+ * @param namespace Optional namespace override (defaults to NODE_ENV)
18
+ * @returns The namespaced exchange name
19
+ */
20
+ export declare function getNamespacedExchange(exchange: string, namespace?: string): string;
21
+ /**
22
+ * Strips the namespace prefix from a queue name
23
+ * @param queue The namespaced queue name
24
+ * @returns The queue name without namespace prefix
25
+ */
26
+ export declare function stripQueueNamespace(queue: string): string;
27
+ /**
28
+ * Extracts the namespace from a namespaced queue name
29
+ * @param queue The namespaced queue name
30
+ * @returns The namespace or null if not namespaced
31
+ */
32
+ export declare function extractQueueNamespace(queue: string): string | null;
33
+ //# sourceMappingURL=namespace-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namespace-helpers.d.ts","sourceRoot":"","sources":["../../src/rabbitmq/namespace-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAGlF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGlE"}