Skip to content

Commit

Permalink
Redesign the API to be more useful
Browse files Browse the repository at this point in the history
  • Loading branch information
illright committed May 17, 2024
1 parent 9871342 commit 061a84a
Show file tree
Hide file tree
Showing 14 changed files with 548 additions and 423 deletions.
144 changes: 134 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,144 @@ npm install --save @feature-sliced/filesystem

Type definitions are built in 😎.

## Usage
## API

### `resolveImport`

```ts
import { locateInFsdRoot } from "@feature-sliced/filesystem";
function resolveImport(
importedPath: string,
importerPath: string,
tsCompilerOptions: typescript.CompilerOptions,
fileExists: (path: string) => boolean,
directoryExists?: (path: string) => boolean,
): string | null;
```

Given a file name, an imported path, and a TSConfig object, produce a path to the imported file, relative to TypeScript's `baseUrl`.

Example:

console.log(
locateInFsdRoot("/home/ubuntu/frontend/src/pages/home/ui/HomePage.tsx"),
```tsx
// /project/src/pages/home/ui/HomePage.tsx
import { Button } from "~/shared/ui";
```

```json
// ./tsconfig.json
{
"compilerOptions": {
"moduleResolution": "Bundler",
"baseUrl": ".",
"paths": {
"~/*": ["./src/*"]
}
}
}
```

```tsx
resolveImport(
"~/shared/ui",
"./src/pages/home/ui/HomePage.tsx",
{ moduleResolution: "Bundler", baseUrl: ".", paths: { "~/*": ["./src/*"] } },
fs.existsSync,
);
// {
// fsdRoot: "/home/ubuntu/frontend/src",
// layer: "pages",
// slice: "home",
// segment: "ui",
// }
```

Expected output: `/project/src/shared/ui/index.ts`.

## FSD-aware traversal

A set of traversal functions for a simple representation of a file system:

```ts
export interface File {
type: "file";
path: string;
}

export interface Folder {
type: "folder";
path: string;
children: Array<File | Folder>;
}
```

### `getLayers`

```ts
export type LayerName =
| "shared"
| "entities"
| "features"
| "widgets"
| "pages"
| "app";

function getLayers(fsdRoot: Folder): Partial<Record<LayerName, Folder>>;
```

Extract layers from an FSD root. Returns a mapping of layer name to folder object.

### `getSlices`

```ts
function getSlices(
slicedLayer: Folder,
additionalSegmentNames: Array<string> = [],
): Record<string, Folder>;
```

Extract slices from a **sliced** layer. Returns a mapping of slice name (potentially containing slashes) to folder object.

A folder is detected as a slice when it has at least one folder/file with a name of a conventional segment (`ui`, `api`, `model`, `lib`, `config`). If your project contains slices that don't have those segments, you can provide additional segment names.

### `getSegments`

```ts
function getSegments(
sliceOrUnslicedLayer: Folder,
): Record<string, Folder | File>;
```

Extract segments from a slice or an **unsliced** layer. Returns a mapping of segment name to folder or file object.

### `getAllSlices`

```ts
function getAllSlices(
fsdRoot: Folder,
additionalSegmentNames: Array<string> = [],
): Record<string, Folder>;
```

Extract slices from all layers of an FSD root. Returns a mapping of slice name (potentially containing slashes) to folder object.

A folder is detected as a slice when it has at least one folder/file with a name of a conventional segment (`ui`, `api`, `model`, `lib`, `config`). If your project contains slices that don't have those segments, you can provide additional segment names.

### `isSliced`

```ts
export type LayerName =
| "shared"
| "entities"
| "features"
| "widgets"
| "pages"
| "app";

function isSliced(layerOrName: Folder | LayerName): boolean;
```

Determine if this layer is sliced. You can pass the folder of a layer or the name (lowercase). Only layers Shared and App are not sliced, the rest are.

### `getIndex`

```ts
function getIndex(fileOrFolder: File | Folder): File | undefined;
```

Get the index (public API) of a slice or segment. When a segment is a file, it is its own index.

[feature-sliced-design]: https://feature-sliced.design
18 changes: 10 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@feature-sliced/filesystem",
"version": "1.1.0",
"version": "2.0.0",
"description": "A set of utilities for locating and working with FSD roots in the file system.",
"scripts": {
"build": "tsup src/index.ts --dts --format esm,cjs --clean",
Expand All @@ -13,7 +13,8 @@
},
"devDependencies": {
"@total-typescript/ts-reset": "^0.5.1",
"@tsconfig/recommended": "^1.0.6",
"@tsconfig/node-lts": "^20.1.3",
"@types/node": "^20.12.12",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"eslint": "^8.57.0",
Expand All @@ -22,18 +23,19 @@
"tsup": "^8.0.2",
"vitest": "^1.6.0"
},
"main": "dist/index.js",
"module": "dist/index.mjs",
"type": "module",
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
},
"import": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
}
},
Expand Down
39 changes: 27 additions & 12 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 061a84a

Please sign in to comment.