s3db.js 4.1.8 → 4.1.10

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/dist/s3db.iife.js CHANGED
@@ -9261,6 +9261,58 @@ ${JSON.stringify(validation, null, 2)}`
9261
9261
  this.emit("get", data);
9262
9262
  return data;
9263
9263
  } catch (error) {
9264
+ if (error.message.includes("Cipher job failed") || error.message.includes("OperationError") || error.originalError?.message?.includes("Cipher job failed")) {
9265
+ try {
9266
+ console.warn(`Decryption failed for resource ${id}, attempting to get raw metadata`);
9267
+ const request = await this.client.headObject(key);
9268
+ const objectVersion = this.extractVersionFromKey(key) || this.version;
9269
+ const tempSchema = new Schema({
9270
+ name: this.name,
9271
+ attributes: this.attributes,
9272
+ passphrase: this.passphrase,
9273
+ version: objectVersion,
9274
+ options: {
9275
+ ...this.options,
9276
+ autoDecrypt: false,
9277
+ // Disable decryption
9278
+ autoEncrypt: false
9279
+ // Disable encryption
9280
+ }
9281
+ });
9282
+ let metadata = await tempSchema.unmapper(request.Metadata);
9283
+ const behaviorImpl = getBehavior(this.behavior);
9284
+ let body = "";
9285
+ if (request.ContentLength > 0) {
9286
+ try {
9287
+ const fullObject = await this.client.getObject(key);
9288
+ body = await streamToString(fullObject.Body);
9289
+ } catch (bodyError) {
9290
+ console.warn(`Failed to read body for resource ${id}:`, bodyError.message);
9291
+ body = "";
9292
+ }
9293
+ }
9294
+ const { metadata: processedMetadata } = await behaviorImpl.handleGet({
9295
+ resource: this,
9296
+ metadata,
9297
+ body
9298
+ });
9299
+ let data = processedMetadata;
9300
+ data.id = id;
9301
+ data._contentLength = request.ContentLength;
9302
+ data._lastModified = request.LastModified;
9303
+ data._hasContent = request.ContentLength > 0;
9304
+ data._mimeType = request.ContentType || null;
9305
+ data._version = objectVersion;
9306
+ data._decryptionFailed = true;
9307
+ if (request.VersionId) data._versionId = request.VersionId;
9308
+ if (request.Expiration) data._expiresAt = request.Expiration;
9309
+ data._definitionHash = this.getDefinitionHash();
9310
+ this.emit("get", data);
9311
+ return data;
9312
+ } catch (fallbackError) {
9313
+ console.error(`Fallback attempt also failed for resource ${id}:`, fallbackError.message);
9314
+ }
9315
+ }
9264
9316
  const enhancedError = new Error(`Failed to get resource with id '${id}': ${error.message}`);
9265
9317
  enhancedError.originalError = error;
9266
9318
  enhancedError.resourceId = id;
@@ -9650,11 +9702,27 @@ ${JSON.stringify(validation, null, 2)}`
9650
9702
  if (limit) {
9651
9703
  filteredIds2 = filteredIds2.slice(0, limit);
9652
9704
  }
