@modern-js/utils 1.2.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/js/modern/clearConsole.js +1 -1
  3. package/dist/js/modern/compatRequire.js +5 -0
  4. package/dist/js/modern/constants.js +4 -18
  5. package/dist/js/modern/index.js +2 -1
  6. package/dist/js/modern/prettyInstructions.js +15 -5
  7. package/dist/js/modern/wait.js +5 -0
  8. package/dist/js/node/clearConsole.js +1 -1
  9. package/dist/js/node/compatRequire.js +10 -2
  10. package/dist/js/node/constants.js +6 -23
  11. package/dist/js/node/index.js +14 -0
  12. package/dist/js/node/prettyInstructions.js +15 -5
  13. package/dist/js/node/wait.js +12 -0
  14. package/dist/js/treeshaking/clearConsole.js +1 -1
  15. package/dist/js/treeshaking/compatRequire.js +5 -0
  16. package/dist/js/treeshaking/constants.js +4 -18
  17. package/dist/js/treeshaking/index.js +2 -1
  18. package/dist/js/treeshaking/prettyInstructions.js +17 -6
  19. package/dist/js/treeshaking/wait.js +8 -0
  20. package/dist/types/compatRequire.d.ts +2 -1
  21. package/dist/types/constants.d.ts +1 -16
  22. package/dist/types/index.d.ts +2 -1
  23. package/dist/types/wait.d.ts +2 -0
  24. package/package.json +2 -3
  25. package/tests/__snapshots__/prettyInstructions.test.ts.snap +19 -0
  26. package/tests/compatRequire.test.ts +11 -1
  27. package/tests/fixtures/compat-require/foo.js +3 -0
  28. package/tests/prettyInstructions.test.ts +139 -0
  29. package/tests/wait.ts +38 -0
  30. package/src/FileSizeReporter.ts +0 -181
  31. package/src/alias.ts +0 -90
  32. package/src/applyOptionsChain.ts +0 -44
  33. package/src/chalk.ts +0 -3
  34. package/src/clearConsole.ts +0 -5
  35. package/src/compatRequire.ts +0 -25
  36. package/src/constants.ts +0 -262
  37. package/src/debug.ts +0 -8
  38. package/src/ensureAbsolutePath.ts +0 -10
  39. package/src/findExists.ts +0 -15
  40. package/src/formatWebpackMessages.ts +0 -131
  41. package/src/generateMetaTags.ts +0 -75
  42. package/src/getBrowserslist.ts +0 -6
  43. package/src/getCacheIdentifier.ts +0 -30
  44. package/src/getEntryOptions.ts +0 -37
  45. package/src/getPackageManager.ts +0 -30
  46. package/src/getPort.ts +0 -62
  47. package/src/import.ts +0 -10
  48. package/src/index.ts +0 -31
  49. package/src/is/index.ts +0 -78
  50. package/src/is/node-env.ts +0 -9
  51. package/src/is/platform.ts +0 -7
  52. package/src/is/type.ts +0 -43
  53. package/src/logger.ts +0 -184
  54. package/src/monorepo.ts +0 -106
  55. package/src/nodeEnv.ts +0 -28
  56. package/src/path.ts +0 -9
  57. package/src/pkgUp.ts +0 -3
  58. package/src/prettyInstructions.ts +0 -88
  59. package/src/printBuildError.ts +0 -47
  60. package/src/readTsConfig.ts +0 -21
  61. package/src/removeSlash.ts +0 -6
  62. package/src/runtimeExports.ts +0 -68
  63. package/src/types.d.ts +0 -1
  64. package/src/watch.ts +0 -56
