Options
All
  • Public
  • Public/Protected
  • All
Menu

TSArch

It's a library for checking architecture conventions in TypeScript&JavaScript projects using any test framework. You check dependencies between files, folders and slices, check for cyclic dependencies and more. It's similar to ArchUnit but for TS/JS projects.

Build status

Build

Installation

npm install --save-dev tsarch

Usage

The project has currently two perspectives on architecture: file based architecture tests and slice based architecture tests.

File API

// imports and applies the jest extensions
import "tsarch/dist/jest"

// imports the files entrypoint
import {filesOfProject} from "tsarch"

describe("architecture", ()=> {

    // architecture tests can take a while to finish
    jest.setTimeout(60000);

    // we use async await in combination with jest since this project uses asynchronous calls
    it("business logic should not depend on the ui", async ()=> {
        const rule = filesOfProject()
            .inFolder("business")
            .shouldNot()
            .dependOnFiles()
            .inFolder("ui")

        await expect(rule).toPassAsync()
    })

    it("business logic should be cycle free", async ()=> {
        const rule = filesOfProject()
            .inFolder("business")
            .should()
            .beFreeOfCycles()

        await expect(rule).toPassAsync()
    })
})

An example without jest and further examples of the usage can be found in the integration tests in test/files/integration.

Slices API

Assume that you have an architecture diagram (Plant Uml) as part of your documentation in the docs folder of your project.

import "tsarch/dist/jest"
import {slicesOfProject} from "tsarch" 
import * as path from "path"

describe("architecture", ()=> {
    jest.setTimeout(60000);

    it('the architecture adheres to the config', async () => {
        const diagramLocation = path.resolve('docs', 'components.puml');

        const rule = await slicesOfProject()
            .definedBy('src/(**)/')
            .should()
            .adhereToDiagramInFile(diagramLocation)

        await expect(rule).toPassAsync()
    });
})

An example without jest and further examples of the usage can be found in the integration tests in test/slices/integration.

Path handling

The path of the project is always relative to a given tsconfig.json. If no tsconfig.json is given ts-arch tries to find one in a parent folder, e.g. if your tsconfig.json is in the same folder as your src folder, then all the paths begin with src/...

Dependency checks on nx monorepositories

ts-arch supports dependency checks on nx monorepositories. It reads the project graph and makes it accessible for the slices api.

The following example illustrates this:

import "tsarch/dist/jest"
import {slicesOfProject} from "tsarch" 
import * as path from "path"

describe("architecture", ()=> {
    jest.setTimeout(60000);

    it('the architecture adheres to the diagram', async () => {
        const diagramLocation = path.resolve('docs', 'components.puml');

        const rule = await slicesOfNxProject()
            .ignoringExternalDependencies()
            .should()
            .adhereToDiagramInFile(diagramLocation)
            .check()

        await expect(rule).toPassAsync()
    });
})

Index

Namespaces

Classes

Interfaces

Type aliases

Variables

Functions

Type aliases

Edge

Edge: { external: boolean; source: string; target: string }

Type declaration

  • external: boolean
  • source: string
  • target: string

Graph

Graph: Edge[]

GraphProvider

GraphProvider: () => Promise<Graph>

Type declaration

MapFunction

MapFunction: (edge: Edge) => MappedEdge | undefined

Type declaration

MappedEdge

MappedEdge: { sourceLabel: string; targetLabel: string }

Type declaration

  • sourceLabel: string
  • targetLabel: string

Nodes

Nodes: {}

Type declaration

Outgoing

Outgoing: { source: string; target: string }

Type declaration

  • source: string
  • target: string

ProjectedCycles

ProjectedCycles: Array<ProjectedEdge[]>

ProjectedEdge

ProjectedEdge: { cumulatedEdges: Edge[]; sourceLabel: string; targetLabel: string }

Type declaration

  • cumulatedEdges: Edge[]
  • sourceLabel: string
  • targetLabel: string

ProjectedGraph

ProjectedGraph: ProjectedEdge[]

ProjectedNode

ProjectedNode: { label: string }

Type declaration

  • label: string

Rule

Rule: { source: string; target: string }

Type declaration

  • source: string
  • target: string

Variables

Const graphCache

graphCache: Map<string | undefined, Promise<Edge[]>> = new Map()

Functions

absolutePath

  • absolutePath(root: string, pathName: string): string

calculateCycles

checkNegativeViolation

checkPositiveViolation

defaultCacheDirectory

  • defaultCacheDirectory(root: string): string

escapeForRegexp

  • escapeForRegexp(input: string): string

exportDiagram

extendJestMatchers

  • extendJestMatchers(): void

extractGraph

  • extractGraph(configFileName?: undefined | string): Promise<Edge[]>

extractGraphUncached

  • extractGraphUncached(configFileName?: undefined | string): Promise<Edge[]>

extractNxGraph

  • extractNxGraph(rootFolder?: undefined | string): Graph

filesOfProject

gatherCycleViolations

gatherDependOnFileViolations

gatherPositiveViolations

gatherRegexMatchingViolations

  • gatherRegexMatchingViolations(files: ProjectedNode[], checkPattern: string, preconditionPatterns: string[], isNegated: boolean): ViolatingNode[]

gatherViolations

generateRule

  • generateRule(data: string): { containedNodes: string[]; rules: Rule[] }

getProjectFiles

  • getProjectFiles(rootDir: string, compilerHost: CompilerHost, config: CompilerOptions & TypeAcquisition): string[]

guessLocationOfNxConfigRecursively

  • guessLocationOfNxConfigRecursively(pathName: string): string | undefined

guessLocationOfTsconfig

  • guessLocationOfTsconfig(): string | undefined

guessLocationOfTsconfigRecursively

  • guessLocationOfTsconfigRecursively(pathName: string): string | undefined

guessNxWorkspaceRoot

  • guessNxWorkspaceRoot(): string

identity

mapToGraph

matchingAllPatterns

  • matchingAllPatterns(input: string, patterns: Array<string | RegExp>): boolean

normalizeWindowsPaths

  • normalizeWindowsPaths(input: string): string

perEdge

perInternalEdge

projectCycles

projectEdges

projectInternalCycles

projectToNodes

safeArrayGet

  • safeArrayGet<T>(input: Array<T>, index: number): T | undefined

sliceByFileSuffix

  • sliceByFileSuffix(labeling: Map<string, string>): MapFunction

sliceByPattern

sliceByRegex

slicesOfNxProject

slicesOfProject

stripSlice

  • stripSlice(relativeFileName: string, stripRegexp: RegExp): string | undefined

Legend

  • Constructor
  • Property
  • Method
  • Property
  • Method
  • Private property
  • Private method
  • Static property
  • Static method
  • Inherited property

Generated using TypeDoc