stitchkit 0.94.0 → 0.94.1
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 +64 -0
- package/dist/agent-runtime/coding-shell-process.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-listing.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-search-patch.d.ts.map +1 -1
- package/dist/agent-runtime/contained-darwin.d.ts +38 -0
- package/dist/agent-runtime/contained-darwin.d.ts.map +1 -0
- package/dist/agent-runtime/contained-files.d.ts +11 -26
- package/dist/agent-runtime/contained-files.d.ts.map +1 -1
- package/dist/agent-runtime/contained-scan.d.ts +21 -0
- package/dist/agent-runtime/contained-scan.d.ts.map +1 -0
- package/dist/agent-runtime/contained-write.d.ts +9 -0
- package/dist/agent-runtime/contained-write.d.ts.map +1 -0
- package/dist/agent-runtime/deferred-tool-types.d.ts +3 -2
- package/dist/agent-runtime/deferred-tool-types.d.ts.map +1 -1
- package/dist/agent-runtime/harness-control.d.ts +0 -1
- package/dist/agent-runtime/harness-control.d.ts.map +1 -1
- package/dist/agent-runtime/harness.d.ts +0 -5
- package/dist/agent-runtime/harness.d.ts.map +1 -1
- package/dist/agent-runtime/managed-tools.d.ts +3 -2
- package/dist/agent-runtime/managed-tools.d.ts.map +1 -1
- package/dist/agent-runtime/runtime.d.ts +1 -1
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/schedule-records.d.ts +34 -0
- package/dist/agent-runtime/schedule-records.d.ts.map +1 -0
- package/dist/agent-runtime/schedules.d.ts +34 -0
- package/dist/agent-runtime/schedules.d.ts.map +1 -1
- package/dist/agent-runtime/store-conformance-lifecycle.d.ts +434 -0
- package/dist/agent-runtime/store-conformance-lifecycle.d.ts.map +1 -0
- package/dist/agent-runtime/store-conformance-ordering.d.ts +18 -0
- package/dist/agent-runtime/store-conformance-ordering.d.ts.map +1 -0
- package/dist/agent-runtime/store-conformance-support.d.ts +130 -0
- package/dist/agent-runtime/store-conformance-support.d.ts.map +1 -0
- package/dist/agent-runtime/store-conformance-terminal.d.ts +12 -0
- package/dist/agent-runtime/store-conformance-terminal.d.ts.map +1 -0
- package/dist/agent-runtime/store-conformance.d.ts.map +1 -1
- package/dist/application/admission-rate.d.ts +21 -0
- package/dist/application/admission-rate.d.ts.map +1 -0
- package/dist/application/admission-run.d.ts +8 -0
- package/dist/application/admission-run.d.ts.map +1 -0
- package/dist/application/admission.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-lock.d.ts +9 -34
- package/dist/application/diagnostic-journal-lock.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-manager.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-storage.d.ts.map +1 -1
- package/dist/application/kernel-resource-context.d.ts.map +1 -1
- package/dist/application/notification-outbox.d.ts.map +1 -1
- package/dist/application/schedule.d.ts +0 -1
- package/dist/application/schedule.d.ts.map +1 -1
- package/dist/application/watch-hub-core.d.ts +122 -0
- package/dist/application/watch-hub-core.d.ts.map +1 -0
- package/dist/application/watch-hub.d.ts +2 -2
- package/dist/application/watch-hub.d.ts.map +1 -1
- package/dist/browser/client-executors.d.ts +14 -0
- package/dist/browser/client-executors.d.ts.map +1 -0
- package/dist/browser/client-multipart.d.ts +1 -1
- package/dist/browser/client-multipart.d.ts.map +1 -1
- package/dist/browser/client.d.ts +3 -2
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/http-fetch.d.ts +22 -0
- package/dist/browser/http-fetch.d.ts.map +1 -0
- package/dist/browser/http.d.ts +1 -3
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/live-state-core.d.ts +63 -0
- package/dist/browser/live-state-core.d.ts.map +1 -0
- package/dist/browser/live-state.d.ts.map +1 -1
- package/dist/browser/realtime-client.d.ts +26 -0
- package/dist/browser/realtime-client.d.ts.map +1 -0
- package/dist/browser/socket-io-connection.d.ts +82 -0
- package/dist/browser/socket-io-connection.d.ts.map +1 -0
- package/dist/browser/socket-io-peer.d.ts +20 -0
- package/dist/browser/socket-io-peer.d.ts.map +1 -0
- package/dist/browser/socket-io-trace.d.ts +31 -0
- package/dist/browser/socket-io-trace.d.ts.map +1 -0
- package/dist/browser/socket-io.d.ts +2 -18
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/contract/client-types.d.ts +134 -0
- package/dist/contract/client-types.d.ts.map +1 -0
- package/dist/contract/define-validation.d.ts +30 -0
- package/dist/contract/define-validation.d.ts.map +1 -0
- package/dist/contract/define.d.ts +3 -357
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/runtime-context.d.ts +131 -0
- package/dist/contract/runtime-context.d.ts.map +1 -0
- package/dist/contract/tool-options.d.ts +105 -0
- package/dist/contract/tool-options.d.ts.map +1 -0
- package/dist/contract/tool-view.d.ts +15 -2
- package/dist/contract/tool-view.d.ts.map +1 -1
- package/dist/durability/contract.d.ts +83 -0
- package/dist/durability/contract.d.ts.map +1 -1
- package/dist/durability/effect.d.ts +24 -0
- package/dist/durability/effect.d.ts.map +1 -0
- package/dist/durability/engine.d.ts +2 -2
- package/dist/durability/engine.d.ts.map +1 -1
- package/dist/durability/events.d.ts +2 -0
- package/dist/durability/events.d.ts.map +1 -1
- package/dist/durability/ledger.d.ts +11 -0
- package/dist/durability/ledger.d.ts.map +1 -1
- package/dist/durability/parks.d.ts +22 -0
- package/dist/durability/parks.d.ts.map +1 -0
- package/dist/durability/scheduler.d.ts +1 -0
- package/dist/durability/scheduler.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/coding-tools.js +4 -4
- package/dist/entrypoints/agent-runtime/harness.js +127 -116
- package/dist/entrypoints/agent-runtime/sandbox.js +4 -4
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +3 -3
- package/dist/entrypoints/agent-runtime/sqlite/node.js +3 -3
- package/dist/entrypoints/agent-runtime/testing.js +246 -214
- package/dist/entrypoints/agent-runtime.js +224 -203
- package/dist/entrypoints/application/diagnostic-journal.js +63 -203
- package/dist/entrypoints/application/opentelemetry.js +1 -1
- package/dist/entrypoints/application.js +361 -324
- package/dist/entrypoints/cli.d.ts +4 -1
- package/dist/entrypoints/cli.d.ts.map +1 -1
- package/dist/entrypoints/cli.js +57 -35
- package/dist/entrypoints/contract.d.ts +5 -2
- package/dist/entrypoints/contract.d.ts.map +1 -1
- package/dist/entrypoints/contract.js +3 -2
- package/dist/entrypoints/files.d.ts +2 -0
- package/dist/entrypoints/files.d.ts.map +1 -1
- package/dist/entrypoints/files.js +98 -2
- package/dist/entrypoints/index.d.ts +4 -2
- package/dist/entrypoints/index.d.ts.map +1 -1
- package/dist/entrypoints/index.js +348 -282
- package/dist/entrypoints/live.js +89 -71
- package/dist/entrypoints/node.d.ts +2 -1
- package/dist/entrypoints/node.d.ts.map +1 -1
- package/dist/entrypoints/node.js +13 -12
- package/dist/entrypoints/react.js +1 -1
- package/dist/entrypoints/remote.js +4 -4
- package/dist/entrypoints/server.d.ts +4 -2
- package/dist/entrypoints/server.d.ts.map +1 -1
- package/dist/entrypoints/server.js +293 -79
- package/dist/entrypoints/testing.d.ts +2 -1
- package/dist/entrypoints/testing.d.ts.map +1 -1
- package/dist/entrypoints/testing.js +288 -281
- package/dist/entrypoints/tools/connections.js +2 -2
- package/dist/entrypoints/tools/invoker.js +4 -4
- package/dist/entrypoints/tools.d.ts +6 -3
- package/dist/entrypoints/tools.d.ts.map +1 -1
- package/dist/entrypoints/tools.js +245 -202
- package/dist/entrypoints/tracking.js +325 -274
- package/dist/files/boundary.d.ts.map +1 -1
- package/dist/files/file-io.d.ts +14 -0
- package/dist/files/file-io.d.ts.map +1 -0
- package/dist/index-1j8pm5t0.js +412 -0
- package/dist/{index-kvj7f4hq.js → index-2bxbyab0.js} +10 -2
- package/dist/{index-xnj9bgxe.js → index-2gxzjvyr.js} +2 -162
- package/dist/index-4gcnakhx.js +82 -0
- package/dist/{index-j05z5gn4.js → index-55hkhm67.js} +136 -119
- package/dist/{index-cq4qfycf.js → index-79z7m7dt.js} +227 -59
- package/dist/{index-97ac4gph.js → index-7f68ghdn.js} +3 -3
- package/dist/{index-r7nmqpsg.js → index-7p1f0vp2.js} +1 -1
- package/dist/{index-dcpdvjsc.js → index-863ea9jb.js} +4 -4
- package/dist/index-8p52kd5p.js +242 -0
- package/dist/{index-2qzskm8h.js → index-dce5wxcq.js} +1 -1
- package/dist/index-e01r054k.js +105 -0
- package/dist/{index-sees8yf8.js → index-ensd0r74.js} +118 -111
- package/dist/{index-1nd48tm9.js → index-gxrt5h6v.js} +2 -1
- package/dist/{index-e87kakm4.js → index-ham5sz8m.js} +112 -110
- package/dist/{index-kj2wbeta.js → index-het2he5g.js} +280 -196
- package/dist/{index-vcvkq30w.js → index-hmp4800j.js} +3 -3
- package/dist/{index-gyr48nzg.js → index-k30h66yd.js} +71 -151
- package/dist/{index-2cr1cqhn.js → index-khtgb21r.js} +2 -2
- package/dist/{index-x4799c19.js → index-ndddxtyx.js} +11 -11
- package/dist/{index-dydjcp8z.js → index-np4m8hd3.js} +38 -36
- package/dist/{index-p81267c2.js → index-p3vsv1fb.js} +621 -357
- package/dist/{index-mp5sn43f.js → index-p9e0w8hs.js} +2 -2
- package/dist/{index-rewkc2hj.js → index-p9sh0xx4.js} +3 -3
- package/dist/{index-70yj2ebz.js → index-paz6sgdp.js} +107 -103
- package/dist/{index-bn2cjajt.js → index-px2gm2jp.js} +26 -102
- package/dist/index-s812ycat.js +65 -0
- package/dist/{index-xsqjkha9.js → index-sp1tzwnb.js} +2 -2
- package/dist/{index-n6hxg8as.js → index-t9rhjr9f.js} +615 -566
- package/dist/{index-zeemqhqx.js → index-v260df89.js} +88 -80
- package/dist/{index-fdp6hdxn.js → index-w906953s.js} +5 -1
- package/dist/{index-mdzh02yc.js → index-wdkt63w3.js} +1 -1
- package/dist/{index-58k4fp34.js → index-wsm5w4ee.js} +1 -1
- package/dist/{index-v38qyerb.js → index-xw3s75nj.js} +1 -1
- package/dist/internal/atomic-file.d.ts +23 -2
- package/dist/internal/atomic-file.d.ts.map +1 -1
- package/dist/internal/exclusive-lock.d.ts +51 -0
- package/dist/internal/exclusive-lock.d.ts.map +1 -0
- package/dist/internal/process-identity.d.ts +47 -0
- package/dist/internal/process-identity.d.ts.map +1 -0
- package/dist/internal/with-exclusive-lock.d.ts +67 -0
- package/dist/internal/with-exclusive-lock.d.ts.map +1 -0
- package/dist/live/watch-client.d.ts.map +1 -1
- package/dist/observability/audit.d.ts +2 -2
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/event.d.ts +2 -1
- package/dist/observability/event.d.ts.map +1 -1
- package/dist/primitives/export-operation.d.ts +1 -1
- package/dist/primitives/export-operation.d.ts.map +1 -1
- package/dist/realtime/registry.d.ts +0 -5
- package/dist/realtime/registry.d.ts.map +1 -1
- package/dist/server/bun.d.ts +0 -1
- package/dist/server/bun.d.ts.map +1 -1
- package/dist/server/context-contribution.d.ts +1 -1
- package/dist/server/context-contribution.d.ts.map +1 -1
- package/dist/server/context.d.ts +1 -1
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/endpoint-response.d.ts +2 -1
- package/dist/server/endpoint-response.d.ts.map +1 -1
- package/dist/server/error-dispatch.d.ts +1 -1
- package/dist/server/error-dispatch.d.ts.map +1 -1
- package/dist/server/error-hook.d.ts +1 -1
- package/dist/server/error-hook.d.ts.map +1 -1
- package/dist/server/handler-state.d.ts +1 -1
- package/dist/server/handler-state.d.ts.map +1 -1
- package/dist/server/implement-registry.d.ts +54 -0
- package/dist/server/implement-registry.d.ts.map +1 -0
- package/dist/server/implement.d.ts +9 -55
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/middleware/auth.d.ts +1 -31
- package/dist/server/middleware/auth.d.ts.map +1 -1
- package/dist/server/middleware/jwt.d.ts +31 -0
- package/dist/server/middleware/jwt.d.ts.map +1 -0
- package/dist/server/multipart-reader.d.ts +22 -0
- package/dist/server/multipart-reader.d.ts.map +1 -0
- package/dist/server/multipart.d.ts +1 -1
- package/dist/server/multipart.d.ts.map +1 -1
- package/dist/server/oauth/cimd.d.ts +88 -0
- package/dist/server/oauth/cimd.d.ts.map +1 -0
- package/dist/server/oauth/endpoints.d.ts +39 -0
- package/dist/server/oauth/endpoints.d.ts.map +1 -0
- package/dist/server/oauth/provider.d.ts +1 -68
- package/dist/server/oauth/provider.d.ts.map +1 -1
- package/dist/server/streaming-pump.d.ts +66 -0
- package/dist/server/streaming-pump.d.ts.map +1 -0
- package/dist/server/streaming-route.d.ts +12 -5
- package/dist/server/streaming-route.d.ts.map +1 -1
- package/dist/server/types.d.ts +4 -1
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/unix-client-bun.d.ts.map +1 -1
- package/dist/server/unix-client-http1.d.ts +76 -0
- package/dist/server/unix-client-http1.d.ts.map +1 -0
- package/dist/server/unix-client.d.ts.map +1 -1
- package/dist/testing/handler-clients.d.ts +2 -1
- package/dist/testing/handler-clients.d.ts.map +1 -1
- package/dist/testing/realtime-probe.d.ts +33 -0
- package/dist/testing/realtime-probe.d.ts.map +1 -0
- package/dist/testing/surface-conformance.d.ts +0 -31
- package/dist/testing/surface-conformance.d.ts.map +1 -1
- package/dist/testing/surface-manifest-digest.d.ts +44 -0
- package/dist/testing/surface-manifest-digest.d.ts.map +1 -0
- package/dist/testing/surface-manifest.d.ts.map +1 -1
- package/dist/tools/agent.d.ts +1 -1
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/cli/args-fields.d.ts +31 -0
- package/dist/tools/cli/args-fields.d.ts.map +1 -0
- package/dist/tools/cli/args-route.d.ts +42 -0
- package/dist/tools/cli/args-route.d.ts.map +1 -0
- package/dist/tools/cli/args-view.d.ts +32 -0
- package/dist/tools/cli/args-view.d.ts.map +1 -0
- package/dist/tools/cli/args.d.ts +2 -65
- package/dist/tools/cli/args.d.ts.map +1 -1
- package/dist/tools/cli/argument-error.d.ts +5 -0
- package/dist/tools/cli/argument-error.d.ts.map +1 -0
- package/dist/tools/cli/checkpoint.d.ts.map +1 -1
- package/dist/tools/cli/command.d.ts +1 -1
- package/dist/tools/cli/command.d.ts.map +1 -1
- package/dist/tools/cli/config.d.ts +1 -1
- package/dist/tools/cli/config.d.ts.map +1 -1
- package/dist/tools/cli/format.d.ts +2 -1
- package/dist/tools/cli/format.d.ts.map +1 -1
- package/dist/tools/cli/invoke.d.ts +2 -1
- package/dist/tools/cli/invoke.d.ts.map +1 -1
- package/dist/tools/cli/managed-surface.d.ts +1 -1
- package/dist/tools/cli/managed-surface.d.ts.map +1 -1
- package/dist/tools/cli/policy.d.ts +1 -1
- package/dist/tools/cli/policy.d.ts.map +1 -1
- package/dist/tools/cli/prepare.d.ts.map +1 -1
- package/dist/tools/cli/run-managed.d.ts.map +1 -1
- package/dist/tools/cli/session.d.ts +1 -1
- package/dist/tools/cli/session.d.ts.map +1 -1
- package/dist/tools/cli/update.d.ts +19 -0
- package/dist/tools/cli/update.d.ts.map +1 -1
- package/dist/tools/cli/view.d.ts +1 -1
- package/dist/tools/cli/view.d.ts.map +1 -1
- package/dist/tools/cli/wait.d.ts +1 -1
- package/dist/tools/cli/wait.d.ts.map +1 -1
- package/dist/tools/connections/runtime.d.ts +1 -1
- package/dist/tools/connections/runtime.d.ts.map +1 -1
- package/dist/tools/execute-args.d.ts +23 -0
- package/dist/tools/execute-args.d.ts.map +1 -0
- package/dist/tools/execute-hooks.d.ts +146 -0
- package/dist/tools/execute-hooks.d.ts.map +1 -0
- package/dist/tools/execute-result.d.ts +40 -0
- package/dist/tools/execute-result.d.ts.map +1 -0
- package/dist/tools/execute.d.ts +4 -193
- package/dist/tools/execute.d.ts.map +1 -1
- package/dist/tools/internal/surface-projector.d.ts +2 -1
- package/dist/tools/internal/surface-projector.d.ts.map +1 -1
- package/dist/tools/invoker.d.ts +2 -1
- package/dist/tools/invoker.d.ts.map +1 -1
- package/dist/tools/lifecycle.d.ts +1 -1
- package/dist/tools/lifecycle.d.ts.map +1 -1
- package/dist/tools/mcp/mount.d.ts +1 -1
- package/dist/tools/mcp/mount.d.ts.map +1 -1
- package/dist/tools/mcp/prepare.d.ts +2 -1
- package/dist/tools/mcp/prepare.d.ts.map +1 -1
- package/dist/tools/mcp/progress.d.ts +1 -1
- package/dist/tools/mcp/progress.d.ts.map +1 -1
- package/dist/tools/mcp/register.d.ts +3 -2
- package/dist/tools/mcp/register.d.ts.map +1 -1
- package/dist/tools/mcp/round-context.d.ts +38 -0
- package/dist/tools/mcp/round-context.d.ts.map +1 -0
- package/dist/tools/mcp/round-policy.d.ts +1 -1
- package/dist/tools/mcp/round-policy.d.ts.map +1 -1
- package/dist/tools/mcp/round.d.ts +3 -11
- package/dist/tools/mcp/round.d.ts.map +1 -1
- package/dist/tools/mcp/runtime-tools.d.ts +2 -1
- package/dist/tools/mcp/runtime-tools.d.ts.map +1 -1
- package/dist/tools/mount.d.ts +3 -1
- package/dist/tools/mount.d.ts.map +1 -1
- package/dist/tools/native-definition.d.ts +2 -1
- package/dist/tools/native-definition.d.ts.map +1 -1
- package/dist/tools/operations/async-operation-runtime-tools.d.ts +2 -1
- package/dist/tools/operations/async-operation-runtime-tools.d.ts.map +1 -1
- package/dist/tools/operations/async-operation-runtime-types.d.ts +2 -1
- package/dist/tools/operations/async-operation-runtime-types.d.ts.map +1 -1
- package/dist/tools/remote.d.ts.map +1 -1
- package/dist/tools/runtime-tool.d.ts +3 -1
- package/dist/tools/runtime-tool.d.ts.map +1 -1
- package/dist/tools/tool-logger.d.ts +1 -1
- package/dist/tools/tool-logger.d.ts.map +1 -1
- package/dist/tracking/client-listeners.d.ts +30 -0
- package/dist/tracking/client-listeners.d.ts.map +1 -0
- package/dist/tracking/client-visit.d.ts +61 -0
- package/dist/tracking/client-visit.d.ts.map +1 -0
- package/dist/tracking/client.d.ts +3 -2
- package/dist/tracking/client.d.ts.map +1 -1
- package/llms/application.2.txt +266 -2
- package/llms/application.txt +8 -266
- package/llms/cli.2.txt +80 -0
- package/llms/cli.txt +45 -74
- package/llms/contract.txt +3 -3
- package/llms/files.txt +3 -0
- package/llms/tools.2.txt +88 -279
- package/llms/tools.3.txt +288 -0
- package/llms/tools.txt +27 -65
- package/llms-full.txt +108 -12
- package/llms.txt +5 -5
- package/package.json +1 -1
- package/dist/index-e2z3ahw9.js +0 -325
- package/dist/index-mkm15s49.js +0 -394
|
@@ -11,7 +11,7 @@ var RealtimeRequestPhaseEventSchema = z.object({
|
|
|
11
11
|
requestId: z.string().min(1),
|
|
12
12
|
event: z.string().min(1),
|
|
13
13
|
phase: RealtimeRequestPhaseSchema,
|
|
14
|
-
elapsedMs: z.number().
|
|
14
|
+
elapsedMs: z.number().nonnegative()
|
|
15
15
|
}).strict();
|
|
16
16
|
|
|
17
17
|
class RealtimeRequestTimeoutError extends Error {
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
deriveCodeChallenge
|
|
3
|
+
} from "./index-hr4tzbwq.js";
|
|
4
|
+
import {
|
|
5
|
+
base64UrlToBytes,
|
|
6
|
+
bytesToBase64Url
|
|
7
|
+
} from "./index-rxfy4cq7.js";
|
|
8
|
+
import {
|
|
9
|
+
unauthorized
|
|
10
|
+
} from "./index-2vtcmrj9.js";
|
|
11
|
+
import {
|
|
12
|
+
safeJsonParse
|
|
13
|
+
} from "./index-kzfs85xp.js";
|
|
14
|
+
import {
|
|
15
|
+
isRecord
|
|
16
|
+
} from "./index-hffjpmq9.js";
|
|
17
|
+
|
|
18
|
+
// src/server/middleware/jwt.ts
|
|
19
|
+
var MAX_TOKEN_BYTES = 8192;
|
|
20
|
+
async function verifyJwt(token, secret, options = {}) {
|
|
21
|
+
if (!secret)
|
|
22
|
+
throw new Error("verifyJwt: a non-empty secret is required");
|
|
23
|
+
if (token.length > MAX_TOKEN_BYTES)
|
|
24
|
+
throw unauthorized("Token too large");
|
|
25
|
+
const [headerB64, payloadB64, signatureB64] = token.split(".");
|
|
26
|
+
if (!headerB64 || !payloadB64 || !signatureB64)
|
|
27
|
+
throw unauthorized("Invalid token format");
|
|
28
|
+
let header;
|
|
29
|
+
let payloadRaw;
|
|
30
|
+
let signature;
|
|
31
|
+
try {
|
|
32
|
+
const decoder = new TextDecoder;
|
|
33
|
+
header = JSON.parse(decoder.decode(base64UrlToBytes(headerB64)));
|
|
34
|
+
payloadRaw = safeJsonParse(decoder.decode(base64UrlToBytes(payloadB64)));
|
|
35
|
+
signature = base64UrlToBytes(signatureB64);
|
|
36
|
+
} catch {
|
|
37
|
+
throw unauthorized("Malformed token");
|
|
38
|
+
}
|
|
39
|
+
if (!isRecord(payloadRaw))
|
|
40
|
+
throw unauthorized("Malformed token");
|
|
41
|
+
const payload = payloadRaw;
|
|
42
|
+
if (header.alg !== "HS256")
|
|
43
|
+
throw unauthorized("Unsupported token algorithm");
|
|
44
|
+
const encoder = new TextEncoder;
|
|
45
|
+
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
|
|
46
|
+
const data = encoder.encode(`${headerB64}.${payloadB64}`);
|
|
47
|
+
const valid = await crypto.subtle.verify("HMAC", key, signature, data);
|
|
48
|
+
if (!valid)
|
|
49
|
+
throw unauthorized("Invalid token signature");
|
|
50
|
+
const leeway = options.leewaySeconds ?? 60;
|
|
51
|
+
const now = Date.now() / 1000;
|
|
52
|
+
if ("exp" in payload) {
|
|
53
|
+
if (typeof payload.exp !== "number")
|
|
54
|
+
throw unauthorized("Malformed token");
|
|
55
|
+
if (payload.exp < now - leeway)
|
|
56
|
+
throw unauthorized("Token expired");
|
|
57
|
+
}
|
|
58
|
+
if ("nbf" in payload) {
|
|
59
|
+
if (typeof payload.nbf !== "number")
|
|
60
|
+
throw unauthorized("Malformed token");
|
|
61
|
+
if (payload.nbf > now + leeway)
|
|
62
|
+
throw unauthorized("Token not yet valid");
|
|
63
|
+
}
|
|
64
|
+
if (options.issuer !== undefined && payload.iss !== options.issuer) {
|
|
65
|
+
throw unauthorized("Token issuer mismatch");
|
|
66
|
+
}
|
|
67
|
+
if (options.audience !== undefined) {
|
|
68
|
+
const aud = payload.aud;
|
|
69
|
+
const ok = Array.isArray(aud) ? aud.includes(options.audience) : aud === options.audience;
|
|
70
|
+
if (!ok)
|
|
71
|
+
throw unauthorized("Token audience mismatch");
|
|
72
|
+
}
|
|
73
|
+
return payload;
|
|
74
|
+
}
|
|
75
|
+
async function signJwt(payload, secret, options = {}) {
|
|
76
|
+
if (!secret)
|
|
77
|
+
throw new Error("signJwt: a non-empty secret is required");
|
|
78
|
+
const now = Math.floor(Date.now() / 1000);
|
|
79
|
+
const claims = {
|
|
80
|
+
...payload,
|
|
81
|
+
iat: now,
|
|
82
|
+
...options.expiresInSec !== undefined && { exp: now + options.expiresInSec },
|
|
83
|
+
...options.issuer !== undefined && { iss: options.issuer },
|
|
84
|
+
...options.audience !== undefined && { aud: options.audience },
|
|
85
|
+
...options.subject !== undefined && { sub: options.subject }
|
|
86
|
+
};
|
|
87
|
+
const encoder = new TextEncoder;
|
|
88
|
+
const headerB64 = bytesToBase64Url(encoder.encode(JSON.stringify({ alg: "HS256", typ: "JWT" })));
|
|
89
|
+
const payloadB64 = bytesToBase64Url(encoder.encode(JSON.stringify(claims)));
|
|
90
|
+
const signingInput = `${headerB64}.${payloadB64}`;
|
|
91
|
+
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
92
|
+
const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(signingInput));
|
|
93
|
+
const signatureB64 = bytesToBase64Url(new Uint8Array(signature));
|
|
94
|
+
return `${signingInput}.${signatureB64}`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// src/server/middleware/pkce.ts
|
|
98
|
+
async function verifyPkce(verifier, challenge) {
|
|
99
|
+
if (!verifier || !challenge)
|
|
100
|
+
return false;
|
|
101
|
+
const derived = await deriveCodeChallenge(verifier);
|
|
102
|
+
return derived === challenge;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export { verifyJwt, signJwt, verifyPkce };
|
|
@@ -329,6 +329,90 @@ var systemClock = {
|
|
|
329
329
|
}
|
|
330
330
|
};
|
|
331
331
|
var DEFAULT_OVERLAP = { mode: "skip" };
|
|
332
|
+
function scheduleState(activated, stopped, accepting, active) {
|
|
333
|
+
if (!activated)
|
|
334
|
+
return stopped ? "stopped" : "inactive";
|
|
335
|
+
if (!accepting)
|
|
336
|
+
return active > 0 ? "draining" : "stopped";
|
|
337
|
+
return active > 0 ? "running" : "scheduled";
|
|
338
|
+
}
|
|
339
|
+
function wallAt(monotonicAt, anchor) {
|
|
340
|
+
if (monotonicAt === null)
|
|
341
|
+
return null;
|
|
342
|
+
return new Date(anchor.wallNow + monotonicAt - anchor.monotonicNow).toISOString();
|
|
343
|
+
}
|
|
344
|
+
function overlapDecision(overlap, active) {
|
|
345
|
+
if (overlap.mode === "skip")
|
|
346
|
+
return active > 0 ? "skip" : "start";
|
|
347
|
+
if (overlap.mode === "queue-one")
|
|
348
|
+
return active > 0 ? "queue" : "start";
|
|
349
|
+
return active >= overlap.maxConcurrent ? "skip" : "start";
|
|
350
|
+
}
|
|
351
|
+
function reportScheduleError(config, error, context) {
|
|
352
|
+
if (!config.onError)
|
|
353
|
+
return;
|
|
354
|
+
Promise.resolve().then(() => config.onError?.(error, context)).catch(() => {});
|
|
355
|
+
}
|
|
356
|
+
async function waitForSettled(active, clock, context, deadlineAt) {
|
|
357
|
+
if (active.size === 0 || context.signal.aborted)
|
|
358
|
+
return;
|
|
359
|
+
await new Promise((resolve) => {
|
|
360
|
+
let settled = false;
|
|
361
|
+
let deadlineTimer = null;
|
|
362
|
+
const finish = () => {
|
|
363
|
+
if (settled)
|
|
364
|
+
return;
|
|
365
|
+
settled = true;
|
|
366
|
+
deadlineTimer?.cancel();
|
|
367
|
+
context.signal.removeEventListener("abort", finish);
|
|
368
|
+
resolve();
|
|
369
|
+
};
|
|
370
|
+
context.signal.addEventListener("abort", finish, { once: true });
|
|
371
|
+
if (deadlineAt !== undefined) {
|
|
372
|
+
deadlineTimer = clock.schedule(finish, Math.max(0, deadlineAt - context.now()));
|
|
373
|
+
}
|
|
374
|
+
Promise.allSettled([...active]).then(finish);
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
async function executeRun(deps, scheduledAt) {
|
|
378
|
+
const { config, descriptor, clock, counts, resourceContext } = deps;
|
|
379
|
+
const startedAt = clock.now();
|
|
380
|
+
const wallStartedAt = clock.wallNow().getTime();
|
|
381
|
+
const runContext = {
|
|
382
|
+
applicationId: resourceContext.applicationId,
|
|
383
|
+
signal: resourceContext.signal,
|
|
384
|
+
scheduledAt,
|
|
385
|
+
startedAt,
|
|
386
|
+
now: () => clock.now()
|
|
387
|
+
};
|
|
388
|
+
counts.runsStarted += 1;
|
|
389
|
+
counts.lastScheduledAt = new Date(wallStartedAt + scheduledAt - startedAt).toISOString();
|
|
390
|
+
counts.lastStartedAt = new Date(wallStartedAt).toISOString();
|
|
391
|
+
deps.changed();
|
|
392
|
+
try {
|
|
393
|
+
await Promise.resolve();
|
|
394
|
+
await config.run(runContext);
|
|
395
|
+
} catch (error) {
|
|
396
|
+
counts.runsFailed += 1;
|
|
397
|
+
counts.lastFinishedAt = clock.wallNow().toISOString();
|
|
398
|
+
reportScheduleError(config, error, runContext);
|
|
399
|
+
if (descriptor.errorPolicy === "stop-schedule") {
|
|
400
|
+
resourceContext.reportHealth("unhealthy");
|
|
401
|
+
deps.stopAdmission();
|
|
402
|
+
} else {
|
|
403
|
+
resourceContext.reportHealth("degraded");
|
|
404
|
+
}
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
counts.runsCompleted += 1;
|
|
408
|
+
counts.lastFinishedAt = clock.wallNow().toISOString();
|
|
409
|
+
if (descriptor.errorPolicy === "continue" && deps.isAccepting()) {
|
|
410
|
+
resourceContext.reportHealth("healthy");
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
function elapsedIntervals(scheduledAt, observedAt, everyMs) {
|
|
414
|
+
return Math.max(1, Math.floor((observedAt - scheduledAt) / everyMs) + 1);
|
|
415
|
+
}
|
|
332
416
|
function createManagedSchedule(config) {
|
|
333
417
|
const descriptor = ManagedScheduleDescriptorSchema.parse({
|
|
334
418
|
id: config.id,
|
|
@@ -347,13 +431,15 @@ function createManagedSchedule(config) {
|
|
|
347
431
|
let activationContext = null;
|
|
348
432
|
let nextRunAt = null;
|
|
349
433
|
let queuedAt = null;
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
434
|
+
const counts = {
|
|
435
|
+
runsStarted: 0,
|
|
436
|
+
runsCompleted: 0,
|
|
437
|
+
runsFailed: 0,
|
|
438
|
+
ticksSkipped: 0,
|
|
439
|
+
lastScheduledAt: null,
|
|
440
|
+
lastStartedAt: null,
|
|
441
|
+
lastFinishedAt: null
|
|
442
|
+
};
|
|
357
443
|
let changedAt = clock.wallNow().toISOString();
|
|
358
444
|
const active = new Set;
|
|
359
445
|
const changed = () => {
|
|
@@ -374,43 +460,20 @@ function createManagedSchedule(config) {
|
|
|
374
460
|
cancelFuture();
|
|
375
461
|
changed();
|
|
376
462
|
};
|
|
377
|
-
const reportError = (error, context) => {
|
|
378
|
-
if (!config.onError)
|
|
379
|
-
return;
|
|
380
|
-
Promise.resolve().then(() => config.onError?.(error, context)).catch(() => {});
|
|
381
|
-
};
|
|
382
|
-
const state = () => {
|
|
383
|
-
if (!activated)
|
|
384
|
-
return stopped ? "stopped" : "inactive";
|
|
385
|
-
if (!accepting)
|
|
386
|
-
return active.size > 0 ? "draining" : "stopped";
|
|
387
|
-
return active.size > 0 ? "running" : "scheduled";
|
|
388
|
-
};
|
|
389
|
-
const wallAt = (monotonicAt, anchor) => {
|
|
390
|
-
if (monotonicAt === null)
|
|
391
|
-
return null;
|
|
392
|
-
return new Date(anchor.wallNow + monotonicAt - anchor.monotonicNow).toISOString();
|
|
393
|
-
};
|
|
394
463
|
const status = () => {
|
|
395
464
|
const captured = clock.wallNow();
|
|
396
465
|
const anchor = { monotonicNow: clock.now(), wallNow: captured.getTime() };
|
|
397
466
|
return ManagedScheduleStatusSchema.parse({
|
|
398
467
|
descriptor,
|
|
399
|
-
state:
|
|
468
|
+
state: scheduleState(activated, stopped, accepting, active.size),
|
|
400
469
|
revision,
|
|
401
470
|
capturedAt: captured.toISOString(),
|
|
402
471
|
changedAt,
|
|
403
472
|
accepting,
|
|
404
473
|
active: active.size,
|
|
405
474
|
queued: queuedAt !== null,
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
runsFailed,
|
|
409
|
-
ticksSkipped,
|
|
410
|
-
nextRunAt: wallAt(nextRunAt, anchor),
|
|
411
|
-
lastScheduledAt,
|
|
412
|
-
lastStartedAt,
|
|
413
|
-
lastFinishedAt
|
|
475
|
+
...counts,
|
|
476
|
+
nextRunAt: wallAt(nextRunAt, anchor)
|
|
414
477
|
});
|
|
415
478
|
};
|
|
416
479
|
let startExecution = () => {
|
|
@@ -428,37 +491,16 @@ function createManagedSchedule(config) {
|
|
|
428
491
|
const resourceContext = activationContext;
|
|
429
492
|
if (!accepting || !resourceContext)
|
|
430
493
|
return;
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
lastScheduledAt = new Date(wallStartedAt + scheduledAt - startedAt).toISOString();
|
|
442
|
-
lastStartedAt = new Date(wallStartedAt).toISOString();
|
|
443
|
-
changed();
|
|
444
|
-
let tracked;
|
|
445
|
-
tracked = Promise.resolve().then(() => config.run(runContext)).then(() => {
|
|
446
|
-
runsCompleted += 1;
|
|
447
|
-
lastFinishedAt = clock.wallNow().toISOString();
|
|
448
|
-
if (descriptor.errorPolicy === "continue" && accepting) {
|
|
449
|
-
resourceContext.reportHealth("healthy");
|
|
450
|
-
}
|
|
451
|
-
}, (error) => {
|
|
452
|
-
runsFailed += 1;
|
|
453
|
-
lastFinishedAt = clock.wallNow().toISOString();
|
|
454
|
-
reportError(error, runContext);
|
|
455
|
-
if (descriptor.errorPolicy === "stop-schedule") {
|
|
456
|
-
resourceContext.reportHealth("unhealthy");
|
|
457
|
-
stopAdmission();
|
|
458
|
-
} else {
|
|
459
|
-
resourceContext.reportHealth("degraded");
|
|
460
|
-
}
|
|
461
|
-
}).finally(() => {
|
|
494
|
+
const tracked = executeRun({
|
|
495
|
+
config,
|
|
496
|
+
descriptor,
|
|
497
|
+
clock,
|
|
498
|
+
counts,
|
|
499
|
+
resourceContext,
|
|
500
|
+
changed,
|
|
501
|
+
stopAdmission,
|
|
502
|
+
isAccepting: () => accepting
|
|
503
|
+
}, scheduledAt).finally(() => {
|
|
462
504
|
active.delete(tracked);
|
|
463
505
|
changed();
|
|
464
506
|
settleExecution();
|
|
@@ -468,30 +510,16 @@ function createManagedSchedule(config) {
|
|
|
468
510
|
const dispatchTick = (scheduledAt) => {
|
|
469
511
|
if (!accepting)
|
|
470
512
|
return;
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
ticksSkipped += 1;
|
|
474
|
-
changed();
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
513
|
+
const decision = overlapDecision(descriptor.overlap, active.size);
|
|
514
|
+
if (decision === "start") {
|
|
477
515
|
startExecution(scheduledAt);
|
|
478
516
|
return;
|
|
479
517
|
}
|
|
480
|
-
if (
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
}
|
|
486
|
-
startExecution(scheduledAt);
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
if (active.size >= descriptor.overlap.maxConcurrent) {
|
|
490
|
-
ticksSkipped += 1;
|
|
491
|
-
changed();
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
|
-
startExecution(scheduledAt);
|
|
518
|
+
if (decision === "queue")
|
|
519
|
+
queuedAt = scheduledAt;
|
|
520
|
+
else
|
|
521
|
+
counts.ticksSkipped += 1;
|
|
522
|
+
changed();
|
|
495
523
|
};
|
|
496
524
|
const arm = () => {
|
|
497
525
|
if (!accepting || nextRunAt === null)
|
|
@@ -502,38 +530,17 @@ function createManagedSchedule(config) {
|
|
|
502
530
|
if (!accepting || nextRunAt === null)
|
|
503
531
|
return;
|
|
504
532
|
const scheduledAt = nextRunAt;
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
ticksSkipped += elapsedIntervals - 1;
|
|
533
|
+
const elapsed = elapsedIntervals(scheduledAt, clock.now(), descriptor.everyMs);
|
|
534
|
+
if (elapsed > 1) {
|
|
535
|
+
counts.ticksSkipped += elapsed - 1;
|
|
509
536
|
changed();
|
|
510
537
|
}
|
|
511
|
-
nextRunAt = scheduledAt +
|
|
538
|
+
nextRunAt = scheduledAt + elapsed * descriptor.everyMs;
|
|
512
539
|
arm();
|
|
513
540
|
dispatchTick(scheduledAt);
|
|
514
541
|
}, delayMs);
|
|
515
542
|
};
|
|
516
|
-
const waitForActive =
|
|
517
|
-
if (active.size === 0 || context.signal.aborted)
|
|
518
|
-
return;
|
|
519
|
-
await new Promise((resolve) => {
|
|
520
|
-
let settled = false;
|
|
521
|
-
let deadlineTimer = null;
|
|
522
|
-
const finish = () => {
|
|
523
|
-
if (settled)
|
|
524
|
-
return;
|
|
525
|
-
settled = true;
|
|
526
|
-
deadlineTimer?.cancel();
|
|
527
|
-
context.signal.removeEventListener("abort", finish);
|
|
528
|
-
resolve();
|
|
529
|
-
};
|
|
530
|
-
context.signal.addEventListener("abort", finish, { once: true });
|
|
531
|
-
if (deadlineAt !== undefined) {
|
|
532
|
-
deadlineTimer = clock.schedule(finish, Math.max(0, deadlineAt - context.now()));
|
|
533
|
-
}
|
|
534
|
-
Promise.allSettled([...active]).then(finish);
|
|
535
|
-
});
|
|
536
|
-
};
|
|
543
|
+
const waitForActive = (context, deadlineAt) => waitForSettled(active, clock, context, deadlineAt);
|
|
537
544
|
const drain = async (context) => {
|
|
538
545
|
stopAdmission();
|
|
539
546
|
await waitForActive(context, context.deadlineAt);
|
|
@@ -36,7 +36,8 @@ var AgentStoreEventKindSchema = z.enum([
|
|
|
36
36
|
"approval/response-rejected",
|
|
37
37
|
"durability/step",
|
|
38
38
|
"durability/park",
|
|
39
|
-
"durability/event"
|
|
39
|
+
"durability/event",
|
|
40
|
+
"durability/effect"
|
|
40
41
|
]);
|
|
41
42
|
var AgentStoreEventEnvelopeSchema = z.object({
|
|
42
43
|
schemaVersion: z.int().positive(),
|
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
parseApiErrorBody,
|
|
13
13
|
refuseLocally,
|
|
14
14
|
responseTraceId
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-v260df89.js";
|
|
16
16
|
import {
|
|
17
17
|
parseTrailingWildcard
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-4gcnakhx.js";
|
|
19
19
|
import {
|
|
20
20
|
isRecord,
|
|
21
21
|
mapObject,
|
|
@@ -433,7 +433,7 @@ function parseContractStream(response, descriptor, abort) {
|
|
|
433
433
|
return new OwnedContractStream(readContractStream(response, descriptor, abort), abort);
|
|
434
434
|
}
|
|
435
435
|
|
|
436
|
-
// src/browser/client.ts
|
|
436
|
+
// src/browser/client-executors.ts
|
|
437
437
|
function withTimeout(options, endpoint) {
|
|
438
438
|
const responseType = endpoint.rawResponse || "stream" in endpoint ? "response" : endpoint.output ? undefined : "void";
|
|
439
439
|
if (endpoint.timeout === undefined && responseType === undefined)
|
|
@@ -474,104 +474,6 @@ function withOutput(endpoint, result, abortStream) {
|
|
|
474
474
|
return schema.parse(value);
|
|
475
475
|
});
|
|
476
476
|
}
|
|
477
|
-
function contractEndpointMatchers(contract, endpointNames, contractConfig) {
|
|
478
|
-
const selected = endpointNames ? new Set(endpointNames) : null;
|
|
479
|
-
const matchers = [];
|
|
480
|
-
for (const [key, endpoint] of typedEntries(contract.endpoints)) {
|
|
481
|
-
if (selected && !selected.has(key))
|
|
482
|
-
continue;
|
|
483
|
-
if (endpoint.expose && !endpoint.expose.includes("HTTP")) {
|
|
484
|
-
if (selected) {
|
|
485
|
-
throw new Error(`Cannot create an HTTP route matcher for non-HTTP endpoint: ${String(key)}`);
|
|
486
|
-
}
|
|
487
|
-
continue;
|
|
488
|
-
}
|
|
489
|
-
matchers.push(createClientRouteMatcher(endpoint, contract.meta.prefix, contractConfig));
|
|
490
|
-
}
|
|
491
|
-
if (selected && matchers.length !== selected.size) {
|
|
492
|
-
throw new Error("Cannot create an HTTP route matcher for an unknown endpoint");
|
|
493
|
-
}
|
|
494
|
-
return matchers;
|
|
495
|
-
}
|
|
496
|
-
function createClient(contract, configOrClient, contractConfig) {
|
|
497
|
-
const client = {};
|
|
498
|
-
const makeExecutor = isHttpAdapter(configOrClient) ? (endpoint) => createHttpExecutor(endpoint, contract.meta.prefix, configOrClient, contractConfig) : (endpoint) => createFetchExecutor(endpoint, contract.meta.prefix, configOrClient, contractConfig);
|
|
499
|
-
for (const [key, endpoint] of typedEntries(contract.endpoints)) {
|
|
500
|
-
if (endpoint.expose && !endpoint.expose.includes("HTTP"))
|
|
501
|
-
continue;
|
|
502
|
-
setClientMethod(client, key, createEndpointMethod(endpoint, makeExecutor(endpoint), contractConfig));
|
|
503
|
-
}
|
|
504
|
-
return client;
|
|
505
|
-
}
|
|
506
|
-
function createClients(contracts, configOrClient, contractConfig) {
|
|
507
|
-
return mapObject(contracts, (_key, contract) => createClient(contract, configOrClient, contractConfig));
|
|
508
|
-
}
|
|
509
|
-
function buildScopedRegistry(contracts, scopeConfigs, surfaceName, build) {
|
|
510
|
-
const registry = {};
|
|
511
|
-
for (const [namespace, value] of Object.entries(contracts)) {
|
|
512
|
-
const list = Array.isArray(value) ? value : [value];
|
|
513
|
-
const surface = {};
|
|
514
|
-
for (const contract of list) {
|
|
515
|
-
const scope = contract.meta.scope;
|
|
516
|
-
if (!scope) {
|
|
517
|
-
throw new Error(`Contract in ${surfaceName} namespace "${namespace}" has no scope`);
|
|
518
|
-
}
|
|
519
|
-
const scopeConfig = scopeConfigs[scope];
|
|
520
|
-
if (!scopeConfig) {
|
|
521
|
-
throw new Error(`Missing ${surfaceName} config for scope: ${scope}`);
|
|
522
|
-
}
|
|
523
|
-
for (const [methodName, method] of Object.entries(build(contract, scopeConfig))) {
|
|
524
|
-
if (Object.hasOwn(surface, methodName)) {
|
|
525
|
-
throw new Error(`${surfaceName[0]?.toUpperCase()}${surfaceName.slice(1)} namespace "${namespace}" has duplicate method: ${methodName}`);
|
|
526
|
-
}
|
|
527
|
-
surface[methodName] = method;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
registry[namespace] = surface;
|
|
531
|
-
}
|
|
532
|
-
return registry;
|
|
533
|
-
}
|
|
534
|
-
function createScopedClients(contracts, configOrClient, scopeConfigs) {
|
|
535
|
-
return buildScopedRegistry(contracts, scopeConfigs, "client", (contract, config) => createClient(contract, configOrClient, config));
|
|
536
|
-
}
|
|
537
|
-
function isHttpAdapter(value) {
|
|
538
|
-
return typeof value === "object" && "get" in value && typeof value.get === "function";
|
|
539
|
-
}
|
|
540
|
-
function setClientMethod(target, key, method) {
|
|
541
|
-
target[key] = method;
|
|
542
|
-
}
|
|
543
|
-
function createEndpointMethod(endpoint, execute, contractConfig) {
|
|
544
|
-
const hasScopedArguments = (contractConfig?.stripPrefixKeys?.length ?? 0) > 0;
|
|
545
|
-
if (endpointHasArguments(endpoint) || hasScopedArguments) {
|
|
546
|
-
const method2 = (requestArgs) => settle(execute, readClientRequestArgs(requestArgs), undefined);
|
|
547
|
-
return Object.assign(method2, {
|
|
548
|
-
withOptions: (...args) => {
|
|
549
|
-
refuseExtraWithOptionsArguments(endpoint, args.length, 2);
|
|
550
|
-
return settle(execute, readClientRequestArgs(args[0]), readClientRequestOptions(args[1]));
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
const method = () => settle(execute, {}, undefined);
|
|
555
|
-
return Object.assign(method, {
|
|
556
|
-
withOptions: (...args) => {
|
|
557
|
-
refuseExtraWithOptionsArguments(endpoint, args.length, 1);
|
|
558
|
-
return settle(execute, {}, readClientRequestOptions(args[0]));
|
|
559
|
-
}
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
function settle(execute, requestArgs, options) {
|
|
563
|
-
try {
|
|
564
|
-
return execute(requestArgs, options);
|
|
565
|
-
} catch (error) {
|
|
566
|
-
return Promise.reject(error);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
function refuseExtraWithOptionsArguments(endpoint, received, expected) {
|
|
570
|
-
if (received <= expected)
|
|
571
|
-
return;
|
|
572
|
-
const shape = expected === 1 ? "withOptions(options)" : "withOptions(args, options)";
|
|
573
|
-
throw new TypeError(`${endpoint.method} ${endpoint.path}: this endpoint declares ${expected === 1 ? "no input" : "an input"}, so its method is ${shape} — it received ${received} arguments. ` + "An extra argument here is dropped, and a request options object in the dropped position " + "sends the request without them: an abort signal placed there never reaches the server.");
|
|
574
|
-
}
|
|
575
477
|
function createHttpExecutor(endpoint, prefix, client, config) {
|
|
576
478
|
const httpMethod = endpoint.method.toLowerCase();
|
|
577
479
|
return (requestArgs, options) => {
|
|
@@ -674,6 +576,115 @@ function createFetchExecutor(endpoint, prefix, config, contractConfig) {
|
|
|
674
576
|
}
|
|
675
577
|
};
|
|
676
578
|
}
|
|
579
|
+
async function throwForErrorResponse(res, config, fallbackBody) {
|
|
580
|
+
const body = await res.json().catch(() => fallbackBody);
|
|
581
|
+
config.onError?.(res.status, body);
|
|
582
|
+
const parsed = parseApiErrorBody(body);
|
|
583
|
+
if (parsed) {
|
|
584
|
+
throw new ApiError(parsed.code, res.status, parsed.details, parsed.message, parsed.hint, responseTraceId(res));
|
|
585
|
+
}
|
|
586
|
+
throw new ApiError("HTTP_ERROR", res.status, { body }, undefined, undefined, responseTraceId(res));
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// src/browser/client.ts
|
|
590
|
+
function contractEndpointMatchers(contract, endpointNames, contractConfig) {
|
|
591
|
+
const selected = endpointNames ? new Set(endpointNames) : null;
|
|
592
|
+
const matchers = [];
|
|
593
|
+
for (const [key, endpoint] of typedEntries(contract.endpoints)) {
|
|
594
|
+
if (selected && !selected.has(key))
|
|
595
|
+
continue;
|
|
596
|
+
if (endpoint.expose && !endpoint.expose.includes("HTTP")) {
|
|
597
|
+
if (selected) {
|
|
598
|
+
throw new Error(`Cannot create an HTTP route matcher for non-HTTP endpoint: ${String(key)}`);
|
|
599
|
+
}
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
matchers.push(createClientRouteMatcher(endpoint, contract.meta.prefix, contractConfig));
|
|
603
|
+
}
|
|
604
|
+
if (selected && matchers.length !== selected.size) {
|
|
605
|
+
throw new Error("Cannot create an HTTP route matcher for an unknown endpoint");
|
|
606
|
+
}
|
|
607
|
+
return matchers;
|
|
608
|
+
}
|
|
609
|
+
function createClient(contract, configOrClient, contractConfig) {
|
|
610
|
+
const client = {};
|
|
611
|
+
const makeExecutor = isHttpAdapter(configOrClient) ? (endpoint) => createHttpExecutor(endpoint, contract.meta.prefix, configOrClient, contractConfig) : (endpoint) => createFetchExecutor(endpoint, contract.meta.prefix, configOrClient, contractConfig);
|
|
612
|
+
for (const [key, endpoint] of typedEntries(contract.endpoints)) {
|
|
613
|
+
if (endpoint.expose && !endpoint.expose.includes("HTTP"))
|
|
614
|
+
continue;
|
|
615
|
+
setClientMethod(client, key, createEndpointMethod(endpoint, makeExecutor(endpoint), contractConfig));
|
|
616
|
+
}
|
|
617
|
+
return client;
|
|
618
|
+
}
|
|
619
|
+
function createClients(contracts, configOrClient, contractConfig) {
|
|
620
|
+
return mapObject(contracts, (_key, contract) => createClient(contract, configOrClient, contractConfig));
|
|
621
|
+
}
|
|
622
|
+
function buildScopedRegistry(contracts, scopeConfigs, surfaceName, build) {
|
|
623
|
+
const registry = {};
|
|
624
|
+
for (const [namespace, value] of Object.entries(contracts)) {
|
|
625
|
+
const list = Array.isArray(value) ? value : [value];
|
|
626
|
+
const surface = {};
|
|
627
|
+
for (const contract of list) {
|
|
628
|
+
const scope = contract.meta.scope;
|
|
629
|
+
if (!scope) {
|
|
630
|
+
throw new Error(`Contract in ${surfaceName} namespace "${namespace}" has no scope`);
|
|
631
|
+
}
|
|
632
|
+
const scopeConfig = scopeConfigs[scope];
|
|
633
|
+
if (!scopeConfig) {
|
|
634
|
+
throw new Error(`Missing ${surfaceName} config for scope: ${scope}`);
|
|
635
|
+
}
|
|
636
|
+
for (const [methodName, method] of Object.entries(build(contract, scopeConfig))) {
|
|
637
|
+
if (Object.hasOwn(surface, methodName)) {
|
|
638
|
+
throw new Error(`${surfaceName[0]?.toUpperCase()}${surfaceName.slice(1)} namespace "${namespace}" has duplicate method: ${methodName}`);
|
|
639
|
+
}
|
|
640
|
+
surface[methodName] = method;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
registry[namespace] = surface;
|
|
644
|
+
}
|
|
645
|
+
return registry;
|
|
646
|
+
}
|
|
647
|
+
function createScopedClients(contracts, configOrClient, scopeConfigs) {
|
|
648
|
+
return buildScopedRegistry(contracts, scopeConfigs, "client", (contract, config) => createClient(contract, configOrClient, config));
|
|
649
|
+
}
|
|
650
|
+
function isHttpAdapter(value) {
|
|
651
|
+
return typeof value === "object" && "get" in value && typeof value.get === "function";
|
|
652
|
+
}
|
|
653
|
+
function setClientMethod(target, key, method) {
|
|
654
|
+
target[key] = method;
|
|
655
|
+
}
|
|
656
|
+
function createEndpointMethod(endpoint, execute, contractConfig) {
|
|
657
|
+
const hasScopedArguments = (contractConfig?.stripPrefixKeys?.length ?? 0) > 0;
|
|
658
|
+
if (endpointHasArguments(endpoint) || hasScopedArguments) {
|
|
659
|
+
const method2 = (requestArgs) => settle(execute, readClientRequestArgs(requestArgs), undefined);
|
|
660
|
+
return Object.assign(method2, {
|
|
661
|
+
withOptions: (...args) => {
|
|
662
|
+
refuseExtraWithOptionsArguments(endpoint, args.length, 2);
|
|
663
|
+
return settle(execute, readClientRequestArgs(args[0]), readClientRequestOptions(args[1]));
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
const method = () => settle(execute, {}, undefined);
|
|
668
|
+
return Object.assign(method, {
|
|
669
|
+
withOptions: (...args) => {
|
|
670
|
+
refuseExtraWithOptionsArguments(endpoint, args.length, 1);
|
|
671
|
+
return settle(execute, {}, readClientRequestOptions(args[0]));
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
function settle(execute, requestArgs, options) {
|
|
676
|
+
try {
|
|
677
|
+
return execute(requestArgs, options);
|
|
678
|
+
} catch (error) {
|
|
679
|
+
return Promise.reject(error);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
function refuseExtraWithOptionsArguments(endpoint, received, expected) {
|
|
683
|
+
if (received <= expected)
|
|
684
|
+
return;
|
|
685
|
+
const shape = expected === 1 ? "withOptions(options)" : "withOptions(args, options)";
|
|
686
|
+
throw new TypeError(`${endpoint.method} ${endpoint.path}: this endpoint declares ${expected === 1 ? "no input" : "an input"}, so its method is ${shape} — it received ${received} arguments. ` + "An extra argument here is dropped, and a request options object in the dropped position " + "sends the request without them: an abort signal placed there never reaches the server.");
|
|
687
|
+
}
|
|
677
688
|
function endpointHasArguments(endpoint) {
|
|
678
689
|
return Boolean(endpoint.params || endpoint.input || endpoint.multipart);
|
|
679
690
|
}
|
|
@@ -697,15 +708,6 @@ function readClientRequestOptions(value) {
|
|
|
697
708
|
function isAbortSignal(value) {
|
|
698
709
|
return typeof value === "object" && value !== null && "aborted" in value && typeof value.aborted === "boolean" && "addEventListener" in value && typeof value.addEventListener === "function" && "removeEventListener" in value && typeof value.removeEventListener === "function";
|
|
699
710
|
}
|
|
700
|
-
async function throwForErrorResponse(res, config, fallbackBody) {
|
|
701
|
-
const body = await res.json().catch(() => fallbackBody);
|
|
702
|
-
config.onError?.(res.status, body);
|
|
703
|
-
const parsed = parseApiErrorBody(body);
|
|
704
|
-
if (parsed) {
|
|
705
|
-
throw new ApiError(parsed.code, res.status, parsed.details, parsed.message, parsed.hint, responseTraceId(res));
|
|
706
|
-
}
|
|
707
|
-
throw new ApiError("HTTP_ERROR", res.status, { body }, undefined, undefined, responseTraceId(res));
|
|
708
|
-
}
|
|
709
711
|
function createUrlBuilder(contract, source, contractConfig) {
|
|
710
712
|
const builder = {};
|
|
711
713
|
for (const [key, endpoint] of typedEntries(contract.endpoints)) {
|