fx 28.0.0 → 30.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 (3) hide show
  1. package/README.md +1 -7
  2. package/index.js +29 -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
  }
@@ -161,7 +170,7 @@ async function transform(json, code) {
161
170
  }
162
171
  }
163
172
 
164
- async function readStdinGenerator() {
173
+ async function read(fd = 0) {
165
174
  const fs = await import('node:fs')
166
175
  const {Buffer} = await import('node:buffer')
167
176
  const {StringDecoder} = await import('node:string_decoder')
@@ -171,7 +180,7 @@ async function readStdinGenerator() {
171
180
  const buffer = Buffer.alloc(4_096)
172
181
  let bytesRead
173
182
  try {
174
- bytesRead = fs.readSync(0, buffer, 0, buffer.length, null)
183
+ bytesRead = fs.readSync(fd, buffer, 0, buffer.length, null)
175
184
  } catch (e) {
176
185
  if (e.code === 'EAGAIN' || e.code === 'EWOULDBLOCK') {
177
186
  sleepSync(10)
@@ -189,6 +198,12 @@ async function readStdinGenerator() {
189
198
  }()
190
199
  }
191
200
 
201
+ async function isFile(path) {
202
+ const fs = await import('node:fs')
203
+ const stat = fs.statSync(path, {throwIfNoEntry: false})
204
+ return stat !== undefined && stat.isFile()
205
+ }
206
+
192
207
  function sleepSync(ms) {
193
208
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms)
194
209
  }
@@ -206,11 +221,11 @@ function* readLine(stdin) {
206
221
  return buffer
207
222
  }
208
223
 
209
- function* parseJson(stdin) {
224
+ function* parseJson(gen) {
210
225
  let lineNumber = 1, buffer = '', lastChar, done = false
211
226
 
212
227
  function next() {
213
- ({value: lastChar, done} = stdin.next())
228
+ ({value: lastChar, done} = gen.next())
214
229
  if (lastChar === '\n') lineNumber++
215
230
  buffer += (lastChar || '')
216
231
  if (buffer.length > 100) buffer = buffer.slice(-40)
@@ -263,7 +278,7 @@ function* parseJson(stdin) {
263
278
  'f': '\f',
264
279
  'n': '\n',
265
280
  'r': '\r',
266
- 't': '\t'
281
+ 't': '\t',
267
282
  }[lastChar]
268
283
  if (!escapedChar) {
269
284
  throw new SyntaxError(errorSnippet())
@@ -275,6 +290,8 @@ function* parseJson(stdin) {
275
290
  escaped = true
276
291
  } else if (lastChar === '"') {
277
292
  break
293
+ } else if (lastChar < '\x1F') {
294
+ throw new SyntaxError(errorSnippet(`Unescaped control character ${JSON.stringify(lastChar)}`))
278
295
  } else if (lastChar === undefined) {
279
296
  throw new SyntaxError(errorSnippet())
280
297
  } else {
@@ -494,7 +511,7 @@ function* parseJson(stdin) {
494
511
 
495
512
  function readEOL() {
496
513
  let line = ''
497
- for (const ch of stdin) {
514
+ for (const ch of gen) {
498
515
  if (!ch || ch === '\n' || line.length >= 60) break
499
516
  line += ch
500
517
  }
@@ -518,7 +535,7 @@ function stringify(value, isPretty = false) {
518
535
 
519
536
  function stringifyValue(value, level = 0) {
520
537
  if (typeof value === 'string') {
521
- return `${colors.string}"${value}"${colors.reset}`
538
+ return `${colors.string}${JSON.stringify(value)}${colors.reset}`
522
539
  } else if (typeof value === 'number') {
523
540
  return `${colors.number}${value}${colors.reset}`
524
541
  } else if (typeof value === 'bigint') {
@@ -545,8 +562,8 @@ function stringify(value, isPretty = false) {
545
562
  (key) =>
546
563
  `${getIndent(level + 1)}${colors.key}"${key}"${colors.reset}: ${stringifyValue(
547
564
  value[key],
548
- level + 1
549
- )}`
565
+ level + 1,
566
+ )}`,
550
567
  )
551
568
  .join(',\n')
552
569
  return `{\n${entries}\n${getIndent(level)}}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fx",
3
- "version": "28.0.0",
3
+ "version": "30.0.0",
4
4
  "bin": {
5
5
  "fx": "index.js"
6
6
  },