s3db.js 13.6.0 → 14.0.2

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 (193) hide show
  1. package/README.md +139 -43
  2. package/dist/s3db.cjs +72425 -38970
  3. package/dist/s3db.cjs.map +1 -1
  4. package/dist/s3db.es.js +72177 -38764
  5. package/dist/s3db.es.js.map +1 -1
  6. package/mcp/lib/base-handler.js +157 -0
  7. package/mcp/lib/handlers/connection-handler.js +280 -0
  8. package/mcp/lib/handlers/query-handler.js +533 -0
  9. package/mcp/lib/handlers/resource-handler.js +428 -0
  10. package/mcp/lib/tool-registry.js +336 -0
  11. package/mcp/lib/tools/connection-tools.js +161 -0
  12. package/mcp/lib/tools/query-tools.js +267 -0
  13. package/mcp/lib/tools/resource-tools.js +404 -0
  14. package/package.json +94 -49
  15. package/src/clients/memory-client.class.js +346 -191
  16. package/src/clients/memory-storage.class.js +300 -84
  17. package/src/clients/s3-client.class.js +7 -6
  18. package/src/concerns/geo-encoding.js +19 -2
  19. package/src/concerns/ip.js +59 -9
  20. package/src/concerns/money.js +8 -1
  21. package/src/concerns/password-hashing.js +49 -8
  22. package/src/concerns/plugin-storage.js +186 -18
  23. package/src/concerns/storage-drivers/filesystem-driver.js +284 -0
  24. package/src/database.class.js +139 -29
  25. package/src/errors.js +332 -42
  26. package/src/plugins/api/auth/oidc-auth.js +66 -17
  27. package/src/plugins/api/auth/strategies/base-strategy.class.js +74 -0
  28. package/src/plugins/api/auth/strategies/factory.class.js +63 -0
  29. package/src/plugins/api/auth/strategies/global-strategy.class.js +44 -0
  30. package/src/plugins/api/auth/strategies/path-based-strategy.class.js +83 -0
  31. package/src/plugins/api/auth/strategies/path-rules-strategy.class.js +118 -0
  32. package/src/plugins/api/concerns/failban-manager.js +106 -57
  33. package/src/plugins/api/concerns/opengraph-helper.js +116 -0
  34. package/src/plugins/api/concerns/route-context.js +601 -0
  35. package/src/plugins/api/concerns/state-machine.js +288 -0
  36. package/src/plugins/api/index.js +180 -41
  37. package/src/plugins/api/routes/auth-routes.js +198 -30
  38. package/src/plugins/api/routes/resource-routes.js +19 -4
  39. package/src/plugins/api/server/health-manager.class.js +163 -0
  40. package/src/plugins/api/server/middleware-chain.class.js +310 -0
  41. package/src/plugins/api/server/router.class.js +472 -0
  42. package/src/plugins/api/server.js +280 -1303
  43. package/src/plugins/api/utils/custom-routes.js +17 -5
  44. package/src/plugins/api/utils/guards.js +76 -17
  45. package/src/plugins/api/utils/openapi-generator-cached.class.js +133 -0
  46. package/src/plugins/api/utils/openapi-generator.js +7 -6
  47. package/src/plugins/api/utils/template-engine.js +77 -3
  48. package/src/plugins/audit.plugin.js +30 -8
  49. package/src/plugins/backup.plugin.js +110 -14
  50. package/src/plugins/cache/cache.class.js +22 -5
  51. package/src/plugins/cache/filesystem-cache.class.js +116 -19
  52. package/src/plugins/cache/memory-cache.class.js +211 -57
  53. package/src/plugins/cache/multi-tier-cache.class.js +371 -0
  54. package/src/plugins/cache/partition-aware-filesystem-cache.class.js +168 -47
  55. package/src/plugins/cache/redis-cache.class.js +552 -0
  56. package/src/plugins/cache/s3-cache.class.js +17 -8
  57. package/src/plugins/cache.plugin.js +176 -61
  58. package/src/plugins/cloud-inventory/drivers/alibaba-driver.js +8 -1
  59. package/src/plugins/cloud-inventory/drivers/aws-driver.js +60 -29
  60. package/src/plugins/cloud-inventory/drivers/azure-driver.js +8 -1
  61. package/src/plugins/cloud-inventory/drivers/base-driver.js +16 -2
  62. package/src/plugins/cloud-inventory/drivers/cloudflare-driver.js +8 -1
  63. package/src/plugins/cloud-inventory/drivers/digitalocean-driver.js +8 -1
  64. package/src/plugins/cloud-inventory/drivers/hetzner-driver.js +8 -1
  65. package/src/plugins/cloud-inventory/drivers/linode-driver.js +8 -1
  66. package/src/plugins/cloud-inventory/drivers/mongodb-atlas-driver.js +8 -1
  67. package/src/plugins/cloud-inventory/drivers/vultr-driver.js +8 -1
  68. package/src/plugins/cloud-inventory/index.js +29 -8
  69. package/src/plugins/cloud-inventory/registry.js +64 -42
  70. package/src/plugins/cloud-inventory.plugin.js +240 -138
  71. package/src/plugins/concerns/plugin-dependencies.js +54 -0
  72. package/src/plugins/concerns/resource-names.js +100 -0
  73. package/src/plugins/consumers/index.js +10 -2
  74. package/src/plugins/consumers/sqs-consumer.js +12 -2
  75. package/src/plugins/cookie-farm-suite.plugin.js +278 -0
  76. package/src/plugins/cookie-farm.errors.js +73 -0
  77. package/src/plugins/cookie-farm.plugin.js +869 -0
  78. package/src/plugins/costs.plugin.js +7 -1
  79. package/src/plugins/eventual-consistency/analytics.js +94 -19
  80. package/src/plugins/eventual-consistency/config.js +15 -7
  81. package/src/plugins/eventual-consistency/consolidation.js +29 -11
  82. package/src/plugins/eventual-consistency/garbage-collection.js +3 -1
  83. package/src/plugins/eventual-consistency/helpers.js +39 -14
  84. package/src/plugins/eventual-consistency/install.js +21 -2
  85. package/src/plugins/eventual-consistency/utils.js +32 -10
  86. package/src/plugins/fulltext.plugin.js +38 -11
  87. package/src/plugins/geo.plugin.js +61 -9
  88. package/src/plugins/identity/concerns/config.js +61 -0
  89. package/src/plugins/identity/concerns/mfa-manager.js +15 -2
  90. package/src/plugins/identity/concerns/rate-limit.js +124 -0
  91. package/src/plugins/identity/concerns/resource-schemas.js +9 -1
  92. package/src/plugins/identity/concerns/token-generator.js +29 -4
  93. package/src/plugins/identity/drivers/auth-driver.interface.js +76 -0
  94. package/src/plugins/identity/drivers/client-credentials-driver.js +127 -0
  95. package/src/plugins/identity/drivers/index.js +18 -0
  96. package/src/plugins/identity/drivers/password-driver.js +122 -0
  97. package/src/plugins/identity/email-service.js +17 -2
  98. package/src/plugins/identity/index.js +413 -69
  99. package/src/plugins/identity/oauth2-server.js +413 -30
  100. package/src/plugins/identity/oidc-discovery.js +16 -8
  101. package/src/plugins/identity/rsa-keys.js +115 -35
  102. package/src/plugins/identity/server.js +166 -45
  103. package/src/plugins/identity/session-manager.js +53 -7
  104. package/src/plugins/identity/ui/pages/mfa-verification.js +17 -15
  105. package/src/plugins/identity/ui/routes.js +363 -255
  106. package/src/plugins/importer/index.js +153 -20
  107. package/src/plugins/index.js +9 -2
  108. package/src/plugins/kubernetes-inventory/index.js +6 -0
  109. package/src/plugins/kubernetes-inventory/k8s-driver.js +867 -0
  110. package/src/plugins/kubernetes-inventory/resource-types.js +274 -0
  111. package/src/plugins/kubernetes-inventory.plugin.js +980 -0
  112. package/src/plugins/metrics.plugin.js +64 -16
  113. package/src/plugins/ml/base-model.class.js +25 -15
  114. package/src/plugins/ml/regression-model.class.js +1 -1
  115. package/src/plugins/ml.errors.js +57 -25
  116. package/src/plugins/ml.plugin.js +28 -4
  117. package/src/plugins/namespace.js +210 -0
  118. package/src/plugins/plugin.class.js +180 -8
  119. package/src/plugins/puppeteer/console-monitor.js +729 -0
  120. package/src/plugins/puppeteer/cookie-manager.js +492 -0
  121. package/src/plugins/puppeteer/network-monitor.js +816 -0
  122. package/src/plugins/puppeteer/performance-manager.js +746 -0
  123. package/src/plugins/puppeteer/proxy-manager.js +478 -0
  124. package/src/plugins/puppeteer/stealth-manager.js +556 -0
  125. package/src/plugins/puppeteer.errors.js +81 -0
  126. package/src/plugins/puppeteer.plugin.js +1327 -0
  127. package/src/plugins/queue-consumer.plugin.js +69 -14
  128. package/src/plugins/recon/behaviors/uptime-behavior.js +691 -0
  129. package/src/plugins/recon/concerns/command-runner.js +148 -0
  130. package/src/plugins/recon/concerns/diff-detector.js +372 -0
  131. package/src/plugins/recon/concerns/fingerprint-builder.js +307 -0
  132. package/src/plugins/recon/concerns/process-manager.js +338 -0
  133. package/src/plugins/recon/concerns/report-generator.js +478 -0
  134. package/src/plugins/recon/concerns/security-analyzer.js +571 -0
  135. package/src/plugins/recon/concerns/target-normalizer.js +68 -0
  136. package/src/plugins/recon/config/defaults.js +321 -0
  137. package/src/plugins/recon/config/resources.js +370 -0
  138. package/src/plugins/recon/index.js +778 -0
  139. package/src/plugins/recon/managers/dependency-manager.js +174 -0
  140. package/src/plugins/recon/managers/scheduler-manager.js +179 -0
  141. package/src/plugins/recon/managers/storage-manager.js +745 -0
  142. package/src/plugins/recon/managers/target-manager.js +274 -0
  143. package/src/plugins/recon/stages/asn-stage.js +314 -0
  144. package/src/plugins/recon/stages/certificate-stage.js +84 -0
  145. package/src/plugins/recon/stages/dns-stage.js +107 -0
  146. package/src/plugins/recon/stages/dnsdumpster-stage.js +362 -0
  147. package/src/plugins/recon/stages/fingerprint-stage.js +71 -0
  148. package/src/plugins/recon/stages/google-dorks-stage.js +440 -0
  149. package/src/plugins/recon/stages/http-stage.js +89 -0
  150. package/src/plugins/recon/stages/latency-stage.js +148 -0
  151. package/src/plugins/recon/stages/massdns-stage.js +302 -0
  152. package/src/plugins/recon/stages/osint-stage.js +1373 -0
  153. package/src/plugins/recon/stages/ports-stage.js +169 -0
  154. package/src/plugins/recon/stages/screenshot-stage.js +94 -0
  155. package/src/plugins/recon/stages/secrets-stage.js +514 -0
  156. package/src/plugins/recon/stages/subdomains-stage.js +295 -0
  157. package/src/plugins/recon/stages/tls-audit-stage.js +78 -0
  158. package/src/plugins/recon/stages/vulnerability-stage.js +78 -0
  159. package/src/plugins/recon/stages/web-discovery-stage.js +113 -0
  160. package/src/plugins/recon/stages/whois-stage.js +349 -0
  161. package/src/plugins/recon.plugin.js +75 -0
  162. package/src/plugins/recon.plugin.js.backup +2635 -0
  163. package/src/plugins/relation.errors.js +87 -14
  164. package/src/plugins/replicator.plugin.js +514 -137
  165. package/src/plugins/replicators/base-replicator.class.js +89 -1
  166. package/src/plugins/replicators/bigquery-replicator.class.js +66 -22
  167. package/src/plugins/replicators/dynamodb-replicator.class.js +22 -15
  168. package/src/plugins/replicators/mongodb-replicator.class.js +22 -15
  169. package/src/plugins/replicators/mysql-replicator.class.js +52 -17
  170. package/src/plugins/replicators/planetscale-replicator.class.js +30 -4
  171. package/src/plugins/replicators/postgres-replicator.class.js +62 -27
  172. package/src/plugins/replicators/s3db-replicator.class.js +25 -18
  173. package/src/plugins/replicators/schema-sync.helper.js +3 -3
  174. package/src/plugins/replicators/sqs-replicator.class.js +8 -2
  175. package/src/plugins/replicators/turso-replicator.class.js +23 -3
  176. package/src/plugins/replicators/webhook-replicator.class.js +42 -4
  177. package/src/plugins/s3-queue.plugin.js +464 -65
  178. package/src/plugins/scheduler.plugin.js +20 -6
  179. package/src/plugins/state-machine.plugin.js +40 -9
  180. package/src/plugins/tfstate/README.md +126 -126
  181. package/src/plugins/tfstate/base-driver.js +28 -4
  182. package/src/plugins/tfstate/errors.js +65 -10
  183. package/src/plugins/tfstate/filesystem-driver.js +52 -8
  184. package/src/plugins/tfstate/index.js +163 -90
  185. package/src/plugins/tfstate/s3-driver.js +64 -6
  186. package/src/plugins/ttl.plugin.js +72 -17
  187. package/src/plugins/vector/distances.js +18 -12
  188. package/src/plugins/vector/kmeans.js +26 -4
  189. package/src/resource.class.js +115 -19
  190. package/src/testing/factory.class.js +20 -3
  191. package/src/testing/seeder.class.js +7 -1
  192. package/src/clients/memory-client.md +0 -917
  193. package/src/plugins/cloud-inventory/drivers/mock-drivers.js +0 -449
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Base handler class for MCP tool handlers
3
+ */
4
+ export class BaseHandler {
5
+ constructor(database) {
6
+ this.database = database;
7
+ }
8
+
9
+ /**
10
+ * Ensure database is connected
11
+ */
12
+ ensureConnected() {
13
+ if (!this.database || !this.database.isConnected()) {
14
+ throw new Error('Database not connected. Use dbConnect tool first.');
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Get resource by name with validation
20
+ */
21
+ getResource(resourceName) {
22
+ this.ensureConnected();
23
+
24
+ if (!this.database.resources[resourceName]) {
25
+ const available = Object.keys(this.database.resources).join(', ');
26
+ throw new Error(`Resource '${resourceName}' not found. Available: ${available}`);
27
+ }
28
+
29
+ return this.database.resources[resourceName];
30
+ }
31
+
32
+ /**
33
+ * Wrap handler execution with error handling
34
+ */
35
+ async execute(method, args) {
36
+ try {
37
+ return await method.call(this, args);
38
+ } catch (error) {
39
+ return this.handleError(error, args);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Standard error handling
45
+ */
46
+ handleError(error, context = {}) {
47
+ const suggestion = this.getErrorSuggestion(error);
48
+
49
+ return {
50
+ success: false,
51
+ error: {
52
+ message: error.message,
53
+ type: error.constructor.name,
54
+ context,
55
+ suggestion,
56
+ stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
57
+ }
58
+ };
59
+ }
60
+
61
+ /**
62
+ * Get contextual error suggestions
63
+ */
64
+ getErrorSuggestion(error) {
65
+ const message = error.message.toLowerCase();
66
+
67
+ if (message.includes('not connected')) {
68
+ return 'Use dbConnect tool first to establish database connection';
69
+ }
70
+ if (message.includes('not found')) {
71
+ return 'Check resource name or use dbListResources to see available resources';
72
+ }
73
+ if (message.includes('validation')) {
74
+ return 'Use resourceValidate to check data before insertion';
75
+ }
76
+ if (message.includes('permission') || message.includes('access')) {
77
+ return 'Check your AWS credentials and bucket permissions';
78
+ }
79
+ if (message.includes('timeout')) {
80
+ return 'Operation timed out. Try with smaller batch size or increase timeout';
81
+ }
82
+
83
+ return null;
84
+ }
85
+
86
+ /**
87
+ * Generate cache key for operations
88
+ */
89
+ generateCacheKey(resource, action, params = {}) {
90
+ const parts = [`resource=${resource}`, `action=${action}`];
91
+
92
+ const sortedParams = Object.entries(params)
93
+ .sort(([a], [b]) => a.localeCompare(b))
94
+ .map(([key, value]) => `${key}=${JSON.stringify(value)}`)
95
+ .join('&');
96
+
97
+ if (sortedParams) {
98
+ parts.push(`params=${sortedParams}`);
99
+ }
100
+
101
+ return parts.join('/');
102
+ }
103
+
104
+ /**
105
+ * Extract partition information from data
106
+ */
107
+ extractPartitionInfo(resource, data) {
108
+ if (!resource?.config?.partitions || !data) {
109
+ return null;
110
+ }
111
+
112
+ const partitionInfo = {};
113
+
114
+ for (const [name, config] of Object.entries(resource.config.partitions)) {
115
+ if (config.fields) {
116
+ const values = {};
117
+ let hasValues = false;
118
+
119
+ for (const field of Object.keys(config.fields)) {
120
+ if (data[field] !== undefined && data[field] !== null) {
121
+ values[field] = data[field];
122
+ hasValues = true;
123
+ }
124
+ }
125
+
126
+ if (hasValues) {
127
+ partitionInfo[name] = values;
128
+ }
129
+ }
130
+ }
131
+
132
+ return Object.keys(partitionInfo).length > 0 ? partitionInfo : null;
133
+ }
134
+
135
+ /**
136
+ * Validate required parameters
137
+ */
138
+ validateParams(params, required) {
139
+ const missing = required.filter(param => params[param] === undefined);
140
+
141
+ if (missing.length > 0) {
142
+ throw new Error(`Missing required parameters: ${missing.join(', ')}`);
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Format response with standard structure
148
+ */
149
+ formatResponse(data, meta = {}) {
150
+ return {
151
+ success: true,
152
+ data,
153
+ timestamp: new Date().toISOString(),
154
+ ...meta
155
+ };
156
+ }
157
+ }
@@ -0,0 +1,280 @@
1
+ import { BaseHandler } from '../base-handler.js';
2
+ import { S3db, CachePlugin, CostsPlugin, MetricsPlugin, FilesystemCache, MemoryCache } from 's3db.js';
3
+
4
+ /**
5
+ * Handler for database connection operations
6
+ */
7
+ export class ConnectionHandler extends BaseHandler {
8
+ constructor(database) {
9
+ super(database);
10
+ }
11
+
12
+ /**
13
+ * Connect to S3DB database
14
+ */
15
+ async connect(args) {
16
+ const {
17
+ connectionString,
18
+ verbose = false,
19
+ parallelism = 10,
20
+ passphrase = 'secret',
21
+ versioningEnabled = false,
22
+ persistHooks = false,
23
+ enableCache = true,
24
+ enableCosts = true,
25
+ enableMetrics = false,
26
+ cacheDriver = 'memory',
27
+ cacheMaxSize = 1000,
28
+ cacheTtl = 300000,
29
+ cacheDirectory = './cache',
30
+ cachePrefix = 'cache',
31
+ cacheCompress = true
32
+ } = args;
33
+
34
+ this.validateParams(args, ['connectionString']);
35
+
36
+ if (this.database && this.database.isConnected()) {
37
+ return this.formatResponse(null, {
38
+ message: 'Database is already connected',
39
+ status: await this.getStatus()
40
+ });
41
+ }
42
+
43
+ // Build plugins array
44
+ const plugins = this.buildPlugins({
45
+ enableCache,
46
+ enableCosts,
47
+ enableMetrics,
48
+ cacheDriver,
49
+ cacheMaxSize,
50
+ cacheTtl,
51
+ cacheDirectory,
52
+ cachePrefix,
53
+ cacheCompress,
54
+ verbose
55
+ });
56
+
57
+ // Create and connect database
58
+ this.database = new S3db({
59
+ connectionString,
60
+ verbose,
61
+ parallelism,
62
+ passphrase,
63
+ versioningEnabled,
64
+ persistHooks,
65
+ plugins
66
+ });
67
+
68
+ await this.database.connect();
69
+
70
+ return this.formatResponse({
71
+ connected: true,
72
+ bucket: this.database.bucket,
73
+ keyPrefix: this.database.keyPrefix,
74
+ version: this.database.s3dbVersion
75
+ }, {
76
+ message: 'Connected to S3DB database',
77
+ plugins: this.getPluginInfo(plugins)
78
+ });
79
+ }
80
+
81
+ /**
82
+ * Disconnect from database
83
+ */
84
+ async disconnect() {
85
+ if (!this.database || !this.database.isConnected()) {
86
+ return this.formatResponse(null, {
87
+ message: 'No database connection to disconnect'
88
+ });
89
+ }
90
+
91
+ await this.database.disconnect();
92
+ const info = {
93
+ bucket: this.database.bucket,
94
+ keyPrefix: this.database.keyPrefix
95
+ };
96
+
97
+ this.database = null;
98
+
99
+ return this.formatResponse(info, {
100
+ message: 'Disconnected from S3DB database'
101
+ });
102
+ }
103
+
104
+ /**
105
+ * Get database status
106
+ */
107
+ async status() {
108
+ if (!this.database) {
109
+ return this.formatResponse({
110
+ connected: false,
111
+ message: 'No database instance created'
112
+ });
113
+ }
114
+
115
+ const status = await this.getStatus();
116
+ return this.formatResponse(status);
117
+ }
118
+
119
+ /**
120
+ * Get detailed database statistics
121
+ */
122
+ async getStats() {
123
+ this.ensureConnected();
124
+
125
+ const stats = {
126
+ database: await this.getStatus(),
127
+ costs: this.getCostStats(),
128
+ cache: await this.getCacheStats(),
129
+ metrics: this.getMetricsStats()
130
+ };
131
+
132
+ return this.formatResponse(stats);
133
+ }
134
+
135
+ /**
136
+ * Clear cache
137
+ */
138
+ async clearCache(args) {
139
+ this.ensureConnected();
140
+ const { resourceName } = args;
141
+
142
+ const cachePlugin = this.getCachePlugin();
143
+ if (!cachePlugin) {
144
+ return this.formatResponse(null, {
145
+ message: 'Cache is not enabled'
146
+ });
147
+ }
148
+
149
+ if (resourceName) {
150
+ const resource = this.getResource(resourceName);
151
+ await cachePlugin.clearCacheForResource(resource);
152
+
153
+ return this.formatResponse(null, {
154
+ message: `Cache cleared for resource: ${resourceName}`
155
+ });
156
+ }
157
+
158
+ await cachePlugin.driver.clear();
159
+ return this.formatResponse(null, {
160
+ message: 'All cache cleared'
161
+ });
162
+ }
163
+
164
+ // Private helper methods
165
+
166
+ private buildPlugins(config) {
167
+ const plugins = [];
168
+
169
+ // Costs plugin
170
+ if (config.enableCosts && process.env.S3DB_COSTS_ENABLED !== 'false') {
171
+ plugins.push(CostsPlugin);
172
+ }
173
+
174
+ // Cache plugin
175
+ if (config.enableCache && process.env.S3DB_CACHE_ENABLED !== 'false') {
176
+ plugins.push(this.buildCachePlugin(config));
177
+ }
178
+
179
+ // Metrics plugin
180
+ if (config.enableMetrics) {
181
+ plugins.push(MetricsPlugin);
182
+ }
183
+
184
+ return plugins;
185
+ }
186
+
187
+ private buildCachePlugin(config) {
188
+ const cacheConfig = {
189
+ includePartitions: true
190
+ };
191
+
192
+ const driver = process.env.S3DB_CACHE_DRIVER || config.cacheDriver;
193
+
194
+ if (driver === 'filesystem') {
195
+ cacheConfig.driver = new FilesystemCache({
196
+ directory: process.env.S3DB_CACHE_DIRECTORY || config.cacheDirectory,
197
+ prefix: process.env.S3DB_CACHE_PREFIX || config.cachePrefix,
198
+ ttl: parseInt(process.env.S3DB_CACHE_TTL) || config.cacheTtl,
199
+ enableCompression: config.cacheCompress,
200
+ enableStats: config.verbose,
201
+ enableCleanup: true,
202
+ cleanupInterval: 300000,
203
+ createDirectory: true
204
+ });
205
+ } else {
206
+ cacheConfig.driver = 'memory';
207
+ cacheConfig.memoryOptions = {
208
+ maxSize: parseInt(process.env.S3DB_CACHE_MAX_SIZE) || config.cacheMaxSize,
209
+ ttl: parseInt(process.env.S3DB_CACHE_TTL) || config.cacheTtl,
210
+ enableStats: config.verbose
211
+ };
212
+ }
213
+
214
+ return new CachePlugin(cacheConfig);
215
+ }
216
+
217
+ private async getStatus() {
218
+ return {
219
+ connected: this.database.isConnected(),
220
+ bucket: this.database.bucket,
221
+ keyPrefix: this.database.keyPrefix,
222
+ version: this.database.s3dbVersion,
223
+ resourceCount: Object.keys(this.database.resources || {}).length,
224
+ resources: Object.keys(this.database.resources || {})
225
+ };
226
+ }
227
+
228
+ private getCostStats() {
229
+ if (!this.database.client?.costs) return null;
230
+
231
+ const costs = this.database.client.costs;
232
+ return {
233
+ total: costs.total,
234
+ totalRequests: costs.requests.total,
235
+ requestsByType: { ...costs.requests },
236
+ eventsByType: { ...costs.events },
237
+ estimatedCostUSD: costs.total
238
+ };
239
+ }
240
+
241
+ private async getCacheStats() {
242
+ const plugin = this.getCachePlugin();
243
+ if (!plugin?.driver) return { enabled: false };
244
+
245
+ try {
246
+ const size = await plugin.driver.size();
247
+ const keys = await plugin.driver.keys();
248
+
249
+ return {
250
+ enabled: true,
251
+ driver: plugin.driver.constructor.name,
252
+ size,
253
+ maxSize: plugin.driver.maxSize || 'unlimited',
254
+ ttl: plugin.driver.ttl || 'no expiration',
255
+ keyCount: keys.length,
256
+ sampleKeys: keys.slice(0, 5)
257
+ };
258
+ } catch (error) {
259
+ return { enabled: false, error: error.message };
260
+ }
261
+ }
262
+
263
+ private getMetricsStats() {
264
+ const plugin = this.database.pluginList?.find(p => p.constructor.name === 'MetricsPlugin');
265
+ if (!plugin) return null;
266
+
267
+ return plugin.getMetrics();
268
+ }
269
+
270
+ private getCachePlugin() {
271
+ return this.database.pluginList?.find(p => p.constructor.name === 'CachePlugin');
272
+ }
273
+
274
+ private getPluginInfo(plugins) {
275
+ return plugins.map(p => ({
276
+ name: typeof p === 'function' ? p.name : p.constructor.name,
277
+ enabled: true
278
+ }));
279
+ }
280
+ }