-
Notifications
You must be signed in to change notification settings - Fork 10
/
index.js
61 lines (50 loc) · 1.84 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
var osa = require('osa2')
var wait = require('blocking-await')
function isInspect(obj) {
var symb = require('util').inspect.custom
return obj == (symb ? symb : 'inspect')
}
// Access the contents of a reference
function dereference(path, args) {
return wait((osa(function(path, args) {
var toStringMode = path[path.length - 1] == 'toString' // Stupid hack
var lastTarget = null
var target = eval(path.shift())
while (path.length != 0) {
lastTarget = target
target = target[path.shift()]
}
if (args.length != 0 || toStringMode) {
obj = target.apply(lastTarget, args)
} else {
obj = target()
}
if (obj == null)
return null
// TODO: Different behavior for array specifiers over object specifiers?
if (/\\[object \\w+Specifier\\]/.test(obj.toString()))
obj = obj.toString()
return obj
}))(path, args))
}
// Used when the node REPL calls .inspect() to print a reference
function createInspector(path) {
return () => `[object JXAReference => ${dereference(path.concat(['toString']),[])}]`
}
// Create a pointer to an object in the AppleScript API
function createReference(path) {
// Object being proxied is the dereference function
return new Proxy((...args) => dereference(path, args), {
// Get trap catches props being accessed, returns a new reference
get: (_, prop) => {
if(isInspect(prop)) // Handle node REPL's .inspect() calls
return createInspector(path)
return createReference(path.concat([prop]))
}
});
};
// Entry point for module. Creates a reference to an Application()
function Application(handle) {
return createReference([`Application("${handle}")`])
}
module.exports.Application = Application