Skip to content

Instantly share code, notes, and snippets.

@uchcode
Last active April 14, 2022 11:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uchcode/f9e48a956942f0940ab7806ee5326e2f to your computer and use it in GitHub Desktop.
Save uchcode/f9e48a956942f0940ab7806ee5326e2f to your computer and use it in GitHub Desktop.
JXA with Require
//
// hello.js
//
// Created by uchcode on 2016/05/28.
// Copyright © 2016 uchcode. All rights reserved.
//
eval( Library('JXAReader.js').read('Require.js') )
ObjC.import('stdlib')
Sys = Require('Sys')
Sys.puts(`hello (again)`)
$.exit(0)
//
// JXAReader.js
//
// Created by uchcode on 2016/05/28.
// Copyright © 2016 uchcode. All rights reserved.
//
function read(fname) {
function LibPath(fname, resourcePath) {
return $(resourcePath + '/Script Libraries/' + fname).stringByStandardizingPath.js
}
const Finder = Application('Finder')
var f
f = LibPath(fname, $.NSBundle.mainBundle.resourcePath.js)
if ( !Finder.exists( Path(f) ) ) {
f = LibPath(fname, '~/Library')
if ( !Finder.exists( Path(f) ) ) {
f = LibPath(fname, '/Library')
if ( !Finder.exists( Path(f) ) ) {
throw `read('${fname}'): File not found.`
}
}
}
const p = $(f)
const u = $.NSUTF8StringEncoding
var e = $()
const c = $.NSString.stringWithContentsOfFileEncodingError(p, u, e).js
if (e.js) throw $.NSString.stringWithFormat('%@', e).js
return c
}
//
// Require.js
//
// Created by uchcode on 2016/05/28.
// Copyright © 2016 uchcode. All rights reserved.
//
function Require(fname) {
function LibPath(fname, resourcePath) {
const l = '/Script Libraries/'
const n = resourcePath + l + fname
const p = $(n).pathExtension.js ? n : n+'.js'
return $(p).stringByStandardizingPath.js
}
const Finder = Application('Finder')
var f
f = LibPath(fname, $.NSBundle.mainBundle.resourcePath.js)
if ( !Finder.exists( Path(f) ) ) {
f = LibPath(fname, '~/Library')
if ( !Finder.exists( Path(f) ) ) {
f = LibPath(fname, '/Library')
if ( !Finder.exists( Path(f) ) ) {
throw `File '${fname}.js' not found in libs.`
}
}
}
const p = $(f)
const u = $.NSUTF8StringEncoding
var e = $()
const c = $.NSString.stringWithContentsOfFileEncodingError(p, u, e).js
if (e.js) throw $.NSString.stringWithFormat('%@', e).js
const module = {exports: {}}
const exports = module.exports
eval(c)
return module.exports
}
//
// Sys.js
//
// Created by uchcode on 2016/05/22.
// Copyright © 2016 uchcode. All rights reserved.
//
module.exports = (function() {
// Private functions
function _stdout(data) {
$.NSFileHandle.fileHandleWithStandardOutput.writeData(data)
}
function _stderr(data) {
$.NSFileHandle.fileHandleWithStandardError.writeData(data)
}
function _fileHandle(output, obj, opt) {
const u = $.NSUTF8StringEncoding
const t = opt != null && opt.terminator !== null ? opt.terminator : '\n'
if (obj)
output( $(`${obj}${t}`).dataUsingEncoding(u) )
else
if (obj === false)
output( $(`false${t}`).dataUsingEncoding(u) )
else if (obj === 0)
output( $(`0${t}`).dataUsingEncoding(u) )
else
output( $(t).dataUsingEncoding(u) )
}
function _is(type, obj) {
const c = Object.prototype.toString.call(obj).slice(8, -1)
return obj !== undefined && obj !== null && c === type
}
function _d(output, obj, opt) {
if ($(obj).js)
if (_is('id', obj))
output(obj, opt)
else
output(JSON.stringify(obj), opt)
else
output(`<${obj}>`, opt)
}
// Standard I/O
function gets() {
return $.NSString.alloc.initWithDataEncoding($.NSFileHandle.fileHandleWithStandardInput.availableData, $.NSUTF8StringEncoding).js
}
function puts(obj, opt) {
_fileHandle(_stdout, obj, opt)
}
function errs(obj, opt) {
_fileHandle(_stderr, obj, opt)
}
function p(obj, opt) {
_d(puts, obj, opt)
}
function e(obj, opt) {
_d(errs, obj, opt)
}
function log(obj) {
$.NSLog('%@', obj)
}
// Utilities
function sh(cmd, opt) {
const a = Application.currentApplication()
const p = opt ? opt.withPrompt : null
a.includeStandardAdditions = true
return a.doShellScript(cmd, {
administratorPrivileges: !!p,
withPrompt: p || '',
alteringLineEndings: false
}).trim()
}
function nstask(launchPath, arguments) {
const t = $.NSTask.new
t.launchPath = launchPath
t.arguments = arguments
const p = $.NSPipe.new
t.standardOutput = p
t.standardError = p
try {
t.launch
// t.waitUntilExit
} catch(e) {
throw $.NSString.stringWithFormat('%@', e).js
}
const d = p.fileHandleForReading.readDataToEndOfFile
const u = $.NSUTF8StringEncoding
const r = $.NSString.alloc.initWithDataEncoding(d, u)
const s = t.terminationStatus
if (s!=0) throw $.NSString.stringWithFormat('%@ (status:%@)', r, s).js
return r.js.trim()
}
function bash(cmd, opt) {
if (opt && opt.withPrompt) {
const c = cmd.replace(/'/g, `\\'`)
const p = ` with prompt "${opt.withPrompt}" with administrator privileges`
const s = `do shell script "${c}"${p}`
const o = `osascript -l AppleScript << '__APPLESCRIPT__'\n${s}\n__APPLESCRIPT__`
return nstask('/usr/bin/env', ['bash', '--login', '-c', o])
}
return nstask('/usr/bin/env', ['bash', '--login', '-c', cmd])
}
function StandardizingPath(path) {
return Path($(path).stringByStandardizingPath.js)
}
// Extensions of Basic
if (!String.readFrom) String.readFrom = function(path) {
const p = $(path).stringByStandardizingPath
const u = $.NSUTF8StringEncoding
var e = $()
const c = $.NSString.stringWithContentsOfFileEncodingError(p, u, e).js
if (e.js) throw $.NSString.stringWithFormat('%@', e).js
return c
}
if (!String.prototype.writeTo) String.prototype.writeTo = function(path) {
const p = $(path).stringByStandardizingPath
const a = true
const u = $.NSUTF8StringEncoding
var e = $()
const c = $(this)
c.writeToFileAtomicallyEncodingError(p, a, u, e)
if (e.js) throw $.NSString.stringWithFormat('%@', e).js
}
if (!String.prototype.format) String.prototype.format = function(f) {
return $.NSString.stringWithFormat(f||'%@', this.toString()).js
}
if (!String.prototype.echo) String.prototype.echo = function(format) {
if (format)
puts(this.format(format))
else
puts(this)
return this
}
if (!Function.prototype.toJSON) Function.prototype.toJSON = Function.prototype.toString
//
return {
gets: gets,
puts: puts,
errs: errs,
p: p,
e: e,
log: log,
nstask: nstask,
bash: bash,
sh: sh,
StandardizingPath: StandardizingPath
}
})()
@uchcode
Copy link
Author

uchcode commented May 28, 2016

We can create a command that is no need to write eval() like this:

(echo "eval( Library('JXAReader.js').read('Require.js') )" && cat hello.js) | osascript -l JavaScript

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment