node-server-engine 1.10.14 โ†’ 1.11.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 (47) hide show
  1. package/README.md +200 -1
  2. package/dist/entities/PubSub/handleMessage/handleMessage.js +1 -1
  3. package/dist/entities/PubSub/handleMessage/handleMessage.js.map +1 -1
  4. package/dist/entities/Redis/Redis.d.ts +66 -24
  5. package/dist/entities/Redis/Redis.js +272 -144
  6. package/dist/entities/Redis/Redis.js.map +1 -1
  7. package/dist/entities/Redis/index.d.ts +1 -1
  8. package/dist/entities/Redis/index.js +10 -38
  9. package/dist/entities/Redis/index.js.map +1 -1
  10. package/dist/entities/SecretManager/SecretManager.d.ts +87 -0
  11. package/dist/entities/SecretManager/SecretManager.js +385 -0
  12. package/dist/entities/SecretManager/SecretManager.js.map +1 -0
  13. package/dist/entities/SecretManager/SecretManager.types.d.ts +71 -0
  14. package/dist/entities/SecretManager/SecretManager.types.js +2 -0
  15. package/dist/entities/SecretManager/SecretManager.types.js.map +1 -0
  16. package/dist/entities/SecretManager/index.d.ts +2 -0
  17. package/dist/entities/SecretManager/index.js +28 -0
  18. package/dist/entities/SecretManager/index.js.map +1 -0
  19. package/dist/entities/Sequelize/Sequelize.js +5 -3
  20. package/dist/entities/Sequelize/Sequelize.js.map +1 -1
  21. package/dist/entities/Server/Server.d.ts +2 -0
  22. package/dist/entities/Server/Server.js +9 -0
  23. package/dist/entities/Server/Server.js.map +1 -1
  24. package/dist/entities/Server/Server.types.d.ts +3 -0
  25. package/dist/entities/Server/Server.types.js.map +1 -1
  26. package/dist/entities/index.d.ts +1 -0
  27. package/dist/entities/index.js +11 -0
  28. package/dist/entities/index.js.map +1 -1
  29. package/dist/middleware/requestMetrics/requestMetrics.js +15 -5
  30. package/dist/middleware/requestMetrics/requestMetrics.js.map +1 -1
  31. package/dist/utils/index.d.ts +0 -1
  32. package/dist/utils/index.js +0 -11
  33. package/dist/utils/index.js.map +1 -1
  34. package/dist/utils/jwt/jwt.js +25 -2
  35. package/dist/utils/jwt/jwt.js.map +1 -1
  36. package/dist/utils/sendEmail/sendEmail.js +4 -2
  37. package/dist/utils/sendEmail/sendEmail.js.map +1 -1
  38. package/package.json +1 -1
  39. package/dist/utils/secretManager/index.d.ts +0 -2
  40. package/dist/utils/secretManager/index.js +0 -28
  41. package/dist/utils/secretManager/index.js.map +0 -1
  42. package/dist/utils/secretManager/secretLoader.d.ts +0 -8
  43. package/dist/utils/secretManager/secretLoader.js +0 -68
  44. package/dist/utils/secretManager/secretLoader.js.map +0 -1
  45. package/dist/utils/secretManager/secretResolver.d.ts +0 -5
  46. package/dist/utils/secretManager/secretResolver.js +0 -41
  47. package/dist/utils/secretManager/secretResolver.js.map +0 -1
package/README.md CHANGED
@@ -17,7 +17,8 @@ Framework used to develop Node backend services. This package ships with a lot o
17
17
  - ๐ŸŒ **i18n** - Internationalization with translation management
18
18
  - ๐Ÿ” **ElasticSearch** - Full-text search integration (v9.2) with auto-migrations
19
19
  - ๐Ÿ’พ **Redis** - Advanced Redis client with retry logic, TLS support (ioredis v5.8)
20
- - ๐Ÿ“ **API Documentation** - Swagger/OpenAPI documentation support
20
+ - ๏ฟฝ **Secret Manager** - GCP Secret Manager integration for secure credential management
21
+ - ๏ฟฝ๐Ÿ“ **API Documentation** - Swagger/OpenAPI documentation support
21
22
  - ๐Ÿ“ค **File Uploads** - Single and chunked file upload middleware with validation
