-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathjson.ts
More file actions
35 lines (33 loc) · 1.07 KB
/
json.ts
File metadata and controls
35 lines (33 loc) · 1.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import type { BIDSFile } from '../types/filetree.ts'
async function readJSONText(file: BIDSFile): Promise<string> {
// Read JSON text from a file
// JSON must be encoded in UTF-8 without a byte order mark (BOM)
const decoder = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true })
// Streaming TextDecoders are buggy in Deno and Chrome, so read the
// entire file into memory before decoding and parsing
const data = await file.readBytes(file.size)
try {
const text = decoder.decode(data)
if (text.startsWith('\uFEFF')) {
throw {}
}
return text
} catch (error) {
throw { key: 'INVALID_JSON_ENCODING' }
} finally {
decoder.decode() // Reset decoder
}
}
export async function loadJSON(file: BIDSFile): Promise<Record<string, unknown>> {
const text = await readJSONText(file) // Raise encoding errors
let parsedText;
try {
parsedText = JSON.parse(text)
} catch (error) {
throw { key: 'JSON_INVALID' } // Raise syntax errors
}
if (Array.isArray(parsedText)) {
throw { key: 'JSON_NOT_AN_OBJECT' }
}
return parsedText
}