s3db.js 13.6.1 → 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 (189) hide show
  1. package/README.md +56 -15
  2. package/dist/s3db.cjs +72446 -39022
  3. package/dist/s3db.cjs.map +1 -1
  4. package/dist/s3db.es.js +72172 -38790
  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 +85 -50
  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/route-context.js +601 -0
  34. package/src/plugins/api/index.js +168 -40
  35. package/src/plugins/api/routes/auth-routes.js +198 -30
  36. package/src/plugins/api/routes/resource-routes.js +19 -4
  37. package/src/plugins/api/server/health-manager.class.js +163 -0
  38. package/src/plugins/api/server/middleware-chain.class.js +310 -0
  39. package/src/plugins/api/server/router.class.js +472 -0
  40. package/src/plugins/api/server.js +280 -1303
  41. package/src/plugins/api/utils/custom-routes.js +17 -5
  42. package/src/plugins/api/utils/guards.js +76 -17
  43. package/src/plugins/api/utils/openapi-generator-cached.class.js +133 -0
  44. package/src/plugins/api/utils/openapi-generator.js +7 -6
  45. package/src/plugins/audit.plugin.js +30 -8
  46. package/src/plugins/backup.plugin.js +110 -14
  47. package/src/plugins/cache/cache.class.js +22 -5
  48. package/src/plugins/cache/filesystem-cache.class.js +116 -19
  49. package/src/plugins/cache/memory-cache.class.js +211 -57
  50. package/src/plugins/cache/multi-tier-cache.class.js +371 -0
  51. package/src/plugins/cache/partition-aware-filesystem-cache.class.js +168 -47
  52. package/src/plugins/cache/redis-cache.class.js +552 -0
  53. package/src/plugins/cache/s3-cache.class.js +17 -8
  54. package/src/plugins/cache.plugin.js +176 -61
  55. package/src/plugins/cloud-inventory/drivers/alibaba-driver.js +8 -1
  56. package/src/plugins/cloud-inventory/drivers/aws-driver.js +60 -29
  57. package/src/plugins/cloud-inventory/drivers/azure-driver.js +8 -1
  58. package/src/plugins/cloud-inventory/drivers/base-driver.js +16 -2
  59. package/src/plugins/cloud-inventory/drivers/cloudflare-driver.js +8 -1
  60. package/src/plugins/cloud-inventory/drivers/digitalocean-driver.js +8 -1
  61. package/src/plugins/cloud-inventory/drivers/hetzner-driver.js +8 -1
  62. package/src/plugins/cloud-inventory/drivers/linode-driver.js +8 -1
  63. package/src/plugins/cloud-inventory/drivers/mongodb-atlas-driver.js +8 -1
  64. package/src/plugins/cloud-inventory/drivers/vultr-driver.js +8 -1
  65. package/src/plugins/cloud-inventory/index.js +29 -8
  66. package/src/plugins/cloud-inventory/registry.js +64 -42
  67. package/src/plugins/cloud-inventory.plugin.js +240 -138
  68. package/src/plugins/concerns/plugin-dependencies.js +54 -0
  69. package/src/plugins/concerns/resource-names.js +100 -0
  70. package/src/plugins/consumers/index.js +10 -2
  71. package/src/plugins/consumers/sqs-consumer.js +12 -2
  72. package/src/plugins/cookie-farm-suite.plugin.js +278 -0
  73. package/src/plugins/cookie-farm.errors.js +73 -0
  74. package/src/plugins/cookie-farm.plugin.js +869 -0
  75. package/src/plugins/costs.plugin.js +7 -1
  76. package/src/plugins/eventual-consistency/analytics.js +94 -19
  77. package/src/plugins/eventual-consistency/config.js +15 -7
  78. package/src/plugins/eventual-consistency/consolidation.js +29 -11
  79. package/src/plugins/eventual-consistency/garbage-collection.js +3 -1
  80. package/src/plugins/eventual-consistency/helpers.js +39 -14
  81. package/src/plugins/eventual-consistency/install.js +21 -2
  82. package/src/plugins/eventual-consistency/utils.js +32 -10
  83. package/src/plugins/fulltext.plugin.js +38 -11
  84. package/src/plugins/geo.plugin.js +61 -9
  85. package/src/plugins/identity/concerns/config.js +61 -0
  86. package/src/plugins/identity/concerns/mfa-manager.js +15 -2
  87. package/src/plugins/identity/concerns/rate-limit.js +124 -0
  88. package/src/plugins/identity/concerns/resource-schemas.js +9 -1
  89. package/src/plugins/identity/concerns/token-generator.js +29 -4
  90. package/src/plugins/identity/drivers/auth-driver.interface.js +76 -0
  91. package/src/plugins/identity/drivers/client-credentials-driver.js +127 -0
  92. package/src/plugins/identity/drivers/index.js +18 -0
  93. package/src/plugins/identity/drivers/password-driver.js +122 -0
  94. package/src/plugins/identity/email-service.js +17 -2
  95. package/src/plugins/identity/index.js +413 -69
  96. package/src/plugins/identity/oauth2-server.js +413 -30
  97. package/src/plugins/identity/oidc-discovery.js +16 -8
  98. package/src/plugins/identity/rsa-keys.js +115 -35
  99. package/src/plugins/identity/server.js +166 -45
  100. package/src/plugins/identity/session-manager.js +53 -7
  101. package/src/plugins/identity/ui/pages/mfa-verification.js +17 -15
  102. package/src/plugins/identity/ui/routes.js +363 -255
  103. package/src/plugins/importer/index.js +153 -20
  104. package/src/plugins/index.js +9 -2
  105. package/src/plugins/kubernetes-inventory/index.js +6 -0
  106. package/src/plugins/kubernetes-inventory/k8s-driver.js +867 -0
  107. package/src/plugins/kubernetes-inventory/resource-types.js +274 -0
  108. package/src/plugins/kubernetes-inventory.plugin.js +980 -0
  109. package/src/plugins/metrics.plugin.js +64 -16
  110. package/src/plugins/ml/base-model.class.js +25 -15
  111. package/src/plugins/ml/regression-model.class.js +1 -1
  112. package/src/plugins/ml.errors.js +57 -25
  113. package/src/plugins/ml.plugin.js +28 -4
  114. package/src/plugins/namespace.js +210 -0
  115. package/src/plugins/plugin.class.js +180 -8
  116. package/src/plugins/puppeteer/console-monitor.js +729 -0
  117. package/src/plugins/puppeteer/cookie-manager.js +492 -0
  118. package/src/plugins/puppeteer/network-monitor.js +816 -0
  119. package/src/plugins/puppeteer/performance-manager.js +746 -0
  120. package/src/plugins/puppeteer/proxy-manager.js +478 -0
  121. package/src/plugins/puppeteer/stealth-manager.js +556 -0
  122. package/src/plugins/puppeteer.errors.js +81 -0
  123. package/src/plugins/puppeteer.plugin.js +1327 -0
  124. package/src/plugins/queue-consumer.plugin.js +69 -14
  125. package/src/plugins/recon/behaviors/uptime-behavior.js +691 -0
  126. package/src/plugins/recon/concerns/command-runner.js +148 -0
  127. package/src/plugins/recon/concerns/diff-detector.js +372 -0
  128. package/src/plugins/recon/concerns/fingerprint-builder.js +307 -0
  129. package/src/plugins/recon/concerns/process-manager.js +338 -0
  130. package/src/plugins/recon/concerns/report-generator.js +478 -0
  131. package/src/plugins/recon/concerns/security-analyzer.js +571 -0
  132. package/src/plugins/recon/concerns/target-normalizer.js +68 -0
  133. package/src/plugins/recon/config/defaults.js +321 -0
  134. package/src/plugins/recon/config/resources.js +370 -0
  135. package/src/plugins/recon/index.js +778 -0
  136. package/src/plugins/recon/managers/dependency-manager.js +174 -0
  137. package/src/plugins/recon/managers/scheduler-manager.js +179 -0
  138. package/src/plugins/recon/managers/storage-manager.js +745 -0
  139. package/src/plugins/recon/managers/target-manager.js +274 -0
  140. package/src/plugins/recon/stages/asn-stage.js +314 -0
  141. package/src/plugins/recon/stages/certificate-stage.js +84 -0
  142. package/src/plugins/recon/stages/dns-stage.js +107 -0
  143. package/src/plugins/recon/stages/dnsdumpster-stage.js +362 -0
  144. package/src/plugins/recon/stages/fingerprint-stage.js +71 -0
  145. package/src/plugins/recon/stages/google-dorks-stage.js +440 -0
  146. package/src/plugins/recon/stages/http-stage.js +89 -0
  147. package/src/plugins/recon/stages/latency-stage.js +148 -0
  148. package/src/plugins/recon/stages/massdns-stage.js +302 -0
  149. package/src/plugins/recon/stages/osint-stage.js +1373 -0
  150. package/src/plugins/recon/stages/ports-stage.js +169 -0
  151. package/src/plugins/recon/stages/screenshot-stage.js +94 -0
  152. package/src/plugins/recon/stages/secrets-stage.js +514 -0
  153. package/src/plugins/recon/stages/subdomains-stage.js +295 -0
  154. package/src/plugins/recon/stages/tls-audit-stage.js +78 -0
  155. package/src/plugins/recon/stages/vulnerability-stage.js +78 -0
  156. package/src/plugins/recon/stages/web-discovery-stage.js +113 -0
  157. package/src/plugins/recon/stages/whois-stage.js +349 -0
  158. package/src/plugins/recon.plugin.js +75 -0
  159. package/src/plugins/recon.plugin.js.backup +2635 -0
  160. package/src/plugins/relation.errors.js +87 -14
  161. package/src/plugins/replicator.plugin.js +514 -137
  162. package/src/plugins/replicators/base-replicator.class.js +89 -1
  163. package/src/plugins/replicators/bigquery-replicator.class.js +66 -22
  164. package/src/plugins/replicators/dynamodb-replicator.class.js +22 -15
  165. package/src/plugins/replicators/mongodb-replicator.class.js +22 -15
  166. package/src/plugins/replicators/mysql-replicator.class.js +52 -17
  167. package/src/plugins/replicators/planetscale-replicator.class.js +30 -4
  168. package/src/plugins/replicators/postgres-replicator.class.js +62 -27
  169. package/src/plugins/replicators/s3db-replicator.class.js +25 -18
  170. package/src/plugins/replicators/schema-sync.helper.js +3 -3
  171. package/src/plugins/replicators/sqs-replicator.class.js +8 -2
  172. package/src/plugins/replicators/turso-replicator.class.js +23 -3
  173. package/src/plugins/replicators/webhook-replicator.class.js +42 -4
  174. package/src/plugins/s3-queue.plugin.js +464 -65
  175. package/src/plugins/scheduler.plugin.js +20 -6
  176. package/src/plugins/state-machine.plugin.js +40 -9
  177. package/src/plugins/tfstate/base-driver.js +28 -4
  178. package/src/plugins/tfstate/errors.js +65 -10
  179. package/src/plugins/tfstate/filesystem-driver.js +52 -8
  180. package/src/plugins/tfstate/index.js +163 -90
  181. package/src/plugins/tfstate/s3-driver.js +64 -6
  182. package/src/plugins/ttl.plugin.js +72 -17
  183. package/src/plugins/vector/distances.js +18 -12
  184. package/src/plugins/vector/kmeans.js +26 -4
  185. package/src/resource.class.js +115 -19
  186. package/src/testing/factory.class.js +20 -3
  187. package/src/testing/seeder.class.js +7 -1
  188. package/src/clients/memory-client.md +0 -917
  189. package/src/plugins/cloud-inventory/drivers/mock-drivers.js +0 -449
