@chidchanun/bcp 0.2.0 → 0.2.2

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.
@@ -0,0 +1,224 @@
1
+ # Environment Validation
2
+
3
+ BCP Framework `0.2.2` adds an optional typed environment schema for application-specific environment variables.
4
+
5
+ The schema is separate from `bcp.config.*` and uses the project convention:
6
+
7
+ ```text
8
+ bcp.environment.ts
9
+ bcp.environment.mts
10
+ bcp.environment.js
11
+ bcp.environment.mjs
12
+ ```
13
+
14
+ Keep only one environment schema file in an application.
15
+
16
+ ## Define a schema
17
+
18
+ ```ts
19
+ import {
20
+ defineEnvironment,
21
+ } from "bcp/config";
22
+
23
+ export default defineEnvironment({
24
+ DB_HOST: {
25
+ type: "string",
26
+ required: true,
27
+ },
28
+
29
+ DB_PORT: {
30
+ type: "number",
31
+ default: 3306,
32
+ min: 1,
33
+ max: 65535,
34
+ },
35
+
36
+ SESSION_SECRET: {
37
+ type: "string",
38
+ required: true,
39
+ secret: true,
40
+ minLength: 32,
41
+ },
42
+
43
+ FEATURE_ENABLED: {
44
+ type: "boolean",
45
+ default: false,
46
+ },
47
+
48
+ BCP_PUBLIC_API_URL: {
49
+ type: "url",
50
+ required: true,
51
+ },
52
+ });
53
+ ```
54
+
55
+ Supported types:
56
+
57
+ ```text
58
+ string
59
+ number
60
+ boolean
61
+ url
62
+ ```
63
+
64
+ Supported rule fields:
65
+
66
+ ```text
67
+ type
68
+ required
69
+ secret
70
+ minLength
71
+ maxLength
72
+ min
73
+ max
74
+ default
75
+ description
76
+ ```
77
+
78
+ `minLength` / `maxLength` are intended for string and URL values. `min` / `max` are intended for numbers.
79
+
80
+ ## Validate from the CLI
81
+
82
+ ```bash
83
+ bcp config check
84
+ ```
85
+
86
+ On Windows where another `bcp.exe` may exist:
87
+
88
+ ```powershell
89
+ npm exec -- bcp-framework config check
90
+ ```
91
+
92
+ JSON output:
93
+
94
+ ```powershell
95
+ npm exec -- bcp-framework config check --json
96
+ ```
97
+
98
+ The command validates:
99
+
100
+ - `bcp.config.*`,
101
+ - `bcp.environment.*`,
102
+ - loaded `.env` files,
103
+ - configured BCP runtime values,
104
+ - application environment-schema values,
105
+ - selected production safety diagnostics.
106
+
107
+ Development is the default mode.
108
+
109
+ To inspect production diagnostics from a shell where `NODE_ENV` can be set:
110
+
111
+ ```bash
112
+ NODE_ENV=production bcp config check
113
+ ```
114
+
115
+ PowerShell example:
116
+
117
+ ```powershell
118
+ $env:NODE_ENV = "production"
119
+ npm exec -- bcp-framework config check
120
+ Remove-Item Env:NODE_ENV
121
+ ```
122
+
123
+ ## Startup validation
124
+
125
+ When a project contains `bcp.environment.*`, `bcp dev` and `bcp build` validate the schema before the application starts or a production build is produced.
126
+
127
+ A missing or invalid required environment variable stops startup/build with a configuration error.
128
+
129
+ Example:
130
+
131
+ ```text
132
+ BCP Configuration Error:
133
+ - SESSION_SECRET must contain at least 32 character(s).
134
+ ```
135
+
136
+ Changing `bcp.environment.*` while the development supervisor is running automatically restarts the dev worker, the same way changes to `.env*` or `bcp.config.*` do.
137
+
138
+ ## Public variables and secrets
139
+
140
+ Variables beginning with:
141
+
142
+ ```text
143
+ BCP_PUBLIC_
144
+ ```
145
+
146
+ can be embedded into browser bundles.
147
+
148
+ Do not use that prefix for credentials, session secrets, access keys or private service tokens.
149
+
150
+ BCP treats this as an error:
151
+
152
+ ```ts
153
+ export default defineEnvironment({
154
+ BCP_PUBLIC_TOKEN: {
155
+ type: "string",
156
+ required: true,
157
+ secret: true,
158
+ },
159
+ });
160
+ ```
161
+
162
+ The `secret: true` flag is metadata used by validation/tooling. It does not encrypt the environment value. Secrets must still be stored in an appropriate environment/secret manager and kept out of public client variables.
163
+
164
+ ## Programmatic validation
165
+
166
+ The same primitives are public through `bcp/config`:
167
+
168
+ ```ts
169
+ import {
170
+ defineEnvironment,
171
+ validateEnvironment,
172
+ } from "bcp/config";
173
+
174
+ const schema = defineEnvironment({
175
+ API_URL: {
176
+ type: "url",
177
+ required: true,
178
+ },
179
+ });
180
+
181
+ const result = validateEnvironment(
182
+ schema,
183
+ process.env
184
+ );
185
+
186
+ if (!result.ok) {
187
+ console.error(
188
+ result.issues
189
+ );
190
+ }
191
+ ```
192
+
193
+ The parsed `result.values` contains only keys declared by the schema. BCP configuration diagnostics do not print raw secret values.
194
+
195
+ ## Production diagnostics
196
+
197
+ Production configuration checks can emit warnings for potentially risky choices such as:
198
+
199
+ - production source maps enabled,
200
+ - `security.poweredByHeader` enabled,
201
+ - Content-Security-Policy disabled,
202
+ - trusted proxy mode enabled.
203
+
204
+ Warnings do not block a build. Environment-schema errors do.
205
+
206
+ Trusted proxy warnings are informational safety reminders. Enable `BCP_TRUST_PROXY` only when untrusted clients cannot bypass the trusted reverse proxy/load balancer.
207
+
208
+ ## Existing applications
209
+
210
+ Environment schemas are optional.
211
+
212
+ Projects without `bcp.environment.*` continue to use the existing `.env` loading and BCP configuration behavior. The `0.2.2` schema system is additive and does not change the established configuration precedence:
213
+
214
+ ```text
215
+ CLI override
216
+
217
+ BCP_* environment
218
+
219
+ bcp.config.*
220
+
221
+ framework defaults
222
+ ```
223
+
224
+ Application-specific variables are validated against `bcp.environment.*` after environment files are loaded.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
5
5
  "releaseState": "unreleased",
