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.iife.js
CHANGED
|
@@ -8983,11 +8983,21 @@ ${JSON.stringify(validation, null, 2)}`,
|
|
|
8983
8983
|
}));
|
|
8984
8984
|
}
|
|
8985
8985
|
applyTransform(data, transformFn) {
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8986
|
+
let cleanData = this._cleanInternalFields(data);
|
|
8987
|
+
if (!transformFn) return cleanData;
|
|
8988
|
+
let transformedData = JSON.parse(JSON.stringify(cleanData));
|
|
8989
8989
|
return transformFn(transformedData);
|
|
8990
8990
|
}
|
|
8991
|
+
_cleanInternalFields(data) {
|
|
8992
|
+
if (!data || typeof data !== "object") return data;
|
|
8993
|
+
const cleanData = { ...data };
|
|
8994
|
+
Object.keys(cleanData).forEach((key) => {
|
|
8995
|
+
if (key.startsWith("$") || key.startsWith("_")) {
|
|
8996
|
+
delete cleanData[key];
|
|
8997
|
+
}
|
|
8998
|
+
});
|
|
8999
|
+
return cleanData;
|
|
9000
|
+
}
|
|
8991
9001
|
async replicate(resourceName, operation, data, id, beforeData = null) {
|
|
8992
9002
|
if (!this.enabled || !this.shouldReplicateResource(resourceName)) {
|
|
8993
9003
|
return { skipped: true, reason: "resource_not_included" };
|
|
@@ -9009,7 +9019,17 @@ ${JSON.stringify(validation, null, 2)}`,
|
|
|
9009
9019
|
let job;
|
|
9010
9020
|
if (operation === "insert") {
|
|
9011
9021
|
const transformedData = this.applyTransform(data, tableConfig.transform);
|
|
9012
|
-
|
|
9022
|
+
try {
|
|
9023
|
+
job = await table.insert([transformedData]);
|
|
9024
|
+
} catch (error) {
|
|
9025
|
+
const { errors: errors2, response } = error;
|
|
9026
|
+
if (this.config.verbose) {
|
|
9027
|
+
console.error("[BigqueryReplicator] BigQuery insert error details:");
|
|
9028
|
+
if (errors2) console.error(JSON.stringify(errors2, null, 2));
|
|
9029
|
+
if (response) console.error(JSON.stringify(response, null, 2));
|
|
9030
|
+
}
|
|
9031
|
+
throw error;
|
|
9032
|
+
}
|
|
9013
9033
|
} else if (operation === "update") {
|
|
9014
9034
|
const transformedData = this.applyTransform(data, tableConfig.transform);
|
|
9015
9035
|
const keys = Object.keys(transformedData).filter((k) => k !== "id");
|
|
@@ -9035,6 +9055,10 @@ ${JSON.stringify(validation, null, 2)}`,
|
|
|
9035
9055
|
lastError = error;
|
|
9036
9056
|
if (this.config.verbose) {
|
|
9037
9057
|
console.warn(`[BigqueryReplicator] Update attempt ${attempt} failed: ${error.message}`);
|
|
9058
|
+
if (error.errors) {
|
|
9059
|
+
console.error("[BigqueryReplicator] BigQuery update error details:");
|
|
9060
|
+
console.error("Errors:", JSON.stringify(error.errors, null, 2));
|
|
9061
|
+
}
|
|
9038
9062
|
}
|
|
9039
9063
|
if (error?.message?.includes("streaming buffer") && attempt < maxRetries) {
|
|
9040
9064
|
const delaySeconds = 30;
|
|
@@ -9050,13 +9074,23 @@ ${JSON.stringify(validation, null, 2)}`,
|
|
|
9050
9074
|
if (!job) throw lastError;
|
|
9051
9075
|
} else if (operation === "delete") {
|
|
9052
9076
|
const query = `DELETE FROM \`${this.projectId}.${this.datasetId}.${tableConfig.table}\` WHERE id = @id`;
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9077
|
+
try {
|
|
9078
|
+
const [deleteJob] = await this.bigqueryClient.createQueryJob({
|
|
9079
|
+
query,
|
|
9080
|
+
params: { id },
|
|
9081
|
+
location: this.location
|
|
9082
|
+
});
|
|
9083
|
+
await deleteJob.getQueryResults();
|
|
9084
|
+
job = [deleteJob];
|
|
9085
|
+
} catch (error) {
|
|
9086
|
+
if (this.config.verbose) {
|
|
9087
|
+
console.error("[BigqueryReplicator] BigQuery delete error details:");
|
|
9088
|
+
console.error("Query:", query);
|
|
9089
|
+
if (error.errors) console.error("Errors:", JSON.stringify(error.errors, null, 2));
|
|
9090
|
+
if (error.response) console.error("Response:", JSON.stringify(error.response, null, 2));
|
|
9091
|
+
}
|
|
9092
|
+
throw error;
|
|
9093
|
+
}
|
|
9060
9094
|
} else {
|
|
9061
9095
|
throw new Error(`Unsupported operation: ${operation}`);
|
|
9062
9096
|
}
|
|
@@ -9331,16 +9365,18 @@ ${JSON.stringify(validation, null, 2)}`,
|
|
|
9331
9365
|
const [okTable, errTable] = await try_fn_default(async () => {
|
|
9332
9366
|
let result2;
|
|
9333
9367
|
if (operation === "insert") {
|
|
9334
|
-
const
|
|
9335
|
-
const
|
|
9368
|
+
const cleanData = this._cleanInternalFields(data);
|
|
9369
|
+
const keys = Object.keys(cleanData);
|
|
9370
|
+
const values = keys.map((k) => cleanData[k]);
|
|
9336
9371
|
const columns = keys.map((k) => `"${k}"`).join(", ");
|
|
9337
9372
|
const params = keys.map((_, i) => `$${i + 1}`).join(", ");
|
|
9338
9373
|
const sql = `INSERT INTO ${table} (${columns}) VALUES (${params}) ON CONFLICT (id) DO NOTHING RETURNING *`;
|
|
9339
9374
|
result2 = await this.client.query(sql, values);
|
|
9340
9375
|
} else if (operation === "update") {
|
|
9341
|
-
const
|
|
9376
|
+
const cleanData = this._cleanInternalFields(data);
|
|
9377
|
+
const keys = Object.keys(cleanData).filter((k) => k !== "id");
|
|
9342
9378
|
const setClause = keys.map((k, i) => `"${k}"=$${i + 1}`).join(", ");
|
|
9343
|
-
const values = keys.map((k) =>
|
|
9379
|
+
const values = keys.map((k) => cleanData[k]);
|
|
9344
9380
|
values.push(id);
|
|
9345
9381
|
const sql = `UPDATE ${table} SET ${setClause} WHERE id=$${keys.length + 1} RETURNING *`;
|
|
9346
9382
|
result2 = await this.client.query(sql, values);
|
|
@@ -9450,6 +9486,16 @@ ${JSON.stringify(validation, null, 2)}`,
|
|
|
9450
9486
|
this.emit("connection_error", { replicator: this.name, error: err.message });
|
|
9451
9487
|
return false;
|
|
9452
9488
|
}
|
|
9489
|
+
_cleanInternalFields(data) {
|
|
9490
|
+
if (!data || typeof data !== "object") return data;
|
|
9491
|
+
const cleanData = { ...data };
|
|
9492
|
+
Object.keys(cleanData).forEach((key) => {
|
|
9493
|
+
if (key.startsWith("$") || key.startsWith("_")) {
|
|
9494
|
+
delete cleanData[key];
|
|
9495
|
+
}
|
|
9496
|
+
});
|
|
9497
|
+
return cleanData;
|
|
9498
|
+
}
|
|
9453
9499
|
async cleanup() {
|
|
9454
9500
|
if (this.client) await this.client.end();
|
|
9455
9501
|
}
|
|
@@ -13181,7 +13227,7 @@ ${JSON.stringify(validation, null, 2)}`,
|
|
|
13181
13227
|
super();
|
|
13182
13228
|
this.version = "1";
|
|
13183
13229
|
this.s3dbVersion = (() => {
|
|
13184
|
-
const [ok, err, version] = try_fn_default(() => true ? "7.3.
|
|
13230
|
+
const [ok, err, version] = try_fn_default(() => true ? "7.3.10" : "latest");
|
|
13185
13231
|
return ok ? version : "latest";
|
|
13186
13232
|
})();
|
|
13187
13233
|
this.resources = {};
|
|
@@ -13845,36 +13891,47 @@ ${JSON.stringify(validation, null, 2)}`,
|
|
|
13845
13891
|
return result;
|
|
13846
13892
|
}
|
|
13847
13893
|
_applyTransformer(resource, data) {
|
|
13894
|
+
let cleanData = this._cleanInternalFields(data);
|
|
13848
13895
|
const normResource = normalizeResourceName$1(resource);
|
|
13849
13896
|
const entry = this.resourcesMap[normResource];
|
|
13850
13897
|
let result;
|
|
13851
|
-
if (!entry) return
|
|
13898
|
+
if (!entry) return cleanData;
|
|
13852
13899
|
if (Array.isArray(entry)) {
|
|
13853
13900
|
for (const item of entry) {
|
|
13854
13901
|
if (typeof item === "object" && item.transform && typeof item.transform === "function") {
|
|
13855
|
-
result = item.transform(
|
|
13902
|
+
result = item.transform(cleanData);
|
|
13856
13903
|
break;
|
|
13857
13904
|
} else if (typeof item === "object" && item.transformer && typeof item.transformer === "function") {
|
|
13858
|
-
result = item.transformer(
|
|
13905
|
+
result = item.transformer(cleanData);
|
|
13859
13906
|
break;
|
|
13860
13907
|
}
|
|
13861
13908
|
}
|
|
13862
|
-
if (!result) result =
|
|
13909
|
+
if (!result) result = cleanData;
|
|
13863
13910
|
} else if (typeof entry === "object") {
|
|
13864
13911
|
if (typeof entry.transform === "function") {
|
|
13865
|
-
result = entry.transform(
|
|
13912
|
+
result = entry.transform(cleanData);
|
|
13866
13913
|
} else if (typeof entry.transformer === "function") {
|
|
13867
|
-
result = entry.transformer(
|
|
13914
|
+
result = entry.transformer(cleanData);
|
|
13868
13915
|
}
|
|
13869
13916
|
} else if (typeof entry === "function") {
|
|
13870
|
-
result = entry(
|
|
13917
|
+
result = entry(cleanData);
|
|
13871
13918
|
} else {
|
|
13872
|
-
result =
|
|
13919
|
+
result = cleanData;
|
|
13873
13920
|
}
|
|
13874
|
-
if (result &&
|
|
13875
|
-
if (!result &&
|
|
13921
|
+
if (result && cleanData && cleanData.id && !result.id) result.id = cleanData.id;
|
|
13922
|
+
if (!result && cleanData) result = cleanData;
|
|
13876
13923
|
return result;
|
|
13877
13924
|
}
|
|
13925
|
+
_cleanInternalFields(data) {
|
|
13926
|
+
if (!data || typeof data !== "object") return data;
|
|
13927
|
+
const cleanData = { ...data };
|
|
13928
|
+
Object.keys(cleanData).forEach((key) => {
|
|
13929
|
+
if (key.startsWith("$") || key.startsWith("_")) {
|
|
13930
|
+
delete cleanData[key];
|
|
13931
|
+
}
|
|
13932
|
+
});
|
|
13933
|
+
return cleanData;
|
|
13934
|
+
}
|
|
13878
13935
|
_resolveDestResource(resource, data) {
|
|
13879
13936
|
const normResource = normalizeResourceName$1(resource);
|
|
13880
13937
|
const entry = this.resourcesMap[normResource];
|
|
@@ -14064,15 +14121,26 @@ ${JSON.stringify(validation, null, 2)}`,
|
|
|
14064
14121
|
throw new Error(`No queue URL found for resource '${resource}'`);
|
|
14065
14122
|
}
|
|
14066
14123
|
_applyTransformer(resource, data) {
|
|
14124
|
+
let cleanData = this._cleanInternalFields(data);
|
|
14067
14125
|
const entry = this.resources[resource];
|
|
14068
|
-
let result =
|
|
14069
|
-
if (!entry) return
|
|
14126
|
+
let result = cleanData;
|
|
14127
|
+
if (!entry) return cleanData;
|
|
14070
14128
|
if (typeof entry.transform === "function") {
|
|
14071
|
-
result = entry.transform(
|
|
14129
|
+
result = entry.transform(cleanData);
|
|
14072
14130
|
} else if (typeof entry.transformer === "function") {
|
|
14073
|
-
result = entry.transformer(
|
|
14131
|
+
result = entry.transformer(cleanData);
|
|
14074
14132
|
}
|
|
14075
|
-
return result ||
|
|
14133
|
+
return result || cleanData;
|
|
14134
|
+
}
|
|
14135
|
+
_cleanInternalFields(data) {
|
|
14136
|
+
if (!data || typeof data !== "object") return data;
|
|
14137
|
+
const cleanData = { ...data };
|
|
14138
|
+
Object.keys(cleanData).forEach((key) => {
|
|
14139
|
+
if (key.startsWith("$") || key.startsWith("_")) {
|
|
14140
|
+
delete cleanData[key];
|
|
14141
|
+
}
|
|
14142
|
+
});
|
|
14143
|
+
return cleanData;
|
|
14076
14144
|
}
|
|
14077
14145
|
/**
|
|
14078
14146
|
* Create standardized message structure
|