Skip to content

Commit 5ffa148

Browse files
committed
Prepare filepath validator kit for release
1 parent 4ade1a2 commit 5ffa148

9 files changed

Lines changed: 422 additions & 204 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
test:
16+
name: Test on Node ${{ matrix.node-version }}
17+
runs-on: ubuntu-latest
18+
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
node-version:
23+
- 20
24+
- 22
25+
26+
steps:
27+
- name: Check out repository
28+
uses: actions/checkout@v5
29+
30+
- name: Set up Node
31+
uses: actions/setup-node@v5
32+
with:
33+
node-version: ${{ matrix.node-version }}
34+
cache: npm
35+
36+
- name: Install dependencies
37+
run: npm ci
38+
39+
- name: Typecheck
40+
run: npm run typecheck
41+
42+
- name: Build
43+
run: npm run build
44+
45+
- name: Test
46+
run: npm test

‎CHANGELOG.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
## 0.1.0
44

5-
- Draft local clean-room implementation.
5+
- Initial clean-room implementation.
66
- Add portable, POSIX, and Windows path validation policies.
7-
- Return structured diagnostics instead of a bare boolean.
7+
- Return structured diagnostics, segment spans, and absolute path metadata instead of a bare boolean.

‎CONTRIBUTING.md‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Contributing
2+
3+
Thanks for taking the time to improve this package.
4+
5+
## Local setup
6+
7+
```bash
8+
npm install
9+
npm run typecheck
10+
npm test
11+
npm run build
12+
```
13+
14+
## Pull requests
15+
16+
Please keep changes focused and include tests for behavior changes. Small API improvements are welcome when they keep path validation predictable, typed, and easy to use in both Node and browser-oriented tooling.
17+
18+
Before opening a pull request, run:
19+
20+
```bash
21+
npm run typecheck
22+
npm test
23+
npm run build
24+
```
25+
26+
## Issues
27+
28+
When reporting a bug, include:
29+
30+
- the package version;
31+
- the path input that failed;
32+
- the options used;
33+
- the expected diagnostic or result;
34+
- the actual diagnostic code or result.
35+
36+
This package validates path strings only. Please keep feature requests focused on diagnostics and policy checks rather than filesystem access, sanitization, or path resolution.

‎DRAFT_REPORT.md‎

Lines changed: 0 additions & 79 deletions
This file was deleted.

‎README.md‎

Lines changed: 145 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,100 @@
11
# filepath-validator-kit
22

