@chidchanun/bcp 0.1.0
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/CHANGELOG.md +49 -0
- package/LICENSE +21 -0
- package/README.md +241 -0
- package/docs/caching.md +76 -0
- package/docs/configuration.md +97 -0
- package/docs/deployment.md +74 -0
- package/docs/getting-started.md +82 -0
- package/docs/middleware.md +58 -0
- package/docs/releasing.md +299 -0
- package/docs/routing.md +103 -0
- package/docs/security.md +57 -0
- package/package.json +68 -0
- package/packages/bundler/src/client-islands.ts +1457 -0
- package/packages/bundler/src/incremental-context.ts +206 -0
- package/packages/bundler/src/index.ts +1991 -0
- package/packages/bundler/src/module-graph.ts +317 -0
- package/packages/bundler/src/partial-hydration.ts +414 -0
- package/packages/bundler/src/production.ts +974 -0
- package/packages/bundler/src/server-production-middleware.ts +447 -0
- package/packages/bundler/src/server-production.ts +1193 -0
- package/packages/bundler/src/special-files.ts +131 -0
- package/packages/cache/src/index.ts +761 -0
- package/packages/cli/bin/bcp.mjs +93 -0
- package/packages/cli/src/args.ts +305 -0
- package/packages/cli/src/bootstrap.ts +514 -0
- package/packages/cli/src/index.ts +504 -0
- package/packages/cli/src/version.ts +45 -0
- package/packages/client/src/cache.ts +11 -0
- package/packages/client/src/config.ts +18 -0
- package/packages/client/src/error-boundary.tsx +149 -0
- package/packages/client/src/hydration.ts +3 -0
- package/packages/client/src/index.tsx +57 -0
- package/packages/client/src/islands.tsx +315 -0
- package/packages/client/src/metadata.ts +281 -0
- package/packages/client/src/navigation-loading.ts +52 -0
- package/packages/client/src/navigation-state.ts +80 -0
- package/packages/client/src/not-found.ts +34 -0
- package/packages/client/src/persistent-layout-runtime.ts +273 -0
- package/packages/client/src/router-v2.tsx +969 -0
- package/packages/client/src/router.tsx +1 -0
- package/packages/config/src/index.ts +1038 -0
- package/packages/env/src/index.ts +593 -0
- package/packages/router/src/advanced-router.ts +1032 -0
- package/packages/router/src/index.ts +1 -0
- package/packages/server/src/compression.ts +249 -0
- package/packages/server/src/dev-document-metadata.ts +154 -0
- package/packages/server/src/dev-hmr.ts +225 -0
- package/packages/server/src/index.ts +2265 -0
- package/packages/server/src/metadata.ts +478 -0
- package/packages/server/src/middleware-dev-server.ts +260 -0
- package/packages/server/src/middleware-loader.ts +140 -0
- package/packages/server/src/middleware-proxy.ts +516 -0
- package/packages/server/src/middleware.ts +704 -0
- package/packages/server/src/navigation-payload.ts +471 -0
- package/packages/server/src/production-server.ts +1746 -0
- package/packages/server/src/response-cache-proxy.ts +828 -0
- package/packages/server/src/security-proxy.ts +406 -0
- package/packages/server/src/security.ts +451 -0
- package/packages/server/src/standalone-production-runtime-v2.ts +2047 -0
- package/packages/server/src/standalone-production-runtime-v3.ts +250 -0
- package/packages/server/src/standalone-production-runtime-v4.ts +289 -0
- package/packages/server/src/standalone-production-runtime-v5.ts +289 -0
- package/packages/server/src/standalone-production-runtime.ts +1951 -0
- package/packages/server/src/standalone-production-server.ts +6 -0
- package/packages/server/src/static-assets.ts +262 -0
- package/packages/server/src/static-dev-server.ts +854 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import * as net from "node:net";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
createSecurityProxy,
|
|
7
|
+
} from "./security-proxy.js";
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
createStandaloneProductionServer as createBaseStandaloneProductionServer,
|
|
11
|
+
type StandaloneApiRoute,
|
|
12
|
+
type StandalonePageRoute,
|
|
13
|
+
type StandaloneProductionServerOptions as BaseStandaloneProductionServerOptions,
|
|
14
|
+
} from "./standalone-production-runtime-v4.js";
|
|
15
|
+
|
|
16
|
+
export type {
|
|
17
|
+
StandaloneApiRoute,
|
|
18
|
+
StandalonePageRoute,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export interface StandaloneProductionServerOptions
|
|
22
|
+
extends BaseStandaloneProductionServerOptions {}
|
|
23
|
+
|
|
24
|
+
export function createStandaloneProductionServer(
|
|
25
|
+
options: StandaloneProductionServerOptions
|
|
26
|
+
) {
|
|
27
|
+
let baseServer:
|
|
28
|
+
ReturnType<
|
|
29
|
+
typeof createBaseStandaloneProductionServer
|
|
30
|
+
> | null =
|
|
31
|
+
null;
|
|
32
|
+
|
|
33
|
+
let securityProxy:
|
|
34
|
+
ReturnType<
|
|
35
|
+
typeof createSecurityProxy
|
|
36
|
+
> | null =
|
|
37
|
+
null;
|
|
38
|
+
|
|
39
|
+
let started =
|
|
40
|
+
false;
|
|
41
|
+
|
|
42
|
+
async function start(): Promise<void> {
|
|
43
|
+
if (started) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
applyFrozenSecurityConfig(
|
|
48
|
+
options.buildDirectory
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const internalPort =
|
|
52
|
+
await findFreePort();
|
|
53
|
+
|
|
54
|
+
baseServer =
|
|
55
|
+
createBaseStandaloneProductionServer({
|
|
56
|
+
...options,
|
|
57
|
+
port:
|
|
58
|
+
internalPort,
|
|
59
|
+
hostname:
|
|
60
|
+
"127.0.0.1",
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
await baseServer.start();
|
|
64
|
+
|
|
65
|
+
securityProxy =
|
|
66
|
+
createSecurityProxy({
|
|
67
|
+
port:
|
|
68
|
+
options.port,
|
|
69
|
+
hostname:
|
|
70
|
+
options.hostname,
|
|
71
|
+
upstreamPort:
|
|
72
|
+
internalPort,
|
|
73
|
+
upstreamHostname:
|
|
74
|
+
"127.0.0.1",
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
await securityProxy.start();
|
|
79
|
+
} catch (error) {
|
|
80
|
+
await baseServer.stop();
|
|
81
|
+
baseServer =
|
|
82
|
+
null;
|
|
83
|
+
securityProxy =
|
|
84
|
+
null;
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
started =
|
|
89
|
+
true;
|
|
90
|
+
|
|
91
|
+
console.log(
|
|
92
|
+
`[BCP Security] Gateway: http://${options.hostname}:${options.port}`
|
|
93
|
+
);
|
|
94
|
+
console.log("");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function stop(): Promise<void> {
|
|
98
|
+
if (securityProxy) {
|
|
99
|
+
await securityProxy.stop();
|
|
100
|
+
securityProxy =
|
|
101
|
+
null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (baseServer) {
|
|
105
|
+
await baseServer.stop();
|
|
106
|
+
baseServer =
|
|
107
|
+
null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
started =
|
|
111
|
+
false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
start,
|
|
116
|
+
stop,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function applyFrozenSecurityConfig(
|
|
121
|
+
buildDirectory: string
|
|
122
|
+
): void {
|
|
123
|
+
const configFile =
|
|
124
|
+
path.join(
|
|
125
|
+
buildDirectory,
|
|
126
|
+
"server",
|
|
127
|
+
"config.json"
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
if (
|
|
131
|
+
!fs.existsSync(
|
|
132
|
+
configFile
|
|
133
|
+
)
|
|
134
|
+
) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
const parsed =
|
|
140
|
+
JSON.parse(
|
|
141
|
+
fs.readFileSync(
|
|
142
|
+
configFile,
|
|
143
|
+
"utf8"
|
|
144
|
+
)
|
|
145
|
+
) as {
|
|
146
|
+
server?: {
|
|
147
|
+
bodyLimit?: number;
|
|
148
|
+
};
|
|
149
|
+
security?: {
|
|
150
|
+
poweredByHeader?: boolean;
|
|
151
|
+
contentSecurityPolicy?: string | false;
|
|
152
|
+
frameOptions?: "DENY" | "SAMEORIGIN" | false;
|
|
153
|
+
referrerPolicy?: string;
|
|
154
|
+
permissionsPolicy?: string | false;
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
if (
|
|
159
|
+
process.env.BCP_BODY_LIMIT === undefined &&
|
|
160
|
+
Number.isInteger(
|
|
161
|
+
parsed.server?.bodyLimit
|
|
162
|
+
)
|
|
163
|
+
) {
|
|
164
|
+
process.env.BCP_BODY_LIMIT =
|
|
165
|
+
String(
|
|
166
|
+
parsed.server?.bodyLimit
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const security =
|
|
171
|
+
parsed.security;
|
|
172
|
+
|
|
173
|
+
if (!security) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
process.env.BCP_POWERED_BY_HEADER ??=
|
|
178
|
+
security.poweredByHeader
|
|
179
|
+
? "1"
|
|
180
|
+
: "0";
|
|
181
|
+
process.env.BCP_SECURITY_CSP ??=
|
|
182
|
+
security.contentSecurityPolicy === false ||
|
|
183
|
+
security.contentSecurityPolicy === undefined
|
|
184
|
+
? "0"
|
|
185
|
+
: security.contentSecurityPolicy;
|
|
186
|
+
process.env.BCP_SECURITY_FRAME_OPTIONS ??=
|
|
187
|
+
security.frameOptions === false ||
|
|
188
|
+
security.frameOptions === undefined
|
|
189
|
+
? "0"
|
|
190
|
+
: security.frameOptions;
|
|
191
|
+
process.env.BCP_SECURITY_REFERRER_POLICY ??=
|
|
192
|
+
security.referrerPolicy ??
|
|
193
|
+
"strict-origin-when-cross-origin";
|
|
194
|
+
process.env.BCP_SECURITY_PERMISSIONS_POLICY ??=
|
|
195
|
+
security.permissionsPolicy === false ||
|
|
196
|
+
security.permissionsPolicy === undefined
|
|
197
|
+
? "0"
|
|
198
|
+
: security.permissionsPolicy;
|
|
199
|
+
} catch (error) {
|
|
200
|
+
throw new Error(
|
|
201
|
+
`BCP Framework: invalid standalone security config at "${configFile}". ${error instanceof Error ? error.message : String(error)}`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async function findFreePort(): Promise<number> {
|
|
207
|
+
const server =
|
|
208
|
+
net.createServer();
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
await new Promise<void>(
|
|
212
|
+
(
|
|
213
|
+
resolve,
|
|
214
|
+
reject
|
|
215
|
+
) => {
|
|
216
|
+
const onError =
|
|
217
|
+
(error: Error) => {
|
|
218
|
+
server.off(
|
|
219
|
+
"listening",
|
|
220
|
+
onListening
|
|
221
|
+
);
|
|
222
|
+
reject(
|
|
223
|
+
error
|
|
224
|
+
);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const onListening =
|
|
228
|
+
() => {
|
|
229
|
+
server.off(
|
|
230
|
+
"error",
|
|
231
|
+
onError
|
|
232
|
+
);
|
|
233
|
+
resolve();
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
server.once(
|
|
237
|
+
"error",
|
|
238
|
+
onError
|
|
239
|
+
);
|
|
240
|
+
server.once(
|
|
241
|
+
"listening",
|
|
242
|
+
onListening
|
|
243
|
+
);
|
|
244
|
+
server.listen(
|
|
245
|
+
0,
|
|
246
|
+
"127.0.0.1"
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
const address =
|
|
252
|
+
server.address();
|
|
253
|
+
|
|
254
|
+
if (
|
|
255
|
+
!address ||
|
|
256
|
+
typeof address ===
|
|
257
|
+
"string"
|
|
258
|
+
) {
|
|
259
|
+
throw new Error(
|
|
260
|
+
"BCP Framework: could not allocate security gateway port."
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return address.port;
|
|
265
|
+
} finally {
|
|
266
|
+
if (
|
|
267
|
+
server.listening
|
|
268
|
+
) {
|
|
269
|
+
await new Promise<void>(
|
|
270
|
+
(
|
|
271
|
+
resolve,
|
|
272
|
+
reject
|
|
273
|
+
) => {
|
|
274
|
+
server.close(
|
|
275
|
+
(error) => {
|
|
276
|
+
if (error) {
|
|
277
|
+
reject(
|
|
278
|
+
error
|
|
279
|
+
);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
resolve();
|
|
283
|
+
}
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|