6
6
  "baseline": "framework-platform",
7
7
  "runtime": {
@@ -30,6 +30,7 @@
30
30
  "update",
31
31
  "db",
32
32
  "generate",
33
+ "config",
33
34
  "doctor",
34
35
  "inspect",
35
36
  "help",
@@ -53,7 +54,12 @@
53
54
  "storageEcosystem": true,
54
55
  "productionHardening": true,
55
56
  "projectGenerators": true,
56
- "projectDiagnostics": true
57
+ "projectDiagnostics": true,
58
+ "documentationPlatform": true,
59
+ "apiManifest": true,
60
+ "typedEnvironmentSchema": true,
61
+ "configurationDiagnostics": true,
62
+ "configCheckCli": true
57
63
  },
58
64
  "storageProviders": [
59
65
  "local",
@@ -62,14 +68,19 @@
62
68
  "s3-compatible"
63
69
  ],
64
70
  "compatibility": {
65
- "previousBaseline": "0.1.29",
71
+ "previousBaseline": "0.2.1",
66
72
  "intentionalBreakingChangesFromPreviousBaseline": false,
67
73
  "migrationGuide": "migration-0.2.md"
68
74
  },
69
75
  "documentation": {
70
76
  "navigationManifest": "docs-web-manifest.json",
77
+ "platformManifest": "platform-manifest.json",
78
+ "apiManifest": "api-manifest.json",
71
79
  "platformContract": "platform-contract.md",
80
+ "documentationPlatform": "documentation-platform.md",
81
+ "apiReference": "api-reference.md",
82
+ "environmentValidation": "environment-validation.md",
72
83
  "migrationGuide": "migration-0.2.md",
73
- "releaseNotes": "releases/0.2.0.md"
84
+ "releaseNotes": "releases/0.2.2.md"
74
85
  }
