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; }