@chidchanun/bcp 0.2.2 → 0.2.4

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 CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  BCP Framework is a React full-stack framework for file-based routing, SSR, SPA navigation, server data loading, guarded application flows, API routes, authentication, database access, validation, uploads, storage and standalone Node.js production deployment.
4
4
 
5
- > **Development target:** `0.2.2Configuration & Environment v2`
5
+ > **Development target:** `0.2.4Application Packaging`
6
6
  >
7
- > `0.2.2` is an unreleased development target until local validation, RC checks, tagging and npm publication complete.
7
+ > `0.2.4` is an unreleased development target until local validation, RC checks, tagging and npm publication complete.
8
8
 
9
9
  ## 0.2 platform
10
10
 
11
- `0.2.0` established the Framework Platform baseline, `0.2.1` added the Documentation Platform, and `0.2.2` adds typed application environment validation and configuration diagnostics without intentionally removing public application entrypoints.
11
+ `0.2.0` established the Framework Platform baseline, `0.2.1` added the Documentation Platform, `0.2.2` added Configuration & Environment v2, `0.2.3` added Database Platform v2, and `0.2.4` adds deployment-oriented application packaging without intentionally removing the existing public application model.
12
12
 
13
13
  Machine-readable platform contracts:
14
14
 
@@ -36,14 +36,14 @@ docs/api-manifest.json
36
36
  | Middleware | Middleware System v2 with onion execution |
37
37
  | Validation | Typed validators and structured validation errors |
38
38
  | Error handling | HTTP error helpers and consistent error responses |
39
- | Database | MySQL helpers, transactions and migrations |
39
+ | Database | Provider-neutral MySQL, PostgreSQL and SQLite adapters, transactions, lifecycle and migrations |
40
40
  | Logging | Structured logger, request logger and request IDs |
41
41
  | Uploads | Buffered multipart helpers and production multipart streaming |
42
42
  | Storage | Local + S3-compatible storage, streaming, list/copy/move, metadata, bulk delete and signed URLs |
43
43
  | Caching | Response cache and revalidation primitives |
44
44
  | Configuration | Typed `bcp.config.*`, optional `bcp.environment.*`, startup diagnostics and `bcp config check` |
45
45
  | Developer tools | Generators, Doctor/Inspect v2, updater, route inspection and project metadata |
46
- | Production | Standalone Node.js build, hardening gateway, graceful shutdown, trusted proxy controls and HTTP timeouts |
46
+ | Production | Standalone Node.js build, application packaging, production dependency pruning, deployment manifests, Docker starter, hardening and graceful shutdown |
47
47
  | Documentation | Manifest-driven docs navigation, platform metadata and public API reference |
48
48
 
49
49
  ## Requirements
@@ -52,7 +52,13 @@ docs/api-manifest.json
52
52
  - React `19`
53
53
  - npm
54
54
 
55
- Database framework primitives currently target MySQL.
55
+ Database drivers are optional and provider-specific:
56
+
57
+ ```text
58
+ MySQL mysql2
59
+ PostgreSQL pg
60
+ SQLite better-sqlite3
61
+ ```
56
62
 
57
63
  ## Quick start
58
64
 
@@ -74,7 +80,7 @@ Generated projects normally keep one framework dependency key:
74
80
 
75
81
  Do not install both `bcp` and a second direct `@chidchanun/bcp` dependency in the same application.
76
82
 
77
- ## Configuration
83
+ ## Configuration & environment
78
84
 
79
85
  Framework configuration stays in one of:
80
86
 
@@ -85,29 +91,16 @@ bcp.config.js
85
91
  bcp.config.mjs
86
92
  ```
87
93
 
88
- Example:
94
+ Application environment validation can be declared in:
89
95
 
90
- ```ts
91
- import {
92
- defineConfig,
93
- } from "bcp/config";
94
-
95
- export default defineConfig({
96
- server: {
97
- port: 3000,
98
- hostname: "0.0.0.0",
99
- },
100
- build: {
101
- minify: true,
102
- sourceMaps: false,
103
- },
104
- security: {
105
- poweredByHeader: false,
106
- },
107
- });
96
+ ```text
97
+ bcp.environment.ts
98
+ bcp.environment.mts
99
+ bcp.environment.js
100
+ bcp.environment.mjs
108
101
  ```
