My kingdom for a place to persist settings


#1

I’m writing some user-configurable scripts, but running into the problem where:

  1. Users have to edit the JavaScript to change settings, and
  2. They lose those customizations if they ever install newer versions.

It would be absolutely spiffy if there were a Settings object so that I could do something like:

settings = Settings.query(<same options as Draft.query>) that finds the described Draft, parses its contents as YAML or JSON, and returns the parsed value as an object. Then I could trivially add user-configurable, persistent settings without having to add a bunch of boilerplate to every script that wants to access that information.

Could we have something like that?


#2

I have scripts that write persistent data as JSON to files in the Drafts folder structure in iCloud. Perhaps you could take this approach and then bundle the relevant generic functions to create/read/update/delete into any scripts that require it? I’m assuming that’s a step up from editing settings in the Draft, which I’m assuming is what you meant by ‘boilerplate’ in this instance.


#3

I like the idea of human-editable configs. That way my project’s users can make changes without me having to also write a config file editor. The boilerplate I meant is that we currently have to do plenty of setup (fetch this file, parse it, save it back out, etc.) when a built-in function could abstract that out for us.


#4

Having js-yaml built in with Drafts would be cool.


#5

This would be the same in two lines of code:

let d = Draft.query( ... ).first;
let settings = JSON.parse(d.content);

There are some other things I have on the internal roadmap for this kind of stuff, but it will be a while until I get to them. There are a number of ways to do it now, however:

  • Files - read/write from files and parse manually.
  • require(...) to load a JS file from /Library/Scripts in iCloud Drive.
  • Load from another draft, like the above example
  • Credential object for some use cases.

#6

Could you add a filter to Drafts.query to search all except trash? Maybe “!trash”


#7

I hadn’t seen generic (only custom defined) use of “first” before, and when I tried it, it didn’t seem to work for me. Specifying the zero based index did however.

E.g.

let d = Draft.query("For Action X", "all", ["script settings"])[0];

#8

Oops. I get my standard library functions mixed up between languages sometimes. :slight_smile: