UNPKG

2.21 kBJavaScriptView Raw
1'use strict'
2
3const { readFile } = require('fs')
4const { promisify } = require('util')
5
6const pathExists = require('path-exists')
7
8const { throwUserError } = require('./error')
9const { throwOnInvalidTomlSequence } = require('./log/messages')
10const { parseToml } = require('./utils/toml')
11
12const pReadFile = promisify(readFile)
13
14// Load the configuration file and parse it (TOML)
15const parseConfig = async function (configPath) {
16 if (configPath === undefined) {
17 return {}
18 }
19
20 if (!(await pathExists(configPath))) {
21 throwUserError('Configuration file does not exist')
22 }
23
24 return await readConfigPath(configPath)
25}
26
27// Same but `configPath` is required and `configPath` might point to a
28// non-existing file.
29const parseOptionalConfig = async function (configPath) {
30 if (!(await pathExists(configPath))) {
31 return {}
32 }
33
34 return await readConfigPath(configPath)
35}
36
37const readConfigPath = async function (configPath) {
38 const configString = await readConfig(configPath)
39
40 validateTomlBlackslashes(configString)
41
42 try {
43 return parseToml(configString)
44 } catch (error) {
45 throwUserError('Could not parse configuration file', error)
46 }
47}
48
49// Reach the configuration file's raw content
50const readConfig = async function (configPath) {
51 try {
52 return await pReadFile(configPath, 'utf8')
53 } catch (error) {
54 throwUserError('Could not read configuration file', error)
55 }
56}
57
58const validateTomlBlackslashes = function (configString) {
59 const result = INVALID_TOML_BLACKSLASH.exec(configString)
60 if (result === null) {
61 return
62 }
63
64 const [, invalidTripleSequence, invalidSequence = invalidTripleSequence] = result
65 throwOnInvalidTomlSequence(invalidSequence)
66}
67
68// The TOML specification forbids unrecognized backslash sequences. However,
69// `toml-node` does not respect the specification and do not fail on those.
70// Therefore, we print a warning message.
71// This only applies to " and """ strings, not ' nor '''
72// Also, """ strings can use trailing backslashes.
73const INVALID_TOML_BLACKSLASH =
74 /\n[a-zA-Z]+ *= *(?:(?:""".*(?<!\\)(\\[^"\\btnfruU\n]).*""")|(?:"(?!")[^\n]*(?<!\\)(\\[^"\\btnfruU])[^\n]*"))/su
75
76module.exports = { parseConfig, parseOptionalConfig }