1 | 'use strict'
|
2 |
|
3 | const { readFile } = require('fs')
|
4 | const { promisify } = require('util')
|
5 |
|
6 | const pathExists = require('path-exists')
|
7 |
|
8 | const { throwUserError } = require('./error')
|
9 | const { throwOnInvalidTomlSequence } = require('./log/messages')
|
10 | const { parseToml } = require('./utils/toml')
|
11 |
|
12 | const pReadFile = promisify(readFile)
|
13 |
|
14 |
|
15 | const 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 |
|
28 |
|
29 | const parseOptionalConfig = async function (configPath) {
|
30 | if (!(await pathExists(configPath))) {
|
31 | return {}
|
32 | }
|
33 |
|
34 | return await readConfigPath(configPath)
|
35 | }
|
36 |
|
37 | const 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 |
|
50 | const 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 |
|
58 | const 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 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 | const INVALID_TOML_BLACKSLASH =
|
74 | /\n[a-zA-Z]+ *= *(?:(?:""".*(?<!\\)(\\[^"\\btnfruU\n]).*""")|(?:"(?!")[^\n]*(?<!\\)(\\[^"\\btnfruU])[^\n]*"))/su
|
75 |
|
76 | module.exports = { parseConfig, parseOptionalConfig }
|