@chidchanun/bcp 0.1.24 → 0.1.25
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 +617 -138
- package/docs/README.md +333 -79
- package/docs/releases/0.1.25.md +132 -0
- package/docs/storage.md +285 -0
- package/package.json +1 -1
- package/packages/client/src/server.ts +24 -0
- package/packages/server/src/file-delivery.ts +629 -0
- package/packages/server/src/storage.ts +829 -0
package/docs/README.md
CHANGED
|
@@ -1,61 +1,134 @@
|
|
|
1
1
|
# BCP Framework Documentation Source
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The `docs/` directory is the documentation source of truth for BCP Framework and is intentionally organized so it can be consumed later by the **`bcp-docs-web`** documentation website.
|
|
4
4
|
|
|
5
|
-
> Documentation target
|
|
5
|
+
> **Documentation target:** BCP Framework `0.1.25`
|
|
6
|
+
>
|
|
7
|
+
> The documentation target can be newer than the version currently published to npm. Unreleased behavior must be labeled as a development target until release validation and publication are complete.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
## Documentation goals
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
The documentation source should make it possible to build `bcp-docs-web` without duplicating framework knowledge into a second repository.
|
|
12
|
+
|
|
13
|
+
The expected relationship is:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
BCP Framework source/tests
|
|
17
|
+
↓
|
|
18
|
+
docs/
|
|
19
|
+
↓
|
|
20
|
+
bcp-docs-web
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Framework source and tests remain authoritative for behavior. Markdown under `docs/` is the authored documentation layer. The future website should primarily render, organize and search this source instead of becoming a separate source of truth.
|
|
24
|
+
|
|
25
|
+
## Content update rule
|
|
26
|
+
|
|
27
|
+
When framework behavior changes:
|
|
28
|
+
|
|
29
|
+
1. Update framework source.
|
|
30
|
+
2. Add or update regression tests.
|
|
31
|
+
3. Update the matching documentation file under `docs/`.
|
|
32
|
+
4. Update the release note under `docs/releases/` when the change belongs to a release milestone.
|
|
33
|
+
5. Only present the feature as published after release validation and npm publication complete.
|
|
34
|
+
|
|
35
|
+
## Recommended `bcp-docs-web` navigation
|
|
36
|
+
|
|
37
|
+
The website should use these top-level groups:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
Getting Started
|
|
41
|
+
Routing & Data
|
|
42
|
+
Authentication
|
|
43
|
+
Database
|
|
44
|
+
Runtime & Infrastructure
|
|
45
|
+
API Reference
|
|
46
|
+
Releases
|
|
47
|
+
```
|
|
10
48
|
|
|
11
49
|
### Getting Started
|
|
12
50
|
|
|
13
|
-
|
|
|
51
|
+
| Website route | Markdown source | Purpose |
|
|
14
52
|
| --- | --- | --- |
|
|
15
53
|
| `/docs/getting-started` | `getting-started.md` | Create and run a BCP application |
|
|
16
|
-
| `/docs/configuration` | `configuration.md` | Framework configuration |
|
|
17
|
-
| `/docs/application-modules` | `application-modules.md` | Client/server boundaries |
|
|
18
|
-
| `/docs/deployment` | `deployment.md` |
|
|
19
|
-
| `/docs/updating` | `updating.md` | Framework
|
|
54
|
+
| `/docs/configuration` | `configuration.md` | Framework configuration and environment behavior |
|
|
55
|
+
| `/docs/application-modules` | `application-modules.md` | Client/server boundaries and module rules |
|
|
56
|
+
| `/docs/deployment` | `deployment.md` | Standalone production deployment |
|
|
57
|
+
| `/docs/updating` | `updating.md` | Framework upgrade workflow |
|
|
20
58
|
|
|
21
|
-
### Routing
|
|
59
|
+
### Routing & Data
|
|
22
60
|
|
|
23
|
-
|
|
|
61
|
+
| Website route | Markdown source | Purpose |
|
|
24
62
|
| --- | --- | --- |
|
|
25
|
-
| `/docs/routing` | `routing.md` | File-based routing |
|
|
63
|
+
| `/docs/routing` | `routing.md` | File-based page/API routing |
|
|
26
64
|
| `/docs/server-data-loaders` | `server-data-loaders.md` | Server-side page data |
|
|
27
65
|
| `/docs/route-guards` | `route-guards.md` | Scoped route authorization |
|
|
28
|
-
| `/docs/form-actions` | `form-actions.md` | Server mutations
|
|
66
|
+
| `/docs/form-actions` | `form-actions.md` | Server mutations and forms |
|
|
29
67
|
| `/docs/server-request-apis` | `server-request-apis.md` | Request/cookie/response APIs |
|
|
30
68
|
| `/docs/validation` | `validation.md` | Typed validation |
|
|
31
69
|
| `/docs/error-handling` | `error-handling.md` | Structured HTTP errors |
|
|
32
|
-
| `/docs/file-upload` | `file-upload.md` | Multipart parsing
|
|
70
|
+
| `/docs/file-upload` | `file-upload.md` | Multipart parsing and upload validation |
|
|
71
|
+
| `/docs/storage` | `storage.md` | Storage adapters and production file delivery |
|
|
33
72
|
|
|
34
73
|
### Authentication
|
|
35
74
|
|
|
36
|
-
|
|
|
75
|
+
| Website route | Markdown source | Purpose |
|
|
37
76
|
| --- | --- | --- |
|
|
38
77
|
| `/docs/authentication` | `authentication.md` | Authentication Core |
|
|
39
|
-
| `/docs/auth-route-guards` | `auth-route-guards.md` | Auth-aware guards |
|
|
78
|
+
| `/docs/auth-route-guards` | `auth-route-guards.md` | Auth-aware route guards |
|
|
40
79
|
| `/docs/session-auth` | `session-auth.md` | JWT cookie sessions |
|
|
41
80
|
|
|
42
81
|
### Database
|
|
43
82
|
|
|
44
|
-
|
|
|
83
|
+
| Website route | Markdown source | Purpose |
|
|
45
84
|
| --- | --- | --- |
|
|
46
85
|
| `/docs/database` | `database.md` | MySQL database primitives |
|
|
47
|
-
| `/docs/database-migrations` | `database-migrations.md` | Migration CLI and files |
|
|
86
|
+
| `/docs/database-migrations` | `database-migrations.md` | Migration CLI and migration files |
|
|
48
87
|
|
|
49
|
-
### Runtime
|
|
88
|
+
### Runtime & Infrastructure
|
|
50
89
|
|
|
51
|
-
|
|
|
90
|
+
| Website route | Markdown source | Purpose |
|
|
52
91
|
| --- | --- | --- |
|
|
53
92
|
| `/docs/middleware` | `middleware.md` | Middleware System v2 |
|
|
54
93
|
| `/docs/hydration` | `hydration.md` | SSR/client hydration parity |
|
|
55
|
-
| `/docs/developer-tools` | `developer-tools.md` | `doctor`
|
|
94
|
+
| `/docs/developer-tools` | `developer-tools.md` | `doctor` and `inspect` diagnostics |
|
|
56
95
|
| `/docs/development-logging` | `development-logging.md` | Structured logging and observability |
|
|
57
|
-
| `/docs/caching` | `caching.md` | Cache
|
|
58
|
-
| `/docs/security` | `security.md` | Security defaults and body limits |
|
|
96
|
+
| `/docs/caching` | `caching.md` | Cache and revalidation |
|
|
97
|
+
| `/docs/security` | `security.md` | Security defaults and request body limits |
|
|
98
|
+
|
|
99
|
+
## API Reference grouping
|
|
100
|
+
|
|
101
|
+
`bcp-docs-web` can derive an API-reference navigation layer from the authored guides.
|
|
102
|
+
|
|
103
|
+
Recommended entrypoint groups:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
bcp
|
|
107
|
+
bcp/server
|
|
108
|
+
bcp/auth
|
|
109
|
+
bcp/database
|
|
110
|
+
bcp/validation
|
|
111
|
+
bcp/error
|
|
112
|
+
bcp/cache
|
|
113
|
+
bcp/config
|
|
114
|
+
bcp/middleware
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The first version of the website does not need generated TypeDoc-style reference pages. It can begin by linking APIs to the guide that owns them, then add generated symbol-level reference later if useful.
|
|
118
|
+
|
|
119
|
+
Suggested ownership:
|
|
120
|
+
|
|
121
|
+
| Entrypoint | Primary guide |
|
|
122
|
+
| --- | --- |
|
|
123
|
+
| `bcp` | `routing.md`, `server-data-loaders.md`, `form-actions.md` |
|
|
124
|
+
| `bcp/server` | `server-request-apis.md`, `file-upload.md`, `storage.md`, `development-logging.md` |
|
|
125
|
+
| `bcp/auth` | `authentication.md`, `auth-route-guards.md` |
|
|
126
|
+
| `bcp/database` | `database.md`, `database-migrations.md` |
|
|
127
|
+
| `bcp/validation` | `validation.md` |
|
|
128
|
+
| `bcp/error` | `error-handling.md` |
|
|
129
|
+
| `bcp/cache` | `caching.md` |
|
|
130
|
+
| `bcp/config` | `configuration.md` |
|
|
131
|
+
| `bcp/middleware` | `middleware.md` |
|
|
59
132
|
|
|
60
133
|
## Current capability groups
|
|
61
134
|
|
|
@@ -63,29 +136,46 @@ When framework behavior changes, update framework source/tests first, then the m
|
|
|
63
136
|
|
|
64
137
|
- React SSR and hydration
|
|
65
138
|
- file-based page/API routing
|
|
66
|
-
- dynamic
|
|
139
|
+
- dynamic routes
|
|
140
|
+
- catch-all and optional catch-all routes
|
|
141
|
+
- route groups
|
|
67
142
|
- layouts and metadata
|
|
68
143
|
- SPA navigation
|
|
69
|
-
-
|
|
144
|
+
- server data loaders
|
|
145
|
+
- route guards
|
|
146
|
+
- form actions
|
|
70
147
|
- client islands / partial hydration
|
|
71
|
-
- Fast Refresh
|
|
148
|
+
- Fast Refresh
|
|
149
|
+
- deterministic development hydration
|
|
72
150
|
|
|
73
151
|
### Server
|
|
74
152
|
|
|
75
153
|
- request-scoped server APIs
|
|
154
|
+
- request IDs
|
|
76
155
|
- cookies and redirects
|
|
77
|
-
- JWT sessions
|
|
156
|
+
- JWT sessions
|
|
157
|
+
- authentication helpers
|
|
78
158
|
- Middleware System v2
|
|
79
|
-
- typed validation
|
|
80
|
-
- structured
|
|
81
|
-
-
|
|
159
|
+
- typed validation
|
|
160
|
+
- structured errors
|
|
161
|
+
- structured logging
|
|
162
|
+
- multipart file uploads
|
|
163
|
+
- upload validation
|
|
164
|
+
- storage adapter contract
|
|
165
|
+
- local filesystem storage adapter
|
|
166
|
+
- production file delivery
|
|
167
|
+
- validators and byte ranges
|
|
82
168
|
|
|
83
169
|
### Database
|
|
84
170
|
|
|
85
171
|
- `bcp/database`
|
|
86
|
-
- MySQL pool
|
|
172
|
+
- lazy MySQL pool
|
|
173
|
+
- prepared execution
|
|
174
|
+
- query helpers
|
|
87
175
|
- transactions
|
|
88
|
-
- migrations
|
|
176
|
+
- migrations
|
|
177
|
+
- migration status
|
|
178
|
+
- rollback
|
|
89
179
|
|
|
90
180
|
### Developer Experience
|
|
91
181
|
|
|
@@ -93,69 +183,110 @@ When framework behavior changes, update framework source/tests first, then the m
|
|
|
93
183
|
- `bcp update`
|
|
94
184
|
- `bcp doctor`
|
|
95
185
|
- `bcp inspect`
|
|
186
|
+
- route inspection
|
|
96
187
|
- `bcp-framework` Windows-safe CLI alias
|
|
97
188
|
- standalone production build
|
|
189
|
+
- unit/integration/E2E/package tests
|
|
98
190
|
- release/package smoke checks
|
|
99
191
|
|
|
100
|
-
## BCP 0.1.
|
|
192
|
+
## BCP 0.1.25 documentation focus
|
|
101
193
|
|
|
102
|
-
###
|
|
194
|
+
### Storage adapters
|
|
103
195
|
|
|
104
|
-
BCP 0.1.
|
|
196
|
+
BCP `0.1.25` introduces the first application-facing storage abstraction through `bcp/server`:
|
|
105
197
|
|
|
106
198
|
```ts
|
|
107
199
|
import {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
sanitizeUploadFileName,
|
|
114
|
-
UploadError,
|
|
200
|
+
createLocalStorage,
|
|
201
|
+
createStorageResponse,
|
|
202
|
+
normalizeStorageKey,
|
|
203
|
+
StorageError,
|
|
204
|
+
storeUploadedFile,
|
|
115
205
|
} from "bcp/server";
|
|
116
206
|
```
|
|
117
207
|
|
|
118
|
-
|
|
208
|
+
The documentation must make these boundaries clear:
|
|
119
209
|
|
|
120
|
-
- `
|
|
121
|
-
-
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
210
|
+
- `StorageAdapter` is the application-facing contract.
|
|
211
|
+
- `createLocalStorage()` is the built-in adapter in this milestone.
|
|
212
|
+
- storage keys are logical relative paths, not operating-system paths.
|
|
213
|
+
- absolute paths and traversal segments are rejected.
|
|
214
|
+
- overwrite is opt-in.
|
|
215
|
+
- local metadata persists content type and SHA-256 identity.
|
|
216
|
+
- `createStorageResponse()` supports `GET` and `HEAD`.
|
|
217
|
+
- validators include ETag and Last-Modified behavior.
|
|
218
|
+
- single byte ranges are supported.
|
|
219
|
+
- multiple ranges are intentionally unsupported in `0.1.25` and return `416`.
|
|
220
|
+
- the default cache policy is private/revalidate.
|
|
221
|
+
- public caching must be explicit.
|
|
222
|
+
- storage keys do not replace authentication or authorization.
|
|
127
223
|
|
|
128
|
-
See `
|
|
224
|
+
See `storage.md`.
|
|
129
225
|
|
|
130
|
-
###
|
|
226
|
+
### File Upload
|
|
131
227
|
|
|
132
|
-
0.1.24
|
|
228
|
+
BCP `0.1.24` introduced:
|
|
133
229
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
230
|
+
- multipart parsing,
|
|
231
|
+
- request/file size limits,
|
|
232
|
+
- MIME allowlists,
|
|
233
|
+
- extension allowlists,
|
|
234
|
+
- required/optional file fields,
|
|
235
|
+
- safe local file names,
|
|
236
|
+
- traversal protection,
|
|
237
|
+
- overwrite protection,
|
|
238
|
+
- SHA-256 metadata.
|
|
239
|
+
|
|
240
|
+
Those APIs remain supported in `0.1.25`.
|
|
241
|
+
|
|
242
|
+
`storeUploadedFile()` is the bridge between a validated multipart `File` and a `StorageAdapter`.
|
|
243
|
+
|
|
244
|
+
See:
|
|
245
|
+
|
|
246
|
+
- `file-upload.md`
|
|
247
|
+
- `storage.md`
|
|
137
248
|
|
|
138
|
-
|
|
249
|
+
### Production auth guard stabilization
|
|
139
250
|
|
|
140
|
-
|
|
251
|
+
The `0.1.24` stabilization cycle unified standalone guard/action authentication imports with the active request-context runtime.
|
|
141
252
|
|
|
142
|
-
|
|
253
|
+
This prevents production-only failures where APIs such as `cookies()`, `getSession()`, `requireAuth()` or `requireRole()` could see a different request-context instance after bundling.
|
|
143
254
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
255
|
+
### Development route graph synchronization
|
|
256
|
+
|
|
257
|
+
The `0.1.24` stabilization cycle also fixed a development graph drift where the route scanner could see a new route while the incremental client bundle graph still represented the previous topology.
|
|
258
|
+
|
|
259
|
+
The development gateway now compares the actual page route graph and refreshes the internal client bundler when pathname/page/layout topology changes.
|
|
260
|
+
|
|
261
|
+
### Logging and observability
|
|
262
|
+
|
|
263
|
+
BCP `0.1.23` introduced:
|
|
264
|
+
|
|
265
|
+
- `logger`,
|
|
266
|
+
- `createLogger()`,
|
|
267
|
+
- request-scoped `requestLogger()`,
|
|
268
|
+
- log levels,
|
|
269
|
+
- pretty/JSON formats,
|
|
270
|
+
- request IDs,
|
|
271
|
+
- structured development request logging,
|
|
272
|
+
- SSR/import debug timing.
|
|
149
273
|
|
|
150
274
|
See `development-logging.md`.
|
|
151
275
|
|
|
152
|
-
### Developer
|
|
276
|
+
### Developer tools
|
|
153
277
|
|
|
154
|
-
0.1.22 introduced
|
|
278
|
+
BCP `0.1.22` introduced:
|
|
279
|
+
|
|
280
|
+
- `bcp doctor`,
|
|
281
|
+
- `bcp inspect`,
|
|
282
|
+
- JSON diagnostic output,
|
|
283
|
+
- duplicate React detection,
|
|
284
|
+
- duplicate BCP installation protection,
|
|
285
|
+
- Windows-safe `bcp-framework` CLI alias.
|
|
155
286
|
|
|
156
287
|
See `developer-tools.md`.
|
|
157
288
|
|
|
158
|
-
##
|
|
289
|
+
## CLI commands
|
|
159
290
|
|
|
160
291
|
```bash
|
|
161
292
|
bcp dev
|
|
@@ -175,19 +306,29 @@ bcp db status
|
|
|
175
306
|
bcp db rollback
|
|
176
307
|
```
|
|
177
308
|
|
|
178
|
-
On Windows systems where SQL Server owns `bcp.exe`, direct
|
|
309
|
+
On Windows systems where Microsoft SQL Server owns `bcp.exe`, direct project-local commands should prefer:
|
|
179
310
|
|
|
180
311
|
```powershell
|
|
181
|
-
bcp-framework doctor
|
|
182
|
-
bcp-framework inspect
|
|
183
|
-
bcp-framework dev
|
|
312
|
+
npm exec -- bcp-framework doctor
|
|
313
|
+
npm exec -- bcp-framework inspect
|
|
314
|
+
npm exec -- bcp-framework dev
|
|
315
|
+
npm exec -- bcp-framework build
|
|
184
316
|
```
|
|
185
317
|
|
|
186
|
-
|
|
318
|
+
Inside npm scripts, `bcp` remains safe because npm prepends `node_modules/.bin` to `PATH`.
|
|
319
|
+
|
|
320
|
+
## Release documentation
|
|
187
321
|
|
|
188
|
-
|
|
322
|
+
Release notes live under:
|
|
189
323
|
|
|
190
324
|
```text
|
|
325
|
+
docs/releases/
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Recommended website release routes:
|
|
329
|
+
|
|
330
|
+
```text
|
|
331
|
+
/releases/0.1.25
|
|
191
332
|
/releases/0.1.24
|
|
192
333
|
/releases/0.1.23
|
|
193
334
|
/releases/0.1.22
|
|
@@ -195,20 +336,133 @@ Recommended release routes:
|
|
|
195
336
|
/releases/0.1.20
|
|
196
337
|
```
|
|
197
338
|
|
|
198
|
-
|
|
339
|
+
The website should display a clear release state for each version:
|
|
340
|
+
|
|
341
|
+
```text
|
|
342
|
+
published
|
|
343
|
+
release candidate
|
|
344
|
+
unreleased development target
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Do not infer publication state only from the existence of a Markdown release note.
|
|
348
|
+
|
|
349
|
+
## Suggested `bcp-docs-web` content model
|
|
350
|
+
|
|
351
|
+
A future website can represent each Markdown page with metadata similar to:
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
interface DocPage {
|
|
355
|
+
title: string;
|
|
356
|
+
slug: string;
|
|
357
|
+
section: string;
|
|
358
|
+
sourceFile: string;
|
|
359
|
+
versionTarget?: string;
|
|
360
|
+
releaseState?:
|
|
361
|
+
| "published"
|
|
362
|
+
| "rc"
|
|
363
|
+
| "unreleased";
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
The metadata does not need to live in frontmatter immediately. The first implementation can use a route manifest in the docs website and consume Markdown files directly.
|
|
368
|
+
|
|
369
|
+
## Suggested website features
|
|
370
|
+
|
|
371
|
+
The first useful version of `bcp-docs-web` should prioritize:
|
|
372
|
+
|
|
373
|
+
1. Sidebar navigation generated from the route/source map.
|
|
374
|
+
2. Markdown rendering with syntax highlighting.
|
|
375
|
+
3. Previous/next page navigation.
|
|
376
|
+
4. Version/development-target banner.
|
|
377
|
+
5. Release note pages.
|
|
378
|
+
6. Search across Markdown content.
|
|
379
|
+
7. Copy buttons for code blocks.
|
|
380
|
+
8. Mobile navigation.
|
|
381
|
+
9. Direct GitHub source/edit links.
|
|
382
|
+
|
|
383
|
+
Later additions can include:
|
|
384
|
+
|
|
385
|
+
- generated API symbol reference,
|
|
386
|
+
- versioned documentation snapshots,
|
|
387
|
+
- interactive examples,
|
|
388
|
+
- framework playgrounds,
|
|
389
|
+
- release comparison pages.
|
|
390
|
+
|
|
391
|
+
## Source conventions
|
|
392
|
+
|
|
393
|
+
For documentation intended for the website:
|
|
394
|
+
|
|
395
|
+
- use one H1 per source page,
|
|
396
|
+
- keep heading hierarchy stable,
|
|
397
|
+
- use fenced code blocks with language tags,
|
|
398
|
+
- use relative repository links for other docs,
|
|
399
|
+
- keep API names exactly aligned with public exports,
|
|
400
|
+
- distinguish current behavior from roadmap plans,
|
|
401
|
+
- include security limitations next to the API they affect,
|
|
402
|
+
- prefer runnable examples over pseudo APIs,
|
|
403
|
+
- avoid documenting private/internal modules as public APIs.
|
|
404
|
+
|
|
405
|
+
## Stable vs development documentation
|
|
406
|
+
|
|
407
|
+
`main` can contain documentation for the next release before npm publication.
|
|
408
|
+
|
|
409
|
+
Therefore the website must distinguish:
|
|
410
|
+
|
|
411
|
+
```text
|
|
412
|
+
Documentation target != necessarily current npm stable version
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
For example, while `0.1.25` is under release validation, `docs/storage.md` can describe the `0.1.25` development target, but the website should not label it as published until the release is actually available.
|
|
199
416
|
|
|
200
|
-
## Release
|
|
417
|
+
## Release validation
|
|
201
418
|
|
|
202
|
-
Before publishing a
|
|
419
|
+
Before publishing a framework release:
|
|
203
420
|
|
|
204
421
|
```bash
|
|
205
422
|
npm run typecheck
|
|
206
423
|
npm run test:unit
|
|
424
|
+
npm run test:e2e
|
|
425
|
+
npm run test:package
|
|
207
426
|
npm run rc:check
|
|
208
427
|
```
|
|
209
428
|
|
|
210
|
-
|
|
429
|
+
Release validation should include packed-package smoke verification and representative production application testing.
|
|
430
|
+
|
|
431
|
+
## Documentation QA checklist
|
|
432
|
+
|
|
433
|
+
Before a docs release or website sync:
|
|
211
434
|
|
|
212
|
-
|
|
435
|
+
- all linked Markdown files exist,
|
|
436
|
+
- examples use public exports,
|
|
437
|
+
- version numbers are current,
|
|
438
|
+
- unreleased features are labeled correctly,
|
|
439
|
+
- Windows CLI instructions use the safe alias where needed,
|
|
440
|
+
- security caveats are present for uploads/storage/authentication,
|
|
441
|
+
- route names match the current router,
|
|
442
|
+
- release notes match the framework version,
|
|
443
|
+
- no generated `.bcp-framework` paths are presented as user-authored source files.
|
|
444
|
+
|
|
445
|
+
## Roadmap
|
|
446
|
+
|
|
447
|
+
After `0.1.25`, the current planned framework direction is:
|
|
448
|
+
|
|
449
|
+
1. S3-compatible / cloud storage integration.
|
|
450
|
+
2. Production upload streaming.
|
|
451
|
+
3. Broader storage adapter ecosystem.
|
|
452
|
+
4. Additional production hardening.
|
|
453
|
+
|
|
454
|
+
These are roadmap items, not published API guarantees.
|
|
455
|
+
|
|
456
|
+
## Repository authority
|
|
457
|
+
|
|
458
|
+
The framework repository remains authoritative for:
|
|
459
|
+
|
|
460
|
+
```text
|
|
461
|
+
source
|
|
462
|
+
public exports
|
|
463
|
+
tests
|
|
464
|
+
docs
|
|
465
|
+
release notes
|
|
466
|
+
```
|
|
213
467
|
|
|
214
|
-
|
|
468
|
+
`bcp-docs-web` should be treated as the presentation/search/navigation layer for this content rather than a competing documentation source.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# BCP Framework 0.1.25
|
|
2
|
+
|
|
3
|
+
BCP 0.1.25 adds the first storage-adapter contract and hardened file-delivery responses on top of the multipart/file upload foundation introduced in 0.1.24.
|
|
4
|
+
|
|
5
|
+
## Highlights
|
|
6
|
+
|
|
7
|
+
- Added `StorageAdapter` for application-level storage abstraction.
|
|
8
|
+
- Added built-in `createLocalStorage()` filesystem adapter.
|
|
9
|
+
- Added traversal-safe relative storage keys.
|
|
10
|
+
- Added overwrite protection by default.
|
|
11
|
+
- Added persistent local metadata for content type and SHA-256 identity.
|
|
12
|
+
- Added `stat()`, ranged `read()`, `exists()` and `delete()` operations.
|
|
13
|
+
- Added `storeUploadedFile()` to write validated multipart `File` values into any storage adapter.
|
|
14
|
+
- Added `createStorageResponse()` for production GET/HEAD delivery.
|
|
15
|
+
- Added strong ETag validators for objects written through the local adapter.
|
|
16
|
+
- Added `If-None-Match`, `If-Modified-Since` and `If-Range` support.
|
|
17
|
+
- Added single byte-range delivery with `206 Partial Content`.
|
|
18
|
+
- Added `416 Range Not Satisfiable` handling.
|
|
19
|
+
- Added safe `Content-Disposition` generation for downloads.
|
|
20
|
+
- Added conservative private cache defaults.
|
|
21
|
+
- Added storage/file-delivery unit and public-export regression coverage.
|
|
22
|
+
|
|
23
|
+
## Storage abstraction
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import {
|
|
27
|
+
createLocalStorage,
|
|
28
|
+
} from "bcp/server";
|
|
29
|
+
|
|
30
|
+
const storage =
|
|
31
|
+
createLocalStorage({
|
|
32
|
+
directory:
|
|
33
|
+
"./uploads",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
await storage.put(
|
|
37
|
+
"documents/report.txt",
|
|
38
|
+
"Hello",
|
|
39
|
+
{
|
|
40
|
+
contentType:
|
|
41
|
+
"text/plain",
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The public adapter contract includes:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
put
|
|
50
|
+
stat
|
|
51
|
+
read
|
|
52
|
+
exists
|
|
53
|
+
delete
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Application code can depend on `StorageAdapter` instead of the local filesystem implementation.
|
|
57
|
+
|
|
58
|
+
## Upload integration
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const stored =
|
|
62
|
+
await storeUploadedFile(
|
|
63
|
+
file,
|
|
64
|
+
{
|
|
65
|
+
storage,
|
|
66
|
+
key:
|
|
67
|
+
"avatars/user-101.webp",
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The upload validation APIs from 0.1.24 remain compatible. `storeUploadedFile()` is additive and reuses the same `UploadConstraints` validation model.
|
|
73
|
+
|
|
74
|
+
## File delivery
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
return createStorageResponse(
|
|
78
|
+
request,
|
|
79
|
+
storage,
|
|
80
|
+
"documents/report.pdf",
|
|
81
|
+
{
|
|
82
|
+
disposition:
|
|
83
|
+
"attachment",
|
|
84
|
+
downloadName:
|
|
85
|
+
"report.pdf",
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The helper supports:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
200 full response
|
|
94
|
+
206 single byte range
|
|
95
|
+
304 validator hit
|
|
96
|
+
404 missing object
|
|
97
|
+
405 unsupported request method
|
|
98
|
+
416 invalid/unsupported range
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`HEAD` returns the same entity metadata headers without reading object bytes into the response body.
|
|
102
|
+
|
|
103
|
+
Multiple ranges are intentionally unsupported in 0.1.25 and return `416`.
|
|
104
|
+
|
|
105
|
+
## Cache policy
|
|
106
|
+
|
|
107
|
+
The default is:
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
private, max-age=0, must-revalidate
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Applications can explicitly opt public immutable files into stronger caching.
|
|
114
|
+
|
|
115
|
+
## Security model
|
|
116
|
+
|
|
117
|
+
- Storage keys reject absolute paths and traversal segments.
|
|
118
|
+
- BCP's local metadata directory cannot be addressed as an application storage key.
|
|
119
|
+
- Existing objects are not overwritten unless requested explicitly.
|
|
120
|
+
- Download filenames are stripped of path/control characters before being placed in response headers.
|
|
121
|
+
- Storage keys do not provide authorization; route/API guards must still enforce ownership and access permissions.
|
|
122
|
+
- Content type remains metadata, not content-signature verification.
|
|
123
|
+
|
|
124
|
+
## Compatibility
|
|
125
|
+
|
|
126
|
+
`saveUploadedFile()` from 0.1.24 remains supported. Applications can migrate incrementally to `StorageAdapter` / `storeUploadedFile()` when they need backend-independent storage behavior.
|
|
127
|
+
|
|
128
|
+
The route-graph synchronization and standalone auth-guard fixes completed during the 0.1.24 stabilization cycle remain part of the 0.1.25 baseline.
|
|
129
|
+
|
|
130
|
+
## Next milestone
|
|
131
|
+
|
|
132
|
+
The next planned milestone is BCP 0.1.26 — storage adapter ecosystem / S3-compatible integration and production upload streaming, unless roadmap priorities are regrouped.
|