Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ea40c15
refactor: separate `core` from `cli` and export the first
zaldih Sep 3, 2024
a04c067
build: remove gulp
zaldih Sep 3, 2024
d6251a4
refactor: use @core paths
zaldih Sep 3, 2024
4a98ee2
refactor: remove unused files
zaldih Sep 3, 2024
0baa4a0
test: re-organize files
zaldih Sep 3, 2024
91f6036
test: fix tests and add suite to index file
zaldih Sep 7, 2024
d53ba6f
test: create npkill core test
zaldih Sep 7, 2024
d79698c
refactor: improve npkill file
zaldih Sep 7, 2024
66d7119
fix: fix package.json path on getVersion
zaldih Sep 7, 2024
ccd6010
Merge branch 'main' into feat/api
zaldih Jul 21, 2025
c75b603
fix(cli): fix status.ui doesn't update
zaldih Jul 21, 2025
3ef0880
chore(logo): update project banner logo
zaldih Jul 22, 2025
ff0ccf3
refactor(cli): rename controller to CliController
zaldih Jul 22, 2025
c56821d
docs(api): add api section to readme
zaldih Jul 22, 2025
9d662fc
feat(api): define api
zaldih Jul 22, 2025
61dc14f
feat(api): remove isDangerous from FoundFolder interface
zaldih Jul 22, 2025
26824bd
refactor: rename FoundFolder to ScanFoundFolder
zaldih Jul 22, 2025
7593006
refactor: comment out maxConcurrentScans in ScanOptions for future im…
zaldih Jul 22, 2025
9dfa483
test: fix tests
zaldih Jul 22, 2025
e35b13a
feat(api): add observable alternatives to all methods
zaldih Jul 22, 2025
93c5594
chore(deps): move rxjs to peerDependencies
zaldih Jul 22, 2025
51f859e
feat: move logger to npkill
zaldih Jul 22, 2025
673233d
feat: add dry-run to api
zaldih Jul 22, 2025
026f565
feat(api): modify methods signature accepting options as second arg
zaldih Jul 26, 2025
b600a16
feat(api): modify methods signature accepting options as second arg
zaldih Jul 26, 2025
577bbf7
feat(api): remove promise wrappers
zaldih Jul 26, 2025
f3cb4a6
refactor(api): remove 'folder' from mehtods name
zaldih Jul 26, 2025
9f0e9c7
feat(api): remove getFileService method
zaldih Jul 26, 2025
3d2810e
Merge branch 'main' into feat/api
zaldih Jul 26, 2025
9c06ea2
feat(scan): add risk analysis
zaldih Jul 26, 2025
c793329
feat(core/cli): remove getFileService from npkill
zaldih Jul 26, 2025
58da1c8
feat(api): add getVersion
zaldih Jul 26, 2025
9f39cc4
fix: fix imports src path
zaldih Jul 26, 2025
106590b
feat: add stopScan method
zaldih Jul 27, 2025
a762fcf
docs(api): add javadoc for main interfaces
zaldih Jul 27, 2025
afd1c50
docs(api): create API.md with a real example
zaldih Jul 27, 2025
f1e7542
fix(worker): fix getFolderSize when no workers available
zaldih Jul 27, 2025
c8fa352
fix(api): change target: string to targets:string[]
zaldih Jul 27, 2025
b9fcb1a
test: fix test and add more
zaldih Jul 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
284 changes: 284 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
# NPKill API

Check notice on line 1 in API.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

API.md#L1

Expected: [None]; Actual: # NPKill API

This document does not include all project documentation at this stage. It brings together the basic concepts.

Check notice on line 3 in API.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

API.md#L3

Expected: 80; Actual: 110
For more details see the project interfaces.

