s3db.js 4.1.4 → 4.1.6

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 CHANGED
@@ -263,74 +263,93 @@ const users = await s3db.createResource({
263
263
  });
264
264
  ```
265
265
 
266
- #### Nested Attributes
266
+ #### List, ListIds, Count, Page, Query (Novo Formato)
267
267
 
268
- `s3db.js` fully supports nested object attributes, allowing you to create complex document structures:
268
+ Todos os métodos de listagem, paginação e contagem agora recebem um único objeto de parâmetros:
269
269
 
270
- ```javascript
270
+ ```js
271
+ // Listar todos os usuários
272
+ const allUsers = await users.list();
273
+
274
+ // Listar usuários de uma partição
275
+ const googleUsers = await users.list({
276
+ partition: 'byUtmSource',
277
+ partitionValues: { 'utm.source': 'google' }
278
+ });
279
+
280
+ // Listar IDs de uma partição
281
+ const googleUserIds = await users.listIds({
282
+ partition: 'byUtmSource',
283
+ partitionValues: { 'utm.source': 'google' }
284
+ });
285
+
286
+ // Paginar resultados
287
+ const page = await users.page({
288
+ partition: 'byUtmSource',
289
+ partitionValues: { 'utm.source': 'google' },
290
+ offset: 0,
291
+ size: 10
292
+ });
293
+ console.log(page.items); // Array de usuários
294
+ console.log(page.totalItems, page.totalPages);
295
+
296
+ // Contar documentos em uma partição
297
+ const count = await users.count({
298
+ partition: 'byUtmSource',
299
+ partitionValues: { 'utm.source': 'google' }
300
+ });
301
+
302
+ // Query com filtro e paginação
303
+ const filtered = await users.query(
304
+ { isActive: true },
305
+ { partition: 'byUtmSource', partitionValues: { 'utm.source': 'google' }, limit: 5, offset: 0 }
306
+ );
307
+ ```
308
+
309
+ #### Partições com Campos Aninhados
310
+
311
+ Você pode usar dot notation para acessar campos aninhados em partições:
312
+
313
+ ```js
271
314
  const users = await s3db.createResource({
272
- name: "users",
315
+ name: 'users',
273
316
  attributes: {
274
- name: "string|required",
275
- email: "email|required",
276
- utm: {
277
- source: "string|required",
278
- medium: "string|required",
279
- campaign: "string|required",
280
- term: "string|optional",
281
- content: "string|optional"
282
- },
283
- address: {
284
- street: "string|required",
285
- city: "string|required",
286
- state: "string|required",
287
- country: "string|required",
288
- zipCode: "string|optional"
289
- },
290
- metadata: {
291
- category: "string|required",
292
- priority: "string|required",
293
- settings: "object|optional"
317
+ name: 'string|required',
318
+ utm: { source: 'string|required', medium: 'string|required' },
319
+ address: { country: 'string|required', city: 'string|required' }
320
+ },
321
+ options: {
322
+ partitions: {
323
+ byUtmSource: { fields: { 'utm.source': 'string' } },
324
+ byCountry: { fields: { 'address.country': 'string' } }
294
325
  }
295
326
  }
296
327
  });
297
328
 
298
- // Insert data with nested objects
299
- const user = await users.insert({
300
- name: "John Doe",
301
- email: "john@example.com",
302
- utm: {
303
- source: "google",
304
- medium: "cpc",
305
- campaign: "brand_awareness",
306
- term: "search term"
307
- },
308
- address: {
309
- street: "123 Main St",
310
- city: "San Francisco",
311
- state: "California",
312
- country: "US",
313
- zipCode: "94105"
314
- },
315
- metadata: {
316
- category: "premium",
317
- priority: "high",
318
- settings: { theme: "dark", notifications: true }
319
- }
329
+ // Listar por campo aninhado
330
+ const usUsers = await users.list({
331
+ partition: 'byCountry',
332
+ partitionValues: { 'address.country': 'US' }
320
333
  });
321
-
322
- // Access nested data
323
- console.log(user.utm.source); // "google"
324
- console.log(user.address.city); // "San Francisco"
325
- console.log(user.metadata.category); // "premium"
326
334
  ```
327
335
 
328
- **Key features of nested attributes:**
329
- - **Deep nesting**: Support for multiple levels of nested objects
330
- - **Validation**: Each nested field can have its own validation rules
331
- - **Optional fields**: Nested objects can contain optional fields
332
- - **Mixed types**: Combine simple types, arrays, and nested objects
333
- - **Partition support**: Use dot notation for partitions on nested fields (e.g., `"utm.source"`, `"address.country"`)
336
+ #### getPartitionKey e getFromPartition
337
+
338
+ ```js
339
+ // Gerar chave de partição
340
+ const key = users.getPartitionKey({
341
+ partitionName: 'byUtmSource',
342
+ id: 'user-123',
343
+ data: { utm: { source: 'google' } }
344
+ });
345
+
346
+ // Buscar diretamente de uma partição
347
+ const user = await users.getFromPartition({
348
+ id: 'user-123',
349
+ partitionName: 'byUtmSource',
350
+ partitionValues: { 'utm.source': 'google' }
351
+ });
352
+ ```
334
353
 
