@seneca/repl
Advanced tools
Comparing version 7.0.1 to 8.0.0
const { Duplex } = require('stream') | ||
const { LambdaClient, InvokeCommand } = require('@aws-sdk/client-lambda') | ||
let AWS_SDK_CLIENT_LAMBDA = null | ||
try { | ||
AWS_SDK_CLIENT_LAMBDA = require('@aws-sdk/client-lambda') | ||
} catch (e) { | ||
console.error(e.message) | ||
console.error( | ||
'Install the module @aws-sdk/client-lambda to access AWS Lambda REPLs.', | ||
) | ||
process.exit(1) | ||
} | ||
// TODO: try catch and print error if not found | ||
const { LambdaClient, InvokeCommand } = AWS_SDK_CLIENT_LAMBDA | ||
// seneca-repl aws://lambda/my-function-name?region=eu-west-1 | ||
@@ -5,0 +18,0 @@ |
@@ -15,2 +15,5 @@ #!/usr/bin/env node | ||
const JP = (arg) => JSON.parse(arg) | ||
const JS = (a0, a1) => JSON.stringify(a0, a1) | ||
const state = { | ||
@@ -386,11 +389,17 @@ connection: { | ||
if (null != historyFile) { | ||
try { | ||
FS.appendFileSync(historyFile, line + OS.EOL) | ||
} catch (e) { | ||
// Don't save history | ||
const send = buildSend(line, state) | ||
if (send.ok) { | ||
if (null != historyFile) { | ||
try { | ||
FS.appendFileSync(historyFile, line + OS.EOL) | ||
} catch (e) { | ||
// Don't save history | ||
} | ||
} | ||
state.connection.sock.write(send.line + '\n') | ||
} else { | ||
console.log('# ERROR:', send.errmsg) | ||
} | ||
state.connection.sock.write(line + '\n') | ||
}) | ||
@@ -418,2 +427,153 @@ .on('error', (err) => { | ||
function buildSend(origline, state) { | ||
let line = origline | ||
let out = { ok: false, line } | ||
const directiveRE = /<%(.*?)%>/g | ||
const parts = [] | ||
let m = null | ||
let last = 0 | ||
while ((m = directiveRE.exec(origline))) { | ||
// console.log('D:',m[0],m[1], last, m.index, directiveRE.lastIndex) | ||
parts.push(origline.substring(last, m.index)) | ||
last = directiveRE.lastIndex | ||
let dirout = expr({ src: m[1], fn: DirectiveMap, fixed: DirectiveFixed }) | ||
parts.push(dirout) | ||
} | ||
parts.push(origline.substring(last, origline.length)) | ||
// console.log(parts) | ||
out.line = parts.join('') | ||
out.ok = true | ||
return out | ||
} | ||
const DirectiveFixed = { | ||
VXGACT: | ||
/.*module\.exports\s*=\s*function\s+make_\w+_\w+\s*\(.*?\)\s*\{.*?return\s*(.*)\}[^}]*$/s, | ||
} | ||
const DirectiveMap = { | ||
Load: (path) => { | ||
let fullpath = Path.isAbsolute(path) ? path : Path.join(process.cwd(), path) | ||
if (FS.existsSync(fullpath)) { | ||
let text = FS.readFileSync(fullpath).toString() | ||
return JS(text) | ||
} else { | ||
throw new Error('Unable to read file: ' + fullpath) | ||
} | ||
}, | ||
Match: (jstr, re, mI) => { | ||
let txt = '' + JP(jstr) | ||
let m = re.exec(txt) | ||
let out = m ? (null == mI ? m[0] : m[mI]) : '' | ||
out = JS(null == out ? '' : '' + out) | ||
return out | ||
}, | ||
VxgAction: (pat, act, defstr) => { | ||
let def = JP(defstr).replace(/\n+/g, '; ') | ||
let func = def.startsWith('async') | ||
? 'function(msg,reply,meta){const actfunc=' + | ||
def + | ||
'actfunc.call(this, msg, meta).then(reply).catch(reply)}' | ||
: def | ||
return `seneca.find('${pat}',{exact:true,action:'${act}'}).func=` + func | ||
}, | ||
} | ||
// TODO: unify with Gubu version | ||
/* | ||
spec: { | ||
src: string | ||
fn: {} | ||
fixed: {} | ||
err: { prefix: '' } | ||
} | ||
state: { | ||
tokens?: string[] | ||
i?: number | ||
val: any | ||
} | ||
*/ | ||
function expr(spec, exprState) { | ||
exprState = exprState || { i: 0, val: undefined } | ||
let top = false | ||
if (null == exprState.tokens) { | ||
top = true | ||
exprState.tokens = [] | ||
let tre = | ||
/\s*,?\s*([)(\.]|"(\\.|[^"\\])*"|\/(\\.|[^\/\\])*\/[a-z]?|[^)(,\s]+)\s*/g | ||
let t = null | ||
while ((t = tre.exec(spec.src))) { | ||
exprState.tokens.push(t[1]) | ||
} | ||
} | ||
exprState.i = exprState.i || 0 | ||
let head = exprState.tokens[exprState.i] | ||
let fn = spec.fn[head] | ||
if (')' === exprState.tokens[exprState.i]) { | ||
exprState.i++ | ||
return exprState.val | ||
} | ||
exprState.i++ | ||
if (null == fn) { | ||
let m = null | ||
try { | ||
let val = spec.fixed[head] | ||
if (val) { | ||
return val | ||
} else if ('undefined' === head) { | ||
return undefined | ||
} else if ('NaN' === head) { | ||
return NaN | ||
} else if ((m = head.match(/^\/(.+)\/([a-z])?$/))) { | ||
// return new RegExp(head.substring(1, head.length - 1)) | ||
let re = new RegExp(m[1], m[2]) | ||
return re | ||
} else { | ||
return JP(head) | ||
} | ||
} catch (je) { | ||
throw new SyntaxError( | ||
`${spec.err?.prefix || ''}` + | ||
`Unexpected token ${head} in expression ${spec.src}: ${je.message}`, | ||
) | ||
} | ||
} | ||
if ('(' === exprState.tokens[exprState.i]) { | ||
exprState.i++ | ||
} | ||
let args = [] | ||
let t = null | ||
while (null != (t = exprState.tokens[exprState.i]) && ')' !== t) { | ||
let ev = expr(spec, exprState) | ||
args.push(ev) | ||
} | ||
exprState.i++ | ||
exprState.val = fn.call(spec.val, ...args) | ||
if ('.' === exprState.tokens[exprState.i]) { | ||
exprState.i++ | ||
return expr(exprState) | ||
} else if (top && exprState.i < exprState.tokens.length) { | ||
return expr(exprState) | ||
} | ||
return exprState.val | ||
} | ||
// Create a duplex stream to operate the REPL | ||
@@ -420,0 +580,0 @@ function connect(spec) { |
{ | ||
"name": "@seneca/repl", | ||
"description": "Provides a client and server REPL for Seneca microservice systems.", | ||
"version": "7.0.1", | ||
"version": "8.0.0", | ||
"main": "dist/repl.js", | ||
@@ -25,2 +25,4 @@ "license": "MIT", | ||
"test-watch": "jest --coverage --watchAll", | ||
"smoke":"node test/smoke.js", | ||
"smoke-repl":"node ./bin/seneca-repl-exec.js", | ||
"prettier": "prettier --write --no-semi --single-quote bin/*.js src/*.ts test/*.js", | ||
@@ -48,13 +50,13 @@ "doc": "seneca-doc", | ||
"devDependencies": { | ||
"@aws-sdk/client-lambda": "^3.476.0", | ||
"@seneca/entity-util": "^1.6.0", | ||
"@seneca/gateway-auth": "^1.0.1", | ||
"@aws-sdk/client-lambda": "^3.499.0", | ||
"@seneca/entity-util": "^2.0.0", | ||
"@seneca/gateway-auth": "^1.0.2", | ||
"@seneca/maintain": "^0.1.0", | ||
"@seneca/owner": "^6.0.2", | ||
"@seneca/owner": "^6.1.0", | ||
"@seneca/user": "^6.3.0", | ||
"jest": "^29.7.0", | ||
"prettier": "^3.1.1", | ||
"seneca": "^3.33.0", | ||
"prettier": "^3.2.4", | ||
"seneca": "^3.34.1", | ||
"seneca-doc": "^2.1.3", | ||
"seneca-entity": "^25.1.1", | ||
"seneca-entity": "^25.1.3", | ||
"seneca-mem-store": "^8.4.0", | ||
@@ -61,0 +63,0 @@ "seneca-promisify": "^3.7.1", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
92473
1502