pathNormalize is not JSON compatible
Setogit opened this issue · comments
In case a path contains /{[a-zA-Z]+}/, dist/clrd.js/pathNormalize tries to globally replace /{[a-zA-Z]+}/ and replaces the first occurrence with the language parameter as intended, but also tries to replace the second and the other occurences of /{[a-zA-Z]+}/ which came from the message JSON key.
According to the JSON spec, http://www.json.org/, /{[a-zA-Z]+}/ is allowed to be included in JSON keys.
Do we really need to replace /{[a-zA-Z]+}/ globally? Removing the 'g' works for me.
Hi @Setogit, you are correct that {
and '}' are allowed in a JSON key, but we choose to reserve these characters as convenience for replacing variables when traversing CLDR data: https://github.com/rxaviers/cldrjs#get-item-given-its-path given no CLDR path uses them.
Did you find any CLDR using these characters? What's your motivation for the change please?
Hi @raxaviers, my motivation is the following. I have a string resource JSON with {} in one of its keys such as path = "key{one}" In this my use case, globalize.formatMessage(path) silently fails because pathNormalize replaces {one} with 'undefined.' As stated in https://github.com/rxaviers/cldrjs#get-item-given-its-path, It's okay to have any locale attributes replaced with their corresponding values by embracing it with {}. My question is does pathNormalize need to globally replace {} as opposed to replace just the first occurrence of {}?
I think the CLDR traverser can be more client friendly by doing one of these:
a. Raise an error if a opening and closing curly brace pair is included in client-supplied path instead of silently failing. In other words, it clearly enforces that the client should not use {} in path because {} are reserved, therefore, the traverser does not strictly support JSON, or
b. Replace just enough (usually one?) {} pairs and not replace the {} included in the path supplied by the client.
Gotcha. First, replying to your (a) and (b) points. Then, the general motivation.
a. raising an issue makes sense given we're reserving {
and }
. Another not-well-handled case is when {variable}
isn't defined, which is currently replaced by an empty string. I'm open for ideas/PRs.
b. Replacing only one {} pair works considering your case (i.e., Globalize message), but isn't sufficient in some cases, e.g., main/{language}/numbers/currencies/{u-cu}
.
Having said that, I am also interested in a solution for this. On react-globalize we use an overloaded message formatter that supports default message, so keys
might contain {}
. In order to overcome that we sanitize the key.
Does it work for you as well. Any different idea?
Thanks
@rxaviers Based on the the CLDR traverser design ( { } is reserved), i've implemented a sanitization logic on my side. Thanks!