UNPKG

4.65 kBJavaScriptView Raw
1"use strict";
2
3const fs = require('fs');
4
5const path = require('path');
6
7const rimraf = require('rimraf');
8
9const mkdirp = require('mkdirp');
10
11const arrify = require('arrify');
12
13const has = require('lodash.has');
14
15const readPkgUp = require('read-pkg-up');
16
17const which = require('which');
18
19const {
20 pkg,
21 path: pkgPath
22} = readPkgUp.sync({
23 cwd: fs.realpathSync(process.cwd())
24});
25const appDirectory = path.dirname(pkgPath);
26
27function resolveKcdScripts() {
28 if (pkg.name === 'kcd-scripts') {
29 return require.resolve('./').replace(process.cwd(), '.');
30 }
31
32 return resolveBin('kcd-scripts');
33} // eslint-disable-next-line complexity
34
35
36function resolveBin(modName, {
37 executable = modName,
38 cwd = process.cwd()
39} = {}) {
40 let pathFromWhich;
41
42 try {
43 pathFromWhich = fs.realpathSync(which.sync(executable));
44 } catch (_error) {// ignore _error
45 }
46
47 try {
48 const modPkgPath = require.resolve(`${modName}/package.json`);
49
50 const modPkgDir = path.dirname(modPkgPath);
51
52 const {
53 bin
54 } = require(modPkgPath);
55
56 const binPath = typeof bin === 'string' ? bin : bin[executable];
57 const fullPathToBin = path.join(modPkgDir, binPath);
58
59 if (fullPathToBin === pathFromWhich) {
60 return executable;
61 }
62
63 return fullPathToBin.replace(cwd, '.');
64 } catch (error) {
65 if (pathFromWhich) {
66 return executable;
67 }
68
69 throw error;
70 }
71}
72
73const fromRoot = (...p) => path.join(appDirectory, ...p);
74
75const hasFile = (...p) => fs.existsSync(fromRoot(...p));
76
77const ifFile = (files, t, f) => arrify(files).some(file => hasFile(file)) ? t : f;
78
79const hasPkgProp = props => arrify(props).some(prop => has(pkg, prop));
80
81const hasPkgSubProp = pkgProp => props => hasPkgProp(arrify(props).map(p => `${pkgProp}.${p}`));
82
83const ifPkgSubProp = pkgProp => (props, t, f) => hasPkgSubProp(pkgProp)(props) ? t : f;
84
85const hasScript = hasPkgSubProp('scripts');
86const hasPeerDep = hasPkgSubProp('peerDependencies');
87const hasDep = hasPkgSubProp('dependencies');
88const hasDevDep = hasPkgSubProp('devDependencies');
89
90const hasAnyDep = args => [hasDep, hasDevDep, hasPeerDep].some(fn => fn(args));
91
92const ifPeerDep = ifPkgSubProp('peerDependencies');
93const ifDep = ifPkgSubProp('dependencies');
94const ifDevDep = ifPkgSubProp('devDependencies');
95
96const ifAnyDep = (deps, t, f) => hasAnyDep(arrify(deps)) ? t : f;
97
98const ifScript = ifPkgSubProp('scripts');
99
100function parseEnv(name, def) {
101 if (envIsSet(name)) {
102 try {
103 return JSON.parse(process.env[name]);
104 } catch (err) {
105 return process.env[name];
106 }
107 }
108
109 return def;
110}
111
112function envIsSet(name) {
113 return process.env.hasOwnProperty(name) && process.env[name] && process.env[name] !== 'undefined';
114}
115
116function getConcurrentlyArgs(scripts, {
117 killOthers = true
118} = {}) {
119 const colors = ['bgBlue', 'bgGreen', 'bgMagenta', 'bgCyan', 'bgWhite', 'bgRed', 'bgBlack', 'bgYellow'];
120 scripts = Object.entries(scripts).reduce((all, [name, script]) => {
121 if (script) {
122 all[name] = script;
123 }
124
125 return all;
126 }, {});
127 const prefixColors = Object.keys(scripts).reduce((pColors, _s, i) => pColors.concat([`${colors[i % colors.length]}.bold.reset`]), []).join(','); // prettier-ignore
128
129 return [killOthers ? '--kill-others-on-fail' : null, '--prefix', '[{name}]', '--names', Object.keys(scripts).join(','), '--prefix-colors', prefixColors, ...Object.values(scripts).map(s => JSON.stringify(s))].filter(Boolean);
130}
131
132function isOptedOut(key, t = true, f = false) {
133 if (!fs.existsSync(fromRoot('.opt-out'))) {
134 return f;
135 }
136
137 const contents = fs.readFileSync(fromRoot('.opt-out'), 'utf-8');
138 return contents.includes(key) ? t : f;
139}
140
141function isOptedIn(key, t = true, f = false) {
142 if (!fs.existsSync(fromRoot('.opt-in'))) {
143 return f;
144 }
145
146 const contents = fs.readFileSync(fromRoot('.opt-in'), 'utf-8');
147 return contents.includes(key) ? t : f;
148}
149
150function uniq(arr) {
151 return Array.from(new Set(arr));
152}
153
154function writeExtraEntry(name, {
155 cjs,
156 esm
157}, clean = true) {
158 if (clean) {
159 rimraf.sync(fromRoot(name));
160 }
161
162 mkdirp.sync(fromRoot(name));
163 const pkgJson = fromRoot(`${name}/package.json`);
164 const entryDir = fromRoot(name);
165 fs.writeFileSync(pkgJson, JSON.stringify({
166 main: path.relative(entryDir, cjs),
167 'jsnext:main': path.relative(entryDir, esm),
168 module: path.relative(entryDir, esm)
169 }, null, 2));
170}
171
172module.exports = {
173 appDirectory,
174 envIsSet,
175 fromRoot,
176 getConcurrentlyArgs,
177 hasFile,
178 hasPkgProp,
179 hasScript,
180 ifAnyDep,
181 ifDep,
182 ifDevDep,
183 ifFile,
184 ifPeerDep,
185 ifScript,
186 isOptedIn,
187 isOptedOut,
188 parseEnv,
189 pkg,
190 resolveBin,
191 resolveKcdScripts,
192 uniq,
193 writeExtraEntry
194};
\No newline at end of file