@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 +117 -121
- package/docs/api-manifest.json +2 -2
- package/docs/api-reference.md +21 -2
- package/docs/application-packaging.md +243 -0
- package/docs/database-migrations.md +79 -19
- package/docs/database.md +197 -28
- package/docs/deployment.md +94 -7
- package/docs/docs-web-manifest.json +7 -4
- package/docs/platform-manifest.json +24 -5
- package/docs/releases/0.2.3.md +77 -0
- package/docs/releases/0.2.4.md +152 -0
- package/package.json +1 -1
- package/packages/cli/src/application-packaging.ts +1162 -0
- package/packages/cli/src/args.ts +2 -0
- package/packages/cli/src/bootstrap.ts +1 -0
- package/packages/cli/src/database-migrations.ts +91 -21
- package/packages/cli/src/index.ts +60 -2
- 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
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
# Database Migrations
|
|
2
2
|
|
|
3
|
-
BCP
|
|
3
|
+
BCP `0.2.3` extends framework-managed SQL migrations across MySQL, PostgreSQL and SQLite.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Supported providers
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Migration bookkeeping uses the same provider selection as `bcp/database`:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```text
|
|
10
|
+
mysql
|
|
11
|
+
postgresql
|
|
12
|
+
sqlite
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Install the optional driver used by the application:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install mysql2
|
|
19
|
+
npm install pg
|
|
20
|
+
npm install better-sqlite3
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Only one driver is required when the project uses one database provider.
|
|
24
|
+
|
|
25
|
+
## Provider configuration
|
|
26
|
+
|
|
27
|
+
MySQL:
|
|
10
28
|
|
|
11
29
|
```env
|
|
30
|
+
DB_DRIVER=mysql
|
|
12
31
|
DB_HOST=localhost
|
|
13
32
|
DB_PORT=3306
|
|
14
33
|
DB_USER=root
|
|
@@ -16,7 +35,20 @@ DB_PASSWORD=
|
|
|
16
35
|
DB_NAME=bcp_app
|
|
17
36
|
```
|
|
18
37
|
|
|
19
|
-
|
|
38
|
+
PostgreSQL:
|
|
39
|
+
|
|
40
|
+
```env
|
|
41
|
+
DATABASE_URL=postgresql://postgres:password@localhost:5432/bcp_app
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
SQLite:
|
|
45
|
+
|
|
46
|
+
```env
|
|
47
|
+
DB_DRIVER=sqlite
|
|
48
|
+
DATABASE_URL=./data/bcp.sqlite
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Database commands load the development environment before connecting, so migration commands and `bcp dev` use the same provider selection.
|
|
20
52
|
|
|
21
53
|
## Create a migration
|
|
22
54
|
|
|
@@ -24,14 +56,14 @@ A project using migrations must have `mysql2` installed. Applications created wi
|
|
|
24
56
|
bcp db create create_users
|
|
25
57
|
```
|
|
26
58
|
|
|
27
|
-
BCP creates an ordered TypeScript file
|
|
59
|
+
BCP creates an ordered TypeScript file:
|
|
28
60
|
|
|
29
61
|
```text
|
|
30
62
|
migrations/
|
|
31
|
-
|
|
63
|
+
20260829090000_create_users.ts
|
|
32
64
|
```
|
|
33
65
|
|
|
34
|
-
|
|
66
|
+
Generated migrations export `up()` and `down()`:
|
|
35
67
|
|
|
36
68
|
```ts
|
|
37
69
|
import type {
|
|
@@ -43,9 +75,9 @@ export async function up(
|
|
|
43
75
|
): Promise<void> {
|
|
44
76
|
await db.execute(`
|
|
45
77
|
CREATE TABLE users (
|
|
46
|
-
id
|
|
78
|
+
id INTEGER PRIMARY KEY,
|
|
47
79
|
email VARCHAR(255) NOT NULL UNIQUE
|
|
48
|
-
)
|
|
80
|
+
)
|
|
49
81
|
`);
|
|
50
82
|
}
|
|
51
83
|
|
|
@@ -58,7 +90,24 @@ export async function down(
|
|
|
58
90
|
}
|
|
59
91
|
```
|
|
60
92
|
|
|
61
|
-
Migration filenames use a UTC timestamp prefix
|
|
93
|
+
Migration filenames use a UTC timestamp prefix for stable execution order.
|
|
94
|
+
|
|
95
|
+
## SQL dialect responsibility
|
|
96
|
+
|
|
97
|
+
BCP keeps its own `_bcp_migrations` bookkeeping provider-aware, but it does not translate application migration SQL.
|
|
98
|
+
|
|
99
|
+
This means migrations should either:
|
|
100
|
+
|
|
101
|
+
- use SQL supported by every database target used by the application, or
|
|
102
|
+
- intentionally target one provider and use that provider's SQL syntax.
|
|
103
|
+
|
|
104
|
+
Parameter placeholders also follow the active provider:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
MySQL ?
|
|
108
|
+
SQLite ?
|
|
109
|
+
PostgreSQL $1, $2, ...
|
|
110
|
+
```
|
|
62
111
|
|
|
63
112
|
## Run pending migrations
|
|
64
113
|
|
|
@@ -66,9 +115,15 @@ Migration filenames use a UTC timestamp prefix so migrations have a stable execu
|
|
|
66
115
|
bcp db migrate
|
|
67
116
|
```
|
|
68
117
|
|
|
69
|
-
BCP creates
|
|
118
|
+
BCP creates `_bcp_migrations` with provider-specific DDL, detects pending migration files, and executes them in filename order.
|
|
119
|
+
|
|
120
|
+
All migrations applied by one command share the same batch number. Each migration runs inside its own transaction and its bookkeeping record is written in that same transaction.
|
|
70
121
|
|
|
71
|
-
|
|
122
|
+
Provider-specific bookkeeping includes:
|
|
123
|
+
|
|
124
|
+
- MySQL `AUTO_INCREMENT`,
|
|
125
|
+
- PostgreSQL `BIGSERIAL`,
|
|
126
|
+
- SQLite `INTEGER PRIMARY KEY AUTOINCREMENT`.
|
|
72
127
|
|
|
73
128
|
## Check status
|
|
74
129
|
|
|
@@ -84,22 +139,27 @@ The command reports applied and pending migration files together with the batch
|
|
|
84
139
|
bcp db rollback
|
|
85
140
|
```
|
|
86
141
|
|
|
87
|
-
Rollback reverses only the latest migration batch. Migrations
|
|
142
|
+
Rollback reverses only the latest migration batch. Migrations run from newest to oldest and each `down()` executes in a transaction together with deletion of its migration record.
|
|
88
143
|
|
|
89
144
|
BCP refuses to roll back an applied migration when its migration file is missing.
|
|
90
145
|
|
|
91
146
|
## Project root
|
|
92
147
|
|
|
93
|
-
All database commands support the normal
|
|
148
|
+
All database commands support the normal project-root option:
|
|
94
149
|
|
|
95
150
|
```bash
|
|
96
151
|
bcp db status --root ./apps/admin
|
|
97
152
|
```
|
|
98
153
|
|
|
99
|
-
##
|
|
154
|
+
## Database Platform v2 behavior
|
|
100
155
|
|
|
101
|
-
|
|
156
|
+
`0.2.3` keeps migration commands consistent across the built-in SQL providers:
|
|
102
157
|
|
|
103
|
-
|
|
158
|
+
```text
|
|
159
|
+
bcp db create
|
|
160
|
+
bcp db migrate
|
|
161
|
+
bcp db status
|
|
162
|
+
bcp db rollback
|
|
163
|
+
```
|
|
104
164
|
|
|
105
|
-
|
|
165
|
+
The command names and migration file contract stay the same regardless of whether the application uses MySQL, PostgreSQL or SQLite.
|
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.
|
package/docs/deployment.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
npm run build
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
BCP writes the production artifact to `.bcp-framework/build`.
|
|
9
|
+
BCP writes the raw production artifact to `.bcp-framework/build`.
|
|
10
10
|
|
|
11
11
|
```text
|
|
12
12
|
.bcp-framework/build/
|
|
@@ -20,18 +20,79 @@ BCP writes the production artifact to `.bcp-framework/build`.
|
|
|
20
20
|
└─ config.json
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
Use the build directory when the deployment system already manages the application's production dependencies and artifact layout.
|
|
24
|
+
|
|
25
|
+
## Application package — 0.2.4
|
|
26
|
+
|
|
27
|
+
For a deployment-oriented directory, run:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bcp package
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
or from the framework repository/example script surface:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm run package
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`bcp package` runs a fresh production build and creates:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
.bcp-framework/package/
|
|
43
|
+
├─ client/
|
|
44
|
+
├─ server/
|
|
45
|
+
│ └─ server.mjs
|
|
46
|
+
├─ public/ # when present
|
|
47
|
+
├─ manifest.json
|
|
48
|
+
├─ package.json
|
|
49
|
+
├─ package-lock.json # when a safe production lock can be derived
|
|
50
|
+
├─ bcp.package.json
|
|
51
|
+
├─ bcp.deployment.json
|
|
52
|
+
├─ bcp.env.json
|
|
53
|
+
├─ Dockerfile
|
|
54
|
+
├─ .dockerignore
|
|
55
|
+
└─ README.md
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The package manifest excludes development dependencies. With a safely pruned npm v3 lockfile, install runtime dependencies with:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm ci --omit=dev
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If no package lock is included, follow the install command recorded in `bcp.package.json`/`bcp.deployment.json`.
|
|
65
|
+
|
|
66
|
+
BCP does not copy `.env` files into the package. Provide environment values and secrets at deployment/runtime.
|
|
67
|
+
|
|
68
|
+
See [Application Packaging](application-packaging.md) for the full packaging contract.
|
|
69
|
+
|
|
23
70
|
## Start
|
|
24
71
|
|
|
72
|
+
For the raw build:
|
|
73
|
+
|
|
25
74
|
```bash
|
|
26
75
|
npm start
|
|
27
76
|
```
|
|
28
77
|
|
|
29
|
-
|
|
78
|
+
or:
|
|
30
79
|
|
|
31
80
|
```bash
|
|
32
81
|
node .bcp-framework/build/server/server.mjs
|
|
33
82
|
```
|
|
34
83
|
|
|
84
|
+
Inside `.bcp-framework/package`, after production dependencies are installed:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm start
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
which runs:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
node server/server.mjs
|
|
94
|
+
```
|
|
95
|
+
|
|
35
96
|
## Runtime server overrides
|
|
36
97
|
|
|
37
98
|
The build retains the configured server defaults. Deployment can override the public bind address with supported runtime variables:
|
|
@@ -41,22 +102,34 @@ BCP_PORT
|
|
|
41
102
|
BCP_HOSTNAME
|
|
42
103
|
```
|
|
43
104
|
|
|
44
|
-
The CLI also supports:
|
|
105
|
+
The CLI also supports the raw build runtime flow:
|
|
45
106
|
|
|
46
107
|
```bash
|
|
47
108
|
bcp start --port 8080 --hostname 0.0.0.0
|
|
48
109
|
```
|
|
49
110
|
|
|
111
|
+
For a packaged application, provide `BCP_PORT` and `BCP_HOSTNAME` through the runtime environment.
|
|
112
|
+
|
|
50
113
|
## Containers
|
|
51
114
|
|
|
52
|
-
|
|
115
|
+
`bcp package` generates a starter Dockerfile in `.bcp-framework/package`.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cd .bcp-framework/package
|
|
119
|
+
docker build -t my-bcp-app .
|
|
120
|
+
docker run --rm -p 3000:3000 my-bcp-app
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Pass credentials and environment-specific settings through the container/orchestrator environment rather than baking them into the image.
|
|
53
124
|
|
|
54
|
-
|
|
125
|
+
If you deploy the raw `.bcp-framework/build` directory instead, the image must separately include the runtime dependencies required by the generated server bundle, including React/React DOM when they remain external to the bundle.
|
|
55
126
|
|
|
56
127
|
## Reverse proxies
|
|
57
128
|
|
|
58
129
|
BCP can run behind a reverse proxy or tunnel. Forward the original host correctly when application middleware or absolute URL construction depends on host information.
|
|
59
130
|
|
|
131
|
+
Only enable trusted-proxy handling when the application process is actually isolated behind a trusted proxy/load balancer.
|
|
132
|
+
|
|
60
133
|
## Multiple instances
|
|
61
134
|
|
|
62
135
|
The current response/data cache is process-local. If multiple containers or Node.js processes serve the application, each maintains independent cache entries and invalidation state.
|
|
@@ -68,7 +141,21 @@ Before deployment:
|
|
|
68
141
|
```bash
|
|
69
142
|
npm run typecheck
|
|
70
143
|
npm test
|
|
71
|
-
|
|
144
|
+
bcp package
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Then validate the deployment package:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
cd .bcp-framework/package
|
|
151
|
+
npm ci --omit=dev
|
|
152
|
+
npm start
|
|
72
153
|
```
|
|
73
154
|
|
|
74
|
-
|
|
155
|
+
If `bcp.package.json` reports `lockfile: false`, use its recorded install command instead of `npm ci`.
|
|
156
|
+
|
|
157
|
+
For framework releases themselves, use:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npm run rc:check
|
|
161
|
+
```
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"versionTarget": "0.2.
|
|
4
|
+
"versionTarget": "0.2.4",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
6
|
"sections": [
|
|
7
7
|
{
|
|
8
8
|
"id": "getting-started",
|
|
9
9
|
"title": "Getting Started",
|
|
10
|
-
"description": "Create, configure, deploy and update BCP applications.",
|
|
10
|
+
"description": "Create, configure, package, deploy and update BCP applications.",
|
|
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
14
|
{ "route": "/docs/environment-validation", "source": "environment-validation.md", "title": "Environment Validation" },
|
|
15
15
|
{ "route": "/docs/application-modules", "source": "application-modules.md", "title": "Application Modules" },
|
|
16
16
|
{ "route": "/docs/project-metadata", "source": "project-metadata.md", "title": "Project Metadata" },
|
|
17
|
+
{ "route": "/docs/application-packaging", "source": "application-packaging.md", "title": "Application Packaging" },
|
|
17
18
|
{ "route": "/docs/deployment", "source": "deployment.md", "title": "Deployment" },
|
|
18
19
|
{ "route": "/docs/updating", "source": "updating.md", "title": "Updating BCP" }
|
|
19
20
|
]
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
{
|
|
46
47
|
"id": "database",
|
|
47
48
|
"title": "Database",
|
|
48
|
-
"description": "
|
|
49
|
+
"description": "Provider-neutral MySQL, PostgreSQL and SQLite primitives, lifecycle and migrations.",
|
|
49
50
|
"pages": [
|
|
50
51
|
{ "route": "/docs/database", "source": "database.md", "title": "Database" },
|
|
51
52
|
{ "route": "/docs/database-migrations", "source": "database-migrations.md", "title": "Database Migrations" }
|
|
@@ -104,7 +105,9 @@
|
|
|
104
105
|
}
|
|
105
106
|
],
|
|
106
107
|
"releases": [
|
|
107
|
-
{ "route": "/releases/0.2.
|
|
108
|
+
{ "route": "/releases/0.2.4", "source": "releases/0.2.4.md", "version": "0.2.4", "state": "unreleased" },
|
|
109
|
+
{ "route": "/releases/0.2.3", "source": "releases/0.2.3.md", "version": "0.2.3" },
|
|
110
|
+
{ "route": "/releases/0.2.2", "source": "releases/0.2.2.md", "version": "0.2.2" },
|
|
108
111
|
{ "route": "/releases/0.2.1", "source": "releases/0.2.1.md", "version": "0.2.1" },
|
|
109
112
|
{ "route": "/releases/0.2.0", "source": "releases/0.2.0.md", "version": "0.2.0" },
|
|
110
113
|
{ "route": "/releases/0.1.29", "source": "releases/0.1.29.md", "version": "0.1.29" },
|