@chidchanun/bcp 0.2.3 → 0.2.5

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.
@@ -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
- Or run the standalone bundle directly:
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
- A minimal deployment image needs the standalone build plus the runtime dependencies required by the generated server bundle, including React/React DOM when they remain external to the bundle.
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
- A typical application image can install production dependencies, copy `.bcp-framework/build`, expose the runtime port and execute `npm start` or `node .bcp-framework/build/server/server.mjs`.
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
- npm run build
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
- For framework releases themselves, use `npm run release:check` in the framework repository.
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.3",
4
+ "versionTarget": "0.2.5",
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
  ]
@@ -35,9 +36,10 @@
35
36
  {
36
37
  "id": "authentication",
37
38
  "title": "Authentication",
38
- "description": "Authentication core, auth-aware route guards and JWT cookie sessions.",
39
+ "description": "Authentication Platform v2, revocable session stores, guest/auth route guards and JWT cookie sessions.",
39
40
  "pages": [
40
41
  { "route": "/docs/authentication", "source": "authentication.md", "title": "Authentication" },
42
+ { "route": "/docs/auth-session-store", "source": "auth-session-store.md", "title": "Auth Session Stores" },
41
43
  { "route": "/docs/auth-route-guards", "source": "auth-route-guards.md", "title": "Auth Route Guards" },
42
44
  { "route": "/docs/session-auth", "source": "session-auth.md", "title": "JWT Sessions" }
43
45
  ]
@@ -104,7 +106,9 @@
104
106
  }
105
107
  ],
106
108
  "releases": [
107
- { "route": "/releases/0.2.3", "source": "releases/0.2.3.md", "version": "0.2.3", "state": "unreleased" },
109
+ { "route": "/releases/0.2.5", "source": "releases/0.2.5.md", "version": "0.2.5", "state": "unreleased" },
110
+ { "route": "/releases/0.2.4", "source": "releases/0.2.4.md", "version": "0.2.4" },
111
+ { "route": "/releases/0.2.3", "source": "releases/0.2.3.md", "version": "0.2.3" },
108
112
  { "route": "/releases/0.2.2", "source": "releases/0.2.2.md", "version": "0.2.2" },
109
113
  { "route": "/releases/0.2.1", "source": "releases/0.2.1.md", "version": "0.2.1" },
110
114
  { "route": "/releases/0.2.0", "source": "releases/0.2.0.md", "version": "0.2.0" },
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "version": "0.2.3",
4
+ "version": "0.2.5",
5
5
  "releaseState": "unreleased",
6
- "baseline": "database-platform-v2",
6
+ "baseline": "authentication-platform-v2",
7
7
  "runtime": {
8
8
  "node": ">=24.11.0",
9
9
  "react": "19",
10
- "buildTarget": "standalone-node"
10
+ "buildTarget": "standalone-node",
11
+ "packageTarget": "standalone-node"
11
12
  },
12
13
  "publicEntrypoints": [
13
14
  "bcp",
@@ -25,6 +26,7 @@
25
26
  "cliCommands": [
26
27
  "dev",
27
28
  "build",
29
+ "package",
28
30
  "start",
29
31
  "routes",
30
32
  "update",
@@ -45,6 +47,12 @@
45
47
  "formActions": true,
46
48
  "middlewareV2": true,
47
49
  "jwtCookieSessions": true,
50
+ "authenticationPlatformV2": true,
51
+ "authSessionStore": true,
52
+ "authSessionRevocation": true,
53
+ "authLogoutAll": true,
54
+ "authIdleTimeout": true,
55
+ "authGuestGuard": true,
48
56
  "databaseMigrations": true,
49
57
  "databaseAdapterContract": true,
50
58
  "databasePostgresql": true,
@@ -58,6 +66,12 @@
58
66
  "streamingUploads": true,
59
67
  "storageEcosystem": true,
60
68
  "productionHardening": true,
69
+ "applicationPackaging": true,
70
+ "productionDependencyPruning": true,
71
+ "deploymentManifest": true,
72
+ "environmentPackagingManifest": true,
73
+ "packageIntegrityManifest": true,
74
+ "dockerPackageStarter": true,
61
75
  "projectGenerators": true,
62
76
  "projectDiagnostics": true,
63
77
  "documentationPlatform": true,
@@ -78,7 +92,7 @@
78
92
  "s3-compatible"
79
93
  ],
80
94
  "compatibility": {
81
- "previousBaseline": "0.2.2",
95
+ "previousBaseline": "0.2.4",
82
96
  "intentionalBreakingChangesFromPreviousBaseline": false,
83
97
  "migrationGuide": "migration-0.2.md"
84
98
  },
@@ -90,7 +104,10 @@
90
104
  "documentationPlatform": "documentation-platform.md",
91
105
  "apiReference": "api-reference.md",
92
106
  "environmentValidation": "environment-validation.md",
107
+ "applicationPackaging": "application-packaging.md",
108
+ "authentication": "authentication.md",
109
+ "authSessionStore": "auth-session-store.md",
93
110
  "migrationGuide": "migration-0.2.md",
94
- "releaseNotes": "releases/0.2.3.md"
111
+ "releaseNotes": "releases/0.2.5.md"
95
112
  }
96
113
  }
