@every-app/sdk 0.2.0 → 0.3.0-rc.10
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/LICENSE +21 -0
- package/README.md +609 -3
- package/dist/cloudflare/catalogSettings.generated.d.ts +81 -0
- package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
- package/dist/cloudflare/catalogSettings.generated.js +174 -0
- package/dist/cloudflare/index.d.ts +23 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +24 -0
- package/dist/cloudflare/sentinel.d.ts +127 -0
- package/dist/cloudflare/sentinel.d.ts.map +1 -0
- package/dist/cloudflare/sentinel.js +85 -0
- package/dist/cloudflare/worker.d.ts +805 -0
- package/dist/cloudflare/worker.d.ts.map +1 -0
- package/dist/cloudflare/worker.js +997 -0
- package/dist/dev/index.d.ts +8 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +7 -0
- package/dist/dev/keypair.d.ts +26 -0
- package/dist/dev/keypair.d.ts.map +1 -0
- package/dist/dev/keypair.js +62 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/internal/aiDefault.d.ts +204 -0
- package/dist/internal/aiDefault.d.ts.map +1 -0
- package/dist/internal/aiDefault.js +334 -0
- package/dist/internal/aiProviders.d.ts +72 -0
- package/dist/internal/aiProviders.d.ts.map +1 -0
- package/dist/internal/aiProviders.js +233 -0
- package/dist/internal/appSettings.d.ts +315 -0
- package/dist/internal/appSettings.d.ts.map +1 -0
- package/dist/internal/appSettings.js +549 -0
- package/dist/internal/audit.d.ts +108 -0
- package/dist/internal/audit.d.ts.map +1 -0
- package/dist/internal/audit.js +235 -0
- package/dist/internal/capabilities.d.ts +3174 -0
- package/dist/internal/capabilities.d.ts.map +1 -0
- package/dist/internal/capabilities.js +1110 -0
- package/dist/internal/catalog/commerce.d.ts +394 -0
- package/dist/internal/catalog/commerce.d.ts.map +1 -0
- package/dist/internal/catalog/commerce.js +477 -0
- package/dist/internal/catalog/comms.d.ts +375 -0
- package/dist/internal/catalog/comms.d.ts.map +1 -0
- package/dist/internal/catalog/comms.js +520 -0
- package/dist/internal/catalog/index.d.ts +1973 -0
- package/dist/internal/catalog/index.d.ts.map +1 -0
- package/dist/internal/catalog/index.js +19 -0
- package/dist/internal/catalog/inference.d.ts +393 -0
- package/dist/internal/catalog/inference.d.ts.map +1 -0
- package/dist/internal/catalog/inference.js +460 -0
- package/dist/internal/catalog/infra.d.ts +423 -0
- package/dist/internal/catalog/infra.d.ts.map +1 -0
- package/dist/internal/catalog/infra.js +543 -0
- package/dist/internal/catalog/search.d.ts +400 -0
- package/dist/internal/catalog/search.d.ts.map +1 -0
- package/dist/internal/catalog/search.js +463 -0
- package/dist/internal/devProviders.d.ts +49 -0
- package/dist/internal/devProviders.d.ts.map +1 -0
- package/dist/internal/devProviders.js +80 -0
- package/dist/internal/email.d.ts +280 -0
- package/dist/internal/email.d.ts.map +1 -0
- package/dist/internal/email.js +613 -0
- package/dist/internal/events.d.ts +193 -0
- package/dist/internal/events.d.ts.map +1 -0
- package/dist/internal/events.js +367 -0
- package/dist/internal/gatewaySettings.d.ts +83 -0
- package/dist/internal/gatewaySettings.d.ts.map +1 -0
- package/dist/internal/gatewaySettings.js +215 -0
- package/dist/internal/identity.d.ts +57 -5
- package/dist/internal/identity.d.ts.map +1 -1
- package/dist/internal/identity.js +99 -22
- package/dist/internal/index.d.ts +22 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +22 -1
- package/dist/internal/members.d.ts +36 -0
- package/dist/internal/members.d.ts.map +1 -0
- package/dist/internal/members.js +7 -0
- package/dist/internal/oauthClient.d.ts +61 -0
- package/dist/internal/oauthClient.d.ts.map +1 -0
- package/dist/internal/oauthClient.js +133 -0
- package/dist/internal/oauthPresets.d.ts +33 -0
- package/dist/internal/oauthPresets.d.ts.map +1 -0
- package/dist/internal/oauthPresets.js +1064 -0
- package/dist/internal/oauthScopes.d.ts +172 -0
- package/dist/internal/oauthScopes.d.ts.map +1 -0
- package/dist/internal/oauthScopes.js +510 -0
- package/dist/internal/oauthSpec.d.ts +102 -0
- package/dist/internal/oauthSpec.d.ts.map +1 -0
- package/dist/internal/oauthSpec.js +789 -0
- package/dist/internal/organizationName.d.ts +18 -0
- package/dist/internal/organizationName.d.ts.map +1 -0
- package/dist/internal/organizationName.js +24 -0
- package/dist/internal/protocol.d.ts +150 -3
- package/dist/internal/protocol.d.ts.map +1 -1
- package/dist/internal/protocol.js +163 -2
- package/dist/internal/providerApps.d.ts +75 -0
- package/dist/internal/providerApps.d.ts.map +1 -0
- package/dist/internal/providerApps.js +59 -0
- package/dist/internal/providerRegistry.d.ts +218 -0
- package/dist/internal/providerRegistry.d.ts.map +1 -0
- package/dist/internal/providerRegistry.js +432 -0
- package/dist/internal/providerSpec.d.ts +66 -0
- package/dist/internal/providerSpec.d.ts.map +1 -0
- package/dist/internal/providerSpec.js +1154 -0
- package/dist/internal/remoteMcp.d.ts +188 -0
- package/dist/internal/remoteMcp.d.ts.map +1 -0
- package/dist/internal/remoteMcp.js +543 -0
- package/dist/internal/signInProviders.d.ts +104 -0
- package/dist/internal/signInProviders.d.ts.map +1 -0
- package/dist/internal/signInProviders.js +245 -0
- package/dist/internal/tools.d.ts +115 -0
- package/dist/internal/tools.d.ts.map +1 -0
- package/dist/internal/tools.js +80 -0
- package/dist/manifest.d.ts +238 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +30 -0
- package/dist/server/ai.d.ts +111 -0
- package/dist/server/ai.d.ts.map +1 -0
- package/dist/server/ai.js +145 -0
- package/dist/server/aiBinding.d.ts +68 -0
- package/dist/server/aiBinding.d.ts.map +1 -0
- package/dist/server/aiBinding.js +294 -0
- package/dist/server/attribution.d.ts +43 -0
- package/dist/server/attribution.d.ts.map +1 -0
- package/dist/server/attribution.js +75 -0
- package/dist/server/authorizeUrl.d.ts +43 -0
- package/dist/server/authorizeUrl.d.ts.map +1 -0
- package/dist/server/authorizeUrl.js +106 -0
- package/dist/server/connectUrl.d.ts +21 -0
- package/dist/server/connectUrl.d.ts.map +1 -0
- package/dist/server/connectUrl.js +37 -0
- package/dist/server/context.d.ts +68 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +117 -0
- package/dist/server/emailBinding.d.ts +72 -0
- package/dist/server/emailBinding.d.ts.map +1 -0
- package/dist/server/emailBinding.js +124 -0
- package/dist/server/emit.d.ts +63 -0
- package/dist/server/emit.d.ts.map +1 -0
- package/dist/server/emit.js +101 -0
- package/dist/server/env.d.ts +44 -0
- package/dist/server/env.d.ts.map +1 -0
- package/dist/server/env.js +1 -0
- package/dist/server/everyApp.d.ts +65 -19
- package/dist/server/everyApp.d.ts.map +1 -1
- package/dist/server/everyApp.js +195 -30
- package/dist/server/fromMcpTools.d.ts +89 -0
- package/dist/server/fromMcpTools.d.ts.map +1 -0
- package/dist/server/fromMcpTools.js +192 -0
- package/dist/server/gatewayFetch.d.ts +54 -14
- package/dist/server/gatewayFetch.d.ts.map +1 -1
- package/dist/server/gatewayFetch.js +201 -37
- package/dist/server/gatewayUrl.d.ts +13 -0
- package/dist/server/gatewayUrl.d.ts.map +1 -0
- package/dist/server/gatewayUrl.js +34 -0
- package/dist/server/index.d.ts +23 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +19 -2
- package/dist/server/integrationFetch.d.ts +162 -0
- package/dist/server/integrationFetch.d.ts.map +1 -0
- package/dist/server/integrationFetch.js +688 -0
- package/dist/server/listMembers.d.ts +32 -0
- package/dist/server/listMembers.d.ts.map +1 -0
- package/dist/server/listMembers.js +71 -0
- package/dist/server/nodeServer.d.ts +48 -0
- package/dist/server/nodeServer.d.ts.map +1 -0
- package/dist/server/nodeServer.js +45 -0
- package/dist/server/refusal.d.ts +55 -0
- package/dist/server/refusal.d.ts.map +1 -0
- package/dist/server/refusal.js +193 -0
- package/dist/server/sendEmail.d.ts +39 -0
- package/dist/server/sendEmail.d.ts.map +1 -0
- package/dist/server/sendEmail.js +114 -0
- package/dist/server/tools.d.ts +184 -0
- package/dist/server/tools.d.ts.map +1 -0
- package/dist/server/tools.js +347 -0
- package/dist/server/toolsEndpoint.d.ts +32 -0
- package/dist/server/toolsEndpoint.d.ts.map +1 -0
- package/dist/server/toolsEndpoint.js +237 -0
- package/dist/tanstack-start/index.d.ts +9 -0
- package/dist/tanstack-start/index.d.ts.map +1 -0
- package/dist/tanstack-start/index.js +29 -0
- package/dist/testing/index.d.ts +93 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +156 -0
- package/package.json +42 -8
- package/dist/server/mcp.d.ts +0 -66
- package/dist/server/mcp.d.ts.map +0 -1
- package/dist/server/mcp.js +0 -147
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The rule for a workspace's name: what the Gateway's setup claim gives
|
|
3
|
+
* the first organization, what a personal organization is called, and
|
|
4
|
+
* what a rename takes (Manage workspace → Rename, `everyapp workspace
|
|
5
|
+
* rename`). The Gateway and the CLI share it so a name the CLI writes is
|
|
6
|
+
* one the Gateway would have accepted. A name is user input that reaches
|
|
7
|
+
* other people: the invitation emails it sends, and every member's
|
|
8
|
+
* organization switcher.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MAX_ORGANIZATION_NAME_LENGTH = 64;
|
|
11
|
+
/**
|
|
12
|
+
* The name, trimmed and with its runs of whitespace made single spaces, or
|
|
13
|
+
* null when it is empty, longer than 64 characters, or has a control or
|
|
14
|
+
* invisible formatting character (line breaks, bidirectional overrides,
|
|
15
|
+
* zero-width characters) anywhere in it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function validOrganizationName(raw: string): string | null;
|
|
18
|
+
//# sourceMappingURL=organizationName.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organizationName.d.ts","sourceRoot":"","sources":["../../src/internal/organizationName.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKhE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The rule for a workspace's name: what the Gateway's setup claim gives
|
|
3
|
+
* the first organization, what a personal organization is called, and
|
|
4
|
+
* what a rename takes (Manage workspace → Rename, `everyapp workspace
|
|
5
|
+
* rename`). The Gateway and the CLI share it so a name the CLI writes is
|
|
6
|
+
* one the Gateway would have accepted. A name is user input that reaches
|
|
7
|
+
* other people: the invitation emails it sends, and every member's
|
|
8
|
+
* organization switcher.
|
|
9
|
+
*/
|
|
10
|
+
export const MAX_ORGANIZATION_NAME_LENGTH = 64;
|
|
11
|
+
/**
|
|
12
|
+
* The name, trimmed and with its runs of whitespace made single spaces, or
|
|
13
|
+
* null when it is empty, longer than 64 characters, or has a control or
|
|
14
|
+
* invisible formatting character (line breaks, bidirectional overrides,
|
|
15
|
+
* zero-width characters) anywhere in it.
|
|
16
|
+
*/
|
|
17
|
+
export function validOrganizationName(raw) {
|
|
18
|
+
if (/[\p{Cc}\p{Cf}\u2028\u2029]/u.test(raw))
|
|
19
|
+
return null;
|
|
20
|
+
const name = raw.trim().replace(/\s+/g, " ");
|
|
21
|
+
if (!name || [...name].length > MAX_ORGANIZATION_NAME_LENGTH)
|
|
22
|
+
return null;
|
|
23
|
+
return name;
|
|
24
|
+
}
|
|
@@ -6,25 +6,108 @@
|
|
|
6
6
|
* and gateway-side JWT minters shared by the platform packages.
|
|
7
7
|
*/
|
|
8
8
|
import { type JWTPayload } from "jose";
|
|
9
|
+
import type { ToolCallClaim } from "./tools.js";
|
|
9
10
|
export declare const IDENTITY_ALG = "RS256";
|
|
10
11
|
export declare const IDENTITY_KEY_ID = "everyapp-identity";
|
|
11
12
|
export declare const IDENTITY_DEV_KEY_ID = "everyapp-identity-dev";
|
|
13
|
+
/**
|
|
14
|
+
* The only issuer a dev-kid token may name. The same value as
|
|
15
|
+
* `@every-app/sdk/dev`'s, kept apart so the Worker never loads the module
|
|
16
|
+
* `cloudflare.config.ts` does (a test pins the two together).
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEV_ISSUER = "https://gateway.dev.localhost";
|
|
12
19
|
export declare const IDENTITY_HEADER = "x-everyapp-identity";
|
|
13
20
|
export declare const PUBLIC_HEADER = "x-everyapp-public";
|
|
21
|
+
/**
|
|
22
|
+
* Carries the gateway's system token on its own calls to an app (the tools
|
|
23
|
+
* catalog fetch). Never an identity: no user, and it only opens the endpoint
|
|
24
|
+
* named by its `purpose` claim.
|
|
25
|
+
*/
|
|
26
|
+
export declare const SYSTEM_HEADER = "x-everyapp-system";
|
|
27
|
+
/**
|
|
28
|
+
* On a refusal the AppGateway binding makes itself (the app's manifest lacks
|
|
29
|
+
* the capability, the gateway holds no key), as opposed to the provider's
|
|
30
|
+
* own answer passed through: the refusal's code, also in the JSON body.
|
|
31
|
+
*/
|
|
32
|
+
export declare const GATEWAY_ERROR_HEADER = "x-everyapp-error";
|
|
33
|
+
/**
|
|
34
|
+
* On a shared app's call to the AppGateway binding for work no request
|
|
35
|
+
* started (a cron, a Workflow step): the organization the work is for. The
|
|
36
|
+
* gateway believes it only from a shared app's Worker, and only for an
|
|
37
|
+
* active organization with a live member; an organization's own app may
|
|
38
|
+
* only name its own. The perimeter strips it, with every `x-everyapp-*`,
|
|
39
|
+
* from what browsers send.
|
|
40
|
+
*/
|
|
41
|
+
export declare const ORG_HEADER = "x-everyapp-org";
|
|
42
|
+
/**
|
|
43
|
+
* Which connection an app's call to an OAuth provider uses: the person's
|
|
44
|
+
* (`user`, the default when a person is behind the call) or the
|
|
45
|
+
* organization's (`organization`, the default for background work),
|
|
46
|
+
* docs/design/2026-10-oauth-providers.md section 7. Set by
|
|
47
|
+
* `integrationFetch({ account })`; the gateway reads it on the held-token
|
|
48
|
+
* branch and ignores it elsewhere.
|
|
49
|
+
*/
|
|
50
|
+
export declare const ACCOUNT_HEADER = "x-everyapp-account";
|
|
51
|
+
/** The values {@link ACCOUNT_HEADER} may carry. */
|
|
52
|
+
export type ConnectionAccount = "user" | "organization";
|
|
14
53
|
/** 120-second lifetime — caps revocation staleness while surviving clock skew. */
|
|
15
54
|
export declare const IDENTITY_TTL_SECONDS = 120;
|
|
16
|
-
/**
|
|
55
|
+
/** System tokens are minted per call and live at most a minute. */
|
|
56
|
+
export declare const SYSTEM_TOKEN_TTL_SECONDS = 60;
|
|
57
|
+
/** Env var carrying the app's manifest id. */
|
|
17
58
|
export declare const APP_ID_ENV = "EVERYAPP_APP_ID";
|
|
59
|
+
/**
|
|
60
|
+
* Env var carrying the expected identity audience: the app's Worker name,
|
|
61
|
+
* which the gateway stamps as `aud` on every token it mints for the app. Two
|
|
62
|
+
* Workers of one app id (two organizations' copies) never accept each
|
|
63
|
+
* other's tokens.
|
|
64
|
+
*/
|
|
65
|
+
export declare const AUDIENCE_ENV = "EVERYAPP_AUDIENCE";
|
|
18
66
|
/** Default env var carrying a JSON array of SPKI PEM public keys. */
|
|
19
67
|
export declare const PUBLIC_KEYS_ENV = "EVERYAPP_IDENTITY_PUBLIC_KEYS";
|
|
20
68
|
/** Env var carrying the expected gateway issuer for user identity verification. */
|
|
21
69
|
export declare const ISSUER_ENV = "EVERYAPP_IDENTITY_ISSUER";
|
|
70
|
+
/**
|
|
71
|
+
* Env var set to `1` on a shared app's Workers (one Worker for every
|
|
72
|
+
* organization): a gateway call from them must say whom it is for.
|
|
73
|
+
*/
|
|
74
|
+
export declare const SHARED_ENV = "EVERYAPP_SHARED";
|
|
22
75
|
/** When set to `1` or `true` in the worker env, the dev identity kid is accepted. */
|
|
23
76
|
export declare const DEV_ENV = "EVERYAPP_DEV";
|
|
77
|
+
/**
|
|
78
|
+
* The organization an app's Worker is pinned to (a secret the deploy sends;
|
|
79
|
+
* in development the stub gateway's organization). `everyApp()` refuses an
|
|
80
|
+
* identity for any other organization; absent on a shared app's Workers.
|
|
81
|
+
*/
|
|
82
|
+
export declare const ORG_ID_ENV = "EVERY_APP_ORG_ID";
|
|
83
|
+
/**
|
|
84
|
+
* The organization the dev gateway's seeded user belongs to. The same value
|
|
85
|
+
* as `@every-app/sdk/dev`'s, kept apart like {@link DEV_ISSUER} (the same
|
|
86
|
+
* test pins the two together).
|
|
87
|
+
*/
|
|
88
|
+
export declare const DEV_ORG_ID = "dev-org";
|
|
24
89
|
/** `sub` claim the gateway mints public-route markers with. */
|
|
25
90
|
export declare const PUBLIC_MARKER_SUB = "public";
|
|
91
|
+
/** `sub` claim of gateway system tokens. */
|
|
92
|
+
export declare const SYSTEM_TOKEN_SUB = "system";
|
|
93
|
+
/**
|
|
94
|
+
* Linked dev (`everyapp dev --gateway`, docs/design/linked-dev.md): the
|
|
95
|
+
* dev Worker's env names the gateway-lite's loopback forwarder and the
|
|
96
|
+
* run's nonce, and the SDK builds a `{ fetch }` in place of the missing
|
|
97
|
+
* `EVERY_APP_GATEWAY` binding from them. Set by `everyAppWorker()` in a
|
|
98
|
+
* development build from the process environment `everyapp dev` starts
|
|
99
|
+
* the app with; never deployed.
|
|
100
|
+
*/
|
|
101
|
+
export declare const LINKED_DEV_URL_ENV = "EVERYAPP_LINKED_DEV_URL";
|
|
102
|
+
export declare const LINKED_DEV_NONCE_ENV = "EVERYAPP_LINKED_DEV_NONCE";
|
|
103
|
+
/** The header the forwarder requires, with the run's nonce: no simple cross-origin request can send it. */
|
|
104
|
+
export declare const LINKED_DEV_HEADER = "x-everyapp-linked-dev";
|
|
105
|
+
/** Where the gateway-lite serves the forwarder, under the app's own host. */
|
|
106
|
+
export declare const LINKED_DEV_FORWARD_PATH = "/__everyapp/gateway";
|
|
26
107
|
export type IdentityChannel = "web" | "api" | "mcp" | "agent";
|
|
27
|
-
export type IdentityTokenType = "user" | "public";
|
|
108
|
+
export type IdentityTokenType = "user" | "public" | "system";
|
|
109
|
+
/** What a system token may open. One purpose per token. */
|
|
110
|
+
export type SystemTokenPurpose = "tools.list";
|
|
28
111
|
/** The actor on whose behalf the request is made (user, MCP client, agent). */
|
|
29
112
|
export interface IdentityActor {
|
|
30
113
|
sub: string;
|
|
@@ -34,28 +117,66 @@ export interface IdentitySubject {
|
|
|
34
117
|
email: string;
|
|
35
118
|
orgId: string;
|
|
36
119
|
orgRole: string;
|
|
120
|
+
/**
|
|
121
|
+
* The organization's name as its owners set it (`org_name`), so an app
|
|
122
|
+
* can show "Acme" rather than an id. Left out when the minter has none.
|
|
123
|
+
*/
|
|
124
|
+
orgName?: string;
|
|
37
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* A member's role in the organization, as the identity token carries it.
|
|
128
|
+
* Owners and admins manage; anything the Gateway might mint that an app
|
|
129
|
+
* doesn't know is read as `member`.
|
|
130
|
+
*/
|
|
131
|
+
export type OrgRole = "owner" | "admin" | "member";
|
|
132
|
+
/** `role` as an {@link OrgRole}: `owner` and `admin` as they are, anything else `member`. */
|
|
133
|
+
export declare function toOrgRole(role: unknown): OrgRole;
|
|
134
|
+
/** Whether `user` manages the organization: an owner or an admin. */
|
|
135
|
+
export declare function isAdmin(user: {
|
|
136
|
+
orgRole: OrgRole | string;
|
|
137
|
+
}): boolean;
|
|
38
138
|
export interface EveryAppUser {
|
|
39
139
|
/** User id (the `sub` claim). */
|
|
40
140
|
id: string;
|
|
41
141
|
email: string;
|
|
42
142
|
orgId: string;
|
|
43
|
-
orgRole:
|
|
143
|
+
orgRole: OrgRole;
|
|
144
|
+
/**
|
|
145
|
+
* The organization's display name (the `org_name` claim), as its owners
|
|
146
|
+
* set it: trimmed, at most 64 characters, no control characters. Show
|
|
147
|
+
* it; never key data by it (names change, `orgId` doesn't). Undefined
|
|
148
|
+
* when the token carries none.
|
|
149
|
+
*/
|
|
150
|
+
orgName?: string;
|
|
44
151
|
channel: IdentityChannel;
|
|
45
152
|
/** The acting principal (user, or `mcp:<client>` / agent). */
|
|
46
153
|
actor: IdentityActor;
|
|
47
154
|
scopes: string[];
|
|
48
155
|
jti: string;
|
|
156
|
+
/**
|
|
157
|
+
* Set only on an MCP tool call (`channel: "mcp"`): the one call this
|
|
158
|
+
* identity was minted for.
|
|
159
|
+
*/
|
|
160
|
+
toolCall?: ToolCallClaim;
|
|
49
161
|
}
|
|
50
162
|
export interface IdentityClaims extends JWTPayload {
|
|
51
163
|
typ: "user";
|
|
52
164
|
email: string;
|
|
53
165
|
org_id: string;
|
|
54
166
|
org_role: string;
|
|
167
|
+
/** The organization's display name; absent when the minter had none. */
|
|
168
|
+
org_name?: string;
|
|
55
169
|
chan: IdentityChannel;
|
|
56
170
|
act: IdentityActor;
|
|
57
171
|
scopes: string[];
|
|
58
172
|
jti: string;
|
|
173
|
+
/** Tool-call binding; only the gateway's ToolBus mints it. */
|
|
174
|
+
tc?: ToolCallClaim;
|
|
175
|
+
}
|
|
176
|
+
export interface SystemClaims extends JWTPayload {
|
|
177
|
+
typ: "system";
|
|
178
|
+
purpose: SystemTokenPurpose;
|
|
179
|
+
jti: string;
|
|
59
180
|
}
|
|
60
181
|
export interface PublicMarkerClaims extends JWTPayload {
|
|
61
182
|
typ: "public";
|
|
@@ -69,11 +190,18 @@ export declare function identitySubjectToClaims(subject: IdentitySubject, opts:
|
|
|
69
190
|
channel?: IdentityChannel;
|
|
70
191
|
actor?: IdentityActor;
|
|
71
192
|
scopes?: string[];
|
|
193
|
+
toolCall?: ToolCallClaim;
|
|
72
194
|
jti: string;
|
|
73
195
|
}): IdentityClaims;
|
|
74
196
|
export declare function identityClaimsToEveryAppUser(payload: JWTPayload): EveryAppUser;
|
|
75
197
|
export declare function publicMarkerClaims(jti: string): PublicMarkerClaims;
|
|
76
198
|
export declare function assertPublicMarkerClaims(payload: JWTPayload): void;
|
|
199
|
+
/**
|
|
200
|
+
* A system token opens exactly one endpoint and lives at most
|
|
201
|
+
* {@link SYSTEM_TOKEN_TTL_SECONDS}: a leaked one is short-lived and useless
|
|
202
|
+
* anywhere else.
|
|
203
|
+
*/
|
|
204
|
+
export declare function assertSystemClaims(payload: JWTPayload, purpose: SystemTokenPurpose): SystemClaims;
|
|
77
205
|
export interface MintIdentityOptions {
|
|
78
206
|
subject: IdentitySubject;
|
|
79
207
|
/** The app id this token is scoped to — becomes the `aud` claim. */
|
|
@@ -82,6 +210,8 @@ export interface MintIdentityOptions {
|
|
|
82
210
|
channel?: IdentityChannel;
|
|
83
211
|
actor?: IdentityActor;
|
|
84
212
|
scopes?: string[];
|
|
213
|
+
/** Bind the token to one MCP tool call (`tc` claim). ToolBus only. */
|
|
214
|
+
toolCall?: ToolCallClaim;
|
|
85
215
|
ttlSeconds?: number;
|
|
86
216
|
now?: number;
|
|
87
217
|
/** Header kid. Defaults to the production kid; dev mints with the dev kid. */
|
|
@@ -108,4 +238,21 @@ export interface MintPublicMarkerOptions {
|
|
|
108
238
|
* an identity token.
|
|
109
239
|
*/
|
|
110
240
|
export declare function mintPublicMarkerJwt(privateKeyPem: string, opts: MintPublicMarkerOptions): Promise<string>;
|
|
241
|
+
export interface MintSystemTokenOptions {
|
|
242
|
+
/** The app id the token is for — becomes the `aud` claim. */
|
|
243
|
+
audience: string;
|
|
244
|
+
issuer: string;
|
|
245
|
+
purpose: SystemTokenPurpose;
|
|
246
|
+
/** At most {@link SYSTEM_TOKEN_TTL_SECONDS}. */
|
|
247
|
+
ttlSeconds?: number;
|
|
248
|
+
now?: number;
|
|
249
|
+
/** Header kid. Defaults to the production kid; dev mints with the dev kid. */
|
|
250
|
+
keyId?: string;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Mint the gateway's system token for `x-everyapp-system`: no user, one
|
|
254
|
+
* purpose, one app, one minute. The SDK only accepts it on the endpoint its
|
|
255
|
+
* purpose names, and never as an identity.
|
|
256
|
+
*/
|
|
257
|
+
export declare function mintSystemJwt(privateKeyPem: string, opts: MintSystemTokenOptions): Promise<string>;
|
|
111
258
|
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/internal/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,20 +9,106 @@ import { SignJWT, importPKCS8 } from "jose";
|
|
|
9
9
|
export const IDENTITY_ALG = "RS256";
|
|
10
10
|
export const IDENTITY_KEY_ID = "everyapp-identity";
|
|
11
11
|
export const IDENTITY_DEV_KEY_ID = "everyapp-identity-dev";
|
|
12
|
+
/**
|
|
13
|
+
* The only issuer a dev-kid token may name. The same value as
|
|
14
|
+
* `@every-app/sdk/dev`'s, kept apart so the Worker never loads the module
|
|
15
|
+
* `cloudflare.config.ts` does (a test pins the two together).
|
|
16
|
+
*/
|
|
17
|
+
export const DEV_ISSUER = "https://gateway.dev.localhost";
|
|
12
18
|
export const IDENTITY_HEADER = "x-everyapp-identity";
|
|
13
19
|
export const PUBLIC_HEADER = "x-everyapp-public";
|
|
20
|
+
/**
|
|
21
|
+
* Carries the gateway's system token on its own calls to an app (the tools
|
|
22
|
+
* catalog fetch). Never an identity: no user, and it only opens the endpoint
|
|
23
|
+
* named by its `purpose` claim.
|
|
24
|
+
*/
|
|
25
|
+
export const SYSTEM_HEADER = "x-everyapp-system";
|
|
26
|
+
/**
|
|
27
|
+
* On a refusal the AppGateway binding makes itself (the app's manifest lacks
|
|
28
|
+
* the capability, the gateway holds no key), as opposed to the provider's
|
|
29
|
+
* own answer passed through: the refusal's code, also in the JSON body.
|
|
30
|
+
*/
|
|
31
|
+
export const GATEWAY_ERROR_HEADER = "x-everyapp-error";
|
|
32
|
+
/**
|
|
33
|
+
* On a shared app's call to the AppGateway binding for work no request
|
|
34
|
+
* started (a cron, a Workflow step): the organization the work is for. The
|
|
35
|
+
* gateway believes it only from a shared app's Worker, and only for an
|
|
36
|
+
* active organization with a live member; an organization's own app may
|
|
37
|
+
* only name its own. The perimeter strips it, with every `x-everyapp-*`,
|
|
38
|
+
* from what browsers send.
|
|
39
|
+
*/
|
|
40
|
+
export const ORG_HEADER = "x-everyapp-org";
|
|
41
|
+
/**
|
|
42
|
+
* Which connection an app's call to an OAuth provider uses: the person's
|
|
43
|
+
* (`user`, the default when a person is behind the call) or the
|
|
44
|
+
* organization's (`organization`, the default for background work),
|
|
45
|
+
* docs/design/2026-10-oauth-providers.md section 7. Set by
|
|
46
|
+
* `integrationFetch({ account })`; the gateway reads it on the held-token
|
|
47
|
+
* branch and ignores it elsewhere.
|
|
48
|
+
*/
|
|
49
|
+
export const ACCOUNT_HEADER = "x-everyapp-account";
|
|
14
50
|
/** 120-second lifetime — caps revocation staleness while surviving clock skew. */
|
|
15
51
|
export const IDENTITY_TTL_SECONDS = 120;
|
|
16
|
-
/**
|
|
52
|
+
/** System tokens are minted per call and live at most a minute. */
|
|
53
|
+
export const SYSTEM_TOKEN_TTL_SECONDS = 60;
|
|
54
|
+
/** Env var carrying the app's manifest id. */
|
|
17
55
|
export const APP_ID_ENV = "EVERYAPP_APP_ID";
|
|
56
|
+
/**
|
|
57
|
+
* Env var carrying the expected identity audience: the app's Worker name,
|
|
58
|
+
* which the gateway stamps as `aud` on every token it mints for the app. Two
|
|
59
|
+
* Workers of one app id (two organizations' copies) never accept each
|
|
60
|
+
* other's tokens.
|
|
61
|
+
*/
|
|
62
|
+
export const AUDIENCE_ENV = "EVERYAPP_AUDIENCE";
|
|
18
63
|
/** Default env var carrying a JSON array of SPKI PEM public keys. */
|
|
19
64
|
export const PUBLIC_KEYS_ENV = "EVERYAPP_IDENTITY_PUBLIC_KEYS";
|
|
20
65
|
/** Env var carrying the expected gateway issuer for user identity verification. */
|
|
21
66
|
export const ISSUER_ENV = "EVERYAPP_IDENTITY_ISSUER";
|
|
67
|
+
/**
|
|
68
|
+
* Env var set to `1` on a shared app's Workers (one Worker for every
|
|
69
|
+
* organization): a gateway call from them must say whom it is for.
|
|
70
|
+
*/
|
|
71
|
+
export const SHARED_ENV = "EVERYAPP_SHARED";
|
|
22
72
|
/** When set to `1` or `true` in the worker env, the dev identity kid is accepted. */
|
|
23
73
|
export const DEV_ENV = "EVERYAPP_DEV";
|
|
74
|
+
/**
|
|
75
|
+
* The organization an app's Worker is pinned to (a secret the deploy sends;
|
|
76
|
+
* in development the stub gateway's organization). `everyApp()` refuses an
|
|
77
|
+
* identity for any other organization; absent on a shared app's Workers.
|
|
78
|
+
*/
|
|
79
|
+
export const ORG_ID_ENV = "EVERY_APP_ORG_ID";
|
|
80
|
+
/**
|
|
81
|
+
* The organization the dev gateway's seeded user belongs to. The same value
|
|
82
|
+
* as `@every-app/sdk/dev`'s, kept apart like {@link DEV_ISSUER} (the same
|
|
83
|
+
* test pins the two together).
|
|
84
|
+
*/
|
|
85
|
+
export const DEV_ORG_ID = "dev-org";
|
|
24
86
|
/** `sub` claim the gateway mints public-route markers with. */
|
|
25
87
|
export const PUBLIC_MARKER_SUB = "public";
|
|
88
|
+
/** `sub` claim of gateway system tokens. */
|
|
89
|
+
export const SYSTEM_TOKEN_SUB = "system";
|
|
90
|
+
/**
|
|
91
|
+
* Linked dev (`everyapp dev --gateway`, docs/design/linked-dev.md): the
|
|
92
|
+
* dev Worker's env names the gateway-lite's loopback forwarder and the
|
|
93
|
+
* run's nonce, and the SDK builds a `{ fetch }` in place of the missing
|
|
94
|
+
* `EVERY_APP_GATEWAY` binding from them. Set by `everyAppWorker()` in a
|
|
95
|
+
* development build from the process environment `everyapp dev` starts
|
|
96
|
+
* the app with; never deployed.
|
|
97
|
+
*/
|
|
98
|
+
export const LINKED_DEV_URL_ENV = "EVERYAPP_LINKED_DEV_URL";
|
|
99
|
+
export const LINKED_DEV_NONCE_ENV = "EVERYAPP_LINKED_DEV_NONCE";
|
|
100
|
+
/** The header the forwarder requires, with the run's nonce: no simple cross-origin request can send it. */
|
|
101
|
+
export const LINKED_DEV_HEADER = "x-everyapp-linked-dev";
|
|
102
|
+
/** Where the gateway-lite serves the forwarder, under the app's own host. */
|
|
103
|
+
export const LINKED_DEV_FORWARD_PATH = "/__everyapp/gateway";
|
|
104
|
+
/** `role` as an {@link OrgRole}: `owner` and `admin` as they are, anything else `member`. */
|
|
105
|
+
export function toOrgRole(role) {
|
|
106
|
+
return role === "owner" || role === "admin" ? role : "member";
|
|
107
|
+
}
|
|
108
|
+
/** Whether `user` manages the organization: an owner or an admin. */
|
|
109
|
+
export function isAdmin(user) {
|
|
110
|
+
return user.orgRole === "owner" || user.orgRole === "admin";
|
|
111
|
+
}
|
|
26
112
|
export class ProtocolClaimsError extends Error {
|
|
27
113
|
constructor(message) {
|
|
28
114
|
super(message);
|
|
@@ -35,12 +121,30 @@ export function identitySubjectToClaims(subject, opts) {
|
|
|
35
121
|
email: subject.email,
|
|
36
122
|
org_id: subject.orgId,
|
|
37
123
|
org_role: subject.orgRole,
|
|
124
|
+
...(subject.orgName ? { org_name: subject.orgName } : {}),
|
|
38
125
|
chan: opts.channel ?? "web",
|
|
39
126
|
act: opts.actor ?? { sub: subject.sub },
|
|
40
127
|
scopes: opts.scopes ?? ["*"],
|
|
41
128
|
jti: opts.jti,
|
|
129
|
+
...(opts.toolCall
|
|
130
|
+
? { tc: { id: opts.toolCall.id, name: opts.toolCall.name } }
|
|
131
|
+
: {}),
|
|
42
132
|
};
|
|
43
133
|
}
|
|
134
|
+
function parseToolCallClaim(value) {
|
|
135
|
+
if (value === undefined)
|
|
136
|
+
return undefined;
|
|
137
|
+
const claim = value;
|
|
138
|
+
if (!claim ||
|
|
139
|
+
typeof claim !== "object" ||
|
|
140
|
+
typeof claim.id !== "string" ||
|
|
141
|
+
typeof claim.name !== "string" ||
|
|
142
|
+
!claim.id ||
|
|
143
|
+
!claim.name) {
|
|
144
|
+
throw new ProtocolClaimsError("identity token has a malformed tc claim");
|
|
145
|
+
}
|
|
146
|
+
return { id: claim.id, name: claim.name };
|
|
147
|
+
}
|
|
44
148
|
export function identityClaimsToEveryAppUser(payload) {
|
|
45
149
|
if (payload.typ !== "user") {
|
|
46
150
|
throw new ProtocolClaimsError("identity token has wrong typ");
|
|
@@ -52,20 +156,28 @@ export function identityClaimsToEveryAppUser(payload) {
|
|
|
52
156
|
if (!sub || !email || !orgId || !orgRole) {
|
|
53
157
|
throw new ProtocolClaimsError("identity token missing required claims");
|
|
54
158
|
}
|
|
159
|
+
// Display only, so a token without it (or with a malformed one) is still
|
|
160
|
+
// an identity: the app falls back to no name.
|
|
161
|
+
const orgName = typeof payload.org_name === "string" && payload.org_name
|
|
162
|
+
? payload.org_name
|
|
163
|
+
: undefined;
|
|
55
164
|
const chan = payload.chan ?? "web";
|
|
56
165
|
const act = payload.act ?? { sub };
|
|
57
166
|
const scopes = Array.isArray(payload.scopes)
|
|
58
167
|
? payload.scopes.filter((scope) => typeof scope === "string")
|
|
59
168
|
: ["*"];
|
|
169
|
+
const toolCall = parseToolCallClaim(payload.tc);
|
|
60
170
|
return {
|
|
61
171
|
id: sub,
|
|
62
172
|
email,
|
|
63
173
|
orgId,
|
|
64
|
-
orgRole,
|
|
174
|
+
orgRole: toOrgRole(orgRole),
|
|
175
|
+
...(orgName ? { orgName } : {}),
|
|
65
176
|
channel: chan,
|
|
66
177
|
actor: { sub: act.sub ?? sub },
|
|
67
178
|
scopes,
|
|
68
179
|
jti: payload.jti ?? "",
|
|
180
|
+
...(toolCall ? { toolCall } : {}),
|
|
69
181
|
};
|
|
70
182
|
}
|
|
71
183
|
export function publicMarkerClaims(jti) {
|
|
@@ -79,6 +191,25 @@ export function assertPublicMarkerClaims(payload) {
|
|
|
79
191
|
throw new ProtocolClaimsError("token is not a public-route marker");
|
|
80
192
|
}
|
|
81
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* A system token opens exactly one endpoint and lives at most
|
|
196
|
+
* {@link SYSTEM_TOKEN_TTL_SECONDS}: a leaked one is short-lived and useless
|
|
197
|
+
* anywhere else.
|
|
198
|
+
*/
|
|
199
|
+
export function assertSystemClaims(payload, purpose) {
|
|
200
|
+
if (payload.typ !== "system" || payload.sub !== SYSTEM_TOKEN_SUB) {
|
|
201
|
+
throw new ProtocolClaimsError("token is not a system token");
|
|
202
|
+
}
|
|
203
|
+
if (payload.purpose !== purpose) {
|
|
204
|
+
throw new ProtocolClaimsError(`system token purpose "${String(payload.purpose)}" is not "${purpose}"`);
|
|
205
|
+
}
|
|
206
|
+
if (typeof payload.iat !== "number" ||
|
|
207
|
+
typeof payload.exp !== "number" ||
|
|
208
|
+
payload.exp - payload.iat > SYSTEM_TOKEN_TTL_SECONDS) {
|
|
209
|
+
throw new ProtocolClaimsError(`system token must expire within ${SYSTEM_TOKEN_TTL_SECONDS}s of issue`);
|
|
210
|
+
}
|
|
211
|
+
return payload;
|
|
212
|
+
}
|
|
82
213
|
let cachedPrivateKey = null;
|
|
83
214
|
async function loadPrivateKey(privateKeyPem) {
|
|
84
215
|
const pem = privateKeyPem.replace(/\\n/g, "\n");
|
|
@@ -102,6 +233,7 @@ export async function mintIdentityJwt(privateKeyPem, opts) {
|
|
|
102
233
|
channel: opts.channel,
|
|
103
234
|
actor: opts.actor,
|
|
104
235
|
scopes: opts.scopes,
|
|
236
|
+
toolCall: opts.toolCall,
|
|
105
237
|
jti,
|
|
106
238
|
}))
|
|
107
239
|
.setProtectedHeader({
|
|
@@ -137,3 +269,32 @@ export async function mintPublicMarkerJwt(privateKeyPem, opts) {
|
|
|
137
269
|
.setExpirationTime(nowSec + ttl)
|
|
138
270
|
.sign(key);
|
|
139
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Mint the gateway's system token for `x-everyapp-system`: no user, one
|
|
274
|
+
* purpose, one app, one minute. The SDK only accepts it on the endpoint its
|
|
275
|
+
* purpose names, and never as an identity.
|
|
276
|
+
*/
|
|
277
|
+
export async function mintSystemJwt(privateKeyPem, opts) {
|
|
278
|
+
const ttl = opts.ttlSeconds ?? SYSTEM_TOKEN_TTL_SECONDS;
|
|
279
|
+
if (ttl <= 0 || ttl > SYSTEM_TOKEN_TTL_SECONDS) {
|
|
280
|
+
throw new RangeError(`system tokens live at most ${SYSTEM_TOKEN_TTL_SECONDS}s (got ${ttl})`);
|
|
281
|
+
}
|
|
282
|
+
const key = await loadPrivateKey(privateKeyPem);
|
|
283
|
+
const nowSec = Math.floor((opts.now ?? Date.now()) / 1000);
|
|
284
|
+
const claims = {
|
|
285
|
+
typ: "system",
|
|
286
|
+
purpose: opts.purpose,
|
|
287
|
+
jti: crypto.randomUUID(),
|
|
288
|
+
};
|
|
289
|
+
return new SignJWT(claims)
|
|
290
|
+
.setProtectedHeader({
|
|
291
|
+
alg: IDENTITY_ALG,
|
|
292
|
+
kid: opts.keyId ?? IDENTITY_KEY_ID,
|
|
293
|
+
})
|
|
294
|
+
.setIssuer(opts.issuer)
|
|
295
|
+
.setSubject(SYSTEM_TOKEN_SUB)
|
|
296
|
+
.setAudience(opts.audience)
|
|
297
|
+
.setIssuedAt(nowSec)
|
|
298
|
+
.setExpirationTime(nowSec + ttl)
|
|
299
|
+
.sign(key);
|
|
300
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider apps, "MCP apps" to the person: a data provider (DataForSEO
|
|
3
|
+
* today) offered to members as an app of the Gateway's own, with no page
|
|
4
|
+
* and no Worker to deploy. The operator turns it on (`everyapp mcp on
|
|
5
|
+
* <id>`) and sets the provider's key as a Gateway setting; the Gateway then
|
|
6
|
+
* serves the provider's tools on its `/mcp` under `<id>_<tool>` names, with
|
|
7
|
+
* the key never leaving the Gateway, every call attributed to the member
|
|
8
|
+
* who made it, counted and audited like an app's capability calls. The
|
|
9
|
+
* launcher lists it under "MCP apps" and its card opens the "Use it from
|
|
10
|
+
* your agent" dialog instead of a page (docs/design/2026-10-mcp-apps-ui.md).
|
|
11
|
+
*
|
|
12
|
+
* A provider app is an `apps` row of tier {@link PROVIDER_APP_TIER} with no
|
|
13
|
+
* hostname and no Worker name: the perimeter never routes it, and the
|
|
14
|
+
* Gateway reaches its tools in-process rather than over a service binding.
|
|
15
|
+
* Its manifest is generated here, so the settings model
|
|
16
|
+
* (./appSettings.ts) reads the provider's key as a required Gateway setting
|
|
17
|
+
* like any app's capability. The registry rules that write the row are in
|
|
18
|
+
* `@every-app/perimeter/registry` (providerApps.ts); the Gateway serves it
|
|
19
|
+
* from `apps/every-app-gateway/src/server/provider-apps/`.
|
|
20
|
+
*/
|
|
21
|
+
import { type ApiKeyCapabilityId } from "./capabilities.js";
|
|
22
|
+
/** The `apps.tier` of a provider app: no Worker, served by the Gateway itself. */
|
|
23
|
+
export declare const PROVIDER_APP_TIER = "provider";
|
|
24
|
+
export interface ProviderAppDefinition {
|
|
25
|
+
/** The app id (its slug and tool-name prefix): lowercase, no underscore. */
|
|
26
|
+
id: string;
|
|
27
|
+
/** What Admin → Apps and the launcher call it. */
|
|
28
|
+
name: string;
|
|
29
|
+
/** What it is for, as the app library and `everyapp_list_apps` tell it. */
|
|
30
|
+
description: string;
|
|
31
|
+
/**
|
|
32
|
+
* The `api_key` capability whose Gateway setting holds the key and whose
|
|
33
|
+
* proxy rules (hosts, methods, account-wide paths) every tool call obeys.
|
|
34
|
+
*/
|
|
35
|
+
capability: ApiKeyCapabilityId;
|
|
36
|
+
/** Why the app lists the capability: the manifest entry's `why`. */
|
|
37
|
+
why: string;
|
|
38
|
+
/**
|
|
39
|
+
* What to say to an agent to try it, after "Use <name> to": the "Use it
|
|
40
|
+
* from your agent" dialog's example sentence.
|
|
41
|
+
*/
|
|
42
|
+
example: string;
|
|
43
|
+
}
|
|
44
|
+
export declare const PROVIDER_APPS: {
|
|
45
|
+
readonly dataforseo: {
|
|
46
|
+
readonly id: "dataforseo";
|
|
47
|
+
readonly name: "DataForSEO";
|
|
48
|
+
readonly description: "SEO data for your agent: keyword metrics and suggestions, live Google results, domain rankings, competitors and backlinks, through the Gateway's DataForSEO key.";
|
|
49
|
+
readonly capability: "dataforseo";
|
|
50
|
+
readonly why: "Serves DataForSEO's keyword, search-result, domain and backlink data to members' AI clients.";
|
|
51
|
+
readonly example: "find keyword ideas for a page about running shoes";
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export type ProviderAppId = keyof typeof PROVIDER_APPS;
|
|
55
|
+
/** The provider app ids, in a stable order. */
|
|
56
|
+
export declare const PROVIDER_APP_IDS: ProviderAppId[];
|
|
57
|
+
export declare function isProviderAppId(id: string): id is ProviderAppId;
|
|
58
|
+
/** The Gateway setting that holds a provider app's key (`DATAFORSEO_API_KEY`). */
|
|
59
|
+
export declare function providerAppKeySetting(id: ProviderAppId): string;
|
|
60
|
+
/**
|
|
61
|
+
* The manifest a provider app's registry row stores: what a deployed app
|
|
62
|
+
* would declare to use the same capability, so Admin → Apps, the settings
|
|
63
|
+
* model and the integration proxy read it like any app's. Read-only
|
|
64
|
+
* access: every provider app only reads data.
|
|
65
|
+
*/
|
|
66
|
+
export declare function providerAppManifest(id: ProviderAppId): {
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
description: string;
|
|
70
|
+
capabilities: Record<string, {
|
|
71
|
+
access: "read";
|
|
72
|
+
why: string;
|
|
73
|
+
}>;
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=providerApps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerApps.d.ts","sourceRoot":"","sources":["../../src/internal/providerApps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAE3B,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAE5C,MAAM,WAAW,qBAAqB;IACpC,4EAA4E;IAC5E,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,EAAE,kBAAkB,CAAC;IAC/B,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,aAAa;;;;;;;;;CAUgC,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,aAAa,CAAC;AAEvD,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,EAEjB,aAAa,EAAE,CAAC;AAE5B,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,aAAa,CAE/D;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,aAAa,GAAG;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/D,CAUA"}
|