- [NPKill API](#npkill-api)
- [Interface: `Npkill`](#interface-npkill)
- [`startScan$(rootPath, options?)`](#startscanrootpath-options)
- [`stopScan()`](#stopscan)
- [`getSize$(path, options?)`](#getsizepath-options)
- [`getNewestFile$(path)`](#getnewestfilepath)
- [`delete$(path, options?)`](#deletepath-options)
- [`getLogs$()`](#getlogs)
- [`isValidRootFolder(path)`](#isvalidrootfolderpath)
- [`getVersion()`](#getversion)
- [Interfaces & Types](#interfaces-types)
- [`ScanOptions`](#scanoptions)
- [`ScanFoundFolder`](#scanfoundfolder)
- [`RiskAnalysis`](#riskanalysis)
- [`GetSizeOptions`](#getsizeoptions)
- [`GetSizeResult`](#getsizeresult)
- [`GetNewestFileResult`](#getnewestfileresult)
- [`DeleteOptions`](#deleteoptions)
- [Usage Example](#usage-example)

---

## Interface: `Npkill`

The core of the system is the `NpkillInterface`. It offers methods to:

- Scan folders recursively.
- Get metadata about folders (size, last modified).
- Perform safe deletions.
- Stream logs and validate folders.

### `startScan$(rootPath, options?)`

Starts a recursive scan from a given root folder.

- **Parameters**:
- `rootPath`: `string` — Folder to start scanning from.
- `options`: [`ScanOptions`](#scanoptions) — Optional scan configuration.

- **Returns**: `Observable<ScanFoundFolder>`
- **Description**: Emits each matching folder as it's found.

---

### `stopScan()`

Stops any ongoing scan and releases resources.

---

### `getSize$(path, options?)`

Returns the total size of a directory.

- **Parameters**:
- `path`: `string` — Path to folder.
- `options`: [`GetSizeOptions`](#getsizeoptions)

- **Returns**: `Observable<GetSizeResult>`

---

### `getNewestFile$(path)`

Gets the most recently modified file inside a directory (recursively).

- **Parameters**:
- `path`: `string`

- **Returns**: `Observable<GetNewestFileResult | null>`

---

### `delete$(path, options?)`

Deletes a folder, optionally as a dry-run. Only allowed if the folder is within the `target` of the initial scan.

Check notice on line 81 in API.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

API.md#L81

Expected: 80; Actual: 113

- **Parameters**:
- `path`: `string`
- `options`: [`DeleteOptions`](#deleteoptions)

- **Returns**: `Observable<DeleteResult>`
- **Throws**: If the path is outside the original target.

---

### `getLogs$()`

Streams internal log entries.

- **Returns**: `Observable<LogEntry[]>`

---

### `isValidRootFolder(path)`

Validates whether a folder is suitable for scanning.

- **Parameters**:
- `path`: `string`

- **Returns**: [`IsValidRootFolderResult`](#isvalidrootfolderresult)

---

### `getVersion()`

Returns the current version of npkill from `package.json`.

- **Returns**: `string`

---

## Interfaces & Types

---

### `ScanOptions`

```ts
interface ScanOptions {
targets: string[];
exclude?: string[];
sortBy?: 'path' | 'size' | 'last-mod';
performRiskAnalysis?: boolean; // Default: true
}
```

---

### `ScanFoundFolder`

```ts
interface ScanFoundFolder {
path: string;
riskAnalysis?: RiskAnalysis;
}
```

---

### `RiskAnalysis`

Determines whether a result is safe to delete. That is, if it is likely to belong to some application and deleting it could break it.

Check notice on line 149 in API.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

API.md#L149

Expected: 80; Actual: 133

```ts
interface RiskAnalysis {
isSensitive: boolean;
reason?: string;
}
```

---

### `GetSizeOptions`

```ts
interface GetSizeOptions {
unit?: 'bytes'; // Default: 'bytes'
}
```

---

### `GetSizeResult`

```ts
interface GetSizeResult {
size: number;
unit: 'bytes';
}
```

---

### `GetNewestFileResult`

```ts
interface GetNewestFileResult {
path: string;
name: string;
timestamp: number;
}
```

---

### `DeleteOptions`

```ts
interface DeleteOptions {
dryRun?: boolean;
}
```

---

## Usage Example

This is a minimal example where:

1. it will start a search for `.nx` folders.
2. Get the most recent file
3. Get the total size of the directory

```ts
import { Npkill } from 'npkill';
import { mergeMap, filter, map } from 'rxjs';

const npkill = new Npkill();

let files: {
path: string;
size: number;
newestFile: string;
}[] = [];

npkill
.startScan$('/home/user/projects/', { target: '.nx' })
.pipe(
// Step 1: For each scan result, get the newest file
mergeMap((scanResult) =>
npkill.getNewestFile$(scanResult.path).pipe(
// Step 2: If no newest file, skip this result
filter((newestFile) => newestFile !== null),
// Step 3: Combine scanResult and newestFile
map((newestFile) => ({
path: scanResult.path,
newestFile: newestFile.path,
})),
),
),
// Step 4: For each result, get the folder size
mergeMap((result) =>
npkill.getSize$(result.path).pipe(
map(({ size }) => ({
...result,
size,
})),
),
),
)
.subscribe({
next: (result) => {
files.push(result);
},
complete: () => {
console.log('✅ Scan complete. Found folders:', files.length);
console.table(files);
console.log(JSON.stringify(files));
},
});
```

Output:

```bash
✅ Scan complete. Found folders: 3
┌─────────┬───────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────┬─────────┐
│ (index) │ path │ newestFile │ size │

Check notice on line 265 in API.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

API.md#L265

Expected: 80; Actual: 140
├─────────┼───────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────┼─────────┤
│ 0 │ '/home/user/projects/hello-world/.nx' │ '/home/user/projects/hello-world/.nx/cache/18.3.4-nx.linux-x64-gnu.node' │ 9388032 │

Check notice on line 267 in API.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

API.md#L267

Expected: 80; Actual: 140
│ 1 │ '/home/user/projects/another-project/.nx' │ '/home/user/projects/another-project/.nx/workspace-data/d/daemon.log' │ 3182592 │

Check notice on line 268 in API.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

API.md#L268

Expected: 80; Actual: 140
│ 2 │ '/home/user/projects/ARCHIVED/demo/.nx' │ '/home/user/projects/ARCHIVED/demo/.nx/cache/d/daemon.log' │ 2375680 │

Check notice on line 269 in API.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

API.md#L269

Expected: 80; Actual: 140
└─────────┴───────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────┴─────────┘
[
{
"path": "/home/user/projects/hello-world/.nx",
"newestFile": "/home/user/projects/hello-world/.nx/cache/18.3.4-nx.linux-x64-gnu.node",
"size": 9388032
},
{
"path": "/home/user/projects/another-project/.nx",
"newestFile": "/home/user/projects/another-project/.nx/workspace-data/d/daemon.log",
"size": 3182592
},
........
]
```
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<p align="center">
<img src="https://npkill.js.org/img/npkill-text-outlined.svg" width="320" alt="npkill logo" />
<img src="https://npkill.js.org/img/npkill-scope-mono.svg" width="50" alt="npkill logo scope" />
<img src="./docs/npkill-text-clean.svg" width="380" alt="npkill logo" />
</p>
<p align="center">
<img alt="npm" src="https://img.shields.io/npm/dy/npkill.svg">
Expand Down Expand Up @@ -34,6 +33,7 @@ We're making an effort to internationalize the Npkill docs. Here's a list of the
- [Options](#options)
- [Examples](#examples)
- [Set Up Locally](#setup-locally)
- [API](#API)
- [Roadmap](#roadmap)
- [Known bugs](#known-bugs)
- [Contributing](#contributing)
Expand Down Expand Up @@ -183,6 +183,14 @@ npm run start
npm run start -- -f -e
```

<a name="API"></a>

# :bookmark_tabs: API

The api allows you to interact with npkill from node to create your own implementations in your scripts (automations, for example).

You can check the basic API [here](./API.md) or on the web (comming soon).

<a name="roadmap"></a>

# :crystal_ball: Roadmap
Expand Down
2 changes: 1 addition & 1 deletion README.tr.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Seçili sonucun bulunduğu klasörü açmak için <kbd>o</kbd> tuşuna basabilir
| -f, --full | Aramaya kullanıcının ev dizininden başlayın (örneğin Linux'ta "/home/user"). |
| -gb | Klasörleri Megabytes yerine Gigabytes olarak göster. |
| -h, --help, ? | Bu yardım sayfasını göster ve çık. |
| -nu, --no-check-update | Başlangıçta güncellemeleri kontrol etme. |
| -nu, --no-check-update | Başlangıçta güncellemeleri kontrol etme. |
| -s, --sort | Sonuçları şu kriterlere göre sırala: `size`, `path` veya `last-mod` |
| -t, --target | Aramak istediğiniz dizinlerin adını belirtin (varsayılan olarak node_modules). |
| -x, --exclude-hidden-directories | Gizli dizinleri ("nokta" dizinleri) arama kapsamı dışında bırak. |
Expand Down
2 changes: 1 addition & 1 deletion docs/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ npm run release

The release script takes care of 2 things:

- Execute the compilation tasks specified in the gulp file (transpiling, copying the binary, etc.) and leaving the artifact ready in lib
- Execute the compilation tasks (`npm run build`).

- Start the interactive release process itself.

Expand Down
Loading
Loading