Skip to content

Commit

Permalink
Create the toolkit for plugin authors (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
illright authored Oct 15, 2024
1 parent 281aaca commit 362a473
Show file tree
Hide file tree
Showing 78 changed files with 679 additions and 501 deletions.
1 change: 0 additions & 1 deletion packages/pretty-reporter/src/format-single-diagnostic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { relative } from 'node:path'
import figures from 'figures'
import terminalLink from 'terminal-link'
import chalk from 'chalk'

import type { Diagnostic } from '@steiger/types'

export function formatSingleDiagnostic(d: Diagnostic, cwd: string): string {
Expand Down
4 changes: 1 addition & 3 deletions packages/pretty-reporter/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import chalk from 'chalk'
import figures from 'figures'

import type { Diagnostic } from '@steiger/types'

import { formatSingleDiagnostic } from './format-single-diagnostic.js'
import { s } from './pluralization.js'

Expand Down Expand Up @@ -46,5 +46,3 @@ export function formatPretty(diagnostics: Array<Diagnostic>, cwd: string) {
export function reportPretty(diagnostics: Array<Diagnostic>, cwd: string) {
console.error(formatPretty(diagnostics, cwd))
}

export type { Diagnostic }
2 changes: 1 addition & 1 deletion packages/steiger-plugin-fsd/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
},
"devDependencies": {
"@steiger/eslint-config": "workspace:*",
"@steiger/toolkit": "workspace:*",
"@steiger/tsconfig": "workspace:*",
"@steiger/types": "workspace:*",
"@total-typescript/ts-reset": "^0.5.1",
"@types/lodash-es": "^4.17.12",
"@types/pluralize": "^0.0.33",
Expand Down
4 changes: 1 addition & 3 deletions packages/steiger-plugin-fsd/src/_lib/index-source-files.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { getIndex, getLayers, getSegments, getSlices, isSliced, type LayerName } from '@feature-sliced/filesystem'
import type { File, Folder } from '@steiger/types'

import { joinFromRoot, parseIntoFsdRoot } from './prepare-test.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot, type File, type Folder } from '@steiger/toolkit'

type SourceFile = {
file: File
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { join } from 'node:path'
import { expect, it } from 'vitest'

import ambiguousSliceNames from './index.js'
import { joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'

it('reports no errors on a project without slice names that match some segment name in Shared', () => {
const root = parseIntoFsdRoot(`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { basename, sep } from 'node:path'
import { getAllSlices, getLayers, getSegments, type LayerName } from '@feature-sliced/filesystem'
import type { PartialDiagnostic, Folder, Rule } from '@steiger/types'
import type { PartialDiagnostic, Folder, Rule } from '@steiger/toolkit'
import { NAMESPACE } from '../constants.js'

/** Forbid slice names that match some segment’s name in shared (e.g., theme, i18n) */
const ambiguousSliceNames = {
name: `${NAMESPACE}/ambiguous-slice-names`,
name: `${NAMESPACE}/ambiguous-slice-names` as const,
check(root) {
const diagnostics: Array<PartialDiagnostic> = []

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, it } from 'vitest'

import { joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'
import excessiveSlicing from './index.js'

it('reports no errors on projects with moderate slicing', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/steiger-plugin-fsd/src/excessive-slicing/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { join } from 'node:path'
import { getLayers, getSlices, isSliced } from '@feature-sliced/filesystem'
import type { PartialDiagnostic, Rule } from '@steiger/types'
import type { PartialDiagnostic, Rule } from '@steiger/toolkit'

import { groupSlices } from '../_lib/group-slices.js'
import { NAMESPACE } from '../constants.js'
Expand All @@ -14,7 +14,7 @@ const THRESHOLDS = {

/** Warn about excessive amounts of ungrouped entities/features/widgets/pages. */
const excessiveSlicing = {
name: `${NAMESPACE}/excessive-slicing`,
name: `${NAMESPACE}/excessive-slicing` as const,
check(root) {
const diagnostics: Array<PartialDiagnostic> = []

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, it, vi } from 'vitest'

import { joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'
import forbiddenImports from './index.js'

vi.mock('tsconfck', async (importOriginal) => {
Expand All @@ -23,7 +23,7 @@ vi.mock('tsconfck', async (importOriginal) => {

vi.mock('node:fs', async (importOriginal) => {
const originalFs = await importOriginal<typeof import('fs')>()
const { createFsMocks } = await import('../_lib/prepare-test.js')
const { createFsMocks } = await import('@steiger/toolkit')

return createFsMocks(
{
Expand Down
4 changes: 2 additions & 2 deletions packages/steiger-plugin-fsd/src/forbidden-imports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { layerSequence, resolveImport, isCrossImportPublicApi } from '@feature-s
import precinct from 'precinct'
const { paperwork } = precinct
import { parse as parseNearestTsConfig } from 'tsconfck'
import type { PartialDiagnostic, Rule } from '@steiger/types'
import type { PartialDiagnostic, Rule } from '@steiger/toolkit'

import { indexSourceFiles } from '../_lib/index-source-files.js'
import { NAMESPACE } from '../constants.js'

const forbiddenImports = {
name: `${NAMESPACE}/forbidden-imports`,
name: `${NAMESPACE}/forbidden-imports` as const,
async check(root) {
const diagnostics: Array<PartialDiagnostic> = []
const { tsconfig } = await parseNearestTsConfig(root.path)
Expand Down
37 changes: 0 additions & 37 deletions packages/steiger-plugin-fsd/src/forbidden-imports/precinct.d.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/steiger-plugin-fsd/src/import-locality/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, it, vi } from 'vitest'

import { joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'
import importLocality from './index.js'

vi.mock('tsconfck', async (importOriginal) => {
Expand All @@ -12,7 +12,7 @@ vi.mock('tsconfck', async (importOriginal) => {

vi.mock('node:fs', async (importOriginal) => {
const originalFs = await importOriginal<typeof import('fs')>()
const { createFsMocks } = await import('../_lib/prepare-test.js')
const { createFsMocks } = await import('@steiger/toolkit')

return createFsMocks(
{
Expand Down
2 changes: 1 addition & 1 deletion packages/steiger-plugin-fsd/src/import-locality/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { resolveImport } from '@feature-sliced/filesystem'
import precinct from 'precinct'
const { paperwork } = precinct
import { parse as parseNearestTsConfig } from 'tsconfck'
import type { PartialDiagnostic, Rule } from '@steiger/types'
import type { PartialDiagnostic, Rule } from '@steiger/toolkit'

import { indexSourceFiles } from '../_lib/index-source-files.js'
import { NAMESPACE } from '../constants.js'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, it } from 'vitest'

import { compareMessages, parseIntoFsdRoot, joinFromRoot } from '../_lib/prepare-test.js'
import { compareMessages, joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'
import inconsistentNaming from './index.js'

it('reports no errors on slice names that are pluralized consistently', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/steiger-plugin-fsd/src/inconsistent-naming/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { partition } from 'lodash-es'
import pluralize from 'pluralize'
const { isPlural, plural, singular } = pluralize
import { getLayers, getSlices } from '@feature-sliced/filesystem'
import type { PartialDiagnostic, Rule } from '@steiger/types'
import type { PartialDiagnostic, Rule } from '@steiger/toolkit'

import { groupSlices } from '../_lib/group-slices.js'
import { NAMESPACE } from '../constants.js'

/** Detect inconsistent naming of slices on layers (singular vs plural) */
const inconsistentNaming = {
name: `${NAMESPACE}/inconsistent-naming`,
name: `${NAMESPACE}/inconsistent-naming` as const,
check(root) {
const diagnostics: Array<PartialDiagnostic> = []

Expand Down
22 changes: 10 additions & 12 deletions packages/steiger-plugin-fsd/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Config, Rule, Plugin, ConfigObject } from '@steiger/types'
import { enableAllRules, type ConfigObjectOf, createPlugin, createConfigs } from '@steiger/toolkit'

import ambiguousSliceNames from './ambiguous-slice-names/index.js'
import excessiveSlicing from './excessive-slicing/index.js'
Expand All @@ -19,7 +19,7 @@ import typoInLayerName from './typo-in-layer-name/index.js'
import noProcesses from './no-processes/index.js'
import packageJson from '../package.json'

const allRules: Array<Rule> = [
const rules = [
ambiguousSliceNames,
excessiveSlicing,
forbiddenImports,
Expand All @@ -39,23 +39,21 @@ const allRules: Array<Rule> = [
noProcesses,
]

const allRulesEnabledConfig: ConfigObject = {
rules: allRules.reduce((acc, rule) => ({ ...acc, [rule.name]: 'error' }), {}),
}

const plugin: Plugin = {
const plugin = createPlugin({
meta: {
name: 'steiger-plugin-fsd',
version: packageJson.version,
},
ruleDefinitions: allRules,
}
ruleDefinitions: rules,
})

const configs: Record<string, Config> = {
recommended: [plugin, allRulesEnabledConfig],
}
const configs = createConfigs({
recommended: enableAllRules(plugin),
})

export default {
plugin,
configs,
}

export type FSDConfigObject = ConfigObjectOf<typeof plugin>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, it, vi } from 'vitest'
import { join } from 'node:path'

import { compareMessages, joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { compareMessages, joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'
import insignificantSlice from './index.js'

vi.mock('tsconfck', async (importOriginal) => {
Expand All @@ -13,7 +13,7 @@ vi.mock('tsconfck', async (importOriginal) => {

vi.mock('node:fs', async (importOriginal) => {
const originalFs = await importOriginal<typeof import('fs')>()
const { createFsMocks } = await import('../_lib/prepare-test.js')
const { createFsMocks } = await import('@steiger/toolkit')

return createFsMocks(
{
Expand Down
4 changes: 2 additions & 2 deletions packages/steiger-plugin-fsd/src/insignificant-slice/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import * as fs from 'node:fs'
import { sep, join } from 'node:path'
import { parse as parseNearestTsConfig } from 'tsconfck'
import { isSliced, resolveImport, unslicedLayers, type LayerName } from '@feature-sliced/filesystem'
import type { Folder, PartialDiagnostic, Rule } from '@steiger/types'
import type { Folder, PartialDiagnostic, Rule } from '@steiger/toolkit'
import precinct from 'precinct'
const { paperwork } = precinct

import { indexSourceFiles } from '../_lib/index-source-files.js'
import { NAMESPACE } from '../constants.js'

const insignificantSlice = {
name: `${NAMESPACE}/insignificant-slice`,
name: `${NAMESPACE}/insignificant-slice` as const,
async check(root) {
const diagnostics: Array<PartialDiagnostic> = []

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, it } from 'vitest'

import { compareMessages, joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { compareMessages, joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'
import noFileSegments from './index.js'

it('reports no errors on a project with only folder segments', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/steiger-plugin-fsd/src/no-file-segments/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { basename } from 'node:path'
import { getLayers, getSlices, isSliced } from '@feature-sliced/filesystem'
import type { PartialDiagnostic, Rule } from '@steiger/types'
import type { PartialDiagnostic, Rule } from '@steiger/toolkit'
import { NAMESPACE } from '../constants.js'

const noFileSegments = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, it } from 'vitest'

import noLayerPublicApi from './index.js'
import { joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'

it('reports no errors on a project without index files on layer level', () => {
const root = parseIntoFsdRoot(`
Expand Down
4 changes: 2 additions & 2 deletions packages/steiger-plugin-fsd/src/no-layer-public-api/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { getIndex, getLayers } from '@feature-sliced/filesystem'
import type { PartialDiagnostic, Rule } from '@steiger/types'
import type { PartialDiagnostic, Rule } from '@steiger/toolkit'
import { NAMESPACE } from '../constants.js'

/** Layers that are allowed to have an index file. */
const exceptionLayers = ['app']

/** Forbid index files on layer level. */
const noLayerPublicApi = {
name: `${NAMESPACE}/no-layer-public-api`,
name: `${NAMESPACE}/no-layer-public-api` as const,
check(root) {
const diagnostics: Array<PartialDiagnostic> = []

Expand Down
2 changes: 1 addition & 1 deletion packages/steiger-plugin-fsd/src/no-processes/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, it } from 'vitest'

import noProcesses from './index.js'
import { joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'

it('reports no errors on a project without the Processes layer', () => {
const root = parseIntoFsdRoot(`
Expand Down
4 changes: 2 additions & 2 deletions packages/steiger-plugin-fsd/src/no-processes/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { basename } from 'node:path'
import type { PartialDiagnostic, Rule } from '@steiger/types'
import type { PartialDiagnostic, Rule } from '@steiger/toolkit'
import { NAMESPACE } from '../constants.js'

const noProcesses = {
name: `${NAMESPACE}/no-processes`,
name: `${NAMESPACE}/no-processes` as const,
check(root) {
const diagnostics: Array<PartialDiagnostic> = []

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, it, vi } from 'vitest'

import { joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'
import noPublicApiSidestep from './index.js'

vi.mock('tsconfck', async (importOriginal) => {
Expand All @@ -12,7 +12,7 @@ vi.mock('tsconfck', async (importOriginal) => {

vi.mock('node:fs', async (importOriginal) => {
const originalFs = await importOriginal<typeof import('fs')>()
const { createFsMocks } = await import('../_lib/prepare-test.js')
const { createFsMocks } = await import('@steiger/toolkit')

return createFsMocks(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import {
resolveImport,
crossReferenceToken,
} from '@feature-sliced/filesystem'
import type { Folder, File, PartialDiagnostic, Rule } from '@steiger/types'
import type { Folder, File, PartialDiagnostic, Rule } from '@steiger/toolkit'

import { indexSourceFiles } from '../_lib/index-source-files.js'
import { NAMESPACE } from '../constants.js'

/** Restrict imports that go inside the slice, sidestepping the public API. */
const noPublicApiSidestep = {
name: `${NAMESPACE}/no-public-api-sidestep`,
name: `${NAMESPACE}/no-public-api-sidestep` as const,
async check(root) {
const diagnostics: Array<PartialDiagnostic> = []
const { tsconfig } = await parseNearestTsConfig(root.path)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, it } from 'vitest'

import noReservedFolderNames from './index.js'
import { joinFromRoot, parseIntoFsdRoot } from '../_lib/prepare-test.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'

it('reports no errors on a project without subfolders in segments that use reserved names', () => {
const root = parseIntoFsdRoot(`
Expand Down
Loading

0 comments on commit 362a473

Please sign in to comment.