Skip to content

Commit 061a84a

Browse files
committed
Redesign the API to be more useful
1 parent 9871342 commit 061a84a

14 files changed

+548
-423
lines changed

README.md

Lines changed: 134 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,144 @@ npm install --save @feature-sliced/filesystem
1919

2020
Type definitions are built in 😎.
2121

22-
## Usage
22+
## API
23+
24+
### `resolveImport`
2325

2426
```ts
25-
import { locateInFsdRoot } from "@feature-sliced/filesystem";
27+
function resolveImport(
28+
importedPath: string,
29+
importerPath: string,
30+
tsCompilerOptions: typescript.CompilerOptions,
31+
fileExists: (path: string) => boolean,
32+
directoryExists?: (path: string) => boolean,
33+
): string | null;
34+
```
35+
36+
Given a file name, an imported path, and a TSConfig object, produce a path to the imported file, relative to TypeScript's `baseUrl`.
37+
38+
Example:
2639

27-
console.log(
28-
locateInFsdRoot("/home/ubuntu/frontend/src/pages/home/ui/HomePage.tsx"),
40+
```tsx
41+
// /project/src/pages/home/ui/HomePage.tsx
42+
import { Button } from "~/shared/ui";
43+
```
44+
45+
```json
46+
// ./tsconfig.json
47+
{
48+
"compilerOptions": {
49+
"moduleResolution": "Bundler",
50+
"baseUrl": ".",
51+
"paths": {
52+
"~/*": ["./src/*"]
53+
}
54+
}
55+
}
56+
```
57+
58+
```tsx
59+
resolveImport(
60+
"~/shared/ui",
61+
"./src/pages/home/ui/HomePage.tsx",
62+
{ moduleResolution: "Bundler", baseUrl: ".", paths: { "~/*": ["./src/*"] } },
63+
fs.existsSync,
2964
);
30-
// {
31-
// fsdRoot: "/home/ubuntu/frontend/src",
32-
// layer: "pages",
33-
// slice: "home",
34-
// segment: "ui",
35-
// }
3665
```
3766

67+
Expected output: `/project/src/shared/ui/index.ts`.
68+
69+
## FSD-aware traversal
70+
71+
A set of traversal functions for a simple representation of a file system:
72+
73+
```ts
74+
export interface File {
75+
type: "file";
76+
path: string;
77+
}
78+
79+
export interface Folder {
80+
type: "folder";
81+
path: string;
82+
children: Array<File | Folder>;
83+
}
84+
```
85+
86+
### `getLayers`
87+
88+
```ts
89+
export type LayerName =
90+
| "shared"
91+
| "entities"
92+
| "features"
93+
| "widgets"
94+
| "pages"
95+
| "app";
96+
97+
function getLayers(fsdRoot: Folder): Partial<Record<LayerName, Folder>>;
98+
```
99+
100+
Extract layers from an FSD root. Returns a mapping of layer name to folder object.
101+
102+
### `getSlices`
103+
104+
```ts
105+
function getSlices(
106+
slicedLayer: Folder,
107+
additionalSegmentNames: Array<string> = [],
108+
): Record<string, Folder>;
109+
```
110+
111+
Extract slices from a **sliced** layer. Returns a mapping of slice name (potentially containing slashes) to folder object.
112+
113+
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.
114+
115+
### `getSegments`
116+
117+
```ts
118+
function getSegments(
119+
sliceOrUnslicedLayer: Folder,
120+
): Record<string, Folder | File>;
121+
```
122+
123+
Extract segments from a slice or an **unsliced** layer. Returns a mapping of segment name to folder or file object.
124+
125+
### `getAllSlices`
126+
127+
```ts
128+
function getAllSlices(
129+
fsdRoot: Folder,
130+
additionalSegmentNames: Array<string> = [],
131+
): Record<string, Folder>;
132+
```
133+
134+
Extract slices from all layers of an FSD root. Returns a mapping of slice name (potentially containing slashes) to folder object.
135+
136+
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.
137+
138+
### `isSliced`
139+
140+
```ts
141+
export type LayerName =
142+
| "shared"
143+
| "entities"
144+
| "features"
145+
| "widgets"
146+
| "pages"
147+
| "app";
148+
149+
function isSliced(layerOrName: Folder | LayerName): boolean;
150+
```
151+
152+
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.
153+
154+
### `getIndex`
155+
156+
```ts
157+
function getIndex(fileOrFolder: File | Folder): File | undefined;
158+
```
159+
160+
Get the index (public API) of a slice or segment. When a segment is a file, it is its own index.
161+
38162
[feature-sliced-design]: https://feature-sliced.design

package.json

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@feature-sliced/filesystem",
3-
"version": "1.1.0",
3+
"version": "2.0.0",
44
"description": "A set of utilities for locating and working with FSD roots in the file system.",
55
"scripts": {
66
"build": "tsup src/index.ts --dts --format esm,cjs --clean",
@@ -13,7 +13,8 @@
1313
},
1414
"devDependencies": {
1515
"@total-typescript/ts-reset": "^0.5.1",
16-
"@tsconfig/recommended": "^1.0.6",
16+
"@tsconfig/node-lts": "^20.1.3",
17+
"@types/node": "^20.12.12",
1718
"@typescript-eslint/eslint-plugin": "^7.8.0",
1819
"@typescript-eslint/parser": "^7.8.0",
1920
"eslint": "^8.57.0",
@@ -22,18 +23,19 @@
2223
"tsup": "^8.0.2",
2324
"vitest": "^1.6.0"
2425
},
25-
"main": "dist/index.js",
26-
"module": "dist/index.mjs",
26+
"type": "module",
27+
"main": "dist/index.cjs",
28+
"module": "dist/index.js",
2729
"types": "dist/index.d.ts",
2830
"exports": {
2931
".": {
3032
"require": {
31-
"types": "./dist/index.d.ts",
32-
"default": "./dist/index.js"
33+
"types": "./dist/index.d.cts",
34+
"default": "./dist/index.cjs"
3335
},
3436
"import": {
35-
"types": "./dist/index.d.mts",
36-
"default": "./dist/index.mjs"
37+
"types": "./dist/index.d.ts",
38+
"default": "./dist/index.js"
3739
}
3840
}
3941
},

pnpm-lock.yaml

Lines changed: 27 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)