create-bcp-app 0.2.10 → 0.2.12

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.
Files changed (3) hide show
  1. package/README.md +91 -202
  2. package/package.json +1 -1
  3. package/template/README.md +81 -128
package/README.md CHANGED
@@ -28,16 +28,6 @@ Generated npm scripts use `bcp` because npm places `node_modules/.bin` on the sc
28
28
  }
29
29
  ```
30
30
 
31
- When Tailwind CSS is selected, the generated packaging script preserves the production CSS step:
32
-
33
- ```json
34
- {
35
- "scripts": {
36
- "package": "npm run css:build:prod && bcp package"
37
- }
38
- }
39
- ```
40
-
41
31
  For direct PowerShell usage, prefer the collision-free local alias:
42
32
 
43
33
  ```powershell
@@ -75,27 +65,21 @@ Select storage provider:
75
65
  Cloudflare R2
76
66
  ```
77
67
 
78
- Equivalent non-interactive flags are available for CI/scaffolding automation.
79
-
80
68
  ## Generated project metadata
81
69
 
82
- New projects include:
83
-
84
- ```text
85
- bcp.project.json
86
- ```
70
+ New projects include `bcp.project.json`.
87
71
 
88
- Example:
72
+ Example for the `0.2.12` target:
89
73
 
90
74
  ```json
