@chidchanun/bcp 0.1.28 → 0.2.0

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.
@@ -1,6 +1,8 @@
1
1
  # Developer Tools
2
2
 
3
- BCP Framework 0.1.22 adds project diagnostics and runtime inspection commands for debugging a BCP application without starting the development server.
3
+ BCP Framework exposes project diagnostics and runtime inspection commands for debugging an installed BCP application without starting the development server.
4
+
5
+ BCP `0.1.29` upgrades these tools with project/deployment diagnostics while keeping the previous report fields available.
4
6
 
5
7
  ## CLI executable names
6
8
 
@@ -11,35 +13,26 @@ bcp
11
13
  bcp-framework
12
14
  ```
13
15
 
14
- `bcp` remains the primary and backward-compatible executable name inside npm scripts.
15
-
16
- On Windows, Microsoft SQL Server also installs a native utility named `bcp.exe`. When that executable appears earlier on `PATH`, typing `bcp` directly in PowerShell can launch the SQL Server utility instead of BCP Framework.
16
+ `bcp` remains the primary executable inside npm scripts.
17
17
 
18
- PowerShell also does not add an application's `node_modules/.bin` directory to its normal interactive `PATH`. Therefore the recommended interactive Windows invocation is the project-local executable through npm:
18
+ On Windows, Microsoft SQL Server can also install a native `bcp.exe`, and normal PowerShell sessions do not automatically include the project's `node_modules/.bin` directory. Prefer:
19
19
 
20
20
  ```powershell
21
21
  npm exec -- bcp-framework doctor
22
22
  npm exec -- bcp-framework inspect
23
+ npm exec -- bcp-framework generate page dashboard/users
23
24
  npm exec -- bcp-framework dev
24
25
  npm exec -- bcp-framework build
25
26
  npm exec -- bcp-framework update
26
27
  ```
27
28
 
28
- Or call the generated Windows shim explicitly:
29
-
30
- ```powershell
31
- .\node_modules\.bin\bcp-framework.cmd doctor
32
- ```
33
-
34
- BCP application npm scripts can continue using `bcp dev`, `bcp build`, and other existing commands because npm places the project's `node_modules/.bin` directory on the script `PATH` before system executables.
29
+ Inside npm scripts, commands can continue to use `bcp ...` because npm prepends `node_modules/.bin` to `PATH`.
35
30
 
36
- ### Framework source checkout
31
+ ## Framework source checkout
37
32
 
38
- The framework source repository itself is a private development workspace and is not an installed copy of the published package. Merely opening PowerShell in `D:\bcp-framework` does not make `bcp-framework` available on `PATH`.
33
+ `bcp doctor` and `bcp inspect` are application diagnostics. They expect an application root with `app/` and an installed BCP dependency.
39
34
 
40
- `bcp doctor` and `bcp inspect` are application diagnostics: they expect an application root with `app/` plus an installed BCP dependency. Do not use them as the release-health command for the framework source checkout.
41
-
42
- For framework development and release validation, use:
35
+ For the framework source checkout itself, use the release validation commands instead:
43
36
 
44
37
  ```powershell
45
38
  npm run typecheck
@@ -47,101 +40,201 @@ npm run test:unit
47
40
  npm run rc:check
48
41
  ```
49
42
 
50
- After a packed or published package is installed into an application such as `bcp-docs`, run:
43
+ ## `bcp doctor`
44
+
45
+ Run from an installed application root:
51
46
 
52
47
  ```powershell
53
48
  npm exec -- bcp-framework doctor
54
- npm exec -- bcp-framework inspect
55
49
  ```
56
50
 
57
- ## `bcp doctor`
58
-
59
- Run a health check from an installed application root. On Windows PowerShell, prefer:
51
+ BCP reports each check as:
60
52
 
61
- ```powershell
62
- npm exec -- bcp-framework doctor
53
+ ```text
54
+ PASS valid/healthy
55
+ WARN non-blocking recommendation
56
+ FAIL blocking project/runtime problem
63
57
  ```
64
58
 
65
- The command checks:
59
+ If one or more checks fail, the command sets a non-zero process exit code.
66
60
 