75
86
  }
@@ -0,0 +1,132 @@
1
+ # BCP Framework 0.2.1
2
+
3
+ > **Milestone:** Documentation Platform
4
+ >
5
+ > **Release state:** unreleased development target. Do not mark this version as published until local validation, RC checks, tagging and npm publication complete.
6
+
7
+ BCP Framework `0.2.1` turns the framework documentation repository into a versioned, machine-readable source for `bcp-docs-web`.
8
+
9
+ ## Highlights
10
+
11
+ ### API manifest
12
+
13
+ New:
14
+
15
+ ```text
16
+ docs/api-manifest.json
17
+ ```
18
+
19
+ The manifest describes every documented public package entrypoint with:
20
+
21
+ - package name,
22
+ - source ownership,
23
+ - environment boundary,
24
+ - API-reference route,
25
+ - summary,
26
+ - related guide routes.
27
+
28
+ It complements `docs/platform-manifest.json`, which remains the compatibility/public-entrypoint baseline.
29
+
30
+ ### API reference
31
+
32
+ New authored guide:
33
+
34
+ ```text
35
+ docs/api-reference.md
36
+ ```
37
+
38
+ It provides one supported reference surface for:
39
+
40
+ ```text
41
+ bcp
42
+ bcp/island
43
+ bcp/cache
44
+ bcp/config
45
+ bcp/validation
46
+ bcp/error
47
+ bcp/database
48
+ bcp/auth
49
+ bcp/server
50
+ bcp/server-only
51
+ bcp/middleware
52
+ ```
53
+
54
+ ### Documentation platform contract
55
+
56
+ New:
57
+
58
+ ```text
59
+ docs/documentation-platform.md
60
+ ```
61
+
62
+ This defines how `bcp-docs-web` should consume:
63
+
64
+ ```text
65
+ docs-web-manifest.json
66
+ platform-manifest.json
67
+ api-manifest.json
68
+ Markdown sources
69
+ ```
70
+
71
+ The website should use manifests for navigation/version/API metadata rather than maintaining a competing hard-coded document list.
72
+
73
+ ### Manifest-driven docs-web synchronization
74
+
75
+ The matching `bcp-docs-web` update replaces the old manually maintained framework page/category map with a manifest-driven synchronization path.
76
+
77
+ The sync validates that documentation, platform and API manifests agree on the selected framework version before updating the docs CMS.
78
+
79
+ ### Versioned source foundation
80
+
81
+ The docs sync continues to accept framework refs such as:
82
+
83
+ ```powershell
84
+ npm run docs:sync -- --ref=v0.2.0
85
+ ```
86
+
87
+ This provides the foundation for historical/versioned documentation without duplicating authored Markdown by hand.
88
+
89
+ ## Compatibility
90
+
91
+ `0.2.1` is an additive documentation-platform release over the `0.2.0` Framework Platform baseline.
92
+
93
+ There is no intentional application runtime public-entrypoint removal in this milestone.
94
+
95
+ Production remains the standalone Node.js target defined by the `0.2.x` platform contract.
96
+
97
+ ## Validation
98
+
99
+ Before release:
100
+
101
+ ```bash
102
+ npm run typecheck
103
+ npm run test:unit
104
+ npm run test:integration
105
+ npm run test:e2e
106
+ npm run test:package
107
+ npm run rc:check
108
+ ```
109
+
110
+ Documentation validation must additionally confirm:
111
+
112
+ - docs-web routes are unique,
113
+ - every manifest Markdown source exists,
114
+ - API entrypoints are unique,
115
+ - API entrypoints match the platform public-entrypoint set,
116
+ - all manifest versions match the framework package version,
117
+ - prepared npm packages contain all three documentation manifests and new authored guides.
118
+
119
+ ## Next milestone
120
+
121
+ Planned next:
122
+
123
+ ```text
124
+ 0.2.2 — Configuration & Environment v2
125
+ ```
126
+
127
+ Focus:
128
+
129
+ - typed production configuration improvements,
130
+ - environment validation,
131
+ - startup configuration diagnostics,
132
+ - configuration schema/inspection tooling.
@@ -0,0 +1,118 @@
1
+ # BCP Framework 0.2.2
2
+
3
+ > **Release state:** unreleased development target.
4
+
5
+ BCP Framework `0.2.2` is the **Configuration & Environment v2** milestone.
6
+
7
+ The release keeps the established BCP configuration precedence and adds an optional typed application environment schema, configuration diagnostics and a dedicated CLI validation workflow.
8
+
9
+ ## Highlights
10
+
11
+ ### Typed application environment schema
12
+
13
+ Projects can add:
14
+
15
+ ```text
16
+ bcp.environment.ts
17
+ ```
18
+
19
+ using the public `bcp/config` API:
20
+
21
+ ```ts
22
+ import {
23
+ defineEnvironment,
24
+ } from "bcp/config";
25
+
26
+ export default defineEnvironment({
27
+ DB_HOST: {
28
+ type: "string",
29
+ required: true,
30
+ },
31
+ DB_PORT: {
32
+ type: "number",
33
+ default: 3306,
34
+ },
35
+ SESSION_SECRET: {
36
+ type: "string",
37
+ required: true,
38
+ secret: true,
39
+ minLength: 32,
40
+ },
41
+ });
42
+ ```
43
+
44
+ Supported values include string, number, boolean and absolute HTTP(S) URL rules.
45
+
46
+ ### `bcp config check`
47
+
48
+ New CLI command:
49
+
50
+ ```bash
51
+ bcp config check
52
+ bcp config check --json
53
+ ```
54
+
55
+ It validates project configuration, environment schema values and production diagnostics without printing secret values.
56
+
57
+ ### Startup diagnostics
58
+
59
+ `bcp dev` and `bcp build` validate `bcp.environment.*` before starting the application/build.
60
+
61
+ Schema errors fail early. Production configuration warnings are reported without blocking the build.
62
+
63
+ ### Development schema watching
64
+
65
+ The dev supervisor now watches:
66
+
67
+ ```text
68
+ .env*
69
+ bcp.config.*
70
+ bcp.environment.*
71
+ ```
72
+
73
+ and restarts the worker when any of these configuration sources change.
74
+
75
+ ### Public configuration API
76
+
77
+ `bcp/config` now exposes additive environment/configuration helpers including:
78
+
79
+ ```text
80
+ defineEnvironment
81
+ validateEnvironment
82
+ loadBcpEnvironmentSchema
83
+ diagnoseBcpConfiguration
84
+ assertConfigurationDiagnostics
85
+ ```
86
+
87
+ ## Compatibility
88
+
89
+ `0.2.2` does not intentionally remove public entrypoints from `0.2.1`.
90
+
91
+ Existing projects without `bcp.environment.*` continue to work with the previous `.env` and `bcp.config.*` behavior.
92
+
93
+ The configuration precedence remains:
94
+
95
+ ```text
96
+ CLI > BCP_* environment > bcp.config.* > framework defaults
97
+ ```
98
+
99
+ ## Security
100
+
101
+ A schema variable marked `secret: true` must not use the `BCP_PUBLIC_` prefix. BCP treats that combination as a configuration error because public-prefixed values can be embedded into browser bundles.
102
+
103
+ `secret: true` is metadata for validation/tooling and does not encrypt environment values.
104
+
105
+ ## Validation
106
+
107
+ Before tagging/publishing:
108
+
109
+ ```bash
110
+ npm run typecheck
111
+ npm run test:unit
112
+ npm run test:integration
113
+ npm run test:package
114
+ npm run test:e2e
115
+ npm run rc:check
116
+ ```
117
+
118
+ The final release tag must point at the exact commit that passed the complete RC sequence.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chidchanun/bcp",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "BCP Framework - a React full-stack framework with file-based routing, SSR, APIs, middleware, islands, caching and standalone production builds.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -9,6 +9,7 @@ export type CliCommand =
9
9
  | "update"
