@chidchanun/bcp 0.2.1 → 0.2.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 +255 -211
- package/docs/README.md +118 -79
- package/docs/api-manifest.json +5 -4
- package/docs/api-reference.md +33 -4
- package/docs/configuration.md +96 -1
- package/docs/database-migrations.md +79 -19
- package/docs/database.md +197 -28
- package/docs/docs-web-manifest.json +6 -3
- package/docs/environment-validation.md +224 -0
- package/docs/platform-manifest.json +20 -5
- package/docs/releases/0.2.2.md +118 -0
- package/docs/releases/0.2.3.md +77 -0
- package/package.json +1 -1
- package/packages/cli/src/args.ts +50 -9
- package/packages/cli/src/bootstrap.ts +22 -7
- package/packages/cli/src/configuration.ts +235 -0
- package/packages/cli/src/database-migrations.ts +91 -21
- package/packages/cli/src/index.ts +101 -1
- package/packages/client/src/config.ts +26 -0
- package/packages/client/src/database-mysql.ts +291 -0
- package/packages/client/src/database-postgresql.ts +355 -0
- package/packages/client/src/database-sqlite.ts +445 -0
- package/packages/client/src/database.mjs +709 -57
- package/packages/client/src/database.ts +347 -182
- package/packages/config/src/diagnostics.ts +226 -0
- package/packages/config/src/environment-loader.ts +101 -0
- package/packages/config/src/environment-schema.ts +677 -0
package/docs/database.md
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
# Database
|
|
2
2
|
|
|
3
|
-
BCP `0.
|
|
3
|
+
BCP `0.2.3` completes Database Platform v2 behind the server-only `bcp/database` entrypoint.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The public database facade is provider-neutral and currently includes built-in adapters for:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- MySQL,
|
|
8
|
+
- PostgreSQL,
|
|
9
|
+
- SQLite.
|
|
10
|
+
|
|
11
|
+
Applications can keep the same `db.query()`, `db.execute()`, `db.transaction()` and lifecycle API while selecting the provider through environment or explicit options.
|
|
12
|
+
|
|
13
|
+
## MySQL
|
|
14
|
+
|
|
15
|
+
Install the optional driver:
|
|
8
16
|
|
|
9
17
|
```bash
|
|
10
|
-
|
|
18
|
+
npm install mysql2
|
|
11
19
|
```
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
## Environment
|
|
21
|
+
Environment:
|
|
16
22
|
|
|
17
23
|
```env
|
|
18
24
|
DB_DRIVER=mysql
|
|
@@ -22,20 +28,105 @@ DB_USER=root
|
|
|
22
28
|
DB_PASSWORD=
|
|
23
29
|
DB_NAME=bcp_app
|
|
24
30
|
DB_CONNECTION_LIMIT=10
|
|
25
|
-
DB_WAIT_FOR_CONNECTIONS=1
|
|
26
|
-
DB_QUEUE_LIMIT=0
|
|
27
|
-
DB_CHARSET=utf8mb4
|
|
28
31
|
```
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
MySQL remains the default when no provider can be inferred.
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
Parameterized query:
|
|
33
36
|
|
|
34
37
|
```ts
|
|
35
38
|
import {
|
|
36
39
|
db,
|
|
37
40
|
} from "bcp/database";
|
|
38
41
|
|
|
42
|
+
const users =
|
|
43
|
+
await db.query(
|
|
44
|
+
"SELECT id, email FROM users WHERE active = ?",
|
|
45
|
+
[
|
|
46
|
+
1,
|
|
47
|
+
]
|
|
48
|
+
);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## PostgreSQL
|
|
52
|
+
|
|
53
|
+
Install the optional driver:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install pg
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
BCP can infer PostgreSQL from a connection URL:
|
|
60
|
+
|
|
61
|
+
```env
|
|
62
|
+
DATABASE_URL=postgresql://postgres:password@localhost:5432/bcp_app
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
or use explicit fields:
|
|
66
|
+
|
|
67
|
+
```env
|
|
68
|
+
DB_DRIVER=postgresql
|
|
69
|
+
DB_HOST=localhost
|
|
70
|
+
DB_PORT=5432
|
|
71
|
+
DB_USER=postgres
|
|
72
|
+
DB_PASSWORD=password
|
|
73
|
+
DB_NAME=bcp_app
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
PostgreSQL parameters use `$1`, `$2`, and later placeholders:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const users =
|
|
80
|
+
await db.query(
|
|
81
|
+
"SELECT id, email FROM users WHERE active = $1",
|
|
82
|
+
[
|
|
83
|
+
true,
|
|
84
|
+
]
|
|
85
|
+
);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`postgres` and `pg` are accepted as environment aliases for the PostgreSQL driver and are normalized to `postgresql`.
|
|
89
|
+
|
|
90
|
+
## SQLite
|
|
91
|
+
|
|
92
|
+
Install the optional driver:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npm install better-sqlite3
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Recommended environment:
|
|
99
|
+
|
|
100
|
+
```env
|
|
101
|
+
DB_DRIVER=sqlite
|
|
102
|
+
DATABASE_URL=./data/bcp.sqlite
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
BCP also recognizes `:memory:`, `sqlite:` / `file:` URLs and common `.sqlite`, `.sqlite3`, and `.db` file names.
|
|
106
|
+
|
|
107
|
+
Example:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import {
|
|
111
|
+
createDatabase,
|
|
112
|
+
} from "bcp/database";
|
|
113
|
+
|
|
114
|
+
const database =
|
|
115
|
+
createDatabase({
|
|
116
|
+
driver:
|
|
117
|
+
"sqlite",
|
|
118
|
+
database:
|
|
119
|
+
"./data/app.sqlite",
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
SQLite operations are serialized by the built-in adapter so async transaction callbacks cannot interleave unrelated queries on the same native connection.
|
|
124
|
+
|
|
125
|
+
## Query and execute
|
|
126
|
+
|
|
127
|
+
`query<T>()` is intended for row-returning statements:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
39
130
|
interface UserRow {
|
|
40
131
|
id: number;
|
|
41
132
|
email: string;
|
|
@@ -43,28 +134,27 @@ interface UserRow {
|
|
|
43
134
|
|
|
44
135
|
const users =
|
|
45
136
|
await db.query<UserRow[]>(
|
|
46
|
-
"SELECT id, email FROM users
|
|
47
|
-
[
|
|
48
|
-
1,
|
|
49
|
-
]
|
|
137
|
+
"SELECT id, email FROM users"
|
|
50
138
|
);
|
|
51
139
|
```
|
|
52
140
|
|
|
53
|
-
|
|
141
|
+
`execute<T>()` is intended for mutations and DDL:
|
|
54
142
|
|
|
55
143
|
```ts
|
|
56
144
|
const result =
|
|
57
145
|
await db.execute(
|
|
58
|
-
"
|
|
146
|
+
"DELETE FROM sessions WHERE expired_at < ?",
|
|
59
147
|
[
|
|
60
|
-
|
|
148
|
+
new Date(),
|
|
61
149
|
]
|
|
62
150
|
);
|
|
63
151
|
```
|
|
64
152
|
|
|
65
|
-
Use
|
|
153
|
+
Use the placeholder syntax of the active database provider. BCP does not rewrite application SQL between dialects.
|
|
66
154
|
|
|
67
|
-
##
|
|
155
|
+
## Transactions
|
|
156
|
+
|
|
157
|
+
The transaction callback receives a provider-scoped `TransactionDatabase`:
|
|
68
158
|
|
|
69
159
|
```ts
|
|
70
160
|
await db.transaction(
|
|
@@ -88,7 +178,33 @@ await db.transaction(
|
|
|
88
178
|
);
|
|
89
179
|
```
|
|
90
180
|
|
|
91
|
-
|
|
181
|
+
The example above uses MySQL/SQLite placeholders. PostgreSQL migrations and application statements should use `$1`, `$2`, and so on.
|
|
182
|
+
|
|
183
|
+
BCP commits when the callback resolves and rolls back when it throws.
|
|
184
|
+
|
|
185
|
+
## Connection lifecycle
|
|
186
|
+
|
|
187
|
+
Database instances remain lazy by default. Importing `bcp/database` does not connect to a provider.
|
|
188
|
+
|
|
189
|
+
BCP `0.2.3` adds explicit lifecycle methods:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
await db.connect();
|
|
193
|
+
|
|
194
|
+
// application work
|
|
195
|
+
|
|
196
|
+
await db.disconnect();
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`close()` remains available as the backward-compatible shutdown method and is equivalent to `disconnect()`:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
await db.close();
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
After disconnecting, the next operation or `connect()` call creates a fresh adapter connection/pool.
|
|
206
|
+
|
|
207
|
+
If adapter initialization fails, BCP resets the pending lifecycle state so a later attempt can retry cleanly. Calling `close()` after a failed initialization is safe.
|
|
92
208
|
|
|
93
209
|
## Custom database instance
|
|
94
210
|
|
|
@@ -99,6 +215,8 @@ import {
|
|
|
99
215
|
|
|
100
216
|
export const reportingDb =
|
|
101
217
|
createDatabase({
|
|
218
|
+
driver:
|
|
219
|
+
"postgresql",
|
|
102
220
|
host:
|
|
103
221
|
"reporting-db.internal",
|
|
104
222
|
database:
|
|
@@ -110,18 +228,69 @@ export const reportingDb =
|
|
|
110
228
|
|
|
111
229
|
Explicit options override environment values for that database instance.
|
|
112
230
|
|
|
113
|
-
##
|
|
231
|
+
## Database adapter contract
|
|
114
232
|
|
|
115
|
-
|
|
233
|
+
Provider implementations use the shared adapter contract:
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
import type {
|
|
237
|
+
DatabaseAdapter,
|
|
238
|
+
TransactionDatabase,
|
|
239
|
+
} from "bcp/database";
|
|
116
240
|
|
|
117
|
-
|
|
241
|
+
const adapter: DatabaseAdapter = {
|
|
242
|
+
driver: "custom",
|
|
243
|
+
|
|
244
|
+
async connect() {},
|
|
245
|
+
|
|
246
|
+
async query<T>(sql, parameters) {
|
|
247
|
+
throw new Error("Not implemented");
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
async execute<T>(sql, parameters) {
|
|
251
|
+
throw new Error("Not implemented");
|
|
252
|
+
},
|
|
253
|
+
|
|
254
|
+
async transaction<T>(
|
|
255
|
+
callback: (
|
|
256
|
+
database: TransactionDatabase
|
|
257
|
+
) => Promise<T>
|
|
258
|
+
) {
|
|
259
|
+
throw new Error("Not implemented");
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
async disconnect() {},
|
|
263
|
+
};
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Inject an adapter directly or through a lazy factory:
|
|
118
267
|
|
|
119
268
|
```ts
|
|
120
|
-
|
|
269
|
+
export const customDb =
|
|
270
|
+
createDatabase({
|
|
271
|
+
adapter: () => adapter,
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The contract lets future providers integrate without changing application-facing database calls.
|
|
276
|
+
|
|
277
|
+
## Migrations
|
|
278
|
+
|
|
279
|
+
Framework migration bookkeeping supports MySQL, PostgreSQL and SQLite in `0.2.3`.
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
bcp db create create_users
|
|
283
|
+
bcp db migrate
|
|
284
|
+
bcp db status
|
|
285
|
+
bcp db rollback
|
|
121
286
|
```
|
|
122
287
|
|
|
288
|
+
BCP selects the internal migration-table dialect from the same active database environment. Migration files themselves remain normal provider SQL and are not automatically translated between SQL dialects.
|
|
289
|
+
|
|
290
|
+
Read more: [Database Migrations](database-migrations.md)
|
|
291
|
+
|
|
123
292
|
## Server-only boundary
|
|
124
293
|
|
|
125
|
-
`bcp/database` is a server-only package export. Importing it into a browser bundle is blocked by the framework
|
|
294
|
+
`bcp/database` is a server-only package export. Importing it into a browser bundle is blocked by the framework browser export boundary.
|
|
126
295
|
|
|
127
|
-
|
|
296
|
+
Provider drivers are optional and loaded lazily. Projects only need to install the driver they actually use.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"versionTarget": "0.2.
|
|
4
|
+
"versionTarget": "0.2.3",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
6
|
"sections": [
|
|
7
7
|
{
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"pages": [
|
|
12
12
|
{ "route": "/docs/getting-started", "source": "getting-started.md", "title": "Getting Started" },
|
|
13
13
|
{ "route": "/docs/configuration", "source": "configuration.md", "title": "Configuration" },
|
|
14
|
+
{ "route": "/docs/environment-validation", "source": "environment-validation.md", "title": "Environment Validation" },
|
|
14
15
|
{ "route": "/docs/application-modules", "source": "application-modules.md", "title": "Application Modules" },
|
|
15
16
|
{ "route": "/docs/project-metadata", "source": "project-metadata.md", "title": "Project Metadata" },
|
|
16
17
|
{ "route": "/docs/deployment", "source": "deployment.md", "title": "Deployment" },
|
|
@@ -44,7 +45,7 @@
|
|
|
44
45
|
{
|
|
45
46
|
"id": "database",
|
|
46
47
|
"title": "Database",
|
|
47
|
-
"description": "
|
|
48
|
+
"description": "Provider-neutral MySQL, PostgreSQL and SQLite primitives, lifecycle and migrations.",
|
|
48
49
|
"pages": [
|
|
49
50
|
{ "route": "/docs/database", "source": "database.md", "title": "Database" },
|
|
50
51
|
{ "route": "/docs/database-migrations", "source": "database-migrations.md", "title": "Database Migrations" }
|
|
@@ -103,7 +104,9 @@
|
|
|
103
104
|
}
|
|
104
105
|
],
|
|
105
106
|
"releases": [
|
|
106
|
-
{ "route": "/releases/0.2.
|
|
107
|
+
{ "route": "/releases/0.2.3", "source": "releases/0.2.3.md", "version": "0.2.3", "state": "unreleased" },
|
|
108
|
+
{ "route": "/releases/0.2.2", "source": "releases/0.2.2.md", "version": "0.2.2" },
|
|
109
|
+
{ "route": "/releases/0.2.1", "source": "releases/0.2.1.md", "version": "0.2.1" },
|
|
107
110
|
{ "route": "/releases/0.2.0", "source": "releases/0.2.0.md", "version": "0.2.0" },
|
|
108
111
|
{ "route": "/releases/0.1.29", "source": "releases/0.1.29.md", "version": "0.1.29" },
|
|
109
112
|
{ "route": "/releases/0.1.28", "source": "releases/0.1.28.md", "version": "0.1.28" },
|
|
@@ -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,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.3",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
|
-
"baseline": "
|
|
6
|
+
"baseline": "database-platform-v2",
|
|
7
7
|
"runtime": {
|
|
8
8
|
"node": ">=24.11.0",
|
|
9
9
|
"react": "19",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"update",
|
|
31
31
|
"db",
|
|
32
32
|
"generate",
|
|
33
|
+
"config",
|
|
33
34
|
"doctor",
|
|
34
35
|
"inspect",
|
|
35
36
|
"help",
|
|
@@ -45,6 +46,11 @@
|
|
|
45
46
|
"middlewareV2": true,
|
|
46
47
|
"jwtCookieSessions": true,
|
|
47
48
|
"databaseMigrations": true,
|
|
49
|
+
"databaseAdapterContract": true,
|
|
50
|
+
"databasePostgresql": true,
|
|
51
|
+
"databaseSqlite": true,
|
|
52
|
+
"databaseLifecycleV2": true,
|
|
53
|
+
"databaseMigrationProviderConsistency": true,
|
|
48
54
|
"validation": true,
|
|
49
55
|
"structuredErrors": true,
|
|
50
56
|
"logging": true,
|
|
@@ -55,8 +61,16 @@
|
|
|
55
61
|
"projectGenerators": true,
|
|
56
62
|
"projectDiagnostics": true,
|
|
57
63
|
"documentationPlatform": true,
|
|
58
|
-
"apiManifest": true
|
|
64
|
+
"apiManifest": true,
|
|
65
|
+
"typedEnvironmentSchema": true,
|
|
66
|
+
"configurationDiagnostics": true,
|
|
67
|
+
"configCheckCli": true
|
|
59
68
|
},
|
|
69
|
+
"databaseProviders": [
|
|
70
|
+
"mysql",
|
|
71
|
+
"postgresql",
|
|
72
|
+
"sqlite"
|
|
73
|
+
],
|
|
60
74
|
"storageProviders": [
|
|
61
75
|
"local",
|
|
62
76
|
"amazon-s3",
|
|
@@ -64,7 +78,7 @@
|
|
|
64
78
|
"s3-compatible"
|
|
65
79
|
],
|
|
66
80
|
"compatibility": {
|
|
67
|
-
"previousBaseline": "0.2.
|
|
81
|
+
"previousBaseline": "0.2.2",
|
|
68
82
|
"intentionalBreakingChangesFromPreviousBaseline": false,
|
|
69
83
|
"migrationGuide": "migration-0.2.md"
|
|
70
84
|
},
|
|
@@ -75,7 +89,8 @@
|
|
|
75
89
|
"platformContract": "platform-contract.md",
|
|
76
90
|
"documentationPlatform": "documentation-platform.md",
|
|
77
91
|
"apiReference": "api-reference.md",
|
|
92
|
+
"environmentValidation": "environment-validation.md",
|
|
78
93
|
"migrationGuide": "migration-0.2.md",
|
|
79
|
-
"releaseNotes": "releases/0.2.
|
|
94
|
+
"releaseNotes": "releases/0.2.3.md"
|
|
80
95
|
}
|
|
81
96
|
}
|