blob: 5cde7bc783e6c2b951a86188c1a2e1bca3fad944 (
plain)
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
'use strict';
const fs = require('fs');
const path = require('path');
const types = require('./types');
// https://github.com/npm/npm/blob/latest/lib/config/core.js#L409-L423
const envReplace = str => {
if (typeof str !== 'string' || !str) {
return str;
}
// Replace any ${ENV} values with the appropriate environment
const regex = /(\\*)\$\{([^}]+)\}/g;
return str.replace(regex, (orig, esc, name) => {
esc = esc.length > 0 && esc.length % 2;
if (esc) {
return orig;
}
if (process.env[name] === undefined) {
throw new Error(`Failed to replace env in config: ${orig}`);
}
return process.env[name];
});
};
// https://github.com/npm/npm/blob/latest/lib/config/core.js#L362-L407
const parseField = (field, key) => {
if (typeof field !== 'string') {
return field;
}
const typeList = [].concat(types[key]);
const isPath = typeList.indexOf(path) !== -1;
const isBool = typeList.indexOf(Boolean) !== -1;
const isString = typeList.indexOf(String) !== -1;
const isNumber = typeList.indexOf(Number) !== -1;
field = `${field}`.trim();
if (/^".*"$/.test(field)) {
try {
field = JSON.parse(field);
} catch (err) {
throw new Error(`Failed parsing JSON config key ${key}: ${field}`);
}
}
if (isBool && !isString && field === '') {
return true;
}
switch (field) { // eslint-disable-line default-case
case 'true': {
return true;
}
case 'false': {
return false;
}
case 'null': {
return null;
}
case 'undefined': {
return undefined;
}
}
field = envReplace(field);
if (isPath) {
const regex = process.platform === 'win32' ? /^~(\/|\\)/ : /^~\//;
if (regex.test(field) && process.env.HOME) {
field = path.resolve(process.env.HOME, field.substr(2));
}
field = path.resolve(field);
}
if (isNumber && !field.isNan()) {
field = Number(field);
}
return field;
};
// https://github.com/npm/npm/blob/latest/lib/config/find-prefix.js
const findPrefix = name => {
name = path.resolve(name);
let walkedUp = false;
while (path.basename(name) === 'node_modules') {
name = path.dirname(name);
walkedUp = true;
}
if (walkedUp) {
return name;
}
const find = (name, original) => {
const regex = /^[a-zA-Z]:(\\|\/)?$/;
if (name === '/' || (process.platform === 'win32' && regex.test(name))) {
return original;
}
try {
const files = fs.readdirSync(name);
if (files.indexOf('node_modules') !== -1 || files.indexOf('package.json') !== -1) {
return name;
}
const dirname = path.dirname(name);
if (dirname === name) {
return original;
}
return find(dirname, original);
} catch (err) {
if (name === original) {
if (err.code === 'ENOENT') {
return original;
}
throw err;
}
return original;
}
};
return find(name, name);
};
exports.envReplace = envReplace;
exports.findPrefix = findPrefix;
exports.parseField = parseField;
|