UNPKG

3.57 kBPlain TextView Raw
1import * as Path from 'path';
2import * as fs from 'fs-extra-plus';
3import * as jsyaml from 'js-yaml';
4import { ParsedArgs } from 'minimist';
5import * as stripJsonComments from 'strip-json-comments';
6
7
8// --------- Lang & Type Utils --------- //
9
10export type Partial<T> = {
11 [P in keyof T]?: T[P];
12}
13
14// for the bin-vdev & cmd-*
15export type CmdMap = { [fnName: string]: (miniArgv: ParsedArgs, rawArgv: string[]) => void }
16
17/**
18 * Split the eventual comman deliminated string as array of trim items.
19 * If array just return the array, if null, return empty array
20 * @param srcNames comma deliminated, single name, or array of names
21 */
22export function asNames(srcNames?: string | string[] | null) {
23 if (srcNames) {
24 if (typeof srcNames === 'string') {
25 return srcNames.split(',').map((s) => s.trim());
26 } else {
27 return srcNames;
28 }
29 } else {
30 return [];
31 }
32}
33// --------- /Lang & Type Utils --------- //
34
35
36// --------- Utils --------- //
37export async function yaml(content: string) {
38 const yamlObj = jsyaml.load(content);
39 if (!yamlObj) {
40 throw new Error(`Could not load yaml`);
41 }
42 return yamlObj;
43}
44
45export async function loadYaml(path: string) {
46 const yamlContent = await fs.readFile(path, 'utf8');
47 return yaml(yamlContent);
48}
49
50export async function readJsonFileWithComments(path: string) {
51 const content = await fs.readFile(path, 'utf8');
52 return JSON.parse(stripJsonComments(content));
53}
54
55export async function saferRemove(relPath: string, log?: boolean) {
56 log = (log !== false); // default is true
57 const baseDir = Path.resolve('./');
58 const fullPath = Path.resolve(relPath);
59 if (!fullPath.startsWith(baseDir)) {
60 throw new Error(`Path to be removed does not look safe (nothing done): ${fullPath}`);
61 }
62 const exists = await fs.pathExists(fullPath);
63 if (exists) {
64 if (log) {
65 console.log(`Deleting: ${relPath}`);
66 }
67 return fs.remove(fullPath);
68 } else {
69 if (log) {
70 console.log(`Already deleted: ${relPath}`);
71 }
72 }
73}
74
75export async function wait(ms: number) {
76 return new Promise(function (resolve) {
77 setTimeout(() => { resolve(); }, ms);
78 });
79}
80
81// return now in milliseconds using high precision
82export function now() {
83 var hrTime = process.hrtime();
84 return hrTime[0] * 1000 + hrTime[1] / 1000000;
85}
86
87export async function printLog(txt: string, dist: string | null, start: number) {
88 const timeStr = Math.round(now() - start) + 'ms';
89
90 let msg = `${txt} - `;
91
92 if (dist) {
93 let size = (await fs.stat(dist)).size;
94 size = Math.round(size / 1000.0);
95 msg += `${dist} - ${timeStr} - ${size} kb`;
96 } else {
97 msg += `${timeStr}`;
98 }
99
100 console.log(msg);
101}
102
103export async function prompt(message: string) {
104 // console.log(`\n${message}: `);
105 process.stdout.write(`\n${message}: `);
106 return new Promise(function (resolve, reject) {
107 process.stdin.resume();
108 process.stdin.setEncoding('utf8');
109 process.stdin.on('data', function (text) {
110 process.stdin.pause();
111 resolve(text.trim());
112 });
113 });
114}
115
116/** Attempted to return the obj value given a dottedNamePath (i.e. 'author.name').
117 * @returns undefined if nothing found or obj or dottedNamePath is null/undefined. Return obj if dottedNamePath == ''.
118 **/
119export function findVal(obj: any, dottedNamePath: string) {
120 if (obj == null || dottedNamePath == null) {
121 return;
122 }
123 if (dottedNamePath.trim() === '') {
124 return obj;
125 }
126
127 let val: any = obj;
128 const names = dottedNamePath.split('.');
129 for (let name of names) {
130 val = val[name];
131 if (val == null) { // if null or undefined, stop and return
132 return val;
133 }
134 }
135 return val;
136}
137// --------- /Utils --------- //
138
139
140
141
142
143