From 9edd73dc6edc6ac27c37df94b2409c2e3fd830f3 Mon Sep 17 00:00:00 2001 From: Pavlo Kulyk Date: Thu, 30 Apr 2026 15:20:10 +0300 Subject: [PATCH 1/8] feat: add test_decimal field to cars model and update related resources --- adminforth/dataConnectors/postgres.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/adminforth/dataConnectors/postgres.ts b/adminforth/dataConnectors/postgres.ts index f91f38cc..3c7c3ccd 100644 --- a/adminforth/dataConnectors/postgres.ts +++ b/adminforth/dataConnectors/postgres.ts @@ -12,6 +12,7 @@ const { Client, types } = pkg; // which treats them as LOCAL server time. Return raw strings so getFieldValue can parse as UTC. types.setTypeParser(1114, (val) => val); // TIMESTAMP WITHOUT TIME ZONE types.setTypeParser(1082, (val) => val); // DATE +types.setTypeParser(1700, (val) => val === null ? null : parseFloat(val).toString()); // NUMERIC/DECIMAL class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDataSourceConnector { From 1c89c55b8cef061233e0fdb7bfd29308a3bc2265 Mon Sep 17 00:00:00 2001 From: Pavlo Kulyk Date: Fri, 1 May 2026 10:20:52 +0300 Subject: [PATCH 2/8] feat: add parse decimal --- adminforth/dataConnectors/postgres.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/adminforth/dataConnectors/postgres.ts b/adminforth/dataConnectors/postgres.ts index 3c7c3ccd..1f1ccd61 100644 --- a/adminforth/dataConnectors/postgres.ts +++ b/adminforth/dataConnectors/postgres.ts @@ -12,8 +12,6 @@ const { Client, types } = pkg; // which treats them as LOCAL server time. Return raw strings so getFieldValue can parse as UTC. types.setTypeParser(1114, (val) => val); // TIMESTAMP WITHOUT TIME ZONE types.setTypeParser(1082, (val) => val); // DATE -types.setTypeParser(1700, (val) => val === null ? null : parseFloat(val).toString()); // NUMERIC/DECIMAL - class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDataSourceConnector { @@ -215,6 +213,11 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa } } + if (field.type === AdminForthDataTypes.DECIMAL) { + const parsed = Number(value); + return isNaN(parsed) ? value : parsed; + } + if (field.type == AdminForthDataTypes.DATE) { if (!value) { return null; From 2903b8967f2499494c447161776e38edabe00d93 Mon Sep 17 00:00:00 2001 From: Pavlo Kulyk Date: Fri, 1 May 2026 11:10:48 +0300 Subject: [PATCH 3/8] feat: enhance decimal parsing to trim trailing zeros --- adminforth/dataConnectors/postgres.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/adminforth/dataConnectors/postgres.ts b/adminforth/dataConnectors/postgres.ts index 1f1ccd61..9da70db1 100644 --- a/adminforth/dataConnectors/postgres.ts +++ b/adminforth/dataConnectors/postgres.ts @@ -214,8 +214,19 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa } if (field.type === AdminForthDataTypes.DECIMAL) { - const parsed = Number(value); - return isNaN(parsed) ? value : parsed; + if (value !== null && value !== undefined) { + + if (value.includes('.')) { + + let trimmed = value.replace(/0+$/, ''); + + if (trimmed.endsWith('.')) { + return trimmed.slice(0, -1); + } + return trimmed; + } + } + return value; } if (field.type == AdminForthDataTypes.DATE) { From e6585a3d40d4ff73b294914081ab26687e5830f7 Mon Sep 17 00:00:00 2001 From: Pavlo Kulyk Date: Fri, 1 May 2026 14:49:41 +0300 Subject: [PATCH 4/8] feat: add decimal.js for enhanced decimal handling and update parsing logic --- adminforth/dataConnectors/postgres.ts | 12 ++---------- adminforth/package-lock.json | 7 +++++++ adminforth/package.json | 1 + adminforth/pnpm-lock.yaml | 8 ++++++++ 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/adminforth/dataConnectors/postgres.ts b/adminforth/dataConnectors/postgres.ts index 9da70db1..881f80b0 100644 --- a/adminforth/dataConnectors/postgres.ts +++ b/adminforth/dataConnectors/postgres.ts @@ -4,6 +4,7 @@ import { AdminForthDataTypes, AdminForthFilterOperators, AdminForthSortDirection import AdminForthBaseConnector from './baseConnector.js'; import pkg from 'pg'; import { afLogger, dbLogger } from '../modules/logger.js'; +import { Decimal } from 'decimal.js'; const { Pool } = pkg; const { Client, types } = pkg; @@ -215,16 +216,7 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa if (field.type === AdminForthDataTypes.DECIMAL) { if (value !== null && value !== undefined) { - - if (value.includes('.')) { - - let trimmed = value.replace(/0+$/, ''); - - if (trimmed.endsWith('.')) { - return trimmed.slice(0, -1); - } - return trimmed; - } + return new Decimal(value).toSignificantDigits().toString(); } return value; } diff --git a/adminforth/package-lock.json b/adminforth/package-lock.json index bc3c2f0d..02b70799 100644 --- a/adminforth/package-lock.json +++ b/adminforth/package-lock.json @@ -25,6 +25,7 @@ "chalk": "^5.4.1", "connection-string": "^4.4.0", "dayjs": "^1.11.11", + "decimal.js": "^10.6.0", "dotenv": "^16.4.5", "esm": "^3.2.25", "execa": "^9.5.2", @@ -2467,6 +2468,12 @@ } } }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, "node_modules/decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", diff --git a/adminforth/package.json b/adminforth/package.json index eb3759ac..3e0012b2 100644 --- a/adminforth/package.json +++ b/adminforth/package.json @@ -99,6 +99,7 @@ "chalk": "^5.4.1", "connection-string": "^4.4.0", "dayjs": "^1.11.11", + "decimal.js": "^10.6.0", "dotenv": "^16.4.5", "esm": "^3.2.25", "execa": "^9.5.2", diff --git a/adminforth/pnpm-lock.yaml b/adminforth/pnpm-lock.yaml index ebe69bf1..86ee446b 100644 --- a/adminforth/pnpm-lock.yaml +++ b/adminforth/pnpm-lock.yaml @@ -53,6 +53,9 @@ importers: dayjs: specifier: ^1.11.11 version: 1.11.19 + decimal.js: + specifier: ^10.6.0 + version: 10.6.0 dotenv: specifier: ^16.4.5 version: 16.6.1 @@ -1842,6 +1845,9 @@ packages: supports-color: optional: true + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} @@ -5776,6 +5782,8 @@ snapshots: dependencies: ms: 2.1.3 + decimal.js@10.6.0: {} + decompress-response@6.0.0: dependencies: mimic-response: 3.1.0 From ceac7ddb37d14547de8f89d31220ad4757a068e6 Mon Sep 17 00:00:00 2001 From: Pavlo Kulyk Date: Fri, 1 May 2026 16:03:31 +0300 Subject: [PATCH 5/8] revert --- adminforth/dataConnectors/postgres.ts | 9 +-------- adminforth/package-lock.json | 7 ------- adminforth/package.json | 1 - adminforth/pnpm-lock.yaml | 8 -------- 4 files changed, 1 insertion(+), 24 deletions(-) diff --git a/adminforth/dataConnectors/postgres.ts b/adminforth/dataConnectors/postgres.ts index 881f80b0..1594e3e7 100644 --- a/adminforth/dataConnectors/postgres.ts +++ b/adminforth/dataConnectors/postgres.ts @@ -213,14 +213,7 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa throw new Error(`AdminForth does not support row type: ${field._underlineType} for timestamps, use VARCHAR (with iso strings) or TIMESTAMP/INT (with unix timestamps). Issue in field: ${field.name} in table: ${field.table}`); } } - - if (field.type === AdminForthDataTypes.DECIMAL) { - if (value !== null && value !== undefined) { - return new Decimal(value).toSignificantDigits().toString(); - } - return value; - } - + if (field.type == AdminForthDataTypes.DATE) { if (!value) { return null; diff --git a/adminforth/package-lock.json b/adminforth/package-lock.json index 02b70799..bc3c2f0d 100644 --- a/adminforth/package-lock.json +++ b/adminforth/package-lock.json @@ -25,7 +25,6 @@ "chalk": "^5.4.1", "connection-string": "^4.4.0", "dayjs": "^1.11.11", - "decimal.js": "^10.6.0", "dotenv": "^16.4.5", "esm": "^3.2.25", "execa": "^9.5.2", @@ -2468,12 +2467,6 @@ } } }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "license": "MIT" - }, "node_modules/decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", diff --git a/adminforth/package.json b/adminforth/package.json index 3e0012b2..eb3759ac 100644 --- a/adminforth/package.json +++ b/adminforth/package.json @@ -99,7 +99,6 @@ "chalk": "^5.4.1", "connection-string": "^4.4.0", "dayjs": "^1.11.11", - "decimal.js": "^10.6.0", "dotenv": "^16.4.5", "esm": "^3.2.25", "execa": "^9.5.2", diff --git a/adminforth/pnpm-lock.yaml b/adminforth/pnpm-lock.yaml index 86ee446b..ebe69bf1 100644 --- a/adminforth/pnpm-lock.yaml +++ b/adminforth/pnpm-lock.yaml @@ -53,9 +53,6 @@ importers: dayjs: specifier: ^1.11.11 version: 1.11.19 - decimal.js: - specifier: ^10.6.0 - version: 10.6.0 dotenv: specifier: ^16.4.5 version: 16.6.1 @@ -1845,9 +1842,6 @@ packages: supports-color: optional: true - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} - decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} @@ -5782,8 +5776,6 @@ snapshots: dependencies: ms: 2.1.3 - decimal.js@10.6.0: {} - decompress-response@6.0.0: dependencies: mimic-response: 3.1.0 From 1466d1129269171dfcccbaaea96fb77dd96192a8 Mon Sep 17 00:00:00 2001 From: Pavlo Kulyk Date: Fri, 1 May 2026 16:04:55 +0300 Subject: [PATCH 6/8] revert --- adminforth/dataConnectors/postgres.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/adminforth/dataConnectors/postgres.ts b/adminforth/dataConnectors/postgres.ts index 1594e3e7..ad660b20 100644 --- a/adminforth/dataConnectors/postgres.ts +++ b/adminforth/dataConnectors/postgres.ts @@ -4,7 +4,6 @@ import { AdminForthDataTypes, AdminForthFilterOperators, AdminForthSortDirection import AdminForthBaseConnector from './baseConnector.js'; import pkg from 'pg'; import { afLogger, dbLogger } from '../modules/logger.js'; -import { Decimal } from 'decimal.js'; const { Pool } = pkg; const { Client, types } = pkg; @@ -213,7 +212,7 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa throw new Error(`AdminForth does not support row type: ${field._underlineType} for timestamps, use VARCHAR (with iso strings) or TIMESTAMP/INT (with unix timestamps). Issue in field: ${field.name} in table: ${field.table}`); } } - + if (field.type == AdminForthDataTypes.DATE) { if (!value) { return null; From 815ebab7ce7cc9623d662f05f588fd9ef1ca4028 Mon Sep 17 00:00:00 2001 From: Pavlo Kulyk Date: Fri, 1 May 2026 16:05:16 +0300 Subject: [PATCH 7/8] revert --- adminforth/dataConnectors/postgres.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/adminforth/dataConnectors/postgres.ts b/adminforth/dataConnectors/postgres.ts index ad660b20..2e553af9 100644 --- a/adminforth/dataConnectors/postgres.ts +++ b/adminforth/dataConnectors/postgres.ts @@ -213,6 +213,7 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa } } + if (field.type == AdminForthDataTypes.DATE) { if (!value) { return null; From e9fb9ca3a5e0324124ec88604d2eda9646c38a66 Mon Sep 17 00:00:00 2001 From: Pavlo Kulyk Date: Fri, 1 May 2026 16:05:49 +0300 Subject: [PATCH 8/8] revert --- adminforth/dataConnectors/postgres.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adminforth/dataConnectors/postgres.ts b/adminforth/dataConnectors/postgres.ts index 2e553af9..f91f38cc 100644 --- a/adminforth/dataConnectors/postgres.ts +++ b/adminforth/dataConnectors/postgres.ts @@ -13,6 +13,7 @@ const { Client, types } = pkg; types.setTypeParser(1114, (val) => val); // TIMESTAMP WITHOUT TIME ZONE types.setTypeParser(1082, (val) => val); // DATE + class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDataSourceConnector { async setupClient(url: string): Promise { @@ -213,7 +214,6 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa } } - if (field.type == AdminForthDataTypes.DATE) { if (!value) { return null;