109
102
 
110
- Configuration precedence remains:
103
+ Configuration precedence is:
111
104
 
112
105
  ```text
113
106
  CLI override
@@ -119,110 +112,124 @@ bcp.config.*
119
112
  framework defaults
120
113
  ```
121
114
 
122
- Read more: [Configuration](docs/configuration.md)
115
+ Validate configuration and declared environment values with:
123
116
 
124
- ## Environment Validation — 0.2.2
117
+ ```bash
118
+ bcp config check
119
+ bcp config check --json
120
+ ```
125
121
 
126
- Application-specific variables can be declared in an optional environment schema:
122
+ Variables beginning with `BCP_PUBLIC_` may be embedded in browser output. Never expose application secrets through public-prefixed variables.
127
123
 
128
- ```text
129
- bcp.environment.ts
130
- ```
124
+ Read more:
131
125
 
132
- Example:
126
+ - [Configuration](docs/configuration.md)
127
+ - [Environment Validation](docs/environment-validation.md)
128
+
129
+ ## Database Platform v2 — 0.2.3
130
+
131
+ Application code uses one server-only database entrypoint across supported SQL providers:
133
132
 
134
133
  ```ts
135
134
  import {
136
- defineEnvironment,
137
- } from "bcp/config";
138
-
139
- export default defineEnvironment({
140
- DB_HOST: {
141
- type: "string",
142
- required: true,
143
- },
144
-
145
- DB_PORT: {
146
- type: "number",
147
- default: 3306,
148
- min: 1,
149
- max: 65535,
150
- },
151
-
152
- SESSION_SECRET: {
153
- type: "string",
154
- required: true,
155
- secret: true,
156
- minLength: 32,
157
- },
158
-
159
- FEATURE_ENABLED: {
160
- type: "boolean",
161
- default: false,
162
- },
163
-
164
- BCP_PUBLIC_API_URL: {
165
- type: "url",
166
- required: true,
167
- },
168
- });
135
+ db,
136
+ createDatabase,
137
+ } from "bcp/database";
169
138
  ```
170
139
 
171
- Supported types:
140
+ Built-in SQL providers:
172
141
 
173
142
  ```text
174
- string
175
- number
176
- boolean
177
- url
143
+ mysql
144
+ postgresql
145
+ sqlite
178
146
  ```
179
147
 
180
- Validate the current project:
148
+ Lifecycle control:
181
149
 
182
- ```bash
183
- bcp config check
150
+ ```ts
151
+ await db.connect();
152
+
153
+ // application work
154
+
155
+ await db.disconnect();
184
156
  ```
185
157
 
186
- JSON diagnostics:
158
+ `db.close()` remains available for backward-compatible shutdown handling.
159
+
160
+ Migration CLI:
187
161
 
188
162
  ```bash
189
- bcp config check --json
163
+ bcp db create create_users
164
+ bcp db migrate
165
+ bcp db status
166
+ bcp db rollback
190
167
  ```
191
168
 
192
- On Windows, where Microsoft SQL Server may provide another `bcp.exe`, prefer:
169
+ BCP makes framework migration bookkeeping provider-aware. Application migration SQL itself is not automatically translated between SQL dialects.
193
170
 
194
- ```powershell
195
- npm exec -- bcp-framework config check
196
- npm exec -- bcp-framework config check --json
171
+ Read more:
172
+
173
+ - [Database](docs/database.md)
174
+ - [Database Migrations](docs/database-migrations.md)
175
+
176
+ ## Application Packaging — 0.2.4
177
+
178
+ Create a fresh production build and convert it into a deployment-oriented package:
179
+
180
+ ```bash
181
+ bcp package
197
182
  ```
198
183
 