@@ -1,5 +1,8 @@
1
1
  import EventEmitter from "events";
2
2
  import { PluginStorage } from "../concerns/plugin-storage.js";
3
+ import { FilesystemStorageDriver } from "../concerns/storage-drivers/filesystem-driver.js";
4
+ import { PluginError } from "../errors.js";
5
+ import { listPluginNamespaces } from "./namespace.js";
3
6
 
4
7
  export class Plugin extends EventEmitter {
5
8
  constructor(options = {}) {
@@ -10,10 +13,20 @@ export class Plugin extends EventEmitter {
10
13
 
11
14
  // Auto-generate slug from class name (CamelCase -> kebab-case)
12
15
  // e.g., EventualConsistencyPlugin -> eventual-consistency-plugin
13
- this.slug = options.slug || this._generateSlug();
16
+ this.baseSlug = options.slug || this._generateSlug();
17
+ this.slug = this.baseSlug;
14
18
 
15
19
  // Storage instance (lazy-loaded)
16
20
  this._storage = null;
21
+
22
+ // Multi-instance & namespacing
23
+ this.instanceName = null;
24
+ this.namespace = null;
25
+ this._namespaceExplicit = false;
26
+
27
+ if (options.namespace || options.instanceId) {
28
+ this.setNamespace(options.namespace || options.instanceId, { explicit: true });
29
+ }
17
30
  }
18
31
 
19
32
  /**
@@ -29,19 +42,166 @@ export class Plugin extends EventEmitter {
29
42
  }
30
43
 
31
44
  /**
32
- * Get PluginStorage instance (lazy-loaded)
33
- * @returns {PluginStorage}
45
+ * Normalize namespace into kebab-case
46
+ * @private
47
+ */
48
+ _normalizeNamespace(value) {
49
+ if (value === null || value === undefined) return null;
50
+ const text = String(value).trim();
51
+ if (!text) return null;
52
+ return text
53
+ .toLowerCase()
54
+ .replace(/[^a-z0-9]+/g, '-')
55
+ .replace(/^-+/, '')
56
+ .replace(/-+$/, '') || null;
57
+ }
58
+
59
+ /**
60
+ * Update plugin namespace (affects storage slug & helpers)
61
+ * @param {string|null} value
62
+ * @param {Object} options
63
+ * @param {boolean} options.explicit - Whether namespace was set explicitly by the user
64
+ */
65
+ setNamespace(value, { explicit = false } = {}) {
66
+ const normalized = this._normalizeNamespace(value);
67
+
68
+ if (!normalized) {
69
+ if (explicit) {
70
+ this.namespace = null;
71
+ this.slug = this.baseSlug;
72
+ this._namespaceExplicit = true;
73
+ this._storage = null;
74
+ if (typeof this.onNamespaceChanged === 'function') {
75
+ this.onNamespaceChanged(this.namespace);
76
+ }
77
+ }
78
+ return;
79
+ }
80
+
81
+ if (this.namespace === normalized && (explicit === false || this._namespaceExplicit)) {
82
+ return;
83
+ }
84
+
85
+ this.namespace = normalized;
86
+ if (explicit) {
87
+ this._namespaceExplicit = true;
88
+ }
89
+
90
+ this.slug = `${this.baseSlug}--${normalized}`;
91
+ this._storage = null; // Recreate storage with new slug on next access
92
+
93
+ if (typeof this.onNamespaceChanged === 'function') {
94
+ this.onNamespaceChanged(this.namespace);
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Set instance name (called by Database when registering the plugin)
100
+ * Automatically derives namespace when not explicitly provided.
101
+ */
102
+ setInstanceName(name) {
103
+ if (!name) return;
104
+ this.instanceName = name;
105
+
106
+ if (!this._namespaceExplicit) {
107
+ const normalized = this._normalizeNamespace(name);
108
+ if (normalized && normalized !== this.baseSlug) {
109
+ this.setNamespace(normalized);
110
+ }
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Hook for subclasses to react to namespace changes
116
+ * @param {string|null} namespace
117
+ */
118
+ // eslint-disable-next-line no-unused-vars
119
+ onNamespaceChanged(namespace) {
120
+ // Subclasses may override
121
+ }
122
+
123
+ /**
124
+ * Get storage instance (lazy-loaded)
125
+ * Supports both S3 and filesystem drivers based on options.storage configuration
126
+ * @returns {PluginStorage|FilesystemStorageDriver}
34
127
  */
35
128
  getStorage() {
36
129
  if (!this._storage) {
37
- if (!this.database || !this.database.client) {
38
- throw new Error('Plugin must be installed before accessing storage');
130
+ // Get storage configuration from options
131
+ const storageConfig = this.options.storage || {};
132
+ const driver = storageConfig.driver || 's3'; // Default to S3
133
+ const config = storageConfig.config || {};
134
+
135
+ if (driver === 'filesystem') {
136
+ // Use filesystem driver
137
+ this._storage = new FilesystemStorageDriver(config, this.slug);
138
+ } else if (driver === 's3') {
139
+ // Use S3-based PluginStorage (default)
140
+ if (!this.database || !this.database.client) {
141
+ throw new PluginError('Plugin storage unavailable until plugin is installed', {
142
+ pluginName: this.name,
143
+ operation: 'getStorage',
144
+ statusCode: 400,
145
+ retriable: false,
146
+ suggestion: 'Call db.installPlugin(new Plugin()) or ensure db.connect() completed before accessing storage.'
147
+ });
148
+ }
149
+ this._storage = new PluginStorage(this.database.client, this.slug);
150
+ } else {
151
+ throw new PluginError(`Unsupported storage driver: ${driver}`, {
152
+ pluginName: this.name,
153
+ operation: 'getStorage',
154
+ statusCode: 400,
155
+ retriable: false,
156
+ suggestion: 'Use "s3" or "filesystem" as storage driver'
157
+ });
39
158
  }
40
- this._storage = new PluginStorage(this.database.client, this.slug);
41
159
  }
42
160
  return this._storage;
43
161
  }
44
162
 
163
+ /**
164
+ * Detect and warn about existing namespaces
165
+ *
166
+ * Automatically called during install() if plugin uses namespaces.
167
+ * Scans storage to find existing namespaces and emits console warnings.
168
+ *
169
+ * @returns {Promise<string[]>} Array of detected namespaces
170
+ */
171
+ async detectAndWarnNamespaces() {
172
+ // Only run if plugin explicitly uses namespaces
173
+ if (!this._namespaceExplicit && !this.namespace) {
174
+ return [];
175
+ }
176
+
177
+ try {
178
+ // Get plugin prefix from slug (e.g., 'recon', 'scheduler', 'cache')
179
+ const pluginPrefix = this.baseSlug;
180
+ const currentNamespace = this.namespace || '';
181
+
182
+ // List existing namespaces in storage
183
+ const existingNamespaces = await listPluginNamespaces(
184
+ this.getStorage(),
185
+ pluginPrefix
186
+ );
187
+
188
+ // Emit console warnings (standardized format)
189
+ if (existingNamespaces.length > 0) {
190
+ console.warn(
191
+ `[${this.name}] Detected ${existingNamespaces.length} existing namespace(s): ${existingNamespaces.join(', ')}`
192
+ );
193
+ }
194
+
195
+ const namespaceDisplay = currentNamespace === '' ? '(none)' : `"${currentNamespace}"`;
196
+ console.warn(`[${this.name}] Using namespace: ${namespaceDisplay}`);
197
+
198
+ return existingNamespaces;
199
+ } catch (error) {
200
+ // Silently fail if storage is not available
201
+ return [];
202
+ }
203
+ }
204
+
45
205
  /**
46
206
  * Install plugin
47
207
  * @param {Database} database - Database instance
@@ -49,6 +209,10 @@ export class Plugin extends EventEmitter {
49
209
  async install(database) {
50
210
  this.database = database;
51
211
  this.beforeInstall();
212
+
213
+ // Auto-detect and warn about namespaces if plugin uses them
214
+ await this.detectAndWarnNamespaces();
215
+
52
216
  await this.onInstall();
53
217
  this.afterInstall();
54
218
  }
@@ -178,7 +342,15 @@ export class Plugin extends EventEmitter {
178
342
  addMiddleware(resource, methodName, middleware) {
179
343
  // Safety check: verify method exists
180
344
  if (typeof resource[methodName] !== 'function') {
181
- throw new Error(`Cannot add middleware to "${methodName}": method does not exist on resource "${resource.name || 'unknown'}"`);
345
+ throw new PluginError(`Cannot add middleware to "${methodName}"`, {
346
+ pluginName: this.name,
347
+ operation: 'addMiddleware',
348
+ statusCode: 400,
349
+ retriable: false,
350
+ suggestion: 'Ensure the resource exposes the method before registering middleware.',
351
+ resourceName: resource.name || 'unknown',
352
+ methodName
353
+ });
182
354
  }
183
355
 
184
356
  if (!resource._pluginMiddlewares) {
@@ -280,4 +452,4 @@ export class Plugin extends EventEmitter {
280
452
  afterUninstall() {
281
453
  this.emit("plugin.afterUninstall", new Date());
282
454
  }
283
- }
455
+ }