67
- - the current Node.js runtime against BCP's minimum supported version,
68
- - `package.json` and the `app/` project structure,
69
- - the declared and installed BCP package,
70
- - installed `react` and `react-dom` versions,
71
- - React / React DOM resolution parity between the application and the framework,
61
+ ### Core checks
62
+
63
+ Doctor continues to check:
64
+
65
+ - supported Node.js version,
66
+ - readable `package.json`,
67
+ - `app/` project structure,
68
+ - declared/installed BCP dependency,
69
+ - installed React / React DOM,
70
+ - React renderer version parity,
71
+ - single React / React DOM resolution,
72
72
  - development environment files,
73
- - resolved `bcp.config.*` settings,
73
+ - resolved `bcp.config.*`,
74
74
  - page/API route discovery and conflicts,
75
75
  - client/server module boundaries.
76
76
 
77
- A successful check is printed as `PASS`, a non-blocking recommendation as `WARN`, and a blocking project/runtime problem as `FAIL`.
77
+ ### Doctor v2 checks 0.1.29
78
78
 
79
- If one or more checks fail, `bcp doctor` sets a non-zero process exit code. This makes it suitable for local scripts and CI gates.
79
+ Doctor now also checks:
80
80
 
81
- Example:
81
+ - dependency lockfile presence,
82
+ - detected package manager,
83
+ - multiple framework dependency declarations,
84
+ - production-hardening environment validity,
85
+ - standalone production artifact presence,
86
+ - Docker + npm lockfile reproducibility guidance,
87
+ - configured storage provider when detected.
82
88
 
83
- ```text
84
- BCP Doctor v0.1.22
85
- Project: D:\apps\my-bcp-app
86
- Runtime: Node.js 24.15.0 | win32 x64
89
+ Example diagnostic IDs include:
87
90
 
88
- [PASS] Node.js runtime: Node.js 24.15.0 satisfies >=24.11.0.
89
- [PASS] Project package: package.json is readable.
90
- [PASS] App directory: app/ is present.
91
- [PASS] React renderer version parity: react and react-dom both resolve to 19.2.8.
92
- [PASS] Single React instance: BCP and the application resolve the same React package.
93
-
94
- Summary: 11 passed, 0 warning(s), 0 failed.
91
+ ```text
92
+ project.lockfile
93
+ dependencies.framework-declarations
94
+ runtime.production-hardening
95
+ production.build
96
+ production.docker-lockfile
97
+ storage.provider
95
98
  ```
96
99
 
97
- ### Duplicate React detection
100
+ ### Duplicate framework declarations
98
101
 
99
- `bcp doctor` specifically checks the package locations used by the application and by BCP itself.
102
+ A BCP application should keep one framework dependency under the application key `bcp`:
100
103
 
101
- This catches local-development layouts where an application resolves React from one `node_modules` tree while the BCP SSR renderer resolves React DOM from another. That situation commonly produces:
104
+ ```json
105
+ {
106
+ "dependencies": {
107
+ "bcp": "npm:@chidchanun/bcp@0.1.29"
108
+ }
109
+ }
110
+ ```
111
+
112
+ Do not keep both:
102
113
 
103
114
  ```text