199
- `bcp dev` and `bcp build` also validate `bcp.environment.*` before startup/build. Invalid required values fail early.
184
+ Framework-repository development can also run:
185
+
186
+ ```bash
187
+ npm run package
188
+ ```
200
189
 
201
- The development supervisor watches:
190
+ Output:
202
191
 
203
192
  ```text
204
- .env*
205
- bcp.config.*
206
- bcp.environment.*
193
+ .bcp-framework/package/
194
+ ├─ client/
195
+ ├─ server/
196
+ │ └─ server.mjs
197
+ ├─ public/ # when present
198
+ ├─ manifest.json
199
+ ├─ package.json
200
+ ├─ package-lock.json # when a safe npm v3 production lock can be derived
201
+ ├─ bcp.package.json
202
+ ├─ bcp.deployment.json
203
+ ├─ bcp.env.json
204
+ ├─ Dockerfile
205
+ ├─ .dockerignore
206
+ └─ README.md
207
207
  ```
208
208
 
209
- and restarts the worker when one of those files changes.
209
+ The package layer:
210
210
 
211
- ### Secret safety
211
+ - runs a fresh `bcp build` before packaging,
212
+ - strips application `devDependencies` from the deployment package,
213
+ - derives a production-only npm v3 lock graph when safe,
214
+ - records `npm ci --omit=dev` when the production lock is available,
215
+ - falls back explicitly to `npm install --omit=dev` when a safe lock cannot be produced,
216
+ - writes deployment/runtime metadata,
217
+ - records environment variable names without copying `.env` values,
218
+ - creates SHA-256 file integrity metadata,
219
+ - generates a Node 24 Alpine Docker starter.
212
220
 
213
- Variables beginning with `BCP_PUBLIC_` can be embedded into browser bundles.
221
+ The current package target is:
214
222
 
215
- A variable marked:
216
-
217
- ```ts
218
- secret: true
223
+ ```text
224
+ standalone-node
219
225
  ```
220
226
 
221
- must not use `BCP_PUBLIC_`. BCP reports this as a configuration error.
227
+ Native executable, desktop, Android and iOS packaging remain later roadmap work.
222
228
 
223
- `secret: true` is tooling metadata; it does not encrypt environment values.
229
+ Read more:
224
230
 
225
- Read more: [Environment Validation](docs/environment-validation.md)
231
+ - [Application Packaging](docs/application-packaging.md)
232
+ - [Deployment](docs/deployment.md)
226
233
 
227
234
  ## Public entrypoints
228
235
 
@@ -257,6 +264,7 @@ Core commands:
257
264
  ```bash
258
265
  bcp dev
259
266
  bcp build
267
+ bcp package
260
268
  bcp start
261
269
  bcp routes
262
270
  bcp update
@@ -322,12 +330,14 @@ app/
322
330
 
323
331
  ## Production build
324
332
 
333
+ Raw standalone build:
334
+
325
335
  ```bash
326
336
  npm run build
327
337
  npm run start
328
338
  ```
329
339
 
330
- Standalone output:
340
+ Output:
331
341
 
332
342
  ```text
333
343
  .bcp-framework/build/
@@ -337,17 +347,13 @@ Standalone output:
337
347
  └─ server.mjs
338
348
  ```
339
349
 
340
- The current production target remains:
350
+ Deployment package:
341
351
 
342
- ```text
343
- standalone-node
352
+ ```bash
353
+ bcp package
344
354
  ```
345
355
 
346
- Native `.exe`, desktop and mobile compilation remain later roadmap work.
347
-
348
- Production hardening includes configurable request/header/keep-alive/shutdown timeouts, trusted-proxy handling and graceful `SIGTERM` / `SIGINT` shutdown.
349
-
350
- Read more: [Production Hardening](docs/production-hardening.md)
356
+ Both current targets remain Node.js `standalone-node` applications. Production hardening includes configurable request/header/keep-alive/shutdown timeouts, trusted-proxy handling and graceful `SIGTERM` / `SIGINT` shutdown.
351
357
 
352
358
  ## Documentation Platform
353
359
 
@@ -367,7 +373,7 @@ Read more:
367
373
 
368
374
  - [Documentation Source Map](docs/README.md)
369
375
  - [Documentation Platform](docs/documentation-platform.md)
370
- - [Environment Validation](docs/environment-validation.md)
376
+ - [Application Packaging](docs/application-packaging.md)
371
377
 
372
378
  ## Release validation
373
379
 
@@ -383,7 +389,7 @@ npm run test:e2e
383
389
  npm run rc:check
384
390
  ```