91
75
  {
92
76
  "schemaVersion": 1,
93
77
  "framework": "bcp",
94
78
  "projectName": "my-app",
95
- "frameworkPackage": "npm:@chidchanun/bcp@0.2.10",
79
+ "frameworkPackage": "npm:@chidchanun/bcp@0.2.12",
96
80
  "createdWith": {
97
81
  "package": "create-bcp-app",
98
- "version": "0.2.10"
82
+ "version": "0.2.12"
99
83
  },
100
84
  "packageManager": "npm",
101
85
  "presets": {
@@ -109,43 +93,9 @@ Example:
109
93
 
110
94
  This manifest records scaffold identity only. It must not contain secrets and should normally be committed to source control.
111
95
 
112
- ## Generated application defaults
113
-
114
- Generated applications include the project-root `@/` alias and TypeScript settings compatible with the BCP bundler.
115
-
116
- Modules that use React client hooks such as `useState` or `useEffect` must declare `"use client"` at the top of the module.
117
-
118
- The generated BCP dependency is pinned to the exact framework release selected by the generator.
119
-
120
- Update later with:
121
-
122
- ```bash
123
- npm run update
124
- ```
125
-
126
- Check without modifying files:
127
-
128
- ```powershell
129
- npm exec -- bcp-framework update --check
130
- ```
131
-
132
- ## Tailwind CSS
133
-
134
- When Tailwind is enabled, the project includes `tailwindcss`, `@tailwindcss/cli`, `concurrently`, `app/globals.css`, `/bcp.css` stylesheet setup and starter utility classes.
135
-
136
- Generated commands include:
137
-
138
- ```text
139
- npm run css:build
140
- npm run css:watch
141
- npm run css:build:prod
142
- ```
143
-
144
- `npm run build` and `npm run package` create the production stylesheet before the BCP production build/package flow.
145
-
146
96
  ## Database presets
147
97
 
148
- The database choice adds starter configuration and the matching driver:
98
+ Database choices add starter configuration and the matching driver:
149
99
 
150
100
  - MySQL: `mysql2`
151
101
  - PostgreSQL: `pg`
@@ -153,71 +103,31 @@ The database choice adds starter configuration and the matching driver:
153
103
  - MongoDB: `mongodb`
154
104
  - None: no database dependency
155
105
 
156
- For **MySQL**, **PostgreSQL** and **SQLite**, generated `lib/database.ts` exposes framework database primitives through `bcp/database`.
106
+ For MySQL, PostgreSQL and SQLite, generated `lib/database.ts` exposes BCP database primitives through `bcp/database`.
157
107
 
158
- The generator intentionally does not force an ORM.
108
+ ## Authentication and security
159
109
 
160
- ## Storage providers
161
-
162
- Selecting a storage provider creates `lib/storage.ts` and provider-specific environment settings. Supported presets are Local Server, Amazon S3 and Cloudflare R2.
163
-
164
- Storage credentials are server-only. Do not expose them through `BCP_PUBLIC_*` variables.
165
-
166
- ## JWT Cookie authentication
167
-
168
- Selecting `JWT Cookie` creates `lib/auth.ts` and starter `/api/auth/login`, `/logout` and `/me` routes, and adds:
169
-
170
- ```dotenv
171
- BCP_SESSION_SECRET=
172
- ```
110
+ The JWT Cookie preset creates `lib/auth.ts` and starter auth routes. BCP `0.2.5+` supports optional revocable server-side auth state, while `0.2.6+` adds permission/policy authorization plus same-origin/CSRF helpers.
173
111
 
174
- Set this to a cryptographically random secret of at least 32 bytes before real authentication use.
175
-
176
- BCP `0.2.5+` can opt into revocable server-side auth state through `AuthSessionStore`.
177
-
178
- ## Authorization & request security — 0.2.6+
179
-
180
- Generated applications can use permission guards and resource policies from `bcp/auth`, plus same-origin and CSRF protection from `bcp/server`.
181
-
182
- Authorization and CSRF checks must remain on the server; hiding UI controls in client code is not an authorization boundary.
183
-
184
- ## Observability — 0.2.7+
185
-
186
- Generated projects can opt into process-local metrics and health/readiness without adding another dependency:
112
+ ## Observability
187
113
 
188
114
  ```ts
189
115
  import {
190
116
  createHealthRegistry,
191
117
  createMetricsRegistry,
192
- createRequestMetricsMiddleware,
193
118
  } from "bcp/observability";
194
119
  ```
195
120
 
196
- `bcp/observability` is server-only. Protect metrics and operational health detail with an appropriate network or authorization boundary when needed.
197
-
198
- ## Background jobs — 0.2.8+
199
-
200
- Generated projects can create a server-only background job queue:
121
+ ## Background jobs and scheduling
201
122
 
202
123
  ```ts
203
124
  import {
204
125
  createJobQueue,
126
+ createJobScheduler,
205
127
  } from "bcp/jobs";
206
128
 
207
129
  export const jobs =
208
130
  createJobQueue();
209
- ```
210
-
211
- Workers support concurrency, delayed jobs, retry/backoff and cancellation.
212
-
213
- ## Job scheduling — 0.2.9+
214
-
215
- Recurring schedules use the same `bcp/jobs` entrypoint:
216
-
217
- ```ts
218
- import {
219
- createJobScheduler,
220
- } from "bcp/jobs";
221
131
 
222
132
  export const scheduler =
223
133
  createJobScheduler({
@@ -225,129 +135,117 @@ export const scheduler =
225
135
  });
226
136
  ```
227
137
 
228
- Interval schedule:
138
+ `0.2.10+` adds visibility leases, heartbeat renewal, stale-running recovery, DLQ/requeue, retention cleanup and Redis-compatible durable adapters.
229
139
 
230
- ```ts
231
- await scheduler.schedule(
232
- "cache.cleanup",
233
- {},
234
- {
235
- everyMs: 300_000,
236
- }
237
- );
238
- ```
239
-
240
- UTC cron schedule:
140
+ ## Workflow orchestration — 0.2.11+
241
141
 
242
142
  ```ts
243
- await scheduler.schedule(
244
- "report.weekday",
245
- {},
246
- {
247
- cron: "30 9 * * 1-5",
248
- }
249
- );
143
+ import {
144
+ createWorkflow,
145
+ } from "bcp/workflow";
146
+
147
+ export const onboarding =
148
+ createWorkflow(
149
+ "user.onboarding",
150
+ workflow => {
151
+ workflow.step(
152
+ "profile",
153
+ createProfile
154
+ );
155
+ workflow.delay(
156
+ "cooldown",
157
+ 1_000
158
+ );
159
+ }
160
+ );
250
161
  ```
251
162
 
252
- ## Durable jobs 0.2.10+
253
-
254
- BCP `0.2.10` adds worker visibility leases, heartbeat renewal, stale-running recovery, DLQ/requeue, retention cleanup and queue statistics.
163
+ `bcp/workflow` supports sequential/parallel steps, retry, persisted delays, compensation and optional execution through `bcp/jobs`.
255
164
 
256
- ```ts
257
- const worker =
258
- jobs.startWorker({
259
- workerId: "worker-a",
260
- concurrency: 4,
261
- visibilityTimeoutMs: 30_000,
262
- heartbeatIntervalMs: 10_000,
263
- });
264
- ```
165
+ ## Transactional Outbox & Events — 0.2.12+
265
166
 
266
- Inspect failed jobs:
167
+ Applications using the SQL Database Platform can persist integration events in the same transaction as business data:
267
168
 
268
169
  ```ts
269
- const deadLetters =
270
- await jobs.deadLetters();
271
- ```
170
+ import {
171
+ db,
172
+ } from "bcp/database";
173
+
174
+ import {
175
+ createSqlOutboxStore,
176
+ createTransactionalOutbox,
177
+ } from "bcp/events";
178
+
179
+ const outboxStore =
180
+ createSqlOutboxStore({
181
+ database: db,
182
+ driver: "mysql",
183
+ });
272
184
 
273
- Requeue:
185
+ const outbox =
186
+ createTransactionalOutbox({
187
+ store: outboxStore,
188
+ });
274
189
 
275
- ```ts
276
- await jobs.requeueDeadLetter(
277
- deadLetters[0].id,
278
- {
279
- resetAttempts: true,
190
+ await db.transaction(
191
+ async tx => {
192
+ await tx.execute(
193
+ "INSERT INTO orders ..."
194
+ );
195
+
196
+ await outbox.publish(
197
+ tx,
198
+ "order.created",
199
+ {
200
+ orderId: 42,
201
+ }
202
+ );
280
203
  }
281
204
  );
282
205
  ```
283
206
 
284
- ### Redis-compatible durable adapters
285
-
286
- BCP intentionally does not install a Redis client library. Applications own the Redis connection and pass a minimal command client to BCP:
287
-
288
- ```ts
289
- interface RedisCommandClient {
290
- sendCommand(
291
- command: string[]
292
- ): Promise<unknown>;
293
- }
294
- ```
295
-
296
- Queue adapter:
207
+ Create migration SQL with:
297
208
 
298
209
  ```ts
299
210
  import {
300
- createJobQueue,
301
- createRedisJobQueueAdapter,
302
- } from "bcp/jobs";
303
-
304
- const adapter =
305
- createRedisJobQueueAdapter({
306
- client: redisCommandClient,
307
- namespace: "my-app:{jobs}",
308
- });
211
+ createOutboxMigrationSql,
212
+ } from "bcp/events";
309
213
 
310
- export const jobs =
311
- createJobQueue({
312
- adapter,
313
- });
214
+ const migrationSql =
215
+ createOutboxMigrationSql(
216
+ "mysql"
217
+ );
314
218
  ```
315
219
 
316
- Scheduler store:
220
+ After commit, dispatch to the durable job queue:
317
221
 
318
222
  ```ts
319
223
  import {
320
- createJobScheduler,
321
- createRedisJobScheduleStore,
322
- } from "bcp/jobs";
323
-
324
- const store =
325
- createRedisJobScheduleStore({
326
- client: redisCommandClient,
327
- namespace: "my-app:{jobs}",
328
- });
224
+ createOutboxDispatcher,
225
+ } from "bcp/events";
329
226
 
330
- export const scheduler =
331
- createJobScheduler({
227
+ const dispatcher =
228
+ createOutboxDispatcher({
229
+ store: outboxStore,
332
230
  queue: jobs,
333
- store,
334
- ownerId: "scheduler-a",
231
+ ownerId: "outbox-a",
335
232
  });
233
+
234
+ const runner =
235
+ dispatcher.start();
336
236
  ```
337
237
 
338
- A typical application may configure its Redis client with:
238
+ Event type `order.created` is handed off to queue name `event.order.created`.
339
239
 
340
- ```dotenv
341
- REDIS_URL=redis://localhost:6379
342
- ```
240
+ The outbox dispatcher supports leases, stale recovery, retry/backoff, custom publishers, a local EventBus, cleanup and statistics.
343
241
 
344
- BCP does not read `REDIS_URL` automatically. Redis credentials, TLS/Cluster/Sentinel configuration and connection lifecycle stay application-owned.
242
+ `bcp/events` is server-only. The SQL outbox protects the database-commit/external-publish boundary, but downstream delivery remains at-least-once, so non-repeatable side effects should use idempotency protection.
345
243
 
346
- `bcp/jobs` is server-only and must not be imported into page/client bundles.
244
+ ## Storage providers
347
245
 
348
- ## Application Packaging 0.2.4+
246
+ Supported presets are Local Server, Amazon S3 and Cloudflare R2. Storage credentials are server-only and must not use `BCP_PUBLIC_*` variables.
349
247
 
350
- Generated projects include:
248
+ ## Application packaging
351
249
 
352
250
  ```bash
353
251
  npm run package
@@ -355,7 +253,7 @@ npm run package
355
253
 
356
254
  The deployment package excludes application `devDependencies` and project `.env` values. Supply real secrets through the deployment environment.
357
255
 
358
- ## Project generators after creation
256
+ ## Project generators
359
257
 
360
258
  ```bash
361
259
  npm run generate -- page dashboard/users
@@ -364,15 +262,6 @@ npm run generate -- middleware
364
262
  npm run generate -- migration create_users
365
263
  ```
366
264
 
367
- Equivalent direct CLI:
368
-
369
- ```bash
370
- bcp generate page dashboard/users
371
- bcp generate api users
372
- bcp generate middleware
373
- bcp generate migration create_users
374
- ```
375
-
376
265
  ## Options
377
266
 
378
267
  ```text
@@ -387,8 +276,8 @@ bcp generate migration create_users
387
276
  -h, --help Show help
388
277
  ```
389
278
 
390
- The `--bcp` option is mainly for prerelease/local package verification:
279
+ For prerelease/local package verification:
391
280
 
392
281
  ```bash
393
- npx create-bcp-app my-app --bcp file:../chidchanun-bcp-0.2.10.tgz
282
+ npx create-bcp-app my-app --bcp file:../chidchanun-bcp-0.2.12.tgz
394
283
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-bcp-app",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Create a new BCP Framework application.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -12,8 +12,6 @@ Open `http://localhost:3000`.
12
12
 
13
13
  ## Project commands
14
14
 
15
- Generated projects use the project-local BCP Framework CLI through npm scripts:
16
-
17
15
  ```bash
18
16
  npm run dev
19
17
  npm run routes
@@ -25,25 +23,17 @@ npm start
25
23
  npm run update
26
24
  ```
27
25
 
28
- The generated scripts call commands such as `bcp dev`, `bcp generate`, `bcp build`, `bcp package` and `bcp start`.
29
-
30
26
  ## Project metadata
31
27
 
32
- Projects created with BCP `0.1.29+` include `bcp.project.json` with non-secret scaffold metadata.
33
-
34
- Commit this file with the project. Do not put passwords, access keys, session secrets or tokens in it.
28
+ Generated projects include `bcp.project.json` with non-secret scaffold metadata. Commit it with the project, but never put passwords, tokens or access keys in it.
35
29
 
36
30
  ## Authentication — BCP 0.2.5+
37
31
 
38
- Projects created with the `JWT Cookie` preset remain stateless by default and use the generated `lib/auth.ts` helpers.
39
-
40
- BCP Authentication Platform v2 can opt into revocable server-side session state with `createAuth()` and `AuthSessionStore`.
32
+ JWT Cookie projects can opt into revocable server-side session state with `createAuth()` and `AuthSessionStore`.
41
33
 
42
34
  ## Authorization & request security — BCP 0.2.6+
43
35
 
44
- Use permission guards and resource policies from `bcp/auth`, and same-origin/CSRF protection from `bcp/server`.
45
-
46
- Authorization must always be enforced server-side. Client UI visibility is not a security boundary.
36
+ Use permission guards/resource policies from `bcp/auth`, and same-origin/CSRF protection from `bcp/server`. Authorization must remain server-side.
47
37
 
48
38
  ## Observability — BCP 0.2.7+
49
39
 
@@ -51,16 +41,11 @@ Authorization must always be enforced server-side. Client UI visibility is not a
51
41
  import {
52
42
  createHealthRegistry,
53
43
  createMetricsRegistry,
54
- createRequestMetricsMiddleware,
55
44
  } from "bcp/observability";
56
45
  ```
57
46
 
58
- Protect operational endpoints when their contents should not be public.
59
-
60
47
  ## Background jobs — BCP 0.2.8+
61
48
 
62
- Create a server-only background queue:
63
-
64
49
  ```ts
65
50
  import {
66
51
  createJobQueue,
@@ -70,21 +55,6 @@ export const jobs =
70
55
  createJobQueue();
71
56
  ```
72
57
 
73
- Register typed work:
74
-
75
- ```ts
76
- jobs.register<{
77
- userId: number;
78
- }>(
79
- "email.welcome",
80
- async ({ payload }) => {
81
- await sendWelcomeEmail(
82
- payload.userId
83
- );
84
- }
85
- );
86
- ```
87
-
88
58
  ## Job scheduling — BCP 0.2.9+
89
59
 
90
60
  ```ts
@@ -98,21 +68,9 @@ export const scheduler =
98
68
  });
99
69
  ```
100
70
 
101
- Example UTC cron schedule:
102
-
103
- ```ts
104
- await scheduler.schedule(
105
- "report.weekday",
106
- {},
107
- {
108
- cron: "30 9 * * 1-5",
109
- }
110
- );
111
- ```
112
-
113
71
  ## Durable jobs — BCP 0.2.10+
114
72
 
115
- Workers can use visibility leases, heartbeat renewal and stale-running recovery:
73
+ Workers can use visibility leases, heartbeat renewal, stale recovery and DLQ/requeue. Redis-compatible adapters are available without forcing a Redis client dependency.
116
74
 
117
75
  ```ts
118
76
  const worker =
@@ -124,97 +82,109 @@ const worker =
124
82
  });
