dependency-cruiser 16.3.3 → 16.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,4 @@
1
1
  import * as path from "node:path";
2
- import figures from "figures";
3
2
 
4
3
  const TEMPLATE = `
5
4
  <html>
@@ -74,9 +73,7 @@ function formatFileName(pFileName) {
74
73
  return `${path.dirname(pFileName)}/<b>${path.basename(pFileName)}</b>`;
75
74
  }
76
75
  function formatDependency(pFrom, pTo) {
77
- return `${formatFileName(pFrom)} ${figures.arrowRight}</br>${formatFileName(
78
- pTo
79
- )}`;
76
+ return `${formatFileName(pFrom)} →</br>${formatFileName(pTo)}`;
80
77
  }
81
78
 
82
79
  /**
@@ -100,14 +97,14 @@ function render3DThing(pCruiseResult) {
100
97
  source: pCurrentModule.source,
101
98
  target: pDependency.resolved,
102
99
  label: formatDependency(pCurrentModule.source, pDependency.resolved),
103
- }))
100
+ })),
104
101
  ),
105
- []
102
+ [],
106
103
  );
107
104
 
108
105
  return TEMPLATE.replace(/@@NODES@@/g, JSON.stringify(lNodes)).replace(
109
106
  /@@LINKS@@/g,
110
- JSON.stringify(lLinks)
107
+ JSON.stringify(lLinks),
111
108
  );
112
109
  }
113
110
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dependency-cruiser",
3
- "version": "16.3.3",
3
+ "version": "16.3.5",
4
4
  "description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
5
5
  "keywords": [
6
6
  "static analysis",
@@ -57,8 +57,10 @@
57
57
  "Stefan Gojan (https://stefan-gojan.de)",
58
58
  "Tharun Rajendran (https://github.com/tharun208)",
59
59
  "electrovir (https://github.com/electrovir)",
60
- "fusheng (https://github.com/lin-hun)"
60
+ "fusheng (https://github.com/lin-hun)",
61
+ "Frederik Schubert (https://github.com/ferdynator)"
61
62
  ],
63
+ "type": "module",
62
64
  "license": "MIT",
63
65
  "repository": {
64
66
  "type": "git",
@@ -136,18 +138,16 @@
136
138
  "README.md"
137
139
  ],
138
140
  "dependencies": {
139
- "acorn": "8.11.3",
141
+ "acorn": "8.12.0",
140
142
  "acorn-jsx": "5.3.2",
141
143
  "acorn-jsx-walk": "2.0.0",
142
144
  "acorn-loose": "8.4.0",
143
- "acorn-walk": "8.3.2",
145
+ "acorn-walk": "8.3.3",
144
146
  "ajv": "8.16.0",
145
147
  "chalk": "5.3.0",
146
148
  "commander": "12.1.0",
147
149
  "enhanced-resolve": "5.17.0",
148
- "figures": "6.1.0",
149
150
  "ignore": "5.3.1",
150
- "indent-string": "5.0.0",
151
151
  "interpret": "^3.1.1",
152
152
  "is-installed-globally": "1.0.0",
153
153
  "json5": "2.2.3",
@@ -158,7 +158,6 @@
158
158
  "rechoir": "^0.8.0",
159
159
  "safe-regex": "2.1.1",
160
160
  "semver": "^7.6.2",
161
- "semver-try-require": "7.0.0",
162
161
  "teamcity-service-messages": "0.1.14",
163
162
  "tsconfig-paths-webpack-plugin": "4.1.0",
164
163
  "watskeburt": "4.0.2",
@@ -177,6 +176,5 @@
177
176
  },
178
177
  "scripts": {
179
178
  "test": "echo for test, build and static analysis scripts: see the github repository"
180
- },
181
- "type": "module"
179
+ }
182
180
  }
@@ -1,10 +1,9 @@
1
1
  import chalk from "chalk";
2
- import figures from "figures";
3
2
 
4
3
  import { getAvailableTranspilers, allExtensions } from "#main/index.mjs";
5
4
 
6
5
  function bool2Symbol(pBool) {
7
- return pBool ? chalk.green(figures.tick) : chalk.red(figures.cross);
6
+ return pBool ? chalk.green("✔") : chalk.red("x");
8
7
  }
9
8
 
10
9
  function formatTranspilers() {
@@ -30,7 +29,7 @@ export default function formatMetaInfo() {
30
29
  Supported:
31
30
 
32
31
  If you need a supported, but not enabled transpiler ('${chalk.red(
33
- figures.cross,
32
+ "x",
34
33
  )}' below), just install
35
34
  it in the same folder dependency-cruiser is installed. E.g. 'npm i livescript'
36
35
  will enable livescript support if it's installed in your project folder.
@@ -1,5 +1,4 @@
1
1
  import { writeFileSync } from "node:fs";
2
- import figures from "figures";
3
2
  import chalk from "chalk";
4
3
  import {
5
4
  fileExists,
@@ -30,9 +29,7 @@ export default function writeConfig(
30
29
  try {
31
30
  writeFileSync(pFileName, pConfig);
32
31
  pOutStream.write(
33
- `\n ${chalk.green(
34
- figures.tick,
35
- )} Successfully created '${pFileName}'\n\n`,
32
+ `\n ${chalk.green("✔")} Successfully created '${pFileName}'\n\n`,
36
33
  );
37
34
  /* c8 ignore start */
38
35
  } catch (pError) {
@@ -1,11 +1,11 @@
1
+ /* eslint-disable prefer-template */
1
2
  /* eslint-disable security/detect-object-injection */
2
3
  import { writeFileSync } from "node:fs";
3
- import figures from "figures";
4
+ import { EOL } from "node:os";
4
5
  import chalk from "chalk";
5
6
  import { PACKAGE_MANIFEST as _PACKAGE_MANIFEST } from "../defaults.mjs";
6
7
  import { readManifest } from "./environment-helpers.mjs";
7
8
  import { folderNameArrayToRE } from "./utl.mjs";
8
- import wrapAndIndent from "#utl/wrap-and-indent.mjs";
9
9
 
10
10
  const PACKAGE_MANIFEST = `./${_PACKAGE_MANIFEST}`;
11
11
 
@@ -14,37 +14,47 @@ const EXPERIMENTAL_SCRIPT_DOC = [
14
14
  name: "depcruise",
15
15
  headline: "npm run depcruise",
16
16
  description:
17
- "validates against the rules in .dependency-cruiser.js and writes the outcome to stdout",
17
+ " validates against the rules in .dependency-cruiser.js and writes the" +
18
+ EOL +
19
+ " outcome to stdout",
18
20
  },
19
21
  {
20
22
  name: "depcruise:html",
21
23
  headline: "npm run depcruise:html",
22
24
  description:
23
- "validates against the rules in .dependency-cruiser.js and writes it to 'dependency-violation-report.html' with a friendly layout",
25
+ " validates against the rules in .dependency-cruiser.js and writes it to" +
26
+ EOL +
27
+ " 'dependency-violation-report.html' with a friendly layout",
24
28
  },
25
29
  {
26
30
  name: "depcruise:graph",
27
31
  headline: "npm run depcruise:graph",
28
32
  description:
29
- "writes a detailed internal graph of your app to 'dependency-graph.html'",
33
+ " writes a detailed internal graph of your app to 'dependency-graph.html'",
30
34
  },
31
35
  {
32
36
  name: "depcruise:graph:dev",
33
37
  headline: "npm run depcruise:graph:dev",
34
38
  description:
35
- "opens a detailed internal graph of your app in your default browser (uses the 'browser' command line program)",
39
+ " opens a detailed internal graph of your app in your default browser" +
40
+ EOL +
41
+ " (uses the 'browser' command line program)",
36
42
  },
37
43
  {
38
44
  name: "depcruise:graph:archi",
39
45
  headline: "depcruise:graph:archi",
40
46
  description:
41
- "writes a high-level internal graph of your app to 'high-level-dependency-graph.html",
47
+ " writes a high-level internal graph of your app to" +
48
+ EOL +
49
+ " 'high-level-dependency-graph.html",
42
50
  },
43
51
  {
44
52
  name: "depcruise:focus",
45
53
  headline: "npm run depcruise:focus <regex>",
46
54
  description:
47
- "writes all dependencies to and from modules matching the given <regex> to stdout - in simple text",
55
+ " writes all dependencies to and from modules matching the given <regex>" +
56
+ EOL +
57
+ " to stdout - in simple text",
48
58
  },
49
59
  // {
50
60
  // name: "depcruise:text",
@@ -121,13 +131,11 @@ function getSuccessMessage(pDestinationManifestFileName) {
121
131
  return EXPERIMENTAL_SCRIPT_DOC.reduce(
122
132
  (pAll, pScript) => {
123
133
  return `${pAll}${
124
- `\n ${chalk.green(figures.play)} ${pScript.headline}` +
125
- `\n${wrapAndIndent(`${pScript.description}`, lExplanationIndent)}\n\n`
134
+ `\n ${chalk.green("►")} ${pScript.headline}` +
135
+ `\n${pScript.description}\n\n`
126
136
  }`;
127
137
  },
128
- ` ${chalk.green(
129
- figures.tick,
130
- )} Run scripts added to '${pDestinationManifestFileName}':\n`,
138
+ ` ${chalk.green("✔")} Run scripts added to '${pDestinationManifestFileName}':\n`,
131
139
  );
132
140
  }
133
141
 
@@ -1,5 +1,4 @@
1
1
  import chalk from "chalk";
2
- import figures from "figures";
3
2
  import { SUMMARY } from "#utl/bus.mjs";
4
3
 
5
4
  const FULL_ON = 100;
@@ -7,8 +6,8 @@ const FULL_ON = 100;
7
6
  function normalizeParameters(pParameters) {
8
7
  return {
9
8
  barSize: 10,
10
- block: figures.squareSmallFilled,
11
- blank: figures.squareSmall,
9
+ block: "■",
10
+ blank: "□",
12
11
  ...(pParameters || {}),
13
12
  };
14
13
  }
@@ -2,8 +2,8 @@ import { readFile } from "node:fs/promises";
2
2
 
3
3
  import { extname } from "node:path";
4
4
  import json5 from "json5";
5
- import tryImport from "semver-try-require";
6
5
  import makeAbsolute from "./make-absolute.mjs";
6
+ import tryImport from "#utl/try-import.mjs";
7
7
  import meta from "#meta.cjs";
8
8
 
9
9
  async function getJSConfig(pBabelConfigFileName) {
@@ -1,5 +1,5 @@
1
1
  import { dirname, resolve } from "node:path";
2
- import tryImport from "semver-try-require";
2
+ import tryImport from "#utl/try-import.mjs";
3
3
  import meta from "#meta.cjs";
4
4
 
5
5
  const typescript = await tryImport(
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-inline-comments */
2
2
  /* eslint-disable max-classes-per-file */
3
- import tryImport from "semver-try-require";
3
+ import tryImport from "#utl/try-import.mjs";
4
4
  import meta from "#meta.cjs";
5
5
 
6
6
  /** @type {import('@swc/core/Visitor')} */
@@ -1,5 +1,5 @@
1
- import tryImport from "semver-try-require";
2
1
  import memoize, { memoizeClear } from "memoize";
2
+ import tryImport from "#utl/try-import.mjs";
3
3
  import meta from "#meta.cjs";
4
4
 
5
5
  /** @type {import('@swc/core')} */
@@ -1,4 +1,4 @@
1
- import tryImport from "semver-try-require";
1
+ import tryImport from "#utl/try-import.mjs";
2
2
  import meta from "#meta.cjs";
3
3
 
4
4
  const babel = await tryImport("@babel/core", meta.supportedTranspilers.babel);
@@ -1,4 +1,4 @@
1
- import tryImport from "semver-try-require";
1
+ import tryImport from "#utl/try-import.mjs";
2
2
  import meta from "#meta.cjs";
3
3
 
4
4
  /*
@@ -1,4 +1,4 @@
1
- import tryImport from "semver-try-require";
1
+ import tryImport from "#utl/try-import.mjs";
2
2
  import meta from "#meta.cjs";
3
3
 
4
4
  const livescript = await tryImport(
@@ -1,5 +1,5 @@
1
- import tryImport from "semver-try-require";
2
1
  import preProcess from "./svelte-preprocess.mjs";
2
+ import tryImport from "#utl/try-import.mjs";
3
3
  import meta from "#meta.cjs";
4
4
 
5
5
  const { compile } = await tryImport(
@@ -1,4 +1,4 @@
1
- import tryImport from "semver-try-require";
1
+ import tryImport from "#utl/try-import.mjs";
2
2
  import meta from "#meta.cjs";
3
3
 
4
4
  const typescript = await tryImport(
@@ -1,6 +1,6 @@
1
1
  const { EOL } = require("node:os");
2
2
  const isEmpty = require("lodash/isEmpty");
3
- const tryRequire = require("semver-try-require");
3
+ const tryRequire = require("#utl/try-require.cjs");
4
4
  const meta = require("#meta.cjs");
5
5
 
6
6
  /*
@@ -53,7 +53,15 @@ function vue3Transpile(pSource) {
53
53
  }
54
54
 
55
55
  function vue2Transpile(pSource) {
56
- return vueTemplateCompiler.parseComponent(pSource)?.script?.content ?? "";
56
+ const lParsedComponent = vueTemplateCompiler.parseComponent(pSource);
57
+ const lScriptContent = lParsedComponent?.script?.content ?? "";
58
+ const lScriptSetupContent = lParsedComponent?.scriptSetup?.content ?? "";
59
+
60
+ if (lScriptContent && lScriptSetupContent) {
61
+ return lScriptContent + EOL + lScriptSetupContent;
62
+ }
63
+
64
+ return lScriptContent || lScriptSetupContent;
57
65
  }
58
66
 
59
67
  module.exports = {
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable max-lines */
2
2
  /* eslint-disable no-inline-comments */
3
- import tryImport from "semver-try-require";
3
+ import tryImport from "#utl/try-import.mjs";
4
4
  import meta from "#meta.cjs";
5
5
 
6
6
  /** @type {import("typescript")} */
@@ -1,7 +1,7 @@
1
1
  import { readFileSync } from "node:fs";
2
- import tryImport from "semver-try-require";
3
2
  import memoize, { memoizeClear } from "memoize";
4
3
  import transpile from "../transpile/index.mjs";
4
+ import tryImport from "#utl/try-import.mjs";
5
5
  import meta from "#meta.cjs";
6
6
  import getExtension from "#utl/get-extension.mjs";
7
7
 
package/src/meta.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  /* generated - don't edit */
2
2
 
3
3
  module.exports = {
4
- version: "16.3.3",
4
+ version: "16.3.5",
5
5
  engines: {
6
6
  node: "^18.17||>=20",
7
7
  },
@@ -1,6 +1,5 @@
1
1
  import { EOL } from "node:os";
2
2
  import chalk from "chalk";
3
- import figures from "figures";
4
3
  import {
5
4
  formatPercentage,
6
5
  formatViolation as _formatViolation,
@@ -20,9 +19,7 @@ const EXTRA_PATH_INFORMATION_INDENT = 6;
20
19
  function formatMiniDependency(pMiniDependency) {
21
20
  return EOL.concat(
22
21
  wrapAndIndent(
23
- pMiniDependency
24
- .map(({ name }) => name)
25
- .join(` ${figures.arrowRight} ${EOL}`),
22
+ pMiniDependency.map(({ name }) => name).join(` → ${EOL}`),
26
23
  EXTRA_PATH_INFORMATION_INDENT,
27
24
  ),
28
25
  );
@@ -33,19 +30,15 @@ function formatModuleViolation(pViolation) {
33
30
  }
34
31
 
35
32
  function formatDependencyViolation(pViolation) {
36
- return `${chalk.bold(pViolation.from)} ${figures.arrowRight} ${chalk.bold(
37
- pViolation.to,
38
- )}`;
33
+ return `${chalk.bold(pViolation.from)} ${chalk.bold(pViolation.to)}`;
39
34
  }
40
35
 
41
36
  function formatCycleViolation(pViolation) {
42
- return `${chalk.bold(pViolation.from)} ${
43
- figures.arrowRight
44
- } ${formatMiniDependency(pViolation.cycle)}`;
37
+ return `${chalk.bold(pViolation.from)} ${formatMiniDependency(pViolation.cycle)}`;
45
38
  }
46
39
 
47
40
  function formatReachabilityViolation(pViolation) {
48
- return `${chalk.bold(pViolation.from)} ${figures.arrowRight} ${chalk.bold(
41
+ return `${chalk.bold(pViolation.from)} ${chalk.bold(
49
42
  pViolation.to,
50
43
  )}${formatMiniDependency(pViolation.via)}`;
51
44
  }
@@ -53,9 +46,7 @@ function formatReachabilityViolation(pViolation) {
53
46
  function formatInstabilityViolation(pViolation) {
54
47
  return `${formatDependencyViolation(pViolation)}${EOL}${wrapAndIndent(
55
48
  chalk.dim(
56
- `instability: ${formatPercentage(pViolation.metrics.from.instability)} ${
57
- figures.arrowRight
58
- } ${formatPercentage(pViolation.metrics.to.instability)}`,
49
+ `instability: ${formatPercentage(pViolation.metrics.from.instability)} ${formatPercentage(pViolation.metrics.to.instability)}`,
59
50
  ),
60
51
  EXTRA_PATH_INFORMATION_INDENT,
61
52
  )}`;
@@ -96,7 +87,7 @@ function sumMeta(pMeta) {
96
87
  }
97
88
 
98
89
  function formatSummary(pSummary) {
99
- let lMessage = `${EOL}${figures.cross} ${sumMeta(
90
+ let lMessage = `${EOL}x ${sumMeta(
100
91
  pSummary,
101
92
  )} dependency violations (${formatMeta(pSummary)}). ${
102
93
  pSummary.totalCruised
@@ -117,7 +108,7 @@ function addExplanation(pRuleSet, pLong) {
117
108
  function formatIgnoreWarning(pNumberOfIgnoredViolations) {
118
109
  if (pNumberOfIgnoredViolations > 0) {
119
110
  return chalk.yellow(
120
- `${figures.warning} ${pNumberOfIgnoredViolations} known violations ignored. Run with --no-ignore-known to see them.${EOL}`,
111
+ `‼ ${pNumberOfIgnoredViolations} known violations ignored. Run with --no-ignore-known to see them.${EOL}`,
121
112
  );
122
113
  }
123
114
  return "";
@@ -129,9 +120,7 @@ function report(pResults, pLong) {
129
120
  );
130
121
 
131
122
  if (lNonIgnorableViolations.length === 0) {
132
- return `${EOL}${chalk.green(
133
- figures.tick,
134
- )} no dependency violations found (${
123
+ return `${EOL}${chalk.green("✔")} no dependency violations found (${
135
124
  pResults.summary.totalCruised
136
125
  } modules, ${
137
126
  pResults.summary.totalDependenciesCruised
@@ -1,4 +1,3 @@
1
- import figures from "figures";
2
1
  import chalk from "chalk";
3
2
 
4
3
  const DEFAULT_OPTIONS = {
@@ -41,9 +40,7 @@ function stringifyModule(pModule) {
41
40
  }
42
41
 
43
42
  function stringify(pFlatDependency) {
44
- return `${stringifyModule(pFlatDependency.from)} ${
45
- figures.arrowRight
46
- } ${stringifyModule(pFlatDependency.to)}`;
43
+ return `${stringifyModule(pFlatDependency.from)} ${stringifyModule(pFlatDependency.to)}`;
47
44
  }
48
45
 
49
46
  /**
@@ -0,0 +1,23 @@
1
+ const LOCAL_MODULE_RE = /^[.]{1,2}($|\/.*)/g;
2
+ const ABSOLUTE_MODULE_RE = /^\/.*/g;
3
+
4
+ const PACKAGE_RE = "[^/]+";
5
+ const SCOPED_PACKAGE_RE = "@[^/]+(/[^/]+)";
6
+ const ROOT_MODULE_RE = new RegExp(`^(${SCOPED_PACKAGE_RE}|${PACKAGE_RE})`, "g");
7
+
8
+ /**
9
+ * returns the module name that likely contains the package.json
10
+ *
11
+ * @param {string} pModuleName module name string as you'd require it
12
+ * @returns {string|undefined} the module name that likely contains the package.json
13
+ */
14
+ module.exports = function extractRootModuleName(pModuleName) {
15
+ if (
16
+ pModuleName.match(LOCAL_MODULE_RE) ||
17
+ pModuleName.match(ABSOLUTE_MODULE_RE)
18
+ ) {
19
+ return pModuleName;
20
+ } else {
21
+ return (pModuleName.match(ROOT_MODULE_RE) || []).shift();
22
+ }
23
+ };
@@ -0,0 +1,67 @@
1
+ import { join } from "node:path/posix";
2
+ import { createRequire } from "node:module";
3
+ import { coerce, satisfies } from "semver";
4
+ import extractRootModuleName from "./extract-root-module-name.cjs";
5
+
6
+ const require = createRequire(import.meta.url);
7
+
8
+ /**
9
+ * @throws {Error}
10
+ * @param {string} pModuleName
11
+ * @returns {string}
12
+ */
13
+ function getVersion(pModuleName) {
14
+ // // The 'proper' way to do this would be with a dynamic import with an
15
+ // // import assertion. Because it's 'experimental' since node 16 and prints
16
+ // // an ugly warning on stderr since node 19 we'll be using the require
17
+ // // hack below in stead.
18
+ // const lManifest = await import(
19
+ // // @ts-expect-error TS2345 extractRootModuleName can return either a string or
20
+ // // undefined. If undefined this function will throw. Which is _fine_, even
21
+ // // _expected_ in the context it's currently used
22
+ // path.join(extractRootModuleName(pModuleName), "package.json"),
23
+ // { assert: { type: "json" } }
24
+ // );
25
+ // // changes the return type to Promise<string>
26
+ // return lManifest.default.version;
27
+ // eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require
28
+ const lManifest = require(
29
+ join(
30
+ // @ts-expect-error TS2345 extractRootModuleName can return either a string or
31
+ // undefined. If undefined this function will throw. Which is _fine_, even
32
+ // _expected_ in the context it's currently used
33
+ extractRootModuleName(pModuleName),
34
+ "package.json",
35
+ ),
36
+ );
37
+ return lManifest.version;
38
+ }
39
+
40
+ /**
41
+ * Tries to import a module and optionally checks its version.
42
+ *
43
+ * @param {string} pModuleName - The name of the module to import.
44
+ * @param {string} [pSemanticVersion] - An semantic version to check against.
45
+ * @returns {Promise<NodeModule | false>} - The imported module or false if the import fails or the version does not satisfy the provided semantic version.
46
+ */
47
+
48
+ // eslint-disable-next-line complexity
49
+ export default async function tryImport(pModuleName, pSemanticVersion) {
50
+ try {
51
+ if (pSemanticVersion) {
52
+ const lVersion = getVersion(pModuleName);
53
+ const lCoerced = coerce(lVersion);
54
+ if (
55
+ lVersion &&
56
+ lCoerced &&
57
+ !satisfies(lCoerced.version, pSemanticVersion)
58
+ ) {
59
+ return false;
60
+ }
61
+ }
62
+ const lModule = await import(pModuleName);
63
+ return lModule.default ? lModule.default : lModule;
64
+ } catch (pError) {
65
+ return false;
66
+ }
67
+ }
@@ -0,0 +1,51 @@
1
+ const { join } = require("node:path");
2
+ const satisfies = require("semver/functions/satisfies");
3
+ const coerce = require("semver/functions/coerce");
4
+ const extractRootModuleName = require("./extract-root-module-name.cjs");
5
+
6
+ /**
7
+ * @throws {Error}
8
+ * @param pModuleName the name of the module to get the version for
9
+ * @return the version of the module identified by pModuleName
10
+ */
11
+ function getVersion(pModuleName) {
12
+ // @ts-expect-error TS2345 extractRootModuleName can return either a string or
13
+ // undefined. If undefined this function will throw. Which is _fine_, even
14
+ // _expected_ in the context it's currently used
15
+ // eslint-disable-next-line import/no-dynamic-require, node/global-require, security/detect-non-literal-require
16
+ return require(join(extractRootModuleName(pModuleName), "package.json"))
17
+ .version;
18
+ }
19
+
20
+ /**
21
+ * returns the (resolved) module identified by pModuleName:
22
+ * - if it is available, and
23
+ * - it satisfies the semantic version range specified by pSemVer
24
+ *
25
+ * returns false in all other cases
26
+ *
27
+ * @param {string} pModuleName the name of the module to resolve
28
+ * @param {string} [pSemanticVersion] (optional) a semantic version (range)
29
+ * @return {NodeModule | false }the (resolved) module identified by pModuleName or false
30
+ */
31
+ function tryRequire(pModuleName, pSemanticVersion) {
32
+ try {
33
+ if (pSemanticVersion) {
34
+ const lVersion = getVersion(pModuleName);
35
+ const lCoerced = coerce(lVersion);
36
+ if (
37
+ lVersion &&
38
+ lCoerced &&
39
+ !satisfies(lCoerced.version, pSemanticVersion)
40
+ ) {
41
+ return false;
42
+ }
43
+ }
44
+ // eslint-disable-next-line import/no-dynamic-require, node/global-require, security/detect-non-literal-require
45
+ return require(pModuleName);
46
+ } catch (pError) {
47
+ return false;
48
+ }
49
+ }
50
+
51
+ module.exports = tryRequire;
@@ -1,11 +1,16 @@
1
- import indentString from "indent-string";
2
1
  import wrapAnsi from "wrap-ansi";
3
2
 
4
3
  const DEFAULT_INDENT = 4;
5
4
 
6
- export default function wrapAndIndent(pString, pIndent = DEFAULT_INDENT) {
5
+ function indentString(pString, pCount) {
6
+ const lRegex = /^(?!\s*$)/gm;
7
+
8
+ return pString.replace(lRegex, " ".repeat(pCount));
9
+ }
10
+
11
+ export default function wrapAndIndent(pString, pCount = DEFAULT_INDENT) {
7
12
  const lDogmaticMaxConsoleWidth = 78;
8
- const lMaxWidth = lDogmaticMaxConsoleWidth - pIndent;
13
+ const lMaxWidth = lDogmaticMaxConsoleWidth - pCount;
9
14
 
10
- return indentString(wrapAnsi(pString, lMaxWidth), pIndent);
15
+ return indentString(wrapAnsi(pString, lMaxWidth), pCount);
11
16
  }