@@ -0,0 +1,152 @@
1
+ # BCP Framework 0.2.4 — Application Packaging
2
+
3
+ > **Release state:** unreleased development target until validation, RC checks, tagging and npm publication complete.
4
+
5
+ BCP Framework `0.2.4` adds a deployment-oriented application packaging layer on top of the existing standalone Node.js production build.
6
+
7
+ ## Highlights
8
+
9
+ - new `bcp package` CLI command
10
+ - every package starts from a fresh production build
11
+ - deployment output under `.bcp-framework/package/`
12
+ - production-only `package.json`
13
+ - npm v3 production lockfile pruning when it can be performed safely
14
+ - `npm ci --omit=dev` deployment contract when a production lock is available
15
+ - safe `npm install --omit=dev` fallback when a lock cannot be derived
16
+ - `bcp.package.json` artifact/integrity manifest
17
+ - `bcp.deployment.json` runtime/deployment contract
18
+ - `bcp.env.json` environment metadata without secret values
19
+ - generated Dockerfile and `.dockerignore`
20
+ - SHA-256 inventory for packaged files
21
+ - unit and prepared-package smoke coverage
22
+
23
+ ## Command
24
+
25
+ ```bash
26
+ bcp package
27
+ ```
28
+
29
+ The command performs:
30
+
31
+ ```text
32
+ production environment/config validation
33
+
34
+ fresh bcp build
35
+
36
+ standalone-node packaging
37
+
38
+ production dependency metadata
39
+
40
+ deployment + environment manifests
41
+
42
+ file integrity inventory
43
+ ```
44
+
45
+ ## Output
46
+
47
+ ```text
48
+ .bcp-framework/package/
49
+ ├── client/
50
+ ├── server/
51
+ │ └── server.mjs
52
+ ├── public/ # when present
53
+ ├── manifest.json
54
+ ├── package.json
55
+ ├── package-lock.json # when safely derivable
56
+ ├── bcp.package.json
57
+ ├── bcp.deployment.json
58
+ ├── bcp.env.json
59
+ ├── Dockerfile
60
+ ├── .dockerignore
61
+ └── README.md
62
+ ```
63
+
64
+ The current package target remains:
65
+
66
+ ```text
67
+ standalone-node
68
+ ```
69
+
70
+ ## Production dependency pruning
71
+
72
+ Application source `devDependencies` are not copied to the package manifest.
73
+
74
+ When an npm lockfile v3 can be reduced safely to the production dependency graph, BCP writes the reduced lockfile and deployment uses:
75
+
76
+ ```bash
77
+ npm ci --omit=dev
78
+ ```
79
+
80
+ If the lockfile contains unsupported metadata such as unsafe workspace links, BCP leaves it out and explicitly records the fallback:
81
+
82
+ ```bash
83
+ npm install --omit=dev
84
+ ```
85
+
86
+ ## Secret safety
87
+
88
+ Application packaging never copies `.env` files into the deployment artifact.
89
+
90
+ `bcp.env.json` records declared environment variable names discovered from example files only. It explicitly records that environment values and environment files are not embedded.
91
+
92
+ Provide credentials, database URLs, session secrets and storage keys through the deployment environment or a secret manager.
93
+
94
+ ## Container starter
95
+
96
+ The package includes a Node 24 Alpine Dockerfile. A basic flow is:
97
+
98
+ ```bash
99
+ cd .bcp-framework/package
100
+ docker build -t my-bcp-app .
101
+ docker run --rm -p 3000:3000 my-bcp-app
102
+ ```
103
+
104
+ ## Compatibility
105
+
106
+ `0.2.4` does not intentionally remove or rename the `0.2.3` public package entrypoints.
107
+
108
+ Existing applications may continue using:
109
+
110
+ ```bash
111
+ bcp build
112
+ bcp start
113
+ ```
114
+
115
+ `bcp package` is additive and is intended for deployment artifact creation.
116
+
117
+ ## Reproducibility scope
118
+
119
+ The packaging layer normalizes production dependency metadata and writes sorted file inventories with SHA-256 digests.
120
+
121
+ The existing production build still contains build-time identity/timestamp metadata, so `0.2.4` does not claim byte-for-byte reproducible artifacts across separate build invocations.
122
+
123
+ ## Validation
124
+
125
+ Before publication run:
126
+
127
+ ```bash
128
+ npm run typecheck
129
+ npm run test:unit
130
+ npm run test:integration
131
+ npm run test:e2e
132
+ npm run test:package
133
+ npm run rc:check
134
+ ```
135
+
136
+ For an application-level packaging smoke test:
137
+
138
+ ```bash
139
+ bcp package
140
+ cd .bcp-framework/package
141
+ npm ci --omit=dev
142
+ npm start
143
+ ```
144
+
145
+ If `bcp.package.json` reports that no lockfile was included, use the install command recorded in that manifest.
146
+
147
+ ## Related documentation
148
+
149
+ - [Application Packaging](../application-packaging.md)
150
+ - [Deployment](../deployment.md)
151
+ - [Production Hardening](../production-hardening.md)
152
+ - [Configuration](../configuration.md)
@@ -0,0 +1,152 @@
1
+ # BCP Framework 0.2.5
2
+
3
+ ## Authentication Platform v2
4
+
5
+ `0.2.5` expands `bcp/auth` from signed JWT-cookie authentication into an optional revocable session platform while preserving the stateless mode used by existing applications.
6
+
7
+ ## Highlights
8
+
9
+ ### Server-side auth session store contract
10
+
11
+ New public types:
12
+
13
+ ```ts
14
+ import type {
15
+ AuthSessionStore,
16
+ AuthSessionStoreRecord,
17
+ } from "bcp/auth";
18
+ ```
19
+
20
+ The contract provides:
21
+
22
+ ```text
23
+ set
24
+ get
25
+ touch
26
+ revoke
27
+ revokeUser
28
+ ```
29
+
30
+ Applications can back this contract with Redis, SQL, or another shared server-side store.
31
+
32
+ ### Built-in memory store
33
+
34
+ Development and tests can use:
35
+
36
+ ```ts
37
+ import {
38
+ createMemoryAuthSessionStore,
39
+ } from "bcp/auth";
40
+ ```
41
+
42
+ The memory adapter is process-local and intentionally not presented as a distributed production session database.
43
+
44
+ ### Revocable sessions
45
+
46
+ When an auth store is configured, a valid signed JWT must also have an active server-side `sid` record.
47
+
48
+ BCP can therefore invalidate a session before the cookie's JWT expiry.
49
+
50
+ New APIs include:
51
+
52
+ ```text
53
+ logoutAll()
54
+ revokeSession()
55
+ revokeUserSessions()
56
+ ```
57
+
58
+ Normal `logout()` also revokes the current `sid` when a store is enabled.
59
+
60
+ ### Idle timeout
61
+
62
+ `AuthOptions` now accepts:
63
+
64
+ ```ts
65
+ idleTimeout: number
66
+ ```
67
+
68
+ The value is measured in seconds and requires a session store.
69
+
70
+ Successful authentication updates the store's `lastSeenAt`. Sessions that exceed the inactivity window are revoked and rejected.
71
+
72
+ BCP intentionally rejects `idleTimeout` without a store instead of silently providing a false sense of server-side inactivity enforcement.
73
+
74
+ ### Session rotation
75
+
76
+ `rotateSession()` continues issuing a fresh `sid`, JWT, expiry, and cookie.
77
+
78
+ With a session store enabled, the previous `sid` is revoked so old cookies no longer pass the server-side session check.
79
+
80
+ ### Guest route guards
81
+
82
+ New APIs:
83
+
84
+ ```ts
85
+ requireGuest()
86
+ createGuestGuard()
87
+ ```
88
+
89
+ These support login, registration, and similar pages that should continue for anonymous users but redirect users who are already authenticated.
90
+
91
+ Default authenticated-user behavior is a `303` redirect. `redirectTo: null` returns `409 Already authenticated`.
92
+
93
+ ## Backward compatibility
94
+
95
+ The default remains stateless signed JWT-cookie authentication:
96
+
97
+ ```ts
98
+ import {
99
+ auth,
100
+ login,
101
+ logout,
102
+ } from "bcp/auth";
103
+ ```
104
+
105
+ Applications do not need to configure a session store unless they need centralized revocation or idle-timeout behavior.
106
+
107
+ No existing public application entrypoint is intentionally removed in this release.
108
+
109
+ ## Security guidance
110
+
111
+ - JWT payloads remain signed rather than encrypted.
112
+ - Do not place passwords, password hashes, tokens, API keys, or credentials in auth payload data.
113
+ - Keep `BCP_SESSION_SECRET` outside source control and at least 32 bytes long.
114
+ - Use a shared durable session-store implementation for production applications that run multiple Node.js processes or containers.
115
+ - The built-in memory store is suitable for local development/tests and process-local prototypes.
116
+
117
+ ## Documentation
118
+
119
+ Updated guides:
120
+
121
+ ```text
122
+ docs/authentication.md
123
+ docs/auth-session-store.md
124
+ docs/auth-route-guards.md
125
+ docs/api-reference.md
126
+ ```
127
+
128
+ ## Validation
129
+
130
+ `0.2.5` adds unit and package smoke coverage for:
131
+
132
+ ```text
133
+ session-store registration and lookup
134
+ session revocation
135
+ session rotation with revocation
136
+ logout-all
137
+ idle timeout
138
+ guest route guards
139
+ bcp/auth publish surface
140
+ Authentication Platform v2 package contents
141
+ ```
142
+
143
+ Before tagging or publishing, run the complete RC sequence:
144
+
145
+ ```bash
146
+ npm run typecheck
147
+ npm run test:unit
148
+ npm run test:integration
149
+ npm run test:e2e
150
+ npm run test:package
151
+ npm run rc:check
152
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chidchanun/bcp",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
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",