22
23
  - ๐Ÿงช **TypeScript** - Written in TypeScript with full type definitions
23
24
  - โœ… **Modern Tooling** - ESLint, Prettier, and automated versioning
@@ -59,6 +60,7 @@ Framework used to develop Node backend services. This package ships with a lot o
59
60
  - [Properties](#properties)
60
61
  - [Message Handler](#message-handler)
61
62
  - [Redis](#redis)
63
+ - [SecretManager](#secretmanager)
62
64
  - [Sequelize](#sequelize)
63
65
  - [Pub/Sub](#pubsub)
64
66
  - [PushNotification](#pushnotification)
@@ -214,6 +216,7 @@ server.init();
214
216
  | cron | Array\<Object> | List of cronjob that are called on server start | [] |
215
217
  | shutdownCallbacks | Array\<Function> | List of functions that are called on server shutdown | [] |
216
218
  | checkEnvironment | Object | [Schema against which verify the environment variables](#environment-variables-verification), will cause server termination if the environment variables are not properly set. | {} |
219
+ | secretManager | [SecretManagerOptions](#secretmanager) | Configuration for GCP Secret Manager integration. Loads secrets at startup before any other initialization. | undefined |
217
220
  | webSocket.server | Object | Settings to create a WebSocket server. See the [ws package documentation](https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback) for details. | |
218
221
  | webSocket.client | Object | Settings passed down to [SocketClient](#socket-client) when a new socket connection is established. | |
219
222
 
@@ -653,6 +656,202 @@ const client = createRedisClient({
653
656
 
654
657
  ---
655
658
 
659
+ ### SecretManager
660
+
661
+ The SecretManager entity provides seamless integration with GCP Secret Manager for secure credential management in production environments. It automatically loads secrets at startup, writes file-based secrets (like certificates) to secure temp locations, and falls back to environment variables in development.
662
+
663
+ ```javascript
664
+ import { SecretManager } from 'node-server-engine';
665
+
666
+ // Initialize (can be done automatically via Server configuration)
667
+ await SecretManager.init({
668
+ enabled: process.env.NODE_ENV === 'production',
669
+ projectId: process.env.GCP_PROJECT_ID,
670
+ cache: true,
671
+ fallbackToEnv: true,
672
+ secrets: [
673
+ 'SQL_PASSWORD', // Simple env variable
674
+ 'JWT_SECRET',
675
+ {
676
+ name: 'PRIVATE_KEY', // File-based secret
677
+ type: 'file',
678
+ targetEnvVar: 'PRIVATE_KEY_PATH',
679
+ filename: 'private-key.pem'
680
+ }
681
+ ]
682
+ });
683
+
684
+ // Get a cached secret value
685
+ const password = SecretManager.getSecret('SQL_PASSWORD');
686
+
687
+ // Fetch a secret on-demand (useful for rotation)
688
+ const apiKey = await SecretManager.fetchSecret('API_KEY');
689
+
690
+ // Reload all secrets
691
+ await SecretManager.reload();
692
+
693
+ // Check initialization status
694
+ if (SecretManager.isInitialized()) {
695
+ console.log('Secrets loaded');
696
+ }
697
+ ```
698
+
699
+ #### Features
700
+
701
+ - **Automatic Loading**: Secrets loaded during server initialization
702
+ - **Environment Fallback**: Uses `process.env` in development or when secrets are unavailable
703
+ - **File Support**: Writes certificates and keys to temp files with secure permissions (0o600)
704
+ - **Caching**: Optional caching of secret values for performance
705
+ - **Secret Rotation**: On-demand fetching for runtime secret updates
706
+ - **Lifecycle Management**: Automatic cleanup of temp files on shutdown
707
+
708
+ #### Server Integration
709
+
710
+ SecretManager can be configured directly in Server options:
711
+
712
+ ```javascript
713
+ import { Server, SecretManagerOptions } from 'node-server-engine';
714
+
715
+ const server = new Server({
716
+ endpoints: [...],
717
+ secretManager: {
718
+ enabled: process.env.NODE_ENV === 'production',
719
+ projectId: process.env.GCP_PROJECT_ID,
720
+ cache: true,
721
+ fallbackToEnv: true,
722
+ secrets: [
723
+ 'SQL_PASSWORD',
724
+ 'JWT_SECRET',
725
+ {
726
+ name: 'PRIVATE_KEY',
727
+ type: 'file',
728
+ targetEnvVar: 'PRIVATE_KEY_PATH',
729
+ filename: 'private-key.pem'
730
+ }
731
+ ]
732
+ }
733
+ });
734
+
735
+ await server.init(); // Secrets loaded before app starts
736
+ ```
737
+
738
+ #### Configuration Options
739
+
740
+ | Property | Type | Description | Default |
741
+ |---------------|-------------------------------|----------------------------------------------------------------|---------------|
742
+ | enabled | boolean | Enable Secret Manager (typically only in production) | false |
743
+ | projectId | string | GCP project ID | Required |
744
+ | cache | boolean | Cache secret values in memory | true |
745
+ | fallbackToEnv | boolean | Fall back to `process.env` if secret loading fails | true |
746
+ | tempDir | string | Directory for file-based secrets | `os.tmpdir()` |
747
+ | secrets | Array<string \| SecretConfig> | List of secrets to load | [] |
748
+
749
+ #### Secret Configuration
750
+
751
+ Secrets can be specified as strings (simple env variables) or objects for advanced configuration:
752
+
753
+ **String format** (simple env variable):
754
+ ```javascript
755
+ 'SQL_PASSWORD' // Loads GCP secret "SQL_PASSWORD" โ†’ process.env.SQL_PASSWORD
756
+ ```
757
+
758
+ **Object format** (advanced configuration):
759
+ ```javascript
760
+ {
761
+ name: 'PRIVATE_KEY', // Secret name in GCP Secret Manager
762
+ type: 'env' | 'file', // Type: 'env' for variables, 'file' for certificates
763
+ targetEnvVar: 'PRIVATE_KEY_PATH', // Env var name (optional for 'env' type)
764
+ filename: 'private-key.pem', // Filename for 'file' type (optional)
765
+ version: 'latest' // Secret version (default: 'latest')
766
+ }
767
+ ```
768
+
769
+ #### Secret Types
770
+
771
+ **Environment Variable Secrets** (`type: 'env'`):
772
+ - Loaded directly into `process.env`
773
+ - Good for passwords, API keys, tokens
774
+ - Example: `'SQL_PASSWORD'` โ†’ `process.env.SQL_PASSWORD`
775
+
776
+ **File-based Secrets** (`type: 'file'`):
777
+ - Written to temp files with secure permissions (0o600)
778
+ - Good for certificates, private keys, JSON credentials
779
+ - Environment variable points to file path
780
+ - Example: `PRIVATE_KEY` โ†’ `/tmp/private-key.pem` โ†’ `process.env.PRIVATE_KEY_PATH`
781
+
782
+ #### Environment Variables
783
+
784
+ | Variable | Description | Required |
785
+ |------------------|---------------------------------------|----------|
786
+ | GCP_PROJECT_ID | GCP project containing secrets | โœ“ |
787
+ | NODE_ENV | Environment (production/development) | - |
788
+
789
+ #### Load Results
790
+
791
+ The `init()` and `reload()` methods return load statistics:
792
+
793
+ ```javascript
794
+ const result = await SecretManager.init({...});
795
+ console.log(result);
796
+ // {
797
+ // loaded: 3, // Successfully loaded from Secret Manager
798
+ // failed: 0, // Failed to load
799
+ // fallback: 1, // Used fallback environment variables
800
+ // details: [...] // Detailed information per secret
801
+ // }
802
+ ```
803
+
804
+ #### Security Features
805
+
806
+ - **Secure File Permissions**: File-based secrets written with 0o600 (owner read/write only)
807
+ - **Automatic Cleanup**: Temp files deleted on server shutdown
808
+ - **No Logging**: Secret values never logged (only metadata)
809
+ - **Lifecycle Integration**: Registered with LifecycleController for proper cleanup
810
+
811
+ #### Example: Multiple Secrets
812
+
813
+ ```javascript
814
+ const secretConfig = {
815
+ enabled: process.env.NODE_ENV === 'production',
816
+ projectId: 'my-gcp-project',
817
+ secrets: [
818
+ // Database credentials
819
+ 'SQL_PASSWORD',
820
+ 'SQL_USER',
821
+
822
+ // API keys
823
+ 'STRIPE_API_KEY',
824
+ 'SENDGRID_API_KEY',
825
+
826
+ // Certificate files
827
+ {
828
+ name: 'TLS_CERT',
829
+ type: 'file',
830
+ targetEnvVar: 'TLS_CERT_PATH',
831
+ filename: 'tls.crt'
832
+ },
833
+ {
834
+ name: 'TLS_KEY',
835
+ type: 'file',
836
+ targetEnvVar: 'TLS_KEY_PATH',
837
+ filename: 'tls.key'
838
+ },
839
+
840
+ // Service account key
841
+ {
842
+ name: 'GCP_SERVICE_ACCOUNT',
843
+ type: 'file',
844
+ targetEnvVar: 'GOOGLE_APPLICATION_CREDENTIALS',
845
+ filename: 'service-account.json'
846
+ }
847
+ ]
848
+ };
849
+
850
+ await SecretManager.init(secretConfig);
851
+ ```
852
+
853
+ ---
854
+
656
855
  ### AWSS3
657
856
 
658
857
  The AWSS3 entity is a generic wrapper around AWS S3 (and S3-compatible services like MinIO, LocalStack). It supports uploads, downloads, streaming, metadata, and deletion with size validation and UUID-based path generation.
@@ -41,7 +41,7 @@ async function handleMessage(message, subscription, handlers, isDebezium = false
41
41
  }
42
42
  });
43
43
  }
44
- } catch (error) {
44
+ } catch {
45
45
  (0, _utils.reportError)(new _EngineError.EngineError({
46
46
  severity: _const.LogSeverity.WARNING,
47
47
  message: `Pub/Sub message is not valid JSON ${subscription.name}`,
@@ -1 +1 @@
1
- {"version":3,"file":"handleMessage.js","names":["_const","require","_EngineError","_utils","namespace","handleMessage","message","subscription","handlers","isDebezium","reportDebug","name","payload","JSON","parse","data","toString","before","after","diff","Object","keys","filter","key","EngineError","severity","LogSeverity","WARNING","error","reportError","ack","hasError","handler","attributes","publishTime","nack"],"sources":["../../../../src/entities/PubSub/handleMessage/handleMessage.ts"],"sourcesContent":["import { Subscription, Message } from '@google-cloud/pubsub';\nimport { PubSubMessageHandler, PubSubDebeziumPayload } from '../PubSub.types';\nimport { LogSeverity } from 'const';\nimport { EngineError } from 'entities/EngineError';\nimport { reportDebug, reportError } from 'utils';\n\nconst namespace = 'engine:PubSub:handleMessage';\n\n/**\n * handle the pubSubClients on message event\n * @param message - Message to parse and handle\n * @param subscription - The related Pub/Sub subscription object\n * @param handlers - Message handlers\n * @param isDebezium - Indicates that the subscription from Debezium events\n */\nexport async function handleMessage(\n message: Message,\n subscription: Subscription,\n handlers: Array<PubSubMessageHandler<unknown>>,\n isDebezium = false\n): Promise<void> {\n reportDebug({\n namespace,\n message: `Received message from Pub/Sub [${subscription.name}]`\n });\n\n let payload;\n try {\n payload = JSON.parse(message.data.toString()) as unknown;\n\n // When handling Debezium message, we calculate automatically the keys that have changed between the previous and current state\n if (isDebezium) {\n payload = payload as PubSubDebeziumPayload<Record<string, unknown>>;\n const { before, after } = payload;\n if (before && after)\n payload.diff = Object.keys(after).filter(\n (key) => after[key] !== before[key]\n );\n else if (before) payload.diff = Object.keys(before);\n else if (after) payload.diff = Object.keys(after);\n else\n throw new EngineError({\n severity: LogSeverity.WARNING,\n message: `Debezium Pub/Sub message did not include before nor after value [${subscription.name}]`,\n data: { subscription, message: message.data.toString() }\n });\n }\n } catch (error) {\n reportError(\n new EngineError({\n severity: LogSeverity.WARNING,\n message: `Pub/Sub message is not valid JSON ${subscription.name}`,\n data: { subscription, message: message.data.toString() }\n })\n );\n // Acknowledge invalid messages to prevent redelivery\n message.ack();\n return;\n }\n\n // Process all handlers\n let hasError = false;\n for (const handler of handlers) {\n try {\n await handler(payload, message.attributes, message.publishTime);\n } catch (error) {\n hasError = true;\n reportError(error);\n }\n }\n\n // Acknowledge message only after successful processing\n // If there was an error, nack the message so it can be redelivered\n if (hasError) {\n reportDebug({\n namespace,\n message: `Nacking message due to handler errors [${subscription.name}]`\n });\n message.nack();\n } else {\n message.ack();\n }\n}\n"],"mappings":";;;;;;AAEA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AAEA,MAAMG,SAAS,GAAG,6BAA6B;;AAE/C;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAeC,aAAaA,CACjCC,OAAgB,EAChBC,YAA0B,EAC1BC,QAA8C,EAC9CC,UAAU,GAAG,KAAK,EACH;EACf,IAAAC,kBAAW,EAAC;IACVN,SAAS;IACTE,OAAO,EAAE,kCAAkCC,YAAY,CAACI,IAAI;EAC9D,CAAC,CAAC;EAEF,IAAIC,OAAO;EACX,IAAI;IACFA,OAAO,GAAGC,IAAI,CAACC,KAAK,CAACR,OAAO,CAACS,IAAI,CAACC,QAAQ,CAAC,CAAC,CAAY;;IAExD;IACA,IAAIP,UAAU,EAAE;MACdG,OAAO,GAAGA,OAAyD;MACnE,MAAM;QAAEK,MAAM;QAAEC;MAAM,CAAC,GAAGN,OAAO;MACjC,IAAIK,MAAM,IAAIC,KAAK,EACjBN,OAAO,CAACO,IAAI,GAAGC,MAAM,CAACC,IAAI,CAACH,KAAK,CAAC,CAACI,MAAM,CACrCC,GAAG,IAAKL,KAAK,CAACK,GAAG,CAAC,KAAKN,MAAM,CAACM,GAAG,CACpC,CAAC,CAAC,KACC,IAAIN,MAAM,EAAEL,OAAO,CAACO,IAAI,GAAGC,MAAM,CAACC,IAAI,CAACJ,MAAM,CAAC,CAAC,KAC/C,IAAIC,KAAK,EAAEN,OAAO,CAACO,IAAI,GAAGC,MAAM,CAACC,IAAI,CAACH,KAAK,CAAC,CAAC,KAEhD,MAAM,IAAIM,wBAAW,CAAC;QACpBC,QAAQ,EAAEC,kBAAW,CAACC,OAAO;QAC7BrB,OAAO,EAAE,oEAAoEC,YAAY,CAACI,IAAI,GAAG;QACjGI,IAAI,EAAE;UAAER,YAAY;UAAED,OAAO,EAAEA,OAAO,CAACS,IAAI,CAACC,QAAQ,CAAC;QAAE;MACzD,CAAC,CAAC;IACN;EACF,CAAC,CAAC,OAAOY,KAAK,EAAE;IACd,IAAAC,kBAAW,EACT,IAAIL,wBAAW,CAAC;MACdC,QAAQ,EAAEC,kBAAW,CAACC,OAAO;MAC7BrB,OAAO,EAAE,qCAAqCC,YAAY,CAACI,IAAI,EAAE;MACjEI,IAAI,EAAE;QAAER,YAAY;QAAED,OAAO,EAAEA,OAAO,CAACS,IAAI,CAACC,QAAQ,CAAC;MAAE;IACzD,CAAC,CACH,CAAC;IACD;IACAV,OAAO,CAACwB,GAAG,CAAC,CAAC;IACb;EACF;;EAEA;EACA,IAAIC,QAAQ,GAAG,KAAK;EACpB,KAAK,MAAMC,OAAO,IAAIxB,QAAQ,EAAE;IAC9B,IAAI;MACF,MAAMwB,OAAO,CAACpB,OAAO,EAAEN,OAAO,CAAC2B,UAAU,EAAE3B,OAAO,CAAC4B,WAAW,CAAC;IACjE,CAAC,CAAC,OAAON,KAAK,EAAE;MACdG,QAAQ,GAAG,IAAI;MACf,IAAAF,kBAAW,EAACD,KAAK,CAAC;IACpB;EACF;;EAEA;EACA;EACA,IAAIG,QAAQ,EAAE;IACZ,IAAArB,kBAAW,EAAC;MACVN,SAAS;MACTE,OAAO,EAAE,0CAA0CC,YAAY,CAACI,IAAI;IACtE,CAAC,CAAC;IACFL,OAAO,CAAC6B,IAAI,CAAC,CAAC;EAChB,CAAC,MAAM;IACL7B,OAAO,CAACwB,GAAG,CAAC,CAAC;EACf;AACF","ignoreList":[]}
1
+ {"version":3,"file":"handleMessage.js","names":["_const","require","_EngineError","_utils","namespace","handleMessage","message","subscription","handlers","isDebezium","reportDebug","name","payload","JSON","parse","data","toString","before","after","diff","Object","keys","filter","key","EngineError","severity","LogSeverity","WARNING","reportError","ack","hasError","handler","attributes","publishTime","error","nack"],"sources":["../../../../src/entities/PubSub/handleMessage/handleMessage.ts"],"sourcesContent":["import { Subscription, Message } from '@google-cloud/pubsub';\nimport { PubSubMessageHandler, PubSubDebeziumPayload } from '../PubSub.types';\nimport { LogSeverity } from 'const';\nimport { EngineError } from 'entities/EngineError';\nimport { reportDebug, reportError } from 'utils';\n\nconst namespace = 'engine:PubSub:handleMessage';\n\n/**\n * handle the pubSubClients on message event\n * @param message - Message to parse and handle\n * @param subscription - The related Pub/Sub subscription object\n * @param handlers - Message handlers\n * @param isDebezium - Indicates that the subscription from Debezium events\n */\nexport async function handleMessage(\n message: Message,\n subscription: Subscription,\n handlers: Array<PubSubMessageHandler<unknown>>,\n isDebezium = false\n): Promise<void> {\n reportDebug({\n namespace,\n message: `Received message from Pub/Sub [${subscription.name}]`\n });\n\n let payload;\n try {\n payload = JSON.parse(message.data.toString()) as unknown;\n\n // When handling Debezium message, we calculate automatically the keys that have changed between the previous and current state\n if (isDebezium) {\n payload = payload as PubSubDebeziumPayload<Record<string, unknown>>;\n const { before, after } = payload;\n if (before && after)\n payload.diff = Object.keys(after).filter(\n (key) => after[key] !== before[key]\n );\n else if (before) payload.diff = Object.keys(before);\n else if (after) payload.diff = Object.keys(after);\n else\n throw new EngineError({\n severity: LogSeverity.WARNING,\n message: `Debezium Pub/Sub message did not include before nor after value [${subscription.name}]`,\n data: { subscription, message: message.data.toString() }\n });\n }\n } catch {\n reportError(\n new EngineError({\n severity: LogSeverity.WARNING,\n message: `Pub/Sub message is not valid JSON ${subscription.name}`,\n data: { subscription, message: message.data.toString() }\n })\n );\n // Acknowledge invalid messages to prevent redelivery\n message.ack();\n return;\n }\n\n // Process all handlers\n let hasError = false;\n for (const handler of handlers) {\n try {\n await handler(payload, message.attributes, message.publishTime);\n } catch (error) {\n hasError = true;\n reportError(error);\n }\n }\n\n // Acknowledge message only after successful processing\n // If there was an error, nack the message so it can be redelivered\n if (hasError) {\n reportDebug({\n namespace,\n message: `Nacking message due to handler errors [${subscription.name}]`\n });\n message.nack();\n } else {\n message.ack();\n }\n}\n"],"mappings":";;;;;;AAEA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AAEA,MAAMG,SAAS,GAAG,6BAA6B;;AAE/C;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAeC,aAAaA,CACjCC,OAAgB,EAChBC,YAA0B,EAC1BC,QAA8C,EAC9CC,UAAU,GAAG,KAAK,EACH;EACf,IAAAC,kBAAW,EAAC;IACVN,SAAS;IACTE,OAAO,EAAE,kCAAkCC,YAAY,CAACI,IAAI;EAC9D,CAAC,CAAC;EAEF,IAAIC,OAAO;EACX,IAAI;IACFA,OAAO,GAAGC,IAAI,CAACC,KAAK,CAACR,OAAO,CAACS,IAAI,CAACC,QAAQ,CAAC,CAAC,CAAY;;IAExD;IACA,IAAIP,UAAU,EAAE;MACdG,OAAO,GAAGA,OAAyD;MACnE,MAAM;QAAEK,MAAM;QAAEC;MAAM,CAAC,GAAGN,OAAO;MACjC,IAAIK,MAAM,IAAIC,KAAK,EACjBN,OAAO,CAACO,IAAI,GAAGC,MAAM,CAACC,IAAI,CAACH,KAAK,CAAC,CAACI,MAAM,CACrCC,GAAG,IAAKL,KAAK,CAACK,GAAG,CAAC,KAAKN,MAAM,CAACM,GAAG,CACpC,CAAC,CAAC,KACC,IAAIN,MAAM,EAAEL,OAAO,CAACO,IAAI,GAAGC,MAAM,CAACC,IAAI,CAACJ,MAAM,CAAC,CAAC,KAC/C,IAAIC,KAAK,EAAEN,OAAO,CAACO,IAAI,GAAGC,MAAM,CAACC,IAAI,CAACH,KAAK,CAAC,CAAC,KAEhD,MAAM,IAAIM,wBAAW,CAAC;QACpBC,QAAQ,EAAEC,kBAAW,CAACC,OAAO;QAC7BrB,OAAO,EAAE,oEAAoEC,YAAY,CAACI,IAAI,GAAG;QACjGI,IAAI,EAAE;UAAER,YAAY;UAAED,OAAO,EAAEA,OAAO,CAACS,IAAI,CAACC,QAAQ,CAAC;QAAE;MACzD,CAAC,CAAC;IACN;EACF,CAAC,CAAC,MAAM;IACN,IAAAY,kBAAW,EACT,IAAIJ,wBAAW,CAAC;MACdC,QAAQ,EAAEC,kBAAW,CAACC,OAAO;MAC7BrB,OAAO,EAAE,qCAAqCC,YAAY,CAACI,IAAI,EAAE;MACjEI,IAAI,EAAE;QAAER,YAAY;QAAED,OAAO,EAAEA,OAAO,CAACS,IAAI,CAACC,QAAQ,CAAC;MAAE;IACzD,CAAC,CACH,CAAC;IACD;IACAV,OAAO,CAACuB,GAAG,CAAC,CAAC;IACb;EACF;;EAEA;EACA,IAAIC,QAAQ,GAAG,KAAK;EACpB,KAAK,MAAMC,OAAO,IAAIvB,QAAQ,EAAE;IAC9B,IAAI;MACF,MAAMuB,OAAO,CAACnB,OAAO,EAAEN,OAAO,CAAC0B,UAAU,EAAE1B,OAAO,CAAC2B,WAAW,CAAC;IACjE,CAAC,CAAC,OAAOC,KAAK,EAAE;MACdJ,QAAQ,GAAG,IAAI;MACf,IAAAF,kBAAW,EAACM,KAAK,CAAC;IACpB;EACF;;EAEA;EACA;EACA,IAAIJ,QAAQ,EAAE;IACZ,IAAApB,kBAAW,EAAC;MACVN,SAAS;MACTE,OAAO,EAAE,0CAA0CC,YAAY,CAACI,IAAI;IACtE,CAAC,CAAC;IACFL,OAAO,CAAC6B,IAAI,CAAC,CAAC;EAChB,CAAC,MAAM;IACL7B,OAAO,CAACuB,GAAG,CAAC,CAAC;EACf;AACF","ignoreList":[]}
@@ -1,27 +1,69 @@
1
- import { Redis as RedisClient, RedisOptions } from 'ioredis';
1
+ import { Redis as RedisClient } from 'ioredis';
2
2
  import { RedisCreateOptions } from './Redis.types';
3
- export declare let redisClient: undefined | RedisClient;
4
3
  /**
5
- * Factory function to create a new Redis instance (exported for testing)
4
+ * Generic Redis wrapper for caching and data storage
5
+ * Provides methods for initialization, connection management, and cleanup
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Initialize Redis connection
10
+ * Redis.init();
11
+ *
12
+ * // Use Redis client
13
+ * await Redis.set('key', 'value');
14
+ * const value = await Redis.get('key');
15
+ *
16
+ * // Get underlying client for advanced operations
17
+ * const client = Redis.getClient();
18
+ * ```
6
19
  */
7
- export declare function createRedisInstance(config: RedisOptions): RedisClient;
8
- /**
9
- * We use a proxy to extend the Redis behavior and allow initialization of the client only when needed while keeping the same interface
10
- */
11
- export declare const Redis: never;
12
- /**
13
- * Get the underlying Redis client (for advanced use cases)
14
- */
15
- export declare function getClient(): RedisClient | undefined;
16
- /**
17
- * On init create client and connect
18
- */
19
- export declare function init(): void;
20
- /**
21
- * On shutdown close connection and clear client
22
- */
23
- export declare function shutdown(): Promise<void>;
24
- /**
25
- * Create Redis client with enhanced configuration
26
- */
27
- export declare function createRedisClient(options?: RedisCreateOptions): RedisClient;
20
+ export declare const Redis: {
21
+ /** Redis client instance */
22
+ client: RedisClient | undefined;
23
+ /**
24
+ * Initialize Redis connection
25
+ * @param options - Redis configuration options
26
+ */
27
+ init(options?: RedisCreateOptions): void;
28
+ /**
29
+ * Shutdown Redis connection and cleanup
30
+ * @returns Promise that resolves when shutdown is complete
31
+ */
32
+ shutdown(): Promise<void>;
33
+ /**
34
+ * Get the underlying Redis client
35
+ * @returns Redis client instance or undefined
36
+ */
37
+ getClient(): RedisClient | undefined;
38
+ /**
39
+ * Create Redis client with configuration
40
+ * @param options - Redis creation options
41
+ * @returns Redis client instance
42
+ * @private
43
+ */
44
+ createRedisClient(options?: RedisCreateOptions): RedisClient;
45
+ get(key: string): Promise<string | null>;
46
+ set(key: string, value: string | number | Buffer, ...args: unknown[]): Promise<"OK" | null>;
47
+ del(...keys: string[]): Promise<number>;
48
+ exists(...keys: string[]): Promise<number>;
49
+ expire(key: string, seconds: number): Promise<number>;
50
+ ttl(key: string): Promise<number>;
51
+ incr(key: string): Promise<number>;
52
+ decr(key: string): Promise<number>;
53
+ hget(key: string, field: string): Promise<string | null>;
54
+ hset(key: string, field: string, value: string | number | Buffer): Promise<number>;
55
+ hgetall(key: string): Promise<Record<string, string>>;
56
+ lpush(key: string, ...values: (string | Buffer | number)[]): Promise<number>;
57
+ rpush(key: string, ...values: (string | Buffer | number)[]): Promise<number>;
58
+ lpop(key: string, count?: number): Promise<string | string[] | null>;
59
+ rpop(key: string, count?: number): Promise<string | string[] | null>;
60
+ lrange(key: string, start: number, stop: number): Promise<string[]>;
61
+ sadd(key: string, ...members: (string | Buffer | number)[]): Promise<number>;
62
+ smembers(key: string): Promise<string[]>;
63
+ sismember(key: string, member: string | Buffer | number): Promise<number>;
64
+ };
65
+ export declare const createRedisClient: (options?: RedisCreateOptions) => RedisClient;
66
+ export declare const getClient: () => RedisClient | undefined;
67
+ export declare const init: (options?: RedisCreateOptions) => void;
68
+ export declare const shutdown: () => Promise<void>;
69
+ export declare let redisClient: RedisClient | undefined;