@workerdeck/server 0.12.0 → 0.13.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/build/index.d.mts +21 -1
- package/build/index.mjs +21 -0
- package/build/index.mjs.map +1 -1
- package/package.json +5 -5
package/build/index.d.mts
CHANGED
|
@@ -433,7 +433,27 @@ type WorkerServerOptions = {
|
|
|
433
433
|
*
|
|
434
434
|
* Upgrades are not routed here: anything outside `basePath` is still refused.
|
|
435
435
|
*/
|
|
436
|
-
fallback?: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
|
|
436
|
+
fallback?: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
|
|
437
|
+
/**
|
|
438
|
+
* Browser origins allowed to call this API cross-origin — for a dashboard
|
|
439
|
+
* served somewhere other than this gateway.
|
|
440
|
+
*
|
|
441
|
+
* Off unless configured, and even then it is *sharing policy, not a
|
|
442
|
+
* credential*: preflights are answered before auth (browsers strip
|
|
443
|
+
* credentials from them, so they would otherwise 401), but every real request
|
|
444
|
+
* still goes through `authenticate`, and an allowlisted page that does not
|
|
445
|
+
* hold the key gets nothing.
|
|
446
|
+
*
|
|
447
|
+
* Two rules the implementation must keep: **exact origins only**, no
|
|
448
|
+
* wildcards or suffix matching; and `Access-Control-Allow-Credentials` is
|
|
449
|
+
* **never** sent, which is what keeps an ambient cookie from becoming
|
|
450
|
+
* cross-origin authority. WebSocket upgrades are exempt from CORS entirely
|
|
451
|
+
* and are unaffected by this — their credential is whatever the host's
|
|
452
|
+
* `authenticate` accepts on the handshake.
|
|
453
|
+
*/
|
|
454
|
+
cors?: {
|
|
455
|
+
origins: string[];
|
|
456
|
+
}; /** Max JSON body size in bytes. Default 1 MiB. */
|
|
437
457
|
maxBodyBytes?: number;
|
|
438
458
|
/**
|
|
439
459
|
* Server-wide bypass policy: refuse `permissionMode: 'bypassPermissions'` on
|
package/build/index.mjs
CHANGED
|
@@ -1454,6 +1454,7 @@ function createWorkerServer(options = {}) {
|
|
|
1454
1454
|
if (!options.authenticate && !options.allowUnauthenticated) throw new Error("createWorkerServer: provide `authenticate` or explicitly set `allowUnauthenticated: true`");
|
|
1455
1455
|
const basePath = options.basePath ?? "/v1";
|
|
1456
1456
|
const fallback = options.fallback;
|
|
1457
|
+
const corsOrigins = options.cors?.origins.length ? new Set(options.cors.origins) : void 0;
|
|
1457
1458
|
const maxBodyBytes = options.maxBodyBytes ?? 1024 * 1024;
|
|
1458
1459
|
/** The engine's adapter, honoring the test-only `engines` override. */
|
|
1459
1460
|
const adapterFor = (engine) => options.engines?.[engine ?? "claude"] ?? getEngineAdapter(engine);
|
|
@@ -2545,6 +2546,26 @@ function createWorkerServer(options = {}) {
|
|
|
2545
2546
|
};
|
|
2546
2547
|
const handleRequest = async (req, res) => {
|
|
2547
2548
|
const pathname = new URL(req.url ?? "/", "http://internal").pathname;
|
|
2549
|
+
const origin = req.headers.origin;
|
|
2550
|
+
const originAllowed = typeof origin === "string" && corsOrigins !== void 0 && corsOrigins.has(origin);
|
|
2551
|
+
if (originAllowed) {
|
|
2552
|
+
res.setHeader("access-control-allow-origin", origin);
|
|
2553
|
+
res.setHeader("vary", "origin");
|
|
2554
|
+
}
|
|
2555
|
+
if (req.method === "OPTIONS" && req.headers["access-control-request-method"] !== void 0) {
|
|
2556
|
+
if (!originAllowed) {
|
|
2557
|
+
res.writeHead(403);
|
|
2558
|
+
res.end();
|
|
2559
|
+
return;
|
|
2560
|
+
}
|
|
2561
|
+
res.setHeader("access-control-allow-methods", "GET, HEAD, POST, PATCH, PUT, DELETE");
|
|
2562
|
+
res.setHeader("access-control-allow-headers", "authorization, content-type, x-workerdeck-key");
|
|
2563
|
+
res.setHeader("access-control-max-age", "600");
|
|
2564
|
+
if (req.headers["access-control-request-private-network"] === "true") res.setHeader("access-control-allow-private-network", "true");
|
|
2565
|
+
res.writeHead(204);
|
|
2566
|
+
res.end();
|
|
2567
|
+
return;
|
|
2568
|
+
}
|
|
2548
2569
|
if (fallback && pathname !== basePath && !pathname.startsWith(basePath + "/")) {
|
|
2549
2570
|
await fallback(req, res);
|
|
2550
2571
|
return;
|