@every-app/sdk 0.3.0-rc.9 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -74
- package/dist/cloudflare/catalogSettings.generated.d.ts +19 -6
- package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -1
- package/dist/cloudflare/catalogSettings.generated.js +43 -14
- package/dist/cloudflare/index.d.ts +1 -1
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/worker.d.ts +63 -9
- package/dist/cloudflare/worker.d.ts.map +1 -1
- package/dist/cloudflare/worker.js +45 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/aiDefault.d.ts +36 -79
- package/dist/internal/aiDefault.d.ts.map +1 -1
- package/dist/internal/aiDefault.js +47 -149
- package/dist/internal/aiProviders.d.ts +1 -1
- package/dist/internal/aiProviders.d.ts.map +1 -1
- package/dist/internal/aiProviders.js +2 -2
- package/dist/internal/appSettings.d.ts +140 -89
- package/dist/internal/appSettings.d.ts.map +1 -1
- package/dist/internal/appSettings.js +264 -156
- package/dist/internal/capabilities.d.ts +108 -503
- package/dist/internal/capabilities.d.ts.map +1 -1
- package/dist/internal/capabilities.js +29 -550
- package/dist/internal/catalog/commerce.js +1 -1
- package/dist/internal/catalog/index.d.ts +35 -0
- package/dist/internal/catalog/index.d.ts.map +1 -1
- package/dist/internal/catalog/infra.d.ts +35 -0
- package/dist/internal/catalog/infra.d.ts.map +1 -1
- package/dist/internal/catalog/infra.js +65 -0
- package/dist/internal/devProviders.d.ts +1 -19
- package/dist/internal/devProviders.d.ts.map +1 -1
- package/dist/internal/devProviders.js +7 -1
- package/dist/internal/events.d.ts +52 -1
- package/dist/internal/events.d.ts.map +1 -1
- package/dist/internal/events.js +65 -3
- package/dist/internal/gatewaySettings.d.ts +6 -16
- package/dist/internal/gatewaySettings.d.ts.map +1 -1
- package/dist/internal/gatewaySettings.js +5 -23
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/mcpOAuth.d.ts +210 -0
- package/dist/internal/mcpOAuth.d.ts.map +1 -0
- package/dist/internal/mcpOAuth.js +735 -0
- package/dist/internal/oauthClient.d.ts +7 -47
- package/dist/internal/oauthClient.d.ts.map +1 -1
- package/dist/internal/oauthClient.js +1 -115
- package/dist/internal/oauthPresets.d.ts +356 -20
- package/dist/internal/oauthPresets.d.ts.map +1 -1
- package/dist/internal/oauthPresets.js +183 -861
- package/dist/internal/oauthScopes.d.ts +43 -155
- package/dist/internal/oauthScopes.d.ts.map +1 -1
- package/dist/internal/oauthScopes.js +82 -475
- package/dist/internal/oauthSpec.d.ts +28 -71
- package/dist/internal/oauthSpec.d.ts.map +1 -1
- package/dist/internal/oauthSpec.js +172 -448
- package/dist/internal/protocol.d.ts +24 -14
- package/dist/internal/protocol.d.ts.map +1 -1
- package/dist/internal/protocol.js +26 -7
- package/dist/internal/providerApps.d.ts +2 -2
- package/dist/internal/providerApps.js +2 -2
- package/dist/internal/providerRegistry.d.ts +5 -64
- package/dist/internal/providerRegistry.d.ts.map +1 -1
- package/dist/internal/providerRegistry.js +19 -118
- package/dist/internal/providerSpec.d.ts.map +1 -1
- package/dist/internal/providerSpec.js +14 -36
- package/dist/internal/remoteMcp.d.ts +191 -47
- package/dist/internal/remoteMcp.d.ts.map +1 -1
- package/dist/internal/remoteMcp.js +338 -133
- package/dist/internal/signInProviders.d.ts +1 -1
- package/dist/internal/signInProviders.d.ts.map +1 -1
- package/dist/internal/tools.d.ts +15 -8
- package/dist/internal/tools.d.ts.map +1 -1
- package/dist/internal/tools.js +9 -8
- package/dist/manifest.d.ts +96 -40
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +1 -1
- package/dist/server/ai.d.ts +1 -93
- package/dist/server/ai.d.ts.map +1 -1
- package/dist/server/ai.js +17 -111
- package/dist/server/attribution.d.ts +10 -1
- package/dist/server/attribution.d.ts.map +1 -1
- package/dist/server/attribution.js +7 -1
- package/dist/server/connectUrl.d.ts +4 -9
- package/dist/server/connectUrl.d.ts.map +1 -1
- package/dist/server/connectUrl.js +17 -14
- package/dist/server/context.d.ts +12 -14
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js +23 -25
- package/dist/server/eventsEndpoint.d.ts +48 -0
- package/dist/server/eventsEndpoint.d.ts.map +1 -0
- package/dist/server/eventsEndpoint.js +145 -0
- package/dist/server/everyApp.d.ts +16 -26
- package/dist/server/everyApp.d.ts.map +1 -1
- package/dist/server/everyApp.js +22 -46
- package/dist/server/gatewayFetch.d.ts +1 -1
- package/dist/server/gatewayFetch.js +1 -1
- package/dist/server/index.d.ts +6 -9
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +4 -8
- package/dist/server/integrationFetch.d.ts +60 -72
- package/dist/server/integrationFetch.d.ts.map +1 -1
- package/dist/server/integrationFetch.js +120 -393
- package/dist/server/refusal.d.ts +0 -9
- package/dist/server/refusal.d.ts.map +1 -1
- package/dist/server/refusal.js +0 -22
- package/dist/server/tools.d.ts +17 -6
- package/dist/server/tools.d.ts.map +1 -1
- package/dist/server/tools.js +14 -4
- package/dist/server/toolsEndpoint.d.ts +2 -1
- package/dist/server/toolsEndpoint.d.ts.map +1 -1
- package/dist/server/toolsEndpoint.js +4 -3
- package/dist/server/webhooks.d.ts +56 -0
- package/dist/server/webhooks.d.ts.map +1 -0
- package/dist/server/webhooks.js +205 -0
- package/dist/testing/index.d.ts +2 -3
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2 -6
- package/package.json +6 -1
- package/dist/server/aiBinding.d.ts +0 -68
- package/dist/server/aiBinding.d.ts.map +0 -1
- package/dist/server/aiBinding.js +0 -294
- package/dist/server/authorizeUrl.d.ts +0 -43
- package/dist/server/authorizeUrl.d.ts.map +0 -1
- package/dist/server/authorizeUrl.js +0 -106
- package/dist/server/emailBinding.d.ts +0 -72
- package/dist/server/emailBinding.d.ts.map +0 -1
- package/dist/server/emailBinding.js +0 -124
- package/dist/server/fromMcpTools.d.ts +0 -89
- package/dist/server/fromMcpTools.d.ts.map +0 -1
- package/dist/server/fromMcpTools.js +0 -192
|
@@ -40,16 +40,14 @@ export declare const GATEWAY_ERROR_HEADER = "x-everyapp-error";
|
|
|
40
40
|
*/
|
|
41
41
|
export declare const ORG_HEADER = "x-everyapp-org";
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* `
|
|
48
|
-
*
|
|
43
|
+
* On background work's call to an OAuth provider's API: the member whose
|
|
44
|
+
* connection to this app the call uses. Set by `for: { background: true,
|
|
45
|
+
* userId }`; the gateway reads it on the held-token branch only, for an
|
|
46
|
+
* organization's own app, and the perimeter strips it, with every
|
|
47
|
+
* `x-everyapp-*`, from browsers. It addresses a connection; it is not a
|
|
48
|
+
* permission: connecting in the app already lets the app use it.
|
|
49
49
|
*/
|
|
50
|
-
export declare const
|
|
51
|
-
/** The values {@link ACCOUNT_HEADER} may carry. */
|
|
52
|
-
export type ConnectionAccount = "user" | "organization";
|
|
50
|
+
export declare const USER_HEADER = "x-everyapp-user";
|
|
53
51
|
/** 120-second lifetime — caps revocation staleness while surviving clock skew. */
|
|
54
52
|
export declare const IDENTITY_TTL_SECONDS = 120;
|
|
55
53
|
/** System tokens are minted per call and live at most a minute. */
|
|
@@ -104,11 +102,11 @@ export declare const LINKED_DEV_NONCE_ENV = "EVERYAPP_LINKED_DEV_NONCE";
|
|
|
104
102
|
export declare const LINKED_DEV_HEADER = "x-everyapp-linked-dev";
|
|
105
103
|
/** Where the gateway-lite serves the forwarder, under the app's own host. */
|
|
106
104
|
export declare const LINKED_DEV_FORWARD_PATH = "/__everyapp/gateway";
|
|
107
|
-
export type IdentityChannel = "web" | "api" | "mcp"
|
|
105
|
+
export type IdentityChannel = "web" | "api" | "mcp";
|
|
108
106
|
export type IdentityTokenType = "user" | "public" | "system";
|
|
109
107
|
/** What a system token may open. One purpose per token. */
|
|
110
|
-
export type SystemTokenPurpose = "tools.list";
|
|
111
|
-
/** The actor on whose behalf the request is made (user, MCP client
|
|
108
|
+
export type SystemTokenPurpose = "tools.list" | "events.deliver";
|
|
109
|
+
/** The actor on whose behalf the request is made (user, MCP client). */
|
|
112
110
|
export interface IdentityActor {
|
|
113
111
|
sub: string;
|
|
114
112
|
}
|
|
@@ -149,12 +147,15 @@ export interface EveryAppUser {
|
|
|
149
147
|
*/
|
|
150
148
|
orgName?: string;
|
|
151
149
|
channel: IdentityChannel;
|
|
152
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* The acting principal: the user id, the credential acting for them
|
|
152
|
+
* (`pat:<id>`, `oauth:<id>`, `access:<email>`).
|
|
153
|
+
*/
|
|
153
154
|
actor: IdentityActor;
|
|
154
155
|
scopes: string[];
|
|
155
156
|
jti: string;
|
|
156
157
|
/**
|
|
157
|
-
* Set only on
|
|
158
|
+
* Set only on a tool call (`channel: "mcp"`): the one call this
|
|
158
159
|
* identity was minted for.
|
|
159
160
|
*/
|
|
160
161
|
toolCall?: ToolCallClaim;
|
|
@@ -177,6 +178,11 @@ export interface SystemClaims extends JWTPayload {
|
|
|
177
178
|
typ: "system";
|
|
178
179
|
purpose: SystemTokenPurpose;
|
|
179
180
|
jti: string;
|
|
181
|
+
/**
|
|
182
|
+
* `events.deliver` only: the SHA-256 (base64url) of the request body the
|
|
183
|
+
* token was minted for, so it opens that one delivery and nothing else.
|
|
184
|
+
*/
|
|
185
|
+
bh?: string;
|
|
180
186
|
}
|
|
181
187
|
export interface PublicMarkerClaims extends JWTPayload {
|
|
182
188
|
typ: "public";
|
|
@@ -248,7 +254,11 @@ export interface MintSystemTokenOptions {
|
|
|
248
254
|
now?: number;
|
|
249
255
|
/** Header kid. Defaults to the production kid; dev mints with the dev kid. */
|
|
250
256
|
keyId?: string;
|
|
257
|
+
/** `events.deliver`: the body's SHA-256, base64url ({@link bodyHash}). */
|
|
258
|
+
bodyHash?: string;
|
|
251
259
|
}
|
|
260
|
+
/** SHA-256 of a request body, base64url: what an `events.deliver` token's `bh` names. */
|
|
261
|
+
export declare function bodyHash(body: string): Promise<string>;
|
|
252
262
|
/**
|
|
253
263
|
* Mint the gateway's system token for `x-everyapp-system`: no user, one
|
|
254
264
|
* purpose, one app, one minute. The SDK only accepts it on the endpoint its
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/internal/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,eAAe,sBAAsB,CAAC;AACnD,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAC3D;;;;GAIG;AACH,eAAO,MAAM,UAAU,kCAAkC,CAAC;AAC1D,eAAO,MAAM,eAAe,wBAAwB,CAAC;AACrD,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD;;;;GAIG;AACH,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AACvD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,mBAAmB,CAAC;AAC3C;;;;;;;GAOG;AACH,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/internal/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,14 +39,14 @@ export const GATEWAY_ERROR_HEADER = "x-everyapp-error";
|
|
|
39
39
|
*/
|
|
40
40
|
export const ORG_HEADER = "x-everyapp-org";
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* `
|
|
47
|
-
*
|
|
42
|
+
* On background work's call to an OAuth provider's API: the member whose
|
|
43
|
+
* connection to this app the call uses. Set by `for: { background: true,
|
|
44
|
+
* userId }`; the gateway reads it on the held-token branch only, for an
|
|
45
|
+
* organization's own app, and the perimeter strips it, with every
|
|
46
|
+
* `x-everyapp-*`, from browsers. It addresses a connection; it is not a
|
|
47
|
+
* permission: connecting in the app already lets the app use it.
|
|
48
48
|
*/
|
|
49
|
-
export const
|
|
49
|
+
export const USER_HEADER = "x-everyapp-user";
|
|
50
50
|
/** 120-second lifetime — caps revocation staleness while surviving clock skew. */
|
|
51
51
|
export const IDENTITY_TTL_SECONDS = 120;
|
|
52
52
|
/** System tokens are minted per call and live at most a minute. */
|
|
@@ -208,6 +208,10 @@ export function assertSystemClaims(payload, purpose) {
|
|
|
208
208
|
payload.exp - payload.iat > SYSTEM_TOKEN_TTL_SECONDS) {
|
|
209
209
|
throw new ProtocolClaimsError(`system token must expire within ${SYSTEM_TOKEN_TTL_SECONDS}s of issue`);
|
|
210
210
|
}
|
|
211
|
+
if (purpose === "events.deliver" &&
|
|
212
|
+
(typeof payload.bh !== "string" || payload.bh.length === 0)) {
|
|
213
|
+
throw new ProtocolClaimsError("an events.deliver token must name the body it was minted for");
|
|
214
|
+
}
|
|
211
215
|
return payload;
|
|
212
216
|
}
|
|
213
217
|
let cachedPrivateKey = null;
|
|
@@ -269,6 +273,17 @@ export async function mintPublicMarkerJwt(privateKeyPem, opts) {
|
|
|
269
273
|
.setExpirationTime(nowSec + ttl)
|
|
270
274
|
.sign(key);
|
|
271
275
|
}
|
|
276
|
+
/** SHA-256 of a request body, base64url: what an `events.deliver` token's `bh` names. */
|
|
277
|
+
export async function bodyHash(body) {
|
|
278
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(body)));
|
|
279
|
+
let binary = "";
|
|
280
|
+
for (const byte of digest)
|
|
281
|
+
binary += String.fromCharCode(byte);
|
|
282
|
+
return btoa(binary)
|
|
283
|
+
.replace(/\+/g, "-")
|
|
284
|
+
.replace(/\//g, "_")
|
|
285
|
+
.replace(/=+$/, "");
|
|
286
|
+
}
|
|
272
287
|
/**
|
|
273
288
|
* Mint the gateway's system token for `x-everyapp-system`: no user, one
|
|
274
289
|
* purpose, one app, one minute. The SDK only accepts it on the endpoint its
|
|
@@ -281,10 +296,14 @@ export async function mintSystemJwt(privateKeyPem, opts) {
|
|
|
281
296
|
}
|
|
282
297
|
const key = await loadPrivateKey(privateKeyPem);
|
|
283
298
|
const nowSec = Math.floor((opts.now ?? Date.now()) / 1000);
|
|
299
|
+
if (opts.purpose === "events.deliver" && !opts.bodyHash) {
|
|
300
|
+
throw new RangeError("an events.deliver token needs the body's hash");
|
|
301
|
+
}
|
|
284
302
|
const claims = {
|
|
285
303
|
typ: "system",
|
|
286
304
|
purpose: opts.purpose,
|
|
287
305
|
jti: crypto.randomUUID(),
|
|
306
|
+
...(opts.bodyHash ? { bh: opts.bodyHash } : {}),
|
|
288
307
|
};
|
|
289
308
|
return new SignJWT(claims)
|
|
290
309
|
.setProtectedHeader({
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* serves the provider's tools on its `/mcp` under `<id>_<tool>` names, with
|
|
7
7
|
* the key never leaving the Gateway, every call attributed to the member
|
|
8
8
|
* who made it, counted and audited like an app's capability calls. The
|
|
9
|
-
*
|
|
10
|
-
* your agent" dialog
|
|
9
|
+
* MCP apps section of Admin → Apps lists it, and its row menu opens the
|
|
10
|
+
* "Use it from your agent" dialog (docs/design/2026-10-mcp-apps-ui.md).
|
|
11
11
|
*
|
|
12
12
|
* A provider app is an `apps` row of tier {@link PROVIDER_APP_TIER} with no
|
|
13
13
|
* hostname and no Worker name: the perimeter never routes it, and the
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* serves the provider's tools on its `/mcp` under `<id>_<tool>` names, with
|
|
7
7
|
* the key never leaving the Gateway, every call attributed to the member
|
|
8
8
|
* who made it, counted and audited like an app's capability calls. The
|
|
9
|
-
*
|
|
10
|
-
* your agent" dialog
|
|
9
|
+
* MCP apps section of Admin → Apps lists it, and its row menu opens the
|
|
10
|
+
* "Use it from your agent" dialog (docs/design/2026-10-mcp-apps-ui.md).
|
|
11
11
|
*
|
|
12
12
|
* A provider app is an `apps` row of tier {@link PROVIDER_APP_TIER} with no
|
|
13
13
|
* hostname and no Worker name: the perimeter never routes it, and the
|
|
@@ -19,19 +19,8 @@
|
|
|
19
19
|
* an IP literal, localhost, or a `.local`, `.internal` or `.arpa` name)
|
|
20
20
|
* and not one the gateway serves itself (`refuseHost`, which knows the
|
|
21
21
|
* gateway's own host and `APP_BASE_DOMAIN`).
|
|
22
|
-
*
|
|
23
|
-
* A second kind of row, a scope-set overlay (`provider_scope_sets`,
|
|
24
|
-
* `everyapp provider scope-set add`), adds a named scope set to a
|
|
25
|
-
* built-in OAuth client that has scope sets (Google, Microsoft, Slack):
|
|
26
|
-
* its scopes, and the routes on the client's own API hosts it unlocks,
|
|
27
|
-
* checked by the rules a built-in set is checked by
|
|
28
|
-
* (`providers.scope-set-overlay-within-client`). An overlay never replaces
|
|
29
|
-
* one of the client's own sets, never names a host outside the client's
|
|
30
|
-
* `api`, and never applies to a registered row (an operator replaces the
|
|
31
|
-
* row's spec instead). Apps list an overlay set under `scopes` as they
|
|
32
|
-
* list a built-in one.
|
|
33
22
|
*/
|
|
34
|
-
import { type Capability, type CapabilityLookup
|
|
23
|
+
import { type Capability, type CapabilityLookup } from "./capabilities.js";
|
|
35
24
|
import { type RegistrableCapability } from "./providerSpec.js";
|
|
36
25
|
/** A `providers` row as the gateway or the CLI read it. */
|
|
37
26
|
export interface ProviderRow {
|
|
@@ -50,42 +39,16 @@ export interface ProviderRow {
|
|
|
50
39
|
/** When, in epoch milliseconds. */
|
|
51
40
|
addedAt?: number | null;
|
|
52
41
|
}
|
|
53
|
-
/** A `provider_scope_sets` row as the gateway or the CLI read it. */
|
|
54
|
-
export interface ScopeSetRow {
|
|
55
|
-
/** The built-in OAuth client the set belongs to (`google-workspace`). */
|
|
56
|
-
providerId: string;
|
|
57
|
-
/** The set's name, what an app lists under `scopes` (`gmail.send`). */
|
|
58
|
-
name: string;
|
|
59
|
-
/** The set's spec, as JSON text or already parsed (`parseScopeSetOverlay`'s shape). */
|
|
60
|
-
spec: unknown;
|
|
61
|
-
addedBy?: string | null;
|
|
62
|
-
addedAt?: number | null;
|
|
63
|
-
}
|
|
64
|
-
/** One overlay the registry serves, as `provider show` reports it. */
|
|
65
|
-
export interface RegisteredScopeSet {
|
|
66
|
-
providerId: string;
|
|
67
|
-
name: string;
|
|
68
|
-
set: OAuthScopeSet;
|
|
69
|
-
addedBy: string | null;
|
|
70
|
-
addedAt: number | null;
|
|
71
|
-
}
|
|
72
|
-
export type ScopeSetRefusalCode = "SCOPE_SET_INVALID" | "SCOPE_SET_PROVIDER_UNKNOWN" | "SCOPE_SET_BUILTIN";
|
|
73
|
-
/** Why an overlay row is not a scope set on this gateway. */
|
|
74
|
-
export interface ScopeSetRefusal {
|
|
75
|
-
providerId: string;
|
|
76
|
-
name: string;
|
|
77
|
-
code: ScopeSetRefusalCode;
|
|
78
|
-
message: string;
|
|
79
|
-
}
|
|
80
42
|
/**
|
|
81
43
|
* The part of a row a key is set for: its hosts, its host setting and its
|
|
82
44
|
* auth, as one canonical string (sorted keys, sorted hosts), so that
|
|
83
45
|
* replacing a row's hosts or auth changes the key and the value it held
|
|
84
46
|
* is no longer read until the operator sets it again. For an OAuth
|
|
85
47
|
* provider the client is bound to its authorize, token and revoke URLs,
|
|
86
|
-
* its API hosts, where the client goes on the token request
|
|
87
|
-
*
|
|
88
|
-
* re-points `tokenUrl`
|
|
48
|
+
* its API hosts, where the client goes on the token request, its client
|
|
49
|
+
* setting names, and its `resource` and `issuer` when it has them
|
|
50
|
+
* (`oauth.client-bound-to-endpoints`): an admin who re-points `tokenUrl`
|
|
51
|
+
* has to paste the secret again.
|
|
89
52
|
*/
|
|
90
53
|
export declare function providerBindingKey(capability: RegistrableCapability): string;
|
|
91
54
|
/** One registered row as `provider list` and `provider show` report it. */
|
|
@@ -123,12 +86,6 @@ export interface ProviderRegistry extends CapabilityLookup {
|
|
|
123
86
|
rows(): readonly RegisteredProvider[];
|
|
124
87
|
/** The rows this registry left out, each with why. */
|
|
125
88
|
readonly rejected: readonly RowRefusal[];
|
|
126
|
-
/** The scope-set overlays this registry applied to built-in clients, in row order. */
|
|
127
|
-
scopeSets(): readonly RegisteredScopeSet[];
|
|
128
|
-
/** Where a client's scope set comes from: its catalog entry, an overlay row, or nowhere. */
|
|
129
|
-
scopeSetSource(providerId: string, name: string): "catalog" | "row" | undefined;
|
|
130
|
-
/** The overlay rows this registry left out, each with why. */
|
|
131
|
-
readonly rejectedScopeSets: readonly ScopeSetRefusal[];
|
|
132
89
|
}
|
|
133
90
|
export interface ProviderRegistryOptions {
|
|
134
91
|
/**
|
|
@@ -137,8 +94,6 @@ export interface ProviderRegistryOptions {
|
|
|
137
94
|
* the rest (IP literals, localhost, `.internal`).
|
|
138
95
|
*/
|
|
139
96
|
refuseHost?: (host: string) => string | null;
|
|
140
|
-
/** The scope-set overlays (`provider_scope_sets`), applied to the catalog's OAuth clients. */
|
|
141
|
-
scopeSets?: readonly ScopeSetRow[];
|
|
142
97
|
}
|
|
143
98
|
/** The prefix a provider's own Gateway settings carry: `stripe` → `STRIPE_`, `tiktok-business` → `TIKTOK_BUSINESS_`. */
|
|
144
99
|
export declare function providerSettingPrefix(id: string): string;
|
|
@@ -194,20 +149,6 @@ export declare function resolveProviderRow(row: ProviderRow, context: {
|
|
|
194
149
|
ok: false;
|
|
195
150
|
refusal: RowRefusal;
|
|
196
151
|
};
|
|
197
|
-
/**
|
|
198
|
-
* The built-in OAuth client an overlay may extend: a catalog entry of mode
|
|
199
|
-
* `oauth_client` with a scope policy. Null for anything else (an API-key
|
|
200
|
-
* entry, a client without sets, a registered row, an unknown id).
|
|
201
|
-
*/
|
|
202
|
-
export declare function overlayableClient(providerId: string): OAuthClientCapability | null;
|
|
203
|
-
/** An overlay row's spec parsed and checked against its client: the set, or the refusal. */
|
|
204
|
-
export declare function resolveScopeSetRow(row: ScopeSetRow): {
|
|
205
|
-
ok: true;
|
|
206
|
-
set: OAuthScopeSet;
|
|
207
|
-
} | {
|
|
208
|
-
ok: false;
|
|
209
|
-
refusal: ScopeSetRefusal;
|
|
210
|
-
};
|
|
211
152
|
/**
|
|
212
153
|
* The catalog and `rows` as one registry. Rows are taken in order; a row
|
|
213
154
|
* whose settings another earlier row holds is the one refused.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providerRegistry.d.ts","sourceRoot":"","sources":["../../src/internal/providerRegistry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"providerRegistry.d.ts","sourceRoot":"","sources":["../../src/internal/providerRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,21 +19,9 @@
|
|
|
19
19
|
* an IP literal, localhost, or a `.local`, `.internal` or `.arpa` name)
|
|
20
20
|
* and not one the gateway serves itself (`refuseHost`, which knows the
|
|
21
21
|
* gateway's own host and `APP_BASE_DOMAIN`).
|
|
22
|
-
*
|
|
23
|
-
* A second kind of row, a scope-set overlay (`provider_scope_sets`,
|
|
24
|
-
* `everyapp provider scope-set add`), adds a named scope set to a
|
|
25
|
-
* built-in OAuth client that has scope sets (Google, Microsoft, Slack):
|
|
26
|
-
* its scopes, and the routes on the client's own API hosts it unlocks,
|
|
27
|
-
* checked by the rules a built-in set is checked by
|
|
28
|
-
* (`providers.scope-set-overlay-within-client`). An overlay never replaces
|
|
29
|
-
* one of the client's own sets, never names a host outside the client's
|
|
30
|
-
* `api`, and never applies to a registered row (an operator replaces the
|
|
31
|
-
* row's spec instead). Apps list an overlay set under `scopes` as they
|
|
32
|
-
* list a built-in one.
|
|
33
22
|
*/
|
|
34
23
|
import { CAPABILITIES, CAPABILITY_IDS, capabilitySettings, } from "./capabilities.js";
|
|
35
24
|
import { isDevOnlyGatewaySetting, isInstallOwnedGatewaySetting, isReservedAppSecretName, isSettableGatewaySetting, } from "./gatewaySettings.js";
|
|
36
|
-
import { parseScopeSetOverlay, withScopeSets } from "./oauthSpec.js";
|
|
37
25
|
import { isSignInSettingName } from "./signInProviders.js";
|
|
38
26
|
import { describeSpecProblems, parseProviderSpec, PROVIDER_ID, } from "./providerSpec.js";
|
|
39
27
|
/**
|
|
@@ -42,9 +30,10 @@ import { describeSpecProblems, parseProviderSpec, PROVIDER_ID, } from "./provide
|
|
|
42
30
|
* replacing a row's hosts or auth changes the key and the value it held
|
|
43
31
|
* is no longer read until the operator sets it again. For an OAuth
|
|
44
32
|
* provider the client is bound to its authorize, token and revoke URLs,
|
|
45
|
-
* its API hosts, where the client goes on the token request
|
|
46
|
-
*
|
|
47
|
-
* re-points `tokenUrl`
|
|
33
|
+
* its API hosts, where the client goes on the token request, its client
|
|
34
|
+
* setting names, and its `resource` and `issuer` when it has them
|
|
35
|
+
* (`oauth.client-bound-to-endpoints`): an admin who re-points `tokenUrl`
|
|
36
|
+
* has to paste the secret again.
|
|
48
37
|
*/
|
|
49
38
|
export function providerBindingKey(capability) {
|
|
50
39
|
if (capability.mode === "ai") {
|
|
@@ -59,13 +48,20 @@ export function providerBindingKey(capability) {
|
|
|
59
48
|
if (capability.mode === "oauth_client") {
|
|
60
49
|
return JSON.stringify({
|
|
61
50
|
kind: "oauth2-user",
|
|
62
|
-
authorizeUrl: capability.
|
|
63
|
-
tokenUrl: capability.flow
|
|
64
|
-
revokeUrl: capability.flow
|
|
65
|
-
inject: capability.
|
|
51
|
+
authorizeUrl: capability.flow.authorizeUrl,
|
|
52
|
+
tokenUrl: capability.flow.tokenUrl,
|
|
53
|
+
revokeUrl: capability.flow.revokeUrl ?? null,
|
|
54
|
+
inject: capability.flow.inject,
|
|
66
55
|
clientId: capability.secrets.clientId,
|
|
67
56
|
clientSecret: capability.secrets.clientSecret ?? null,
|
|
68
57
|
hosts: [...capability.api].sort(),
|
|
58
|
+
// Only when present, so a row without them keeps the key it was bound to.
|
|
59
|
+
...(capability.flow?.resource === undefined
|
|
60
|
+
? {}
|
|
61
|
+
: { resource: capability.flow.resource }),
|
|
62
|
+
...(capability.flow?.issuer === undefined
|
|
63
|
+
? {}
|
|
64
|
+
: { issuer: capability.flow.issuer }),
|
|
69
65
|
});
|
|
70
66
|
}
|
|
71
67
|
return JSON.stringify({
|
|
@@ -207,10 +203,10 @@ export function registrableHosts(capability) {
|
|
|
207
203
|
return [new URL(capability.origin).hostname.toLowerCase()];
|
|
208
204
|
const hosts = [...capability.api];
|
|
209
205
|
const urls = [
|
|
210
|
-
capability.
|
|
211
|
-
capability.flow
|
|
212
|
-
capability.flow
|
|
213
|
-
capability.flow
|
|
206
|
+
capability.flow.authorizeUrl,
|
|
207
|
+
capability.flow.tokenUrl,
|
|
208
|
+
capability.flow.revokeUrl,
|
|
209
|
+
capability.flow.identity?.url,
|
|
214
210
|
];
|
|
215
211
|
for (const url of urls) {
|
|
216
212
|
if (!url)
|
|
@@ -270,92 +266,12 @@ export function resolveProviderRow(row, context) {
|
|
|
270
266
|
? { ok: false, refusal }
|
|
271
267
|
: { ok: true, capability: parsed.capability };
|
|
272
268
|
}
|
|
273
|
-
/**
|
|
274
|
-
* The built-in OAuth client an overlay may extend: a catalog entry of mode
|
|
275
|
-
* `oauth_client` with a scope policy. Null for anything else (an API-key
|
|
276
|
-
* entry, a client without sets, a registered row, an unknown id).
|
|
277
|
-
*/
|
|
278
|
-
export function overlayableClient(providerId) {
|
|
279
|
-
if (!CAPABILITY_IDS.includes(providerId))
|
|
280
|
-
return null;
|
|
281
|
-
const capability = CAPABILITIES[providerId];
|
|
282
|
-
return capability.mode === "oauth_client" && capability.scopePolicy
|
|
283
|
-
? capability
|
|
284
|
-
: null;
|
|
285
|
-
}
|
|
286
|
-
/** An overlay row's spec parsed and checked against its client: the set, or the refusal. */
|
|
287
|
-
export function resolveScopeSetRow(row) {
|
|
288
|
-
const refuse = (code, message) => ({
|
|
289
|
-
ok: false,
|
|
290
|
-
refusal: { providerId: row.providerId, name: row.name, code, message },
|
|
291
|
-
});
|
|
292
|
-
const client = overlayableClient(row.providerId);
|
|
293
|
-
if (!client) {
|
|
294
|
-
return refuse("SCOPE_SET_PROVIDER_UNKNOWN", `${row.providerId} isn't a built-in OAuth client with scope sets (google-workspace, microsoft-365, slack); a registered provider's sets are in its spec`);
|
|
295
|
-
}
|
|
296
|
-
if (Object.hasOwn(client.scopePolicy.sets, row.name)) {
|
|
297
|
-
return refuse("SCOPE_SET_BUILTIN", `${row.name} is one of ${row.providerId}'s own sets; an overlay adds a set, never replaces one`);
|
|
298
|
-
}
|
|
299
|
-
let spec = row.spec;
|
|
300
|
-
if (typeof spec === "string") {
|
|
301
|
-
try {
|
|
302
|
-
spec = JSON.parse(spec);
|
|
303
|
-
}
|
|
304
|
-
catch {
|
|
305
|
-
return refuse("SCOPE_SET_INVALID", "the stored spec isn't JSON");
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
const parsed = parseScopeSetOverlay(typeof spec === "object" && spec !== null && !Array.isArray(spec)
|
|
309
|
-
? { ...spec, name: row.name }
|
|
310
|
-
: spec, { id: row.providerId, capability: client });
|
|
311
|
-
if (!parsed.ok) {
|
|
312
|
-
return refuse("SCOPE_SET_INVALID", describeSpecProblems(parsed.problems));
|
|
313
|
-
}
|
|
314
|
-
return { ok: true, set: parsed.set };
|
|
315
|
-
}
|
|
316
269
|
/**
|
|
317
270
|
* The catalog and `rows` as one registry. Rows are taken in order; a row
|
|
318
271
|
* whose settings another earlier row holds is the one refused.
|
|
319
272
|
*/
|
|
320
273
|
export function providerRegistry(rows = [], options = {}) {
|
|
321
274
|
const catalog = new Map(CAPABILITY_IDS.map((id) => [id, CAPABILITIES[id]]));
|
|
322
|
-
// Scope-set overlays on the catalog's OAuth clients, before any row is
|
|
323
|
-
// looked at: a row never shadows the catalog, with or without overlays.
|
|
324
|
-
const overlays = [];
|
|
325
|
-
const rejectedScopeSets = [];
|
|
326
|
-
const overlaySets = new Map();
|
|
327
|
-
for (const row of options.scopeSets ?? []) {
|
|
328
|
-
if (overlays.some((each) => each.providerId === row.providerId && each.name === row.name)) {
|
|
329
|
-
rejectedScopeSets.push({
|
|
330
|
-
providerId: row.providerId,
|
|
331
|
-
name: row.name,
|
|
332
|
-
code: "SCOPE_SET_INVALID",
|
|
333
|
-
message: "listed twice",
|
|
334
|
-
});
|
|
335
|
-
continue;
|
|
336
|
-
}
|
|
337
|
-
const resolved = resolveScopeSetRow(row);
|
|
338
|
-
if (!resolved.ok) {
|
|
339
|
-
rejectedScopeSets.push(resolved.refusal);
|
|
340
|
-
continue;
|
|
341
|
-
}
|
|
342
|
-
overlays.push({
|
|
343
|
-
providerId: row.providerId,
|
|
344
|
-
name: row.name,
|
|
345
|
-
set: resolved.set,
|
|
346
|
-
addedBy: row.addedBy ?? null,
|
|
347
|
-
addedAt: row.addedAt ?? null,
|
|
348
|
-
});
|
|
349
|
-
const sets = overlaySets.get(row.providerId) ?? {};
|
|
350
|
-
sets[row.name] = resolved.set;
|
|
351
|
-
overlaySets.set(row.providerId, sets);
|
|
352
|
-
}
|
|
353
|
-
for (const [id, sets] of overlaySets) {
|
|
354
|
-
const client = catalog.get(id);
|
|
355
|
-
if (client?.mode === "oauth_client") {
|
|
356
|
-
catalog.set(id, withScopeSets(client, sets));
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
275
|
const accepted = new Map();
|
|
360
276
|
const rejected = [];
|
|
361
277
|
const rowSettings = new Set();
|
|
@@ -411,21 +327,6 @@ export function providerRegistry(rows = [], options = {}) {
|
|
|
411
327
|
},
|
|
412
328
|
rows: () => [...accepted.values()],
|
|
413
329
|
rejected,
|
|
414
|
-
scopeSets: () => [...overlays],
|
|
415
|
-
scopeSetSource: (providerId, name) => {
|
|
416
|
-
if (overlays.some((each) => each.providerId === providerId && each.name === name)) {
|
|
417
|
-
return "row";
|
|
418
|
-
}
|
|
419
|
-
const capability = CAPABILITY_IDS.includes(providerId)
|
|
420
|
-
? CAPABILITIES[providerId]
|
|
421
|
-
: undefined;
|
|
422
|
-
return capability?.mode === "oauth_client" &&
|
|
423
|
-
capability.scopePolicy &&
|
|
424
|
-
Object.hasOwn(capability.scopePolicy.sets, name)
|
|
425
|
-
? "catalog"
|
|
426
|
-
: undefined;
|
|
427
|
-
},
|
|
428
|
-
rejectedScopeSets,
|
|
429
330
|
};
|
|
430
331
|
}
|
|
431
332
|
/** The catalog alone, as a registry: what every surface reads without a gateway's rows. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providerSpec.d.ts","sourceRoot":"","sources":["../../src/internal/providerSpec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAGL,KAAK,oBAAoB,EAEzB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAM3B,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"providerSpec.d.ts","sourceRoot":"","sources":["../../src/internal/providerSpec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAGL,KAAK,oBAAoB,EAEzB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAM3B,MAAM,mBAAmB,CAAC;AAO3B,oEAAoE;AACpE,eAAO,MAAM,WAAW,QAA2B,CAAC;AACpD,kFAAkF;AAClF,eAAO,MAAM,oBAAoB,QAA2B,CAAC;AAC7D,0FAA0F;AAC1F,eAAO,MAAM,aAAa,QACoD,CAAC;AA4C/E,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AACzD,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAkEzD,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,0HAA0H;AAC1H,MAAM,MAAM,qBAAqB,GAC7B,gBAAgB,GAChB,qBAAqB,GACrB,oBAAoB,CAAC;AAEzB,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,qBAAqB,CAAA;CAAE,GAC3D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAA;CAAE,CAAC;AA+iBnD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAsNpE;AAkOD,wFAAwF;AACxF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,mBAAmB,EAAE,GACvC,MAAM,CAIR;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,qBAAqB,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+FzB;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAC5B,UAAU,EAAE,qBAAqB,GAChC,SAAS,MAAM,EAAE,CAKnB"}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* registry's (./providerRegistry.ts), run after this parse.
|
|
22
22
|
*/
|
|
23
23
|
import { DEFAULT_WRITE_METHODS, authSettingNames, } from "./capabilities.js";
|
|
24
|
-
import { oauthSpecOf, parseOAuthUserSpec } from "./oauthSpec.js";
|
|
24
|
+
import { REMOVED_OAUTH_FIELDS, oauthSpecOf, parseOAuthUserSpec, } from "./oauthSpec.js";
|
|
25
25
|
/** A provider id: lowercase, a letter first, 2 to 40 characters. */
|
|
26
26
|
export const PROVIDER_ID = /^[a-z][a-z0-9-]{1,39}$/;
|
|
27
27
|
/** A Gateway setting name a provider may hold: upper case, 3 to 64 characters. */
|
|
@@ -96,10 +96,6 @@ const KNOWN_FIELDS = new Set([
|
|
|
96
96
|
"example",
|
|
97
97
|
"verified",
|
|
98
98
|
"tags",
|
|
99
|
-
// An `oauth2-user` spec's own (./oauthSpec.ts).
|
|
100
|
-
"scopeSets",
|
|
101
|
-
"alwaysRequested",
|
|
102
|
-
"tolerated",
|
|
103
99
|
// An `ai` spec's own.
|
|
104
100
|
"baseUrl",
|
|
105
101
|
"models",
|
|
@@ -128,11 +124,7 @@ const NOT_AI_FIELDS = [
|
|
|
128
124
|
"readMethods",
|
|
129
125
|
"writeMethods",
|
|
130
126
|
"accountWidePaths",
|
|
131
|
-
...OAUTH_ONLY_FIELDS_LIST(),
|
|
132
127
|
];
|
|
133
|
-
function OAUTH_ONLY_FIELDS_LIST() {
|
|
134
|
-
return ["scopeSets", "alwaysRequested", "tolerated"];
|
|
135
|
-
}
|
|
136
128
|
/** Fields an API-key spec has that an `oauth2-user` spec does not. */
|
|
137
129
|
const API_KEY_ONLY_FIELDS = [
|
|
138
130
|
"hostSetting",
|
|
@@ -144,11 +136,6 @@ const API_KEY_ONLY_FIELDS = [
|
|
|
144
136
|
"rate",
|
|
145
137
|
"verified",
|
|
146
138
|
];
|
|
147
|
-
const OAUTH_ONLY_FIELDS = [
|
|
148
|
-
"scopeSets",
|
|
149
|
-
"alwaysRequested",
|
|
150
|
-
"tolerated",
|
|
151
|
-
];
|
|
152
139
|
function isRecord(value) {
|
|
153
140
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
154
141
|
}
|
|
@@ -656,7 +643,11 @@ export function parseProviderSpec(input) {
|
|
|
656
643
|
problems: [{ path: "(root)", message: "must be a JSON object" }],
|
|
657
644
|
};
|
|
658
645
|
}
|
|
646
|
+
const oauthSpec = isRecord(input["auth"]) && input["auth"]["kind"] === "oauth2-user";
|
|
659
647
|
for (const field of Object.keys(input)) {
|
|
648
|
+
// An OAuth spec's removed fields get their own message below.
|
|
649
|
+
if (oauthSpec && Object.hasOwn(REMOVED_OAUTH_FIELDS, field))
|
|
650
|
+
continue;
|
|
660
651
|
if (!KNOWN_FIELDS.has(field)) {
|
|
661
652
|
problems.push({ path: field, message: "unknown field" });
|
|
662
653
|
}
|
|
@@ -715,7 +706,12 @@ export function parseProviderSpec(input) {
|
|
|
715
706
|
return parseAiSpec(input, problems, { id, name, description, docs, api });
|
|
716
707
|
}
|
|
717
708
|
if (isOAuth) {
|
|
718
|
-
|
|
709
|
+
// Fields an OAuth spec had before scopes moved to each app's config,
|
|
710
|
+
// each refused with what to write instead.
|
|
711
|
+
for (const [field, message] of Object.entries(REMOVED_OAUTH_FIELDS)) {
|
|
712
|
+
if (input[field] !== undefined)
|
|
713
|
+
problems.push({ path: field, message });
|
|
714
|
+
}
|
|
719
715
|
const hint = text(input["hint"], "hint", problems, { max: 500 });
|
|
720
716
|
const example = text(input["example"], "example", problems, { max: 200 });
|
|
721
717
|
const tags = tagList(input["tags"], problems);
|
|
@@ -746,11 +742,6 @@ export function parseProviderSpec(input) {
|
|
|
746
742
|
hosts,
|
|
747
743
|
...(description === undefined ? {} : { description }),
|
|
748
744
|
...(api === undefined ? {} : { reference: api }),
|
|
749
|
-
...(access === undefined
|
|
750
|
-
? {}
|
|
751
|
-
: { access: access }),
|
|
752
|
-
...(readMethods === undefined ? {} : { readMethods }),
|
|
753
|
-
...(writeMethods === undefined ? {} : { writeMethods }),
|
|
754
745
|
...(hint === undefined ? {} : { hint }),
|
|
755
746
|
...(example === undefined ? {} : { example }),
|
|
756
747
|
...(tags === undefined ? {} : { tags }),
|
|
@@ -761,14 +752,6 @@ export function parseProviderSpec(input) {
|
|
|
761
752
|
}
|
|
762
753
|
return { ok: true, id, capability: parsed.capability };
|
|
763
754
|
}
|
|
764
|
-
for (const field of OAUTH_ONLY_FIELDS) {
|
|
765
|
-
if (input[field] !== undefined) {
|
|
766
|
-
problems.push({
|
|
767
|
-
path: field,
|
|
768
|
-
message: "only an oauth2-user spec has it",
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
755
|
const hostSetting = input["hostSetting"] === undefined
|
|
773
756
|
? undefined
|
|
774
757
|
: secretName(input["hostSetting"], "hostSetting", problems);
|
|
@@ -1048,13 +1031,8 @@ export function describeSpecProblems(problems) {
|
|
|
1048
1031
|
* gives the entry back.
|
|
1049
1032
|
*/
|
|
1050
1033
|
export function providerSpecOf(id, capability) {
|
|
1051
|
-
if (capability.mode === "oauth_client")
|
|
1052
|
-
|
|
1053
|
-
if (!spec) {
|
|
1054
|
-
throw new Error(`${id} is a catalog OAuth client without a Gateway-owned flow: it has no spec`);
|
|
1055
|
-
}
|
|
1056
|
-
return spec;
|
|
1057
|
-
}
|
|
1034
|
+
if (capability.mode === "oauth_client")
|
|
1035
|
+
return oauthSpecOf(id, capability);
|
|
1058
1036
|
if (capability.mode === "ai") {
|
|
1059
1037
|
if (!capability.chat || !capability.models) {
|
|
1060
1038
|
throw new Error(`${id} is a catalog AI entry without a model list: it has no spec`);
|
|
@@ -1149,6 +1127,6 @@ export function providerSpecOf(id, capability) {
|
|
|
1149
1127
|
}
|
|
1150
1128
|
/** The methods an app with `access: "write"` may use on `capability` besides its read methods. */
|
|
1151
1129
|
export function writeMethodsOf(capability) {
|
|
1152
|
-
return ((capability.mode === "
|
|
1130
|
+
return ((capability.mode === "api_key" ? capability.writeMethods : undefined) ??
|
|
1153
1131
|
DEFAULT_WRITE_METHODS);
|
|
1154
1132
|
}
|