Question: Prevent @ $ characters from being removed
thim81 opened this issue ยท 18 comments
Hi @mesqueeb,
Thanks for the creation of such a powerful, yet easy to use package + the footprint is nice & small.
I noticed that when transforming a string with an @ or $ character, the @ & $ gets removed.
Example:
- camelCase("@nextlink") becomes ==> "nextLink"
- camelCase("$filter") becomes ==> "filter"
Is there a way to prevent this?
@thim81 this was quite an interesting issue to solve.
I finished an entire rewrite of the library on a new branch. There are breaking changes.
I'm interested to get your feedback. Please review lines 251 ~ 300 from this file:
https://github.com/mesqueeb/case-anything/blob/special-character-playground/test/index.ts/#L251-L304
each line, you can see the input string and the expected result.
Does this align with your use case?
Do you have some example strings for me so I can run them through the new system?
PS: The rewrite took me 4 hours ๐
--
case-anything was made with โฅ by Luca Ban.
If you use this library in your projects, you can support the maintenance of this library by a small contribution via Github ๐.
Hi @mesqueeb
I had a look at the test cases & the results which do make sense. I see you even include support for the "." character.
My main use-case is to transform query/header/path field names and request properties, which can contain some special characters.
Query parameters example https://example.com/path/to/$orderby?=ferret&$top=10
where $orderby
and $top
are the field names, that will be cased with "case-anything".
Example request body properties:
{
"value": [],
"@count": 68,
"@nextLink": "https://customername.smc.slgnt.eu/lists/v2/audiences?$count=true&$top=3&$skip=3"
}
some context: I'm implementing your excellent "case-anything" in a small OpenAPI formatting package that I have built.
This item started as a question, so if you feel that the @$ removal behaviour don't belong in your package, I would understand that and I try to figure out a way for it when implementing your package.
It was never my intention to use up 4 hours of your time ๐คญ, but I'm very grateful and hope that your branch becomes part of the release ๐ค .
That's ok! I enjoyed the challenge.
I added some more tests this morning to represent a potential query.
Please look at lines 376 ~ 400:
https://github.com/mesqueeb/case-anything/blob/9dbb3c32a33180b4226acd5ec3ebca7c0a41be22/test/index.ts/#L376-L400
I don't feel like any of these would be particularly useful for you though? : S
which usage are you looking for exactly? I'd feel weird releasing something that's kinda besides the point.
Can you give me more detailed use-case examples. Ideally you give me the desired input and output.
I had a look the additional test, there are some strange results.
const query = `$orderBy=name&skip=3&sort=true&name=James-P&email=sullivan@monsters.inc`
test('kebabCase(query) - dont strip', (t) => t.is(kebabCase(query, false), '$order-by-=name-&skip-=3-&sort-=true-&name-=james--p-&email-=sullivan-@monsters-.inc')) // prettier-ignore
I would expect $order-by=name-&skip=3-&sort=true&name-=james--p&email=sullivan@monsters.inc
without the additional "-" behind $order-by-
and before the @ & . sullivan-@monsters-.inc
Which seems to happen for the whole range of tests after the pascalCase
tests.
The use-case would be really transforming property names, that are defined in a OpenAPI YAML file.
Like so:
components:
parameters:
odataCount:
name: $count
in: query
description: Request a count of matching items included with the returned results
schema:
type: boolean
default: false
odataFilter:
name: $filterItems
in: query
required: false
description: An expression used to filter the returned items
schema:
type: string
example: name+eq+'contact'
default: name+eq+'contact'
schemas:
MessageMailResults:
description: A filtered list of sent email messages.
type: object
properties:
value:
description: "List of sent email messages, based on the query options."
type: array
items:
$ref: "#/components/schemas/MessageMailResultData"
"@nextLink":
$ref: "#/components/schemas/LinkNext"
where I'm using the casing formatting to modify, as example:
"@nextLink"
to a kebab-case: "@-next-link"
and name: $filterItems
to PascalCase name: $FilterItems
for
const query = `$orderBy=name&skip=3&sort=true&name=James-P&email=sullivan@monsters.inc`
current implementation on the new branch:
const stripSpecial = false
kebabCase(query, stripSpecial)
// becomes
'$order-by-=name-&skip-=3-&sort-=true-&name-=james--p-&email-=sullivan-@monsters-.inc'
steps:
- split on words
- attach special characters back in front of words
- join with
-
But I think it indeed makes little sense.
I can try to change it to:
- split on words
- join with
-
OR with special character if there was a special character instead.
that would result in this:
const stripSpecial = false
kebabCase(query, stripSpecial)
// becomes
'$order-by=name&skip=3&sort=true&name=james-p&email=sullivan@monsters.inc'
makes muuuch more sense.
Does this suit your use case? I think I'll go with this version if you like it.
@thim81 I have finished my proposed implementation and am much more satisfied with the results.
I have made the tests more readable as well, and easier for you to find your exact use cases you want to review.
This time, please review from lines 350 ~ until the end of the file:
Please note that as soon as there is one space in your query, it will throw things off quite a bit. This is the nature of case-anything I will not change. Because of my philosophy:
As soon as there is a space in the target string, it will regard the input as a sentence and only split each part at the spaces.
So in your case I would find and replace any spaces with a temporary symbol on beforehand, then apply kebabCase and then put the spaces back.
Eg. something like:
kebabCase(query.replaceAll(' ', '|||')).replaceAll('|||', ' ')
@mesqueeb I had a quick look at the lines 350 ~ and noticed some unwanted side-effect:
Example: line 420 t.is(pascalCase(
$orderBy=name&...where
$orderBybecomes
$orderbywhile with pascalCase I would have expected
$OrderBy`
@thim81 your comment is a bit hard to read. Can you add three ``` above and below the example you wanna show me?
๐
BTW, I think you read the test wrong. The input is $orderBy
the output is the line underneath that:
@thim81 that is because there is a space in that query! ๐
Please note that as soon as there is one space in your query, it will throw things off quite a bit. This is the nature of case-anything I will not change. Because of my philosophy:
As soon as there is a space in the target string, it will regard the input as a sentence and only split each part at the spaces.
So in your case I would find and replace any spaces with a temporary symbol on beforehand, then apply kebabCase and then put the spaces back.
Eg. something like:
kebabCase(query.replaceAll(' ', '|||')).replaceAll('|||', ' ')
A little higher in the tests I have the example of the same query without spaces. I think that's your desired behaviour.
๐คฆ how could I have missed that, apologies (again).
FYI: a query string with spaces is not valid, since the browser would not properly handle that, so users would use the "+" character OR "%20" https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20
But your workaround with the replace
is very handy to keep in mind.
I have prepared a range of feature PR's for new casing options, so looking forward for your remarks and comments.
I have ran the tests locally and they all pass. Perhaps it might be handy for you to setup a "test" action using the Github actions, that way you are certain the PR's pass the test suite.
@thim81 thank you so much! So looking at the query example without spaces, this is in line with your desired behaviour ? If so I'll make sure to release this asap.
Also thanks for the other PRs! I'll merge and release them as well : )
The example without the spaces is exactly the expected behaviour ๐
@thim81
all changes are released as v2
See change notes:
https://github.com/mesqueeb/case-anything/releases/tag/v2.0.0
and also check the brand new readme:
https://github.com/mesqueeb/case-anything#readme
Nice ๐
The readme looks great, very clear.
Thanks for the time and effort you have put into the package, it is greatly appreciated.