9653
- const { results: results2 } = await promisePool.PromisePool.for(filteredIds2).withConcurrency(this.parallelism).process(async (id) => {
9654
- return await this.get(id);
9705
+ const { results: results2, errors: errors2 } = await promisePool.PromisePool.for(filteredIds2).withConcurrency(this.parallelism).handleError(async (error, id) => {
9706
+ console.warn(`Failed to get resource ${id}:`, error.message);
9707
+ return null;
9708
+ }).process(async (id) => {
9709
+ try {
9710
+ return await this.get(id);
9711
+ } catch (error) {
9712
+ if (error.message.includes("Cipher job failed") || error.message.includes("OperationError")) {
9713
+ console.warn(`Decryption failed for ${id}, returning basic info`);
9714
+ return {
9715
+ id,
9716
+ _decryptionFailed: true,
9717
+ _error: error.message
9718
+ };
9719
+ }
9720
+ throw error;
9721
+ }
9655
9722
  });
9656
- this.emit("list", { partition, partitionValues, count: results2.length });
9657
- return results2;
9723
+ const validResults2 = results2.filter((item) => item !== null);
9724
+ this.emit("list", { partition, partitionValues, count: validResults2.length, errors: errors2.length });
9725
+ return validResults2;
9658
9726
  }
9659
9727
  const partitionDef = this.options.partitions[partition];
9660
9728
  if (!partitionDef) {
@@ -9685,11 +9753,29 @@ ${JSON.stringify(validation, null, 2)}`
9685
9753
  if (limit) {
9686
9754
  filteredIds = filteredIds.slice(0, limit);
9687
9755
  }
9688
- const { results } = await promisePool.PromisePool.for(filteredIds).withConcurrency(this.parallelism).process(async (id) => {
9689
- return await this.getFromPartition({ id, partitionName: partition, partitionValues });
9756
+ const { results, errors } = await promisePool.PromisePool.for(filteredIds).withConcurrency(this.parallelism).handleError(async (error, id) => {
9757
+ console.warn(`Failed to get partition resource ${id}:`, error.message);
9758
+ return null;
9759
+ }).process(async (id) => {
9760
+ try {
9761
+ return await this.getFromPartition({ id, partitionName: partition, partitionValues });
9762
+ } catch (error) {
9763
+ if (error.message.includes("Cipher job failed") || error.message.includes("OperationError")) {
9764
+ console.warn(`Decryption failed for partition resource ${id}, returning basic info`);
9765
+ return {
9766
+ id,
9767
+ _partition: partition,
9768
+ _partitionValues: partitionValues,
9769
+ _decryptionFailed: true,
9770
+ _error: error.message
9771
+ };
9772
+ }
9773
+ throw error;
9774
+ }
9690
9775
  });
9691
- this.emit("list", { partition, partitionValues, count: results.length });
9692
- return results;
9776
+ const validResults = results.filter((item) => item !== null);
9777
+ this.emit("list", { partition, partitionValues, count: validResults.length, errors: errors.length });
9778
+ return validResults;
9693
9779
  }
9694
9780
  /**
9695
9781
  * Get multiple resources by their IDs
@@ -9700,11 +9786,30 @@ ${JSON.stringify(validation, null, 2)}`
9700
9786
  * users.forEach(user => console.log(user.name));
9701
9787
  */
9702
9788
  async getMany(ids) {
9703
- const { results } = await promisePool.PromisePool.for(ids).withConcurrency(this.client.parallelism).process(async (id) => {
9789
+ const { results, errors } = await promisePool.PromisePool.for(ids).withConcurrency(this.client.parallelism).handleError(async (error, id) => {
9790
+ console.warn(`Failed to get resource ${id}:`, error.message);
9791
+ return {
9792
+ id,
9793
+ _error: error.message,
9794
+ _decryptionFailed: error.message.includes("Cipher job failed") || error.message.includes("OperationError")
9795
+ };
9796
+ }).process(async (id) => {
9704
9797
  this.emit("id", id);
9705
- const data = await this.get(id);
9706
- this.emit("data", data);
9707
- return data;
9798
+ try {
9799
+ const data = await this.get(id);
9800
+ this.emit("data", data);
9801
+ return data;
9802
+ } catch (error) {
9803
+ if (error.message.includes("Cipher job failed") || error.message.includes("OperationError")) {
9804
+ console.warn(`Decryption failed for ${id}, returning basic info`);
9805
+ return {
9806
+ id,
9807
+ _decryptionFailed: true,
9808
+ _error: error.message
9809
+ };
9810
+ }
9811
+ throw error;
9812
+ }
9708
9813
  });
9709
9814
  this.emit("getMany", ids.length);
9710
9815
  return results;
@@ -9719,9 +9824,28 @@ ${JSON.stringify(validation, null, 2)}`
9719
9824
  async getAll() {
9720
9825
  let ids = await this.listIds();
9721
9826
  if (ids.length === 0) return [];
9722
- const { results } = await promisePool.PromisePool.for(ids).withConcurrency(this.client.parallelism).process(async (id) => {
9723
- const data = await this.get(id);
9724
- return data;
9827
+ const { results, errors } = await promisePool.PromisePool.for(ids).withConcurrency(this.client.parallelism).handleError(async (error, id) => {
9828
+ console.warn(`Failed to get resource ${id}:`, error.message);
9829
+ return {
9830
+ id,
9831
+ _error: error.message,
9832
+ _decryptionFailed: error.message.includes("Cipher job failed") || error.message.includes("OperationError")
9833
+ };
9834
+ }).process(async (id) => {
9835
+ try {
9836
+ const data = await this.get(id);
9837
+ return data;
9838
+ } catch (error) {
9839
+ if (error.message.includes("Cipher job failed") || error.message.includes("OperationError")) {
9840
+ console.warn(`Decryption failed for ${id}, returning basic info`);
9841
+ return {
9842
+ id,
9843
+ _decryptionFailed: true,
9844
+ _error: error.message
9845
+ };
9846
+ }
9847
+ throw error;
9848
+ }
9725
9849
  });
9726
9850
  this.emit("getAll", results.length);
9727
9851
  return results;
@@ -9936,7 +10060,27 @@ ${JSON.stringify(validation, null, 2)}`
9936
10060
  * @returns {Object} Schema object for the version
9937
10061
  */
9938
10062
  async getSchemaForVersion(version) {
9939
- return this.schema;
10063
+ if (version === this.version) {
10064
+ return this.schema;
10065
+ }
10066
+ try {
10067
+ const compatibleSchema = new Schema({
10068
+ name: this.name,
10069
+ attributes: this.attributes,
10070
+ passphrase: this.passphrase,
10071
+ version,
10072
+ options: {
10073
+ ...this.options,
10074
+ // For older versions, be more lenient with decryption
10075
+ autoDecrypt: true,
10076
+ autoEncrypt: true
10077
+ }
10078
+ });
10079
+ return compatibleSchema;
10080
+ } catch (error) {
10081
+ console.warn(`Failed to create compatible schema for version ${version}, using current schema:`, error.message);
10082
+ return this.schema;
10083
+ }
9940
10084
  }
9941
10085
  /**
9942
10086
  * Create partition references after insert
@@ -10180,7 +10324,7 @@ ${JSON.stringify(validation, null, 2)}`
10180
10324
  this.version = "1";
10181
10325
  this.s3dbVersion = (() => {
10182
10326
  try {
10183
- return true ? "4.1.7" : "latest";
10327
+ return true ? "4.1.9" : "latest";
10184
10328
  } catch (e) {
10185
10329
  return "latest";
10186
10330
  }