104
- Invalid hook call. Hooks can only be called inside of the body of a function component.
115
+ bcp
116
+ @chidchanun/bcp
105
117
  ```
106
118
 
107
- For local release testing, install the packed `.tgz` artifact instead of linking `.package/bcp` directly into another project. A packed package lets the BCP peer dependencies resolve from the application's normal `node_modules` tree.
119
+ as separate application dependencies. Multiple framework copies can split shared React/framework contexts and produce misleading loader/auth errors.
108
120
 
109
- ### Duplicate BCP package protection
121
+ ### Lockfile / Docker diagnostics
110
122
 
111
- A BCP application must not load `node_modules/bcp` and `node_modules/@chidchanun/bcp` as two separate framework copies.
123
+ A lockfile is recommended for reproducible CI and Docker builds.
112
124
 
113
- The CLI performs a startup preflight. If both package roots exist, runtime commands such as `dev`, `build`, and `start` stop before SSR starts. Two framework copies create separate React contexts, which can make APIs such as `useLoaderData()` incorrectly report missing loader data even when the route loader executed successfully.
125
+ For npm applications with a `Dockerfile`, Doctor expects `package-lock.json` so the image can use `npm ci` deterministically.
114
126
 
115
- For local release verification, install the tarball under the existing `bcp` dependency key instead of adding the scoped package beside it:
127
+ Other package-manager lockfiles can still be identified, but the Docker recommendation must match the package manager used by that project.
116
128
 
117
- ```powershell
118
- npm install `
119
- --no-save `
120
- --package-lock=false `
121
- "bcp@file:D:\bcp-framework\.package\artifacts\chidchanun-bcp-0.1.22.tgz"
129
+ ### Production-hardening diagnostics
130
+
131
+ Doctor validates the current `0.1.28+` hardening environment controls:
132
+
133
+ ```text
134
+ BCP_REQUEST_TIMEOUT_MS
135
+ BCP_HEADERS_TIMEOUT_MS
136
+ BCP_KEEP_ALIVE_TIMEOUT_MS
137
+ BCP_SHUTDOWN_TIMEOUT_MS
138
+ BCP_TRUST_PROXY
122
139
  ```
123
140
 
124
- The installed folder remains `node_modules/bcp` even when the package inside the tarball is published as `@chidchanun/bcp`.
141
+ Invalid timeout relationships or invalid values are reported before deployment.
125
142
 
126
143
  ## `bcp inspect`
127
144
 
128
- Use `inspect` when you want a deterministic snapshot of the project inputs BCP sees:
145
+ Use Inspect for a deterministic snapshot of the project inputs BCP sees:
129
146
 
130
147
  ```powershell
131
148
  npm exec -- bcp-framework inspect
132
149
  ```
133
150
 
134
- It prints:
151
+ The existing report includes:
135
152
 
136
153
  - framework version,
137
154
  - Node.js/platform information,
138
- - development `.env` files that were loaded,
139
- - names of public `BCP_PUBLIC_*` variables (values are not exposed by the summary),
140
- - the fully resolved BCP configuration,
141
- - resolved BCP/React/React DOM package versions,
142
- - discovered page and API routes.
155
+ - development `.env` files,
156
+ - names of public `BCP_PUBLIC_*` variables,
157
+ - resolved BCP configuration,
158
+ - resolved BCP/React/React DOM versions,
159
+ - discovered page/API routes.
160
+
161
+ Inspect validates route conflicts and client boundaries before returning its report. It does not start an HTTP server.
162
+
163
+ ## Inspect v2 project report — 0.1.29
164
+
165
+ The report now adds a `project` object.
166
+
167
+ Representative JSON shape:
168
+
169
+ ```json
170
+ {
171
+ "project": {
172
+ "packageManager": "npm",
173
+ "lockfile": "package-lock.json",
174
+ "metadataFile": "bcp.project.json",
175
+ "presets": {
176
+ "tailwind": true,
177
+ "database": "mysql",
178
+ "auth": "jwt-cookie",
179
+ "storage": "local"
180
+ },
181
+ "productionBuild": true,
182
+ "dockerfile": "Dockerfile",
183
+ "frameworkDeclarations": [
184
+ {
185
+ "name": "bcp",
186
+ "range": "npm:@chidchanun/bcp@0.1.29",
187
+ "section": "dependencies"
188
+ }
189
+ ],
190
+ "storage": {
191
+ "provider": "local",
192
+ "file": "lib/storage.ts"
193
+ },
194
+ "hardening": {
195
+ "valid": true,
196
+ "message": "..."
197
+ }
198
+ }
199
+ }
200
+ ```
201
+
202
+ The `project` field is additive; previous top-level Inspect fields remain available.
203
+
204
+ ## `bcp.project.json` integration
205
+
206
+ Projects created by `create-bcp-app` `0.1.29+` contain a non-secret `bcp.project.json` manifest.
207
+
208
+ Inspect uses this metadata for explicit preset identity where available, including:
209
+
210
+ ```text
211
+ package manager
212
+ Tailwind preset
213
+ database preset
214
+ auth preset
215
+ storage preset
216
+ ```
217
+
218
+ For older projects without the manifest, diagnostics fall back to package files and source inspection where practical.
219
+
220
+ See [Project Metadata](project-metadata.md).
143
221
 
144
- `inspect` validates route conflicts and client boundaries before printing its report. It does not start an HTTP server.
222
+ ## Storage detection
223
+
224
+ For new generated projects, the storage provider comes from `bcp.project.json`.
225
+
226
+ For older projects, Inspect can infer common providers from `lib/storage.ts`:
227
+
228
+ ```text
229
+ local
230
+ amazon-s3
231
+ cloudflare-r2
232
+ s3-compatible
233
+ custom
234
+ none
235
+ ```
236
+
237
+ This is diagnostic metadata only; it does not expose access keys or other credentials.
145
238
 
146
239
  ## JSON output
147
240
 
@@ -152,20 +245,20 @@ npm exec -- bcp-framework doctor --json
152
245
  npm exec -- bcp-framework inspect --json
153
246
  ```
