UNPKG

4.11 kBJavaScriptView Raw
1import path from 'path';
2import { promisify } from 'util';
3import fs from 'fs';
4const readFile = promisify(fs.readFile);
5/**
6 * Send a string to lowercase
7 * @param str the string to lowercase
8 * @returns the lowercased string
9 */
10export const toLowerCase = (str) => str.toLowerCase();
11/**
12 * Convert a string using dash-case to PascalCase
13 * @param str the string to convert to PascalCase
14 * @returns the PascalCased string
15 */
16export const dashToPascalCase = (str) => toLowerCase(str)
17 .split('-')
18 .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
19 .join('');
20// TODO(STENCIL-356): Investigate removing this unused function
21/**
22 * Flattens a two-dimensional array into a one dimensional array
23 * @param array the array to flatten
24 * @returns the flattened array
25 */
26export function flatOne(array) {
27 if (array.flat) {
28 return array.flat(1);
29 }
30 return array.reduce((result, item) => {
31 result.push(...item);
32 return result;
33 }, []);
34}
35/**
36 * Sorts a provided array by a property belonging to an item that exists on each item in the array
37 * @param array the array to sort
38 * @param prop a function to look up a field on an entry in the provided array
39 * @returns a shallow copy of the array, sorted by the property resolved by `prop`
40 */
41export function sortBy(array, prop) {
42 return array.slice().sort((a, b) => {
43 const nameA = prop(a);
44 const nameB = prop(b);
45 if (nameA < nameB)
46 return -1;
47 if (nameA > nameB)
48 return 1;
49 return 0;
50 });
51}
52/**
53 * Normalize a path
54 * @param str the path to normalize
55 * @returns the normalized path
56 */
57export function normalizePath(str) {
58 // Convert Windows backslash paths to slash paths: foo\\bar ➔ foo/bar
59 // https://github.com/sindresorhus/slash MIT
60 // By Sindre Sorhus
61 if (typeof str !== 'string') {
62 throw new Error(`invalid path to normalize`);
63 }
64 str = str.trim();
65 if (EXTENDED_PATH_REGEX.test(str) || NON_ASCII_REGEX.test(str)) {
66 return str;
67 }
68 str = str.replace(SLASH_REGEX, '/');
69 // always remove the trailing /
70 // this makes our file cache look ups consistent
71 if (str.charAt(str.length - 1) === '/') {
72 const colonIndex = str.indexOf(':');
73 if (colonIndex > -1) {
74 if (colonIndex < str.length - 2) {
75 str = str.substring(0, str.length - 1);
76 }
77 }
78 else if (str.length > 1) {
79 str = str.substring(0, str.length - 1);
80 }
81 }
82 return str;
83}
84/**
85 * Generate the relative import from `pathFrom` to `pathTo`
86 * @param pathFrom the path that shall be used as the origin in determining the relative path
87 * @param pathTo the path that shall be used as the destination in determining the relative path
88 * @param ext an extension to remove from the final path
89 * @returns the derived relative import
90 */
91export function relativeImport(pathFrom, pathTo, ext) {
92 let relativePath = path.relative(path.dirname(pathFrom), path.dirname(pathTo));
93 if (relativePath === '') {
94 relativePath = '.';
95 }
96 else if (relativePath[0] !== '.') {
97 relativePath = './' + relativePath;
98 }
99 return normalizePath(`${relativePath}/${path.basename(pathTo, ext)}`);
100}
101/**
102 * Attempts to read a `package.json` file at the provided directory.
103 * @param rootDir the directory to search for the `package.json` file to read
104 * @returns the read and parsed `package.json` file
105 */
106export async function readPackageJson(rootDir) {
107 const pkgJsonPath = path.join(rootDir, 'package.json');
108 let pkgJson;
109 try {
110 pkgJson = await readFile(pkgJsonPath, 'utf8');
111 }
112 catch (e) {
113 throw new Error(`Missing "package.json" file for distribution: ${pkgJsonPath}`);
114 }
115 let pkgData;
116 try {
117 pkgData = JSON.parse(pkgJson);
118 }
119 catch (e) {
120 throw new Error(`Error parsing package.json: ${pkgJsonPath}, ${e}`);
121 }
122 return pkgData;
123}
124const EXTENDED_PATH_REGEX = /^\\\\\?\\/;
125const NON_ASCII_REGEX = /[^\x00-\x80]+/;
126const SLASH_REGEX = /\\/g;