mirror of
https://github.com/antonmedv/fx.git
synced 2024-09-11 18:27:10 +03:00
Print js code in errors; add @ map syntax
This commit is contained in:
parent
6520c2c6b7
commit
c699c8c992
49
npm/index.js
49
npm/index.js
@ -48,9 +48,14 @@ const skip = Symbol('skip')
|
|||||||
|
|
||||||
async function runTransforms(json, args, theme) {
|
async function runTransforms(json, args, theme) {
|
||||||
const process = await import('node:process')
|
const process = await import('node:process')
|
||||||
let i, code, output = json
|
let i, code, jsCode, output = json
|
||||||
for ([i, code] of args.entries()) try {
|
for ([i, code] of args.entries()) try {
|
||||||
output = await transform(output, code)
|
jsCode = transpile(code)
|
||||||
|
const fn = `(function () {
|
||||||
|
const x = this
|
||||||
|
return ${jsCode}
|
||||||
|
})`
|
||||||
|
output = await run(output, fn)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
printErr(err)
|
printErr(err)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
@ -73,52 +78,50 @@ async function runTransforms(json, args, theme) {
|
|||||||
console.error(
|
console.error(
|
||||||
`\n ${pre} ${code} ${post}\n` +
|
`\n ${pre} ${code} ${post}\n` +
|
||||||
` ${' '.repeat(pre.length + 1)}${'^'.repeat(code.length)}\n` +
|
` ${' '.repeat(pre.length + 1)}${'^'.repeat(code.length)}\n` +
|
||||||
|
(jsCode !== code ? `\n${jsCode}\n` : ``) +
|
||||||
`\n${err.stack || err}`,
|
`\n${err.stack || err}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function transform(json, code) {
|
function transpile(code) {
|
||||||
if ('.' === code)
|
if ('.' === code)
|
||||||
return json
|
return 'x'
|
||||||
|
|
||||||
if (/^(\.\w*)+\[]/.test(code))
|
if (/^(\.\w*)+\[]/.test(code))
|
||||||
return eval(`(function () {
|
return `(${fold(code.split('[]'))})(x)`
|
||||||
return (${fold(code.split('[]'))})(this)
|
|
||||||
})`).call(json)
|
|
||||||
|
|
||||||
function fold(s) {
|
function fold(s) {
|
||||||
if (s.length === 1)
|
if (s.length === 1)
|
||||||
return 'x => x' + s[0]
|
return 'x => x' + s[0]
|
||||||
let obj = s.shift()
|
let obj = s.shift()
|
||||||
obj = obj === '.' ? 'x' : 'x' + obj
|
obj = obj === '.' ? 'x' : 'x' + obj
|
||||||
return `x => Object.values(${obj}).flatMap(${fold(s)})`
|
return `x => ${obj}.flatMap(${fold(s)})`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (/^\.\[/.test(code))
|
if (/^\.\[/.test(code))
|
||||||
return eval(`(function () {
|
return `x${code.substring(1)}`
|
||||||
const x = this
|
|
||||||
return this${code.substring(1)}
|
|
||||||
})`).call(json)
|
|
||||||
|
|
||||||
if (/^\./.test(code))
|
if (/^\./.test(code))
|
||||||
return eval(`(function () {
|
return `x${code}`
|
||||||
const x = this
|
|
||||||
return this${code}
|
|
||||||
})`).call(json)
|
|
||||||
|
|
||||||
|
// deprecated
|
||||||
if (/^map\(.+?\)$/i.test(code)) {
|
if (/^map\(.+?\)$/i.test(code)) {
|
||||||
let s = code.substring(4, code.length - 1)
|
let s = code.substring(4, code.length - 1)
|
||||||
if (s[0] === '.') s = 'x' + s
|
if (s[0] === '.') s = 'x' + s
|
||||||
return eval(`(function () {
|
return `x.map((x, i) => apply(${s}, x, i))`
|
||||||
return this.map((x, i) => apply(${s}, x, i))
|
|
||||||
})`).call(json)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn = eval(`(function () {
|
if (/^@/.test(code)) {
|
||||||
const x = this
|
const jsCode = transpile(code.substring(1))
|
||||||
return ${code}
|
return `x.map((x, i) => apply(${jsCode}, x, i))`
|
||||||
})`).call(json)
|
}
|
||||||
|
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run(json, code) {
|
||||||
|
const fn = eval(code).call(json)
|
||||||
|
|
||||||
return apply(fn, json)
|
return apply(fn, json)
|
||||||
|
|
||||||
|
10
npm/test.js
10
npm/test.js
@ -139,6 +139,16 @@ void async function main() {
|
|||||||
t.deepEqual(JSON.parse(stdout), [0, 2, 6])
|
t.deepEqual(JSON.parse(stdout), [0, 2, 6])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await test('transform - @ works', async t => {
|
||||||
|
const {stdout} = await run([1, 2, 3], `'@x * 2'`)
|
||||||
|
t.deepEqual(JSON.parse(stdout), [2, 4, 6])
|
||||||
|
})
|
||||||
|
|
||||||
|
await test('transform - @ works with dot', async t => {
|
||||||
|
const {stdout} = await run([{foo: 'bar'}], `@.foo`)
|
||||||
|
t.deepEqual(JSON.parse(stdout), ['bar'])
|
||||||
|
})
|
||||||
|
|
||||||
await test('transform - flat map works', async t => {
|
await test('transform - flat map works', async t => {
|
||||||
const {stdout} = await run({master: {foo: [{bar: [{val: 1}]}]}}, '.master.foo[].bar[].val')
|
const {stdout} = await run({master: {foo: [{bar: [{val: 1}]}]}}, '.master.foo[].bar[].val')
|
||||||
t.deepEqual(JSON.parse(stdout), [1])
|
t.deepEqual(JSON.parse(stdout), [1])
|
||||||
|
Loading…
Reference in New Issue
Block a user