This repository contains some JavaScript and TypeScript modules I've written to be used with the Scriptable app for iOS.
The compiled modules are in the dist folder. Their sources are in the src folder.
These scripts do not show up as standalone scripts in the Scriptable app, nor do they add TypeScript compatibility to Scriptable. However, they do abstract away a lot of complex logic, allowing me to write simple scripts either in Scriptable or in Shortcuts inline scripts.
For example:
const { ExampleClass } = importModule('modules/example');
const example = new ExampleClass();
let result = await example.doSomething();
Script.setShortcutOutput(result)
This takes advantage of how importModule works to find modules in various locations.
If you just want the modules as is, you can download the JavaScript files from the dist folder. There are a few ways to copy them, but the easiest way would be to use Finder to copy the files from their downloaded location to the Scriptable folder on iCloud. See the Scriptable documentation for more information on where to put them and how to import them.
Most modules have a README.md
file with more information on how to use the APIs.
If you want to build from or edit the source, you will need to install NodeJS. Then, you can run the following commands to install dependencies and build the modules:
git clone https://github.com/pacorain/scriptable-modules.git
cd scriptable-modules
npm install
npm run build
You can also run npm run install-modules
to copy the modules to the Scriptable folder on your iCloud drive, inside a modules
subdirectory. This is useful if you want to use the modules in Shortcuts inline scripts. This obviously requires that you are on a Mac and signed into iCloud Drive.
You can also just have the modules built in a different folder by setting the MODULE_OUTPUT_DIR
environment variable. This should theoretically work on Windows with iCloud Drive installed, but I haven't tested it. You could also output to a directory that you can drag to iCloud Drive in a web browser, I think.
There are also build:watch
and install-modules:watch
scripts that will watch for changes and rebuild the modules automatically, though there may be some latency between when the rebuilt modules are written to iCloud and when your iOS device sees the changes.
This repo uses rollup to compile TypeScript modules into self-contained JavaScript files. This means each module is a single file.
Rollup is configured looks for modules in the src folder. Modules are identified by their module.json
file; this file may contain an empty object ({}
), but it must exist for the module to be compiled. Each module is then stored in a JavaScript file, by default in the dist folder. Unless otherwise specified by the module config, the JavaScript file will have the same name as the module folder.
Using pure TypeScript to compile Scriptable is not possible because Scriptable appears to only work on ESModule import statements, and CommonJS export statements, which TypeScript does not support. This is why the modules are compiled to JavaScript with rollup. See #2 for more info.
I use [Jest][] for testing. Unit testing can be completed in the test folder. There is no enforced structure, but I try to follow the convention of having a {module_name}.spec.ts file for each module. Jest is configured to look for these files, and to run TypeScript tests, in the jest.config.js file.
Scriptable is unique, and runs JavaScript code in a non-standard environment so that some global constants map directly to iOS APIs. This creates a challenge for testing. Any scriptable APIs that are used in the modules must be mocked in the tests. This is done in test/mocks.ts. This updates global variables, as long as at least one member is imported from the file.