diff --git a/package-lock.json b/package-lock.json index bac12f8..67df835 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", @@ -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", diff --git a/package.json b/package.json index 5124196..26f3a53 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", @@ -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/src/server/parameter-processor.ts b/src/server/parameter-processor.ts index af1aa02..c182a26 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 (paramValue === undefined) return paramValue; + if (typeof paramValue === 'boolean') return paramValue; + + return paramValue.toLowerCase() === 'true'; default: let converter = ServerContainer.get().paramConverters.get(paramType); if (!converter) { diff --git a/test/integration/datatypes.spec.ts b/test/integration/datatypes.spec.ts index 7843309..0331d0b 100644 --- a/test/integration/datatypes.spec.ts +++ b/test/integration/datatypes.spec.ts @@ -157,6 +157,23 @@ 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('boolean-as-body-param') + @BodyOptions({ strict: false }) + public testBooleanAsBodyParam(expand: boolean): string { + return `expand:${expand}`; + } @POST @Path('upload') @@ -478,6 +495,44 @@ 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(); + } + ); + }); + + 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) => {