From a59de1f7c4e5005bcf064695ed5375944a0ca2cf Mon Sep 17 00:00:00 2001 From: Sebastian Mahr Date: Thu, 16 Jan 2025 08:39:37 +0000 Subject: [PATCH 1/7] feat: improve boolean conversion --- src/server/parameter-processor.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/server/parameter-processor.ts b/src/server/parameter-processor.ts index af1aa02..e5db10f 100644 --- a/src/server/parameter-processor.ts +++ b/src/server/parameter-processor.ts @@ -92,7 +92,10 @@ export class ParameterProcessor { case 'Number': return paramValue === undefined ? paramValue : parseFloat(paramValue as string); case 'Boolean': - return paramValue === undefined ? paramValue : paramValue === 'true' || paramValue === true; + if(typeof paramValue === "string"){ + return paramValue.toLowerCase() === 'true' + } + return paramValue === undefined ? paramValue : paramValue === true; default: let converter = ServerContainer.get().paramConverters.get(paramType); if (!converter) { From 30dbc6ae8eb19c4ec80b88d60b63cac66d7b1916 Mon Sep 17 00:00:00 2001 From: Sebastian Mahr Date: Thu, 16 Jan 2025 08:40:39 +0000 Subject: [PATCH 2/7] chore: bumb version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bac12f8..110dd10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@nmshd/typescript-rest", - "version": "3.0.5", + "version": "3.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@nmshd/typescript-rest", - "version": "3.0.5", + "version": "3.1.0", "license": "MIT", "dependencies": { "@types/body-parser": "1.19.5", diff --git a/package.json b/package.json index 5124196..dc3e6a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nmshd/typescript-rest", - "version": "3.0.5", + "version": "3.1.0", "description": "A Library to create RESTFul APIs with Typescript", "keywords": [ "API", From fe2a5cd859a3b5a806fa03c61a14e5133dab59cd Mon Sep 17 00:00:00 2001 From: Sebastian Mahr Date: Thu, 16 Jan 2025 08:49:29 +0000 Subject: [PATCH 3/7] core: prettier and eslint --- src/server/parameter-processor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/parameter-processor.ts b/src/server/parameter-processor.ts index e5db10f..cf0097b 100644 --- a/src/server/parameter-processor.ts +++ b/src/server/parameter-processor.ts @@ -92,8 +92,8 @@ export class ParameterProcessor { case 'Number': return paramValue === undefined ? paramValue : parseFloat(paramValue as string); case 'Boolean': - if(typeof paramValue === "string"){ - return paramValue.toLowerCase() === 'true' + if (typeof paramValue === 'string') { + return paramValue.toLowerCase() === 'true'; } return paramValue === undefined ? paramValue : paramValue === true; default: From df8b26791461333f8eb62b0b25b59b8c23d6aa9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= Date: Thu, 16 Jan 2025 10:20:37 +0100 Subject: [PATCH 4/7] chore: audit fix --- package-lock.json | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 110dd10..67df835 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3108,10 +3108,11 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3914,9 +3915,9 @@ } }, "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -3938,7 +3939,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -3953,6 +3954,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/cookie": { @@ -6518,9 +6523,9 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, "node_modules/path-type": { @@ -10360,9 +10365,9 @@ } }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -10888,9 +10893,9 @@ } }, "express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -10911,7 +10916,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -12736,9 +12741,9 @@ } }, "path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" }, "path-type": { "version": "4.0.0", From 086fe0a7783e31365bbbaf5d0b361e93110e7cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= Date: Thu, 16 Jan 2025 10:23:32 +0100 Subject: [PATCH 5/7] fix: codestyle --- src/server/parameter-processor.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/parameter-processor.ts b/src/server/parameter-processor.ts index cf0097b..c182a26 100644 --- a/src/server/parameter-processor.ts +++ b/src/server/parameter-processor.ts @@ -92,10 +92,10 @@ export class ParameterProcessor { case 'Number': return paramValue === undefined ? paramValue : parseFloat(paramValue as string); case 'Boolean': - if (typeof paramValue === 'string') { - return paramValue.toLowerCase() === 'true'; - } - return paramValue === undefined ? paramValue : paramValue === true; + if (paramValue === undefined) return paramValue; + if (typeof paramValue === 'boolean') return paramValue; + + return paramValue.toLowerCase() === 'true'; default: let converter = ServerContainer.get().paramConverters.get(paramType); if (!converter) { From ce2aa7320662d45cd7375b1e6303af9c0fe293f7 Mon Sep 17 00:00:00 2001 From: Sebastian Mahr Date: Thu, 16 Jan 2025 10:26:29 +0100 Subject: [PATCH 6/7] chore: fix tests --- test/integration/datatypes.spec.ts | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/integration/datatypes.spec.ts b/test/integration/datatypes.spec.ts index 7843309..c52b17b 100644 --- a/test/integration/datatypes.spec.ts +++ b/test/integration/datatypes.spec.ts @@ -157,6 +157,16 @@ export class TestParamsService { ): string { return `limit:${limit}|prefix:${prefix}|expand:${expand}`; } + @GET + @Path('boolean-casing') + public testBooleanCasing( + @QueryParam('True') True?: boolean, + @QueryParam('TRUE') TRUE?: boolean, + @QueryParam('False') False?: boolean, + @QueryParam('FALSE') FALSE?: boolean + ): string { + return `True:${True}|TRUE:${TRUE}|False:${False}|FALSE:${FALSE}`; + } @POST @Path('upload') @@ -478,6 +488,30 @@ describe('Data Types Tests', () => { } ); }); + + it('should handle boolean parameters with different casings', (done) => { + request( + { + url: 'http://localhost:5674/testparams/boolean-casing?True=True&TRUE=TRUE&False=False&FALSE=FALSE' + }, + (error, response, body) => { + expect(body).toEqual('True:true|TRUE:true|False:false|FALSE:false'); + done(); + } + ); + }); + + it('should handle boolean parameters as undefined', (done) => { + request( + { + url: 'http://localhost:5674/testparams/boolean-casing?True=' + }, + (error, response, body) => { + expect(body).toEqual('True:false|TRUE:undefined|False:undefined|FALSE:undefined'); + done(); + } + ); + }); }); describe('Download Service', () => { it('should return a file', (done) => { From b5b533b2e1a4bdb8f9b81d782f33b6de4399635c Mon Sep 17 00:00:00 2001 From: Sebastian Mahr Date: Thu, 16 Jan 2025 11:51:29 +0100 Subject: [PATCH 7/7] chore: add tests --- package.json | 2 +- test/integration/datatypes.spec.ts | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index dc3e6a0..26f3a53 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "lint:prettier": "prettier --check .", "lint:tsc": "tsc --noEmit", "start": "tsc -w", - "pretest": "cross-env NODE_ENV=test npm run build && npm run lint", + "pretest": "cross-env NODE_ENV=test npm run build", "test": "cross-env NODE_ENV=test jest --config ./test/jest.config.js --coverage --runInBand", "test:integration": "cross-env NODE_ENV=test jest --config ./test/jest.config-integration.js --runInBand", "test:unit": "cross-env NODE_ENV=test jest --config ./test/jest.config-unit.js", diff --git a/test/integration/datatypes.spec.ts b/test/integration/datatypes.spec.ts index c52b17b..0331d0b 100644 --- a/test/integration/datatypes.spec.ts +++ b/test/integration/datatypes.spec.ts @@ -168,6 +168,13 @@ export class TestParamsService { return `True:${True}|TRUE:${TRUE}|False:${False}|FALSE:${FALSE}`; } + @POST + @Path('boolean-as-body-param') + @BodyOptions({ strict: false }) + public testBooleanAsBodyParam(expand: boolean): string { + return `expand:${expand}`; + } + @POST @Path('upload') public testUploadFile( @@ -512,6 +519,20 @@ describe('Data Types Tests', () => { } ); }); + + it('should handle boolean parameters as param in body', (done) => { + request.post( + { + url: 'http://localhost:5674/testparams/boolean-as-body-param', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(true) + }, + (error, response, body) => { + expect(body).toEqual('expand:true'); + done(); + } + ); + }); }); describe('Download Service', () => { it('should return a file', (done) => {