385
391
 
386
- `0.2.2` adds Configuration & Environment v2 unit/package checks covering schema parsing, project schema loading, diagnostics, CLI parsing, public `bcp/config` exports and packed-package files.
392
+ `0.2.4` adds Application Packaging unit and prepared-package smoke checks covering production dependency metadata, production lock pruning, environment-value exclusion, deployment metadata and the `bcp package` CLI surface.
387
393
 
388
394
  Do not tag or publish until the final release commit passes the complete RC sequence.
389
395
 
@@ -400,24 +406,14 @@ Do not tag or publish until the final release commit passes the complete RC sequ
400
406
  | `0.2.0` | Framework Platform |
401
407
  | `0.2.1` | Documentation Platform |
402
408
  | `0.2.2` | Configuration & Environment v2 |
409
+ | `0.2.3` | Database Platform v2 |
410
+ | `0.2.4` | Application Packaging |
403
411
 
404
412
  ## Roadmap
405
413
 
406
- Next planned milestone:
407
-
408
- ```text
409
- 0.2.3 — Database Platform v2
410
- ```
411
-
412
- Planned focus:
413
-
414
- - database adapter contract,
415
- - PostgreSQL support,
416
- - SQLite support,
417
- - connection lifecycle improvements,
418
- - migration consistency across providers.
414
+ `0.2.4 Application Packaging` establishes the deployment artifact contract for the existing standalone Node.js runtime.
419
415
 
420
- Application packaging remains later `0.2.x` roadmap work.
416
+ The next planned framework milestone can build on this package contract without changing the current Node.js deployment model. Native `.exe`, desktop and mobile compilation remain later roadmap work.
421
417
 
422
418
  ## License
423
419
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "version": "0.2.2",
4
+ "version": "0.2.4",
5
5
  "releaseState": "unreleased",
6
6
  "coverage": "public-entrypoints",