335
354
  #### Automatic Timestamps
336
355
 
@@ -440,7 +459,7 @@ try {
440
459
  });
441
460
  } catch (error) {
442
461
  console.error("Operation failed:", error.message);
443
- // Error: S3 metadata size exceeds 2KB limit. Current size: 2500 bytes, limit: 2048 bytes
462
+ // Error: S3 metadata size exceeds 2KB limit. Current size: 2500 bytes, limit: 2000 bytes
444
463
  }
445
464
  ```
446
465
 
package/dist/s3db.cjs.js CHANGED
@@ -901,10 +901,10 @@ class Client extends EventEmitter {
901
901
  Bucket: this.config.bucket,
902
902
  Key: this.config.keyPrefix ? path.join(this.config.keyPrefix, key) : key,
903
903
  Metadata: { ...metadata },
904
- Body: body || "",
905
- ContentType: contentType,
906
- ContentEncoding: contentEncoding
904
+ Body: body || Buffer.alloc(0)
907
905
  };
906
+ if (contentType !== void 0) options2.ContentType = contentType;
907
+ if (contentEncoding !== void 0) options2.ContentEncoding = contentEncoding;
908
908
  try {
909
909
  const response = await this.sendCommand(new clientS3.PutObjectCommand(options2));
910
910
  this.emit("putObject", response, options2);
@@ -8500,12 +8500,16 @@ class ResourceWriter extends EventEmitter {
8500
8500
  }
8501
8501
  write(chunk) {
8502
8502
  this.buffer.push(chunk);
8503
- this._maybeWrite();
8503
+ this._maybeWrite().catch((error) => {
8504
+ this.emit("error", error);
8505
+ });
8504
8506
  return true;
8505
8507
  }
8506
8508
  end() {
8507
8509
  this.ended = true;
8508
- this._maybeWrite();
8510
+ this._maybeWrite().catch((error) => {
8511
+ this.emit("error", error);
8512
+ });
8509
8513
  }
8510
8514
  async _maybeWrite() {
8511
8515
  if (this.writing) return;
@@ -8602,7 +8606,7 @@ function calculateTotalSize(mappedObject) {
8602
8606
  return Object.values(sizes).reduce((total, size) => total + size, 0);
8603
8607
  }
8604
8608
 
8605
- const S3_METADATA_LIMIT_BYTES$3 = 2048;
8609
+ const S3_METADATA_LIMIT_BYTES$3 = 2e3;
8606
8610
  async function handleInsert$3({ resource, data, mappedData }) {
8607
8611
  const totalSize = calculateTotalSize(mappedData);
8608
8612
  if (totalSize > S3_METADATA_LIMIT_BYTES$3) {
@@ -8656,7 +8660,7 @@ var userManagement = /*#__PURE__*/Object.freeze({
8656
8660
  handleUpsert: handleUpsert$3
8657
8661
  });
8658
8662
 
8659
- const S3_METADATA_LIMIT_BYTES$2 = 2048;
8663
+ const S3_METADATA_LIMIT_BYTES$2 = 2e3;
8660
8664
  async function handleInsert$2({ resource, data, mappedData }) {
8661
8665
  const totalSize = calculateTotalSize(mappedData);
8662
8666
  if (totalSize > S3_METADATA_LIMIT_BYTES$2) {
@@ -8690,7 +8694,7 @@ var enforceLimits = /*#__PURE__*/Object.freeze({
8690
8694
  handleUpsert: handleUpsert$2
8691
8695
  });
8692
8696
 
8693
- const S3_METADATA_LIMIT_BYTES$1 = 2048;
8697
+ const S3_METADATA_LIMIT_BYTES$1 = 2e3;
8694
8698
  const TRUNCATE_SUFFIX = "...";
8695
8699
  const TRUNCATE_SUFFIX_BYTES = calculateUTF8Bytes(TRUNCATE_SUFFIX);
8696
8700
  async function handleInsert$1({ resource, data, mappedData }) {
@@ -8748,7 +8752,7 @@ var dataTruncate = /*#__PURE__*/Object.freeze({
8748
8752
  handleUpsert: handleUpsert$1
8749
8753
  });
8750
8754
 
8751
- const S3_METADATA_LIMIT_BYTES = 2048;
8755
+ const S3_METADATA_LIMIT_BYTES = 2e3;
8752
8756
  const OVERFLOW_FLAG = "$overflow";
8753
8757
  const OVERFLOW_FLAG_VALUE = "true";
8754
8758
  const OVERFLOW_FLAG_BYTES = calculateUTF8Bytes(OVERFLOW_FLAG) + calculateUTF8Bytes(OVERFLOW_FLAG_VALUE);
@@ -9817,7 +9821,7 @@ class Database extends EventEmitter {
9817
9821
  this.version = "1";
9818
9822
  this.s3dbVersion = (() => {
9819
9823
  try {
9820
- return true ? "4.1.3" : "latest";
9824
+ return true ? "4.1.4" : "latest";
9821
9825
  } catch (e) {
9822
9826
  return "latest";
9823
9827
  }