safe-formdata 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,6 +9,28 @@
|
|
|
9
9
|
safe-formdata is a **security-focused** parser that establishes a predictable boundary between untrusted input and application logic.
|
|
10
10
|
It enforces strict rules on keys and forbids structural inference by design.
|
|
11
11
|
|
|
12
|
+
## Table of Contents
|
|
13
|
+
|
|
14
|
+
- [safe-formdata](#safe-formdata)
|
|
15
|
+
- [Table of Contents](#table-of-contents)
|
|
16
|
+
- [Overview](#overview)
|
|
17
|
+
- [Design principles](#design-principles)
|
|
18
|
+
- [Security scope](#security-scope)
|
|
19
|
+
- [Design decisions (Why not?)](#design-decisions-why-not)
|
|
20
|
+
- [Why no structural inference?](#why-no-structural-inference)
|
|
21
|
+
- [Why no generic type parameters?](#why-no-generic-type-parameters)
|
|
22
|
+
- [Why no multiple values or repeated keys?](#why-no-multiple-values-or-repeated-keys)
|
|
23
|
+
- [Why no throwing or `parseOrThrow`?](#why-no-throwing-or-parseorthrow)
|
|
24
|
+
- [What is safe-formdata not?](#what-is-safe-formdata-not)
|
|
25
|
+
- [Installation](#installation)
|
|
26
|
+
- [Quick Start](#quick-start)
|
|
27
|
+
- [API](#api)
|
|
28
|
+
- [parse(formData): ParseResult](#parseformdata-parseresult)
|
|
29
|
+
- [Result](#result)
|
|
30
|
+
- [Issues](#issues)
|
|
31
|
+
- [Versioning](#versioning)
|
|
32
|
+
- [License](#license)
|
|
33
|
+
|
|
12
34
|
---
|
|
13
35
|
|
|
14
36
|
## Overview
|
|
@@ -59,46 +81,6 @@ Security decisions and issue triage are based on the definitions in SECURITY.md.
|
|
|
59
81
|
|
|
60
82
|
---
|
|
61
83
|
|
|
62
|
-
## API
|
|
63
|
-
|
|
64
|
-
### parse(formData): ParseResult
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
import { parse } from "safe-formdata";
|
|
68
|
-
|
|
69
|
-
const { data, issues } = parse(formData);
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
- `data` is `null` if any boundary violations are detected
|
|
73
|
-
- `issues` contains all detected structural issues
|
|
74
|
-
- Partial success is not allowed
|
|
75
|
-
|
|
76
|
-
### Result
|
|
77
|
-
|
|
78
|
-
```ts
|
|
79
|
-
export interface ParseResult {
|
|
80
|
-
data: Record<string, string | File> | null;
|
|
81
|
-
issues: ParseIssue[];
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
- `data` is non-null only when no boundary violations are detected
|
|
86
|
-
- `data` is always a flat object; no structural inference is performed
|
|
87
|
-
- `issues` must always be checked by the caller
|
|
88
|
-
|
|
89
|
-
### Issues
|
|
90
|
-
|
|
91
|
-
```ts
|
|
92
|
-
export interface ParseIssue {
|
|
93
|
-
code: "invalid_key" | "forbidden_key" | "duplicate_key";
|
|
94
|
-
path: string[];
|
|
95
|
-
key?: unknown;
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
- `path` is always empty and exists only for compatibility
|
|
100
|
-
- Issues are informational and are never thrown
|
|
101
|
-
|
|
102
84
|
## Design decisions (Why not?)
|
|
103
85
|
|
|
104
86
|
safe-formdata intentionally omits several common features.
|
|
@@ -168,6 +150,103 @@ inspect issues and decide what to do.
|
|
|
168
150
|
safe-formdata defines a safe boundary.
|
|
169
151
|
Validation and typing belong beyond it.
|
|
170
152
|
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Installation
|
|
156
|
+
|
|
157
|
+
Install safe-formdata using your preferred package manager:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# npm
|
|
161
|
+
npm install safe-formdata
|
|
162
|
+
|
|
163
|
+
# yarn
|
|
164
|
+
yarn add safe-formdata
|
|
165
|
+
|
|
166
|
+
# pnpm
|
|
167
|
+
pnpm add safe-formdata
|
|
168
|
+
|
|
169
|
+
# bun
|
|
170
|
+
bun add safe-formdata
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Requirements**: TypeScript 5.0+ (for discriminated union type narrowing)
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Quick Start
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { parse } from "safe-formdata";
|
|
181
|
+
|
|
182
|
+
const formData = new FormData();
|
|
183
|
+
formData.append("username", "alice");
|
|
184
|
+
formData.append("age", "25");
|
|
185
|
+
|
|
186
|
+
const result = parse(formData);
|
|
187
|
+
|
|
188
|
+
if (result.data !== null) {
|
|
189
|
+
// Success: data is available
|
|
190
|
+
console.log(result.data.username); // 'alice'
|
|
191
|
+
console.log(result.data.age); // '25'
|
|
192
|
+
} else {
|
|
193
|
+
// Failure: validation issues occurred
|
|
194
|
+
console.error(result.issues);
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Key points**:
|
|
199
|
+
|
|
200
|
+
- All values are `string | File` - no automatic type conversion
|
|
201
|
+
- Use `data !== null` to check for success and narrow the type
|
|
202
|
+
- Security boundaries are enforced from the start
|
|
203
|
+
|
|
204
|
+
For complete examples including file uploads and validation patterns, see the [examples/](./examples) directory.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## API
|
|
209
|
+
|
|
210
|
+
### parse(formData): ParseResult
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
import { parse } from "safe-formdata";
|
|
214
|
+
|
|
215
|
+
const { data, issues } = parse(formData);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
- `data` is `null` if any boundary violations are detected
|
|
219
|
+
- `issues` contains all detected structural issues
|
|
220
|
+
- Partial success is not allowed
|
|
221
|
+
|
|
222
|
+
### Result
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
export interface ParseResult {
|
|
226
|
+
data: Record<string, string | File> | null;
|
|
227
|
+
issues: ParseIssue[];
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
- `data` is non-null only when no boundary violations are detected
|
|
232
|
+
- `data` is always a flat object; no structural inference is performed
|
|
233
|
+
- `issues` must always be checked by the caller
|
|
234
|
+
|
|
235
|
+
### Issues
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
export interface ParseIssue {
|
|
239
|
+
code: "invalid_key" | "forbidden_key" | "duplicate_key";
|
|
240
|
+
path: string[];
|
|
241
|
+
key?: unknown;
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
- `path` is always empty and exists only for compatibility
|
|
246
|
+
- Issues are informational and are never thrown
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
171
250
|
## Versioning
|
|
172
251
|
|
|
173
252
|
v0.x focuses exclusively on establishing and clarifying the FormData boundary.
|