diff --git a/src/params/interface.ts b/src/params/interface.ts index 1e43ab75..57269f5f 100644 --- a/src/params/interface.ts +++ b/src/params/interface.ts @@ -249,6 +249,10 @@ export interface ParamDeclaration { * * This can be useful to build UI where the component updates itself when the param values change. * A common scenario where this is useful is searching/paging/sorting. + * + * --- + * + * Note: this value overrides the `dynamic` value on a custom parameter type ([[ParamTypeDefinition.dynamic]]). */ dynamic: boolean; @@ -270,6 +274,10 @@ export interface ParamDeclaration { * to serialize to `/product/camping/tents/awesome_tent` * instead of `/product/camping%2Ftents%2Fawesome_tent`. * + * --- + * + * Note: this value overrides the `raw` value on a custom parameter type ([[ParamTypeDefinition.raw]]). + * * ### Decoding warning * * The decoding behavior of raw parameters is not defined. @@ -491,5 +499,19 @@ export interface ParamTypeDefinition { * - No start-of-string or end-of-string: `/^foo$/` */ pattern: RegExp; + + + /** + * Disables url-encoding of parameter values + * + * If a parameter type is declared `raw`, it will not be url-encoded. + * Custom encoding can still be applied in the [[encode]] function. + * + * ### Decoding warning + * + * The decoding behavior of raw parameters is not defined. + * See: [[ParamDeclaration.raw]] for details + */ + raw: boolean; } diff --git a/src/params/param.ts b/src/params/param.ts index a48cb140..6f9ca6d6 100644 --- a/src/params/param.ts +++ b/src/params/param.ts @@ -1,4 +1,7 @@ -/** @module params */ /** for typedoc */ +/** + * @internalapi + * @module params + */ /** for typedoc */ import {extend, filter, map, applyPairs, allTrueR} from "../common/common"; import {prop, propEq} from "../common/hof"; import {isInjectable, isDefined, isString, isArray} from "../common/predicates"; @@ -69,6 +72,7 @@ export class Param { replace: any; isOptional: boolean; dynamic: boolean; + raw: boolean; config: any; constructor(id: string, type: ParamType, config: ParamDeclaration, location: DefType, paramTypes: ParamTypes) { @@ -78,6 +82,7 @@ export class Param { type = arrayMode ? type.$asArray(arrayMode, location === DefType.SEARCH) : type; let isOptional = config.value !== undefined; let dynamic = isDefined(config.dynamic) ? !!config.dynamic : !!type.dynamic; + let raw = isDefined(config.raw) ? !!config.raw : !!type.raw; let squash = getSquashPolicy(config, isOptional); let replace = getReplace(config, arrayMode, isOptional, squash); @@ -88,7 +93,7 @@ export class Param { return extend(arrayDefaults, arrayParamNomenclature, config).array; } - extend(this, {id, type, location, squash, replace, isOptional, dynamic, config, array: arrayMode}); + extend(this, {id, type, location, squash, replace, isOptional, dynamic, raw, config, array: arrayMode}); } isDefaultValue(value: any): boolean { diff --git a/src/url/urlMatcher.ts b/src/url/urlMatcher.ts index 1c25cd4b..53ce8347 100644 --- a/src/url/urlMatcher.ts +++ b/src/url/urlMatcher.ts @@ -432,7 +432,7 @@ export class UrlMatcher { // If this parameter value is an array, encode the value using encodeDashes if (isArray(encoded)) return acc + map( encoded, UrlMatcher.encodeDashes).join("-"); // If the parameter type is "raw", then do not encodeURIComponent - if (param.type.raw) return acc + encoded; + if (param.raw) return acc + encoded; // Encode the value return acc + encodeURIComponent( encoded); }, ""); @@ -444,7 +444,7 @@ export class UrlMatcher { if (encoded == null || (isDefaultValue && squash !== false)) return; if (!isArray(encoded)) encoded = [ encoded]; if (encoded.length === 0) return; - if (!param.type.raw) encoded = map( encoded, encodeURIComponent); + if (!param.raw) encoded = map( encoded, encodeURIComponent); return ( encoded).map(val => `${param.id}=${val}`); }).filter(identity).reduce(unnestR, []).join("&");