s3db.js 6.2.0 → 7.0.1
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/PLUGINS.md +2724 -0
- package/README.md +372 -469
- package/UNLICENSE +24 -0
- package/dist/s3db.cjs.js +12105 -19396
- package/dist/s3db.cjs.min.js +1 -1
- package/dist/s3db.d.ts +373 -72
- package/dist/s3db.es.js +12090 -19393
- package/dist/s3db.es.min.js +1 -1
- package/dist/s3db.iife.js +12103 -19398
- package/dist/s3db.iife.min.js +1 -1
- package/package.json +44 -38
- package/src/behaviors/body-only.js +110 -0
- package/src/behaviors/body-overflow.js +153 -0
- package/src/behaviors/enforce-limits.js +195 -0
- package/src/behaviors/index.js +39 -0
- package/src/behaviors/truncate-data.js +204 -0
- package/src/behaviors/user-managed.js +147 -0
- package/src/client.class.js +515 -0
- package/src/concerns/base62.js +61 -0
- package/src/concerns/calculator.js +204 -0
- package/src/concerns/crypto.js +159 -0
- package/src/concerns/id.js +8 -0
- package/src/concerns/index.js +5 -0
- package/src/concerns/try-fn.js +151 -0
- package/src/connection-string.class.js +75 -0
- package/src/database.class.js +599 -0
- package/src/errors.js +261 -0
- package/src/index.js +17 -0
- package/src/plugins/audit.plugin.js +442 -0
- package/src/plugins/cache/cache.class.js +53 -0
- package/src/plugins/cache/index.js +6 -0
- package/src/plugins/cache/memory-cache.class.js +164 -0
- package/src/plugins/cache/s3-cache.class.js +189 -0
- package/src/plugins/cache.plugin.js +275 -0
- package/src/plugins/consumers/index.js +24 -0
- package/src/plugins/consumers/rabbitmq-consumer.js +56 -0
- package/src/plugins/consumers/sqs-consumer.js +102 -0
- package/src/plugins/costs.plugin.js +81 -0
- package/src/plugins/fulltext.plugin.js +473 -0
- package/src/plugins/index.js +12 -0
- package/src/plugins/metrics.plugin.js +603 -0
- package/src/plugins/plugin.class.js +210 -0
- package/src/plugins/plugin.obj.js +13 -0
- package/src/plugins/queue-consumer.plugin.js +134 -0
- package/src/plugins/replicator.plugin.js +769 -0
- package/src/plugins/replicators/base-replicator.class.js +85 -0
- package/src/plugins/replicators/bigquery-replicator.class.js +328 -0
- package/src/plugins/replicators/index.js +44 -0
- package/src/plugins/replicators/postgres-replicator.class.js +427 -0
- package/src/plugins/replicators/s3db-replicator.class.js +352 -0
- package/src/plugins/replicators/sqs-replicator.class.js +427 -0
- package/src/resource.class.js +2626 -0
- package/src/s3db.d.ts +1263 -0
- package/src/schema.class.js +706 -0
- package/src/stream/index.js +16 -0
- package/src/stream/resource-ids-page-reader.class.js +10 -0
- package/src/stream/resource-ids-reader.class.js +63 -0
- package/src/stream/resource-reader.class.js +81 -0
- package/src/stream/resource-writer.class.js +92 -0
- package/src/validator.class.js +97 -0
package/src/errors.js
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
export class BaseError extends Error {
|
|
2
|
+
constructor({ verbose, bucket, key, message, code, statusCode, requestId, awsMessage, original, commandName, commandInput, metadata, suggestion, ...rest }) {
|
|
3
|
+
if (verbose) message = message + `\n\nVerbose:\n\n${JSON.stringify(rest, null, 2)}`;
|
|
4
|
+
super(message);
|
|
5
|
+
|
|
6
|
+
if (typeof Error.captureStackTrace === 'function') {
|
|
7
|
+
Error.captureStackTrace(this, this.constructor);
|
|
8
|
+
} else {
|
|
9
|
+
this.stack = (new Error(message)).stack;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
super.name = this.constructor.name;
|
|
13
|
+
this.name = this.constructor.name;
|
|
14
|
+
this.bucket = bucket;
|
|
15
|
+
this.key = key;
|
|
16
|
+
this.thrownAt = new Date();
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.statusCode = statusCode;
|
|
19
|
+
this.requestId = requestId;
|
|
20
|
+
this.awsMessage = awsMessage;
|
|
21
|
+
this.original = original;
|
|
22
|
+
this.commandName = commandName;
|
|
23
|
+
this.commandInput = commandInput;
|
|
24
|
+
this.metadata = metadata;
|
|
25
|
+
this.suggestion = suggestion;
|
|
26
|
+
this.data = { bucket, key, ...rest, verbose, message };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
toJson() {
|
|
30
|
+
return {
|
|
31
|
+
name: this.name,
|
|
32
|
+
message: this.message,
|
|
33
|
+
code: this.code,
|
|
34
|
+
statusCode: this.statusCode,
|
|
35
|
+
requestId: this.requestId,
|
|
36
|
+
awsMessage: this.awsMessage,
|
|
37
|
+
bucket: this.bucket,
|
|
38
|
+
key: this.key,
|
|
39
|
+
thrownAt: this.thrownAt,
|
|
40
|
+
commandName: this.commandName,
|
|
41
|
+
commandInput: this.commandInput,
|
|
42
|
+
metadata: this.metadata,
|
|
43
|
+
suggestion: this.suggestion,
|
|
44
|
+
data: this.data,
|
|
45
|
+
original: this.original,
|
|
46
|
+
stack: this.stack,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
toString() {
|
|
51
|
+
return `${this.name} | ${this.message}`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Base error class for S3DB
|
|
56
|
+
export class S3dbError extends BaseError {
|
|
57
|
+
constructor(message, details = {}) {
|
|
58
|
+
// Extrai campos AWS se presentes
|
|
59
|
+
let code, statusCode, requestId, awsMessage, original, metadata;
|
|
60
|
+
if (details.original) {
|
|
61
|
+
original = details.original;
|
|
62
|
+
code = original.code || original.Code || original.name;
|
|
63
|
+
statusCode = original.statusCode || (original.$metadata && original.$metadata.httpStatusCode);
|
|
64
|
+
requestId = original.requestId || (original.$metadata && original.$metadata.requestId);
|
|
65
|
+
awsMessage = original.message;
|
|
66
|
+
metadata = original.$metadata ? { ...original.$metadata } : undefined;
|
|
67
|
+
}
|
|
68
|
+
super({ message, ...details, code, statusCode, requestId, awsMessage, original, metadata });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Database operation errors
|
|
73
|
+
export class DatabaseError extends S3dbError {
|
|
74
|
+
constructor(message, details = {}) {
|
|
75
|
+
super(message, details);
|
|
76
|
+
Object.assign(this, details);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Validation errors
|
|
81
|
+
export class ValidationError extends S3dbError {
|
|
82
|
+
constructor(message, details = {}) {
|
|
83
|
+
super(message, details);
|
|
84
|
+
Object.assign(this, details);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Authentication errors
|
|
89
|
+
export class AuthenticationError extends S3dbError {
|
|
90
|
+
constructor(message, details = {}) {
|
|
91
|
+
super(message, details);
|
|
92
|
+
Object.assign(this, details);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Permission/Authorization errors
|
|
97
|
+
export class PermissionError extends S3dbError {
|
|
98
|
+
constructor(message, details = {}) {
|
|
99
|
+
super(message, details);
|
|
100
|
+
Object.assign(this, details);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Encryption errors
|
|
105
|
+
export class EncryptionError extends S3dbError {
|
|
106
|
+
constructor(message, details = {}) {
|
|
107
|
+
super(message, details);
|
|
108
|
+
Object.assign(this, details);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Resource not found error
|
|
113
|
+
export class ResourceNotFound extends S3dbError {
|
|
114
|
+
constructor({ bucket, resourceName, id, original, ...rest }) {
|
|
115
|
+
if (typeof id !== 'string') throw new Error('id must be a string');
|
|
116
|
+
if (typeof bucket !== 'string') throw new Error('bucket must be a string');
|
|
117
|
+
if (typeof resourceName !== 'string') throw new Error('resourceName must be a string');
|
|
118
|
+
super(`Resource not found: ${resourceName}/${id} [bucket:${bucket}]`, {
|
|
119
|
+
bucket,
|
|
120
|
+
resourceName,
|
|
121
|
+
id,
|
|
122
|
+
original,
|
|
123
|
+
...rest
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export class NoSuchBucket extends S3dbError {
|
|
129
|
+
constructor({ bucket, original, ...rest }) {
|
|
130
|
+
if (typeof bucket !== 'string') throw new Error('bucket must be a string');
|
|
131
|
+
super(`Bucket does not exists [bucket:${bucket}]`, { bucket, original, ...rest });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export class NoSuchKey extends S3dbError {
|
|
136
|
+
constructor({ bucket, key, resourceName, id, original, ...rest }) {
|
|
137
|
+
if (typeof key !== 'string') throw new Error('key must be a string');
|
|
138
|
+
if (typeof bucket !== 'string') throw new Error('bucket must be a string');
|
|
139
|
+
if (id !== undefined && typeof id !== 'string') throw new Error('id must be a string');
|
|
140
|
+
super(`No such key: ${key} [bucket:${bucket}]`, { bucket, key, resourceName, id, original, ...rest });
|
|
141
|
+
this.resourceName = resourceName;
|
|
142
|
+
this.id = id;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export class NotFound extends S3dbError {
|
|
147
|
+
constructor({ bucket, key, resourceName, id, original, ...rest }) {
|
|
148
|
+
if (typeof key !== 'string') throw new Error('key must be a string');
|
|
149
|
+
if (typeof bucket !== 'string') throw new Error('bucket must be a string');
|
|
150
|
+
super(`Not found: ${key} [bucket:${bucket}]`, { bucket, key, resourceName, id, original, ...rest });
|
|
151
|
+
this.resourceName = resourceName;
|
|
152
|
+
this.id = id;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export class MissingMetadata extends S3dbError {
|
|
157
|
+
constructor({ bucket, original, ...rest }) {
|
|
158
|
+
if (typeof bucket !== 'string') throw new Error('bucket must be a string');
|
|
159
|
+
super(`Missing metadata for bucket [bucket:${bucket}]`, { bucket, original, ...rest });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export class InvalidResourceItem extends S3dbError {
|
|
164
|
+
constructor({
|
|
165
|
+
bucket,
|
|
166
|
+
resourceName,
|
|
167
|
+
attributes,
|
|
168
|
+
validation,
|
|
169
|
+
message,
|
|
170
|
+
original,
|
|
171
|
+
...rest
|
|
172
|
+
}) {
|
|
173
|
+
if (typeof bucket !== 'string') throw new Error('bucket must be a string');
|
|
174
|
+
if (typeof resourceName !== 'string') throw new Error('resourceName must be a string');
|
|
175
|
+
super(
|
|
176
|
+
message || `Validation error: This item is not valid. Resource=${resourceName} [bucket:${bucket}].\n${JSON.stringify(validation, null, 2)}`,
|
|
177
|
+
{
|
|
178
|
+
bucket,
|
|
179
|
+
resourceName,
|
|
180
|
+
attributes,
|
|
181
|
+
validation,
|
|
182
|
+
original,
|
|
183
|
+
...rest
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export class UnknownError extends S3dbError {}
|
|
190
|
+
|
|
191
|
+
export const ErrorMap = {
|
|
192
|
+
'NotFound': NotFound,
|
|
193
|
+
'NoSuchKey': NoSuchKey,
|
|
194
|
+
'UnknownError': UnknownError,
|
|
195
|
+
'NoSuchBucket': NoSuchBucket,
|
|
196
|
+
'MissingMetadata': MissingMetadata,
|
|
197
|
+
'InvalidResourceItem': InvalidResourceItem,
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// Utilitário para mapear erro AWS para erro customizado
|
|
201
|
+
export function mapAwsError(err, context = {}) {
|
|
202
|
+
const code = err.code || err.Code || err.name;
|
|
203
|
+
const metadata = err.$metadata ? { ...err.$metadata } : undefined;
|
|
204
|
+
const commandName = context.commandName;
|
|
205
|
+
const commandInput = context.commandInput;
|
|
206
|
+
let suggestion;
|
|
207
|
+
if (code === 'NoSuchKey' || code === 'NotFound') {
|
|
208
|
+
suggestion = 'Check if the key exists in the specified bucket and if your credentials have permission.';
|
|
209
|
+
return new NoSuchKey({ ...context, original: err, metadata, commandName, commandInput, suggestion });
|
|
210
|
+
}
|
|
211
|
+
if (code === 'NoSuchBucket') {
|
|
212
|
+
suggestion = 'Check if the bucket exists and if your credentials have permission.';
|
|
213
|
+
return new NoSuchBucket({ ...context, original: err, metadata, commandName, commandInput, suggestion });
|
|
214
|
+
}
|
|
215
|
+
if (code === 'AccessDenied' || (err.statusCode === 403) || code === 'Forbidden') {
|
|
216
|
+
suggestion = 'Check your credentials and bucket policy.';
|
|
217
|
+
return new PermissionError('Access denied', { ...context, original: err, metadata, commandName, commandInput, suggestion });
|
|
218
|
+
}
|
|
219
|
+
if (code === 'ValidationError' || (err.statusCode === 400)) {
|
|
220
|
+
suggestion = 'Check the request parameters and payload.';
|
|
221
|
+
return new ValidationError('Validation error', { ...context, original: err, metadata, commandName, commandInput, suggestion });
|
|
222
|
+
}
|
|
223
|
+
if (code === 'MissingMetadata') {
|
|
224
|
+
suggestion = 'Check if the object metadata is present and valid.';
|
|
225
|
+
return new MissingMetadata({ ...context, original: err, metadata, commandName, commandInput, suggestion });
|
|
226
|
+
}
|
|
227
|
+
// Outros mapeamentos podem ser adicionados aqui
|
|
228
|
+
suggestion = 'Check the error details and AWS documentation.';
|
|
229
|
+
return new UnknownError('Unknown error', { ...context, original: err, metadata, commandName, commandInput, suggestion });
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export class ConnectionStringError extends S3dbError {
|
|
233
|
+
constructor(message, details = {}) {
|
|
234
|
+
super(message, { ...details, suggestion: 'Check the connection string format and credentials.' });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export class CryptoError extends S3dbError {
|
|
239
|
+
constructor(message, details = {}) {
|
|
240
|
+
super(message, { ...details, suggestion: 'Check if the crypto library is available and input is valid.' });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export class SchemaError extends S3dbError {
|
|
245
|
+
constructor(message, details = {}) {
|
|
246
|
+
super(message, { ...details, suggestion: 'Check schema definition and input data.' });
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export class ResourceError extends S3dbError {
|
|
251
|
+
constructor(message, details = {}) {
|
|
252
|
+
super(message, { ...details, suggestion: details.suggestion || 'Check resource configuration, attributes, and operation context.' });
|
|
253
|
+
Object.assign(this, details);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export class PartitionError extends S3dbError {
|
|
258
|
+
constructor(message, details = {}) {
|
|
259
|
+
super(message, { ...details, suggestion: details.suggestion || 'Check partition definition, fields, and input values.' });
|
|
260
|
+
}
|
|
261
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// directories
|
|
2
|
+
export * from './behaviors/index.js'
|
|
3
|
+
export * from './concerns/index.js'
|
|
4
|
+
export * from './plugins/index.js'
|
|
5
|
+
export * from './stream/index.js'
|
|
6
|
+
|
|
7
|
+
// single
|
|
8
|
+
export * from './client.class.js'
|
|
9
|
+
export * from './connection-string.class.js'
|
|
10
|
+
export * from './database.class.js'
|
|
11
|
+
export * from './errors.js'
|
|
12
|
+
export * from './resource.class.js'
|
|
13
|
+
export * from './schema.class.js'
|
|
14
|
+
export * from './validator.class.js'
|
|
15
|
+
|
|
16
|
+
// default
|
|
17
|
+
export { S3db as default } from './database.class.js'
|