125
83
  ```
126
84
 
127
- Retry-exhausted jobs are available through the adapter DLQ contract:
85
+ ## Workflow orchestration BCP 0.2.11+
128
86
 
129
87
  ```ts
130
- const deadLetters =
131
- await jobs.deadLetters();
88
+ import {
89
+ createWorkflow,
90
+ } from "bcp/workflow";
132
91
 
133
- await jobs.requeueDeadLetter(
134
- deadLetters[0].id,
135
- {
136
- resetAttempts: true,
137
- }
138
- );
92
+ export const onboarding =
93
+ createWorkflow(
94
+ "user.onboarding",
95
+ workflow => {
96
+ workflow.step(
97
+ "profile",
98
+ createProfile
99
+ );
100
+ workflow.delay(
101
+ "cooldown",
102
+ 1_000
103
+ );
104
+ }
105
+ );
139
106
  ```
140
107
 
141
- Operational helpers:
108
+ Workflows support sequential/parallel steps, retries, persisted delays, compensation, run leases and optional durable queue execution.
109
+
110
+ ## Transactional Outbox & Events — BCP 0.2.12+
111
+
112
+ Use `bcp/events` when application data and an integration event must commit atomically in the same SQL transaction.
142
113
 
143
114
  ```ts
144
- await jobs.recoverStale();
145
- const stats = await jobs.stats();
146
- await jobs.cleanup({
147
- before:
148
- Date.now() -
149
- 7 * 24 * 60 * 60 * 1000,
150
- });
151
- ```
115
+ import {
116
+ db,
117
+ } from "bcp/database";
118
+
119
+ import {
120
+ createSqlOutboxStore,
121
+ createTransactionalOutbox,
122
+ } from "bcp/events";
123
+
124
+ const outboxStore =
125
+ createSqlOutboxStore({
126
+ database: db,
127
+ driver: "mysql",
128
+ });
152
129
 
153
- ### Redis-compatible adapters
130
+ const outbox =
131
+ createTransactionalOutbox({
132
+ store: outboxStore,
133
+ });
154
134
 
155
- BCP does not install a Redis library. Supply an application-owned command client:
135
+ await db.transaction(
136
+ async tx => {
137
+ await tx.execute(
138
+ "INSERT INTO orders ..."
139
+ );
156
140
 
157
- ```ts
158
- interface RedisCommandClient {
159
- sendCommand(
160
- command: string[]
161
- ): Promise<unknown>;
162
- }
141
+ await outbox.publish(
142
+ tx,
143
+ "order.created",
144
+ {
145
+ orderId: 42,
146
+ }
147
+ );
148
+ }
149
+ );
163
150
  ```
164
151
 
165
- Create a durable queue:
152
+ Generate the required table SQL:
166
153
 
167
154
  ```ts