154
247
 
155
- You can also target another installed BCP application directory:
248
+ Target another installed BCP application with:
156
249
 
157
250
  ```powershell
158
251
  npm exec -- bcp-framework doctor --root ..\my-app --json
159
252
  npm exec -- bcp-framework inspect --root ..\my-app --json
160
253
  ```
161
254
 
162
- `--json` is intentionally limited to `doctor` and `inspect` so other CLI commands keep their existing human-oriented output contracts.
255
+ `--json` is intentionally limited to Doctor/Inspect so other commands can retain human-oriented output contracts.
163
256
 
164
- ## Environment and config behavior
257
+ ## Environment behavior
165
258
 
166
- Developer tools inspect the development environment because they are intended to diagnose `bcp dev` projects.
259
+ Developer tools inspect the development environment because they are primarily project-development diagnostics.
167
260
 
168
- Environment file precedence remains the same as the normal framework environment loader:
261
+ Environment file precedence remains:
169
262
 
170
263
  ```text
171
264
  .env
@@ -174,16 +267,20 @@ Environment file precedence remains the same as the normal framework environment
174
267
  .env.development.local
175
268
  ```
176
269
 
177
- Resolved configuration still follows the framework configuration precedence rules. `bcp inspect` displays the final resolved config rather than only the source `bcp.config.*` object.
270
+ Inspect displays resolved configuration, not only the raw `bcp.config.*` source object.
178
271
 
179
272
  ## CI example
180
273
 
181
- A simple project-health gate can use:
182
-
183
274
  ```bash
184
275
  bcp doctor --json > bcp-doctor.json
185
276
  ```
186
277
 
187
- Inside npm scripts or CI package-script execution, npm already places `node_modules/.bin` on `PATH`.
278
+ The command exits non-zero when blocking checks fail while the JSON report remains suitable for CI artifacts/logs.
279
+
280
+ ## Related documentation
188
281
 
