This gets you most of the way there:
> With the Aeson library, the order of keys in objects is undefined due to objects being implemented as HashMaps. To allow user-specified key orders in the pretty-printed JSON, encodePretty' can be configured with a comparison function.
- https://hackage.haskell.org/package/aeson-pretty-0.8.7/docs/...
I'm not sure that messes with spacing or not though or you require specific space preserving requirements to interoperate with current clients.
Even if not you can probably look at the source of encodePretty' and work out how to not mess with spacing or keep it all on one line.
I've wanted a version of Aeson for a while that preserves order and all formatting for things like linters that are very unobtrusive. It seems your use case would have benefitted from that as well.
Given the example:
{
"baz": ...,
"bar": ...,
"foo": ...,
"quux": ...,
}
Then listing all of the keys in your desired order: comp :: Text -> Text -> Ordering
comp = keyOrder ["foo","bar","baz","qux"] `mappend` comparing length
Note if you list all keys in the first argument of keyOrder it never goes to comparing length. There is probably a cleaner way to denote that this is the case but I can't be bothered to figure it out atm.You can use this function:
encodePretty' defConfig { confCompare = comp } YourType
And it will produce: {
"foo": ...,
"bar": ...,
"baz": ...,
"quux": ...,
}
Can you give a sample of the javascript in the order necessary? This is from NPM? They have to use some comparison function to figure out how to sort their keys I'd imagine, so you could just copy that with Haskell.