168
155
  import {
169
- createJobQueue,
170
- createRedisJobQueueAdapter,
171
- } from "bcp/jobs";
172
-
173
- const adapter =
174
- createRedisJobQueueAdapter({
175
- client: redisCommandClient,
176
- namespace: "my-app:{jobs}",
177
- });
156
+ createOutboxMigrationSql,
157
+ } from "bcp/events";
178
158
 
179
- export const jobs =
180
- createJobQueue({
181
- adapter,
182
- });
159
+ const sql =
160
+ createOutboxMigrationSql(
161
+ "mysql"
162
+ );
183
163
  ```
184
164
 
185
- Create a shared schedule store:
165
+ Dispatch committed events to the durable queue:
186
166
 
187
167
  ```ts
188
168
  import {
189
- createJobScheduler,
190
- createRedisJobScheduleStore,
191
- } from "bcp/jobs";
169
+ createOutboxDispatcher,
170
+ } from "bcp/events";
192
171
 
193
- const store =
194
- createRedisJobScheduleStore({
195
- client: redisCommandClient,
196
- namespace: "my-app:{jobs}",
197
- });
198
-
199
- export const scheduler =
200
- createJobScheduler({
172
+ const dispatcher =
173
+ createOutboxDispatcher({
174
+ store: outboxStore,
201
175
  queue: jobs,
202
- store,
203
- ownerId: "scheduler-a",
176
+ ownerId: "outbox-a",
204
177
  });
205
- ```
206
-
207
- A typical deployment may use:
208
178
 
209
- ```dotenv
210
- REDIS_URL=redis://localhost:6379
179
+ const runner =
180
+ dispatcher.start();
211
181
  ```
212
182
 
213
- BCP does not read this variable automatically. The application owns Redis connection creation, credentials, TLS/Cluster configuration and shutdown.
183
+ Event `order.created` is queued as `event.order.created`.
214
184
 
215
- The processing model is at-least-once, so side-effecting job handlers should be idempotent when duplicate execution is unsafe.
185
+ The dispatcher supports leases, stale recovery, retry/backoff, custom publishers, local EventBus delivery, retention cleanup and statistics.
216
186
 
217
- `bcp/jobs` is server-only and cannot be imported into page/client bundles.
187
+ `bcp/events` is server-only. Outbox delivery remains at-least-once, so non-repeatable downstream side effects should use idempotency protection.
218
188
 
219
189
  ## Generate framework files
220
190
 
@@ -225,22 +195,9 @@ npm run generate -- middleware
225
195
  npm run generate -- migration create_users
226
196
  ```
227
197
 
228
- Equivalent direct commands:
229
-
230
- ```bash
231
- bcp generate page dashboard/users
232
- bcp generate api users
233
- bcp generate middleware
234
- bcp generate migration create_users
235
- ```
236
-
237
- Existing page/API/middleware targets are not replaced unless `--force` is supplied explicitly.
238
-
239
198
  ## Direct CLI usage
240
199
 
241
- BCP Framework is installed as a project-local dependency.
242
-
243
- For PowerShell direct usage:
200
+ For PowerShell:
244
201
 
245
202
  ```powershell
246
203
  npm exec -- bcp-framework --version
@@ -252,8 +209,6 @@ npm exec -- bcp-framework build
252
209
  npm exec -- bcp-framework package
253
210
  ```
254
211
 
255
- Microsoft SQL Server can install another Windows executable named `bcp.exe`, so the `bcp-framework` alias avoids that command-name collision.
256
-
257
212
  ## Production build
258
213
 
259
214
  ```bash
@@ -261,12 +216,10 @@ npm run build
261
216
  npm start
262
217
  ```
263
218
 
264
- ## Deployment package — BCP 0.2.4+
219
+ ## Deployment package
265
220
 
266
221
  ```bash
267
222
  npm run package
268
223
  ```
269
224
 
270
- The output is written to `.bcp-framework/package/` and contains standalone output, production dependency metadata, deployment/environment manifests, integrity hashes and a starter Dockerfile.
271
-
272
- BCP intentionally excludes project `.env` files and application `devDependencies` from the deployment package. Provide secrets through your deployment environment.
225
+ BCP excludes project `.env` files and application `devDependencies` from the deployment package. Supply secrets through the deployment environment.