189
- The command exits non-zero when blocking checks fail, while the JSON report remains available for CI logs or artifacts.
282
+ - [Project Generators](generators.md)
283
+ - [Project Metadata](project-metadata.md)
284
+ - [Production Hardening](production-hardening.md)
285
+ - [Configuration](configuration.md)
286
+ - [Deployment](deployment.md)
@@ -0,0 +1,97 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "framework": "bcp",
4
+ "versionTarget": "0.2.0",
5
+ "releaseState": "unreleased",
6
+ "sections": [
7
+ {
8
+ "id": "getting-started",
9
+ "title": "Getting Started",
10
+ "pages": [
11
+ { "route": "/docs/getting-started", "source": "getting-started.md", "title": "Getting Started" },
12
+ { "route": "/docs/configuration", "source": "configuration.md", "title": "Configuration" },
13
+ { "route": "/docs/application-modules", "source": "application-modules.md", "title": "Application Modules" },
14
+ { "route": "/docs/project-metadata", "source": "project-metadata.md", "title": "Project Metadata" },
15
+ { "route": "/docs/deployment", "source": "deployment.md", "title": "Deployment" },
16
+ { "route": "/docs/updating", "source": "updating.md", "title": "Updating BCP" }
17
+ ]
18
+ },
19
+ {
20
+ "id": "routing-data",
21
+ "title": "Routing & Data",
22
+ "pages": [
23
+ { "route": "/docs/routing", "source": "routing.md", "title": "Routing" },
24
+ { "route": "/docs/server-data-loaders", "source": "server-data-loaders.md", "title": "Server Data Loaders" },
25
+ { "route": "/docs/route-guards", "source": "route-guards.md", "title": "Route Guards" },
26
+ { "route": "/docs/form-actions", "source": "form-actions.md", "title": "Form Actions" },
27
+ { "route": "/docs/server-request-apis", "source": "server-request-apis.md", "title": "Server Request APIs" },
28
+ { "route": "/docs/validation", "source": "validation.md", "title": "Validation" },
29
+ { "route": "/docs/error-handling", "source": "error-handling.md", "title": "Error Handling" }
30
+ ]
31
+ },
32
+ {
33
+ "id": "authentication",
34
+ "title": "Authentication",
35
+ "pages": [
36
+ { "route": "/docs/authentication", "source": "authentication.md", "title": "Authentication" },
37
+ { "route": "/docs/auth-route-guards", "source": "auth-route-guards.md", "title": "Auth Route Guards" },
38
+ { "route": "/docs/session-auth", "source": "session-auth.md", "title": "JWT Sessions" }
39
+ ]
40
+ },
41
+ {
42
+ "id": "database",
43
+ "title": "Database",
44
+ "pages": [
45
+ { "route": "/docs/database", "source": "database.md", "title": "Database" },
46
+ { "route": "/docs/database-migrations", "source": "database-migrations.md", "title": "Database Migrations" }
47
+ ]
48
+ },
49
+ {
50
+ "id": "runtime",
51
+ "title": "Runtime & Infrastructure",
52
+ "pages": [
53
+ { "route": "/docs/middleware", "source": "middleware.md", "title": "Middleware" },
54
+ { "route": "/docs/hydration", "source": "hydration.md", "title": "Hydration" },
55
+ { "route": "/docs/development-logging", "source": "development-logging.md", "title": "Logging & Observability" },
56
+ { "route": "/docs/caching", "source": "caching.md", "title": "Caching" },
57
+ { "route": "/docs/security", "source": "security.md", "title": "Security" },
58
+ { "route": "/docs/production-hardening", "source": "production-hardening.md", "title": "Production Hardening" }
59
+ ]
60
+ },
61
+ {
62
+ "id": "storage",
63
+ "title": "Storage & Uploads",
64
+ "pages": [
65
+ { "route": "/docs/file-upload", "source": "file-upload.md", "title": "File Upload" },
66
+ { "route": "/docs/storage", "source": "storage.md", "title": "Storage & File Delivery" },
67
+ { "route": "/docs/storage-ecosystem", "source": "storage-ecosystem.md", "title": "Storage Ecosystem" },
68
+ { "route": "/docs/s3-storage", "source": "s3-storage.md", "title": "S3-Compatible Storage" }
69
+ ]
70
+ },
71
+ {
72
+ "id": "developer-experience",
73
+ "title": "Developer Experience",
74
+ "pages": [
75
+ { "route": "/docs/generators", "source": "generators.md", "title": "Project Generators" },
76
+ { "route": "/docs/developer-tools", "source": "developer-tools.md", "title": "Doctor & Inspect" }
77
+ ]
78
+ },
79
+ {
80
+ "id": "platform-compatibility",
81
+ "title": "Platform & Compatibility",
82
+ "pages": [
83
+ { "route": "/docs/platform-contract", "source": "platform-contract.md", "title": "Framework Platform Contract" },
84
+ { "route": "/docs/migration-0.2", "source": "migration-0.2.md", "title": "Migrating to 0.2.0" }
85
+ ]
86
+ }
87
+ ],
88
+ "releases": [
89
+ { "route": "/releases/0.2.0", "source": "releases/0.2.0.md", "version": "0.2.0", "state": "unreleased" },
90
+ { "route": "/releases/0.1.29", "source": "releases/0.1.29.md", "version": "0.1.29" },
91
+ { "route": "/releases/0.1.28", "source": "releases/0.1.28.md", "version": "0.1.28" },
92
+ { "route": "/releases/0.1.27", "source": "releases/0.1.27.md", "version": "0.1.27" },
93
+ { "route": "/releases/0.1.26", "source": "releases/0.1.26.md", "version": "0.1.26" },
94
+ { "route": "/releases/0.1.25", "source": "releases/0.1.25.md", "version": "0.1.25" },
95
+ { "route": "/releases/0.1.24", "source": "releases/0.1.24.md", "version": "0.1.24" }
96
+ ]
97
+ }
@@ -0,0 +1,149 @@
1
+ # Project Generators
2
+
3
+ BCP Framework `0.1.29` adds project generators for common file-based application scaffolds.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ bcp generate page dashboard/users
9
+ bcp generate api users
10
+ bcp generate middleware
11
+ bcp generate migration create_users
12
+ ```
13
+
14
+ On Windows, direct project-local execution can use the collision-free CLI alias:
15
+
16
+ ```powershell
17
+ npm exec -- bcp-framework generate page dashboard/users
18
+ ```
19
+
20
+ ## Page generator
21
+
22
+ ```bash
23
+ bcp generate page dashboard/users
24
+ ```
25
+
26
+ creates:
27
+
28
+ ```text
29
+ app/
30
+ └─ dashboard/
31
+ └─ users/
32
+ └─ page.tsx
33
+ ```
34
+
35
+ The generated page exports a valid default React component.
36
+
37
+ Dynamic and grouped route segments are accepted when they match BCP route naming rules:
38
+
39
+ ```bash
40
+ bcp generate page users/[id]
41
+ bcp generate page docs/[...slug]
42
+ bcp generate page catalog/[[...slug]]
43
+ bcp generate page "(admin)/settings"
44
+ ```
45
+
46
+ The generator rejects `.` / `..`, traversal attempts and invalid route characters.
47
+
48
+ ## API route generator
49
+
50
+ ```bash
51
+ bcp generate api users
52
+ ```
53
+
54
+ creates:
55
+
56
+ ```text
57
+ app/
58
+ └─ api/
59
+ └─ users/
60
+ └─ route.ts
61
+ ```
62
+
63
+ The generated API route contains a minimal `GET()` handler returning JSON.
64
+
65
+ Both of these are equivalent:
66
+
67
+ ```bash
68
+ bcp generate api users
69
+ bcp generate api api/users
70
+ ```
71
+
72
+ ## Middleware generator
73
+
74
+ ```bash
75
+ bcp generate middleware
76
+ ```
77
+
78
+ creates a project-root `middleware.ts` using Middleware System v2:
79
+
80
+ ```ts
81
+ import type {
82
+ MiddlewarePipelineHandler,
83
+ } from "bcp/middleware";
84
+
85
+ export const middleware:
86
+ MiddlewarePipelineHandler =
87
+ async (
88
+ _request,
89
+ next
90
+ ) => {
91
+ return next();
92
+ };
93
+ ```
94
+
95
+ ## Migration generator
96
+
97
+ ```bash
98
+ bcp generate migration create_users
99
+ ```
100
+
101
+ reuses the database migration generator and creates a timestamped migration under `migrations/`.
102
+
103
+ It is equivalent to:
104
+
105
+ ```bash
106
+ bcp db create create_users
107
+ ```
108
+
109
+ The generator intentionally reuses the existing migration implementation so migration naming and file format have one source of truth.
110
+
111
+ ## Existing files and `--force`
112
+
113
+ Page, API and middleware generators refuse to replace existing files by default:
114
+
115
+ ```text
116
+ BCP Generate: ... already exists. Pass --force to replace it.
117
+ ```
118
+
119
+ Explicit replacement:
120
+
121
+ ```bash
122
+ bcp generate page dashboard/users --force
123
+ ```
124
+
125
+ Use `--force` carefully because it replaces the scaffold target file rather than merging source code.
126
+
127
+ ## Project root
128
+
129
+ Generators use the same project-root resolution as other BCP CLI commands.
130
+
131
+ ```bash
132
+ bcp generate page users --root ./my-app
133
+ ```
134
+
135
+ ## Recommended workflow
136
+
137
+ ```text
138
+ create-bcp-app
139
+
140
+ bcp generate page / api / middleware / migration
141
+
142
+ bcp routes
143
+
144
+ bcp doctor
145
+
146
+ npm run typecheck
147
+ ```
148
+
149
+ After generating page/API files, `bcp routes` can confirm the discovered route paths.