Repository: sverweij/dependency-cruiser
Pull request #864 (2023-11-11 13:01:59)

feat(extract): makes support for workspaces explicit
## Description

- adds explicit detection of modules aliased via [workspaces](https://docs.npmjs.com/cli/v10/using-npm/workspaces)
- introduces the `aliased-workspace` dependency type

## Motivation and Context

Imports from workspaces have been well-supported in dependency-cruiser since the stone age. Not by briliant foresight, but because it plugs into the regular node.js module resolution - workspaces are symlinks in node_modules sorta automatically linked to local folders. Dependency-cruiser didn't explicitly name them as separate dependency-types (instead slotting them into dependency type 'local' or 'npm-no-pkg' (when `npm i` wasn't run on the folder yet)). This PR corrects that oversight.

This PR also fixes a bug uncovered by @throrin19: workspace imports were erroneously classified as tsconfig aliases (see #863 for details).

## How Has This Been Tested?

- [x] green ci
- [x] additional unit tests
- [x] additional integration test


## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] Documentation only change
- [ ] Refactor (non-breaking change which fixes an issue without changing functionality)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist

- [x] :book:

  - My change doesn't require a documentation update, or ...
  - it _does_ and I have updated it

- [x] :balance_scale:
  - The contribution will be subject to [The MIT license](https://github.com/sverweij/dependency-cruiser/blob/main/LICENSE), and I'm OK with that.
  - The contribution is my own original work.
  - I am ok with the stuff in [**CONTRIBUTING.md**](https://github.com/sverweij/dependency-cruiser/blob/main/.github/CONTRIBUTING.md).


codeclimate[bot]: Code Climate has analyzed commit 06192066 and detected **0 issues** on this pull request.

View more on [Code Climate](https://codeclimate.com/github/sverweij/dependency-cruiser/pull/864).

codeclimate[bot]: Code Climate has analyzed commit 54848839 and detected **0 issues** on this pull request.

View more on [Code Climate](https://codeclimate.com/github/sverweij/dependency-cruiser/pull/864).

codeclimate[bot]: Code Climate has analyzed commit 3c6e23d0 and detected **0 issues** on this pull request.

View more on [Code Climate](https://codeclimate.com/github/sverweij/dependency-cruiser/pull/864).

codeclimate[bot]: Code Climate has analyzed commit aa2860f8 and detected **0 issues** on this pull request.

View more on [Code Climate](https://codeclimate.com/github/sverweij/dependency-cruiser/pull/864).


Patch:
diff --git a/.c8rc.json b/.c8rc.json
index 4a6fd3b0..13d9cbeb 100644
--- a/.c8rc.json
+++ b/.c8rc.json
@@ -1,7 +1,7 @@
 {
   "checkCoverage": true,
   "statements": 99.89,
-  "branches": 98.72,
+  "branches": 98.76,
   "functions": 100,
   "lines": 99.89,
   "exclude": [
diff --git a/doc/rules-reference.md b/doc/rules-reference.md
index 1811e205..39a26dec 100644
--- a/doc/rules-reference.md
+++ b/doc/rules-reference.md
@@ -933,8 +933,9 @@ This is a list of dependency types dependency-cruiser currently detects.
 | core                   | it's a core module                                                                                                                                                                                          | "fs"                      |
 | aliased                | the module was imported via an alias - always occurs alongside one of 'aliased-\*' dependency types below _and_ alongside the dependency type of the dependency it's aliased to (so: local, npm, core ,...) | "~/hello.ts"              |
 | aliased-subpath-import | the module was imported via a [subpath import](https://nodejs.org/api/packages.html#subpath-imports)                                                                                                        | "#thing/hello.mjs"        |
-| aliased-webpack        | the module was imported via a [webpack resolve alias](https://webpack.js.org/configuration/resolve/#resolvealias)                                                                                           | "Utilities"               |
 | aliased-tsconfig       | the module was imported via a typescript [compilerOptions.paths setting in tsconfig](https://www.typescriptlang.org/tsconfig#paths)                                                                         | "@thing/hello"            |
+| aliased-webpack        | the module was imported via a [webpack resolve alias](https://webpack.js.org/configuration/resolve/#resolvealias)                                                                                           | "Utilities"               |
+| aliased-workspace      | the module was imported via a [workspace](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#workspaces)                                                                                           | "local-workspace-package" |
 | unknown                | it's unknown what kind of dependency type this is - probably because the module could not be resolved in the first place                                                                                    | "loodash"                 |
 | undetermined           | the dependency fell through all detection holes. This could happen with amd dependencies - which have a whole Jurassic park of ways to define where to resolve modules to                                   | "veloci!./raptor"         |
 | type-only              | the module was imported as 'type only' (e.g. `import type { IThing } from "./things";`) - only available for TypeScript sources, and only when tsPreCompilationDeps !== false                               |                           |
diff --git a/src/extract/resolve/module-classifiers.mjs b/src/extract/resolve/module-classifiers.mjs
index 15e125bb..6a0206f6 100644
--- a/src/extract/resolve/module-classifiers.mjs
+++ b/src/extract/resolve/module-classifiers.mjs
@@ -1,4 +1,5 @@
 import { isAbsolute, resolve as path_resolve } from "node:path";
+import { isMatch } from "picomatch";
 import getExtension from "#utl/get-extension.mjs";
 
 let gFollowableExtensionsCache = new Set();
@@ -89,14 +90,7 @@ export function isFollowable(pResolvedFilename, pResolveOptions) {
   );
 }
 
-function isWebPackAliased(pModuleName, pAliasObject) {
-  return Object.keys(pAliasObject || {}).some((pAliasLHS) =>
-    pModuleName.startsWith(pAliasLHS),
-  );
-}
-
 /**
- *
  * @param {string} pModuleName
  * @param {object} pManifest
  * @returns {boolean}
@@ -105,6 +99,11 @@ function isSubpathImport(pModuleName, pManifest) {
   return (
     pModuleName.startsWith("#") &&
     Object.keys(pManifest?.imports ?? {}).some((pImportLHS) => {
+      // Although they might look as such, the LHS of an import statement
+      // (a 'subpath pattern') is not a glob. The * functions as string
+      // replacement only.
+      // Quoting https://nodejs.org/api/packages.html#subpath-imports :
+      // > "* maps expose nested subpaths as it is a string replacement syntax only"
       const lMatchREasString = pImportLHS.replace(/\*/g, ".+");
       // eslint-disable-next-line security/detect-non-literal-regexp
       const lMatchRE = new RegExp(`^${lMatchREasString}$`);
@@ -113,6 +112,83 @@ function isSubpathImport(pModuleName, pManifest) {
   );
 }
 
+/**
+ * @param {string} pModuleName
+ * @param {object} pAliasObject
+ * @returns {boolean}
+ */
+function isWebPackAliased(pModuleName, pAliasObject) {
+  return Object.keys(pAliasObject || {}).some((pAliasLHS) =>
+    pModuleName.startsWith(pAliasLHS),
+  );
+}
+
+/**
+ * @param {string} pModuleName
+ * @param {string} pResolvedModuleName
+ * @param {object} pManifest
+ * @returns {boolean}
+ */
+// eslint-disable-next-line max-lines-per-function
+function isWorkspaceAliased(pModuleName, pResolvedModuleName, pManifest) {
+  // reference: https://docs.npmjs.com/cli/v10/using-npm/workspaces
+  if (pManifest?.workspaces) {
+    // workspaces are an array of globs that match the (sub) workspace
+    // folder itself only.
+    //
+    // workspaces: [
+    //  "packages/*",  -> matches packages/a, packages/b, packages/c, ...
+    //  "libs/x",      -> matches libs/x
+    //  "libs/y",      -> matches libs/y
+    //  "apps"         -> matches apps
+    // ]
+    //
+    // By definition this will _never_ match resolved module names.
+    // E.g. in packages/a => packages/a/dist/main/index.js or
+    // in libs/x => libs/x/index.js
+    //
+    // This is why we chuck a `/**` at the end of each workspace glob, which
+    // transforms it into a 'starts with' glob. And yeah, you can have a /
+    // at the end of a glob. And because double slashes are taken literally
+    // we have a ternary operator to prevent those.
+    //
+    // oh and: ```picomatch.isMatch('asdf', 'asdf/**') === true``` so
+    // in case it's only 'asdf' that's in the resolved module name for some reason
+    //  we're good as well.
+    const lModuleFriendlyWorkspaceGlobs = pManifest.workspaces.map(
+      (pWorkspace) =>
+        pWorkspace.endsWith("/") ? `${pWorkspace}**` : `${pWorkspace}/**`,
+    );
+    if (isMatch(pResolvedModuleName, lModuleFriendlyWorkspaceGlobs)) {
+      return true;
+    }
+    // it's possible to run node with --preserve-symlinks, in which case
+    // the symlinked workspace folders are not resolved to their realpath.
+    // So we need to check both the thing in node_modules _and_ the resolved
+    // thing. Annoyingly, the symlink in node_modules is the `name` attribute
+    // of the workspace, not the path of the  workspace itself. So if it's
+    // in node_modules we need to check against the unresolved modulename.
+    //
+    // Other then the detection for when symlinks are resolved to their realpath
+    // (the if above), this is a 'best effort' detection only for now; there's
+    // guaranteed to be scenarios where this will fail. How often is the
+    // --preserve-symlinks flag used in practice, though?
+    const lModuleFriendlyWorkspaceGlobsWithNodeModules =
+      lModuleFriendlyWorkspaceGlobs.map(
+        (pWorkspace) => `(node_modules/)?${pWorkspace}`,
+      );
+    return isMatch(pModuleName, lModuleFriendlyWorkspaceGlobsWithNodeModules);
+  }
+  return false;
+}
+
+/**
+ * @param {string} pModuleName
+ * @param {string} pResolvedModuleName
+ * @param {import("../../../types/resolve-options").IResolveOptions} pResolveOptions
+ * @param {string} pBaseDirectory
+ * @returns {boolean}
+ */
 function isLikelyTSAliased(
   pModuleName,
   pResolvedModuleName,
@@ -128,7 +204,6 @@ function isLikelyTSAliased(
 }
 
 /**
- *
  * @param {string} pModuleName
  * @param {string} pResolvedModuleName
  * @param {import("../../../types/resolve-options").IResolveOptions} pResolveOptions
@@ -147,6 +222,9 @@ export function getAliasTypes(
   if (isWebPackAliased(pModuleName, pResolveOptions.alias)) {
     return ["aliased", "aliased-webpack"];
   }
+  if (isWorkspaceAliased(pModuleName, pResolvedModuleName, pManifest)) {
+    return ["aliased", "aliased-workspace"];
+  }
   if (
     isLikelyTSAliased(
       pModuleName,
diff --git a/src/schema/configuration.schema.json b/src/schema/configuration.schema.json
index 32977a33..7f455456 100644
--- a/src/schema/configuration.schema.json
+++ b/src/schema/configuration.schema.json
@@ -388,8 +388,9 @@
       "enum": [
         "aliased",
         "aliased-subpath-import",
-        "aliased-webpack",
         "aliased-tsconfig",
+        "aliased-webpack",
+        "aliased-workspace",
         "core",
         "deprecated",
         "local",
diff --git a/src/schema/configuration.schema.mjs b/src/schema/configuration.schema.mjs
index 2644539c..67e9d805 100644
--- a/src/schema/configuration.schema.mjs
+++ b/src/schema/configuration.schema.mjs
@@ -1,1 +1,1 @@
-/* generated - don't edit */export default {"title":"dependency-cruiser configuration","$schema":"http://json-schema.org/draft-07/schema#","$id":"https://dependency-cruiser.js.org/schema/configuration.schema.json","type":"object","additionalProperties":false,"properties":{"$schema":{"type":"string"},"forbidden":{"type":"array","items":{"$ref":"#/definitions/ForbiddenRuleType"}},"allowed":{"type":"array","items":{"$ref":"#/definitions/AllowedRuleType"}},"allowedSeverity":{"$ref":"#/definitions/SeverityType"},"required":{"type":"array","items":{"$ref":"#/definitions/RequiredRuleType"}},"options":{"$ref":"#/definitions/OptionsType"},"extends":{"$ref":"#/definitions/ExtendsType"}},"definitions":{"RuleSetType":{"type":"object","additionalProperties":false,"properties":{"forbidden":{"type":"array","items":{"$ref":"#/definitions/ForbiddenRuleType"}},"allowed":{"type":"array","items":{"$ref":"#/definitions/AllowedRuleType"}},"allowedSeverity":{"$ref":"#/definitions/SeverityType"},"required":{"type":"array","items":{"$ref":"#/definitions/RequiredRuleType"}}}},"AllowedRuleType":{"oneOf":[{"$ref":"#/definitions/RegularAllowedRuleType"},{"$ref":"#/definitions/ReachabilityAllowedRuleType"}]},"RegularAllowedRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"comment":{"type":"string"},"scope":{"type":"string","enum":["module","folder"]},"from":{"$ref":"#/definitions/FromRestrictionType"},"to":{"$ref":"#/definitions/ToRestrictionType"}}},"ReachabilityAllowedRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"comment":{"type":"string"},"scope":{"type":"string","enum":["module","folder"]},"from":{"$ref":"#/definitions/ReachabilityFromRestrictionType"},"to":{"$ref":"#/definitions/ReachabilityToRestrictionType"}}},"ForbiddenRuleType":{"oneOf":[{"$ref":"#/definitions/RegularForbiddenRuleType"},{"$ref":"#/definitions/ReachabilityForbiddenRuleType"},{"$ref":"#/definitions/DependentsForbiddenRuleType"}]},"RegularForbiddenRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"from":{"$ref":"#/definitions/FromRestrictionType"},"to":{"$ref":"#/definitions/ToRestrictionType"}}},"DependentsForbiddenRuleType":{"type":"object","required":["module","from"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"module":{"$ref":"#/definitions/DependentsModuleRestrictionType"},"from":{"$ref":"#/definitions/DependentsFromRestrictionType"}}},"ReachabilityForbiddenRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"from":{"$ref":"#/definitions/ReachabilityFromRestrictionType"},"to":{"$ref":"#/definitions/ReachabilityToRestrictionType"}}},"RequiredRuleType":{"type":"object","required":["module","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"module":{"$ref":"#/definitions/RequiredModuleRestrictionType"},"to":{"$ref":"#/definitions/RequiredToRestrictionType"}}},"FromRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"orphan":{"type":"boolean"}}},"ReachabilityFromRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"ToRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"couldNotResolve":{"type":"boolean"},"circular":{"type":"boolean"},"dynamic":{"type":"boolean"},"exoticallyRequired":{"type":"boolean"},"exoticRequire":{"$ref":"#/definitions/REAsStringsType"},"exoticRequireNot":{"$ref":"#/definitions/REAsStringsType"},"preCompilationOnly":{"type":"boolean"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"dependencyTypesNot":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"moreThanOneDependencyType":{"type":"boolean"},"license":{"$ref":"#/definitions/REAsStringsType"},"licenseNot":{"$ref":"#/definitions/REAsStringsType"},"via":{"$ref":"#/definitions/REAsStringsType"},"viaOnly":{"$ref":"#/definitions/REAsStringsType"},"viaNot":{"$ref":"#/definitions/REAsStringsType"},"viaSomeNot":{"$ref":"#/definitions/REAsStringsType"},"moreUnstable":{"type":"boolean"}}},"DependentsModuleRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"numberOfDependentsLessThan":{"type":"integer","minimum":0,"maximum":100},"numberOfDependentsMoreThan":{"type":"integer","minimum":0,"maximum":100}}},"DependentsFromRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"ReachabilityToRestrictionType":{"required":["reachable"],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"reachable":{"type":"boolean"}}},"RequiredModuleRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"RequiredToRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"DependencyTypeType":{"type":"string","enum":["aliased","aliased-subpath-import","aliased-webpack","aliased-tsconfig","core","deprecated","local","localmodule","npm","npm-bundled","npm-dev","npm-no-pkg","npm-optional","npm-peer","npm-unknown","undetermined","unknown","type-only"]},"REAsStringsType":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"SeverityType":{"type":"string","enum":["error","warn","info","ignore"]},"OptionsType":{"type":"object","additionalProperties":false,"properties":{"doNotFollow":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundDoNotFollowType"}]},"exclude":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundExcludeType"}]},"includeOnly":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundIncludeOnlyType"}]},"focus":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundFocusType"}]},"reaches":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundReachesType"}]},"highlight":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundHighlightType"}]},"knownViolations":{"$ref":"#/definitions/ViolationsType"},"collapse":{"oneOf":[{"type":"string"},{"type":"integer","minimum":1,"maximum":9}]},"maxDepth":{"type":"integer","minimum":0,"maximum":99},"moduleSystems":{"$ref":"#/definitions/ModuleSystemsType"},"prefix":{"type":"string"},"preserveSymlinks":{"type":"boolean"},"combinedDependencies":{"type":"boolean"},"tsConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"}}},"tsPreCompilationDeps":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["specify"]}]},"extraExtensionsToScan":{"type":"array","items":{"type":"string"}},"externalModuleResolutionStrategy":{"type":"string","enum":["node_modules","yarn-pnp"]},"builtInModules":{"type":"object","additionalProperties":false,"properties":{"override":{"type":"array","items":{"type":"string"}},"add":{"type":"array","items":{"type":"string"}}}},"forceDeriveDependents":{"type":"boolean"},"webpackConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"},"env":{"oneOf":[{"type":"object"},{"type":"string"}]},"arguments":{"type":"object"}}},"enhancedResolveOptions":{"type":"object","additionalProperties":false,"properties":{"exportsFields":{"type":"array","items":{"type":"string"}},"conditionNames":{"type":"array","items":{"type":"string"}},"extensions":{"type":"array","items":{"type":"string"}},"mainFields":{"type":"array"},"mainFiles":{"type":"array"},"cachedInputFileSystem":{"type":"object","additionalProperties":false,"properties":{"cacheDuration":{"type":"integer","minimum":0,"maximum":1800000}}}}},"babelConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"}}},"parser":{"type":"string","enum":["acorn","swc","tsc"]},"exoticRequireStrings":{"type":"array","items":{"type":"string"}},"reporterOptions":{"$ref":"#/definitions/ReporterOptionsType"},"progress":{"type":"object","additionalProperties":false,"properties":{"type":{"type":"string","enum":["cli-feedback","performance-log","ndjson","none"]},"maximumLevel":{"type":"number","enum":[-1,40,50,60,70,80,99]}}},"metrics":{"type":"boolean"},"baseDir":{"type":"string"},"cache":{"oneOf":[{"type":"boolean"},{"type":"string"},{"$ref":"#/definitions/CacheOptionsType"}]}}},"ModuleSystemType":{"type":"string","enum":["cjs","es6","amd","tsd"]},"ModuleSystemsType":{"type":"array","items":{"$ref":"#/definitions/ModuleSystemType"}},"CompoundExcludeType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"dynamic":{"type":"boolean"}}},"CompoundDoNotFollowType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}}}},"CompoundIncludeOnlyType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"CompoundFocusType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"depth":{"type":"number","minimum":1,"maximum":4}}},"CompoundReachesType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"CompoundHighlightType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"ReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"anon":{"$ref":"#/definitions/AnonReporterOptionsType"},"archi":{"$ref":"#/definitions/DotReporterOptionsType"},"dot":{"$ref":"#/definitions/DotReporterOptionsType"},"ddot":{"$ref":"#/definitions/DotReporterOptionsType"},"flat":{"$ref":"#/definitions/DotReporterOptionsType"},"markdown":{"$ref":"#/definitions/MarkdownReporterOptionsType"},"metrics":{"$ref":"#/definitions/MetricsReporterOptionsType"},"mermaid":{"$ref":"#/definitions/MermaidReporterOptionsType"},"text":{"$ref":"#/definitions/TextReporterOptionsType"}}},"AnonReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"wordlist":{"type":"array","items":{"type":"string"}}}},"MetricsReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"orderBy":{"type":"string","enum":["instability","moduleCount","afferentCouplings","efferentCouplings","name"]},"hideModules":{"type":"boolean"},"hideFolders":{"type":"boolean"}}},"MarkdownReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"showTitle":{"type":"boolean"},"title":{"type":"string"},"showSummary":{"type":"boolean"},"showSummaryHeader":{"type":"boolean"},"summaryHeader":{"type":"string"},"showStatsSummary":{"type":"boolean"},"showRulesSummary":{"type":"boolean"},"includeIgnoredInSummary":{"type":"boolean"},"showDetails":{"type":"boolean"},"includeIgnoredInDetails":{"type":"boolean"},"showDetailsHeader":{"type":"boolean"},"detailsHeader":{"type":"string"},"collapseDetails":{"type":"boolean"},"collapsedMessage":{"type":"string"},"noViolationsMessage":{"type":"string"},"showFooter":{"type":"boolean"}}},"MermaidReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"minify":{"type":"boolean"}}},"TextReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"highlightFocused":{"type":"boolean"}}},"DotReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"collapsePattern":{"$ref":"#/definitions/REAsStringsType"},"filters":{"$ref":"#/definitions/ReporterFiltersType"},"showMetrics":{"type":"boolean"},"theme":{"$ref":"#/definitions/DotThemeType"}}},"DotThemeType":{"type":"object","additionalProperties":false,"properties":{"replace":{"type":"boolean"},"graph":{"type":"object"},"node":{"type":"object"},"edge":{"type":"object"},"modules":{"$ref":"#/definitions/DotThemeArrayType"},"dependencies":{"$ref":"#/definitions/DotThemeArrayType"}}},"DotThemeArrayType":{"type":"array","items":{"$ref":"#/definitions/DotThemeEntryType"}},"DotThemeEntryType":{"type":"object","additionalProperties":false,"properties":{"criteria":{"type":"object"},"attributes":{"type":"object"}}},"ReporterFiltersType":{"type":"object","additionalProperties":false,"properties":{"exclude":{"$ref":"#/definitions/CompoundExcludeType"},"includeOnly":{"$ref":"#/definitions/CompoundIncludeOnlyType"},"focus":{"$ref":"#/definitions/CompoundFocusType"},"reaches":{"$ref":"#/definitions/CompoundReachesType"}}},"ViolationsType":{"type":"array","items":{"$ref":"#/definitions/ViolationType"}},"ViolationType":{"type":"object","required":["from","to","rule"],"additionalProperties":false,"properties":{"from":{"type":"string"},"to":{"type":"string"},"type":{"$ref":"#/definitions/ViolationTypeType"},"rule":{"$ref":"#/definitions/RuleSummaryType"},"cycle":{"type":"array","items":{"type":"string"}},"via":{"type":"array","items":{"type":"string"}},"metrics":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"from":{"type":"object","required":["instability"],"additionalProperties":false,"properties":{"instability":{"type":"number"}}},"to":{"type":"object","required":["instability"],"additionalProperties":false,"properties":{"instability":{"type":"number"}}}}},"comment":{"type":"string"}}},"RuleSummaryType":{"type":"object","required":["name","severity"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"}}},"ViolationTypeType":{"type":"string","enum":["dependency","module","reachability","cycle","instability","folder"]},"CacheOptionsType":{"type":"object","additionalProperties":false,"properties":{"folder":{"type":"string"},"strategy":{"$ref":"#/definitions/CacheStrategyType"},"compress":{"type":"boolean","default":false}}},"CacheStrategyType":{"type":"string","enum":["metadata","content"]},"ExtendsType":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}}}
\ No newline at end of file
+/* generated - don't edit */export default {"title":"dependency-cruiser configuration","$schema":"http://json-schema.org/draft-07/schema#","$id":"https://dependency-cruiser.js.org/schema/configuration.schema.json","type":"object","additionalProperties":false,"properties":{"$schema":{"type":"string"},"forbidden":{"type":"array","items":{"$ref":"#/definitions/ForbiddenRuleType"}},"allowed":{"type":"array","items":{"$ref":"#/definitions/AllowedRuleType"}},"allowedSeverity":{"$ref":"#/definitions/SeverityType"},"required":{"type":"array","items":{"$ref":"#/definitions/RequiredRuleType"}},"options":{"$ref":"#/definitions/OptionsType"},"extends":{"$ref":"#/definitions/ExtendsType"}},"definitions":{"RuleSetType":{"type":"object","additionalProperties":false,"properties":{"forbidden":{"type":"array","items":{"$ref":"#/definitions/ForbiddenRuleType"}},"allowed":{"type":"array","items":{"$ref":"#/definitions/AllowedRuleType"}},"allowedSeverity":{"$ref":"#/definitions/SeverityType"},"required":{"type":"array","items":{"$ref":"#/definitions/RequiredRuleType"}}}},"AllowedRuleType":{"oneOf":[{"$ref":"#/definitions/RegularAllowedRuleType"},{"$ref":"#/definitions/ReachabilityAllowedRuleType"}]},"RegularAllowedRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"comment":{"type":"string"},"scope":{"type":"string","enum":["module","folder"]},"from":{"$ref":"#/definitions/FromRestrictionType"},"to":{"$ref":"#/definitions/ToRestrictionType"}}},"ReachabilityAllowedRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"comment":{"type":"string"},"scope":{"type":"string","enum":["module","folder"]},"from":{"$ref":"#/definitions/ReachabilityFromRestrictionType"},"to":{"$ref":"#/definitions/ReachabilityToRestrictionType"}}},"ForbiddenRuleType":{"oneOf":[{"$ref":"#/definitions/RegularForbiddenRuleType"},{"$ref":"#/definitions/ReachabilityForbiddenRuleType"},{"$ref":"#/definitions/DependentsForbiddenRuleType"}]},"RegularForbiddenRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"from":{"$ref":"#/definitions/FromRestrictionType"},"to":{"$ref":"#/definitions/ToRestrictionType"}}},"DependentsForbiddenRuleType":{"type":"object","required":["module","from"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"module":{"$ref":"#/definitions/DependentsModuleRestrictionType"},"from":{"$ref":"#/definitions/DependentsFromRestrictionType"}}},"ReachabilityForbiddenRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"from":{"$ref":"#/definitions/ReachabilityFromRestrictionType"},"to":{"$ref":"#/definitions/ReachabilityToRestrictionType"}}},"RequiredRuleType":{"type":"object","required":["module","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"module":{"$ref":"#/definitions/RequiredModuleRestrictionType"},"to":{"$ref":"#/definitions/RequiredToRestrictionType"}}},"FromRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"orphan":{"type":"boolean"}}},"ReachabilityFromRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"ToRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"couldNotResolve":{"type":"boolean"},"circular":{"type":"boolean"},"dynamic":{"type":"boolean"},"exoticallyRequired":{"type":"boolean"},"exoticRequire":{"$ref":"#/definitions/REAsStringsType"},"exoticRequireNot":{"$ref":"#/definitions/REAsStringsType"},"preCompilationOnly":{"type":"boolean"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"dependencyTypesNot":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"moreThanOneDependencyType":{"type":"boolean"},"license":{"$ref":"#/definitions/REAsStringsType"},"licenseNot":{"$ref":"#/definitions/REAsStringsType"},"via":{"$ref":"#/definitions/REAsStringsType"},"viaOnly":{"$ref":"#/definitions/REAsStringsType"},"viaNot":{"$ref":"#/definitions/REAsStringsType"},"viaSomeNot":{"$ref":"#/definitions/REAsStringsType"},"moreUnstable":{"type":"boolean"}}},"DependentsModuleRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"numberOfDependentsLessThan":{"type":"integer","minimum":0,"maximum":100},"numberOfDependentsMoreThan":{"type":"integer","minimum":0,"maximum":100}}},"DependentsFromRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"ReachabilityToRestrictionType":{"required":["reachable"],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"reachable":{"type":"boolean"}}},"RequiredModuleRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"RequiredToRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"DependencyTypeType":{"type":"string","enum":["aliased","aliased-subpath-import","aliased-tsconfig","aliased-webpack","aliased-workspace","core","deprecated","local","localmodule","npm","npm-bundled","npm-dev","npm-no-pkg","npm-optional","npm-peer","npm-unknown","undetermined","unknown","type-only"]},"REAsStringsType":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"SeverityType":{"type":"string","enum":["error","warn","info","ignore"]},"OptionsType":{"type":"object","additionalProperties":false,"properties":{"doNotFollow":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundDoNotFollowType"}]},"exclude":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundExcludeType"}]},"includeOnly":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundIncludeOnlyType"}]},"focus":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundFocusType"}]},"reaches":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundReachesType"}]},"highlight":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundHighlightType"}]},"knownViolations":{"$ref":"#/definitions/ViolationsType"},"collapse":{"oneOf":[{"type":"string"},{"type":"integer","minimum":1,"maximum":9}]},"maxDepth":{"type":"integer","minimum":0,"maximum":99},"moduleSystems":{"$ref":"#/definitions/ModuleSystemsType"},"prefix":{"type":"string"},"preserveSymlinks":{"type":"boolean"},"combinedDependencies":{"type":"boolean"},"tsConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"}}},"tsPreCompilationDeps":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["specify"]}]},"extraExtensionsToScan":{"type":"array","items":{"type":"string"}},"externalModuleResolutionStrategy":{"type":"string","enum":["node_modules","yarn-pnp"]},"builtInModules":{"type":"object","additionalProperties":false,"properties":{"override":{"type":"array","items":{"type":"string"}},"add":{"type":"array","items":{"type":"string"}}}},"forceDeriveDependents":{"type":"boolean"},"webpackConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"},"env":{"oneOf":[{"type":"object"},{"type":"string"}]},"arguments":{"type":"object"}}},"enhancedResolveOptions":{"type":"object","additionalProperties":false,"properties":{"exportsFields":{"type":"array","items":{"type":"string"}},"conditionNames":{"type":"array","items":{"type":"string"}},"extensions":{"type":"array","items":{"type":"string"}},"mainFields":{"type":"array"},"mainFiles":{"type":"array"},"cachedInputFileSystem":{"type":"object","additionalProperties":false,"properties":{"cacheDuration":{"type":"integer","minimum":0,"maximum":1800000}}}}},"babelConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"}}},"parser":{"type":"string","enum":["acorn","swc","tsc"]},"exoticRequireStrings":{"type":"array","items":{"type":"string"}},"reporterOptions":{"$ref":"#/definitions/ReporterOptionsType"},"progress":{"type":"object","additionalProperties":false,"properties":{"type":{"type":"string","enum":["cli-feedback","performance-log","ndjson","none"]},"maximumLevel":{"type":"number","enum":[-1,40,50,60,70,80,99]}}},"metrics":{"type":"boolean"},"baseDir":{"type":"string"},"cache":{"oneOf":[{"type":"boolean"},{"type":"string"},{"$ref":"#/definitions/CacheOptionsType"}]}}},"ModuleSystemType":{"type":"string","enum":["cjs","es6","amd","tsd"]},"ModuleSystemsType":{"type":"array","items":{"$ref":"#/definitions/ModuleSystemType"}},"CompoundExcludeType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"dynamic":{"type":"boolean"}}},"CompoundDoNotFollowType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}}}},"CompoundIncludeOnlyType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"CompoundFocusType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"depth":{"type":"number","minimum":1,"maximum":4}}},"CompoundReachesType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"CompoundHighlightType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"ReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"anon":{"$ref":"#/definitions/AnonReporterOptionsType"},"archi":{"$ref":"#/definitions/DotReporterOptionsType"},"dot":{"$ref":"#/definitions/DotReporterOptionsType"},"ddot":{"$ref":"#/definitions/DotReporterOptionsType"},"flat":{"$ref":"#/definitions/DotReporterOptionsType"},"markdown":{"$ref":"#/definitions/MarkdownReporterOptionsType"},"metrics":{"$ref":"#/definitions/MetricsReporterOptionsType"},"mermaid":{"$ref":"#/definitions/MermaidReporterOptionsType"},"text":{"$ref":"#/definitions/TextReporterOptionsType"}}},"AnonReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"wordlist":{"type":"array","items":{"type":"string"}}}},"MetricsReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"orderBy":{"type":"string","enum":["instability","moduleCount","afferentCouplings","efferentCouplings","name"]},"hideModules":{"type":"boolean"},"hideFolders":{"type":"boolean"}}},"MarkdownReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"showTitle":{"type":"boolean"},"title":{"type":"string"},"showSummary":{"type":"boolean"},"showSummaryHeader":{"type":"boolean"},"summaryHeader":{"type":"string"},"showStatsSummary":{"type":"boolean"},"showRulesSummary":{"type":"boolean"},"includeIgnoredInSummary":{"type":"boolean"},"showDetails":{"type":"boolean"},"includeIgnoredInDetails":{"type":"boolean"},"showDetailsHeader":{"type":"boolean"},"detailsHeader":{"type":"string"},"collapseDetails":{"type":"boolean"},"collapsedMessage":{"type":"string"},"noViolationsMessage":{"type":"string"},"showFooter":{"type":"boolean"}}},"MermaidReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"minify":{"type":"boolean"}}},"TextReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"highlightFocused":{"type":"boolean"}}},"DotReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"collapsePattern":{"$ref":"#/definitions/REAsStringsType"},"filters":{"$ref":"#/definitions/ReporterFiltersType"},"showMetrics":{"type":"boolean"},"theme":{"$ref":"#/definitions/DotThemeType"}}},"DotThemeType":{"type":"object","additionalProperties":false,"properties":{"replace":{"type":"boolean"},"graph":{"type":"object"},"node":{"type":"object"},"edge":{"type":"object"},"modules":{"$ref":"#/definitions/DotThemeArrayType"},"dependencies":{"$ref":"#/definitions/DotThemeArrayType"}}},"DotThemeArrayType":{"type":"array","items":{"$ref":"#/definitions/DotThemeEntryType"}},"DotThemeEntryType":{"type":"object","additionalProperties":false,"properties":{"criteria":{"type":"object"},"attributes":{"type":"object"}}},"ReporterFiltersType":{"type":"object","additionalProperties":false,"properties":{"exclude":{"$ref":"#/definitions/CompoundExcludeType"},"includeOnly":{"$ref":"#/definitions/CompoundIncludeOnlyType"},"focus":{"$ref":"#/definitions/CompoundFocusType"},"reaches":{"$ref":"#/definitions/CompoundReachesType"}}},"ViolationsType":{"type":"array","items":{"$ref":"#/definitions/ViolationType"}},"ViolationType":{"type":"object","required":["from","to","rule"],"additionalProperties":false,"properties":{"from":{"type":"string"},"to":{"type":"string"},"type":{"$ref":"#/definitions/ViolationTypeType"},"rule":{"$ref":"#/definitions/RuleSummaryType"},"cycle":{"type":"array","items":{"type":"string"}},"via":{"type":"array","items":{"type":"string"}},"metrics":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"from":{"type":"object","required":["instability"],"additionalProperties":false,"properties":{"instability":{"type":"number"}}},"to":{"type":"object","required":["instability"],"additionalProperties":false,"properties":{"instability":{"type":"number"}}}}},"comment":{"type":"string"}}},"RuleSummaryType":{"type":"object","required":["name","severity"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"}}},"ViolationTypeType":{"type":"string","enum":["dependency","module","reachability","cycle","instability","folder"]},"CacheOptionsType":{"type":"object","additionalProperties":false,"properties":{"folder":{"type":"string"},"strategy":{"$ref":"#/definitions/CacheStrategyType"},"compress":{"type":"boolean","default":false}}},"CacheStrategyType":{"type":"string","enum":["metadata","content"]},"ExtendsType":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}}}
\ No newline at end of file
diff --git a/src/schema/cruise-result.schema.json b/src/schema/cruise-result.schema.json
index 128db541..d30bb11a 100644
--- a/src/schema/cruise-result.schema.json
+++ b/src/schema/cruise-result.schema.json
@@ -269,8 +269,9 @@
       "enum": [
         "aliased",
         "aliased-subpath-import",
-        "aliased-webpack",
         "aliased-tsconfig",
+        "aliased-webpack",
+        "aliased-workspace",
         "core",
         "deprecated",
         "local",
diff --git a/src/schema/cruise-result.schema.mjs b/src/schema/cruise-result.schema.mjs
index fe9a481e..ee43768d 100644
--- a/src/schema/cruise-result.schema.mjs
+++ b/src/schema/cruise-result.schema.mjs
@@ -1,1 +1,1 @@
-/* generated - don't edit */export default {"title":"dependency-cruiser output format","$schema":"http://json-schema.org/draft-07/schema#","$id":"https://dependency-cruiser.js.org/schema/cruise-result.schema.json","type":"object","required":["summary","modules"],"additionalProperties":false,"properties":{"modules":{"$ref":"#/definitions/ModulesType"},"folders":{"$ref":"#/definitions/FoldersType"},"summary":{"$ref":"#/definitions/SummaryType"},"revisionData":{"$ref":"#/definitions/RevisionDataType"}},"definitions":{"ModulesType":{"type":"array","items":{"$ref":"#/definitions/ModuleType"}},"ModuleType":{"type":"object","required":["source","dependencies","valid"],"additionalProperties":false,"properties":{"source":{"type":"string"},"valid":{"type":"boolean"},"dependencies":{"$ref":"#/definitions/DependenciesType"},"dependents":{"type":"array","items":{"type":"string"}},"followable":{"type":"boolean"},"matchesDoNotFollow":{"type":"boolean"},"matchesFocus":{"type":"boolean"},"matchesReaches":{"type":"boolean"},"matchesHighlight":{"type":"boolean"},"coreModule":{"type":"boolean"},"couldNotResolve":{"type":"boolean"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"license":{"type":"string"},"orphan":{"type":"boolean"},"reachable":{"type":"array","items":{"$ref":"#/definitions/ReachableType"}},"reaches":{"type":"array","items":{"$ref":"#/definitions/ReachesType"}},"rules":{"type":"array","items":{"$ref":"#/definitions/RuleSummaryType"}},"consolidated":{"type":"boolean"},"instability":{"type":"number"},"checksum":{"type":"string"}}},"ReachableType":{"type":"object","required":["value","asDefinedInRule","matchedFrom"],"additionalProperties":false,"properties":{"value":{"type":"boolean"},"asDefinedInRule":{"type":"string"},"matchedFrom":{"type":"string"}}},"ReachesType":{"type":"object","required":["modules","asDefinedInRule"],"additionalProperties":false,"properties":{"modules":{"type":"array","items":{"type":"object","required":["source","via"],"additionalProperties":false,"properties":{"source":{"type":"string"},"via":{"type":"array","items":{"type":"string"}}}}},"asDefinedInRule":{"type":"string"}}},"DependenciesType":{"type":"array","items":{"$ref":"#/definitions/DependencyType"}},"DependencyType":{"type":"object","required":["circular","coreModule","couldNotResolve","dependencyTypes","exoticallyRequired","dynamic","followable","module","moduleSystem","resolved","valid"],"additionalProperties":false,"properties":{"module":{"type":"string"},"protocol":{"type":"string","enum":["data:","file:","node:"]},"mimeType":{"type":"string"},"resolved":{"type":"string"},"coreModule":{"type":"boolean"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"license":{"type":"string"},"followable":{"type":"boolean"},"dynamic":{"type":"boolean"},"exoticallyRequired":{"type":"boolean"},"exoticRequire":{"type":"string"},"matchesDoNotFollow":{"type":"boolean"},"couldNotResolve":{"type":"boolean"},"preCompilationOnly":{"type":"boolean"},"typeOnly":{"type":"boolean"},"circular":{"type":"boolean"},"cycle":{"type":"array","items":{"type":"string"}},"moduleSystem":{"$ref":"#/definitions/ModuleSystemType"},"valid":{"type":"boolean"},"rules":{"type":"array","items":{"$ref":"#/definitions/RuleSummaryType"}},"instability":{"type":"number"}}},"DependencyTypeType":{"type":"string","enum":["aliased","aliased-subpath-import","aliased-webpack","aliased-tsconfig","core","deprecated","local","localmodule","npm","npm-bundled","npm-dev","npm-no-pkg","npm-optional","npm-peer","npm-unknown","undetermined","unknown","type-only"]},"ModuleSystemType":{"type":"string","enum":["cjs","es6","amd","tsd"]},"RuleSummaryType":{"type":"object","required":["name","severity"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"}}},"SeverityType":{"type":"string","enum":["error","warn","info","ignore"]},"FoldersType":{"type":"array","items":{"$ref":"#/definitions/FolderType"}},"FolderType":{"type":"object","required":["name","moduleCount"],"additionalProperties":false,"properties":{"name":{"type":"string"},"dependents":{"type":"array","items":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string"}}}},"dependencies":{"type":"array","items":{"type":"object","required":["name","valid","circular"],"additionalProperties":false,"properties":{"name":{"type":"string"},"instability":{"type":"number"},"valid":{"type":"boolean"},"circular":{"type":"boolean"},"cycle":{"type":"array","items":{"type":"string"}},"rules":{"type":"array","items":{"$ref":"#/definitions/RuleSummaryType"}}}}},"moduleCount":{"type":"number"},"afferentCouplings":{"type":"number"},"efferentCouplings":{"type":"number"},"instability":{"type":"number"}}},"SummaryType":{"type":"object","required":["violations","error","warn","info","totalCruised","optionsUsed"],"additionalProperties":false,"properties":{"violations":{"$ref":"#/definitions/ViolationsType"},"error":{"type":"number"},"warn":{"type":"number"},"info":{"type":"number"},"ignore":{"type":"number"},"totalCruised":{"type":"number"},"totalDependenciesCruised":{"type":"number"},"ruleSetUsed":{"$ref":"#/definitions/RuleSetType"},"optionsUsed":{"$ref":"#/definitions/OptionsUsedType"}}},"ViolationsType":{"type":"array","items":{"$ref":"#/definitions/ViolationType"}},"ViolationType":{"type":"object","required":["from","to","rule"],"additionalProperties":false,"properties":{"from":{"type":"string"},"to":{"type":"string"},"type":{"$ref":"#/definitions/ViolationTypeType"},"rule":{"$ref":"#/definitions/RuleSummaryType"},"cycle":{"type":"array","items":{"type":"string"}},"via":{"type":"array","items":{"type":"string"}},"metrics":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"from":{"type":"object","required":["instability"],"additionalProperties":false,"properties":{"instability":{"type":"number"}}},"to":{"type":"object","required":["instability"],"additionalProperties":false,"properties":{"instability":{"type":"number"}}}}},"comment":{"type":"string"}}},"ViolationTypeType":{"type":"string","enum":["dependency","module","reachability","cycle","instability","folder"]},"RuleSetType":{"type":"object","additionalProperties":false,"properties":{"forbidden":{"type":"array","items":{"$ref":"#/definitions/ForbiddenRuleType"}},"allowed":{"type":"array","items":{"$ref":"#/definitions/AllowedRuleType"}},"allowedSeverity":{"$ref":"#/definitions/SeverityType"},"required":{"type":"array","items":{"$ref":"#/definitions/RequiredRuleType"}}}},"AllowedRuleType":{"oneOf":[{"$ref":"#/definitions/RegularAllowedRuleType"},{"$ref":"#/definitions/ReachabilityAllowedRuleType"}]},"RegularAllowedRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"comment":{"type":"string"},"scope":{"type":"string","enum":["module","folder"]},"from":{"$ref":"#/definitions/FromRestrictionType"},"to":{"$ref":"#/definitions/ToRestrictionType"}}},"ReachabilityAllowedRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"comment":{"type":"string"},"scope":{"type":"string","enum":["module","folder"]},"from":{"$ref":"#/definitions/ReachabilityFromRestrictionType"},"to":{"$ref":"#/definitions/ReachabilityToRestrictionType"}}},"ForbiddenRuleType":{"oneOf":[{"$ref":"#/definitions/RegularForbiddenRuleType"},{"$ref":"#/definitions/ReachabilityForbiddenRuleType"},{"$ref":"#/definitions/DependentsForbiddenRuleType"}]},"RegularForbiddenRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"from":{"$ref":"#/definitions/FromRestrictionType"},"to":{"$ref":"#/definitions/ToRestrictionType"}}},"DependentsForbiddenRuleType":{"type":"object","required":["module","from"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"module":{"$ref":"#/definitions/DependentsModuleRestrictionType"},"from":{"$ref":"#/definitions/DependentsFromRestrictionType"}}},"ReachabilityForbiddenRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"from":{"$ref":"#/definitions/ReachabilityFromRestrictionType"},"to":{"$ref":"#/definitions/ReachabilityToRestrictionType"}}},"RequiredRuleType":{"type":"object","required":["module","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"module":{"$ref":"#/definitions/RequiredModuleRestrictionType"},"to":{"$ref":"#/definitions/RequiredToRestrictionType"}}},"FromRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"orphan":{"type":"boolean"}}},"ReachabilityFromRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"ToRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"couldNotResolve":{"type":"boolean"},"circular":{"type":"boolean"},"dynamic":{"type":"boolean"},"exoticallyRequired":{"type":"boolean"},"exoticRequire":{"$ref":"#/definitions/REAsStringsType"},"exoticRequireNot":{"$ref":"#/definitions/REAsStringsType"},"preCompilationOnly":{"type":"boolean"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"dependencyTypesNot":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"moreThanOneDependencyType":{"type":"boolean"},"license":{"$ref":"#/definitions/REAsStringsType"},"licenseNot":{"$ref":"#/definitions/REAsStringsType"},"via":{"$ref":"#/definitions/REAsStringsType"},"viaOnly":{"$ref":"#/definitions/REAsStringsType"},"viaNot":{"$ref":"#/definitions/REAsStringsType"},"viaSomeNot":{"$ref":"#/definitions/REAsStringsType"},"moreUnstable":{"type":"boolean"}}},"DependentsModuleRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"numberOfDependentsLessThan":{"type":"integer","minimum":0,"maximum":100},"numberOfDependentsMoreThan":{"type":"integer","minimum":0,"maximum":100}}},"DependentsFromRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"ReachabilityToRestrictionType":{"required":["reachable"],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"reachable":{"type":"boolean"}}},"RequiredModuleRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"RequiredToRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"REAsStringsType":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"OptionsUsedType":{"type":"object","additionalProperties":false,"properties":{"doNotFollow":{"$ref":"#/definitions/CompoundDoNotFollowType"},"exclude":{"$ref":"#/definitions/CompoundExcludeType"},"includeOnly":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundIncludeOnlyType"}]},"focus":{"$ref":"#/definitions/CompoundFocusType"},"reaches":{"$ref":"#/definitions/CompoundReachesType"},"highlight":{"$ref":"#/definitions/CompoundHighlightType"},"knownViolations":{"$ref":"#/definitions/ViolationsType"},"collapse":{"type":"string"},"maxDepth":{"type":"integer","minimum":0,"maximum":99},"moduleSystems":{"$ref":"#/definitions/ModuleSystemsType"},"prefix":{"type":"string"},"preserveSymlinks":{"type":"boolean"},"combinedDependencies":{"type":"boolean"},"tsConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"}}},"tsPreCompilationDeps":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["specify"]}]},"extraExtensionsToScan":{"type":"array","items":{"type":"string"}},"externalModuleResolutionStrategy":{"type":"string","enum":["node_modules","yarn-pnp"]},"builtInModules":{"type":"object","additionalProperties":false,"properties":{"override":{"type":"array","items":{"type":"string"}},"add":{"type":"array","items":{"type":"string"}}}},"forceDeriveDependents":{"type":"boolean"},"webpackConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"},"env":{"oneOf":[{"type":"object"},{"type":"string"}]},"arguments":{"type":"object"}}},"enhancedResolveOptions":{"type":"object","additionalProperties":false,"properties":{"exportsFields":{"type":"array","items":{"type":"string"}},"conditionNames":{"type":"array","items":{"type":"string"}},"extensions":{"type":"array","items":{"type":"string"}},"mainFields":{"type":"array"},"mainFiles":{"type":"array"},"cachedInputFileSystem":{"type":"object","additionalProperties":false,"properties":{"cacheDuration":{"type":"integer","minimum":0,"maximum":1800000}}}}},"babelConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"}}},"parser":{"type":"string","enum":["acorn","swc","tsc"]},"exoticRequireStrings":{"type":"array","items":{"type":"string"}},"reporterOptions":{"$ref":"#/definitions/ReporterOptionsType"},"progress":{"type":"object","additionalProperties":false,"properties":{"type":{"type":"string","enum":["cli-feedback","performance-log","ndjson","none"]},"maximumLevel":{"type":"number","enum":[-1,40,50,60,70,80,99]}}},"metrics":{"type":"boolean"},"baseDir":{"type":"string"},"cache":{"oneOf":[{"type":"boolean","enum":[false]},{"$ref":"#/definitions/CacheOptionsType"}]},"args":{"type":"string"},"rulesFile":{"type":"string"},"outputTo":{"type":"string"},"outputType":{"$ref":"#/definitions/OutputType"}}},"ModuleSystemsType":{"type":"array","items":{"$ref":"#/definitions/ModuleSystemType"}},"OutputType":{"oneOf":[{"type":"string","enum":["json","html","dot","ddot","cdot","archi","fdot","flat","csv","err","err-long","err-html","teamcity","anon","text","metrics","markdown","mermaid","d2","null"]},{"type":"string","pattern":"^plugin:[^:]+$"}]},"CompoundExcludeType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"dynamic":{"type":"boolean"}}},"CompoundDoNotFollowType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}}}},"CompoundIncludeOnlyType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"CompoundFocusType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"depth":{"type":"number","minimum":1,"maximum":4}}},"CompoundReachesType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"CompoundHighlightType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"ReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"anon":{"$ref":"#/definitions/AnonReporterOptionsType"},"archi":{"$ref":"#/definitions/DotReporterOptionsType"},"dot":{"$ref":"#/definitions/DotReporterOptionsType"},"ddot":{"$ref":"#/definitions/DotReporterOptionsType"},"flat":{"$ref":"#/definitions/DotReporterOptionsType"},"markdown":{"$ref":"#/definitions/MarkdownReporterOptionsType"},"metrics":{"$ref":"#/definitions/MetricsReporterOptionsType"},"mermaid":{"$ref":"#/definitions/MermaidReporterOptionsType"},"text":{"$ref":"#/definitions/TextReporterOptionsType"}}},"AnonReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"wordlist":{"type":"array","items":{"type":"string"}}}},"MetricsReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"orderBy":{"type":"string","enum":["instability","moduleCount","afferentCouplings","efferentCouplings","name"]},"hideModules":{"type":"boolean"},"hideFolders":{"type":"boolean"}}},"MarkdownReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"showTitle":{"type":"boolean"},"title":{"type":"string"},"showSummary":{"type":"boolean"},"showSummaryHeader":{"type":"boolean"},"summaryHeader":{"type":"string"},"showStatsSummary":{"type":"boolean"},"showRulesSummary":{"type":"boolean"},"includeIgnoredInSummary":{"type":"boolean"},"showDetails":{"type":"boolean"},"includeIgnoredInDetails":{"type":"boolean"},"showDetailsHeader":{"type":"boolean"},"detailsHeader":{"type":"string"},"collapseDetails":{"type":"boolean"},"collapsedMessage":{"type":"string"},"noViolationsMessage":{"type":"string"},"showFooter":{"type":"boolean"}}},"MermaidReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"minify":{"type":"boolean"}}},"TextReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"highlightFocused":{"type":"boolean"}}},"DotReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"collapsePattern":{"$ref":"#/definitions/REAsStringsType"},"filters":{"$ref":"#/definitions/ReporterFiltersType"},"showMetrics":{"type":"boolean"},"theme":{"$ref":"#/definitions/DotThemeType"}}},"DotThemeType":{"type":"object","additionalProperties":false,"properties":{"replace":{"type":"boolean"},"graph":{"type":"object"},"node":{"type":"object"},"edge":{"type":"object"},"modules":{"$ref":"#/definitions/DotThemeArrayType"},"dependencies":{"$ref":"#/definitions/DotThemeArrayType"}}},"DotThemeArrayType":{"type":"array","items":{"$ref":"#/definitions/DotThemeEntryType"}},"DotThemeEntryType":{"type":"object","additionalProperties":false,"properties":{"criteria":{"type":"object"},"attributes":{"type":"object"}}},"ReporterFiltersType":{"type":"object","additionalProperties":false,"properties":{"exclude":{"$ref":"#/definitions/CompoundExcludeType"},"includeOnly":{"$ref":"#/definitions/CompoundIncludeOnlyType"},"focus":{"$ref":"#/definitions/CompoundFocusType"},"reaches":{"$ref":"#/definitions/CompoundReachesType"}}},"CacheOptionsType":{"type":"object","additionalProperties":false,"properties":{"folder":{"type":"string"},"strategy":{"$ref":"#/definitions/CacheStrategyType"},"compress":{"type":"boolean","default":false}}},"CacheStrategyType":{"type":"string","enum":["metadata","content"]},"RevisionDataType":{"type":"object","required":["SHA1","changes"],"properties":{"SHA1":{"type":"string"},"changes":{"type":"array","items":{"type":"object","required":["name","changeType"],"properties":{"name":{"type":"string"},"changeType":{"type":"string","enum":["added","copied","deleted","modified","renamed","type changed","unmerged","pairing broken","unknown","unmodified","untracked","ignored"]},"oldName":{"type":"string"},"checksum":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"rulesFile":{"type":"string"}}}}}}}}
\ No newline at end of file
+/* generated - don't edit */export default {"title":"dependency-cruiser output format","$schema":"http://json-schema.org/draft-07/schema#","$id":"https://dependency-cruiser.js.org/schema/cruise-result.schema.json","type":"object","required":["summary","modules"],"additionalProperties":false,"properties":{"modules":{"$ref":"#/definitions/ModulesType"},"folders":{"$ref":"#/definitions/FoldersType"},"summary":{"$ref":"#/definitions/SummaryType"},"revisionData":{"$ref":"#/definitions/RevisionDataType"}},"definitions":{"ModulesType":{"type":"array","items":{"$ref":"#/definitions/ModuleType"}},"ModuleType":{"type":"object","required":["source","dependencies","valid"],"additionalProperties":false,"properties":{"source":{"type":"string"},"valid":{"type":"boolean"},"dependencies":{"$ref":"#/definitions/DependenciesType"},"dependents":{"type":"array","items":{"type":"string"}},"followable":{"type":"boolean"},"matchesDoNotFollow":{"type":"boolean"},"matchesFocus":{"type":"boolean"},"matchesReaches":{"type":"boolean"},"matchesHighlight":{"type":"boolean"},"coreModule":{"type":"boolean"},"couldNotResolve":{"type":"boolean"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"license":{"type":"string"},"orphan":{"type":"boolean"},"reachable":{"type":"array","items":{"$ref":"#/definitions/ReachableType"}},"reaches":{"type":"array","items":{"$ref":"#/definitions/ReachesType"}},"rules":{"type":"array","items":{"$ref":"#/definitions/RuleSummaryType"}},"consolidated":{"type":"boolean"},"instability":{"type":"number"},"checksum":{"type":"string"}}},"ReachableType":{"type":"object","required":["value","asDefinedInRule","matchedFrom"],"additionalProperties":false,"properties":{"value":{"type":"boolean"},"asDefinedInRule":{"type":"string"},"matchedFrom":{"type":"string"}}},"ReachesType":{"type":"object","required":["modules","asDefinedInRule"],"additionalProperties":false,"properties":{"modules":{"type":"array","items":{"type":"object","required":["source","via"],"additionalProperties":false,"properties":{"source":{"type":"string"},"via":{"type":"array","items":{"type":"string"}}}}},"asDefinedInRule":{"type":"string"}}},"DependenciesType":{"type":"array","items":{"$ref":"#/definitions/DependencyType"}},"DependencyType":{"type":"object","required":["circular","coreModule","couldNotResolve","dependencyTypes","exoticallyRequired","dynamic","followable","module","moduleSystem","resolved","valid"],"additionalProperties":false,"properties":{"module":{"type":"string"},"protocol":{"type":"string","enum":["data:","file:","node:"]},"mimeType":{"type":"string"},"resolved":{"type":"string"},"coreModule":{"type":"boolean"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"license":{"type":"string"},"followable":{"type":"boolean"},"dynamic":{"type":"boolean"},"exoticallyRequired":{"type":"boolean"},"exoticRequire":{"type":"string"},"matchesDoNotFollow":{"type":"boolean"},"couldNotResolve":{"type":"boolean"},"preCompilationOnly":{"type":"boolean"},"typeOnly":{"type":"boolean"},"circular":{"type":"boolean"},"cycle":{"type":"array","items":{"type":"string"}},"moduleSystem":{"$ref":"#/definitions/ModuleSystemType"},"valid":{"type":"boolean"},"rules":{"type":"array","items":{"$ref":"#/definitions/RuleSummaryType"}},"instability":{"type":"number"}}},"DependencyTypeType":{"type":"string","enum":["aliased","aliased-subpath-import","aliased-tsconfig","aliased-webpack","aliased-workspace","core","deprecated","local","localmodule","npm","npm-bundled","npm-dev","npm-no-pkg","npm-optional","npm-peer","npm-unknown","undetermined","unknown","type-only"]},"ModuleSystemType":{"type":"string","enum":["cjs","es6","amd","tsd"]},"RuleSummaryType":{"type":"object","required":["name","severity"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"}}},"SeverityType":{"type":"string","enum":["error","warn","info","ignore"]},"FoldersType":{"type":"array","items":{"$ref":"#/definitions/FolderType"}},"FolderType":{"type":"object","required":["name","moduleCount"],"additionalProperties":false,"properties":{"name":{"type":"string"},"dependents":{"type":"array","items":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string"}}}},"dependencies":{"type":"array","items":{"type":"object","required":["name","valid","circular"],"additionalProperties":false,"properties":{"name":{"type":"string"},"instability":{"type":"number"},"valid":{"type":"boolean"},"circular":{"type":"boolean"},"cycle":{"type":"array","items":{"type":"string"}},"rules":{"type":"array","items":{"$ref":"#/definitions/RuleSummaryType"}}}}},"moduleCount":{"type":"number"},"afferentCouplings":{"type":"number"},"efferentCouplings":{"type":"number"},"instability":{"type":"number"}}},"SummaryType":{"type":"object","required":["violations","error","warn","info","totalCruised","optionsUsed"],"additionalProperties":false,"properties":{"violations":{"$ref":"#/definitions/ViolationsType"},"error":{"type":"number"},"warn":{"type":"number"},"info":{"type":"number"},"ignore":{"type":"number"},"totalCruised":{"type":"number"},"totalDependenciesCruised":{"type":"number"},"ruleSetUsed":{"$ref":"#/definitions/RuleSetType"},"optionsUsed":{"$ref":"#/definitions/OptionsUsedType"}}},"ViolationsType":{"type":"array","items":{"$ref":"#/definitions/ViolationType"}},"ViolationType":{"type":"object","required":["from","to","rule"],"additionalProperties":false,"properties":{"from":{"type":"string"},"to":{"type":"string"},"type":{"$ref":"#/definitions/ViolationTypeType"},"rule":{"$ref":"#/definitions/RuleSummaryType"},"cycle":{"type":"array","items":{"type":"string"}},"via":{"type":"array","items":{"type":"string"}},"metrics":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"from":{"type":"object","required":["instability"],"additionalProperties":false,"properties":{"instability":{"type":"number"}}},"to":{"type":"object","required":["instability"],"additionalProperties":false,"properties":{"instability":{"type":"number"}}}}},"comment":{"type":"string"}}},"ViolationTypeType":{"type":"string","enum":["dependency","module","reachability","cycle","instability","folder"]},"RuleSetType":{"type":"object","additionalProperties":false,"properties":{"forbidden":{"type":"array","items":{"$ref":"#/definitions/ForbiddenRuleType"}},"allowed":{"type":"array","items":{"$ref":"#/definitions/AllowedRuleType"}},"allowedSeverity":{"$ref":"#/definitions/SeverityType"},"required":{"type":"array","items":{"$ref":"#/definitions/RequiredRuleType"}}}},"AllowedRuleType":{"oneOf":[{"$ref":"#/definitions/RegularAllowedRuleType"},{"$ref":"#/definitions/ReachabilityAllowedRuleType"}]},"RegularAllowedRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"comment":{"type":"string"},"scope":{"type":"string","enum":["module","folder"]},"from":{"$ref":"#/definitions/FromRestrictionType"},"to":{"$ref":"#/definitions/ToRestrictionType"}}},"ReachabilityAllowedRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"comment":{"type":"string"},"scope":{"type":"string","enum":["module","folder"]},"from":{"$ref":"#/definitions/ReachabilityFromRestrictionType"},"to":{"$ref":"#/definitions/ReachabilityToRestrictionType"}}},"ForbiddenRuleType":{"oneOf":[{"$ref":"#/definitions/RegularForbiddenRuleType"},{"$ref":"#/definitions/ReachabilityForbiddenRuleType"},{"$ref":"#/definitions/DependentsForbiddenRuleType"}]},"RegularForbiddenRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"from":{"$ref":"#/definitions/FromRestrictionType"},"to":{"$ref":"#/definitions/ToRestrictionType"}}},"DependentsForbiddenRuleType":{"type":"object","required":["module","from"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"module":{"$ref":"#/definitions/DependentsModuleRestrictionType"},"from":{"$ref":"#/definitions/DependentsFromRestrictionType"}}},"ReachabilityForbiddenRuleType":{"type":"object","required":["from","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"from":{"$ref":"#/definitions/ReachabilityFromRestrictionType"},"to":{"$ref":"#/definitions/ReachabilityToRestrictionType"}}},"RequiredRuleType":{"type":"object","required":["module","to"],"additionalProperties":false,"properties":{"name":{"type":"string"},"severity":{"$ref":"#/definitions/SeverityType"},"scope":{"type":"string","enum":["module","folder"]},"comment":{"type":"string"},"module":{"$ref":"#/definitions/RequiredModuleRestrictionType"},"to":{"$ref":"#/definitions/RequiredToRestrictionType"}}},"FromRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"orphan":{"type":"boolean"}}},"ReachabilityFromRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"ToRestrictionType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"couldNotResolve":{"type":"boolean"},"circular":{"type":"boolean"},"dynamic":{"type":"boolean"},"exoticallyRequired":{"type":"boolean"},"exoticRequire":{"$ref":"#/definitions/REAsStringsType"},"exoticRequireNot":{"$ref":"#/definitions/REAsStringsType"},"preCompilationOnly":{"type":"boolean"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"dependencyTypesNot":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}},"moreThanOneDependencyType":{"type":"boolean"},"license":{"$ref":"#/definitions/REAsStringsType"},"licenseNot":{"$ref":"#/definitions/REAsStringsType"},"via":{"$ref":"#/definitions/REAsStringsType"},"viaOnly":{"$ref":"#/definitions/REAsStringsType"},"viaNot":{"$ref":"#/definitions/REAsStringsType"},"viaSomeNot":{"$ref":"#/definitions/REAsStringsType"},"moreUnstable":{"type":"boolean"}}},"DependentsModuleRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"numberOfDependentsLessThan":{"type":"integer","minimum":0,"maximum":100},"numberOfDependentsMoreThan":{"type":"integer","minimum":0,"maximum":100}}},"DependentsFromRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"ReachabilityToRestrictionType":{"required":["reachable"],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"},"reachable":{"type":"boolean"}}},"RequiredModuleRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"pathNot":{"$ref":"#/definitions/REAsStringsType"}}},"RequiredToRestrictionType":{"required":[],"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"REAsStringsType":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"OptionsUsedType":{"type":"object","additionalProperties":false,"properties":{"doNotFollow":{"$ref":"#/definitions/CompoundDoNotFollowType"},"exclude":{"$ref":"#/definitions/CompoundExcludeType"},"includeOnly":{"oneOf":[{"$ref":"#/definitions/REAsStringsType"},{"$ref":"#/definitions/CompoundIncludeOnlyType"}]},"focus":{"$ref":"#/definitions/CompoundFocusType"},"reaches":{"$ref":"#/definitions/CompoundReachesType"},"highlight":{"$ref":"#/definitions/CompoundHighlightType"},"knownViolations":{"$ref":"#/definitions/ViolationsType"},"collapse":{"type":"string"},"maxDepth":{"type":"integer","minimum":0,"maximum":99},"moduleSystems":{"$ref":"#/definitions/ModuleSystemsType"},"prefix":{"type":"string"},"preserveSymlinks":{"type":"boolean"},"combinedDependencies":{"type":"boolean"},"tsConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"}}},"tsPreCompilationDeps":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["specify"]}]},"extraExtensionsToScan":{"type":"array","items":{"type":"string"}},"externalModuleResolutionStrategy":{"type":"string","enum":["node_modules","yarn-pnp"]},"builtInModules":{"type":"object","additionalProperties":false,"properties":{"override":{"type":"array","items":{"type":"string"}},"add":{"type":"array","items":{"type":"string"}}}},"forceDeriveDependents":{"type":"boolean"},"webpackConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"},"env":{"oneOf":[{"type":"object"},{"type":"string"}]},"arguments":{"type":"object"}}},"enhancedResolveOptions":{"type":"object","additionalProperties":false,"properties":{"exportsFields":{"type":"array","items":{"type":"string"}},"conditionNames":{"type":"array","items":{"type":"string"}},"extensions":{"type":"array","items":{"type":"string"}},"mainFields":{"type":"array"},"mainFiles":{"type":"array"},"cachedInputFileSystem":{"type":"object","additionalProperties":false,"properties":{"cacheDuration":{"type":"integer","minimum":0,"maximum":1800000}}}}},"babelConfig":{"type":"object","additionalProperties":false,"properties":{"fileName":{"type":"string"}}},"parser":{"type":"string","enum":["acorn","swc","tsc"]},"exoticRequireStrings":{"type":"array","items":{"type":"string"}},"reporterOptions":{"$ref":"#/definitions/ReporterOptionsType"},"progress":{"type":"object","additionalProperties":false,"properties":{"type":{"type":"string","enum":["cli-feedback","performance-log","ndjson","none"]},"maximumLevel":{"type":"number","enum":[-1,40,50,60,70,80,99]}}},"metrics":{"type":"boolean"},"baseDir":{"type":"string"},"cache":{"oneOf":[{"type":"boolean","enum":[false]},{"$ref":"#/definitions/CacheOptionsType"}]},"args":{"type":"string"},"rulesFile":{"type":"string"},"outputTo":{"type":"string"},"outputType":{"$ref":"#/definitions/OutputType"}}},"ModuleSystemsType":{"type":"array","items":{"$ref":"#/definitions/ModuleSystemType"}},"OutputType":{"oneOf":[{"type":"string","enum":["json","html","dot","ddot","cdot","archi","fdot","flat","csv","err","err-long","err-html","teamcity","anon","text","metrics","markdown","mermaid","d2","null"]},{"type":"string","pattern":"^plugin:[^:]+$"}]},"CompoundExcludeType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"dynamic":{"type":"boolean"}}},"CompoundDoNotFollowType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"dependencyTypes":{"type":"array","items":{"$ref":"#/definitions/DependencyTypeType"}}}},"CompoundIncludeOnlyType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"CompoundFocusType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"},"depth":{"type":"number","minimum":1,"maximum":4}}},"CompoundReachesType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"CompoundHighlightType":{"type":"object","additionalProperties":false,"properties":{"path":{"$ref":"#/definitions/REAsStringsType"}}},"ReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"anon":{"$ref":"#/definitions/AnonReporterOptionsType"},"archi":{"$ref":"#/definitions/DotReporterOptionsType"},"dot":{"$ref":"#/definitions/DotReporterOptionsType"},"ddot":{"$ref":"#/definitions/DotReporterOptionsType"},"flat":{"$ref":"#/definitions/DotReporterOptionsType"},"markdown":{"$ref":"#/definitions/MarkdownReporterOptionsType"},"metrics":{"$ref":"#/definitions/MetricsReporterOptionsType"},"mermaid":{"$ref":"#/definitions/MermaidReporterOptionsType"},"text":{"$ref":"#/definitions/TextReporterOptionsType"}}},"AnonReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"wordlist":{"type":"array","items":{"type":"string"}}}},"MetricsReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"orderBy":{"type":"string","enum":["instability","moduleCount","afferentCouplings","efferentCouplings","name"]},"hideModules":{"type":"boolean"},"hideFolders":{"type":"boolean"}}},"MarkdownReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"showTitle":{"type":"boolean"},"title":{"type":"string"},"showSummary":{"type":"boolean"},"showSummaryHeader":{"type":"boolean"},"summaryHeader":{"type":"string"},"showStatsSummary":{"type":"boolean"},"showRulesSummary":{"type":"boolean"},"includeIgnoredInSummary":{"type":"boolean"},"showDetails":{"type":"boolean"},"includeIgnoredInDetails":{"type":"boolean"},"showDetailsHeader":{"type":"boolean"},"detailsHeader":{"type":"string"},"collapseDetails":{"type":"boolean"},"collapsedMessage":{"type":"string"},"noViolationsMessage":{"type":"string"},"showFooter":{"type":"boolean"}}},"MermaidReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"minify":{"type":"boolean"}}},"TextReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"highlightFocused":{"type":"boolean"}}},"DotReporterOptionsType":{"type":"object","additionalProperties":false,"properties":{"collapsePattern":{"$ref":"#/definitions/REAsStringsType"},"filters":{"$ref":"#/definitions/ReporterFiltersType"},"showMetrics":{"type":"boolean"},"theme":{"$ref":"#/definitions/DotThemeType"}}},"DotThemeType":{"type":"object","additionalProperties":false,"properties":{"replace":{"type":"boolean"},"graph":{"type":"object"},"node":{"type":"object"},"edge":{"type":"object"},"modules":{"$ref":"#/definitions/DotThemeArrayType"},"dependencies":{"$ref":"#/definitions/DotThemeArrayType"}}},"DotThemeArrayType":{"type":"array","items":{"$ref":"#/definitions/DotThemeEntryType"}},"DotThemeEntryType":{"type":"object","additionalProperties":false,"properties":{"criteria":{"type":"object"},"attributes":{"type":"object"}}},"ReporterFiltersType":{"type":"object","additionalProperties":false,"properties":{"exclude":{"$ref":"#/definitions/CompoundExcludeType"},"includeOnly":{"$ref":"#/definitions/CompoundIncludeOnlyType"},"focus":{"$ref":"#/definitions/CompoundFocusType"},"reaches":{"$ref":"#/definitions/CompoundReachesType"}}},"CacheOptionsType":{"type":"object","additionalProperties":false,"properties":{"folder":{"type":"string"},"strategy":{"$ref":"#/definitions/CacheStrategyType"},"compress":{"type":"boolean","default":false}}},"CacheStrategyType":{"type":"string","enum":["metadata","content"]},"RevisionDataType":{"type":"object","required":["SHA1","changes"],"properties":{"SHA1":{"type":"string"},"changes":{"type":"array","items":{"type":"object","required":["name","changeType"],"properties":{"name":{"type":"string"},"changeType":{"type":"string","enum":["added","copied","deleted","modified","renamed","type changed","unmerged","pairing broken","unknown","unmodified","untracked","ignored"]},"oldName":{"type":"string"},"checksum":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"rulesFile":{"type":"string"}}}}}}}}
\ No newline at end of file
diff --git a/src/validate/matchers.mjs b/src/validate/matchers.mjs
index 631a566f..53ea890f 100644
--- a/src/validate/matchers.mjs
+++ b/src/validate/matchers.mjs
@@ -6,8 +6,9 @@ import { intersects } from "#utl/array-util.mjs";
 const NOT_REALLY_DUPLICATES = new Set([
   "aliased",
   "aliased-subpath-import",
-  "aliased-webpack",
   "aliased-tsconfig",
+  "aliased-webpack",
+  "aliased-workspace",
   "type-only",
 ]);
 
diff --git "a/test/cli/__fixtures__/workspaces-mono-repo/libs/b\303\274cher/index.mjs" "b/test/cli/__fixtures__/workspaces-mono-repo/libs/b\303\274cher/index.mjs"
new file mode 100644
index 00000000..f71d56a0
--- /dev/null
+++ "b/test/cli/__fixtures__/workspaces-mono-repo/libs/b\303\274cher/index.mjs"
@@ -0,0 +1,1 @@
+export default "Hallo von Bücher in der Bibliothek";
diff --git "a/test/cli/__fixtures__/workspaces-mono-repo/libs/\345\233\276\344\271\246/index.mjs" "b/test/cli/__fixtures__/workspaces-mono-repo/libs/\345\233\276\344\271\246/index.mjs"
new file mode 100644
index 00000000..a425fb38
--- /dev/null
+++ "b/test/cli/__fixtures__/workspaces-mono-repo/libs/\345\233\276\344\271\246/index.mjs"
@@ -0,0 +1,1 @@
+export default "你好，来自图书馆的书籍";
diff --git "a/test/cli/__fixtures__/workspaces-mono-repo/packages/\344\272\213\347\211\251/index.js" "b/test/cli/__fixtures__/workspaces-mono-repo/packages/\344\272\213\347\211\251/index.js"
new file mode 100644
index 00000000..88222412
--- /dev/null
+++ "b/test/cli/__fixtures__/workspaces-mono-repo/packages/\344\272\213\347\211\251/index.js"
@@ -0,0 +1,1 @@
+module.exports = "东西包";
diff --git "a/test/cli/__fixtures__/workspaces-mono-repo/packages/\344\272\213\347\211\251/package.json" "b/test/cli/__fixtures__/workspaces-mono-repo/packages/\344\272\213\347\211\251/package.json"
new file mode 100644
index 00000000..c65b4515
--- /dev/null
+++ "b/test/cli/__fixtures__/workspaces-mono-repo/packages/\344\272\213\347\211\251/package.json"
@@ -0,0 +1,6 @@
+{
+  "version": "1.0.0",
+  "name": "3kq578f",
+  "description": "3kq578f is punycode for 事物",
+  "main": "index.js"
+}
diff --git a/tools/schema/dependency-type.mjs b/tools/schema/dependency-type.mjs
index d2d55326..fe4c22e0 100644
--- a/tools/schema/dependency-type.mjs
+++ b/tools/schema/dependency-type.mjs
@@ -5,8 +5,9 @@ export default {
       enum: [
         "aliased",
         "aliased-subpath-import",
-        "aliased-webpack",
         "aliased-tsconfig",
+        "aliased-webpack",
+        "aliased-workspace",
         "core",
         "deprecated",
         "local",
diff --git a/types/shared-types.d.ts b/types/shared-types.d.ts
index 58936b33..01785fb5 100644
--- a/types/shared-types.d.ts
+++ b/types/shared-types.d.ts
@@ -37,8 +37,9 @@ export type SeverityType = "error" | "warn" | "info" | "ignore";
 export type DependencyType =
   | "aliased"
   | "aliased-subpath-import"
-  | "aliased-webpack"
   | "aliased-tsconfig"
+  | "aliased-webpack"
+  | "aliased-workspace"
   | "core"
   | "deprecated"
   | "local"


Test patch:
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/apps/index.mjs b/test/cli/__fixtures__/workspaces-mono-repo/apps/index.mjs
new file mode 100644
index 00000000..e874d64a
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/apps/index.mjs
@@ -0,0 +1,12 @@
+import frenchThing from "chose";
+import englishThing from "thing";
+import germanThing from "ding";
+import chineseThing from "3kq578f";
+
+import englishBooks from "libs/books/index.mjs";
+import frenchBooks from "libs/livres/index.mjs";
+import germanBooks from "libs/bücher/index.mjs";
+import chineseBooks from "libs/图书/index.mjs";
+
+console.log(frenchThing, englishThing, germanThing, chineseThing);
+console.log(englishBooks, frenchBooks, germanBooks, chineseBooks);
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/expected.json b/test/cli/__fixtures__/workspaces-mono-repo/expected.json
new file mode 100644
index 00000000..e54e8d87
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/expected.json
@@ -0,0 +1,206 @@
+{
+  "modules": [
+    {
+      "source": "apps/index.mjs",
+      "dependencies": [
+        {
+          "module": "3kq578f",
+          "moduleSystem": "es6",
+          "dynamic": false,
+          "exoticallyRequired": false,
+          "resolved": "packages/事物/index.js",
+          "coreModule": false,
+          "followable": true,
+          "couldNotResolve": false,
+          "dependencyTypes": ["aliased", "aliased-workspace", "local"],
+          "matchesDoNotFollow": false,
+          "circular": false,
+          "valid": true
+        },
+        {
+          "module": "chose",
+          "moduleSystem": "es6",
+          "dynamic": false,
+          "exoticallyRequired": false,
+          "resolved": "packages/chose/index.js",
+          "coreModule": false,
+          "followable": true,
+          "couldNotResolve": false,
+          "dependencyTypes": ["aliased", "aliased-workspace", "local"],
+          "matchesDoNotFollow": false,
+          "circular": false,
+          "valid": true
+        },
+        {
+          "module": "ding",
+          "moduleSystem": "es6",
+          "dynamic": false,
+          "exoticallyRequired": false,
+          "resolved": "packages/ding/index.js",
+          "coreModule": false,
+          "followable": true,
+          "couldNotResolve": false,
+          "dependencyTypes": ["aliased", "aliased-workspace", "local"],
+          "matchesDoNotFollow": false,
+          "circular": false,
+          "valid": true
+        },
+        {
+          "module": "libs/books/index.mjs",
+          "moduleSystem": "es6",
+          "dynamic": false,
+          "exoticallyRequired": false,
+          "resolved": "libs/books/index.mjs",
+          "coreModule": false,
+          "followable": true,
+          "couldNotResolve": false,
+          "dependencyTypes": ["aliased", "aliased-workspace", "local"],
+          "matchesDoNotFollow": false,
+          "circular": false,
+          "valid": true
+        },
+        {
+          "module": "libs/bücher/index.mjs",
+          "moduleSystem": "es6",
+          "dynamic": false,
+          "exoticallyRequired": false,
+          "resolved": "libs/bücher/index.mjs",
+          "coreModule": false,
+          "followable": true,
+          "couldNotResolve": false,
+          "dependencyTypes": ["aliased", "aliased-workspace", "local"],
+          "matchesDoNotFollow": false,
+          "circular": false,
+          "valid": true
+        },
+        {
+          "module": "libs/livres/index.mjs",
+          "moduleSystem": "es6",
+          "dynamic": false,
+          "exoticallyRequired": false,
+          "resolved": "libs/livres/index.mjs",
+          "coreModule": false,
+          "followable": true,
+          "couldNotResolve": false,
+          "dependencyTypes": ["aliased", "aliased-workspace", "local"],
+          "matchesDoNotFollow": false,
+          "circular": false,
+          "valid": true
+        },
+        {
+          "module": "libs/图书/index.mjs",
+          "moduleSystem": "es6",
+          "dynamic": false,
+          "exoticallyRequired": false,
+          "resolved": "libs/图书/index.mjs",
+          "coreModule": false,
+          "followable": true,
+          "couldNotResolve": false,
+          "dependencyTypes": ["aliased", "aliased-workspace", "local"],
+          "matchesDoNotFollow": false,
+          "circular": false,
+          "valid": true
+        },
+        {
+          "module": "thing",
+          "moduleSystem": "es6",
+          "dynamic": false,
+          "exoticallyRequired": false,
+          "resolved": "packages/thing/index.js",
+          "coreModule": false,
+          "followable": true,
+          "couldNotResolve": false,
+          "dependencyTypes": ["aliased", "aliased-workspace", "local"],
+          "matchesDoNotFollow": false,
+          "circular": false,
+          "valid": true
+        }
+      ],
+      "dependents": [],
+      "orphan": false,
+      "valid": true
+    },
+    {
+      "source": "packages/事物/index.js",
+      "dependencies": [],
+      "dependents": ["apps/index.mjs"],
+      "orphan": false,
+      "valid": true
+    },
+    {
+      "source": "packages/chose/index.js",
+      "dependencies": [],
+      "dependents": ["apps/index.mjs"],
+      "orphan": false,
+      "valid": true
+    },
+    {
+      "source": "packages/ding/index.js",
+      "dependencies": [],
+      "dependents": ["apps/index.mjs"],
+      "orphan": false,
+      "valid": true
+    },
+    {
+      "source": "libs/books/index.mjs",
+      "dependencies": [],
+      "dependents": ["apps/index.mjs"],
+      "orphan": false,
+      "valid": true
+    },
+    {
+      "source": "libs/bücher/index.mjs",
+      "dependencies": [],
+      "dependents": ["apps/index.mjs"],
+      "orphan": false,
+      "valid": true
+    },
+    {
+      "source": "libs/livres/index.mjs",
+      "dependencies": [],
+      "dependents": ["apps/index.mjs"],
+      "orphan": false,
+      "valid": true
+    },
+    {
+      "source": "libs/图书/index.mjs",
+      "dependencies": [],
+      "dependents": ["apps/index.mjs"],
+      "orphan": false,
+      "valid": true
+    },
+    {
+      "source": "packages/thing/index.js",
+      "dependencies": [],
+      "dependents": ["apps/index.mjs"],
+      "orphan": false,
+      "valid": true
+    }
+  ],
+  "summary": {
+    "violations": [],
+    "error": 0,
+    "warn": 0,
+    "info": 0,
+    "ignore": 0,
+    "totalCruised": 9,
+    "totalDependenciesCruised": 8,
+    "optionsUsed": {
+      "baseDir": "test/cli/__fixtures__/workspaces-mono-repo",
+      "combinedDependencies": false,
+      "doNotFollow": {
+        "path": "node_modules"
+      },
+      "exoticRequireStrings": [],
+      "externalModuleResolutionStrategy": "node_modules",
+      "metrics": false,
+      "moduleSystems": ["es6", "cjs", "tsd", "amd"],
+      "outputTo": "test/cli/__output__/workspaces-mono-repo.json",
+      "outputType": "json",
+      "preserveSymlinks": false,
+      "tsPreCompilationDeps": false,
+      "args": "apps"
+    },
+    "ruleSetUsed": {}
+  }
+}
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/libs/books/index.mjs b/test/cli/__fixtures__/workspaces-mono-repo/libs/books/index.mjs
new file mode 100644
index 00000000..8a396317
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/libs/books/index.mjs
@@ -0,0 +1,1 @@
+export default "hello from books in the library";
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/libs/livres/index.mjs b/test/cli/__fixtures__/workspaces-mono-repo/libs/livres/index.mjs
new file mode 100644
index 00000000..8638d2b1
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/libs/livres/index.mjs
@@ -0,0 +1,1 @@
+export default "bonjour de livres dans la bibliothèque";
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/libs/package.json b/test/cli/__fixtures__/workspaces-mono-repo/libs/package.json
new file mode 100644
index 00000000..3b4eabca
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/libs/package.json
@@ -0,0 +1,4 @@
+{
+  "name": "libs",
+  "version": "1.0.0"
+}
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/node_modules/.package-lock.json b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/.package-lock.json
new file mode 100644
index 00000000..93a1ac5b
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/.package-lock.json
@@ -0,0 +1,42 @@
+{
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "libs": {
+      "version": "1.0.0"
+    },
+    "node_modules/3kq578f": {
+      "resolved": "packages/事物",
+      "link": true
+    },
+    "node_modules/chose": {
+      "resolved": "packages/chose",
+      "link": true
+    },
+    "node_modules/ding": {
+      "resolved": "packages/ding",
+      "link": true
+    },
+    "node_modules/libs": {
+      "resolved": "libs",
+      "link": true
+    },
+    "node_modules/thing": {
+      "resolved": "packages/thing",
+      "link": true
+    },
+    "packages/chose": {
+      "version": "1.0.0"
+    },
+    "packages/ding": {
+      "version": "1.0.0"
+    },
+    "packages/thing": {
+      "version": "1.0.0"
+    },
+    "packages/事物": {
+      "name": "3kq578f",
+      "version": "1.0.0"
+    }
+  }
+}
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/node_modules/3kq578f b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/3kq578f
new file mode 120000
index 00000000..7d13bfe9
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/3kq578f
@@ -0,0 +1,1 @@
+../packages/事物
\ No newline at end of file
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/node_modules/chose b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/chose
new file mode 120000
index 00000000..8ef52e40
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/chose
@@ -0,0 +1,1 @@
+../packages/chose
\ No newline at end of file
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/node_modules/ding b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/ding
new file mode 120000
index 00000000..8e90a3b4
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/ding
@@ -0,0 +1,1 @@
+../packages/ding
\ No newline at end of file
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/node_modules/libs b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/libs
new file mode 120000
index 00000000..d4bda9b4
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/libs
@@ -0,0 +1,1 @@
+../libs
\ No newline at end of file
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/node_modules/thing b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/thing
new file mode 120000
index 00000000..f0689fc8
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/node_modules/thing
@@ -0,0 +1,1 @@
+../packages/thing
\ No newline at end of file
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/package.json b/test/cli/__fixtures__/workspaces-mono-repo/package.json
new file mode 100644
index 00000000..71536901
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/package.json
@@ -0,0 +1,9 @@
+{
+  "name": "workspaces-mono-repo",
+  "version": "1.0.0",
+  "main": "index.js",
+  "workspaces": [
+    "libs",
+    "packages/*"
+  ]
+}
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/packages/chose/index.js b/test/cli/__fixtures__/workspaces-mono-repo/packages/chose/index.js
new file mode 100644
index 00000000..3a144752
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/packages/chose/index.js
@@ -0,0 +1,1 @@
+module.exports = "pacquet chose";
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/packages/chose/package.json b/test/cli/__fixtures__/workspaces-mono-repo/packages/chose/package.json
new file mode 100644
index 00000000..0768a98e
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/packages/chose/package.json
@@ -0,0 +1,5 @@
+{
+  "name": "chose",
+  "version": "1.0.0",
+  "main": "index.js"
+}
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/packages/ding/index.js b/test/cli/__fixtures__/workspaces-mono-repo/packages/ding/index.js
new file mode 100644
index 00000000..f6d519d3
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/packages/ding/index.js
@@ -0,0 +1,1 @@
+module.exports = "Ding Pakket";
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/packages/ding/package.json b/test/cli/__fixtures__/workspaces-mono-repo/packages/ding/package.json
new file mode 100644
index 00000000..fa5d92e5
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/packages/ding/package.json
@@ -0,0 +1,5 @@
+{
+  "name": "ding",
+  "version": "1.0.0",
+  "main": "index.js"
+}
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/packages/thing/index.js b/test/cli/__fixtures__/workspaces-mono-repo/packages/thing/index.js
new file mode 100644
index 00000000..f0a94e96
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/packages/thing/index.js
@@ -0,0 +1,1 @@
+module.exports = "thing package";
diff --git a/test/cli/__fixtures__/workspaces-mono-repo/packages/thing/package.json b/test/cli/__fixtures__/workspaces-mono-repo/packages/thing/package.json
new file mode 100644
index 00000000..debc196b
--- /dev/null
+++ b/test/cli/__fixtures__/workspaces-mono-repo/packages/thing/package.json
@@ -0,0 +1,5 @@
+{
+  "name": "thing",
+  "version": "1.0.0",
+  "main": "index.js"
+}
diff --git a/test/cli/index.spec.mjs b/test/cli/index.spec.mjs
index 3766c060..6263ddb3 100644
--- a/test/cli/index.spec.mjs
+++ b/test/cli/index.spec.mjs
@@ -125,6 +125,26 @@ const TEST_PAIRS = [
     expect: "alternate-basedir/expected.json",
     cleanup: true,
   },
+  {
+    description: "workspaces mono repo",
+    dirOrFile: "apps",
+    options: {
+      outputTo: path.join(OUT_DIR, "workspaces-mono-repo.json"),
+      outputType: "json",
+      doNotFollow: "node_modules",
+      ruleSet: {
+        options: {
+          preserveSymlinks: false,
+          baseDir: join(
+            process.cwd(),
+            "test/cli/__fixtures__/workspaces-mono-repo",
+          ),
+        },
+      },
+    },
+    expect: "workspaces-mono-repo/expected.json",
+    cleanup: true,
+  },
 ];
 
 function resetOutputDirectory() {
diff --git a/test/extract/resolve/module-classifiers.get-alias-types.spec.mjs b/test/extract/resolve/module-classifiers.get-alias-types.spec.mjs
new file mode 100644
index 00000000..2114ae11
--- /dev/null
+++ b/test/extract/resolve/module-classifiers.get-alias-types.spec.mjs
@@ -0,0 +1,240 @@
+import { deepEqual } from "node:assert/strict";
+import { getAliasTypes } from "#extract/resolve/module-classifiers.mjs";
+
+describe("[I] extract/resolve/module-classifiers - getAliasTypes", () => {
+  it("returns an empty array for non-aliased modules", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+    };
+    const lResolveOptions = {
+      baseDirectory: "over/the/rainbow",
+      alias: {
+        "@": "./src",
+      },
+    };
+    deepEqual(getAliasTypes("fs", "fs", lResolveOptions, lManifest), []);
+  });
+
+  it("returns aliased and aliased-subpath-import for subpath imports", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+      imports: {
+        "#*": "./src/*",
+      },
+    };
+    const lResolveOptions = {
+      baseDirectory: "over/the/rainbow",
+      alias: {
+        "@": "./src",
+      },
+    };
+    deepEqual(
+      getAliasTypes(
+        "#some/thing.js",
+        "src/some/thing.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      ["aliased", "aliased-subpath-import"],
+    );
+  });
+
+  it("doesn't run aliased and aliased-subpath-import when a thing starts with #, but it isn't in the imports", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+      imports: {
+        "#different/things": "./lib/*",
+      },
+    };
+    const lResolveOptions = {
+      baseDirectory: "over/the/rainbow",
+      alias: {
+        "@": "./src",
+      },
+    };
+    deepEqual(
+      getAliasTypes(
+        "#some/thing.js",
+        "src/some/thing.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      [],
+    );
+  });
+  it("doesn't run aliased and aliased-subpath-import when a thing starts with #, but there are no imports", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+    };
+    const lResolveOptions = {
+      baseDirectory: "over/the/rainbow",
+      alias: {
+        "@": "./src",
+      },
+    };
+    deepEqual(
+      getAliasTypes(
+        "#some/thing.js",
+        "src/some/thing.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      [],
+    );
+  });
+
+  it("returns aliased and aliased-webpack for webpack aliases", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+    };
+    const lResolveOptions = {
+      baseDirectory: "over/the/rainbow",
+      alias: {
+        "@": "./src",
+      },
+    };
+    deepEqual(
+      getAliasTypes(
+        "@some/thing.js",
+        "src/some/thing.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      ["aliased", "aliased-webpack"],
+    );
+  });
+
+  it("returns aliased and aliased-workspace for workspace alias (literals)", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+      workspaces: [
+        "packages/b-package",
+        "packages/a-package",
+        "packages/c-package",
+      ],
+    };
+    const lResolveOptions = {
+      baseDirectory: "over/the/rainbow",
+      alias: {
+        "@": "./src",
+      },
+    };
+    deepEqual(
+      getAliasTypes(
+        "some-workspaced-local-package",
+        "packages/a-package/index.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      ["aliased", "aliased-workspace"],
+    );
+  });
+
+  it("returns aliased and aliased-workspace for workspace alias (globs)", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+      workspaces: ["packages/*"],
+    };
+    const lResolveOptions = {};
+    deepEqual(
+      getAliasTypes(
+        "some-workspaced-local-package",
+        "packages/a-package/index.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      ["aliased", "aliased-workspace"],
+    );
+  });
+
+  it("returns aliased and aliased-workspace for workspace alias (glob ending with /)", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+      workspaces: ["*/"],
+    };
+    const lResolveOptions = {};
+    deepEqual(
+      getAliasTypes(
+        "some-workspaced-local-package",
+        "packages/a-package/index.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      ["aliased", "aliased-workspace"],
+    );
+  });
+
+  it("returns aliased and aliased-workspace for workspace alias (convoluted glob)", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+      workspaces: ["*/?-package"],
+    };
+    const lResolveOptions = {};
+    deepEqual(
+      getAliasTypes(
+        "some-workspaced-local-package",
+        "packages/a-package/index.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      ["aliased", "aliased-workspace"],
+    );
+  });
+
+  it("returns aliased and aliased-workspace for workspace alias (even when the symlink isn't followed)", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+      workspaces: ["*/?-package"],
+    };
+    const lResolveOptions = {};
+    deepEqual(
+      getAliasTypes(
+        "some-workspaced-local-package",
+        "node_modules/a-package/index.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      ["aliased", "aliased-workspace"],
+    );
+  });
+
+  it("should return aliased and aliased-tsconfig for tsconfig alias", () => {
+    const lManifest = {
+      name: "test",
+      version: "1.0.0",
+      dependencies: {},
+    };
+    const lResolveOptions = {
+      tsConfig: "tsconfig.json",
+    };
+    deepEqual(
+      getAliasTypes(
+        "@tsconfig/package",
+        "aap/noot/mies.js",
+        lResolveOptions,
+        lManifest,
+      ),
+      ["aliased", "aliased-tsconfig"],
+    );
+  });
+});