s3db.js 7.3.10 → 7.4.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/dist/s3db.d.ts CHANGED
@@ -47,6 +47,7 @@ declare module 's3db.js' {
47
47
  idSize?: number;
48
48
  versioningEnabled?: boolean;
49
49
  map?: any;
50
+ events?: EventListenerConfig;
50
51
  }
51
52
 
52
53
  /** Partition configuration */
@@ -65,6 +66,11 @@ declare module 's3db.js' {
65
66
  afterDelete?: Function[];
66
67
  }
67
68
 
69
+ /** Event listener configuration */
70
+ export interface EventListenerConfig {
71
+ [eventName: string]: Function | Function[];
72
+ }
73
+
68
74
  /** Query options */
69
75
  export interface QueryOptions {
70
76
  limit?: number;
package/dist/s3db.es.js CHANGED
@@ -9650,7 +9650,13 @@ class Client extends EventEmitter {
9650
9650
  if (metadata) {
9651
9651
  for (const [k, v] of Object.entries(metadata)) {
9652
9652
  const validKey = String(k).replace(/[^a-zA-Z0-9\-_]/g, "_");
9653
- stringMetadata[validKey] = String(v);
9653
+ const stringValue = String(v);
9654
+ const hasSpecialChars = /[^\x00-\x7F]/.test(stringValue);
9655
+ if (hasSpecialChars) {
9656
+ stringMetadata[validKey] = Buffer.from(stringValue, "utf8").toString("base64");
9657
+ } else {
9658
+ stringMetadata[validKey] = stringValue;
9659
+ }
9654
9660
  }
9655
9661
  }
9656
9662
  const options = {
@@ -9687,6 +9693,28 @@ class Client extends EventEmitter {
9687
9693
  let response, error;
9688
9694
  try {
9689
9695
  response = await this.sendCommand(new GetObjectCommand(options));
9696
+ if (response.Metadata) {
9697
+ const decodedMetadata = {};
9698
+ for (const [key2, value] of Object.entries(response.Metadata)) {
9699
+ if (typeof value === "string") {
9700
+ try {
9701
+ const decoded = Buffer.from(value, "base64").toString("utf8");
9702
+ const hasSpecialChars = /[^\x00-\x7F]/.test(decoded);
9703
+ const isValidBase64 = Buffer.from(decoded, "utf8").toString("base64") === value;
9704
+ if (isValidBase64 && hasSpecialChars && decoded !== value) {
9705
+ decodedMetadata[key2] = decoded;
9706
+ } else {
9707
+ decodedMetadata[key2] = value;
9708
+ }
9709
+ } catch (decodeError) {
9710
+ decodedMetadata[key2] = value;
9711
+ }
9712
+ } else {
9713
+ decodedMetadata[key2] = value;
9714
+ }
9715
+ }
9716
+ response.Metadata = decodedMetadata;
9717
+ }
9690
9718
  return response;
9691
9719
  } catch (err) {
9692
9720
  error = err;
@@ -11070,6 +11098,7 @@ class Resource extends EventEmitter {
11070
11098
  * @param {Function} [config.idGenerator] - Custom ID generator function
11071
11099
  * @param {number} [config.idSize=22] - Size for auto-generated IDs
11072
11100
  * @param {boolean} [config.versioningEnabled=false] - Enable versioning for this resource
11101
+ * @param {Object} [config.events={}] - Event listeners to automatically add
11073
11102
  * @example
11074
11103
  * const users = new Resource({
11075
11104
  * name: 'users',
@@ -11091,6 +11120,14 @@ class Resource extends EventEmitter {
11091
11120
  * beforeInsert: [async (data) => {
11092
11121
  * return data;
11093
11122
  * }]
11123
+ * },
11124
+ * events: {
11125
+ * insert: (ev) => console.log('Inserted:', ev.id),
11126
+ * update: [
11127
+ * (ev) => console.warn('Update detected'),
11128
+ * (ev) => console.log('Updated:', ev.id)
11129
+ * ],
11130
+ * delete: (ev) => console.log('Deleted:', ev.id)
11094
11131
  * }
11095
11132
  * });
11096
11133
  *
@@ -11143,7 +11180,8 @@ class Resource extends EventEmitter {
11143
11180
  hooks = {},
11144
11181
  idGenerator: customIdGenerator,
11145
11182
  idSize = 22,
11146
- versioningEnabled = false
11183
+ versioningEnabled = false,
11184
+ events = {}
11147
11185
  } = config;
11148
11186
  this.name = name;
11149
11187
  this.client = client;
@@ -11185,6 +11223,19 @@ class Resource extends EventEmitter {
11185
11223
  }
11186
11224
  }
11187
11225
  }
11226
+ if (events && Object.keys(events).length > 0) {
11227
+ for (const [eventName, listeners] of Object.entries(events)) {
11228
+ if (Array.isArray(listeners)) {
11229
+ for (const listener of listeners) {
11230
+ if (typeof listener === "function") {
11231
+ this.on(eventName, listener);
11232
+ }
11233
+ }
11234
+ } else if (typeof listeners === "function") {
11235
+ this.on(eventName, listeners);
11236
+ }
11237
+ }
11238
+ }
11188
11239
  this._initMiddleware();
11189
11240
  }
11190
11241
  /**
@@ -13224,6 +13275,24 @@ function validateResourceConfig(config) {
13224
13275
  }
13225
13276
  }
13226
13277
  }
13278
+ if (config.events !== void 0) {
13279
+ if (typeof config.events !== "object" || Array.isArray(config.events)) {
13280
+ errors.push("Resource 'events' must be an object");
13281
+ } else {
13282
+ for (const [eventName, listeners] of Object.entries(config.events)) {
13283
+ if (Array.isArray(listeners)) {
13284
+ for (let i = 0; i < listeners.length; i++) {
13285
+ const listener = listeners[i];
13286
+ if (typeof listener !== "function") {
13287
+ errors.push(`Resource 'events.${eventName}[${i}]' must be a function`);
13288
+ }
13289
+ }
13290
+ } else if (typeof listeners !== "function") {
13291
+ errors.push(`Resource 'events.${eventName}' must be a function or array of functions`);
13292
+ }
13293
+ }
13294
+ }
13295
+ }
13227
13296
  return {
13228
13297
  isValid: errors.length === 0,
13229
13298
  errors
@@ -13236,7 +13305,7 @@ class Database extends EventEmitter {
13236
13305
  super();
13237
13306
  this.version = "1";
13238
13307
  this.s3dbVersion = (() => {
13239
- const [ok, err, version] = try_fn_default(() => true ? "7.3.10" : "latest");
13308
+ const [ok, err, version] = try_fn_default(() => true ? "7.4.1" : "latest");
13240
13309
  return ok ? version : "latest";
13241
13310
  })();
13242
13311
  this.resources = {};
@@ -13607,7 +13676,8 @@ class Database extends EventEmitter {
13607
13676
  versioningEnabled: this.versioningEnabled,
13608
13677
  map: config.map,
13609
13678
  idGenerator: config.idGenerator,
13610
- idSize: config.idSize
13679
+ idSize: config.idSize,
13680
+ events: config.events || {}
13611
13681
  });
13612
13682
  resource.database = this;
13613
13683
  this.resources[name] = resource;