3-
Validate file paths with explicit platform policies and structured diagnostics.
3+
[![npm version](https://img.shields.io/npm/v/filepath-validator-kit.svg)](https://www.npmjs.com/package/filepath-validator-kit)
4+
[![License: MPL-2.0](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](LICENSE)
5+
[![CI](https://github.com/Recoveredd/filepath-validator-kit/actions/workflows/ci.yml/badge.svg)](https://github.com/Recoveredd/filepath-validator-kit/actions/workflows/ci.yml)
6+
7+
Validate file path strings with explicit portable, POSIX or Windows policies and structured diagnostics.
8+
9+
`filepath-validator-kit` is a small clean-room toolkit for forms, config editors, archive builders and CLIs that need to explain why a user-provided path is unsafe or unsupported. It validates strings only: no filesystem access, no path resolution, no symlink checks and no mutation of user input.
10+
11+
Links: [npm](https://www.npmjs.com/package/filepath-validator-kit) · [GitHub](https://github.com/Recoveredd/filepath-validator-kit)
12+
13+
## Package quality
14+
15+
- TypeScript types are generated from the source.
16+
- ESM-only package with no runtime dependencies.
17+
- Marked as side-effect free for bundlers.
18+
- Browser-friendly implementation with no Node-only APIs.
19+
- CI runs `npm ci`, `typecheck`, `build`, and `test`.
20+
- Tested on Node.js 20 and 22 with GitHub Actions.
21+
22+
## Install
23+
24+
```bash
25+
npm install filepath-validator-kit
26+
```
27+
28+
## Quick Start
429

530
```ts
6-
import { isValidPath, vetPath } from "filepath-validator-kit";
31+
import { assertValidPath, isValidPath, vetPath } from "filepath-validator-kit";
732

833
isValidPath("notes/2026-05-12.txt");
934
// true
1035

1136
const result = vetPath("reports/con.txt", { platform: "portable" });
1237

1338
if (!result.valid) {
14-
console.log(result.issues[0]?.code);
39+
result.issues[0]?.code;
1540
// "windows-reserved-name"
41+
42+
result.issues[0]?.segment;
43+
// "con.txt"
1644
}
45+
46+
assertValidPath("exports/report.csv");
47+
// "exports/report.csv"
1748
```
1849

19-
## Why
50+
## Why this package
2051

21-
Some path checks only return `true` or `false`. `filepath-validator-kit` is for validation flows that need to explain what failed, which segment failed, and whether the policy is POSIX, Windows, or portable across both.
52+
Some path validators only answer `true` or `false`. That is hard to use in product UI, imports, config files and command-line tools because the caller still has to explain what went wrong.
53+
54+
`filepath-validator-kit` returns stable issue codes, source offsets and the failing path segment:
55+
56+
```ts
57+
const result = vetPath("safe//con.txt", { platform: "portable" });
58+
59+
result.issues;
60+
// [
61+
// {
62+
// code: "empty-segment",
63+
// message: "Path contains an empty segment.",
64+
// segmentIndex: 1,
65+
// segment: "",
66+
// start: 5,
67+
// end: 5
68+
// },
69+
// {
70+
// code: "windows-reserved-name",
71+
// message: "Path segment is a Windows-reserved device name.",
72+
// segmentIndex: 2,
73+
// segment: "con.txt",
74+
// start: 6,
75+
// end: 13
76+
// }
77+
// ]
78+
```
2279

2380
## API
2481

2582
### `vetPath(input, options?)`
2683

27-
Returns a `PathVetResult`.
84+
Returns a `PathVetResult`:
85+
86+
```ts
87+
type PathVetResult = {
88+
valid: boolean;
89+
input: unknown;
90+
normalizedSeparators: string;
91+
absolute: boolean;
92+
segments: PathVetSegment[];
93+
issues: PathVetIssue[];
94+
};
95+
```
96+
97+
Example:
2898

2999
```ts
30100
const result = vetPath("assets/logo?.svg", {
@@ -34,24 +104,80 @@ const result = vetPath("assets/logo?.svg", {
34104
});
35105
```
36106

37-
Options:
38-
39-
- `platform`: `"portable"` by default, or `"posix"` / `"windows"`.
40-
- `allowAbsolute`: defaults to `true`.
41-
- `allowRelative`: defaults to `true`.
42-
- `allowTraversal`: allows `.` and `..` segments when `true`; defaults to `false`.
43-
- `allowEmptySegments`: allows repeated separators when `true`; defaults to `false`.
44-
- `maxLength`: optional full path length limit.
45-
- `maxSegmentLength`: optional per-segment length limit.
46-
47107
### `isValidPath(input, options?)`
48108

49109
Boolean shortcut for `vetPath(input, options).valid`.
50110

111+
```ts
112+
isValidPath("assets/logo.svg", { platform: "portable" });
113+
// true
114+
```
115+
51116
### `assertValidPath(input, options?)`
52117

53-
Returns the input string or throws `PathVetError`.
118+
Returns the input string when it is valid or throws `PathVetError`.
119+
120+
```ts
121+
try {
122+
assertValidPath("reports/con.txt", { platform: "portable" });
123+
} catch (error) {
124+
if (error instanceof PathVetError) {
125+
console.log(error.result.issues);
126+
}
127+
}
128+
```
129+
130+
## Options
131+
132+
| Option | Default | Description |
133+
| --- | --- | --- |
134+
| `platform` | `"portable"` | Validation policy: `"portable"`, `"posix"` or `"windows"`. |
135+
| `allowAbsolute` | `true` | Reject absolute paths when set to `false`. |
136+
| `allowRelative` | `true` | Reject relative paths when set to `false`. |
137+
| `allowTraversal` | `false` | Allow `.` and `..` segments. |
138+
| `allowEmptySegments` | `false` | Allow repeated separators such as `safe//file.txt`. |
139+
| `maxLength` | none | Optional full path length limit. |
140+
| `maxSegmentLength` | none | Optional per-segment length limit. |
141+
142+
## Policies
143+
144+
- `portable`: rejects Windows-reserved characters, Windows device names and Windows trailing dots/spaces.
145+
- `windows`: applies Windows segment restrictions.
146+
- `posix`: accepts characters such as `?` and `:` because they are not path separators under POSIX.
147+
148+
Root-only absolute paths such as `/` and `C:\\` are accepted when absolute paths are allowed.
149+
150+
## Diagnostics
151+
152+
Issue codes are stable and intended for UI messages, logs or localization:
153+
154+
- `empty-input`
155+
- `not-a-string`
156+
- `invalid-option`
157+
- `absolute-not-allowed`
158+
- `relative-not-allowed`
159+
- `traversal-not-allowed`
160+
- `empty-segment`
161+
- `segment-too-long`
162+
- `path-too-long`
163+
- `nul-byte`
164+
- `windows-reserved-character`
165+
- `windows-reserved-name`
166+
- `windows-trailing-dot-or-space`
167+
168+
## Limits
169+
170+
This package validates path strings only. It does not:
171+
172+
- check whether a file exists;
173+
- normalize or resolve paths;
174+
- inspect permissions;
175+
- resolve symlinks;
176+
- sanitize filenames;
177+
- guarantee that every filesystem, archive format or host application will accept the path.
178+
179+
Use it as an explainable first-pass validation layer before application-specific checks.
54180

55-
## Notes
181+
## License
56182

57-
This library validates path strings only. It does not touch the file system, resolve symlinks, check permissions, or guarantee that an operating system will accept a path in every context.
183+
MPL-2.0

‎SECURITY.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Security Policy
2+
3+
## Reporting a Vulnerability
4+
5+
If you find a security issue, please report it privately when GitHub security advisories are available for this repository. If private advisories are not available, open a minimal issue that describes the affected package and version without publishing exploit details.
6+
7+
Please include:
8+
9+
- the affected package and version;
10+
- the smallest input or scenario needed to understand the issue;
11+
- the validation options used;
12+
- the impact you believe it has;
13+
- whether the issue affects Node, browsers, or both.
14+
15+
This package does not touch the filesystem, but misleading validation can still matter in upload forms, archive builders, config editors, or CLI tools. Reports about denial-of-service behavior or incorrect acceptance of unsafe path strings are welcome.

0 commit comments

Comments
 (0)