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.
- package/README.md +139 -43
- package/dist/s3db.cjs +72425 -38970
- package/dist/s3db.cjs.map +1 -1
- package/dist/s3db.es.js +72177 -38764
- package/dist/s3db.es.js.map +1 -1
- package/mcp/lib/base-handler.js +157 -0
- package/mcp/lib/handlers/connection-handler.js +280 -0
- package/mcp/lib/handlers/query-handler.js +533 -0
- package/mcp/lib/handlers/resource-handler.js +428 -0
- package/mcp/lib/tool-registry.js +336 -0
- package/mcp/lib/tools/connection-tools.js +161 -0
- package/mcp/lib/tools/query-tools.js +267 -0
- package/mcp/lib/tools/resource-tools.js +404 -0
- package/package.json +94 -49
- package/src/clients/memory-client.class.js +346 -191
- package/src/clients/memory-storage.class.js +300 -84
- package/src/clients/s3-client.class.js +7 -6
- package/src/concerns/geo-encoding.js +19 -2
- package/src/concerns/ip.js +59 -9
- package/src/concerns/money.js +8 -1
- package/src/concerns/password-hashing.js +49 -8
- package/src/concerns/plugin-storage.js +186 -18
- package/src/concerns/storage-drivers/filesystem-driver.js +284 -0
- package/src/database.class.js +139 -29
- package/src/errors.js +332 -42
- package/src/plugins/api/auth/oidc-auth.js +66 -17
- package/src/plugins/api/auth/strategies/base-strategy.class.js +74 -0
- package/src/plugins/api/auth/strategies/factory.class.js +63 -0
- package/src/plugins/api/auth/strategies/global-strategy.class.js +44 -0
- package/src/plugins/api/auth/strategies/path-based-strategy.class.js +83 -0
- package/src/plugins/api/auth/strategies/path-rules-strategy.class.js +118 -0
- package/src/plugins/api/concerns/failban-manager.js +106 -57
- package/src/plugins/api/concerns/opengraph-helper.js +116 -0
- package/src/plugins/api/concerns/route-context.js +601 -0
- package/src/plugins/api/concerns/state-machine.js +288 -0
- package/src/plugins/api/index.js +180 -41
- package/src/plugins/api/routes/auth-routes.js +198 -30
- package/src/plugins/api/routes/resource-routes.js +19 -4
- package/src/plugins/api/server/health-manager.class.js +163 -0
- package/src/plugins/api/server/middleware-chain.class.js +310 -0
- package/src/plugins/api/server/router.class.js +472 -0
- package/src/plugins/api/server.js +280 -1303
- package/src/plugins/api/utils/custom-routes.js +17 -5
- package/src/plugins/api/utils/guards.js +76 -17
- package/src/plugins/api/utils/openapi-generator-cached.class.js +133 -0
- package/src/plugins/api/utils/openapi-generator.js +7 -6
- package/src/plugins/api/utils/template-engine.js +77 -3
- package/src/plugins/audit.plugin.js +30 -8
- package/src/plugins/backup.plugin.js +110 -14
- package/src/plugins/cache/cache.class.js +22 -5
- package/src/plugins/cache/filesystem-cache.class.js +116 -19
- package/src/plugins/cache/memory-cache.class.js +211 -57
- package/src/plugins/cache/multi-tier-cache.class.js +371 -0
- package/src/plugins/cache/partition-aware-filesystem-cache.class.js +168 -47
- package/src/plugins/cache/redis-cache.class.js +552 -0
- package/src/plugins/cache/s3-cache.class.js +17 -8
- package/src/plugins/cache.plugin.js +176 -61
- package/src/plugins/cloud-inventory/drivers/alibaba-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/aws-driver.js +60 -29
- package/src/plugins/cloud-inventory/drivers/azure-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/base-driver.js +16 -2
- package/src/plugins/cloud-inventory/drivers/cloudflare-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/digitalocean-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/hetzner-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/linode-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/mongodb-atlas-driver.js +8 -1
- package/src/plugins/cloud-inventory/drivers/vultr-driver.js +8 -1
- package/src/plugins/cloud-inventory/index.js +29 -8
- package/src/plugins/cloud-inventory/registry.js +64 -42
- package/src/plugins/cloud-inventory.plugin.js +240 -138
- package/src/plugins/concerns/plugin-dependencies.js +54 -0
- package/src/plugins/concerns/resource-names.js +100 -0
- package/src/plugins/consumers/index.js +10 -2
- package/src/plugins/consumers/sqs-consumer.js +12 -2
- package/src/plugins/cookie-farm-suite.plugin.js +278 -0
- package/src/plugins/cookie-farm.errors.js +73 -0
- package/src/plugins/cookie-farm.plugin.js +869 -0
- package/src/plugins/costs.plugin.js +7 -1
- package/src/plugins/eventual-consistency/analytics.js +94 -19
- package/src/plugins/eventual-consistency/config.js +15 -7
- package/src/plugins/eventual-consistency/consolidation.js +29 -11
- package/src/plugins/eventual-consistency/garbage-collection.js +3 -1
- package/src/plugins/eventual-consistency/helpers.js +39 -14
- package/src/plugins/eventual-consistency/install.js +21 -2
- package/src/plugins/eventual-consistency/utils.js +32 -10
- package/src/plugins/fulltext.plugin.js +38 -11
- package/src/plugins/geo.plugin.js +61 -9
- package/src/plugins/identity/concerns/config.js +61 -0
- package/src/plugins/identity/concerns/mfa-manager.js +15 -2
- package/src/plugins/identity/concerns/rate-limit.js +124 -0
- package/src/plugins/identity/concerns/resource-schemas.js +9 -1
- package/src/plugins/identity/concerns/token-generator.js +29 -4
- package/src/plugins/identity/drivers/auth-driver.interface.js +76 -0
- package/src/plugins/identity/drivers/client-credentials-driver.js +127 -0
- package/src/plugins/identity/drivers/index.js +18 -0
- package/src/plugins/identity/drivers/password-driver.js +122 -0
- package/src/plugins/identity/email-service.js +17 -2
- package/src/plugins/identity/index.js +413 -69
- package/src/plugins/identity/oauth2-server.js +413 -30
- package/src/plugins/identity/oidc-discovery.js +16 -8
- package/src/plugins/identity/rsa-keys.js +115 -35
- package/src/plugins/identity/server.js +166 -45
- package/src/plugins/identity/session-manager.js +53 -7
- package/src/plugins/identity/ui/pages/mfa-verification.js +17 -15
- package/src/plugins/identity/ui/routes.js +363 -255
- package/src/plugins/importer/index.js +153 -20
- package/src/plugins/index.js +9 -2
- package/src/plugins/kubernetes-inventory/index.js +6 -0
- package/src/plugins/kubernetes-inventory/k8s-driver.js +867 -0
- package/src/plugins/kubernetes-inventory/resource-types.js +274 -0
- package/src/plugins/kubernetes-inventory.plugin.js +980 -0
- package/src/plugins/metrics.plugin.js +64 -16
- package/src/plugins/ml/base-model.class.js +25 -15
- package/src/plugins/ml/regression-model.class.js +1 -1
- package/src/plugins/ml.errors.js +57 -25
- package/src/plugins/ml.plugin.js +28 -4
- package/src/plugins/namespace.js +210 -0
- package/src/plugins/plugin.class.js +180 -8
- package/src/plugins/puppeteer/console-monitor.js +729 -0
- package/src/plugins/puppeteer/cookie-manager.js +492 -0
- package/src/plugins/puppeteer/network-monitor.js +816 -0
- package/src/plugins/puppeteer/performance-manager.js +746 -0
- package/src/plugins/puppeteer/proxy-manager.js +478 -0
- package/src/plugins/puppeteer/stealth-manager.js +556 -0
- package/src/plugins/puppeteer.errors.js +81 -0
- package/src/plugins/puppeteer.plugin.js +1327 -0
- package/src/plugins/queue-consumer.plugin.js +69 -14
- package/src/plugins/recon/behaviors/uptime-behavior.js +691 -0
- package/src/plugins/recon/concerns/command-runner.js +148 -0
- package/src/plugins/recon/concerns/diff-detector.js +372 -0
- package/src/plugins/recon/concerns/fingerprint-builder.js +307 -0
- package/src/plugins/recon/concerns/process-manager.js +338 -0
- package/src/plugins/recon/concerns/report-generator.js +478 -0
- package/src/plugins/recon/concerns/security-analyzer.js +571 -0
- package/src/plugins/recon/concerns/target-normalizer.js +68 -0
- package/src/plugins/recon/config/defaults.js +321 -0
- package/src/plugins/recon/config/resources.js +370 -0
- package/src/plugins/recon/index.js +778 -0
- package/src/plugins/recon/managers/dependency-manager.js +174 -0
- package/src/plugins/recon/managers/scheduler-manager.js +179 -0
- package/src/plugins/recon/managers/storage-manager.js +745 -0
- package/src/plugins/recon/managers/target-manager.js +274 -0
- package/src/plugins/recon/stages/asn-stage.js +314 -0
- package/src/plugins/recon/stages/certificate-stage.js +84 -0
- package/src/plugins/recon/stages/dns-stage.js +107 -0
- package/src/plugins/recon/stages/dnsdumpster-stage.js +362 -0
- package/src/plugins/recon/stages/fingerprint-stage.js +71 -0
- package/src/plugins/recon/stages/google-dorks-stage.js +440 -0
- package/src/plugins/recon/stages/http-stage.js +89 -0
- package/src/plugins/recon/stages/latency-stage.js +148 -0
- package/src/plugins/recon/stages/massdns-stage.js +302 -0
- package/src/plugins/recon/stages/osint-stage.js +1373 -0
- package/src/plugins/recon/stages/ports-stage.js +169 -0
- package/src/plugins/recon/stages/screenshot-stage.js +94 -0
- package/src/plugins/recon/stages/secrets-stage.js +514 -0
- package/src/plugins/recon/stages/subdomains-stage.js +295 -0
- package/src/plugins/recon/stages/tls-audit-stage.js +78 -0
- package/src/plugins/recon/stages/vulnerability-stage.js +78 -0
- package/src/plugins/recon/stages/web-discovery-stage.js +113 -0
- package/src/plugins/recon/stages/whois-stage.js +349 -0
- package/src/plugins/recon.plugin.js +75 -0
- package/src/plugins/recon.plugin.js.backup +2635 -0
- package/src/plugins/relation.errors.js +87 -14
- package/src/plugins/replicator.plugin.js +514 -137
- package/src/plugins/replicators/base-replicator.class.js +89 -1
- package/src/plugins/replicators/bigquery-replicator.class.js +66 -22
- package/src/plugins/replicators/dynamodb-replicator.class.js +22 -15
- package/src/plugins/replicators/mongodb-replicator.class.js +22 -15
- package/src/plugins/replicators/mysql-replicator.class.js +52 -17
- package/src/plugins/replicators/planetscale-replicator.class.js +30 -4
- package/src/plugins/replicators/postgres-replicator.class.js +62 -27
- package/src/plugins/replicators/s3db-replicator.class.js +25 -18
- package/src/plugins/replicators/schema-sync.helper.js +3 -3
- package/src/plugins/replicators/sqs-replicator.class.js +8 -2
- package/src/plugins/replicators/turso-replicator.class.js +23 -3
- package/src/plugins/replicators/webhook-replicator.class.js +42 -4
- package/src/plugins/s3-queue.plugin.js +464 -65
- package/src/plugins/scheduler.plugin.js +20 -6
- package/src/plugins/state-machine.plugin.js +40 -9
- package/src/plugins/tfstate/README.md +126 -126
- package/src/plugins/tfstate/base-driver.js +28 -4
- package/src/plugins/tfstate/errors.js +65 -10
- package/src/plugins/tfstate/filesystem-driver.js +52 -8
- package/src/plugins/tfstate/index.js +163 -90
- package/src/plugins/tfstate/s3-driver.js +64 -6
- package/src/plugins/ttl.plugin.js +72 -17
- package/src/plugins/vector/distances.js +18 -12
- package/src/plugins/vector/kmeans.js +26 -4
- package/src/resource.class.js +115 -19
- package/src/testing/factory.class.js +20 -3
- package/src/testing/seeder.class.js +7 -1
- package/src/clients/memory-client.md +0 -917
- package/src/plugins/cloud-inventory/drivers/mock-drivers.js +0 -449
package/src/errors.js
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
export class BaseError extends Error {
|
|
2
|
-
constructor({
|
|
2
|
+
constructor({
|
|
3
|
+
verbose,
|
|
4
|
+
bucket,
|
|
5
|
+
key,
|
|
6
|
+
message,
|
|
7
|
+
code,
|
|
8
|
+
statusCode,
|
|
9
|
+
requestId,
|
|
10
|
+
awsMessage,
|
|
11
|
+
original,
|
|
12
|
+
commandName,
|
|
13
|
+
commandInput,
|
|
14
|
+
metadata,
|
|
15
|
+
description,
|
|
16
|
+
suggestion,
|
|
17
|
+
retriable,
|
|
18
|
+
docs,
|
|
19
|
+
title,
|
|
20
|
+
hint,
|
|
21
|
+
...rest
|
|
22
|
+
}) {
|
|
3
23
|
if (verbose) message = message + `\n\nVerbose:\n\n${JSON.stringify(rest, null, 2)}`;
|
|
4
24
|
super(message);
|
|
5
25
|
|
|
@@ -15,7 +35,7 @@ export class BaseError extends Error {
|
|
|
15
35
|
this.key = key;
|
|
16
36
|
this.thrownAt = new Date();
|
|
17
37
|
this.code = code;
|
|
18
|
-
this.statusCode = statusCode;
|
|
38
|
+
this.statusCode = statusCode ?? 500;
|
|
19
39
|
this.requestId = requestId;
|
|
20
40
|
this.awsMessage = awsMessage;
|
|
21
41
|
this.original = original;
|
|
@@ -23,7 +43,23 @@ export class BaseError extends Error {
|
|
|
23
43
|
this.commandInput = commandInput;
|
|
24
44
|
this.metadata = metadata;
|
|
25
45
|
this.description = description;
|
|
26
|
-
this.
|
|
46
|
+
this.suggestion = suggestion;
|
|
47
|
+
this.retriable = retriable ?? false;
|
|
48
|
+
this.docs = docs;
|
|
49
|
+
this.title = title || this.constructor.name;
|
|
50
|
+
this.hint = hint;
|
|
51
|
+
this.data = {
|
|
52
|
+
bucket,
|
|
53
|
+
key,
|
|
54
|
+
...rest,
|
|
55
|
+
verbose,
|
|
56
|
+
message,
|
|
57
|
+
suggestion: this.suggestion,
|
|
58
|
+
retriable: this.retriable,
|
|
59
|
+
docs: this.docs,
|
|
60
|
+
title: this.title,
|
|
61
|
+
hint: this.hint
|
|
62
|
+
};
|
|
27
63
|
}
|
|
28
64
|
|
|
29
65
|
toJson() {
|
|
@@ -37,6 +73,11 @@ export class BaseError extends Error {
|
|
|
37
73
|
bucket: this.bucket,
|
|
38
74
|
key: this.key,
|
|
39
75
|
thrownAt: this.thrownAt,
|
|
76
|
+
retriable: this.retriable,
|
|
77
|
+
suggestion: this.suggestion,
|
|
78
|
+
docs: this.docs,
|
|
79
|
+
title: this.title,
|
|
80
|
+
hint: this.hint,
|
|
40
81
|
commandName: this.commandName,
|
|
41
82
|
commandInput: this.commandInput,
|
|
42
83
|
metadata: this.metadata,
|
|
@@ -72,54 +113,108 @@ export class S3dbError extends BaseError {
|
|
|
72
113
|
// Database operation errors
|
|
73
114
|
export class DatabaseError extends S3dbError {
|
|
74
115
|
constructor(message, details = {}) {
|
|
75
|
-
|
|
76
|
-
|
|
116
|
+
const merged = {
|
|
117
|
+
statusCode: details.statusCode ?? 500,
|
|
118
|
+
retriable: details.retriable ?? false,
|
|
119
|
+
suggestion: details.suggestion ?? 'Check database configuration and ensure the operation parameters are valid.',
|
|
120
|
+
...details
|
|
121
|
+
};
|
|
122
|
+
super(message, merged);
|
|
123
|
+
Object.assign(this, merged);
|
|
77
124
|
}
|
|
78
125
|
}
|
|
79
126
|
|
|
80
127
|
// Validation errors
|
|
81
128
|
export class ValidationError extends S3dbError {
|
|
82
129
|
constructor(message, details = {}) {
|
|
83
|
-
|
|
84
|
-
|
|
130
|
+
const merged = {
|
|
131
|
+
statusCode: details.statusCode ?? 422,
|
|
132
|
+
retriable: details.retriable ?? false,
|
|
133
|
+
suggestion: details.suggestion ?? 'Review validation errors and adjust the request payload before retrying.',
|
|
134
|
+
...details
|
|
135
|
+
};
|
|
136
|
+
super(message, merged);
|
|
137
|
+
Object.assign(this, merged);
|
|
85
138
|
}
|
|
86
139
|
}
|
|
87
140
|
|
|
88
141
|
// Authentication errors
|
|
89
142
|
export class AuthenticationError extends S3dbError {
|
|
90
143
|
constructor(message, details = {}) {
|
|
91
|
-
|
|
92
|
-
|
|
144
|
+
const merged = {
|
|
145
|
+
statusCode: details.statusCode ?? 401,
|
|
146
|
+
retriable: details.retriable ?? false,
|
|
147
|
+
suggestion: details.suggestion ?? 'Provide valid authentication credentials and try again.',
|
|
148
|
+
...details
|
|
149
|
+
};
|
|
150
|
+
super(message, merged);
|
|
151
|
+
Object.assign(this, merged);
|
|
93
152
|
}
|
|
94
153
|
}
|
|
95
154
|
|
|
96
155
|
// Permission/Authorization errors
|
|
97
156
|
export class PermissionError extends S3dbError {
|
|
98
157
|
constructor(message, details = {}) {
|
|
99
|
-
|
|
100
|
-
|
|
158
|
+
const merged = {
|
|
159
|
+
statusCode: details.statusCode ?? 403,
|
|
160
|
+
retriable: details.retriable ?? false,
|
|
161
|
+
suggestion: details.suggestion ?? 'Verify IAM permissions, bucket policies, and credentials before retrying.',
|
|
162
|
+
...details
|
|
163
|
+
};
|
|
164
|
+
super(message, merged);
|
|
165
|
+
Object.assign(this, merged);
|
|
101
166
|
}
|
|
102
167
|
}
|
|
103
168
|
|
|
104
169
|
// Encryption errors
|
|
105
170
|
export class EncryptionError extends S3dbError {
|
|
106
171
|
constructor(message, details = {}) {
|
|
107
|
-
|
|
108
|
-
|
|
172
|
+
const merged = {
|
|
173
|
+
statusCode: details.statusCode ?? 500,
|
|
174
|
+
retriable: details.retriable ?? false,
|
|
175
|
+
suggestion: details.suggestion ?? 'Check encryption keys and inputs. This error generally requires code/config changes before retrying.',
|
|
176
|
+
...details
|
|
177
|
+
};
|
|
178
|
+
super(message, merged);
|
|
179
|
+
Object.assign(this, merged);
|
|
109
180
|
}
|
|
110
181
|
}
|
|
111
182
|
|
|
112
183
|
// Resource not found error
|
|
113
184
|
export class ResourceNotFound extends S3dbError {
|
|
114
185
|
constructor({ bucket, resourceName, id, original, ...rest }) {
|
|
115
|
-
if (typeof id !== 'string')
|
|
116
|
-
|
|
117
|
-
|
|
186
|
+
if (typeof id !== 'string') {
|
|
187
|
+
throw new ValidationError('ResourceNotFound requires id to be a string', {
|
|
188
|
+
field: 'id',
|
|
189
|
+
value: id,
|
|
190
|
+
retriable: false,
|
|
191
|
+
suggestion: 'Provide the resource id as a string when constructing ResourceNotFound.'
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
if (typeof bucket !== 'string') {
|
|
195
|
+
throw new ValidationError('ResourceNotFound requires bucket to be a string', {
|
|
196
|
+
field: 'bucket',
|
|
197
|
+
value: bucket,
|
|
198
|
+
retriable: false,
|
|
199
|
+
suggestion: 'Provide the bucket name as a string when constructing ResourceNotFound.'
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (typeof resourceName !== 'string') {
|
|
203
|
+
throw new ValidationError('ResourceNotFound requires resourceName to be a string', {
|
|
204
|
+
field: 'resourceName',
|
|
205
|
+
value: resourceName,
|
|
206
|
+
retriable: false,
|
|
207
|
+
suggestion: 'Provide the resource name as a string when constructing ResourceNotFound.'
|
|
208
|
+
});
|
|
209
|
+
}
|
|
118
210
|
super(`Resource not found: ${resourceName}/${id} [bucket:${bucket}]`, {
|
|
119
211
|
bucket,
|
|
120
212
|
resourceName,
|
|
121
213
|
id,
|
|
122
214
|
original,
|
|
215
|
+
statusCode: rest.statusCode ?? 404,
|
|
216
|
+
retriable: rest.retriable ?? false,
|
|
217
|
+
suggestion: rest.suggestion ?? 'Confirm the resource ID and ensure it exists before retrying.',
|
|
123
218
|
...rest
|
|
124
219
|
});
|
|
125
220
|
}
|
|
@@ -127,17 +222,62 @@ export class ResourceNotFound extends S3dbError {
|
|
|
127
222
|
|
|
128
223
|
export class NoSuchBucket extends S3dbError {
|
|
129
224
|
constructor({ bucket, original, ...rest }) {
|
|
130
|
-
if (typeof bucket !== 'string')
|
|
131
|
-
|
|
225
|
+
if (typeof bucket !== 'string') {
|
|
226
|
+
throw new ValidationError('NoSuchBucket requires bucket to be a string', {
|
|
227
|
+
field: 'bucket',
|
|
228
|
+
value: bucket,
|
|
229
|
+
retriable: false,
|
|
230
|
+
suggestion: 'Provide the bucket name as a string when constructing NoSuchBucket.'
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
super(`Bucket does not exists [bucket:${bucket}]`, {
|
|
234
|
+
bucket,
|
|
235
|
+
original,
|
|
236
|
+
statusCode: rest.statusCode ?? 404,
|
|
237
|
+
retriable: rest.retriable ?? false,
|
|
238
|
+
suggestion: rest.suggestion ?? 'Verify the bucket name and AWS region. Create the bucket if it is missing.',
|
|
239
|
+
...rest
|
|
240
|
+
});
|
|
132
241
|
}
|
|
133
242
|
}
|
|
134
243
|
|
|
135
244
|
export class NoSuchKey extends S3dbError {
|
|
136
245
|
constructor({ bucket, key, resourceName, id, original, ...rest }) {
|
|
137
|
-
if (typeof key !== 'string')
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
246
|
+
if (typeof key !== 'string') {
|
|
247
|
+
throw new ValidationError('NoSuchKey requires key to be a string', {
|
|
248
|
+
field: 'key',
|
|
249
|
+
value: key,
|
|
250
|
+
retriable: false,
|
|
251
|
+
suggestion: 'Provide the object key as a string when constructing NoSuchKey.'
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (typeof bucket !== 'string') {
|
|
255
|
+
throw new ValidationError('NoSuchKey requires bucket to be a string', {
|
|
256
|
+
field: 'bucket',
|
|
257
|
+
value: bucket,
|
|
258
|
+
retriable: false,
|
|
259
|
+
suggestion: 'Provide the bucket name as a string when constructing NoSuchKey.'
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
if (id !== undefined && typeof id !== 'string') {
|
|
263
|
+
throw new ValidationError('NoSuchKey requires id to be a string when provided', {
|
|
264
|
+
field: 'id',
|
|
265
|
+
value: id,
|
|
266
|
+
retriable: false,
|
|
267
|
+
suggestion: 'Provide the resource id as a string when including it in NoSuchKey.'
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
super(`No such key: ${key} [bucket:${bucket}]`, {
|
|
271
|
+
bucket,
|
|
272
|
+
key,
|
|
273
|
+
resourceName,
|
|
274
|
+
id,
|
|
275
|
+
original,
|
|
276
|
+
statusCode: rest.statusCode ?? 404,
|
|
277
|
+
retriable: rest.retriable ?? false,
|
|
278
|
+
suggestion: rest.suggestion ?? 'Check if the object key is correct and that the object was uploaded.',
|
|
279
|
+
...rest
|
|
280
|
+
});
|
|
141
281
|
this.resourceName = resourceName;
|
|
142
282
|
this.id = id;
|
|
143
283
|
}
|
|
@@ -145,9 +285,33 @@ export class NoSuchKey extends S3dbError {
|
|
|
145
285
|
|
|
146
286
|
export class NotFound extends S3dbError {
|
|
147
287
|
constructor({ bucket, key, resourceName, id, original, ...rest }) {
|
|
148
|
-
if (typeof key !== 'string')
|
|
149
|
-
|
|
150
|
-
|
|
288
|
+
if (typeof key !== 'string') {
|
|
289
|
+
throw new ValidationError('NotFound requires key to be a string', {
|
|
290
|
+
field: 'key',
|
|
291
|
+
value: key,
|
|
292
|
+
retriable: false,
|
|
293
|
+
suggestion: 'Provide the object key as a string when constructing NotFound.'
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
if (typeof bucket !== 'string') {
|
|
297
|
+
throw new ValidationError('NotFound requires bucket to be a string', {
|
|
298
|
+
field: 'bucket',
|
|
299
|
+
value: bucket,
|
|
300
|
+
retriable: false,
|
|
301
|
+
suggestion: 'Provide the bucket name as a string when constructing NotFound.'
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
super(`Not found: ${key} [bucket:${bucket}]`, {
|
|
305
|
+
bucket,
|
|
306
|
+
key,
|
|
307
|
+
resourceName,
|
|
308
|
+
id,
|
|
309
|
+
original,
|
|
310
|
+
statusCode: rest.statusCode ?? 404,
|
|
311
|
+
retriable: rest.retriable ?? false,
|
|
312
|
+
suggestion: rest.suggestion ?? 'Confirm the key and bucket. Upload the object if it is missing.',
|
|
313
|
+
...rest
|
|
314
|
+
});
|
|
151
315
|
this.resourceName = resourceName;
|
|
152
316
|
this.id = id;
|
|
153
317
|
}
|
|
@@ -155,8 +319,22 @@ export class NotFound extends S3dbError {
|
|
|
155
319
|
|
|
156
320
|
export class MissingMetadata extends S3dbError {
|
|
157
321
|
constructor({ bucket, original, ...rest }) {
|
|
158
|
-
if (typeof bucket !== 'string')
|
|
159
|
-
|
|
322
|
+
if (typeof bucket !== 'string') {
|
|
323
|
+
throw new ValidationError('MissingMetadata requires bucket to be a string', {
|
|
324
|
+
field: 'bucket',
|
|
325
|
+
value: bucket,
|
|
326
|
+
retriable: false,
|
|
327
|
+
suggestion: 'Provide the bucket name as a string when constructing MissingMetadata.'
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
super(`Missing metadata for bucket [bucket:${bucket}]`, {
|
|
331
|
+
bucket,
|
|
332
|
+
original,
|
|
333
|
+
statusCode: rest.statusCode ?? 500,
|
|
334
|
+
retriable: rest.retriable ?? false,
|
|
335
|
+
suggestion: rest.suggestion ?? 'Re-upload metadata or run db.uploadMetadataFile() to regenerate it.',
|
|
336
|
+
...rest
|
|
337
|
+
});
|
|
160
338
|
}
|
|
161
339
|
}
|
|
162
340
|
|
|
@@ -170,8 +348,22 @@ export class InvalidResourceItem extends S3dbError {
|
|
|
170
348
|
original,
|
|
171
349
|
...rest
|
|
172
350
|
}) {
|
|
173
|
-
if (typeof bucket !== 'string')
|
|
174
|
-
|
|
351
|
+
if (typeof bucket !== 'string') {
|
|
352
|
+
throw new ValidationError('InvalidResourceItem requires bucket to be a string', {
|
|
353
|
+
field: 'bucket',
|
|
354
|
+
value: bucket,
|
|
355
|
+
retriable: false,
|
|
356
|
+
suggestion: 'Provide the bucket name as a string when constructing InvalidResourceItem.'
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
if (typeof resourceName !== 'string') {
|
|
360
|
+
throw new ValidationError('InvalidResourceItem requires resourceName to be a string', {
|
|
361
|
+
field: 'resourceName',
|
|
362
|
+
value: resourceName,
|
|
363
|
+
retriable: false,
|
|
364
|
+
suggestion: 'Provide the resource name as a string when constructing InvalidResourceItem.'
|
|
365
|
+
});
|
|
366
|
+
}
|
|
175
367
|
super(
|
|
176
368
|
message || `Validation error: This item is not valid. Resource=${resourceName} [bucket:${bucket}].\n${JSON.stringify(validation, null, 2)}`,
|
|
177
369
|
{
|
|
@@ -180,6 +372,9 @@ export class InvalidResourceItem extends S3dbError {
|
|
|
180
372
|
attributes,
|
|
181
373
|
validation,
|
|
182
374
|
original,
|
|
375
|
+
statusCode: rest.statusCode ?? 422,
|
|
376
|
+
retriable: rest.retriable ?? false,
|
|
377
|
+
suggestion: rest.suggestion ?? 'Fix validation errors on the provided attributes before retrying the request.',
|
|
183
378
|
...rest
|
|
184
379
|
}
|
|
185
380
|
);
|
|
@@ -206,23 +401,63 @@ export function mapAwsError(err, context = {}) {
|
|
|
206
401
|
let description;
|
|
207
402
|
if (code === 'NoSuchKey' || code === 'NotFound') {
|
|
208
403
|
description = 'The specified key does not exist in the bucket. Check if the key exists and if your credentials have permission to access it.';
|
|
209
|
-
return new NoSuchKey({
|
|
404
|
+
return new NoSuchKey({
|
|
405
|
+
...context,
|
|
406
|
+
original: err,
|
|
407
|
+
metadata,
|
|
408
|
+
commandName,
|
|
409
|
+
commandInput,
|
|
410
|
+
description,
|
|
411
|
+
retriable: false
|
|
412
|
+
});
|
|
210
413
|
}
|
|
211
414
|
if (code === 'NoSuchBucket') {
|
|
212
415
|
description = 'The specified bucket does not exist. Check if the bucket name is correct and if your credentials have permission to access it.';
|
|
213
|
-
return new NoSuchBucket({
|
|
416
|
+
return new NoSuchBucket({
|
|
417
|
+
...context,
|
|
418
|
+
original: err,
|
|
419
|
+
metadata,
|
|
420
|
+
commandName,
|
|
421
|
+
commandInput,
|
|
422
|
+
description,
|
|
423
|
+
retriable: false
|
|
424
|
+
});
|
|
214
425
|
}
|
|
215
426
|
if (code === 'AccessDenied' || (err.statusCode === 403) || code === 'Forbidden') {
|
|
216
427
|
description = 'Access denied. Check your AWS credentials, IAM permissions, and bucket policy.';
|
|
217
|
-
return new PermissionError('Access denied', {
|
|
428
|
+
return new PermissionError('Access denied', {
|
|
429
|
+
...context,
|
|
430
|
+
original: err,
|
|
431
|
+
metadata,
|
|
432
|
+
commandName,
|
|
433
|
+
commandInput,
|
|
434
|
+
description,
|
|
435
|
+
retriable: false
|
|
436
|
+
});
|
|
218
437
|
}
|
|
219
438
|
if (code === 'ValidationError' || (err.statusCode === 400)) {
|
|
220
439
|
description = 'Validation error. Check the request parameters and payload format.';
|
|
221
|
-
return new ValidationError('Validation error', {
|
|
440
|
+
return new ValidationError('Validation error', {
|
|
441
|
+
...context,
|
|
442
|
+
original: err,
|
|
443
|
+
metadata,
|
|
444
|
+
commandName,
|
|
445
|
+
commandInput,
|
|
446
|
+
description,
|
|
447
|
+
retriable: false
|
|
448
|
+
});
|
|
222
449
|
}
|
|
223
450
|
if (code === 'MissingMetadata') {
|
|
224
451
|
description = 'Object metadata is missing or invalid. Check if the object was uploaded correctly.';
|
|
225
|
-
return new MissingMetadata({
|
|
452
|
+
return new MissingMetadata({
|
|
453
|
+
...context,
|
|
454
|
+
original: err,
|
|
455
|
+
metadata,
|
|
456
|
+
commandName,
|
|
457
|
+
commandInput,
|
|
458
|
+
description,
|
|
459
|
+
retriable: false
|
|
460
|
+
});
|
|
226
461
|
}
|
|
227
462
|
// Outros mapeamentos podem ser adicionados aqui
|
|
228
463
|
// Incluir detalhes do erro original para facilitar debug
|
|
@@ -234,35 +469,71 @@ export function mapAwsError(err, context = {}) {
|
|
|
234
469
|
].filter(Boolean).join(' | ');
|
|
235
470
|
|
|
236
471
|
description = `Check the error details and AWS documentation. Original error: ${err.message || err.toString()}`;
|
|
237
|
-
return new UnknownError(errorDetails, {
|
|
472
|
+
return new UnknownError(errorDetails, {
|
|
473
|
+
...context,
|
|
474
|
+
original: err,
|
|
475
|
+
metadata,
|
|
476
|
+
commandName,
|
|
477
|
+
commandInput,
|
|
478
|
+
description,
|
|
479
|
+
retriable: context.retriable ?? false
|
|
480
|
+
});
|
|
238
481
|
}
|
|
239
482
|
|
|
240
483
|
export class ConnectionStringError extends S3dbError {
|
|
241
484
|
constructor(message, details = {}) {
|
|
242
485
|
const description = details.description || 'Invalid connection string format. Check the connection string syntax and credentials.';
|
|
243
|
-
|
|
486
|
+
const merged = {
|
|
487
|
+
statusCode: details.statusCode ?? 400,
|
|
488
|
+
retriable: details.retriable ?? false,
|
|
489
|
+
suggestion: details.suggestion ?? 'Fix the connection string and retry the operation.',
|
|
490
|
+
description,
|
|
491
|
+
...details
|
|
492
|
+
};
|
|
493
|
+
super(message, merged);
|
|
244
494
|
}
|
|
245
495
|
}
|
|
246
496
|
|
|
247
497
|
export class CryptoError extends S3dbError {
|
|
248
498
|
constructor(message, details = {}) {
|
|
249
499
|
const description = details.description || 'Cryptography operation failed. Check if the crypto library is available and input is valid.';
|
|
250
|
-
|
|
500
|
+
const merged = {
|
|
501
|
+
statusCode: details.statusCode ?? 500,
|
|
502
|
+
retriable: details.retriable ?? false,
|
|
503
|
+
suggestion: details.suggestion ?? 'Validate crypto inputs and environment setup before retrying.',
|
|
504
|
+
description,
|
|
505
|
+
...details
|
|
506
|
+
};
|
|
507
|
+
super(message, merged);
|
|
251
508
|
}
|
|
252
509
|
}
|
|
253
510
|
|
|
254
511
|
export class SchemaError extends S3dbError {
|
|
255
512
|
constructor(message, details = {}) {
|
|
256
513
|
const description = details.description || 'Schema validation failed. Check schema definition and input data format.';
|
|
257
|
-
|
|
514
|
+
const merged = {
|
|
515
|
+
statusCode: details.statusCode ?? 400,
|
|
516
|
+
retriable: details.retriable ?? false,
|
|
517
|
+
suggestion: details.suggestion ?? 'Update the schema or adjust the data to match the schema definition.',
|
|
518
|
+
description,
|
|
519
|
+
...details
|
|
520
|
+
};
|
|
521
|
+
super(message, merged);
|
|
258
522
|
}
|
|
259
523
|
}
|
|
260
524
|
|
|
261
525
|
export class ResourceError extends S3dbError {
|
|
262
526
|
constructor(message, details = {}) {
|
|
263
527
|
const description = details.description || 'Resource operation failed. Check resource configuration, attributes, and operation context.';
|
|
264
|
-
|
|
265
|
-
|
|
528
|
+
const merged = {
|
|
529
|
+
statusCode: details.statusCode ?? 400,
|
|
530
|
+
retriable: details.retriable ?? false,
|
|
531
|
+
suggestion: details.suggestion ?? 'Review the resource configuration and request payload before retrying.',
|
|
532
|
+
description,
|
|
533
|
+
...details
|
|
534
|
+
};
|
|
535
|
+
super(message, merged);
|
|
536
|
+
Object.assign(this, merged);
|
|
266
537
|
}
|
|
267
538
|
}
|
|
268
539
|
|
|
@@ -300,6 +571,8 @@ Docs: https://github.com/forattini-dev/s3db.js/blob/main/docs/README.md#partitio
|
|
|
300
571
|
|
|
301
572
|
super(message, {
|
|
302
573
|
...details,
|
|
574
|
+
statusCode: details.statusCode ?? 400,
|
|
575
|
+
retriable: details.retriable ?? false,
|
|
303
576
|
description
|
|
304
577
|
});
|
|
305
578
|
}
|
|
@@ -374,6 +647,8 @@ Docs: https://github.com/forattini-dev/s3db.js/blob/main/docs/plugins/eventual-c
|
|
|
374
647
|
configuredResources,
|
|
375
648
|
registeredResources,
|
|
376
649
|
pluginInitialized,
|
|
650
|
+
statusCode: rest.statusCode ?? 400,
|
|
651
|
+
retriable: rest.retriable ?? false,
|
|
377
652
|
description
|
|
378
653
|
});
|
|
379
654
|
}
|
|
@@ -418,12 +693,17 @@ Docs: https://github.com/forattini-dev/s3db.js/blob/main/docs/plugins/README.md
|
|
|
418
693
|
`.trim();
|
|
419
694
|
}
|
|
420
695
|
|
|
421
|
-
|
|
696
|
+
const merged = {
|
|
422
697
|
...rest,
|
|
423
698
|
pluginName,
|
|
424
699
|
operation,
|
|
700
|
+
statusCode: rest.statusCode ?? 500,
|
|
701
|
+
retriable: rest.retriable ?? false,
|
|
425
702
|
description
|
|
426
|
-
}
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
super(message, merged);
|
|
706
|
+
Object.assign(this, merged);
|
|
427
707
|
}
|
|
428
708
|
}
|
|
429
709
|
|
|
@@ -464,6 +744,8 @@ Docs: https://github.com/forattini-dev/s3db.js/blob/main/docs/plugins/README.md#
|
|
|
464
744
|
pluginSlug,
|
|
465
745
|
key,
|
|
466
746
|
operation,
|
|
747
|
+
statusCode: rest.statusCode ?? 500,
|
|
748
|
+
retriable: rest.retriable ?? false,
|
|
467
749
|
description
|
|
468
750
|
});
|
|
469
751
|
}
|
|
@@ -516,6 +798,8 @@ Check driver configuration and permissions.
|
|
|
516
798
|
operation,
|
|
517
799
|
queueSize,
|
|
518
800
|
maxQueueSize,
|
|
801
|
+
statusCode: rest.statusCode ?? 503,
|
|
802
|
+
retriable: rest.retriable ?? (queueSize >= maxQueueSize),
|
|
519
803
|
description
|
|
520
804
|
});
|
|
521
805
|
}
|
|
@@ -553,6 +837,8 @@ Docs: https://github.com/forattini-dev/s3db.js/blob/main/docs/README.md#behavior
|
|
|
553
837
|
...rest,
|
|
554
838
|
behavior,
|
|
555
839
|
availableBehaviors,
|
|
840
|
+
statusCode: rest.statusCode ?? 400,
|
|
841
|
+
retriable: rest.retriable ?? false,
|
|
556
842
|
description
|
|
557
843
|
});
|
|
558
844
|
}
|
|
@@ -591,6 +877,8 @@ Docs: https://github.com/forattini-dev/s3db.js/blob/main/docs/README.md#streamin
|
|
|
591
877
|
...rest,
|
|
592
878
|
operation,
|
|
593
879
|
resource,
|
|
880
|
+
statusCode: rest.statusCode ?? 500,
|
|
881
|
+
retriable: rest.retriable ?? false,
|
|
594
882
|
description
|
|
595
883
|
});
|
|
596
884
|
}
|
|
@@ -649,6 +937,8 @@ Docs: https://github.com/forattini-dev/s3db.js/blob/main/docs/README.md#metadata
|
|
|
649
937
|
excess,
|
|
650
938
|
resourceName,
|
|
651
939
|
operation,
|
|
940
|
+
statusCode: rest.statusCode ?? 413,
|
|
941
|
+
retriable: rest.retriable ?? false,
|
|
652
942
|
description
|
|
653
943
|
});
|
|
654
944
|
}
|