From 4118ccebe3b72094e24f83015d97a7370b71a18c Mon Sep 17 00:00:00 2001
From: Petr Kachanovsky
Date: Wed, 9 Apr 2025 11:24:23 +0300
Subject: [PATCH 1/4] fix: fix filter by autogenerated _id for mongodb
---
adminforth/dataConnectors/mongo.ts | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/adminforth/dataConnectors/mongo.ts b/adminforth/dataConnectors/mongo.ts
index b07ff5c7..1d88694e 100644
--- a/adminforth/dataConnectors/mongo.ts
+++ b/adminforth/dataConnectors/mongo.ts
@@ -1,6 +1,6 @@
import dayjs from 'dayjs';
import { MongoClient } from 'mongodb';
-import { Decimal128 } from 'bson';
+import { Decimal128, ObjectId } from 'bson';
import { IAdminForthDataSourceConnector, IAdminForthSingleFilter, IAdminForthAndOrFilter, AdminForthResource } from '../types/Back.js';
import AdminForthBaseConnector from './baseConnector.js';
@@ -64,14 +64,6 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
}, {});
}
- getPrimaryKey(resource) {
- for (const col of resource.dataSourceColumns) {
- if (col.primaryKey) {
- return col.name;
- }
- }
- }
-
getFieldValue(field, value) {
if (field.type == AdminForthDataTypes.DATETIME) {
if (!value) {
@@ -89,6 +81,9 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
return !!value;
} else if (field.type == AdminForthDataTypes.DECIMAL) {
return value?.toString();
+ } else if (field.name === '_id' && !field.fillOnCreate) {
+ // if "_id" was created by mongo it will be ObjectId
+ return value?.toString();
}
return value;
@@ -111,6 +106,9 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
return value ? true : false;
} else if (field.type == AdminForthDataTypes.DECIMAL) {
return Decimal128.fromString(value?.toString());
+ } else if (field.name === '_id' && !field.fillOnCreate) {
+ // if "_id" was created by mongo it supposed to be saved as ObjectId
+ return ObjectId.createFromHexString(value);
}
return value;
}
From 52868140d583c3ec90428fb595c3e6bc6fbb0d29 Mon Sep 17 00:00:00 2001
From: Petr Kachanovsky
Date: Fri, 11 Apr 2025 10:03:22 +0300
Subject: [PATCH 2/4] change mongo _id transformation to fix filtering
---
adminforth/dataConnectors/mongo.ts | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/adminforth/dataConnectors/mongo.ts b/adminforth/dataConnectors/mongo.ts
index 1d88694e..5ddccc20 100644
--- a/adminforth/dataConnectors/mongo.ts
+++ b/adminforth/dataConnectors/mongo.ts
@@ -82,8 +82,10 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
} else if (field.type == AdminForthDataTypes.DECIMAL) {
return value?.toString();
} else if (field.name === '_id' && !field.fillOnCreate) {
- // if "_id" was created by mongo it will be ObjectId
- return value?.toString();
+ // value is supposed to be an ObjectId or string representing it
+ if (typeof value === 'object') {
+ return value?.toString();
+ }
}
return value;
@@ -107,8 +109,20 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
} else if (field.type == AdminForthDataTypes.DECIMAL) {
return Decimal128.fromString(value?.toString());
} else if (field.name === '_id' && !field.fillOnCreate) {
- // if "_id" was created by mongo it supposed to be saved as ObjectId
- return ObjectId.createFromHexString(value);
+ // value is supposed to be an ObjectId
+ if (!ObjectId.isValid(value)) {
+ return null;
+ }
+ if (typeof value === 'string' || typeof value === 'number') {
+ // if string or number - turn it into ObjectId
+ return new ObjectId(value);
+ } else if (typeof value === 'object') {
+ // assume it is a correct ObjectId
+ return value;
+ }
+
+ // unsupported type for ObjectId
+ return null;
}
return value;
}
@@ -203,7 +217,8 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
async updateRecordOriginalValues({ resource, recordId, newValues }) {
const collection = this.client.db().collection(resource.table);
- await collection.updateOne({ [this.getPrimaryKey(resource)]: recordId }, { $set: newValues });
+ const primaryKeyColumn = resource.dataSourceColumns.find((col) => col.name === this.getPrimaryKey(resource));
+ await collection.updateOne({ [primaryKeyColumn.name]: this.setFieldValue(primaryKeyColumn, recordId) }, { $set: newValues });
}
async deleteRecord({ resource, recordId }): Promise {
From 08154a93266fade0187e793e1fde4951efde0ace Mon Sep 17 00:00:00 2001
From: Petr Kachanovsky
Date: Fri, 11 Apr 2025 10:07:16 +0300
Subject: [PATCH 3/4] add filter normalization to connector requests
---
adminforth/dataConnectors/baseConnector.ts | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/adminforth/dataConnectors/baseConnector.ts b/adminforth/dataConnectors/baseConnector.ts
index 3d032415..0198a944 100644
--- a/adminforth/dataConnectors/baseConnector.ts
+++ b/adminforth/dataConnectors/baseConnector.ts
@@ -37,7 +37,14 @@ export default class AdminForthBaseConnector implements IAdminForthDataSourceCon
limit: 1,
offset: 0,
sort: [],
- filters: { operator: AdminForthFilterOperators.AND, subFilters: [{ field: this.getPrimaryKey(resource), operator: AdminForthFilterOperators.EQ, value: id }]},
+ filters: {
+ operator: AdminForthFilterOperators.AND,
+ subFilters: [{
+ field: this.getPrimaryKey(resource),
+ operator: AdminForthFilterOperators.EQ,
+ value: this.setFieldValue(resource.dataSourceColumns.find((col) => col.name === this.getPrimaryKey(resource)), id),
+ }],
+ },
});
return data.length > 0 ? data[0] : null;
}
@@ -191,7 +198,14 @@ export default class AdminForthBaseConnector implements IAdminForthDataSourceCon
process.env.HEAVY_DEBUG && console.log('☝️🪲🪲🪲🪲 checkUnique|||', column, value);
const existingRecord = await this.getData({
resource,
- filters: { operator: AdminForthFilterOperators.AND, subFilters: [{ field: column.name, operator: AdminForthFilterOperators.EQ, value }]},
+ filters: {
+ operator: AdminForthFilterOperators.AND,
+ subFilters: [{
+ field: column.name,
+ operator: AdminForthFilterOperators.EQ,
+ value: this.setFieldValue(column, value),
+ }],
+ },
limit: 1,
sort: [],
offset: 0,
From 5ba0c0e9eb4fded8d9742f0d0d9dca8009c72847 Mon Sep 17 00:00:00 2001
From: Petr Kachanovsky
Date: Fri, 11 Apr 2025 10:21:12 +0300
Subject: [PATCH 4/4] fix mongo delete record filter
---
adminforth/dataConnectors/mongo.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/adminforth/dataConnectors/mongo.ts b/adminforth/dataConnectors/mongo.ts
index 5ddccc20..dac3bc6c 100644
--- a/adminforth/dataConnectors/mongo.ts
+++ b/adminforth/dataConnectors/mongo.ts
@@ -222,9 +222,9 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
}
async deleteRecord({ resource, recordId }): Promise {
- const primaryKey = this.getPrimaryKey(resource);
const collection = this.client.db().collection(resource.table);
- const res = await collection.deleteOne({ [primaryKey]: recordId });
+ const primaryKeyColumn = resource.dataSourceColumns.find((col) => col.name === this.getPrimaryKey(resource));
+ const res = await collection.deleteOne({ [primaryKeyColumn.name]: this.setFieldValue(primaryKeyColumn, recordId) });
return res.deletedCount > 0;
}