@jini-ai/http-kit 0.3.2 → 0.3.3
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/dist/delegated-tools.d.ts +89 -0
- package/dist/delegated-tools.d.ts.map +1 -1
- package/dist/delegated-tools.js +106 -1
- package/dist/delegated-tools.js.map +1 -1
- package/package.json +6 -6
- package/dist/express/run-stream.d.ts +0 -15
- package/dist/express/run-stream.d.ts.map +0 -1
- package/dist/express/run-stream.js +0 -11
- package/dist/express/run-stream.js.map +0 -1
- package/dist/express-index.d.ts +0 -32
- package/dist/express-index.d.ts.map +0 -1
- package/dist/express-index.js +0 -14
- package/dist/express-index.js.map +0 -1
- package/dist/fastify/adapter.d.ts +0 -31
- package/dist/fastify/adapter.d.ts.map +0 -1
- package/dist/fastify/adapter.js +0 -64
- package/dist/fastify/adapter.js.map +0 -1
- package/dist/fastify/agents.d.ts +0 -13
- package/dist/fastify/agents.d.ts.map +0 -1
- package/dist/fastify/agents.js +0 -7
- package/dist/fastify/agents.js.map +0 -1
- package/dist/fastify/api-security-middleware.d.ts +0 -64
- package/dist/fastify/api-security-middleware.d.ts.map +0 -1
- package/dist/fastify/api-security-middleware.js +0 -139
- package/dist/fastify/api-security-middleware.js.map +0 -1
- package/dist/fastify/compat.d.ts +0 -22
- package/dist/fastify/compat.d.ts.map +0 -1
- package/dist/fastify/compat.js +0 -16
- package/dist/fastify/compat.js.map +0 -1
- package/dist/fastify/daemon-status.d.ts +0 -22
- package/dist/fastify/daemon-status.d.ts.map +0 -1
- package/dist/fastify/daemon-status.js +0 -9
- package/dist/fastify/daemon-status.js.map +0 -1
- package/dist/fastify/host-tools.d.ts +0 -13
- package/dist/fastify/host-tools.d.ts.map +0 -1
- package/dist/fastify/host-tools.js +0 -8
- package/dist/fastify/host-tools.js.map +0 -1
- package/dist/fastify/index.d.ts +0 -36
- package/dist/fastify/index.d.ts.map +0 -1
- package/dist/fastify/index.js +0 -18
- package/dist/fastify/index.js.map +0 -1
- package/dist/fastify/local-daemon-request.d.ts +0 -43
- package/dist/fastify/local-daemon-request.d.ts.map +0 -1
- package/dist/fastify/local-daemon-request.js +0 -155
- package/dist/fastify/local-daemon-request.js.map +0 -1
- package/dist/fastify/origin.d.ts +0 -21
- package/dist/fastify/origin.d.ts.map +0 -1
- package/dist/fastify/origin.js +0 -14
- package/dist/fastify/origin.js.map +0 -1
- package/dist/fastify/request.d.ts +0 -20
- package/dist/fastify/request.d.ts.map +0 -1
- package/dist/fastify/request.js +0 -25
- package/dist/fastify/request.js.map +0 -1
- package/dist/fastify/response.d.ts +0 -20
- package/dist/fastify/response.d.ts.map +0 -1
- package/dist/fastify/response.js +0 -41
- package/dist/fastify/response.js.map +0 -1
- package/dist/fastify/route-registration-guard.d.ts +0 -70
- package/dist/fastify/route-registration-guard.d.ts.map +0 -1
- package/dist/fastify/route-registration-guard.js +0 -69
- package/dist/fastify/route-registration-guard.js.map +0 -1
- package/dist/fastify/run-stream.d.ts +0 -18
- package/dist/fastify/run-stream.d.ts.map +0 -1
- package/dist/fastify/run-stream.js +0 -10
- package/dist/fastify/run-stream.js.map +0 -1
- package/dist/fastify/runs.d.ts +0 -17
- package/dist/fastify/runs.d.ts.map +0 -1
- package/dist/fastify/runs.js +0 -33
- package/dist/fastify/runs.js.map +0 -1
- package/dist/run-stream.d.ts +0 -60
- package/dist/run-stream.d.ts.map +0 -1
- package/dist/run-stream.js +0 -108
- package/dist/run-stream.js.map +0 -1
|
@@ -77,6 +77,95 @@ export declare function readOnlyRefusalMessage(toolId: string): string;
|
|
|
77
77
|
* fix is one line in the host's own wiring rather than an investigation.
|
|
78
78
|
*/
|
|
79
79
|
export declare const READ_ONLY_UNVERIFIABLE_MESSAGE = "this host cannot verify read-only tools \u2014 POST /api/delegated-tool-calls was mounted without DelegatedToolsHttpDeps.toolRegistry, so a requireReadOnly call cannot be checked and is refused";
|
|
80
|
+
/**
|
|
81
|
+
* A `Principal` narrowed to tools that only read.
|
|
82
|
+
*
|
|
83
|
+
* `checkReadOnlyConstraint` above only ever validates the OUTER `toolId` — the one the caller
|
|
84
|
+
* named in this request. It cannot see what a consumer's own `ToolExecutor` composition does
|
|
85
|
+
* once `bridge.execute()` hands control to `deps.toolExecutor`: a decorator that composition
|
|
86
|
+
* stacks on top of the bare executor (a recovery loop that retries through a different tool id
|
|
87
|
+
* after a failure, for instance) can dispatch a tool the caller never named, using the exact same
|
|
88
|
+
* `principal` the outer call carried — one hop past the only check this route ever ran. Adding a
|
|
89
|
+
* second request-shaped flag would not close that gap either: it would have to be threaded, by
|
|
90
|
+
* hand, through every decorator between here and the handler, and a decorator that forgot would
|
|
91
|
+
* fail open silently. `principal` is the one value every layer already passes unchanged, so the
|
|
92
|
+
* constraint travels as an ATTENUATED IDENTITY instead — a principal permitted to invoke only
|
|
93
|
+
* read-only tools, checkable by {@link refuseNonReadOnlyDispatch} at any depth a consumer's own
|
|
94
|
+
* composition cares to ask.
|
|
95
|
+
*
|
|
96
|
+
* A distinct field rather than a `Principal.roles` entry: `roles` is what a `ToolPolicy` branches
|
|
97
|
+
* on, and a synthetic role would silently join that decision for every registration in the
|
|
98
|
+
* process. This field is inert to everything except {@link refuseNonReadOnlyDispatch}.
|
|
99
|
+
*/
|
|
100
|
+
export interface ReadOnlyConstrainedPrincipal extends Principal {
|
|
101
|
+
readonly toolAccess: 'read-only';
|
|
102
|
+
}
|
|
103
|
+
/** Attenuates `principal` for one execution: it may now invoke only tools registered read-only. */
|
|
104
|
+
export declare function constrainPrincipalToReadOnlyTools(principal: Principal): ReadOnlyConstrainedPrincipal;
|
|
105
|
+
/**
|
|
106
|
+
* Whether `principal` is carrying the read-only attenuation.
|
|
107
|
+
*
|
|
108
|
+
* Reads the field structurally, so a principal that travelled through layers typed as the plain
|
|
109
|
+
* `Principal` (every decorator between here and wherever a dispatch is about to happen) still
|
|
110
|
+
* answers truthfully.
|
|
111
|
+
*
|
|
112
|
+
* @complexity O(1).
|
|
113
|
+
*/
|
|
114
|
+
export declare function principalIsReadOnlyConstrained(principal: Principal): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* THE read-only dispatch decision for any tool id a consumer's own `ToolExecutor` composition is
|
|
117
|
+
* about to invoke — the outer call this route already checked, or a nested one a decorator issues
|
|
118
|
+
* one or more hops in. Every consumer's own composition should ask this before dispatching on
|
|
119
|
+
* behalf of a principal it did not itself resolve; none should re-implement the check, so changing
|
|
120
|
+
* what the constraint means stays one edit.
|
|
121
|
+
*
|
|
122
|
+
* @param options.principal - The principal the dispatch would run under. Unconstrained ⇒ always
|
|
123
|
+
* `null` — this is a no-op for every pre-existing caller that never attenuates a principal.
|
|
124
|
+
* @param options.toolId - The id actually about to be dispatched, which is not necessarily the id
|
|
125
|
+
* named in the original request — that difference is the whole reason this function exists.
|
|
126
|
+
* @param options.registry - Descriptors to resolve `toolId` against; `undefined` ⇒ refuse (an
|
|
127
|
+
* unverifiable constrained dispatch is refused, never waived, matching `checkReadOnlyConstraint`).
|
|
128
|
+
* @returns `null` when the dispatch may proceed, otherwise the refusal text to report.
|
|
129
|
+
* @complexity O(1) for an unconstrained principal; O(n) in registered tool count for a constrained
|
|
130
|
+
* one, since `ToolRegistry` exposes enumeration rather than lookup by id.
|
|
131
|
+
*/
|
|
132
|
+
export declare function refuseNonReadOnlyDispatch(options: {
|
|
133
|
+
readonly principal: Principal;
|
|
134
|
+
readonly toolId: string;
|
|
135
|
+
readonly registry: Pick<ToolRegistry, 'list'> | undefined;
|
|
136
|
+
}): string | null;
|
|
137
|
+
export interface ReadOnlyToolConstraintDeps {
|
|
138
|
+
/** The same registry `inner` was built over — descriptors only; this gate never reaches a handler. */
|
|
139
|
+
readonly registry: Pick<ToolRegistry, 'list'> | undefined;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Wraps `inner` so a read-only-constrained principal (one {@link constrainPrincipalToReadOnlyTools}
|
|
143
|
+
* attenuated) cannot dispatch a tool that isn't registered read-only — whichever layer chose the
|
|
144
|
+
* id. This is what turns the attenuation into an actual gate rather than a field nobody reads:
|
|
145
|
+
* {@link refuseNonReadOnlyDispatch} is the decision, this is its enforcement point.
|
|
146
|
+
*
|
|
147
|
+
* **Compose this as close to the bare `ToolExecutor` as your own stack allows** — directly around
|
|
148
|
+
* `@jini-ai/daemon`'s `createToolExecutor` output, beneath any decorator of your own that might
|
|
149
|
+
* dispatch a tool id the caller never named (a retry, a recovery loop that calls a different tool
|
|
150
|
+
* as a remedy, ...). Every such decorator's own `inner.execute` call still has to come through here
|
|
151
|
+
* to reach a handler, which is what makes this a gate on the CLASS of defect (an unnamed nested
|
|
152
|
+
* dispatch) rather than on one instance of it — see `read-only-tool-constraint.ts` in Tovu's own
|
|
153
|
+
* `apps/website`, the consumer this was ported from, for the composition this mirrors.
|
|
154
|
+
*
|
|
155
|
+
* `delegatedToolExecuteRoute`'s own `handle` additionally composes this around whatever
|
|
156
|
+
* `ToolExecutor` a host supplies, whenever a call attenuates its principal. That outer composition
|
|
157
|
+
* only re-covers the SAME outer `toolId` {@link checkReadOnlyConstraint} already checked — it
|
|
158
|
+
* cannot see a nested dispatch a host's own inner decorator issues, because that decorator holds a
|
|
159
|
+
* reference to whatever `ToolExecutor` IT was built with, not to this route's wrapped one. Closing
|
|
160
|
+
* the nested case for a given host's stack requires that host to compose this decorator itself,
|
|
161
|
+
* innermost, in its own `ToolExecutor` construction — this export exists so it can, without having
|
|
162
|
+
* to rediscover or reimplement the mechanism.
|
|
163
|
+
*
|
|
164
|
+
* @returns A drop-in `ToolExecutor`; `resumeConfirmation`/`cancel`/`getAuditRecord` delegate
|
|
165
|
+
* straight through.
|
|
166
|
+
* @complexity One extra property read per unconstrained call; one registry scan per constrained one.
|
|
167
|
+
*/
|
|
168
|
+
export declare function withReadOnlyToolConstraint(inner: ToolExecutor, deps: ReadOnlyToolConstraintDeps): ToolExecutor;
|
|
80
169
|
/**
|
|
81
170
|
* `POST /api/delegated-tool-calls` — executes one delegated tool call against an already-started
|
|
82
171
|
* run. Maps `ToolExecutionResult.status` to the HTTP response via `toolExecutionResultToApiResult`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegated-tools.d.ts","sourceRoot":"","sources":["../src/delegated-tools.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAkB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"delegated-tools.d.ts","sourceRoot":"","sources":["../src/delegated-tools.ts"],"names":[],"mappings":"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"}
|
package/dist/delegated-tools.js
CHANGED
|
@@ -55,6 +55,93 @@ export function readOnlyRefusalMessage(toolId) {
|
|
|
55
55
|
* fix is one line in the host's own wiring rather than an investigation.
|
|
56
56
|
*/
|
|
57
57
|
export const READ_ONLY_UNVERIFIABLE_MESSAGE = 'this host cannot verify read-only tools — POST /api/delegated-tool-calls was mounted without DelegatedToolsHttpDeps.toolRegistry, so a requireReadOnly call cannot be checked and is refused';
|
|
58
|
+
/** Attenuates `principal` for one execution: it may now invoke only tools registered read-only. */
|
|
59
|
+
export function constrainPrincipalToReadOnlyTools(principal) {
|
|
60
|
+
return { ...principal, toolAccess: 'read-only' };
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Whether `principal` is carrying the read-only attenuation.
|
|
64
|
+
*
|
|
65
|
+
* Reads the field structurally, so a principal that travelled through layers typed as the plain
|
|
66
|
+
* `Principal` (every decorator between here and wherever a dispatch is about to happen) still
|
|
67
|
+
* answers truthfully.
|
|
68
|
+
*
|
|
69
|
+
* @complexity O(1).
|
|
70
|
+
*/
|
|
71
|
+
export function principalIsReadOnlyConstrained(principal) {
|
|
72
|
+
return principal.toolAccess === 'read-only';
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* THE read-only dispatch decision for any tool id a consumer's own `ToolExecutor` composition is
|
|
76
|
+
* about to invoke — the outer call this route already checked, or a nested one a decorator issues
|
|
77
|
+
* one or more hops in. Every consumer's own composition should ask this before dispatching on
|
|
78
|
+
* behalf of a principal it did not itself resolve; none should re-implement the check, so changing
|
|
79
|
+
* what the constraint means stays one edit.
|
|
80
|
+
*
|
|
81
|
+
* @param options.principal - The principal the dispatch would run under. Unconstrained ⇒ always
|
|
82
|
+
* `null` — this is a no-op for every pre-existing caller that never attenuates a principal.
|
|
83
|
+
* @param options.toolId - The id actually about to be dispatched, which is not necessarily the id
|
|
84
|
+
* named in the original request — that difference is the whole reason this function exists.
|
|
85
|
+
* @param options.registry - Descriptors to resolve `toolId` against; `undefined` ⇒ refuse (an
|
|
86
|
+
* unverifiable constrained dispatch is refused, never waived, matching `checkReadOnlyConstraint`).
|
|
87
|
+
* @returns `null` when the dispatch may proceed, otherwise the refusal text to report.
|
|
88
|
+
* @complexity O(1) for an unconstrained principal; O(n) in registered tool count for a constrained
|
|
89
|
+
* one, since `ToolRegistry` exposes enumeration rather than lookup by id.
|
|
90
|
+
*/
|
|
91
|
+
export function refuseNonReadOnlyDispatch(options) {
|
|
92
|
+
if (!principalIsReadOnlyConstrained(options.principal))
|
|
93
|
+
return null;
|
|
94
|
+
if (options.registry === undefined)
|
|
95
|
+
return READ_ONLY_UNVERIFIABLE_MESSAGE;
|
|
96
|
+
const descriptor = options.registry.list().find((candidate) => candidate.id === options.toolId);
|
|
97
|
+
if (isReadOnlyTool(descriptor))
|
|
98
|
+
return null;
|
|
99
|
+
return readOnlyRefusalMessage(options.toolId);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Wraps `inner` so a read-only-constrained principal (one {@link constrainPrincipalToReadOnlyTools}
|
|
103
|
+
* attenuated) cannot dispatch a tool that isn't registered read-only — whichever layer chose the
|
|
104
|
+
* id. This is what turns the attenuation into an actual gate rather than a field nobody reads:
|
|
105
|
+
* {@link refuseNonReadOnlyDispatch} is the decision, this is its enforcement point.
|
|
106
|
+
*
|
|
107
|
+
* **Compose this as close to the bare `ToolExecutor` as your own stack allows** — directly around
|
|
108
|
+
* `@jini-ai/daemon`'s `createToolExecutor` output, beneath any decorator of your own that might
|
|
109
|
+
* dispatch a tool id the caller never named (a retry, a recovery loop that calls a different tool
|
|
110
|
+
* as a remedy, ...). Every such decorator's own `inner.execute` call still has to come through here
|
|
111
|
+
* to reach a handler, which is what makes this a gate on the CLASS of defect (an unnamed nested
|
|
112
|
+
* dispatch) rather than on one instance of it — see `read-only-tool-constraint.ts` in Tovu's own
|
|
113
|
+
* `apps/website`, the consumer this was ported from, for the composition this mirrors.
|
|
114
|
+
*
|
|
115
|
+
* `delegatedToolExecuteRoute`'s own `handle` additionally composes this around whatever
|
|
116
|
+
* `ToolExecutor` a host supplies, whenever a call attenuates its principal. That outer composition
|
|
117
|
+
* only re-covers the SAME outer `toolId` {@link checkReadOnlyConstraint} already checked — it
|
|
118
|
+
* cannot see a nested dispatch a host's own inner decorator issues, because that decorator holds a
|
|
119
|
+
* reference to whatever `ToolExecutor` IT was built with, not to this route's wrapped one. Closing
|
|
120
|
+
* the nested case for a given host's stack requires that host to compose this decorator itself,
|
|
121
|
+
* innermost, in its own `ToolExecutor` construction — this export exists so it can, without having
|
|
122
|
+
* to rediscover or reimplement the mechanism.
|
|
123
|
+
*
|
|
124
|
+
* @returns A drop-in `ToolExecutor`; `resumeConfirmation`/`cancel`/`getAuditRecord` delegate
|
|
125
|
+
* straight through.
|
|
126
|
+
* @complexity One extra property read per unconstrained call; one registry scan per constrained one.
|
|
127
|
+
*/
|
|
128
|
+
export function withReadOnlyToolConstraint(inner, deps) {
|
|
129
|
+
return {
|
|
130
|
+
execute: async (principal, run, toolId, input, signal, emitSurface) => {
|
|
131
|
+
const refusal = refuseNonReadOnlyDispatch({ principal, toolId, registry: deps.registry });
|
|
132
|
+
// Refused BEFORE `inner` — no handler runs, nothing durable happens. `denied` rather than a
|
|
133
|
+
// throw: this is an authorization outcome `ToolExecutionResult` already models, so every
|
|
134
|
+
// caller handles it without a special case. `executionId` is minted here since there is no
|
|
135
|
+
// kernel execution to borrow one from.
|
|
136
|
+
if (refusal !== null)
|
|
137
|
+
return { executionId: randomUUID(), status: 'denied', error: refusal };
|
|
138
|
+
return inner.execute(principal, run, toolId, input, signal, emitSurface);
|
|
139
|
+
},
|
|
140
|
+
resumeConfirmation: (executionId, decision) => inner.resumeConfirmation(executionId, decision),
|
|
141
|
+
cancel: (executionId) => inner.cancel(executionId),
|
|
142
|
+
getAuditRecord: (executionId) => inner.getAuditRecord(executionId),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
58
145
|
/**
|
|
59
146
|
* Evaluates a request's read-only constraint against the live registry.
|
|
60
147
|
*
|
|
@@ -187,7 +274,25 @@ export const delegatedToolExecuteRoute = defineJsonRoute({
|
|
|
187
274
|
catch (error) {
|
|
188
275
|
return err(reportInternalError(deps, 'resolve-principal', error, input.runId, input.toolId));
|
|
189
276
|
}
|
|
190
|
-
|
|
277
|
+
// Attenuates the resolved principal itself for a `requireReadOnly` call, so the constraint
|
|
278
|
+
// survives past this route: a consumer's own `ToolExecutor` composition may dispatch a tool id
|
|
279
|
+
// one or more hops past the one checked above (a nested/recovery dispatch using this same
|
|
280
|
+
// principal), and only the principal — not this request's `requireReadOnly` flag, which dies
|
|
281
|
+
// at this function's return — reaches that far. See `constrainPrincipalToReadOnlyTools`'s own
|
|
282
|
+
// doc. A no-op for every existing unconstrained caller.
|
|
283
|
+
if (input.requireReadOnly === true) {
|
|
284
|
+
principal = constrainPrincipalToReadOnlyTools(principal);
|
|
285
|
+
}
|
|
286
|
+
// Composes the SAME enforcement decorator this package exports for a host's own use, here,
|
|
287
|
+
// around whatever `ToolExecutor` the host supplied — a second, independent check of the OUTER
|
|
288
|
+
// `toolId` `checkReadOnlyConstraint` already ran (never a WEAKER outcome than that check, only
|
|
289
|
+
// ever redundant with it; see `withReadOnlyToolConstraint`'s own doc for why this alone cannot
|
|
290
|
+
// close a nested dispatch a host's own inner decorator issues). Skipped entirely for an
|
|
291
|
+
// unconstrained call so the pre-existing gateway's executor reference is untouched.
|
|
292
|
+
const toolExecutor = input.requireReadOnly === true
|
|
293
|
+
? withReadOnlyToolConstraint(deps.toolExecutor, { registry: deps.toolRegistry })
|
|
294
|
+
: deps.toolExecutor;
|
|
295
|
+
const bridge = createDelegatedToolBridge({ lifecycle: deps.lifecycle, toolExecutor });
|
|
191
296
|
try {
|
|
192
297
|
// `signal` carries the caller's HTTP connection dropping — see `mountJsonRoute`
|
|
193
298
|
// (`adapter.ts`). The bridge already combines it with the run's own cancellation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegated-tools.js","sourceRoot":"","sources":["../src/delegated-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"delegated-tools.js","sourceRoot":"","sources":["../src/delegated-tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/http-kit",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Composable Express route packs and JSON-route transport for a @jini-ai/core daemon composition: request parsing, response serialization, same-origin guard, and a route-pack registrar.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -38,16 +38,16 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"express": "^4.21.0",
|
|
41
|
-
"@jini-ai/agent-runtime": "0.3.
|
|
41
|
+
"@jini-ai/agent-runtime": "0.3.2",
|
|
42
|
+
"@jini-ai/daemon": "0.3.2",
|
|
43
|
+
"@jini-ai/protocol": "0.3.1",
|
|
42
44
|
"@jini-ai/core": "0.3.1",
|
|
43
|
-
"@jini-ai/platform": "0.3.0"
|
|
44
|
-
"@jini-ai/protocol": "0.3.0",
|
|
45
|
-
"@jini-ai/daemon": "0.3.0"
|
|
45
|
+
"@jini-ai/platform": "0.3.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/express": "^4.17.21",
|
|
49
49
|
"@vitest/coverage-v8": "^2.1.9",
|
|
50
|
-
"@jini-ai/chat": "0.3.
|
|
50
|
+
"@jini-ai/chat": "0.3.3"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
53
|
"build": "tsc -p tsconfig.json",
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module express/run-stream
|
|
3
|
-
*
|
|
4
|
-
* Express-specific mounting glue for the shared AG-UI SSE run-stream handler (`../run-stream.js`).
|
|
5
|
-
* Express's `Request`/`Response` already *are* Node's raw `http.IncomingMessage`/
|
|
6
|
-
* `http.ServerResponse` (Express's `Response` extends `http.ServerResponse` directly), so this
|
|
7
|
-
* file's only job is resolving `req.params.runId` and handing the request/response straight
|
|
8
|
-
* through — a few lines, not a reimplementation, per the design decision that motivated building
|
|
9
|
-
* the SSE primitive once instead of duplicating it per transport.
|
|
10
|
-
*/
|
|
11
|
-
import type { Express } from 'express';
|
|
12
|
-
import { type RunStreamDeps } from '../run-stream.js';
|
|
13
|
-
/** Mounts the AG-UI SSE run-stream route on `app`. A pack's `http(app, services)` calls this directly. */
|
|
14
|
-
export declare function registerRunStreamRoute(app: Express, deps: RunStreamDeps): void;
|
|
15
|
-
//# sourceMappingURL=run-stream.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../src/express/run-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAiD,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAErG,0GAA0G;AAC1G,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAO9E"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { handleRunStreamRequest, RUN_STREAM_ROUTE_PATH } from '../run-stream.js';
|
|
2
|
-
/** Mounts the AG-UI SSE run-stream route on `app`. A pack's `http(app, services)` calls this directly. */
|
|
3
|
-
export function registerRunStreamRoute(app, deps) {
|
|
4
|
-
app.get(RUN_STREAM_ROUTE_PATH, async (req, res) => {
|
|
5
|
-
// `:runId` is a required path segment of RUN_STREAM_ROUTE_PATH — this handler is only ever
|
|
6
|
-
// reached via a URL that already matched it, so the param is always present at runtime even
|
|
7
|
-
// though @types/express types every param as possibly `undefined` in general.
|
|
8
|
-
await handleRunStreamRequest(req, res, req.params.runId, deps);
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=run-stream.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-stream.js","sourceRoot":"","sources":["../../src/express/run-stream.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAsB,MAAM,kBAAkB,CAAC;AAErG,0GAA0G;AAC1G,MAAM,UAAU,sBAAsB,CAAC,GAAY,EAAE,IAAmB;IACtE,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACnE,2FAA2F;QAC3F,4FAA4F;QAC5F,8EAA8E;QAC9E,MAAM,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,KAAM,EAAE,IAAI,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/express-index.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module @jini/http/express
|
|
3
|
-
*
|
|
4
|
-
* The Express-native transport namespace: re-exports this package's existing flat Express
|
|
5
|
-
* implementation (request parsing, response serialization, the mounting Adapter, the `/api`
|
|
6
|
-
* security middleware, the route-registration guard, compat error helpers, the daemon-status
|
|
7
|
-
* routes, and the runs/agents/host-tools route packs) under one namespace, mirroring
|
|
8
|
-
* `./fastify/index.js`'s shape so a transport-switchable caller (`@jini/node-host`'s
|
|
9
|
-
* `createLocalNodeDaemon`) can import either namespace symmetrically. Nothing here is a new
|
|
10
|
-
* implementation — every export is the same flat file every other consumer of this package
|
|
11
|
-
* already imports directly from the root barrel; this module exists only so `httpExpress.*` and
|
|
12
|
-
* `httpFastify.*` read the same at call sites that need to pick a transport explicitly.
|
|
13
|
-
*/
|
|
14
|
-
export type { AdapterContext } from './adapter.js';
|
|
15
|
-
export { defineJsonRoute, mountJsonRoute } from './adapter.js';
|
|
16
|
-
export type { ApiBearerAuthMiddlewareDeps, ApiOriginGuardMiddlewareDeps } from './api-security-middleware.js';
|
|
17
|
-
export { registerApiBearerAuthMiddleware, registerApiOriginGuardMiddleware } from './api-security-middleware.js';
|
|
18
|
-
export { createCompatApiError, createCompatApiErrorResponse, sendApiError as sendCompatApiError, } from './compat.js';
|
|
19
|
-
export type { DaemonShutdownResponse, DaemonStatusDeps, DaemonStatusResponse, } from './daemon-status.js';
|
|
20
|
-
export { daemonShutdownRoute, daemonStatusRoute, registerDaemonStatusRoutes } from './daemon-status.js';
|
|
21
|
-
export { isLoopbackHostname, isLoopbackPeerAddress, localOriginFromHeader, normalizeLocalAuthority, requireLocalDaemonRequest, validateLocalDaemonRequest, } from './local-daemon-request.js';
|
|
22
|
-
export type { OriginContext } from './origin.js';
|
|
23
|
-
export { guardSameOrigin } from './origin.js';
|
|
24
|
-
export { rawInput, validationError } from './request.js';
|
|
25
|
-
export { registerRunStreamRoute } from './express/run-stream.js';
|
|
26
|
-
export { sendApiError, sendJson, statusForError } from './response.js';
|
|
27
|
-
export type { InstallRouteRegistrationGuardOptions, RouteRegistration } from './route-registration-guard.js';
|
|
28
|
-
export { getRouteRegistrationInventory, guardedRouteKey, installRouteRegistrationGuard, } from './route-registration-guard.js';
|
|
29
|
-
export { registerRunRoutes } from './runs.js';
|
|
30
|
-
export { registerAgentRoutes } from './agents.js';
|
|
31
|
-
export { registerHostToolsRoutes } from './host-tools.js';
|
|
32
|
-
//# sourceMappingURL=express-index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"express-index.d.ts","sourceRoot":"","sources":["../src/express-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE/D,YAAY,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAC9G,OAAO,EAAE,+BAA+B,EAAE,gCAAgC,EAAE,MAAM,8BAA8B,CAAC;AAEjH,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,YAAY,IAAI,kBAAkB,GACnC,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAExG,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEvE,YAAY,EAAE,oCAAoC,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAC7G,OAAO,EACL,6BAA6B,EAC7B,eAAe,EACf,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/express-index.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export { defineJsonRoute, mountJsonRoute } from './adapter.js';
|
|
2
|
-
export { registerApiBearerAuthMiddleware, registerApiOriginGuardMiddleware } from './api-security-middleware.js';
|
|
3
|
-
export { createCompatApiError, createCompatApiErrorResponse, sendApiError as sendCompatApiError, } from './compat.js';
|
|
4
|
-
export { daemonShutdownRoute, daemonStatusRoute, registerDaemonStatusRoutes } from './daemon-status.js';
|
|
5
|
-
export { isLoopbackHostname, isLoopbackPeerAddress, localOriginFromHeader, normalizeLocalAuthority, requireLocalDaemonRequest, validateLocalDaemonRequest, } from './local-daemon-request.js';
|
|
6
|
-
export { guardSameOrigin } from './origin.js';
|
|
7
|
-
export { rawInput, validationError } from './request.js';
|
|
8
|
-
export { registerRunStreamRoute } from './express/run-stream.js';
|
|
9
|
-
export { sendApiError, sendJson, statusForError } from './response.js';
|
|
10
|
-
export { getRouteRegistrationInventory, guardedRouteKey, installRouteRegistrationGuard, } from './route-registration-guard.js';
|
|
11
|
-
export { registerRunRoutes } from './runs.js';
|
|
12
|
-
export { registerAgentRoutes } from './agents.js';
|
|
13
|
-
export { registerHostToolsRoutes } from './host-tools.js';
|
|
14
|
-
//# sourceMappingURL=express-index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"express-index.js","sourceRoot":"","sources":["../src/express-index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,+BAA+B,EAAE,gCAAgC,EAAE,MAAM,8BAA8B,CAAC;AAEjH,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,YAAY,IAAI,kBAAkB,GACnC,MAAM,aAAa,CAAC;AAOrB,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAExG,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGvE,OAAO,EACL,6BAA6B,EAC7B,eAAe,EACf,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The module's top orchestration layer: wires request parsing, the same-origin guard, a route's
|
|
3
|
-
* `handle`, and response serialization into a single Fastify route handler. This is the only file
|
|
4
|
-
* in this subtree that knows about Fastify's `request`/`reply` on the mounting side. Same job as
|
|
5
|
-
* `../express/adapter.ts`'s `mountJsonRoute`, registered through Fastify's native
|
|
6
|
-
* `fastify.route({ method, url, handler })` instead of Express's `app[method](path, handler)`.
|
|
7
|
-
*/
|
|
8
|
-
import type { FastifyInstance } from 'fastify';
|
|
9
|
-
import { type OriginContext } from './origin.js';
|
|
10
|
-
import type { JsonRouteSpec } from '../types.js';
|
|
11
|
-
/** Server startup state a mounted route needs to evaluate its same-origin guard. */
|
|
12
|
-
export interface AdapterContext extends OriginContext {
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Identity function that pins a route spec's generic parameters at the definition site so
|
|
16
|
-
* callers do not have to repeat them. The returned spec is consumed by `mountJsonRoute` (live)
|
|
17
|
-
* and by tests (direct invocation of `route.parse` / `route.handle`).
|
|
18
|
-
*/
|
|
19
|
-
export declare function defineJsonRoute<Input, Output, Deps>(spec: JsonRouteSpec<Input, Output, Deps>): JsonRouteSpec<Input, Output, Deps>;
|
|
20
|
-
/**
|
|
21
|
-
* Mounts one JsonRouteSpec on a Fastify instance. The Adapter is the only code here that knows
|
|
22
|
-
* about request/reply; the route's parse and handle functions operate on `RouteInputContext` and
|
|
23
|
-
* `Deps` respectively, so they are unit testable without Fastify.
|
|
24
|
-
*
|
|
25
|
-
* `exposeHeadRoute: false` is passed explicitly so a `GET` spec does not also register Fastify's
|
|
26
|
-
* automatic `HEAD` sibling route — the Express version never registers one either, and a spec's
|
|
27
|
-
* `handle` is not written to answer a bodyless `HEAD` request correctly (e.g. `daemonStatusRoute`
|
|
28
|
-
* always returns a JSON body).
|
|
29
|
-
*/
|
|
30
|
-
export declare function mountJsonRoute<Input, Output, Deps>(app: FastifyInstance, spec: JsonRouteSpec<Input, Output, Deps>, deps: Deps, adapter: AdapterContext): void;
|
|
31
|
-
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/fastify/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAI7E,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7D,oFAAoF;AACpF,MAAM,WAAW,cAAe,SAAQ,aAAa;CAAG;AAExD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EACjD,IAAI,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,GACvC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAEpC;AAWD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAChD,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EACxC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,cAAc,GACtB,IAAI,CA+BN"}
|
package/dist/fastify/adapter.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { createApiError } from '@jini/protocol';
|
|
2
|
-
import { rawInput } from './request.js';
|
|
3
|
-
import { sendApiError, sendJson, statusForError } from './response.js';
|
|
4
|
-
import { guardSameOrigin } from './origin.js';
|
|
5
|
-
/**
|
|
6
|
-
* Identity function that pins a route spec's generic parameters at the definition site so
|
|
7
|
-
* callers do not have to repeat them. The returned spec is consumed by `mountJsonRoute` (live)
|
|
8
|
-
* and by tests (direct invocation of `route.parse` / `route.handle`).
|
|
9
|
-
*/
|
|
10
|
-
export function defineJsonRoute(spec) {
|
|
11
|
-
return spec;
|
|
12
|
-
}
|
|
13
|
-
/** Maps the shared, lower-case `HttpMethod` union to the upper-case method literal Fastify's `route()` expects. */
|
|
14
|
-
const FASTIFY_METHOD = {
|
|
15
|
-
get: 'GET',
|
|
16
|
-
post: 'POST',
|
|
17
|
-
put: 'PUT',
|
|
18
|
-
delete: 'DELETE',
|
|
19
|
-
patch: 'PATCH',
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Mounts one JsonRouteSpec on a Fastify instance. The Adapter is the only code here that knows
|
|
23
|
-
* about request/reply; the route's parse and handle functions operate on `RouteInputContext` and
|
|
24
|
-
* `Deps` respectively, so they are unit testable without Fastify.
|
|
25
|
-
*
|
|
26
|
-
* `exposeHeadRoute: false` is passed explicitly so a `GET` spec does not also register Fastify's
|
|
27
|
-
* automatic `HEAD` sibling route — the Express version never registers one either, and a spec's
|
|
28
|
-
* `handle` is not written to answer a bodyless `HEAD` request correctly (e.g. `daemonStatusRoute`
|
|
29
|
-
* always returns a JSON body).
|
|
30
|
-
*/
|
|
31
|
-
export function mountJsonRoute(app, spec, deps, adapter) {
|
|
32
|
-
app.route({
|
|
33
|
-
method: FASTIFY_METHOD[spec.method],
|
|
34
|
-
url: spec.path,
|
|
35
|
-
exposeHeadRoute: false,
|
|
36
|
-
handler: async (req, reply) => {
|
|
37
|
-
try {
|
|
38
|
-
if (spec.requireSameOrigin) {
|
|
39
|
-
const origin = guardSameOrigin(req, adapter);
|
|
40
|
-
if (!origin.ok) {
|
|
41
|
-
sendApiError(reply, statusForError(origin.error), origin.error);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
const parsed = spec.parse(rawInput(req));
|
|
46
|
-
if (!parsed.ok) {
|
|
47
|
-
sendApiError(reply, statusForError(parsed.error), parsed.error);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const result = await spec.handle(parsed.value, deps);
|
|
51
|
-
if (!result.ok) {
|
|
52
|
-
sendApiError(reply, statusForError(result.error), result.error);
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
sendJson(reply, spec.successStatus ?? 200, result.value);
|
|
56
|
-
}
|
|
57
|
-
catch (e) {
|
|
58
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
59
|
-
sendApiError(reply, 500, createApiError('INTERNAL_ERROR', message));
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=adapter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/fastify/adapter.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,eAAe,EAAsB,MAAM,aAAa,CAAC;AAMlE;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAwC;IAExC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,mHAAmH;AACnH,MAAM,cAAc,GAAoE;IACtF,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;CACf,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAoB,EACpB,IAAwC,EACxC,IAAU,EACV,OAAuB;IAEvB,GAAG,CAAC,KAAK,CAAC;QACR,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;QACnC,GAAG,EAAE,IAAI,CAAC,IAAI;QACd,eAAe,EAAE,KAAK;QACtB,OAAO,EAAE,KAAK,EAAE,GAAmB,EAAE,KAAmB,EAAE,EAAE;YAC1D,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBAC3B,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;oBAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;wBACf,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;wBAChE,OAAO;oBACT,CAAC;gBACH,CAAC;gBACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;gBACzC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBACf,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChE,OAAO;gBACT,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBACrD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBACf,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChE,OAAO;gBACT,CAAC;gBACD,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,IAAI,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,OAAO,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC3D,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,cAAc,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
package/dist/fastify/agents.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module fastify/agents
|
|
3
|
-
*
|
|
4
|
-
* Fastify-mounting glue for `../agents.js`'s `agentListRoute` — the exact same `JsonRouteSpec`
|
|
5
|
-
* the Express mounting in `../agents.js` uses, just mounted through this subtree's own
|
|
6
|
-
* `mountJsonRoute` instead.
|
|
7
|
-
*/
|
|
8
|
-
import type { FastifyInstance } from 'fastify';
|
|
9
|
-
import { type AgentsHttpDeps } from '../agents.js';
|
|
10
|
-
import { type AdapterContext } from './adapter.js';
|
|
11
|
-
/** Mounts `GET /api/agents` on `app` — the Fastify-native equivalent of `../agents.js`'s `registerAgentRoutes`. */
|
|
12
|
-
export declare function registerAgentRoutes(app: FastifyInstance, deps: AgentsHttpDeps, adapter: AdapterContext): void;
|
|
13
|
-
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/fastify/agents.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnE,mHAAmH;AACnH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAE7G"}
|
package/dist/fastify/agents.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { agentListRoute } from '../agents.js';
|
|
2
|
-
import { mountJsonRoute } from './adapter.js';
|
|
3
|
-
/** Mounts `GET /api/agents` on `app` — the Fastify-native equivalent of `../agents.js`'s `registerAgentRoutes`. */
|
|
4
|
-
export function registerAgentRoutes(app, deps, adapter) {
|
|
5
|
-
mountJsonRoute(app, agentListRoute, deps, adapter);
|
|
6
|
-
}
|
|
7
|
-
//# sourceMappingURL=agents.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/fastify/agents.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAuB,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,cAAc,EAAuB,MAAM,cAAc,CAAC;AAEnE,mHAAmH;AACnH,MAAM,UAAU,mBAAmB,CAAC,GAAoB,EAAE,IAAoB,EAAE,OAAuB;IACrG,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module fastify/api-security-middleware
|
|
3
|
-
*
|
|
4
|
-
* The two `/api` request gates a locally-bound daemon needs before any route handler runs:
|
|
5
|
-
* bearer-token authentication (optional, active only when a token is configured) and cross-origin
|
|
6
|
-
* rejection (always active). Same job and decision logic as `../express/api-security-middleware.ts`
|
|
7
|
-
* (see that file's own doc for the full drop-list this was genericized from), reimplemented on
|
|
8
|
-
* Fastify's native `onRequest` lifecycle hook (`app.addHook('onRequest', ...)`) in place of
|
|
9
|
-
* Express's `app.use('/api', ...)` path-scoped middleware. Fastify has no first-class "scope this
|
|
10
|
-
* hook to a URL prefix" primitive at the plain-instance level (that requires nesting the routes
|
|
11
|
-
* themselves inside a `.register()` plugin with a `prefix`, which `mountPackHttp`'s pack-agnostic
|
|
12
|
-
* mounting does not do), so both hooks below scope themselves manually by checking the request's
|
|
13
|
-
* own path against the `/api` prefix before applying either gate — the observable behavior is
|
|
14
|
-
* identical to the Express version's `app.use('/api', ...)` scoping.
|
|
15
|
-
*/
|
|
16
|
-
import type { FastifyInstance } from 'fastify';
|
|
17
|
-
import { type ApiTokenAuthEnvConfig } from '@jini/core';
|
|
18
|
-
export interface ApiBearerAuthMiddlewareDeps {
|
|
19
|
-
/** Env var names for the token/disable flags. Defaults to `JINI_API_TOKEN` / `JINI_DISABLE_API_AUTH`. */
|
|
20
|
-
tokenConfig?: ApiTokenAuthEnvConfig;
|
|
21
|
-
/** Defaults to `process.env`. Threaded through so tests never have to mutate real process env. */
|
|
22
|
-
env?: NodeJS.ProcessEnv;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Registers a bearer-token gate on every `/api/*` route, active only when
|
|
26
|
-
* {@link isApiTokenMiddlewareEnabled} says a token is configured and auth hasn't been disabled.
|
|
27
|
-
* When active: open-probe paths and loopback peers skip the check unconditionally; every other
|
|
28
|
-
* request must send `Authorization: Bearer <token>` matching the configured token exactly, or the
|
|
29
|
-
* request is rejected with 401 before reaching any route handler.
|
|
30
|
-
*
|
|
31
|
-
* @param app - The Fastify instance to register the gate on.
|
|
32
|
-
* @param deps - See {@link ApiBearerAuthMiddlewareDeps}. Both fields are optional; omitting `deps`
|
|
33
|
-
* entirely reads `JINI_API_TOKEN`/`JINI_DISABLE_API_AUTH` from real `process.env`.
|
|
34
|
-
* @returns Nothing. Registers zero hooks (a deliberate no-op, not a bug) when no token is configured.
|
|
35
|
-
* @complexity Setup is O(1). Each gated request is O(1) (one Set lookup, one regex match).
|
|
36
|
-
* @overallScore 100/100
|
|
37
|
-
*/
|
|
38
|
-
export declare function registerApiBearerAuthMiddleware(app: FastifyInstance, deps?: ApiBearerAuthMiddlewareDeps): void;
|
|
39
|
-
export interface ApiOriginGuardMiddlewareDeps {
|
|
40
|
-
/** The host this daemon is bound to — compared against a request's `Host`/`Origin` headers. */
|
|
41
|
-
host: string;
|
|
42
|
-
/** Extra allow-listed origins (e.g. a reverse-proxy's public origin). Defaults to none. */
|
|
43
|
-
extraAllowedOrigins?: readonly string[];
|
|
44
|
-
/** Returns the daemon's resolved listen port, or a falsy value before it has resolved. */
|
|
45
|
-
getResolvedPort: () => number | null | undefined;
|
|
46
|
-
/** Defaults to `process.env`. Threaded through so `JINI_WEB_PORT` is testable without mutating real process env. */
|
|
47
|
-
env?: NodeJS.ProcessEnv;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Registers an unconditional cross-origin gate on every `/api/*` route: non-browser clients (no
|
|
51
|
-
* `Origin` header) and requests whose `Origin` resolves to a loopback, private-LAN, or explicitly
|
|
52
|
-
* allow-listed origin are let through; everything else is rejected with 403. `Origin: null`
|
|
53
|
-
* (typically a sandboxed iframe) is always rejected — see the Express version's doc for why the
|
|
54
|
-
* origin daemon's safe-GET exemption for that case was dropped.
|
|
55
|
-
*
|
|
56
|
-
* @param app - The Fastify instance to register the gate on.
|
|
57
|
-
* @param deps - See {@link ApiOriginGuardMiddlewareDeps}.
|
|
58
|
-
* @returns Nothing. Unlike the bearer-token gate, this always registers its hook — there is
|
|
59
|
-
* no "disabled" state.
|
|
60
|
-
* @complexity Setup is O(1). Each gated request is O(p) in the number of allowed ports (typically 1-2).
|
|
61
|
-
* @overallScore 100/100
|
|
62
|
-
*/
|
|
63
|
-
export declare function registerApiOriginGuardMiddleware(app: FastifyInstance, deps: ApiOriginGuardMiddlewareDeps): void;
|
|
64
|
-
//# sourceMappingURL=api-security-middleware.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-security-middleware.d.ts","sourceRoot":"","sources":["../../src/fastify/api-security-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAC7E,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAC;AAgBpB,MAAM,WAAW,2BAA2B;IAC1C,yGAAyG;IACzG,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,kGAAkG;IAClG,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAoBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,GAAE,2BAAgC,GAAG,IAAI,CAmClH;AAED,MAAM,WAAW,4BAA4B;IAC3C,+FAA+F;IAC/F,IAAI,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,0FAA0F;IAC1F,eAAe,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACjD,oHAAoH;IACpH,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAWD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gCAAgC,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,4BAA4B,GAAG,IAAI,CAyC/G"}
|