From 67fba601d95ca035851207b2115fb1ba57542959 Mon Sep 17 00:00:00 2001 From: Vitalii Kulyk Date: Fri, 7 Mar 2025 14:08:25 +0200 Subject: [PATCH 1/2] polymor --- adminforth/modules/configValidator.ts | 5 ++--- adminforth/modules/restApi.ts | 12 +++++++++++- dev-demo/resources/api_keys.ts | 4 ++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/adminforth/modules/configValidator.ts b/adminforth/modules/configValidator.ts index 367ac857a..2abbafc35 100644 --- a/adminforth/modules/configValidator.ts +++ b/adminforth/modules/configValidator.ts @@ -505,7 +505,6 @@ export default class ConfigValidator implements IConfigValidator { } if (col.foreignResource) { - if (!col.foreignResource.resourceId) { // resourceId is absent or empty if (!col.foreignResource.polymorphicResources && !col.foreignResource.polymorphicOn) { @@ -525,11 +524,11 @@ export default class ConfigValidator implements IConfigValidator { } // we do || here because 'resourceId' might yet not be assigned from 'table' col.foreignResource.polymorphicResources.forEach((polymorphicResource, polymorphicResourceIndex) => { - if (!polymorphicResource.resourceId) { + if (polymorphicResource.resourceId === undefined) { errors.push(`Resource "${res.resourceId}" column "${col.name}" has polymorphic foreign resource without resourceId`); } else if (!polymorphicResource.whenValue) { errors.push(`Resource "${res.resourceId}" column "${col.name}" has polymorphic foreign resource without whenValue`); - } else { + } else if (polymorphicResource.resourceId !== null) { const resource = this.inputConfig.resources.find((r) => r.resourceId === polymorphicResource.resourceId || r.table === polymorphicResource.resourceId); if (!resource) { const similar = suggestIfTypo(this.inputConfig.resources.map((r) => r.resourceId || r.table), polymorphicResource.resourceId); diff --git a/adminforth/modules/restApi.ts b/adminforth/modules/restApi.ts index 2f98b73d7..2960c8127 100644 --- a/adminforth/modules/restApi.ts +++ b/adminforth/modules/restApi.ts @@ -703,6 +703,9 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { const targetResourcePkFields = {}; const pksUniques = {}; col.foreignResource.polymorphicResources.forEach((pr) => { + if (pr.resourceId === null) { + return; + } targetResources[pr.whenValue] = this.adminforth.config.resources.find((res) => res.resourceId == pr.resourceId); targetConnectors[pr.whenValue] = this.adminforth.connectors[targetResources[pr.whenValue].dataSource]; targetResourcePkFields[pr.whenValue] = targetResources[pr.whenValue].columns.find((col) => col.primaryKey).name; @@ -747,6 +750,13 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { data.data.forEach((item) => { item[col.name] = targetDataMap[item[col.name]]; + + if (!item[col.name]) { + const systemResource = col.foreignResource.polymorphicResources.find(pr => pr.resourceId === null); + if (systemResource) { + item[col.foreignResource.polymorphicOn] = systemResource.whenValue; + } + } }); }) ); @@ -819,7 +829,7 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { return { error: `Column '${column}' in resource '${resourceId}' is not a foreign key` }; } - const targetResourceIds = columnConfig.foreignResource.resourceId ? [columnConfig.foreignResource.resourceId] : columnConfig.foreignResource.polymorphicResources.map((pr) => pr.resourceId); + const targetResourceIds = columnConfig.foreignResource.resourceId ? [columnConfig.foreignResource.resourceId] : columnConfig.foreignResource.polymorphicResources.filter(pr => pr.resourceId !== null).map((pr) => pr.resourceId); const targetResources = targetResourceIds.map((trId) => this.adminforth.config.resources.find((res) => res.resourceId == trId)); const responses = (await Promise.all( diff --git a/dev-demo/resources/api_keys.ts b/dev-demo/resources/api_keys.ts index cd055ae8b..429896c81 100644 --- a/dev-demo/resources/api_keys.ts +++ b/dev-demo/resources/api_keys.ts @@ -54,6 +54,10 @@ export default { resourceId: 'providers', whenValue: 'provider', }, + { + resourceId: null, + whenValue: 'Syst1em', + }, ], polymorphicOn: 'owner', }, From 9873c6f7722d7ea47790747feeb4f03082d0ba01 Mon Sep 17 00:00:00 2001 From: Vitalii Kulyk Date: Fri, 7 Mar 2025 14:12:21 +0200 Subject: [PATCH 2/2] fix: handle null resourceId in polymorphic foreign resources --- adminforth/modules/restApi.ts | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/adminforth/modules/restApi.ts b/adminforth/modules/restApi.ts index 2960c8127..92b4ebaa4 100644 --- a/adminforth/modules/restApi.ts +++ b/adminforth/modules/restApi.ts @@ -706,7 +706,11 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { if (pr.resourceId === null) { return; } - targetResources[pr.whenValue] = this.adminforth.config.resources.find((res) => res.resourceId == pr.resourceId); + const targetResource = this.adminforth.config.resources.find((res) => res.resourceId == pr.resourceId); + if (!targetResource) { + return; + } + targetResources[pr.whenValue] = targetResource; targetConnectors[pr.whenValue] = this.adminforth.connectors[targetResources[pr.whenValue].dataSource]; targetResourcePkFields[pr.whenValue] = targetResources[pr.whenValue].columns.find((col) => col.primaryKey).name; const pksUnique = [...new Set(data.data.filter((item) => item[col.foreignResource.polymorphicOn] === pr.whenValue).map((item) => item[col.name]))]; @@ -984,7 +988,14 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { const targetConnectors = {}; const targetResourcePkFields = {}; column.foreignResource.polymorphicResources.forEach((pr) => { - targetResources[pr.whenValue] = this.adminforth.config.resources.find((res) => res.resourceId == pr.resourceId); + if (pr.resourceId === null) { + return; + } + const targetResource = this.adminforth.config.resources.find((res) => res.resourceId == pr.resourceId); + if (!targetResource) { + return; + } + targetResources[pr.whenValue] = targetResource; targetConnectors[pr.whenValue] = this.adminforth.connectors[targetResources[pr.whenValue].dataSource]; targetResourcePkFields[pr.whenValue] = targetResources[pr.whenValue].columns.find((col) => col.primaryKey).name; }); @@ -1072,7 +1083,14 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI { const targetConnectors = {}; const targetResourcePkFields = {}; column.foreignResource.polymorphicResources.forEach((pr) => { - targetResources[pr.whenValue] = this.adminforth.config.resources.find((res) => res.resourceId == pr.resourceId); + if (pr.resourceId === null) { + return; + } + const targetResource = this.adminforth.config.resources.find((res) => res.resourceId == pr.resourceId); + if (!targetResource) { + return; + } + targetResources[pr.whenValue] = targetResource; targetConnectors[pr.whenValue] = this.adminforth.connectors[targetResources[pr.whenValue].dataSource]; targetResourcePkFields[pr.whenValue] = targetResources[pr.whenValue].columns.find((col) => col.primaryKey).name; });