10
10
  | "db"
11
11
  | "generate"
12
+ | "config"
12
13
  | "doctor"
13
14
  | "inspect"
14
15
  | "help"
@@ -28,6 +29,10 @@ export type GenerateCliKind =
28
29
  | "migration"
29
30
  | "help";
30
31
 
32
+ export type ConfigCliAction =
33
+ | "check"
34
+ | "help";
35
+
31
36
  export interface CliOptions {
32
37
  command: CliCommand;
33
38
 
@@ -54,6 +59,8 @@ export interface CliOptions {
54
59
  generateKind?: GenerateCliKind;
55
60
 
56
61
  generateName?: string;
62
+
63
+ configAction?: ConfigCliAction;
57
64
  }
58
65
 
59
66
  export function parseCliArgs(
@@ -97,6 +104,9 @@ export function parseCliArgs(
97
104
  let generateName:
98
105
  string | undefined;
99
106
 
107
+ let configAction:
108
+ ConfigCliAction | undefined;
109
+
100
110
  let commandSet = false;
101
111
 
102
112
  for (
@@ -120,6 +130,11 @@ export function parseCliArgs(
120
130
  command === "generate"
121
131
  ) {
122
132
  generateKind = "help";
133
+ } else if (
134
+ commandSet &&
135
+ command === "config"
136
+ ) {
137
+ configAction = "help";
123
138
  } else {
124
139
  command = "help";
125
140
  }
@@ -268,13 +283,6 @@ export function parseCliArgs(
268
283
  );
269
284
  }
270
285
 
271
- /**
272
- * npm compatibility
273
- *
274
- * Some npm environments may consume an unknown script
275
- * option such as --port and leave only its numeric value
276
- * in argv. Accept a bare number for dev/start servers.
277
- */
278
286
  if (
279
287
  isPortShortcut(argument) &&
280
288
  (
@@ -374,6 +382,32 @@ export function parseCliArgs(
374
382
  );
375
383
  }
376
384
 
385
+ if (
386
+ commandSet &&
387
+ command === "config"
388
+ ) {
389
+ if (
390
+ configAction === undefined
391
+ ) {
392
+ if (
393
+ argument === "check" ||
394
+ argument === "help"
395
+ ) {
396
+ configAction =
397
+ argument;
398
+ continue;
399
+ }
400
+
401
+ throw new Error(
402
+ `Unknown config command: ${argument}`
403
+ );
404
+ }
405
+
406
+ throw new Error(
407
+ `Unexpected argument: ${argument}`
408
+ );
409
+ }
410
+
377
411
  if (commandSet) {
378
412
  throw new Error(
379
413
  `Unexpected argument: ${argument}`
@@ -388,6 +422,7 @@ export function parseCliArgs(
388
422
  argument === "update" ||
389
423
  argument === "db" ||
390
424
  argument === "generate" ||
425
+ argument === "config" ||
391
426
  argument === "doctor" ||
392
427
  argument === "inspect" ||
393
428
  argument === "help" ||
@@ -418,10 +453,11 @@ export function parseCliArgs(
418
453
  if (
419
454
  json &&
420
455
  command !== "doctor" &&
421
- command !== "inspect"
456
+ command !== "inspect" &&
457
+ command !== "config"
422
458
  ) {
423
459
  throw new Error(
424
- "Option --json is only valid with `bcp doctor` or `bcp inspect`."
460
+ "Option --json is only valid with `bcp doctor`, `bcp inspect`, or `bcp config`."
425
461
  );
426
462
  }
427
463
 
@@ -464,6 +500,11 @@ export function parseCliArgs(
464
500
  generateName,
465
501
  }
466
502
  : {}),
503
+ ...(command === "config"
504
+ ? {
505
+ configAction,
506
+ }
507
+ : {}),
467
508
  };
468
509
  }
469
510