package/src/index.ts DELETED
@@ -1,31 +0,0 @@
1
- export * as fs from 'fs-extra';
2
- export * from './chalk';
3
- export * from './formatWebpackMessages';
4
- export * from './FileSizeReporter';
5
- export * from './printBuildError';
6
- export * from './debug';
7
- export * from './findExists';
8
- export * from './is';
9
- export * from './compatRequire';
10
- export * from './logger';
11
- export * from './constants';
12
- export * from './ensureAbsolutePath';
13
- export * from './getCacheIdentifier';
14
- export * from './clearConsole';
15
- export * from './pkgUp';
16
- export * from './applyOptionsChain';
17
- export * from './getBrowserslist';
18
- export * from './removeSlash';
19
- export * from './getEntryOptions';
20
- export * from './getPort';
21
- export * from './monorepo';
22
- export * from './getPackageManager';
23
- export * from './runtimeExports';
24
- export * from './readTsConfig';
25
- export * from './path';
26
- export * from './generateMetaTags';
27
- export * from './prettyInstructions';
28
- export * from './alias';
29
- export * from './import';
30
- export * from './watch';
31
- export * from './nodeEnv';
package/src/is/index.ts DELETED
@@ -1,78 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { isDev } from './node-env';
4
-
5
- /**
6
- * Check if the package name is in dependencies or devDependencies.
7
- *
8
- * @param appDirectory - Project root directory.
9
- * @param name - Package name.
10
- * @returns True if the name is in dependencies or devDependencies, false otherwise.
11
- */
12
- export const isDepExists = (appDirectory: string, name: string): boolean => {
13
- const json = require(path.resolve(appDirectory, './package.json'));
14
-
15
- const { dependencies = {}, devDependencies = {} } = json;
16
-
17
- return (
18
- dependencies.hasOwnProperty(name) || devDependencies.hasOwnProperty(name)
19
- );
20
- };
21
-
22
- /**
23
- * Is typescript project.
24
- *
25
- * @param root - App directory.
26
- * @returns Whether to use typescript.
27
- */
28
- export const isTypescript = (root: string): boolean =>
29
- fs.existsSync(path.resolve(root, './tsconfig.json'));
30
-
31
- /**
32
- * Is Empty object
33
- *
34
- * @param o - Any object.
35
- * @returns Whether it is empty object.
36
- */
37
- export const isEmpty = (o: Record<string, unknown>) =>
38
- Object.entries(o).length === 0 && o.constructor === Object;
39
-
40
- /**
41
- * Is SSR project
42
- *
43
- * @param config - User config.
44
- * @returns Whether to use server side render.
45
- */
46
- export const isSSR = (config: any): boolean => {
47
- const { server } = config;
48
-
49
- if (server?.ssr) {
50
- return true;
51
- }
52
-
53
- if (server?.ssrByEntries && !isEmpty(server.ssrByEntries)) {
54
- for (const name of Object.keys(server.ssrByEntries)) {
55
- if (server.ssrByEntries[name]) {
56
- return true;
57
- }
58
- }
59
- }
60
-
61
- return false;
62
- };
63
-
64
- export const isUseSSRBundle = (config: any): boolean => {
65
- const { output } = config;
66
- if (output?.ssg) {
67
- return true;
68
- }
69
-
70
- return isSSR(config);
71
- };
72
-
73
- export const isFastRefresh = () =>
74
- isDev() && process.env.FAST_REFRESH !== 'false';
75
-
76
- export * from './node-env';
77
- export * from './platform';
78
- export * from './type';
@@ -1,9 +0,0 @@
1
- export const isDev = (): boolean => process.env.NODE_ENV === 'development';
2
-
3
- export const isProd = (): boolean => process.env.NODE_ENV === 'production';
4
-
5
- export const isTest = () => process.env.NODE_ENV === 'test';
6
-
7
- // Variable used for enabling profiling in Production.
8
- export const isProdProfile = () =>
9
- isProd() && process.argv.includes('--profile');
@@ -1,7 +0,0 @@
1
- export const isNodeJS = (): boolean =>
2
- typeof process !== 'undefined' &&
3
- process.versions != null &&
4
- process.versions.node != null &&
5
- (process.versions as any).electron == null;
6
-
7
- export const isBrowser = (): boolean => typeof window !== 'undefined';
package/src/is/type.ts DELETED
@@ -1,43 +0,0 @@
1
- export function isString(str: any): str is string {
2
- return typeof str === 'string';
3
- }
4
-
5
- export function isUndefined(obj: any): obj is undefined {
6
- return typeof obj === 'undefined';
7
- }
8
-
9
- export function isArray(obj: any): obj is any[] {
10
- return Object.prototype.toString.call(obj) === '[object Array]';
11
- }
12
-
13
- // eslint-disable-next-line @typescript-eslint/ban-types
14
- export function isFunction(func: any): func is Function {
15
- return typeof func === 'function';
16
- }
17
-
18
- // eslint-disable-next-line @typescript-eslint/ban-types
19
- export function isObject(obj: any): obj is object {
20
- return typeof obj === 'object';
21
- }
22
-
23
- export function isPlainObject(obj: any): obj is Record<string, any> {
24
- return (
25
- obj &&
26
- typeof obj === 'object' &&
27
- Object.prototype.toString.call(obj) === '[object Object]'
28
- );
29
- }
30
-
31
- export function isPromise(obj: any): obj is Promise<any> {
32
- /* eslint-disable promise/prefer-await-to-then */
33
- return (
34
- Boolean(obj) &&
35
- (typeof obj === 'object' || typeof obj === 'function') &&
36
- typeof obj.then === 'function'
37
- );
38
- /* eslint-enable promise/prefer-await-to-then */
39
- }
40
-
41
- export function isRegExp(obj: any): obj is RegExp {
42
- return Object.prototype.toString.call(obj) === '[object RegExp]';
43
- }
package/src/logger.ts DELETED
@@ -1,184 +0,0 @@
1
- import chalk, { Color } from 'chalk';
2
-
3
- type LogLevel = 'debug' | 'info' | 'warn' | 'error';
4
-
5
- type LogMsg = number | string | Error;
6
-
7
- interface LoggerConfiguration {
8
- color?: typeof Color;
9
- label?: string;
10
- level?: LogLevel;
11
- }
12
-
13
- interface InstanceConfiguration {
14
- displayLabel?: boolean;
15
- underlineLabel?: boolean;
16
- uppercaseLabel?: boolean;
17
- }
18
-
19
- interface ConstructorOptions {
20
- config?: InstanceConfiguration;
21
- types?: Record<string, LoggerConfiguration>;
22
- }
23
-
24
- type LoggerFunction = (
25
- message?: number | string | Error,
26
- ...args: any[]
27
- ) => void;
28
-
29
- const { grey, underline } = chalk;
30
-
31
- const LOG_TYPES = {
32
- error: {
33
- color: 'red',
34
- label: 'error',
35
- level: 'error',
36
- },
37
- info: {
38
- color: 'blue',
39
- label: 'info',
40
- level: 'info',
41
- },
42
- warn: {
43
- color: 'yellow',
44
- label: 'warning',
45
- level: 'warn',
46
- },
47
- debug: {
48
- color: 'red',
49
- label: 'debug',
50
- level: 'debug',
51
- },
52
- log: { level: 'info' },
53
- };
54
-
55
- const DEFAULT_CONFIG = {
56
- displayLabel: true,
57
- underlineLabel: true,
58
- uppercaseLabel: false,
59
- };
60
-
61
- class Logger {
62
- private readonly logCount: number = 200;
63
-
64
- private history: Partial<Record<string, Array<string>>> = {};
65
-
66
- private readonly config: InstanceConfiguration;
67
-
68
- private readonly types: Record<string, LoggerConfiguration>;
69
-
70
- private readonly longestLabel: string;
71
-
72
- [key: string]: any;
73
-
74
- constructor(options: ConstructorOptions = {}) {
75
- this.config = { ...DEFAULT_CONFIG, ...(options.config || {}) };
76
- this.types = {
77
- ...(LOG_TYPES as Record<string, LoggerConfiguration>),
78
- ...(options.types || {}),
79
- };
80
- this.longestLabel = this.getLongestLabel();
81
-
82
- Object.keys(this.types).forEach(type => {
83
- this[type] = this._log.bind(this, type);
84
- });
85
- }
86
-
87
- private retainLog(type: string, message: string) {
88
- if (!this.history[type]) {
89
- this.history[type] = [];
90
- }
91
- this.history[type]!.push(message);
92
- while (this.history[type]!.length > this.logCount) {
93
- this.history[type]!.shift();
94
- }
95
- }
96
-
97
- // eslint-disable-next-line max-statements
98
- private _log(type: string, message?: LogMsg) {
99
- if (message === undefined) {
100
- // eslint-disable-next-line no-console
101
- console.log();
102
- return;
103
- }
104
-
105
- let label = '';
106
- let text = '';
107
- const logType = this.types[type];
108
-
109
- if (this.config.displayLabel && logType.label) {
110
- label = this.config.uppercaseLabel
111
- ? logType.label.toUpperCase()
112
- : logType.label;
113
-
114
- if (this.config.underlineLabel) {
115
- label = underline(label).padEnd(this.longestUnderlinedLabel.length + 1);
116
- } else {
117
- label = label.padEnd(this.longestLabel.length + 1);
118
- }
119
-
120
- label = logType.color ? chalk[logType.color](label) : label;
121
- }
122
-
123
- if (message instanceof Error) {
124
- if (message.stack) {
125
- const [name, ...rest] = message.stack.split('\n');
126
- text = `${name}\n${grey(rest.join('\n'))}`;
127
- } else {
128
- text = message.message;
129
- }
130
- } else {
131
- text = `${message}`;
132
- }
133
-
134
- // only retain logs of warn/error level
135
- if (logType.level === 'warn' || logType.level === 'error') {
136
- // retain log text without label
137
- this.retainLog(type, text);
138
- }
139
-
140
- const log = label.length > 0 ? `${label} ${text}` : text;
141
- // eslint-disable-next-line no-console
142
- console.log(log);
143
- }
144
-
145
- private getLongestLabel() {
146
- let longestLabel = '';
147
- Object.keys(this.types).forEach(type => {
148
- const { label = '' } = this.types[type];
149
- if (label.length > longestLabel.length) {
150
- longestLabel = label;
151
- }
152
- });
153
- return longestLabel;
154
- }
155
-
156
- private get longestUnderlinedLabel() {
157
- return underline(this.longestLabel);
158
- }
159
-
160
- getRetainedLogs(type: string) {
161
- return this.history[type] || [];
162
- }
163
-
164
- clearRetainedLogs(type: string) {
165
- if (type) {
166
- if (this.history[type]) {
167
- this.history[type] = [];
168
- }
169
- } else {
170
- this.history = {};
171
- }
172
- }
173
- }
174
-
175
- type LoggerInterface = {
176
- [key in keyof typeof LOG_TYPES]: LoggerFunction;
177
- };
178
-
179
- const logger = new Logger() as Logger & LoggerInterface;
180
-
181
- logger.Logger = Logger;
182
-
183
- export { logger };
184
- export type { LoggerInterface };
package/src/monorepo.ts DELETED
@@ -1,106 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import glob from 'glob';
4
- import yaml from 'yaml';
5
-
6
- const PACKAGE_MAX_DEPTH = 5;
7
-
8
- const WOKRSPACES_FILES = {
9
- YARN: 'package.json',
10
- PNPM: 'pnpm-workspaces.yaml',
11
- LERNA: 'lerna.json',
12
- };
13
-
14
- export const isLerna = (root: string) =>
15
- fs.existsSync(path.join(root, WOKRSPACES_FILES.LERNA));
16
-
17
- export const isYarnWorkspaces = (root: string) => {
18
- const pkg = path.join(root, WOKRSPACES_FILES.YARN);
19
-
20
- if (!fs.existsSync(pkg)) {
21
- return false;
22
- }
23
-
24
- const json = JSON.parse(fs.readFileSync(pkg, 'utf8'));
25
-
26
- return Boolean(json.workspaces?.packages);
27
- };
28
-
29
- export const isPnpmWorkspaces = (root: string) =>
30
- fs.existsSync(path.join(root, WOKRSPACES_FILES.PNPM));
31
-
32
- export const isMonorepo = (root: string) =>
33
- isLerna(root) || isYarnWorkspaces(root) || isPnpmWorkspaces(root);
34
-
35
- export const isModernjsMonorepo = (root: string) => {
36
- const json = JSON.parse(
37
- fs.readFileSync(path.join(root, 'package.json'), 'utf8'),
38
- );
39
-
40
- const deps = {
41
- ...(json.dependencies || {}),
42
- ...(json.devDependencies || {}),
43
- };
44
-
45
- return Boolean(deps['@modern-js/monorepo-tools']);
46
- };
47
-
48
- export const findMonorepoRoot = (
49
- appDirectory: string,
50
- maxDepth: number = PACKAGE_MAX_DEPTH,
51
- ) => {
52
- let inMonorepo = false;
53
-
54
- for (let depth = 0; depth < maxDepth; depth++) {
55
- if (isMonorepo(appDirectory)) {
56
- inMonorepo = true;
57
- break;
58
- }
59
- // eslint-disable-next-line no-param-reassign
60
- appDirectory = path.dirname(appDirectory);
61
- }
62
-
63
- return inMonorepo ? appDirectory : undefined;
64
- };
65
-
66
- export const getMonorepoPackages = (
67
- root: string,
68
- ): { name: string; path: string }[] => {
69
- let packages: string[] = [];
70
-
71
- if (isYarnWorkspaces(root)) {
72
- const json = JSON.parse(
73
- fs.readFileSync(path.join(root, 'package.json'), 'utf8'),
74
- );
75
- ({ packages } = json.workspaces);
76
- } else if (isLerna(root)) {
77
- const json = JSON.parse(
78
- fs.readFileSync(path.resolve(root, 'lerna.json'), 'utf8'),
79
- );
80
- ({ packages } = json);
81
- } else {
82
- ({ packages } = yaml.parse(
83
- fs.readFileSync(path.join(root, WOKRSPACES_FILES.PNPM), 'utf8'),
84
- ));
85
- }
86
-
87
- if (packages) {
88
- return packages
89
- .map(name =>
90
- // The trailing / ensures only dirs are picked up
91
- glob.sync(path.join(root, `${name}/`), {
92
- ignore: ['**/node_modules/**'],
93
- }),
94
- )
95
- .flat()
96
- .filter(filepath => fs.existsSync(path.resolve(filepath, 'package.json')))
97
- .map(filepath => ({
98
- path: filepath,
99
- name: JSON.parse(
100
- fs.readFileSync(path.resolve(filepath, 'package.json'), 'utf8'),
101
- ).name,
102
- }));
103
- }
104
-
105
- return [];
106
- };
package/src/nodeEnv.ts DELETED
@@ -1,28 +0,0 @@
1
- import execa from 'execa';
2
-
3
- export async function canUseNpm() {
4
- try {
5
- await execa('npm', ['--version'], { env: process.env });
6
- return true;
7
- } catch (e) {
8
- return false;
9
- }
10
- }
11
-
12
- export async function canUseYarn() {
13
- try {
14
- await execa('yarn', ['--version'], { env: process.env });
15
- return true;
16
- } catch (e) {
17
- return false;
18
- }
19
- }
20
-
21
- export async function canUsePnpm() {
22
- try {
23
- await execa('pnpm', ['--version'], { env: process.env });
24
- return true;
25
- } catch (e) {
26
- return false;
27
- }
28
- }
package/src/path.ts DELETED
@@ -1,9 +0,0 @@
1
- import path from 'path';
2
- import upath from 'upath';
3
-
4
- export const isRelativePath = (test: string): boolean =>
5
- /^\.\.?($|[\\/])/.test(test);
6
-
7
- export const normalizeOutputPath = (s: string) => s.replace(/\\/g, '\\\\');
8
- export const normalizeToPosixPath = (p: string) =>
9
- upath.normalizeSafe(path.normalize(p));
package/src/pkgUp.ts DELETED
@@ -1,3 +0,0 @@
1
- import pkgUp from 'pkg-up';
2
-
3
- export { pkgUp };
@@ -1,88 +0,0 @@
1
- import os from 'os';
2
- import chalk from 'chalk';
3
- import { isDev } from './is';
4
-
5
- // TODO: type
6
- interface EntryPoint {
7
- entryName: string;
8
- }
9
-
10
- interface ServerRoute {
11
- entryName: string;
12
- isSSR: boolean;
13
- urlPath: string;
14
- }
15
-
16
- // TODO: remove hard code 'main'
17
- export const isSingleEntry = (entrypoints: EntryPoint[]) =>
18
- entrypoints.length === 1 && entrypoints[0].entryName === 'main';
19
-
20
- const normalizeUrl = (url: string) => url.replace(/([^:]\/)\/+/g, '$1');
21
-
22
- const getAddressUrls = (protocol = 'http', port: number) => {
23
- const interfaces = os.networkInterfaces();
24
- const ipv4Interfaces: os.NetworkInterfaceInfo[] = [];
25
- Object.keys(interfaces).forEach(key => {
26
- interfaces[key]!.forEach(detail => {
27
- if (detail.family === 'IPv4') {
28
- ipv4Interfaces.push(detail);
29
- }
30
- });
31
- });
32
-
33
- return ipv4Interfaces.reduce(
34
- (memo: { type: string; url: string }[], detail) => {
35
- let type = 'Network: ';
36
- let url = `${protocol}://${detail.address}:${port}`;
37
- if (detail.address.includes(`localhost`)) {
38
- type = 'Local: ';
39
- url = `${protocol}://localhost:${port}`;
40
- }
41
-
42
- memo.push({ type, url });
43
- return memo;
44
- },
45
- [],
46
- );
47
- };
48
-
49
- export const prettyInstructions = (appContext: any, config: any) => {
50
- const { entrypoints, serverRoutes, port } = appContext as {
51
- entrypoints: EntryPoint[];
52
- serverRoutes: ServerRoute[];
53
- port: number;
54
- };
55
-
56
- const urls = getAddressUrls(
57
- config.dev.https && isDev() ? 'https' : 'http',
58
- port,
59
- );
60
-
61
- const routes = serverRoutes.filter(route => route.entryName);
62
-
63
- let message = 'App running at:\n\n';
64
-
65
- if (isSingleEntry(entrypoints)) {
66
- message += urls
67
- .map(
68
- ({ type, url }) =>
69
- ` ${chalk.bold(`> ${type.padEnd(10)}`)}${chalk.cyanBright(
70
- normalizeUrl(`${url}/${routes[0].urlPath}`),
71
- )}\n`,
72
- )
73
- .join('');
74
- } else {
75
- const maxNameLength = Math.max(...routes.map(r => r.entryName.length));
76
-
77
- urls.forEach(({ type, url }) => {
78
- message += ` ${chalk.bold(`> ${type}`)}\n`;
79
- routes.forEach(({ entryName, urlPath }) => {
80
- message += ` ${chalk.yellowBright(
81
- entryName.padEnd(maxNameLength + 8),
82
- )}${chalk.cyanBright(normalizeUrl(`${url}/${urlPath}`))}\n`;
83
- });
84
- });
85
- }
86
-
87
- return message;
88
- };
@@ -1,47 +0,0 @@
1
- /* eslint-disable eslint-comments/no-unlimited-disable */
2
- /* eslint-disable */
3
- /**
4
- * Copyright (c) 2015-present, Facebook, Inc.
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE file at
8
- * https://github.com/facebook/create-react-app/blob/master/LICENSE
9
- */
10
-
11
- // Modified by Chao Xu (xuchaobei)
12
-
13
- import chalk from 'chalk';
14
- import { logger } from './logger';
15
-
16
- export function printBuildError(err: Error) {
17
- const message = err != null && err.message;
18
- const stack = err != null && err.stack;
19
-
20
- // Add more helpful message for Terser error
21
- if (
22
- stack &&
23
- typeof message === 'string' &&
24
- message.indexOf('from Terser') !== -1
25
- ) {
26
- try {
27
- const matched = /(.+)\[(.+):(.+),(.+)\]\[.+\]/.exec(stack);
28
- if (!matched) {
29
- throw new Error('Using errors for control flow is bad.');
30
- }
31
- const problemPath = matched[2];
32
- const line = matched[3];
33
- const column = matched[4];
34
- logger.error(
35
- `Failed to minify the code from this file: \n\n ${chalk.yellow(
36
- `\t${problemPath}:${line}${column !== '0' ? ':' + column : ''}`
37
- )}\n`
38
- );
39
- } catch (ignored) {
40
- logger.error(`Failed to minify the bundle. ${err}\n`);
41
- }
42
- } else {
43
- logger.error((message || err) + '\n');
44
- }
45
- logger.log();
46
- };
47
- /* eslint-enable */
@@ -1,21 +0,0 @@
1
- import path from 'path';
2
-
3
- export const readTsConfig = (root: string) => {
4
- // import typescript from 'typescript' cause eslint fromat error.
5
- const typescript = require('typescript');
6
-
7
- return typescript.readConfigFile(
8
- path.resolve(root, './tsconfig.json'),
9
- typescript.sys.readFile,
10
- ).config;
11
- };
12
-
13
- export const readTsConfigByFile = (filename: string) => {
14
- // import typescript from 'typescript' cause eslint fromat error.
15
- const typescript = require('typescript');
16
-
17
- return typescript.readConfigFile(
18
- path.resolve(filename),
19
- typescript.sys.readFile,
20
- ).config;
21
- };
@@ -1,6 +0,0 @@
1
- export const removeLeadingSlash = (s: string): string => s.replace(/^\/+/, '');
2
-
3
- export const removeTailSlash = (s: string): string => s.replace(/\/+$/, '');
4
-
5
- export const removeSlash = (s: string): string =>
6
- removeLeadingSlash(removeTailSlash(s));