fx 30.1.1 → 31.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +51 -35
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -48,9 +48,14 @@ const skip = Symbol('skip')
48
48
 
49
49
  async function runTransforms(json, args, theme) {
50
50
  const process = await import('node:process')
51
- let i, code, output = json
51
+ let i, code, jsCode, output = json
52
52
  for ([i, code] of args.entries()) try {
53
- output = await transform(output, code)
53
+ jsCode = transpile(code)
54
+ const fn = `(function () {
55
+ const x = this
56
+ return ${jsCode}
57
+ })`
58
+ output = await run(output, fn)
54
59
  } catch (err) {
55
60
  printErr(err)
56
61
  process.exit(1)
@@ -73,61 +78,58 @@ async function runTransforms(json, args, theme) {
73
78
  console.error(
74
79
  `\n ${pre} ${code} ${post}\n` +
75
80
  ` ${' '.repeat(pre.length + 1)}${'^'.repeat(code.length)}\n` +
81
+ (jsCode !== code ? `\n${jsCode}\n` : ``) +
76
82
  `\n${err.stack || err}`,
77
83
  )
78
84
  }
79
85
  }
80
86
 
81
- async function transform(json, code) {
87
+ function transpile(code) {
82
88
  if ('.' === code)
83
- return json
84
-
85
- if ('?' === code)
86
- return Object.keys(json)
89
+ return 'x'
87
90
 
88
91
  if (/^(\.\w*)+\[]/.test(code))
89
- return eval(`(function () {
90
- return (${fold(code.split('[]'))})(this)
91
- })`).call(json)
92
+ return `(${fold(code.split('[]'))})(x)`
92
93
 
93
94
  function fold(s) {
94
95
  if (s.length === 1)
95
96
  return 'x => x' + s[0]
96
97
  let obj = s.shift()
97
98
  obj = obj === '.' ? 'x' : 'x' + obj
98
- return `x => Object.values(${obj}).flatMap(${fold(s)})`
99
+ return `x => ${obj}.flatMap(${fold(s)})`
99
100
  }
100
101
 
101
102
  if (/^\.\[/.test(code))
102
- return eval(`(function () {
103
- return this${code.substring(1)}
104
- })`).call(json)
103
+ return `x${code.substring(1)}`
105
104
 
106
105
  if (/^\./.test(code))
107
- return eval(`(function () {
108
- return this${code}
109
- })`).call(json)
106
+ return `x${code}`
110
107
 
111
- if (/^[a-z]+\(.+?\)$/i.test(code)) {
108
+ // deprecated
109
+ if (/^map\(.+?\)$/i.test(code)) {
112
110
  let s = code.substring(4, code.length - 1)
113
111
  if (s[0] === '.') s = 'x' + s
114
- return eval(`(function () {
115
- return this.map((x, i) => apply(${s}, x, i))
116
- })`).call(json)
112
+ return `x.map((x, i) => apply(${s}, x, i))`
113
+ }
114
+
115
+ if (/^@/.test(code)) {
116
+ const jsCode = transpile(code.substring(1))
117
+ return `x.map((x, i) => apply(${jsCode}, x, i))`
117
118
  }
118
119
 
119
- const fn = eval(`(function () {
120
- const x = this
121
- return ${code}
122
- })`).call(json)
120
+ return code
121
+ }
122
+
123
+ async function run(json, code) {
124
+ const fn = eval(code).call(json)
125
+
126
+ return apply(fn, json)
123
127
 
124
128
  function apply(fn, ...args) {
125
129
  if (typeof fn === 'function') return fn(...args)
126
130
  return fn
127
131
  }
128
132
 
129
- return apply(fn, json)
130
-
131
133
  function len(x) {
132
134
  if (Array.isArray(x)) return x.length
133
135
  if (typeof x === 'string') return x.length
@@ -145,11 +147,18 @@ async function transform(json, code) {
145
147
  throw new Error(`Cannot sort ${typeof x}`)
146
148
  }
147
149
 
148
- function sortBy(func) {
150
+ function map(fn) {
151
+ return function (x) {
152
+ if (Array.isArray(x)) return x.map((v, i) => fn(v, i))
153
+ throw new Error(`Cannot map ${typeof x}`)
154
+ }
155
+ }
156
+
157
+ function sortBy(fn) {
149
158
  return function (x) {
150
159
  if (Array.isArray(x)) return x.sort((a, b) => {
151
- const fa = func(a)
152
- const fb = func(b)
160
+ const fa = fn(a)
161
+ const fb = fn(b)
153
162
  return fa < fb ? -1 : fa > fb ? 1 : 0
154
163
  })
155
164
  throw new Error(`Cannot sort ${typeof x}`)
@@ -160,11 +169,8 @@ async function transform(json, code) {
160
169
  return function (x) {
161
170
  const grouped = {}
162
171
  for (const item of x) {
163
- const key = typeof keyFn === 'function'
164
- ? keyFn(item)
165
- : item[keyFn]
166
- if (!grouped.hasOwnProperty(key))
167
- grouped[key] = []
172
+ const key = typeof keyFn === 'function' ? keyFn(item) : item[keyFn]
173
+ if (!grouped.hasOwnProperty(key)) grouped[key] = []
168
174
  grouped[key].push(item)
169
175
  }
170
176
  return grouped
@@ -200,6 +206,16 @@ async function transform(json, code) {
200
206
  if (Array.isArray(x)) return x.reverse()
201
207
  throw new Error(`Cannot reverse ${typeof x}`)
202
208
  }
209
+
210
+ function keys(x) {
211
+ if (typeof x === 'object' && x !== null) return Object.keys(x)
212
+ throw new Error(`Cannot get keys of ${typeof x}`)
213
+ }
214
+
215
+ function values(x) {
216
+ if (typeof x === 'object' && x !== null) return Object.values(x)
217
+ throw new Error(`Cannot get values of ${typeof x}`)
218
+ }
203
219
  }
204
220
 
205
221
  async function read(fd = 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fx",
3
- "version": "30.1.1",
3
+ "version": "31.0.0",
4
4
  "bin": {
5
5
  "fx": "index.js"
6
6
  },