s3db.js 7.3.8 → 7.3.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.cjs.js +99 -31
- package/dist/s3db.cjs.min.js +1 -1
- package/dist/s3db.es.js +99 -31
- package/dist/s3db.es.min.js +1 -1
- package/dist/s3db.iife.js +99 -31
- package/dist/s3db.iife.min.js +1 -1
- package/package.json +1 -1
- package/src/plugins/replicators/bigquery-replicator.class.js +98 -55
- package/src/plugins/replicators/postgres-replicator.class.js +23 -4
- package/src/plugins/replicators/s3db-replicator.class.js +29 -11
- package/src/plugins/replicators/sqs-replicator.class.js +23 -5
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
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
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
|
-
|
|
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(JSON.stringify(errors2, null, 2));
|
|
9042
|
+
if (response) console.error(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
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
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
|
}
|
|
@@ -9344,16 +9378,18 @@ class PostgresReplicator extends base_replicator_class_default {
|
|
|
9344
9378
|
const [okTable, errTable] = await try_fn_default(async () => {
|
|
9345
9379
|
let result2;
|
|
9346
9380
|
if (operation === "insert") {
|
|
9347
|
-
const
|
|
9348
|
-
const
|
|
9381
|
+
const cleanData = this._cleanInternalFields(data);
|
|
9382
|
+
const keys = Object.keys(cleanData);
|
|
9383
|
+
const values = keys.map((k) => cleanData[k]);
|
|
9349
9384
|
const columns = keys.map((k) => `"${k}"`).join(", ");
|
|
9350
9385
|
const params = keys.map((_, i) => `$${i + 1}`).join(", ");
|
|
9351
9386
|
const sql = `INSERT INTO ${table} (${columns}) VALUES (${params}) ON CONFLICT (id) DO NOTHING RETURNING *`;
|
|
9352
9387
|
result2 = await this.client.query(sql, values);
|
|
9353
9388
|
} else if (operation === "update") {
|
|
9354
|
-
const
|
|
9389
|
+
const cleanData = this._cleanInternalFields(data);
|
|
9390
|
+
const keys = Object.keys(cleanData).filter((k) => k !== "id");
|
|
9355
9391
|
const setClause = keys.map((k, i) => `"${k}"=$${i + 1}`).join(", ");
|
|
9356
|
-
const values = keys.map((k) =>
|
|
9392
|
+
const values = keys.map((k) => cleanData[k]);
|
|
9357
9393
|
values.push(id);
|
|
9358
9394
|
const sql = `UPDATE ${table} SET ${setClause} WHERE id=$${keys.length + 1} RETURNING *`;
|
|
9359
9395
|
result2 = await this.client.query(sql, values);
|
|
@@ -9463,6 +9499,16 @@ class PostgresReplicator extends base_replicator_class_default {
|
|
|
9463
9499
|
this.emit("connection_error", { replicator: this.name, error: err.message });
|
|
9464
9500
|
return false;
|
|
9465
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
|
+
}
|
|
9466
9512
|
async cleanup() {
|
|
9467
9513
|
if (this.client) await this.client.end();
|
|
9468
9514
|
}
|
|
@@ -13194,7 +13240,7 @@ class Database extends EventEmitter {
|
|
|
13194
13240
|
super();
|
|
13195
13241
|
this.version = "1";
|
|
13196
13242
|
this.s3dbVersion = (() => {
|
|
13197
|
-
const [ok, err, version] = try_fn_default(() => true ? "7.3.
|
|
13243
|
+
const [ok, err, version] = try_fn_default(() => true ? "7.3.10" : "latest");
|
|
13198
13244
|
return ok ? version : "latest";
|
|
13199
13245
|
})();
|
|
13200
13246
|
this.resources = {};
|
|
@@ -13858,36 +13904,47 @@ class S3dbReplicator extends base_replicator_class_default {
|
|
|
13858
13904
|
return result;
|
|
13859
13905
|
}
|
|
13860
13906
|
_applyTransformer(resource, data) {
|
|
13907
|
+
let cleanData = this._cleanInternalFields(data);
|
|
13861
13908
|
const normResource = normalizeResourceName$1(resource);
|
|
13862
13909
|
const entry = this.resourcesMap[normResource];
|
|
13863
13910
|
let result;
|
|
13864
|
-
if (!entry) return
|
|
13911
|
+
if (!entry) return cleanData;
|
|
13865
13912
|
if (Array.isArray(entry)) {
|
|
13866
13913
|
for (const item of entry) {
|
|
13867
13914
|
if (typeof item === "object" && item.transform && typeof item.transform === "function") {
|
|
13868
|
-
result = item.transform(
|
|
13915
|
+
result = item.transform(cleanData);
|
|
13869
13916
|
break;
|
|
13870
13917
|
} else if (typeof item === "object" && item.transformer && typeof item.transformer === "function") {
|
|
13871
|
-
result = item.transformer(
|
|
13918
|
+
result = item.transformer(cleanData);
|
|
13872
13919
|
break;
|
|
13873
13920
|
}
|
|
13874
13921
|
}
|
|
13875
|
-
if (!result) result =
|
|
13922
|
+
if (!result) result = cleanData;
|
|
13876
13923
|
} else if (typeof entry === "object") {
|
|
13877
13924
|
if (typeof entry.transform === "function") {
|
|
13878
|
-
result = entry.transform(
|
|
13925
|
+
result = entry.transform(cleanData);
|
|
13879
13926
|
} else if (typeof entry.transformer === "function") {
|
|
13880
|
-
result = entry.transformer(
|
|
13927
|
+
result = entry.transformer(cleanData);
|
|
13881
13928
|
}
|
|
13882
13929
|
} else if (typeof entry === "function") {
|
|
13883
|
-
result = entry(
|
|
13930
|
+
result = entry(cleanData);
|
|
13884
13931
|
} else {
|
|
13885
|
-
result =
|
|
13932
|
+
result = cleanData;
|
|
13886
13933
|
}
|
|
13887
|
-
if (result &&
|
|
13888
|
-
if (!result &&
|
|
13934
|
+
if (result && cleanData && cleanData.id && !result.id) result.id = cleanData.id;
|
|
13935
|
+
if (!result && cleanData) result = cleanData;
|
|
13889
13936
|
return result;
|
|
13890
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
|
+
}
|
|
13891
13948
|
_resolveDestResource(resource, data) {
|
|
13892
13949
|
const normResource = normalizeResourceName$1(resource);
|
|
13893
13950
|
const entry = this.resourcesMap[normResource];
|
|
@@ -14077,15 +14134,26 @@ class SqsReplicator extends base_replicator_class_default {
|
|
|
14077
14134
|
throw new Error(`No queue URL found for resource '${resource}'`);
|
|
14078
14135
|
}
|
|
14079
14136
|
_applyTransformer(resource, data) {
|
|
14137
|
+
let cleanData = this._cleanInternalFields(data);
|
|
14080
14138
|
const entry = this.resources[resource];
|
|
14081
|
-
let result =
|
|
14082
|
-
if (!entry) return
|
|
14139
|
+
let result = cleanData;
|
|
14140
|
+
if (!entry) return cleanData;
|
|
14083
14141
|
if (typeof entry.transform === "function") {
|
|
14084
|
-
result = entry.transform(
|
|
14142
|
+
result = entry.transform(cleanData);
|
|
14085
14143
|
} else if (typeof entry.transformer === "function") {
|
|
14086
|
-
result = entry.transformer(
|
|
14144
|
+
result = entry.transformer(cleanData);
|
|
14087
14145
|
}
|
|
14088
|
-
return result ||
|
|
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;
|
|
14089
14157
|
}
|
|
14090
14158
|
/**
|
|
14091
14159
|
* Create standardized message structure
|