-
Notifications
You must be signed in to change notification settings - Fork 403
Fix missing @QueryParams decorator options #270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
MichalLytek
wants to merge
7
commits into
typestack:master
from
MichalLytek:fix/params-decorator-options
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
e8cbf59
Fix missing @QueryParams options
MichalLytek 3e71052
Add normalizing feature to queries object
MichalLytek 1c97969
Create test cases for @QueryParams and its options
MichalLytek 6353ca1
Add check if property type is not undefined (no type annotation)
MichalLytek 4eac44c
Add info in docs about @QueryParams() features
MichalLytek 1ca0c3c
Add optional query params test case
MichalLytek 5aa5087
Merge branch 'master' into fix/params-decorator-options
MichalLytek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,32 +103,32 @@ export class ActionParameterHandler<T extends BaseDriver> { | |
/** | ||
* Normalizes parameter value. | ||
*/ | ||
protected normalizeParamValue(value: any, param: ParamMetadata): Promise<any>|any { | ||
protected async normalizeParamValue(value: any, param: ParamMetadata): Promise<any> { | ||
if (value === null || value === undefined) | ||
return value; | ||
|
||
// map @QueryParams object properties from string to basic types (normalize) | ||
if (param.type === "queries" && typeof value === "object") { | ||
Object.keys(value).map(key => { | ||
const ParamType = Reflect.getMetadata("design:type", param.targetType.prototype, key); | ||
if (ParamType) { | ||
const typeString = typeof ParamType(); // reflected type is always constructor-like (?) | ||
value[key] = this.normalizeValue(value[key], typeString); | ||
} | ||
}); | ||
} | ||
|
||
switch (param.targetName) { | ||
case "number": | ||
if (value === "") return undefined; | ||
return +value; | ||
|
||
case "number": | ||
case "string": | ||
return value; | ||
|
||
case "boolean": | ||
if (value === "true" || value === "1") { | ||
return true; | ||
|
||
} else if (value === "false" || value === "0") { | ||
return false; | ||
} | ||
|
||
return !!value; | ||
return this.normalizeValue(value, param.targetName); | ||
|
||
case "date": | ||
const parsedDate = new Date(value); | ||
if (isNaN(parsedDate.getTime())) { | ||
return Promise.reject(new BadRequestError(`${param.name} is invalid! It can't be parsed to date.`)); | ||
throw new BadRequestError(`${param.name} is invalid! It can't be parsed to date.`); | ||
} | ||
return parsedDate; | ||
|
||
|
@@ -138,8 +138,41 @@ export class ActionParameterHandler<T extends BaseDriver> { | |
value = this.transformValue(value, param); | ||
value = this.validateValue(value, param); // note this one can return promise | ||
} | ||
return value; | ||
} | ||
} | ||
|
||
/** | ||
* Normalizes string value to number or boolean. | ||
*/ | ||
protected normalizeValue(value: any, type: string) { | ||
switch (type) { | ||
case "number": | ||
if (value === "") | ||
return undefined; | ||
const valueNumber = Number(value); | ||
// tslint:disable-next-line:triple-equals | ||
if (valueNumber == value) | ||
return valueNumber; | ||
else | ||
throw new BadRequestError(`${value} can't be parsed to number.`); | ||
|
||
case "string": | ||
return value; | ||
|
||
case "boolean": | ||
if (value === "true" || value === "1") { | ||
return true; | ||
|
||
} else if (value === "false" || value === "0") { | ||
return false; | ||
} | ||
|
||
return Boolean(value); | ||
|
||
default: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should also cover the |
||
return value; | ||
} | ||
return value; | ||
} | ||
|
||
/** | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,22 @@ | ||
import {ParamOptions} from "../decorator-options/ParamOptions"; | ||
import {getMetadataArgsStorage} from "../index"; | ||
|
||
/** | ||
* Injects all request's query parameters to the controller action parameter. | ||
* Must be applied on a controller action parameter. | ||
*/ | ||
export function QueryParams(): Function { | ||
export function QueryParams(options?: ParamOptions): Function { | ||
return function (object: Object, methodName: string, index: number) { | ||
getMetadataArgsStorage().params.push({ | ||
type: "queries", | ||
object: object, | ||
method: methodName, | ||
index: index, | ||
parse: false, | ||
required: false | ||
parse: options ? options.parse : false, | ||
required: options ? options.required : undefined, | ||
classTransform: options ? options.transform : undefined, | ||
explicitType: options ? options.type : undefined, | ||
validate: options ? options.validate : undefined, | ||
}); | ||
}; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if a parameter is passed in the query with no value it should be casted to
null
instead ofundefined
.I will add a normal comment to detail this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just extracted pleerock's code to separate method, I haven't changed nothing in normalizing logic.
https://github.com/pleerock/routing-controllers/blob/master/src/ActionParameterHandler.ts#L112
I agree that we should convert
""
to true for boolean, but for number we should use undefined if param value not exist or NaN if it's not a number string. However I would like to don't mix different things in one PR, as we first need to discuss the edge cases we should merge this@QueryParams
PR and start a new one with better normalizing.