dbdock 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 (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +596 -0
  3. package/dist/alerts/alert-templates.d.ts +3 -0
  4. package/dist/alerts/alert-templates.js +95 -0
  5. package/dist/alerts/alert-templates.js.map +1 -0
  6. package/dist/alerts/alert.module.d.ts +2 -0
  7. package/dist/alerts/alert.module.js +23 -0
  8. package/dist/alerts/alert.module.js.map +1 -0
  9. package/dist/alerts/alert.service.d.ts +23 -0
  10. package/dist/alerts/alert.service.js +210 -0
  11. package/dist/alerts/alert.service.js.map +1 -0
  12. package/dist/alerts/alert.types.d.ts +24 -0
  13. package/dist/alerts/alert.types.js +11 -0
  14. package/dist/alerts/alert.types.js.map +1 -0
  15. package/dist/app.module.d.ts +2 -0
  16. package/dist/app.module.js +34 -0
  17. package/dist/app.module.js.map +1 -0
  18. package/dist/backup/backup.module.d.ts +2 -0
  19. package/dist/backup/backup.module.js +26 -0
  20. package/dist/backup/backup.module.js.map +1 -0
  21. package/dist/backup/backup.service.d.ts +23 -0
  22. package/dist/backup/backup.service.js +303 -0
  23. package/dist/backup/backup.service.js.map +1 -0
  24. package/dist/backup/backup.types.d.ts +42 -0
  25. package/dist/backup/backup.types.js +16 -0
  26. package/dist/backup/backup.types.js.map +1 -0
  27. package/dist/backup/compression.service.d.ts +6 -0
  28. package/dist/backup/compression.service.js +30 -0
  29. package/dist/backup/compression.service.js.map +1 -0
  30. package/dist/cli/commands/backup.d.ts +8 -0
  31. package/dist/cli/commands/backup.js +198 -0
  32. package/dist/cli/commands/backup.js.map +1 -0
  33. package/dist/cli/commands/cleanup.d.ts +6 -0
  34. package/dist/cli/commands/cleanup.js +160 -0
  35. package/dist/cli/commands/cleanup.js.map +1 -0
  36. package/dist/cli/commands/delete.d.ts +6 -0
  37. package/dist/cli/commands/delete.js +252 -0
  38. package/dist/cli/commands/delete.js.map +1 -0
  39. package/dist/cli/commands/init.d.ts +1 -0
  40. package/dist/cli/commands/init.js +534 -0
  41. package/dist/cli/commands/init.js.map +1 -0
  42. package/dist/cli/commands/list.d.ts +8 -0
  43. package/dist/cli/commands/list.js +288 -0
  44. package/dist/cli/commands/list.js.map +1 -0
  45. package/dist/cli/commands/restore.d.ts +1 -0
  46. package/dist/cli/commands/restore.js +637 -0
  47. package/dist/cli/commands/restore.js.map +1 -0
  48. package/dist/cli/commands/schedule.d.ts +1 -0
  49. package/dist/cli/commands/schedule.js +197 -0
  50. package/dist/cli/commands/schedule.js.map +1 -0
  51. package/dist/cli/commands/start.d.ts +7 -0
  52. package/dist/cli/commands/start.js +267 -0
  53. package/dist/cli/commands/start.js.map +1 -0
  54. package/dist/cli/commands/status.d.ts +1 -0
  55. package/dist/cli/commands/status.js +46 -0
  56. package/dist/cli/commands/status.js.map +1 -0
  57. package/dist/cli/commands/test.d.ts +1 -0
  58. package/dist/cli/commands/test.js +212 -0
  59. package/dist/cli/commands/test.js.map +1 -0
  60. package/dist/cli/index.d.ts +2 -0
  61. package/dist/cli/index.js +78 -0
  62. package/dist/cli/index.js.map +1 -0
  63. package/dist/cli/utils/config.d.ts +80 -0
  64. package/dist/cli/utils/config.js +29 -0
  65. package/dist/cli/utils/config.js.map +1 -0
  66. package/dist/cli/utils/logger.d.ts +7 -0
  67. package/dist/cli/utils/logger.js +15 -0
  68. package/dist/cli/utils/logger.js.map +1 -0
  69. package/dist/cli/utils/progress.d.ts +21 -0
  70. package/dist/cli/utils/progress.js +130 -0
  71. package/dist/cli/utils/progress.js.map +1 -0
  72. package/dist/cli/utils/retention.d.ts +26 -0
  73. package/dist/cli/utils/retention.js +118 -0
  74. package/dist/cli/utils/retention.js.map +1 -0
  75. package/dist/config/config.module.d.ts +2 -0
  76. package/dist/config/config.module.js +29 -0
  77. package/dist/config/config.module.js.map +1 -0
  78. package/dist/config/config.schema.d.ts +56 -0
  79. package/dist/config/config.schema.js +219 -0
  80. package/dist/config/config.schema.js.map +1 -0
  81. package/dist/config/config.service.d.ts +13 -0
  82. package/dist/config/config.service.js +160 -0
  83. package/dist/config/config.service.js.map +1 -0
  84. package/dist/crypto/crypto.module.d.ts +2 -0
  85. package/dist/crypto/crypto.module.js +21 -0
  86. package/dist/crypto/crypto.module.js.map +1 -0
  87. package/dist/crypto/crypto.service.d.ts +22 -0
  88. package/dist/crypto/crypto.service.js +187 -0
  89. package/dist/crypto/crypto.service.js.map +1 -0
  90. package/dist/dbdock.d.ts +10 -0
  91. package/dist/dbdock.js +36 -0
  92. package/dist/dbdock.js.map +1 -0
  93. package/dist/index.d.ts +33 -0
  94. package/dist/index.js +77 -0
  95. package/dist/index.js.map +1 -0
  96. package/dist/main.d.ts +1 -0
  97. package/dist/main.js +10 -0
  98. package/dist/main.js.map +1 -0
  99. package/dist/scheduler/schedule-manager.d.ts +22 -0
  100. package/dist/scheduler/schedule-manager.js +126 -0
  101. package/dist/scheduler/schedule-manager.js.map +1 -0
  102. package/dist/scheduler/scheduler.module.d.ts +2 -0
  103. package/dist/scheduler/scheduler.module.js +25 -0
  104. package/dist/scheduler/scheduler.module.js.map +1 -0
  105. package/dist/scheduler/scheduler.service.d.ts +28 -0
  106. package/dist/scheduler/scheduler.service.js +171 -0
  107. package/dist/scheduler/scheduler.service.js.map +1 -0
  108. package/dist/standalone/backup-standalone.d.ts +14 -0
  109. package/dist/standalone/backup-standalone.js +364 -0
  110. package/dist/standalone/backup-standalone.js.map +1 -0
  111. package/dist/storage/adapters/cloudinary.adapter.d.ts +23 -0
  112. package/dist/storage/adapters/cloudinary.adapter.js +215 -0
  113. package/dist/storage/adapters/cloudinary.adapter.js.map +1 -0
  114. package/dist/storage/adapters/local.adapter.d.ts +20 -0
  115. package/dist/storage/adapters/local.adapter.js +214 -0
  116. package/dist/storage/adapters/local.adapter.js.map +1 -0
  117. package/dist/storage/adapters/r2.adapter.d.ts +10 -0
  118. package/dist/storage/adapters/r2.adapter.js +33 -0
  119. package/dist/storage/adapters/r2.adapter.js.map +1 -0
  120. package/dist/storage/adapters/s3.adapter.d.ts +26 -0
  121. package/dist/storage/adapters/s3.adapter.js +199 -0
  122. package/dist/storage/adapters/s3.adapter.js.map +1 -0
  123. package/dist/storage/storage.interface.d.ts +38 -0
  124. package/dist/storage/storage.interface.js +3 -0
  125. package/dist/storage/storage.interface.js.map +1 -0
  126. package/dist/storage/storage.module.d.ts +2 -0
  127. package/dist/storage/storage.module.js +21 -0
  128. package/dist/storage/storage.module.js.map +1 -0
  129. package/dist/storage/storage.service.d.ts +10 -0
  130. package/dist/storage/storage.service.js +89 -0
  131. package/dist/storage/storage.service.js.map +1 -0
  132. package/dist/utils/logger.d.ts +12 -0
  133. package/dist/utils/logger.js +41 -0
  134. package/dist/utils/logger.js.map +1 -0
  135. package/dist/utils/stream.pipe.d.ts +17 -0
  136. package/dist/utils/stream.pipe.js +54 -0
  137. package/dist/utils/stream.pipe.js.map +1 -0
  138. package/dist/wal/postgres-config.helper.d.ts +5 -0
  139. package/dist/wal/postgres-config.helper.js +117 -0
  140. package/dist/wal/postgres-config.helper.js.map +1 -0
  141. package/dist/wal/retention.service.d.ts +23 -0
  142. package/dist/wal/retention.service.js +158 -0
  143. package/dist/wal/retention.service.js.map +1 -0
  144. package/dist/wal/retention.types.d.ts +20 -0
  145. package/dist/wal/retention.types.js +3 -0
  146. package/dist/wal/retention.types.js.map +1 -0
  147. package/dist/wal/wal-archiver.service.d.ts +28 -0
  148. package/dist/wal/wal-archiver.service.js +263 -0
  149. package/dist/wal/wal-archiver.service.js.map +1 -0
  150. package/dist/wal/wal.module.d.ts +2 -0
  151. package/dist/wal/wal.module.js +26 -0
  152. package/dist/wal/wal.module.js.map +1 -0
  153. package/dist/wal/wal.types.d.ts +27 -0
  154. package/dist/wal/wal.types.js +11 -0
  155. package/dist/wal/wal.types.js.map +1 -0
  156. package/package.json +155 -0
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var S3StorageAdapter_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.S3StorageAdapter = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const client_s3_1 = require("@aws-sdk/client-s3");
16
+ const lib_storage_1 = require("@aws-sdk/lib-storage");
17
+ const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
18
+ let S3StorageAdapter = S3StorageAdapter_1 = class S3StorageAdapter {
19
+ logger = new common_1.Logger(S3StorageAdapter_1.name);
20
+ client;
21
+ bucket;
22
+ constructor(config) {
23
+ this.bucket = config.bucket;
24
+ this.client = new client_s3_1.S3Client({
25
+ endpoint: config.endpoint,
26
+ region: config.region || 'us-east-1',
27
+ credentials: {
28
+ accessKeyId: config.accessKeyId,
29
+ secretAccessKey: config.secretAccessKey,
30
+ },
31
+ forcePathStyle: config.forcePathStyle ?? false,
32
+ });
33
+ this.logger.log(`S3 adapter initialized for bucket: ${this.bucket}`);
34
+ }
35
+ async uploadStream(stream, options) {
36
+ try {
37
+ const upload = new lib_storage_1.Upload({
38
+ client: this.client,
39
+ params: {
40
+ Bucket: this.bucket,
41
+ Key: options.key,
42
+ Body: stream,
43
+ ContentType: options.contentType,
44
+ Metadata: options.metadata,
45
+ },
46
+ });
47
+ upload.on('httpUploadProgress', (progress) => {
48
+ if (progress.loaded && progress.total) {
49
+ const percent = ((progress.loaded / progress.total) * 100).toFixed(2);
50
+ this.logger.log(`Upload progress for ${options.key}: ${percent}%`);
51
+ }
52
+ });
53
+ const result = await upload.done();
54
+ this.logger.log(`Uploaded ${options.key} to S3`);
55
+ return {
56
+ key: options.key,
57
+ etag: result.ETag,
58
+ };
59
+ }
60
+ catch (error) {
61
+ const friendlyMessage = this.getFriendlyError(error);
62
+ this.logger.error(`Failed to upload ${options.key}: ${friendlyMessage}`);
63
+ const cleanError = new Error(friendlyMessage);
64
+ cleanError.name = 'StorageConfigurationError';
65
+ throw cleanError;
66
+ }
67
+ }
68
+ async downloadStream(options) {
69
+ try {
70
+ const command = new client_s3_1.GetObjectCommand({
71
+ Bucket: this.bucket,
72
+ Key: options.key,
73
+ });
74
+ const response = await this.client.send(command);
75
+ if (!response.Body) {
76
+ throw new Error(`No body in response for ${options.key}`);
77
+ }
78
+ return response.Body;
79
+ }
80
+ catch (error) {
81
+ const friendlyMessage = this.getFriendlyError(error);
82
+ this.logger.error(`Failed to download ${options.key}: ${friendlyMessage}`);
83
+ const cleanError = new Error(friendlyMessage);
84
+ cleanError.name = 'StorageConfigurationError';
85
+ throw cleanError;
86
+ }
87
+ }
88
+ async listObjects(options) {
89
+ try {
90
+ const command = new client_s3_1.ListObjectsV2Command({
91
+ Bucket: this.bucket,
92
+ Prefix: options?.prefix,
93
+ MaxKeys: options?.maxKeys || 1000,
94
+ StartAfter: options?.startAfter,
95
+ });
96
+ const response = await this.client.send(command);
97
+ if (!response.Contents) {
98
+ return [];
99
+ }
100
+ return response.Contents.map((obj) => ({
101
+ key: obj.Key,
102
+ size: obj.Size || 0,
103
+ lastModified: obj.LastModified || new Date(),
104
+ }));
105
+ }
106
+ catch (error) {
107
+ const friendlyMessage = this.getFriendlyError(error);
108
+ this.logger.error(`Failed to list objects: ${friendlyMessage}`);
109
+ const cleanError = new Error(friendlyMessage);
110
+ cleanError.name = 'StorageConfigurationError';
111
+ throw cleanError;
112
+ }
113
+ }
114
+ async deleteObject(options) {
115
+ try {
116
+ const command = new client_s3_1.DeleteObjectCommand({
117
+ Bucket: this.bucket,
118
+ Key: options.key,
119
+ });
120
+ await this.client.send(command);
121
+ this.logger.log(`Deleted ${options.key} from S3`);
122
+ }
123
+ catch (error) {
124
+ const friendlyMessage = this.getFriendlyError(error);
125
+ this.logger.error(`Failed to delete ${options.key}: ${friendlyMessage}`);
126
+ const cleanError = new Error(friendlyMessage);
127
+ cleanError.name = 'StorageConfigurationError';
128
+ throw cleanError;
129
+ }
130
+ }
131
+ async generatePresignedUrl(options) {
132
+ try {
133
+ const command = new client_s3_1.GetObjectCommand({
134
+ Bucket: this.bucket,
135
+ Key: options.key,
136
+ });
137
+ const url = await (0, s3_request_presigner_1.getSignedUrl)(this.client, command, {
138
+ expiresIn: options.expiresIn || 3600,
139
+ });
140
+ return url;
141
+ }
142
+ catch (error) {
143
+ const friendlyMessage = this.getFriendlyError(error);
144
+ this.logger.error(`Failed to generate presigned URL for ${options.key}: ${friendlyMessage}`);
145
+ const cleanError = new Error(friendlyMessage);
146
+ cleanError.name = 'StorageConfigurationError';
147
+ throw cleanError;
148
+ }
149
+ }
150
+ async objectExists(key) {
151
+ try {
152
+ const command = new client_s3_1.HeadObjectCommand({
153
+ Bucket: this.bucket,
154
+ Key: key,
155
+ });
156
+ await this.client.send(command);
157
+ return true;
158
+ }
159
+ catch (error) {
160
+ if (error.name === 'NotFound') {
161
+ return false;
162
+ }
163
+ throw error;
164
+ }
165
+ }
166
+ getFriendlyError(error) {
167
+ const err = error;
168
+ const code = err?.code;
169
+ const message = err?.message || '';
170
+ if (code === 'EPROTO' || message.includes('SSL') || message.includes('TLS')) {
171
+ return 'Invalid storage configuration: SSL/TLS handshake failed. Please verify your endpoint URL, access key ID, and secret access key are correct.';
172
+ }
173
+ if (code === 'ENOTFOUND' || message.includes('getaddrinfo')) {
174
+ return 'Invalid storage configuration: Could not resolve endpoint hostname. Please verify your endpoint URL is correct.';
175
+ }
176
+ if (code === 'SignatureDoesNotMatch' || message.includes('signature')) {
177
+ return 'Invalid storage configuration: Authentication failed. Please verify your access key ID and secret access key are correct.';
178
+ }
179
+ if (code === 'InvalidAccessKeyId') {
180
+ return 'Invalid storage configuration: Access key ID not found. Please verify your access key ID is correct.';
181
+ }
182
+ if (code === 'NoSuchBucket') {
183
+ return `Invalid storage configuration: Bucket "${this.bucket}" does not exist. Please verify your bucket name is correct.`;
184
+ }
185
+ if (code === 'AccessDenied' || code === 'Forbidden') {
186
+ return 'Invalid storage configuration: Access denied. Please verify your credentials have the necessary permissions for this bucket.';
187
+ }
188
+ if (code === 'ETIMEDOUT' || code === 'ECONNREFUSED') {
189
+ return 'Invalid storage configuration: Connection failed. Please verify your endpoint URL and network connectivity.';
190
+ }
191
+ return message || 'Unknown storage error occurred';
192
+ }
193
+ };
194
+ exports.S3StorageAdapter = S3StorageAdapter;
195
+ exports.S3StorageAdapter = S3StorageAdapter = S3StorageAdapter_1 = __decorate([
196
+ (0, common_1.Injectable)(),
197
+ __metadata("design:paramtypes", [Object])
198
+ ], S3StorageAdapter);
199
+ //# sourceMappingURL=s3.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.adapter.js","sourceRoot":"","sources":["../../../src/storage/adapters/s3.adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { Readable } from 'stream';
2
+ export interface UploadOptions {
3
+ key: string;
4
+ metadata?: Record<string, string>;
5
+ contentType?: string;
6
+ }
7
+ export interface DownloadOptions {
8
+ key: string;
9
+ }
10
+ export interface ListOptions {
11
+ prefix?: string;
12
+ maxKeys?: number;
13
+ startAfter?: string;
14
+ }
15
+ export interface StorageObject {
16
+ key: string;
17
+ size: number;
18
+ lastModified: Date;
19
+ metadata?: Record<string, string>;
20
+ }
21
+ export interface DeleteOptions {
22
+ key: string;
23
+ }
24
+ export interface PresignedUrlOptions {
25
+ key: string;
26
+ expiresIn?: number;
27
+ }
28
+ export interface IStorageAdapter {
29
+ uploadStream(stream: Readable, options: UploadOptions): Promise<{
30
+ key: string;
31
+ etag?: string;
32
+ }>;
33
+ downloadStream(options: DownloadOptions): Promise<Readable>;
34
+ listObjects(options?: ListOptions): Promise<StorageObject[]>;
35
+ deleteObject(options: DeleteOptions): Promise<void>;
36
+ generatePresignedUrl(options: PresignedUrlOptions): Promise<string>;
37
+ objectExists(key: string): Promise<boolean>;
38
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=storage.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.interface.js","sourceRoot":"","sources":["../../src/storage/storage.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare class StorageModule {
2
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.StorageModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const storage_service_1 = require("./storage.service");
12
+ let StorageModule = class StorageModule {
13
+ };
14
+ exports.StorageModule = StorageModule;
15
+ exports.StorageModule = StorageModule = __decorate([
16
+ (0, common_1.Module)({
17
+ providers: [storage_service_1.StorageService],
18
+ exports: [storage_service_1.StorageService],
19
+ })
20
+ ], StorageModule);
21
+ //# sourceMappingURL=storage.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.module.js","sourceRoot":"","sources":["../../src/storage/storage.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,uDAAmD;AAM5C,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,sCAAa;wBAAb,aAAa;IAJzB,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,CAAC,gCAAc,CAAC;QAC3B,OAAO,EAAE,CAAC,gCAAc,CAAC;KAC1B,CAAC;GACW,aAAa,CAAG"}
@@ -0,0 +1,10 @@
1
+ import { DBDockConfigService } from '../config/config.service';
2
+ import { IStorageAdapter } from './storage.interface';
3
+ export declare class StorageService {
4
+ private configService;
5
+ private readonly logger;
6
+ private adapter;
7
+ constructor(configService: DBDockConfigService);
8
+ private initializeAdapter;
9
+ getAdapter(): IStorageAdapter;
10
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var StorageService_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.StorageService = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const config_service_1 = require("../config/config.service");
16
+ const local_adapter_1 = require("./adapters/local.adapter");
17
+ const s3_adapter_1 = require("./adapters/s3.adapter");
18
+ const r2_adapter_1 = require("./adapters/r2.adapter");
19
+ const cloudinary_adapter_1 = require("./adapters/cloudinary.adapter");
20
+ const config_schema_1 = require("../config/config.schema");
21
+ let StorageService = StorageService_1 = class StorageService {
22
+ configService;
23
+ logger = new common_1.Logger(StorageService_1.name);
24
+ adapter;
25
+ constructor(configService) {
26
+ this.configService = configService;
27
+ this.initializeAdapter();
28
+ }
29
+ initializeAdapter() {
30
+ const storageConfig = this.configService.get('storage');
31
+ switch (storageConfig.provider) {
32
+ case config_schema_1.StorageProvider.LOCAL:
33
+ this.adapter = new local_adapter_1.LocalStorageAdapter(storageConfig.localPath || './backups');
34
+ this.logger.log('Initialized local storage adapter');
35
+ break;
36
+ case config_schema_1.StorageProvider.S3:
37
+ if (!storageConfig.accessKeyId || !storageConfig.secretAccessKey) {
38
+ throw new Error('S3 credentials are required');
39
+ }
40
+ this.adapter = new s3_adapter_1.S3StorageAdapter({
41
+ endpoint: storageConfig.endpoint,
42
+ bucket: storageConfig.bucket,
43
+ accessKeyId: storageConfig.accessKeyId,
44
+ secretAccessKey: storageConfig.secretAccessKey,
45
+ });
46
+ this.logger.log('Initialized S3 storage adapter');
47
+ break;
48
+ case config_schema_1.StorageProvider.R2:
49
+ if (!storageConfig.accessKeyId || !storageConfig.secretAccessKey) {
50
+ throw new Error('R2 credentials are required');
51
+ }
52
+ if (!storageConfig.endpoint) {
53
+ throw new Error('R2 account ID is required in endpoint');
54
+ }
55
+ const accountId = storageConfig.endpoint.split('.')[0];
56
+ this.adapter = new r2_adapter_1.R2StorageAdapter({
57
+ accountId,
58
+ bucket: storageConfig.bucket,
59
+ accessKeyId: storageConfig.accessKeyId,
60
+ secretAccessKey: storageConfig.secretAccessKey,
61
+ });
62
+ this.logger.log('Initialized R2 storage adapter');
63
+ break;
64
+ case config_schema_1.StorageProvider.CLOUDINARY:
65
+ if (!storageConfig.accessKeyId || !storageConfig.secretAccessKey) {
66
+ throw new Error('Cloudinary credentials are required');
67
+ }
68
+ this.adapter = new cloudinary_adapter_1.CloudinaryStorageAdapter({
69
+ cloudName: storageConfig.bucket,
70
+ apiKey: storageConfig.accessKeyId,
71
+ apiSecret: storageConfig.secretAccessKey,
72
+ folder: storageConfig.endpoint,
73
+ });
74
+ this.logger.log('Initialized Cloudinary storage adapter');
75
+ break;
76
+ default:
77
+ throw new Error(`Unknown storage provider: ${storageConfig.provider}`);
78
+ }
79
+ }
80
+ getAdapter() {
81
+ return this.adapter;
82
+ }
83
+ };
84
+ exports.StorageService = StorageService;
85
+ exports.StorageService = StorageService = StorageService_1 = __decorate([
86
+ (0, common_1.Injectable)(),
87
+ __metadata("design:paramtypes", [config_service_1.DBDockConfigService])
88
+ ], StorageService);
89
+ //# sourceMappingURL=storage.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.service.js","sourceRoot":"","sources":["../../src/storage/storage.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { Logger as NestLogger } from '@nestjs/common';
2
+ export declare class DBDockLogger extends NestLogger {
3
+ logBackupStart(backupId: string, type: string): void;
4
+ logBackupComplete(backupId: string, duration: number, size: number): void;
5
+ logBackupError(backupId: string, error: Error): void;
6
+ logRestoreStart(backupId: string, targetTime?: string): void;
7
+ logRestoreComplete(backupId: string, duration: number): void;
8
+ logRestoreError(backupId: string, error: Error): void;
9
+ logWalArchive(walFile: string): void;
10
+ logWalArchiveError(walFile: string, error: Error): void;
11
+ private formatBytes;
12
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DBDockLogger = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ class DBDockLogger extends common_1.Logger {
6
+ logBackupStart(backupId, type) {
7
+ this.log(`Backup started: ${backupId} (type: ${type})`);
8
+ }
9
+ logBackupComplete(backupId, duration, size) {
10
+ this.log(`Backup completed: ${backupId} (duration: ${duration}ms, size: ${this.formatBytes(size)})`);
11
+ }
12
+ logBackupError(backupId, error) {
13
+ this.error(`Backup failed: ${backupId} - ${error.message}`, error.stack);
14
+ }
15
+ logRestoreStart(backupId, targetTime) {
16
+ const timeInfo = targetTime ? ` to time: ${targetTime}` : '';
17
+ this.log(`Restore started: ${backupId}${timeInfo}`);
18
+ }
19
+ logRestoreComplete(backupId, duration) {
20
+ this.log(`Restore completed: ${backupId} (duration: ${duration}ms)`);
21
+ }
22
+ logRestoreError(backupId, error) {
23
+ this.error(`Restore failed: ${backupId} - ${error.message}`, error.stack);
24
+ }
25
+ logWalArchive(walFile) {
26
+ this.log(`WAL archived: ${walFile}`);
27
+ }
28
+ logWalArchiveError(walFile, error) {
29
+ this.error(`WAL archive failed: ${walFile} - ${error.message}`);
30
+ }
31
+ formatBytes(bytes) {
32
+ if (bytes === 0)
33
+ return '0 B';
34
+ const k = 1024;
35
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
36
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
37
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
38
+ }
39
+ }
40
+ exports.DBDockLogger = DBDockLogger;
41
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;;AAAA,2CAAsD;AAEtD,MAAa,YAAa,SAAQ,eAAU;IAC1C,cAAc,CAAC,QAAgB,EAAE,IAAY;QAC3C,IAAI,CAAC,GAAG,CAAC,mBAAmB,QAAQ,WAAW,IAAI,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,iBAAiB,CAAC,QAAgB,EAAE,QAAgB,EAAE,IAAY;QAChE,IAAI,CAAC,GAAG,CACN,qBAAqB,QAAQ,eAAe,QAAQ,aAAa,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAC3F,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,QAAgB,EAAE,KAAY;QAC3C,IAAI,CAAC,KAAK,CAAC,kBAAkB,QAAQ,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3E,CAAC;IAED,eAAe,CAAC,QAAgB,EAAE,UAAmB;QACnD,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,IAAI,CAAC,GAAG,CAAC,oBAAoB,QAAQ,GAAG,QAAQ,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,kBAAkB,CAAC,QAAgB,EAAE,QAAgB;QACnD,IAAI,CAAC,GAAG,CAAC,sBAAsB,QAAQ,eAAe,QAAQ,KAAK,CAAC,CAAC;IACvE,CAAC;IAED,eAAe,CAAC,QAAgB,EAAE,KAAY;QAC5C,IAAI,CAAC,KAAK,CAAC,mBAAmB,QAAQ,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5E,CAAC;IAED,aAAa,CAAC,OAAe;QAC3B,IAAI,CAAC,GAAG,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,kBAAkB,CAAC,OAAe,EAAE,KAAY;QAC9C,IAAI,CAAC,KAAK,CAAC,uBAAuB,OAAO,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC;IAEO,WAAW,CAAC,KAAa;QAC/B,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAE9B,MAAM,CAAC,GAAG,IAAI,CAAC;QACf,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpD,OAAO,GAAG,UAAU,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,CAAC;CACF;AA7CD,oCA6CC"}
@@ -0,0 +1,17 @@
1
+ import { Transform, TransformCallback } from 'stream';
2
+ export declare class CounterStream extends Transform {
3
+ private bytesProcessed;
4
+ _transform(chunk: unknown, encoding: BufferEncoding, callback: TransformCallback): void;
5
+ _flush(callback: TransformCallback): void;
6
+ getBytesProcessed(): number;
7
+ }
8
+ export declare class ProgressStream extends Transform {
9
+ private bytesProcessed;
10
+ private lastReportedProgress;
11
+ private readonly reportInterval;
12
+ private readonly onProgress?;
13
+ constructor(reportIntervalBytes?: number, onProgress?: (bytes: number) => void);
14
+ _transform(chunk: unknown, encoding: BufferEncoding, callback: TransformCallback): void;
15
+ _flush(callback: TransformCallback): void;
16
+ getBytesProcessed(): number;
17
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProgressStream = exports.CounterStream = void 0;
4
+ const stream_1 = require("stream");
5
+ class CounterStream extends stream_1.Transform {
6
+ bytesProcessed = 0;
7
+ _transform(chunk, encoding, callback) {
8
+ this.bytesProcessed += chunk.length;
9
+ this.push(chunk);
10
+ callback();
11
+ }
12
+ _flush(callback) {
13
+ callback();
14
+ }
15
+ getBytesProcessed() {
16
+ return this.bytesProcessed;
17
+ }
18
+ }
19
+ exports.CounterStream = CounterStream;
20
+ class ProgressStream extends stream_1.Transform {
21
+ bytesProcessed = 0;
22
+ lastReportedProgress = 0;
23
+ reportInterval;
24
+ onProgress;
25
+ constructor(reportIntervalBytes = 1024 * 1024, onProgress) {
26
+ super();
27
+ this.reportInterval = reportIntervalBytes;
28
+ this.onProgress = onProgress;
29
+ }
30
+ _transform(chunk, encoding, callback) {
31
+ const buffer = chunk;
32
+ this.bytesProcessed += buffer.length;
33
+ if (this.bytesProcessed - this.lastReportedProgress >=
34
+ this.reportInterval) {
35
+ this.lastReportedProgress = this.bytesProcessed;
36
+ if (this.onProgress) {
37
+ this.onProgress(this.bytesProcessed);
38
+ }
39
+ }
40
+ this.push(chunk);
41
+ callback();
42
+ }
43
+ _flush(callback) {
44
+ if (this.onProgress && this.bytesProcessed > this.lastReportedProgress) {
45
+ this.onProgress(this.bytesProcessed);
46
+ }
47
+ callback();
48
+ }
49
+ getBytesProcessed() {
50
+ return this.bytesProcessed;
51
+ }
52
+ }
53
+ exports.ProgressStream = ProgressStream;
54
+ //# sourceMappingURL=stream.pipe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.pipe.js","sourceRoot":"","sources":["../../src/utils/stream.pipe.ts"],"names":[],"mappings":";;;AAAA,mCAAsD;AAEtD,MAAa,aAAc,SAAQ,kBAAS;IAClC,cAAc,GAAG,CAAC,CAAC;IAE3B,UAAU,CACR,KAAc,EACd,QAAwB,EACxB,QAA2B;QAE3B,IAAI,CAAC,cAAc,IAAK,KAAgB,CAAC,MAAM,CAAC;QAChD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,QAAQ,EAAE,CAAC;IACb,CAAC;IAED,MAAM,CAAC,QAA2B;QAChC,QAAQ,EAAE,CAAC;IACb,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;CACF;AApBD,sCAoBC;AAED,MAAa,cAAe,SAAQ,kBAAS;IACnC,cAAc,GAAG,CAAC,CAAC;IACnB,oBAAoB,GAAG,CAAC,CAAC;IAChB,cAAc,CAAS;IACvB,UAAU,CAA2B;IAEtD,YACE,mBAAmB,GAAG,IAAI,GAAG,IAAI,EACjC,UAAoC;QAEpC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,cAAc,GAAG,mBAAmB,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,UAAU,CACR,KAAc,EACd,QAAwB,EACxB,QAA2B;QAE3B,MAAM,MAAM,GAAG,KAAe,CAAC;QAC/B,IAAI,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC;QAErC,IACE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,oBAAoB;YAC/C,IAAI,CAAC,cAAc,EACnB,CAAC;YACD,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC;YAChD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,QAAQ,EAAE,CAAC;IACb,CAAC;IAED,MAAM,CAAC,QAA2B;QAChC,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACvE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACvC,CAAC;QACD,QAAQ,EAAE,CAAC;IACb,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;CACF;AA/CD,wCA+CC"}
@@ -0,0 +1,5 @@
1
+ export declare class PostgresConfigHelper {
2
+ static getArchiveCommandScript(archivePath: string): string;
3
+ static getPostgresqlConfSettings(archivePath: string): string;
4
+ static getSetupInstructions(): string;
5
+ }
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PostgresConfigHelper = void 0;
4
+ class PostgresConfigHelper {
5
+ static getArchiveCommandScript(archivePath) {
6
+ return `
7
+ #!/bin/bash
8
+ # PostgreSQL WAL Archive Command Script
9
+ # Generated by DBDock
10
+
11
+ WAL_FILE="$1"
12
+ WAL_PATH="$2"
13
+ ARCHIVE_PATH="${archivePath}"
14
+
15
+ # Create archive directory if it doesn't exist
16
+ mkdir -p "$ARCHIVE_PATH"
17
+
18
+ # Copy WAL file to archive location
19
+ cp "$WAL_PATH" "$ARCHIVE_PATH/$WAL_FILE"
20
+
21
+ # Signal DBDock to process this WAL file
22
+ # You can integrate this with DBDock's WAL archiver
23
+ # For now, we just copy it to the archive location
24
+
25
+ exit 0
26
+ `.trim();
27
+ }
28
+ static getPostgresqlConfSettings(archivePath) {
29
+ return `
30
+ # PostgreSQL Configuration for DBDock WAL Archiving
31
+ # Add these settings to postgresql.conf
32
+
33
+ # Enable WAL archiving
34
+ wal_level = replica
35
+ archive_mode = on
36
+ archive_command = 'test ! -f ${archivePath}/%f && cp %p ${archivePath}/%f'
37
+
38
+ # Archive timeout (optional - archives WAL every 5 minutes even if not full)
39
+ archive_timeout = 300
40
+
41
+ # WAL segment size (default is 16MB)
42
+ # Note: This is a compile-time setting and cannot be changed in postgresql.conf
43
+
44
+ # For better PITR recovery
45
+ full_page_writes = on
46
+ `.trim();
47
+ }
48
+ static getSetupInstructions() {
49
+ return `
50
+ # DBDock WAL Archiving Setup Instructions
51
+
52
+ ## 1. Configure PostgreSQL
53
+
54
+ Add the following to your postgresql.conf:
55
+
56
+ \`\`\`
57
+ wal_level = replica
58
+ archive_mode = on
59
+ archive_command = 'test ! -f /path/to/archive/%f && cp %p /path/to/archive/%f'
60
+ archive_timeout = 300
61
+ \`\`\`
62
+
63
+ ## 2. Create Archive Directory
64
+
65
+ \`\`\`bash
66
+ mkdir -p /path/to/archive
67
+ chown postgres:postgres /path/to/archive
68
+ chmod 700 /path/to/archive
69
+ \`\`\`
70
+
71
+ ## 3. Restart PostgreSQL
72
+
73
+ \`\`\`bash
74
+ sudo systemctl restart postgresql
75
+ \`\`\`
76
+
77
+ ## 4. Verify Configuration
78
+
79
+ \`\`\`sql
80
+ SELECT name, setting FROM pg_settings WHERE name IN ('wal_level', 'archive_mode', 'archive_command');
81
+ \`\`\`
82
+
83
+ ## 5. Monitor WAL Archiving
84
+
85
+ \`\`\`sql
86
+ SELECT * FROM pg_stat_archiver;
87
+ \`\`\`
88
+
89
+ ## 6. Configure DBDock
90
+
91
+ Enable PITR in your dbdock.config.json:
92
+
93
+ \`\`\`json
94
+ {
95
+ "pitr": {
96
+ "enabled": true,
97
+ "walIntervalSeconds": 300,
98
+ "retentionDays": 30
99
+ }
100
+ }
101
+ \`\`\`
102
+
103
+ ## 7. Archive WAL Files with DBDock
104
+
105
+ You can manually archive WAL files or set up a cron job:
106
+
107
+ \`\`\`bash
108
+ # Archive all WAL files in the archive directory
109
+ for wal in /path/to/archive/*; do
110
+ dbdock wal:archive --file "$wal"
111
+ done
112
+ \`\`\`
113
+ `.trim();
114
+ }
115
+ }
116
+ exports.PostgresConfigHelper = PostgresConfigHelper;
117
+ //# sourceMappingURL=postgres-config.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-config.helper.js","sourceRoot":"","sources":["../../src/wal/postgres-config.helper.ts"],"names":[],"mappings":";;;AAAA,MAAa,oBAAoB;IAC/B,MAAM,CAAC,uBAAuB,CAAC,WAAmB;QAChD,OAAO;;;;;;;gBAOK,WAAW;;;;;;;;;;;;;CAa1B,CAAC,IAAI,EAAE,CAAC;IACP,CAAC;IAED,MAAM,CAAC,yBAAyB,CAAC,WAAmB;QAClD,OAAO;;;;;;;+BAOoB,WAAW,gBAAgB,WAAW;;;;;;;;;;CAUpE,CAAC,IAAI,EAAE,CAAC;IACP,CAAC;IAED,MAAM,CAAC,oBAAoB;QACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEV,CAAC,IAAI,EAAE,CAAC;IACP,CAAC;CACF;AAjHD,oDAiHC"}