7
7
  "entrypoints": [
@@ -74,7 +74,7 @@
74
74
  "source": "packages/client/src/database.ts",
75
75
  "environment": "server",
76
76
  "route": "/docs/api-reference#bcp-database",
77
- "summary": "Database pool, prepared query/execute helpers and transaction primitives.",
77
+ "summary": "Provider-neutral MySQL, PostgreSQL and SQLite query, transaction, lifecycle and migration primitives.",
78
78
  "guides": [
79
79
  "/docs/database",
80
80
  "/docs/database-migrations"
@@ -130,16 +130,35 @@ Related guide: [Error Handling](error-handling.md).
130
130
 
131
131
  ## `bcp/database`
132
132
 
133
- Server-only database primitives.
133
+ Server-only Database Platform v2 APIs.
134
134
 
135
135
  ```ts
136
136
  import {
137
137
  createDatabase,
138
138
  db,
139
+ resolveDatabaseOptions,
140
+ type DatabaseAdapter,
141
+ type DatabaseAdapterFactory,
142
+ type DatabaseConnectionOptions,
143
+ type DatabaseDriver,
144
+ type DatabaseOptions,
145
+ type DatabaseParameters,
146
+ type ResolvedDatabaseOptions,
147
+ type TransactionDatabase,
139
148
  } from "bcp/database";
140
149
  ```
141
150
 
142
- Use the public database helpers instead of importing framework-internal pool/runtime modules.
151
+ Built-in SQL providers are:
152
+
153
+ ```text
154
+ mysql
155
+ postgresql
156
+ sqlite
157
+ ```
158
+
159
+ `BcpDatabase` instances expose lazy query/execute/transaction operations plus explicit `connect()`, `disconnect()` and backward-compatible `close()` lifecycle methods.
160
+
161
+ Use the public database helpers and adapter types instead of importing framework-internal provider/pool runtime modules.
143
162
 
144
163
  Related guides: [Database](database.md), [Database Migrations](database-migrations.md).
145
164
 
@@ -0,0 +1,243 @@
1
+ # Application Packaging
2
+
3
+ BCP Framework `0.2.4` adds an application packaging layer on top of the standalone Node.js production build.
4
+
5
+ The goal is to turn a BCP project into a deployment-oriented directory that contains the built application, production dependency metadata, deployment metadata and container starter files without copying source-only development dependencies or project secrets.
6
+
7
+ ## Create a package
8
+
9
+ From the application root:
10
+
11
+ ```bash
12
+ bcp package
13
+ ```
14
+
15
+ `bcp package` always runs a fresh production build first. This prevents an older `.bcp-framework/build` directory from being packaged accidentally.
16
+
17
+ The output is written to:
18
+
19
+ ```text
20
+ .bcp-framework/
21
+ └── package/
22
+ ├── client/
23
+ ├── server/
24
+ │ └── server.mjs
25
+ ├── public/ # when the application has public assets
26
+ ├── manifest.json
27
+ ├── package.json
28
+ ├── package-lock.json # when a safe npm v3 production lock can be derived
29
+ ├── bcp.package.json
30
+ ├── bcp.deployment.json
31
+ ├── bcp.env.json
32
+ ├── Dockerfile
33
+ ├── .dockerignore
34
+ └── README.md
35
+ ```
36
+
37
+ The current packaging target is:
38
+
39
+ ```text
40
+ standalone-node
41
+ ```
42
+
43
+ Native executable, desktop and mobile packaging are not part of `0.2.4`.
44
+
45
+ ## Production dependencies
46
+
47
+ The generated package-level `package.json` keeps runtime metadata only:
48
+
49
+ - `dependencies`
50
+ - `optionalDependencies`
51
+ - `peerDependencies`
52
+ - supported peer metadata / overrides when present
53
+ - `engines.node`
54
+ - the standalone `start` script
55
+
56
+ `devDependencies` are intentionally excluded.
57
+
58
+ When the project has an npm lockfile v3 that can be safely converted to the production dependency graph, BCP writes a pruned `package-lock.json` and records:
59
+
60
+ ```bash
61
+ npm ci --omit=dev
62
+ ```
63
+
64
+ as the deployment install command.
65
+
66
+ If a safe production lock cannot be derived, packaging continues without copying an unsafe lockfile and records:
67
+
68
+ ```bash
69
+ npm install --omit=dev
70
+ ```
71
+
72
+ instead. The CLI prints a warning in that case.
73
+
74
+ This fallback is intentional: an application package must not pretend to be reproducibly locked when the framework cannot prove the lock metadata is safe for the standalone artifact.
75
+
76
+ ## Package manifest
77
+
78
+ `bcp.package.json` describes the produced artifact. It includes:
79
+
80
+ - schema version
81
+ - target runtime
82
+ - BCP Framework version
83
+ - application name/version
84
+ - Node.js requirement
85
+ - entrypoint and start command
86
+ - dependency installation command
87
+ - whether a production lockfile is included
88
+ - build/deployment/environment manifest paths
89
+ - package file inventory
90
+ - byte size and SHA-256 digest for each packaged file
91
+
92
+ Example shape:
93
+
94
+ ```json
95
+ {
96
+ "schemaVersion": 1,
97
+ "target": "standalone-node",
98
+ "frameworkVersion": "0.2.4",
99
+ "application": {
100
+ "name": "my-app",
101
+ "version": "0.1.0"
102
+ },
103
+ "runtime": {
104
+ "node": ">=24.11.0",
105
+ "entrypoint": "server/server.mjs",
106
+ "startCommand": "npm start"
107
+ },
108
+ "install": {
109
+ "command": "npm ci --omit=dev",
110
+ "lockfile": true,
111
+ "devDependenciesIncluded": false
112
+ }
113
+ }
114
+ ```
115
+
116
+ The file inventory allows deployment tooling to verify an application package before shipping it to a server or container image.
117
+
118
+ ## Deployment manifest
119
+
120
+ `bcp.deployment.json` is a small deployment contract for the current package target. It records:
121
+
122
+ ```text
123
+ runtime: Node.js
124
+ install: npm ci --omit=dev (or npm install --omit=dev fallback)
125
+ start: npm start
126
+ entrypoint: server/server.mjs
127
+ container starter: Dockerfile
128
+ ```
129
+
130
+ Future deployment adapters can consume this manifest without changing the current standalone Node.js contract.
131
+
132
+ ## Environment manifest and secret safety
133
+
134
+ BCP application packages do **not** copy project `.env` files.
135
+
136
+ `bcp.env.json` contains metadata only. When files such as `.env.example` exist, BCP can record declared variable names, but it does not record their values.
137
+
138
+ For example:
139
+
140
+ ```dotenv
141
+ DATABASE_URL=postgresql://user:password@example/db
142
+ BCP_SESSION_SECRET=secret
143
+ ```
144
+
145
+ is represented only as names such as:
146
+
147
+ ```json
148
+ {
149
+ "declaredKeys": [
150
+ "BCP_SESSION_SECRET",
151
+ "DATABASE_URL"
152
+ ],
153
+ "valuesIncluded": false,
154
+ "environmentFilesIncluded": false
155
+ }
156
+ ```
157
+
158
+ Supply real secrets through your deployment environment, secret manager or container/orchestrator configuration.
159
+
160
+ Runtime server overrides remain available through:
161
+
162
+ ```text
163
+ BCP_HOSTNAME
164
+ BCP_PORT
165
+ ```
166
+
167
+ ## Run the package
168
+
169
+ After copying `.bcp-framework/package` to the target machine:
170
+
171
+ ```bash
172
+ cd package
173
+ npm ci --omit=dev
174
+ npm start
175
+ ```
176
+
177
+ If `bcp.package.json` says `lockfile: false`, use the recorded install command instead.
178
+
179
+ You can also start the bundled entrypoint directly after dependencies are installed:
180
+
181
+ ```bash
182
+ node server/server.mjs
183
+ ```
184
+
185
+ ## Docker
186
+
187
+ The generated package contains a starter `Dockerfile`:
188
+
189
+ ```bash
190
+ docker build -t my-bcp-app .
191
+ docker run --rm -p 3000:3000 my-bcp-app
192
+ ```
193
+
194
+ Pass runtime environment values with the deployment mechanism you normally use. Do not bake secrets into the image.
195
+
196
+ ## Build vs package
197
+
198
+ Use `bcp build` when you need the framework's raw standalone build output:
199
+
200
+ ```text
201
+ .bcp-framework/build/
202
+ ```
203
+
204
+ Use `bcp package` when you need a deployment-oriented artifact:
205
+
206
+ ```text
207
+ .bcp-framework/package/
208
+ ```
209
+
210
+ In short:
211
+
212
+ ```text
213
+ source application
214
+
215
+ bcp build
216
+
217
+ standalone build
218
+
219
+ bcp package
220
+
221
+ deployment package + production metadata
222
+ ```
223
+
224
+ ## Determinism
225
+
226
+ The packaging layer writes sorted dependency metadata and a sorted file inventory. File hashes are calculated from the final package content.
227
+
228
+ The underlying BCP build currently retains its build identifier/timestamp behavior, so `0.2.4` does not promise byte-for-byte identical packages across independent build invocations. The integrity manifest is intended for verification of a specific produced artifact, not as a claim of fully reproducible builds.
229
+
230
+ ## Validation
231
+
232
+ Framework release validation includes Application Packaging unit and packed-package smoke coverage.
233
+
234
+ Recommended project validation is:
235
+
236
+ ```bash
237
+ bcp package
238
+ cd .bcp-framework/package
239
+ npm ci --omit=dev
240
+ npm start
241
+ ```
242
+
243
+ Then exercise representative routes, API endpoints and any optional runtime providers used by the application.