s3db.js 7.3.6 → 7.3.9

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.cjs.js CHANGED
@@ -8996,11 +8996,21 @@ class BigqueryReplicator extends base_replicator_class_default {
8996
8996
  }));
8997
8997
  }
8998
8998
  applyTransform(data, transformFn) {
8999
- if (!transformFn) return data;
9000
- let transformedData = JSON.parse(JSON.stringify(data));
9001
- if (transformedData._length) delete transformedData._length;
8999
+ let cleanData = this._cleanInternalFields(data);
9000
+ if (!transformFn) return cleanData;
9001
+ let transformedData = JSON.parse(JSON.stringify(cleanData));
9002
9002
  return transformFn(transformedData);
9003
9003
  }
9004
+ _cleanInternalFields(data) {
9005
+ if (!data || typeof data !== "object") return data;
9006
+ const cleanData = { ...data };
9007
+ Object.keys(cleanData).forEach((key) => {
9008
+ if (key.startsWith("$") || key.startsWith("_")) {
9009
+ delete cleanData[key];
9010
+ }
9011
+ });
9012
+ return cleanData;
9013
+ }
9004
9014
  async replicate(resourceName, operation, data, id, beforeData = null) {
9005
9015
  if (!this.enabled || !this.shouldReplicateResource(resourceName)) {
9006
9016
  return { skipped: true, reason: "resource_not_included" };
@@ -9022,7 +9032,17 @@ class BigqueryReplicator extends base_replicator_class_default {
9022
9032
  let job;
9023
9033
  if (operation === "insert") {
9024
9034
  const transformedData = this.applyTransform(data, tableConfig.transform);
9025
- job = await table.insert([transformedData]);
9035
+ try {
9036
+ job = await table.insert([transformedData]);
9037
+ } catch (error) {
9038
+ const { errors: errors2, response } = error;
9039
+ if (this.config.verbose) {
9040
+ console.error("[BigqueryReplicator] BigQuery insert error details:");
9041
+ if (errors2) console.error("Errors:", JSON.stringify(errors2, null, 2));
9042
+ if (response) console.error("Response:", JSON.stringify(response, null, 2));
9043
+ }
9044
+ throw error;
9045
+ }
9026
9046
  } else if (operation === "update") {
9027
9047
  const transformedData = this.applyTransform(data, tableConfig.transform);
9028
9048
  const keys = Object.keys(transformedData).filter((k) => k !== "id");
@@ -9048,6 +9068,10 @@ class BigqueryReplicator extends base_replicator_class_default {
9048
9068
  lastError = error;
9049
9069
  if (this.config.verbose) {
9050
9070
  console.warn(`[BigqueryReplicator] Update attempt ${attempt} failed: ${error.message}`);
9071
+ if (error.errors) {
9072
+ console.error("[BigqueryReplicator] BigQuery update error details:");
9073
+ console.error("Errors:", JSON.stringify(error.errors, null, 2));
9074
+ }
9051
9075
  }
9052
9076
  if (error?.message?.includes("streaming buffer") && attempt < maxRetries) {
9053
9077
  const delaySeconds = 30;
@@ -9063,13 +9087,23 @@ class BigqueryReplicator extends base_replicator_class_default {
9063
9087
  if (!job) throw lastError;
9064
9088
  } else if (operation === "delete") {
9065
9089
  const query = `DELETE FROM \`${this.projectId}.${this.datasetId}.${tableConfig.table}\` WHERE id = @id`;
9066
- const [deleteJob] = await this.bigqueryClient.createQueryJob({
9067
- query,
9068
- params: { id },
9069
- location: this.location
9070
- });
9071
- await deleteJob.getQueryResults();
9072
- job = [deleteJob];
9090
+ try {
9091
+ const [deleteJob] = await this.bigqueryClient.createQueryJob({
9092
+ query,
9093
+ params: { id },
9094
+ location: this.location
9095
+ });
9096
+ await deleteJob.getQueryResults();
9097
+ job = [deleteJob];
9098
+ } catch (error) {
9099
+ if (this.config.verbose) {
9100
+ console.error("[BigqueryReplicator] BigQuery delete error details:");
9101
+ console.error("Query:", query);
9102
+ if (error.errors) console.error("Errors:", JSON.stringify(error.errors, null, 2));
9103
+ if (error.response) console.error("Response:", JSON.stringify(error.response, null, 2));
9104
+ }
9105
+ throw error;
9106
+ }
9073
9107
  } else {
9074
9108
  throw new Error(`Unsupported operation: ${operation}`);
9075
9109
  }
@@ -9102,6 +9136,9 @@ class BigqueryReplicator extends base_replicator_class_default {
9102
9136
  }
9103
9137
  }
9104
9138
  const success = errors.length === 0;
9139
+ if (errors.length > 0) {
9140
+ console.warn(`[BigqueryReplicator] Replication completed with errors for ${resourceName}:`, errors);
9141
+ }
9105
9142
  this.emit("replicated", {
9106
9143
  replicator: this.name,
9107
9144
  resourceName,
@@ -9152,6 +9189,9 @@ class BigqueryReplicator extends base_replicator_class_default {
9152
9189
  errors.push({ id: record.id, error: err.message });
9153
9190
  }
9154
9191
  }
9192
+ if (errors.length > 0) {
9193
+ console.warn(`[BigqueryReplicator] Batch replication completed with ${errors.length} error(s) for ${resourceName}:`, errors);
9194
+ }
9155
9195
  return {
9156
9196
  success: errors.length === 0,
9157
9197
  results,
@@ -9338,16 +9378,18 @@ class PostgresReplicator extends base_replicator_class_default {
9338
9378
  const [okTable, errTable] = await try_fn_default(async () => {
9339
9379
  let result2;
9340
9380
  if (operation === "insert") {
9341
- const keys = Object.keys(data);
9342
- const values = keys.map((k) => data[k]);
9381
+ const cleanData = this._cleanInternalFields(data);
9382
+ const keys = Object.keys(cleanData);
9383
+ const values = keys.map((k) => cleanData[k]);
9343
9384
  const columns = keys.map((k) => `"${k}"`).join(", ");
9344
9385
  const params = keys.map((_, i) => `$${i + 1}`).join(", ");
9345
9386
  const sql = `INSERT INTO ${table} (${columns}) VALUES (${params}) ON CONFLICT (id) DO NOTHING RETURNING *`;
9346
9387
  result2 = await this.client.query(sql, values);
9347
9388
  } else if (operation === "update") {
9348
- const keys = Object.keys(data).filter((k) => k !== "id");
9389
+ const cleanData = this._cleanInternalFields(data);
9390
+ const keys = Object.keys(cleanData).filter((k) => k !== "id");
9349
9391
  const setClause = keys.map((k, i) => `"${k}"=$${i + 1}`).join(", ");
9350
- const values = keys.map((k) => data[k]);
9392
+ const values = keys.map((k) => cleanData[k]);
9351
9393
  values.push(id);
9352
9394
  const sql = `UPDATE ${table} SET ${setClause} WHERE id=$${keys.length + 1} RETURNING *`;
9353
9395
  result2 = await this.client.query(sql, values);
@@ -9382,6 +9424,9 @@ class PostgresReplicator extends base_replicator_class_default {
9382
9424
  }
9383
9425
  }
9384
9426
  const success = errors.length === 0;
9427
+ if (errors.length > 0) {
9428
+ console.warn(`[PostgresReplicator] Replication completed with errors for ${resourceName}:`, errors);
9429
+ }
9385
9430
  this.emit("replicated", {
9386
9431
  replicator: this.name,
9387
9432
  resourceName,
@@ -9432,6 +9477,9 @@ class PostgresReplicator extends base_replicator_class_default {
9432
9477
  errors.push({ id: record.id, error: err.message });
9433
9478
  }
9434
9479
  }
9480
+ if (errors.length > 0) {
9481
+ console.warn(`[PostgresReplicator] Batch replication completed with ${errors.length} error(s) for ${resourceName}:`, errors);
9482
+ }
9435
9483
  return {
9436
9484
  success: errors.length === 0,
9437
9485
  results,
@@ -9451,6 +9499,16 @@ class PostgresReplicator extends base_replicator_class_default {
9451
9499
  this.emit("connection_error", { replicator: this.name, error: err.message });
9452
9500
  return false;
9453
9501
  }
9502
+ _cleanInternalFields(data) {
9503
+ if (!data || typeof data !== "object") return data;
9504
+ const cleanData = { ...data };
9505
+ Object.keys(cleanData).forEach((key) => {
9506
+ if (key.startsWith("$") || key.startsWith("_")) {
9507
+ delete cleanData[key];
9508
+ }
9509
+ });
9510
+ return cleanData;
9511
+ }
9454
9512
  async cleanup() {
9455
9513
  if (this.client) await this.client.end();
9456
9514
  }
@@ -13182,7 +13240,7 @@ class Database extends EventEmitter {
13182
13240
  super();
13183
13241
  this.version = "1";
13184
13242
  this.s3dbVersion = (() => {
13185
- const [ok, err, version] = try_fn_default(() => true ? "7.3.6" : "latest");
13243
+ const [ok, err, version] = try_fn_default(() => true ? "7.3.8" : "latest");
13186
13244
  return ok ? version : "latest";
13187
13245
  })();
13188
13246
  this.resources = {};
@@ -13846,36 +13904,47 @@ class S3dbReplicator extends base_replicator_class_default {
13846
13904
  return result;
13847
13905
  }
13848
13906
  _applyTransformer(resource, data) {
13907
+ let cleanData = this._cleanInternalFields(data);
13849
13908
  const normResource = normalizeResourceName$1(resource);
13850
13909
  const entry = this.resourcesMap[normResource];
13851
13910
  let result;
13852
- if (!entry) return data;
13911
+ if (!entry) return cleanData;
13853
13912
  if (Array.isArray(entry)) {
13854
13913
  for (const item of entry) {
13855
13914
  if (typeof item === "object" && item.transform && typeof item.transform === "function") {
13856
- result = item.transform(data);
13915
+ result = item.transform(cleanData);
13857
13916
  break;
13858
13917
  } else if (typeof item === "object" && item.transformer && typeof item.transformer === "function") {
13859
- result = item.transformer(data);
13918
+ result = item.transformer(cleanData);
13860
13919
  break;
13861
13920
  }
13862
13921
  }
13863
- if (!result) result = data;
13922
+ if (!result) result = cleanData;
13864
13923
  } else if (typeof entry === "object") {
13865
13924
  if (typeof entry.transform === "function") {
13866
- result = entry.transform(data);
13925
+ result = entry.transform(cleanData);
13867
13926
  } else if (typeof entry.transformer === "function") {
13868
- result = entry.transformer(data);
13927
+ result = entry.transformer(cleanData);
13869
13928
  }
13870
13929
  } else if (typeof entry === "function") {
13871
- result = entry(data);
13930
+ result = entry(cleanData);
13872
13931
  } else {
13873
- result = data;
13932
+ result = cleanData;
13874
13933
  }
13875
- if (result && data && data.id && !result.id) result.id = data.id;
13876
- if (!result && data) result = data;
13934
+ if (result && cleanData && cleanData.id && !result.id) result.id = cleanData.id;
13935
+ if (!result && cleanData) result = cleanData;
13877
13936
  return result;
13878
13937
  }
13938
+ _cleanInternalFields(data) {
13939
+ if (!data || typeof data !== "object") return data;
13940
+ const cleanData = { ...data };
13941
+ Object.keys(cleanData).forEach((key) => {
13942
+ if (key.startsWith("$") || key.startsWith("_")) {
13943
+ delete cleanData[key];
13944
+ }
13945
+ });
13946
+ return cleanData;
13947
+ }
13879
13948
  _resolveDestResource(resource, data) {
13880
13949
  const normResource = normalizeResourceName$1(resource);
13881
13950
  const entry = this.resourcesMap[normResource];
@@ -13924,6 +13993,9 @@ class S3dbReplicator extends base_replicator_class_default {
13924
13993
  errors.push({ id: record.id, error: err.message });
13925
13994
  }
13926
13995
  }
13996
+ if (errors.length > 0) {
13997
+ console.warn(`[S3dbReplicator] Batch replication completed with ${errors.length} error(s) for ${resourceName}:`, errors);
13998
+ }
13927
13999
  this.emit("batch_replicated", {
13928
14000
  replicator: this.name,
13929
14001
  resourceName,
@@ -14062,15 +14134,26 @@ class SqsReplicator extends base_replicator_class_default {
14062
14134
  throw new Error(`No queue URL found for resource '${resource}'`);
14063
14135
  }
14064
14136
  _applyTransformer(resource, data) {
14137
+ let cleanData = this._cleanInternalFields(data);
14065
14138
  const entry = this.resources[resource];
14066
- let result = data;
14067
- if (!entry) return data;
14139
+ let result = cleanData;
14140
+ if (!entry) return cleanData;
14068
14141
  if (typeof entry.transform === "function") {
14069
- result = entry.transform(data);
14142
+ result = entry.transform(cleanData);
14070
14143
  } else if (typeof entry.transformer === "function") {
14071
- result = entry.transformer(data);
14144
+ result = entry.transformer(cleanData);
14072
14145
  }
14073
- return result || data;
14146
+ return result || cleanData;
14147
+ }
14148
+ _cleanInternalFields(data) {
14149
+ if (!data || typeof data !== "object") return data;
14150
+ const cleanData = { ...data };
14151
+ Object.keys(cleanData).forEach((key) => {
14152
+ if (key.startsWith("$") || key.startsWith("_")) {
14153
+ delete cleanData[key];
14154
+ }
14155
+ });
14156
+ return cleanData;
14074
14157
  }
14075
14158
  /**
14076
14159
  * Create standardized message structure
@@ -14221,6 +14304,9 @@ class SqsReplicator extends base_replicator_class_default {
14221
14304
  }
14222
14305
  }
14223
14306
  }
14307
+ if (errors.length > 0) {
14308
+ console.warn(`[SqsReplicator] Batch replication completed with ${errors.length} error(s) for ${resource}:`, errors);
14309
+ }
14224
14310
  this.emit("batch_replicated", {
14225
14311
  replicator: this.name,
14226
14312
  resource,