If anyone’s interested, I finally managed to solve this issue. It took a lot of work, and the details are extremely technical.
I’ve created a JXA library that can do the following, even if there’s “data” node types like CustomIconData:
- Deserialize Plist XML into JXA objects.
- Serialize JXA objects to Plist XML.
- Convert Plist XML to JSON.
- Convert JSON to Plist XML.
- I can deserialize the KM Macros Plist file, which is in binary format, into JXA objects.
Bottom line is, I can now work with all forms of KM Macros and Actions, in JXA. And get the results back into KM with no loss of any values.
I say this with a fair degree of certainty (Murphy’s Law notwithstanding), because my library routines have methods that verify things work as expected.
For instance, when I convert a Plist XML string to a JXA object, I convert it back to XML to verify that the results are exactly the same. So if anything should ever NOT convert correctly, I’ll know right away.
But I don’t see this happening, as I can convert my entire KM Macros library both directions and they match exactly. Byte-to-byte.
##Technical Summary:
###The Problem:
Plists support a datatype called “Data”, which contains base64-encoded data. KM uses this datatype to store things like CustomIconData and StyledText.
When Plists with this type are deserialized into a JXA object, then serialized back to a Plist XML string, the “Data” values are lost.
There’s appears to be no solution for this, using the tools and APIs that are provided by Apple. I don’t say this lightly - believe me, I’ve done my research. Although if someone can prove me wrong, please do!
###The Solution:
Before I deserialize a Plist XML string to a JXA object, I use some regex magic to “tokenize” Data nodes into String nodes.
After I serialize JXA objects back to Plist XML, I reverse the process, using some more regex magic to convert the tokenized String nodes back to Data nodes.
And any time I use the JSON format, it always originates from the XML format, so the Data nodes are still tokenized, so JSON has no problems with them. Conversion back to XML format de-tokenizes the Data nodes.
As for the tokens themselves, I decided to use UUIDs. I can’t see any situation where this will ever fail, especially since the tokens have the be at the very start and end of the tokenized string, so the likelyhood of this ever happening is next to nil.
I can even work with the Plists for the macros that contain the JXA code that has these UUIDs hard-coded, and they tokenize just fine, because the tokens are never at the start and end of the nodes.
Kudos to anyone who read all the way to this point. Extra bonus points for those people who actually understand what I’m talking about. All one of you.