@zackbart/connecta 0.28.0 → 0.29.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 +961 -5
- package/README.md +62 -39
- package/bin/connecta.mjs +110 -139
- package/bin/meta-tool-names.d.mts +2 -0
- package/bin/meta-tool-names.mjs +9 -0
- package/bin/version.mjs +3 -0
- package/dist/access-tokens.js +53 -63
- package/dist/activity-request.js +8 -0
- package/dist/activity.d.ts +76 -42
- package/dist/activity.js +110 -42
- package/dist/auth/clerk-sdk/client.d.ts +65 -0
- package/dist/auth/clerk-sdk/client.js +5 -0
- package/dist/auth/clerk-sdk/generated.js +1845 -0
- package/dist/auth/clerk-transport.js +19 -0
- package/dist/auth/clerk.d.ts +17 -7
- package/dist/auth/clerk.js +189 -107
- package/dist/auth/cloudflare-access.js +25 -26
- package/dist/auth/downstream-client-metadata.d.ts +29 -0
- package/dist/auth/downstream-client-metadata.js +133 -0
- package/dist/auth/downstream-oauth.js +1632 -1509
- package/dist/auth/downstream-revocation.js +106 -0
- package/dist/auth/oauth-token-response.js +231 -0
- package/dist/auth/oauth-v2-migration.js +116 -0
- package/dist/auth/static-oauth.js +526 -0
- package/dist/auth-elicitation.js +283 -0
- package/dist/branding.d.ts +8 -16
- package/dist/branding.js +26 -59
- package/dist/byte-read-response.js +39 -0
- package/dist/call-admission.js +12 -16
- package/dist/catalog-cache.js +739 -0
- package/dist/catalog-drift.d.ts +50 -15
- package/dist/catalog-drift.js +365 -128
- package/dist/catalog-fingerprint.js +2 -4
- package/dist/catalog-freshness.js +13 -0
- package/dist/catalog-limits.js +2 -2
- package/dist/catalog-service.js +368 -224
- package/dist/catalog.js +43 -84
- package/dist/concurrency.js +3 -4
- package/dist/config-defaults.d.ts +39 -0
- package/dist/config-defaults.js +46 -0
- package/dist/config-schema.d.ts +181 -0
- package/dist/config-schema.js +435 -0
- package/dist/config-value-sources.js +102 -0
- package/dist/config.d.ts +631 -0
- package/dist/config.js +503 -0
- package/dist/connector-access.d.ts +1 -0
- package/dist/connector-access.js +13 -15
- package/dist/connector-caller.d.ts +8 -0
- package/dist/connector-caller.js +15 -6
- package/dist/connector-scope.js +1 -1
- package/dist/connectors/api-connector.d.ts +220 -0
- package/dist/connectors/api-connector.js +214 -0
- package/dist/connectors/api.d.ts +8 -71
- package/dist/connectors/api.js +13 -99
- package/dist/connectors/guarded-fetch.d.ts +144 -0
- package/dist/connectors/guarded-fetch.js +108 -25
- package/dist/connectors/negotiation-cache.js +46 -0
- package/dist/connectors/option-shapes.js +27 -0
- package/dist/connectors/remote-mcp.d.ts +30 -4
- package/dist/connectors/remote-mcp.js +1780 -351
- package/dist/connectors/resource-uri.js +335 -0
- package/dist/credential-contract.d.ts +10 -0
- package/dist/credential-rules.js +1 -3
- package/dist/credential-url.js +108 -0
- package/dist/credentials.d.ts +6 -1
- package/dist/credentials.js +27 -18
- package/dist/d1.d.ts +130 -0
- package/dist/d1.js +290 -0
- package/dist/describe-config.d.ts +165 -0
- package/dist/describe-config.js +315 -0
- package/dist/described.js +106 -0
- package/dist/downstream-input-context.js +119 -0
- package/dist/downstream-input.js +323 -0
- package/dist/errors.d.ts +97 -20
- package/dist/errors.js +158 -80
- package/dist/execute.js +453 -305
- package/dist/executor-admission.d.ts +1 -0
- package/dist/executor-admission.js +11 -15
- package/dist/executor-contract.d.ts +20 -0
- package/dist/executor-contract.js +48 -0
- package/dist/executor-result.js +24 -9
- package/dist/executors/quickjs-child.js +3 -4
- package/dist/executors/quickjs-runtime.js +147 -59
- package/dist/executors/quickjs.js +29 -35
- package/dist/favicon.js +1 -2
- package/dist/fix-prompt.js +1 -3
- package/dist/guest-runtime.js +188 -0
- package/dist/guest-types.d.ts +176 -0
- package/dist/guest-types.js +1 -0
- package/dist/html-security.js +24 -0
- package/dist/identity.js +1 -3
- package/dist/inbound-credential.js +52 -0
- package/dist/index.d.ts +25 -257
- package/dist/index.js +65 -478
- package/dist/invocation-auth.js +69 -0
- package/dist/invocation.js +230 -73
- package/dist/json-schema.d.ts +1 -1
- package/dist/mcp-client-context.js +35 -0
- package/dist/mcp-result.js +11 -7
- package/dist/meta-output.js +76 -0
- package/dist/meta-tool-names.d.ts +2 -0
- package/dist/meta-tool-names.js +3 -0
- package/dist/meta-tools.js +285 -209
- package/dist/module-contracts.d.ts +8 -23
- package/dist/node.d.ts +0 -2
- package/dist/node.js +2 -2
- package/dist/oauth-callback-outcome.js +1 -3
- package/dist/oauth-handoff.js +117 -0
- package/dist/oauth-partition.js +17 -0
- package/dist/oauth-sealing.js +20 -0
- package/dist/operator-record.d.ts +137 -0
- package/dist/operator-record.js +420 -0
- package/dist/operator-ui/assets.js +31 -0
- package/dist/operator-ui/contract.d.ts +72 -0
- package/dist/operator-ui/contract.js +1 -0
- package/dist/operator-ui/fix-prompts.d.ts +18 -0
- package/dist/operator-ui/generated.js +5 -4
- package/dist/operator-ui/model.d.ts +12 -87
- package/dist/operator-ui/model.js +2 -9
- package/dist/operator-ui/setup-commands.js +1 -3
- package/dist/operator-ui/view.d.ts +323 -0
- package/dist/operator-ui/view.js +62 -189
- package/dist/page-styles.js +2 -3
- package/dist/program-source.js +14 -2
- package/dist/{exempt-writes.js → program-writes.js} +55 -18
- package/dist/provider.d.ts +142 -0
- package/dist/provider.js +187 -0
- package/dist/providers/_shared/google/result-size.js +57 -0
- package/dist/providers/_shared/google/service-account.d.ts +58 -0
- package/dist/providers/_shared/google/service-account.js +500 -0
- package/dist/providers/_shared/google/workspace.d.ts +276 -0
- package/dist/providers/_shared/google/workspace.js +518 -0
- package/dist/providers/basecamp/index.d.ts +43 -0
- package/dist/providers/basecamp/index.js +997 -0
- package/dist/providers/basecamp/skill.generated.js +9 -0
- package/dist/providers/breeze/index.d.ts +34 -0
- package/dist/providers/breeze/index.js +1446 -0
- package/dist/providers/breeze/skill.generated.js +9 -0
- package/dist/providers/ccb/index.d.ts +103 -0
- package/dist/providers/ccb/index.js +1725 -0
- package/dist/providers/ccb/skill.generated.js +9 -0
- package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
- package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
- package/dist/providers/cloudflare/skill.generated.js +10 -0
- package/dist/providers/docs/index.d.ts +54 -0
- package/dist/providers/docs/index.js +1237 -0
- package/dist/providers/docs/skill.generated.js +9 -0
- package/dist/providers/drive/index.d.ts +53 -0
- package/dist/providers/drive/index.js +1523 -0
- package/dist/providers/drive/skill.generated.js +9 -0
- package/dist/providers/forms/index.d.ts +54 -0
- package/dist/providers/forms/index.js +1217 -0
- package/dist/providers/forms/skill.generated.js +11 -0
- package/dist/providers/github/auth.d.ts +32 -0
- package/dist/providers/github/auth.js +361 -0
- package/dist/providers/github/hosted.js +218 -0
- package/dist/providers/github/index.d.ts +13 -0
- package/dist/providers/github/index.js +140 -0
- package/dist/providers/github/key.js +100 -0
- package/dist/providers/github/rest.js +321 -0
- package/dist/providers/github/scope.d.ts +29 -0
- package/dist/providers/github/scope.js +124 -0
- package/dist/providers/github/skill.generated.js +8 -0
- package/dist/providers/gmail/index.d.ts +51 -0
- package/dist/providers/gmail/index.js +1436 -0
- package/dist/providers/gmail/skill.generated.js +9 -0
- package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
- package/dist/providers/linear/index.js +352 -0
- package/dist/providers/linear/skill.generated.js +8 -0
- package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
- package/dist/providers/mixpanel/index.js +416 -0
- package/dist/providers/mixpanel/skill.generated.js +9 -0
- package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
- package/dist/providers/{notion.js → notion/index.js} +226 -239
- package/dist/providers/notion/skill.generated.js +10 -0
- package/dist/providers/overflow/index.d.ts +60 -0
- package/dist/providers/overflow/index.js +1535 -0
- package/dist/providers/overflow/skill.generated.js +8 -0
- package/dist/providers/planning-center/index.d.ts +59 -0
- package/dist/providers/planning-center/index.js +2199 -0
- package/dist/providers/planning-center/skill.generated.js +10 -0
- package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
- package/dist/providers/revenuecat/index.js +557 -0
- package/dist/providers/revenuecat/skill.generated.js +11 -0
- package/dist/providers/sheets/index.d.ts +54 -0
- package/dist/providers/sheets/index.js +1237 -0
- package/dist/providers/sheets/skill.generated.js +10 -0
- package/dist/providers/slides/index.d.ts +53 -0
- package/dist/providers/slides/index.js +2645 -0
- package/dist/providers/slides/skill.generated.js +9 -0
- package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
- package/dist/providers/stripe/index.js +266 -0
- package/dist/providers/stripe/skill.generated.js +11 -0
- package/dist/providers/tithely/index.d.ts +49 -0
- package/dist/providers/tithely/index.js +1003 -0
- package/dist/providers/tithely/skill.generated.js +8 -0
- package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
- package/dist/providers/vercel/index.js +1038 -0
- package/dist/providers/vercel/mcp-ownership.js +212 -0
- package/dist/providers/vercel/skill.generated.js +11 -0
- package/dist/registry.d.ts +108 -171
- package/dist/registry.js +513 -925
- package/dist/request-state.js +21 -0
- package/dist/resource-read.js +100 -0
- package/dist/result-shapes.js +17 -49
- package/dist/retired-toolkits.js +1 -1
- package/dist/routes/access-tokens.js +3 -6
- package/dist/routes/activity-context.js +21 -0
- package/dist/routes/activity-disclosure.js +40 -0
- package/dist/routes/activity.js +59 -21
- package/dist/routes/actor-labels.js +3 -50
- package/dist/routes/connect.js +221 -0
- package/dist/routes/credentials.js +15 -27
- package/dist/routes/mcp.js +356 -130
- package/dist/routes/oauth-client-metadata.js +15 -0
- package/dist/routes/oauth-management.js +45 -107
- package/dist/routes/oauth.js +136 -57
- package/dist/routes/operator.js +3 -3
- package/dist/routes/shared.d.ts +25 -64
- package/dist/routes/shared.js +160 -80
- package/dist/routes/skills.js +30 -0
- package/dist/routes/ui-config.js +225 -0
- package/dist/routes/ui-data.js +40 -35
- package/dist/routes/ui.js +66 -56
- package/dist/runtime/admission.js +4 -2
- package/dist/runtime/call-admission.js +3 -1
- package/dist/runtime/connector-scope.js +1 -4
- package/dist/runtime/run.js +10 -39
- package/dist/runtime/services.js +12 -117
- package/dist/runtime/shared-read.js +1 -3
- package/dist/runtime/storage.js +8 -1
- package/dist/sent-secrets.d.ts +52 -0
- package/dist/sent-secrets.js +474 -0
- package/dist/server.js +28 -71
- package/dist/skills.js +406 -174
- package/dist/sqlite.d.ts +48 -0
- package/dist/sqlite.js +166 -0
- package/dist/storage/keys.js +428 -0
- package/dist/storage/memory.js +7 -0
- package/dist/storage/sql.d.ts +66 -0
- package/dist/storage/sql.js +534 -0
- package/dist/timeout.js +4 -2
- package/dist/tool-name.js +17 -0
- package/dist/tool-safety.d.ts +9 -35
- package/dist/tool-safety.js +20 -40
- package/dist/types.d.ts +320 -54
- package/dist/types.js +0 -1
- package/dist/ui.d.ts +7 -19
- package/dist/ui.js +76 -90
- package/dist/url-safety.js +3 -6
- package/dist/usage-guide.js +137 -0
- package/dist/validate.d.ts +7 -0
- package/dist/validate.js +309 -47
- package/dist/version.d.ts +1 -7
- package/dist/version.js +3 -7
- package/dist/worker.d.ts +11 -0
- package/dist/worker.js +434 -0
- package/documentation/architecture.md +665 -230
- package/documentation/auth.md +962 -458
- package/documentation/code-mode.md +501 -312
- package/documentation/meta-tools.md +449 -200
- package/documentation/operator-tests.md +93 -0
- package/documentation/provider-migration-0.29.md +60 -0
- package/examples/worker/AGENTS.md +34 -12
- package/examples/worker/README.md +286 -255
- package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
- package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
- package/examples/worker/src/connecta.config.ts +151 -0
- package/examples/worker/src/index.ts +14 -197
- package/examples/worker/wrangler.jsonc +15 -35
- package/package.json +125 -35
- package/templates/node/.dockerignore +1 -2
- package/templates/node/.env.example +20 -21
- package/templates/node/AGENTS.md +21 -17
- package/templates/node/Dockerfile +3 -5
- package/templates/node/README.md +133 -58
- package/templates/node/docker-compose.yml +11 -12
- package/templates/node/package.json +4 -2
- package/templates/node/src/connecta.config.ts +119 -0
- package/templates/node/src/index.ts +9 -154
- package/templates/node/src/provision-token.ts +17 -0
- package/AGENTS.md +0 -170
- package/dist/artifacts/connector.d.ts +0 -58
- package/dist/artifacts/connector.js +0 -730
- package/dist/artifacts/document.js +0 -86
- package/dist/artifacts/guide.js +0 -140
- package/dist/artifacts/html-scan.js +0 -329
- package/dist/artifacts/json.js +0 -78
- package/dist/artifacts/kv-store.d.ts +0 -20
- package/dist/artifacts/kv-store.js +0 -140
- package/dist/artifacts/markdown.js +0 -478
- package/dist/artifacts/module.d.ts +0 -37
- package/dist/artifacts/module.js +0 -66
- package/dist/artifacts/operations.d.ts +0 -197
- package/dist/artifacts/operations.js +0 -1002
- package/dist/artifacts/refresh.d.ts +0 -55
- package/dist/artifacts/refresh.js +0 -236
- package/dist/artifacts/routes.js +0 -206
- package/dist/artifacts/types.d.ts +0 -214
- package/dist/artifacts/types.js +0 -22
- package/dist/artifacts/validate.d.ts +0 -62
- package/dist/artifacts/validate.js +0 -651
- package/dist/artifacts.d.ts +0 -6
- package/dist/artifacts.js +0 -9
- package/dist/auth/bearer.d.ts +0 -11
- package/dist/auth/bearer.js +0 -50
- package/dist/providers/linear.js +0 -217
- package/dist/providers/mixpanel.js +0 -247
- package/dist/providers/revenuecat.js +0 -317
- package/dist/providers/stripe.js +0 -253
- package/dist/providers/vercel.js +0 -1253
- package/dist/storage/file.d.ts +0 -15
- package/dist/storage/file.js +0 -455
- package/ethos.md +0 -93
- package/examples/worker/src/cloudflare-kv.ts +0 -43
- package/examples/worker/src/d1-activity-row.ts +0 -155
- package/examples/worker/src/d1-activity.ts +0 -147
- package/examples/worker/src/d1-storage.ts +0 -138
- package/examples/worker/src/r2-artifact-blobs.ts +0 -29
- package/templates/node/src/file-activity.ts +0 -182
package/dist/server.js
CHANGED
|
@@ -3,10 +3,11 @@ import { notFoundResponse } from "./branding.js";
|
|
|
3
3
|
import { aggregateCallAdmissionSnapshots } from "./call-admission.js";
|
|
4
4
|
import { isAdmittingExecutor } from "./executor-admission.js";
|
|
5
5
|
import { createMcpRoute, MCP_CORS_HEADERS } from "./routes/mcp.js";
|
|
6
|
-
import { routeOAuthCallback
|
|
6
|
+
import { routeOAuthCallback } from "./routes/oauth.js";
|
|
7
|
+
import { routeOAuthClientMetadata } from "./routes/oauth-client-metadata.js";
|
|
8
|
+
import { routeConnect } from "./routes/connect.js";
|
|
7
9
|
import { runEdge } from "./runtime/run.js";
|
|
8
|
-
import { withSecurityHeaders, } from "./routes/shared.js";
|
|
9
|
-
const isArtifactPath = (path) => path === "/artifacts" || path.startsWith("/artifacts/");
|
|
10
|
+
import { authMetadata, withSecurityHeaders, } from "./routes/shared.js";
|
|
10
11
|
/**
|
|
11
12
|
* Build the Web-standard fetch handler.
|
|
12
13
|
*
|
|
@@ -20,47 +21,24 @@ const isArtifactPath = (path) => path === "/artifacts" || path.startsWith("/arti
|
|
|
20
21
|
* `close()` has disposed that runtime.
|
|
21
22
|
*/
|
|
22
23
|
export function createFetchHandler(opts) {
|
|
23
|
-
const {
|
|
24
|
+
const { registry } = opts;
|
|
25
|
+
const { auth, publicUrl } = opts.config;
|
|
24
26
|
const routeMcp = createMcpRoute(opts);
|
|
25
|
-
|
|
26
|
-
const metadata = (request, baseUrl) => Effect.gen(function* () {
|
|
27
|
-
for (const provider of auth) {
|
|
28
|
-
const handleMetadata = provider.handleMetadata?.bind(provider);
|
|
29
|
-
if (handleMetadata) {
|
|
30
|
-
const response = yield* Effect.promise(async () => handleMetadata(request, baseUrl));
|
|
31
|
-
if (response)
|
|
32
|
-
return response;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
});
|
|
27
|
+
const metadata = (request, baseUrl) => Effect.promise(async () => (await authMetadata(request, baseUrl, auth))?.response ?? null);
|
|
37
28
|
const health = async () => {
|
|
38
29
|
// The executor is required, so code admission always has a shape to
|
|
39
30
|
// report: either the executor's own pool or the fallback controller
|
|
40
31
|
// wrapped around it at construction.
|
|
41
|
-
const codeAdmission = isAdmittingExecutor(opts.executor)
|
|
42
|
-
? opts.executor.admissionSnapshot?.()
|
|
43
|
-
: undefined;
|
|
32
|
+
const codeAdmission = isAdmittingExecutor(opts.executor) ? opts.executor.admissionSnapshot?.() : undefined;
|
|
44
33
|
return Response.json({
|
|
45
34
|
status: "ok",
|
|
46
35
|
connectors: registry.listConnectors().length,
|
|
47
|
-
server: opts.serverInfo,
|
|
36
|
+
server: opts.config.serverInfo,
|
|
48
37
|
// Which sandbox, not how it is tuned: `connecta doctor` reports the
|
|
49
38
|
// executor it just exercised rather than assuming one, and a
|
|
50
39
|
// deployment whose executor identifies as nothing omits the key
|
|
51
40
|
// instead of inviting a guess (#368).
|
|
52
|
-
...(opts.executorName !== undefined
|
|
53
|
-
? { executor: { name: opts.executorName } }
|
|
54
|
-
: {}),
|
|
55
|
-
// Counts only, from refreshes that already happened — the endpoint
|
|
56
|
-
// asks no downstream anything, and `connecta doctor` reads it to
|
|
57
|
-
// report a stale allowlist without a probe of its own (#343).
|
|
58
|
-
// Stable 64-bit hashes preserve that shape without publishing ids.
|
|
59
|
-
catalogDrift: Object.fromEntries(await Promise.all(Object.entries(registry.catalogDriftSnapshot()).map(async ([id, report]) => {
|
|
60
|
-
const hash = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(id)));
|
|
61
|
-
const key = Array.from(hash.subarray(0, 8), byte => byte.toString(16).padStart(2, "0")).join("");
|
|
62
|
-
return [key, report];
|
|
63
|
-
}))),
|
|
41
|
+
...(opts.executorName !== undefined ? { executor: { name: opts.executorName } } : {}),
|
|
64
42
|
admission: {
|
|
65
43
|
policy: "global-fifo",
|
|
66
44
|
requests: opts.requestAdmission.snapshot(),
|
|
@@ -71,24 +49,32 @@ export function createFetchHandler(opts) {
|
|
|
71
49
|
},
|
|
72
50
|
reservedRoutes: [
|
|
73
51
|
"/health",
|
|
74
|
-
...(opts.ui?.reservedPaths ?? []),
|
|
75
|
-
...(opts.ui && opts.activity?.list ? ["/activity"] : []),
|
|
76
|
-
...(opts.ui && opts.accessTokens ? ["/tokens"] : []),
|
|
77
|
-
...(opts.ui && opts.artifactsModule ? ["/artifacts", "/artifacts/*"] : []),
|
|
52
|
+
...(opts.config.ui?.reservedPaths ?? []),
|
|
53
|
+
...(opts.config.ui && opts.config.activity?.store.list ? ["/activity"] : []),
|
|
54
|
+
...(opts.config.ui && opts.config.accessTokens ? ["/tokens"] : []),
|
|
78
55
|
],
|
|
79
56
|
},
|
|
80
|
-
...(opts.deploymentInfo ? { deployment: opts.deploymentInfo } : {}),
|
|
57
|
+
...(opts.config.deploymentInfo ? { deployment: opts.config.deploymentInfo } : {}),
|
|
81
58
|
});
|
|
82
59
|
};
|
|
83
60
|
const route = (context) => Effect.gen(function* () {
|
|
84
61
|
const { request, path, baseUrl } = context;
|
|
62
|
+
const clientMetadata = routeOAuthClientMetadata(context);
|
|
63
|
+
if (clientMetadata)
|
|
64
|
+
return clientMetadata;
|
|
85
65
|
// Private mutations own OPTIONS so they never inherit wildcard CORS.
|
|
86
|
-
const ui = opts.ui;
|
|
66
|
+
const ui = opts.config.ui;
|
|
87
67
|
if (ui) {
|
|
88
68
|
const uiResponse = yield* Effect.promise(() => ui.handle(context));
|
|
89
69
|
if (uiResponse)
|
|
90
70
|
return uiResponse;
|
|
91
71
|
}
|
|
72
|
+
const connect = yield* routeConnect(context);
|
|
73
|
+
if (connect)
|
|
74
|
+
return connect;
|
|
75
|
+
const oauthCallback = yield* routeOAuthCallback(context);
|
|
76
|
+
if (oauthCallback)
|
|
77
|
+
return oauthCallback;
|
|
92
78
|
if (request.method === "OPTIONS") {
|
|
93
79
|
const preflight = yield* routeMcp.handle(context);
|
|
94
80
|
if (preflight)
|
|
@@ -105,46 +91,20 @@ export function createFetchHandler(opts) {
|
|
|
105
91
|
const response = yield* metadata(request, baseUrl);
|
|
106
92
|
if (response)
|
|
107
93
|
return response;
|
|
108
|
-
return notFoundResponse(request, opts);
|
|
94
|
+
return notFoundResponse(request, opts.config);
|
|
109
95
|
}
|
|
110
96
|
if (path === "/health")
|
|
111
97
|
return yield* Effect.promise(health);
|
|
112
|
-
const oauthCallback = yield* routeOAuthCallback(context);
|
|
113
|
-
if (oauthCallback)
|
|
114
|
-
return oauthCallback;
|
|
115
98
|
const mcp = yield* routeMcp.handle(context);
|
|
116
99
|
if (mcp)
|
|
117
100
|
return mcp;
|
|
118
|
-
return notFoundResponse(request, opts);
|
|
101
|
+
return notFoundResponse(request, opts.config);
|
|
119
102
|
});
|
|
120
103
|
const serve = (request, runtimeContext) => Effect.suspend(() => {
|
|
121
104
|
const url = new URL(request.url);
|
|
122
105
|
const baseUrl = publicUrl ?? url.origin;
|
|
123
106
|
const path = url.pathname;
|
|
124
|
-
const defer = runtimeContext
|
|
125
|
-
? runtimeContext.waitUntil.bind(runtimeContext)
|
|
126
|
-
: undefined;
|
|
127
|
-
// The artifact hostname has no MCP, health, OAuth, or operator routes.
|
|
128
|
-
// Dispatch before MCP origin checks so even a hostile /mcp gets the same
|
|
129
|
-
// 404 as any other unserved path.
|
|
130
|
-
if (opts.artifactOrigin && url.origin === new URL(opts.artifactOrigin).origin) {
|
|
131
|
-
if (!isArtifactPath(path) || !opts.ui || !opts.artifactsModule) {
|
|
132
|
-
return Effect.succeed(withSecurityHeaders(notFoundResponse(request, opts), url, path));
|
|
133
|
-
}
|
|
134
|
-
const context = {
|
|
135
|
-
request, url, path, baseUrl: opts.artifactOrigin, opts, defer, runtimeContext,
|
|
136
|
-
};
|
|
137
|
-
return Effect.map(Effect.promise(() => opts.ui.handle(context)), response => withSecurityHeaders(response ?? notFoundResponse(request, opts), url, path));
|
|
138
|
-
}
|
|
139
|
-
if (opts.artifactOrigin && isArtifactPath(path) && opts.ui && opts.artifactsModule) {
|
|
140
|
-
const target = new URL(opts.artifactOrigin);
|
|
141
|
-
target.pathname = path;
|
|
142
|
-
target.search = url.search;
|
|
143
|
-
return Effect.succeed(withSecurityHeaders(new Response(null, {
|
|
144
|
-
status: 308,
|
|
145
|
-
headers: { Location: target.toString() },
|
|
146
|
-
}), url, path));
|
|
147
|
-
}
|
|
107
|
+
const defer = runtimeContext ? runtimeContext.waitUntil.bind(runtimeContext) : undefined;
|
|
148
108
|
const originRefusal = routeMcp.rejectOrigin(request);
|
|
149
109
|
if (originRefusal) {
|
|
150
110
|
return Effect.succeed(withSecurityHeaders(originRefusal, url, path));
|
|
@@ -155,10 +115,7 @@ export function createFetchHandler(opts) {
|
|
|
155
115
|
// external DNS, TLS, and the tunnel in front of connecta — so /health is
|
|
156
116
|
// exempt. It is unauthenticated, returns no user data, and sets no
|
|
157
117
|
// cookies, so forcing HTTPS on it protects nothing.
|
|
158
|
-
if (publicUrl &&
|
|
159
|
-
path !== "/health" &&
|
|
160
|
-
new URL(publicUrl).protocol === "https:" &&
|
|
161
|
-
url.protocol === "http:") {
|
|
118
|
+
if (publicUrl && path !== "/health" && new URL(publicUrl).protocol === "https:" && url.protocol === "http:") {
|
|
162
119
|
// Assign the path and query onto the configured URL instead of resolving
|
|
163
120
|
// attacker-controlled text against it. A pathname beginning with `//`
|
|
164
121
|
// (including a backslash form normalized by URL parsing) is an authority
|