fx 28.0.1 → 30.0.1

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 (3) hide show
  1. package/README.md +1 -7
  2. package/index.js +30 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -13,16 +13,10 @@ Or use **npx**:
13
13
  cat file.json | npx fx .field
14
14
  ```
15
15
 
16
- Or use **node**:
17
-
18
- ```sh
19
- cat file.json | node <(curl -s https://fx.wtf) .field
20
- ```
21
-
22
16
  Or use **deno**:
23
17
 
24
18
  ```sh
25
- cat file.json | deno run https://fx.wtf .field
19
+ cat file.json | deno run -A https://fx.wtf .field
26
20
  ```
27
21
 
28
22
  ## Usage
package/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  void async function main() {
5
5
  const os = await import('node:os')
6
+ const fs = await import('node:fs')
6
7
  const process = await import('node:process')
7
8
  let flagHelp = false
8
9
  let flagRaw = false
@@ -19,8 +20,16 @@ void async function main() {
19
20
  return printUsage()
20
21
  await importFxrc(process.cwd())
21
22
  await importFxrc(os.homedir())
22
- const stdin = await readStdinGenerator()
23
- const input = flagRaw ? readLine(stdin) : parseJson(stdin)
23
+ let fd = 0 // stdin
24
+ if (args.length > 0) {
25
+ if (await isFile(args[0])) {
26
+ fd = fs.openSync(args.shift(), 'r')
27
+ } else if (await isFile(args.at(-1))) {
28
+ fd = fs.openSync(args.pop(), 'r')
29
+ }
30
+ }
31
+ const gen = await read(fd)
32
+ const input = flagRaw ? readLine(gen) : parseJson(gen)
24
33
  if (flagSlurp) {
25
34
  const array = []
26
35
  for (const json of input) {
@@ -63,7 +72,7 @@ async function runTransforms(json, args) {
63
72
  console.error(
64
73
  `\n ${pre} ${code} ${post}\n` +
65
74
  ` ${' '.repeat(pre.length + 1)}${'^'.repeat(code.length)}\n` +
66
- `\n${err.stack || err}`
75
+ `\n${err.stack || err}`,
67
76
  )
68
77
  }
69
78
  }
@@ -99,6 +108,7 @@ async function transform(json, code) {
99
108
  }
100
109
 
101
110
  const fn = eval(`(function () {
111
+ const x = this
102
112
  return ${code}
103
113
  })`).call(json)
104
114
 
@@ -161,7 +171,7 @@ async function transform(json, code) {
161
171
  }
162
172
  }
163
173
 
164
- async function readStdinGenerator() {
174
+ async function read(fd = 0) {
165
175
  const fs = await import('node:fs')
166
176
  const {Buffer} = await import('node:buffer')
167
177
  const {StringDecoder} = await import('node:string_decoder')
@@ -171,7 +181,7 @@ async function readStdinGenerator() {
171
181
  const buffer = Buffer.alloc(4_096)
172
182
  let bytesRead
173
183
  try {
174
- bytesRead = fs.readSync(0, buffer, 0, buffer.length, null)
184
+ bytesRead = fs.readSync(fd, buffer, 0, buffer.length, null)
175
185
  } catch (e) {
176
186
  if (e.code === 'EAGAIN' || e.code === 'EWOULDBLOCK') {
177
187
  sleepSync(10)
@@ -189,6 +199,12 @@ async function readStdinGenerator() {
189
199
  }()
190
200
  }
191
201
 
202
+ async function isFile(path) {
203
+ const fs = await import('node:fs')
204
+ const stat = fs.statSync(path, {throwIfNoEntry: false})
205
+ return stat !== undefined && stat.isFile()
206
+ }
207
+
192
208
  function sleepSync(ms) {
193
209
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms)
194
210
  }
@@ -206,11 +222,11 @@ function* readLine(stdin) {
206
222
  return buffer
207
223
  }
208
224
 
209
- function* parseJson(stdin) {
225
+ function* parseJson(gen) {
210
226
  let lineNumber = 1, buffer = '', lastChar, done = false
211
227
 
212
228
  function next() {
213
- ({value: lastChar, done} = stdin.next())
229
+ ({value: lastChar, done} = gen.next())
214
230
  if (lastChar === '\n') lineNumber++
215
231
  buffer += (lastChar || '')
216
232
  if (buffer.length > 100) buffer = buffer.slice(-40)
@@ -263,7 +279,7 @@ function* parseJson(stdin) {
263
279
  'f': '\f',
264
280
  'n': '\n',
265
281
  'r': '\r',
266
- 't': '\t'
282
+ 't': '\t',
267
283
  }[lastChar]
268
284
  if (!escapedChar) {
269
285
  throw new SyntaxError(errorSnippet())
@@ -275,6 +291,8 @@ function* parseJson(stdin) {
275
291
  escaped = true
276
292
  } else if (lastChar === '"') {
277
293
  break
294
+ } else if (lastChar < '\x1F') {
295
+ throw new SyntaxError(errorSnippet(`Unescaped control character ${JSON.stringify(lastChar)}`))
278
296
  } else if (lastChar === undefined) {
279
297
  throw new SyntaxError(errorSnippet())
280
298
  } else {
@@ -494,7 +512,7 @@ function* parseJson(stdin) {
494
512
 
495
513
  function readEOL() {
496
514
  let line = ''
497
- for (const ch of stdin) {
515
+ for (const ch of gen) {
498
516
  if (!ch || ch === '\n' || line.length >= 60) break
499
517
  line += ch
500
518
  }
@@ -508,7 +526,7 @@ function stringify(value, isPretty = false) {
508
526
  string: isPretty ? '\x1b[32m' : '',
509
527
  number: isPretty ? '\x1b[36m' : '',
510
528
  boolean: isPretty ? '\x1b[35m' : '',
511
- null: isPretty ? '\x1b[2m' : '',
529
+ null: isPretty ? '\x1b[38;5;243m' : '',
512
530
  reset: isPretty ? '\x1b[0m' : '',
513
531
  }
514
532
 
@@ -545,8 +563,8 @@ function stringify(value, isPretty = false) {
545
563
  (key) =>
546
564
  `${getIndent(level + 1)}${colors.key}"${key}"${colors.reset}: ${stringifyValue(
547
565
  value[key],
548
- level + 1
549
- )}`
566
+ level + 1,
567
+ )}`,
550
568
  )
551
569
  .join(',\n')
552
570
  return `{\n${entries}\n${getIndent(level)}}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fx",
3
- "version": "28.0.1",
3
+ "version": "30.0.1",
4
4
  "bin": {
5
5
  "fx": "index.js"
6
6
  },