@every-app/sdk 0.2.0 → 0.3.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +608 -2
- package/dist/cloudflare/index.d.ts +22 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +21 -0
- package/dist/cloudflare/sentinel.d.ts +69 -0
- package/dist/cloudflare/sentinel.d.ts.map +1 -0
- package/dist/cloudflare/sentinel.js +50 -0
- package/dist/cloudflare/worker.d.ts +511 -0
- package/dist/cloudflare/worker.d.ts.map +1 -0
- package/dist/cloudflare/worker.js +738 -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 +24 -0
- package/dist/dev/keypair.d.ts.map +1 -0
- package/dist/dev/keypair.js +60 -0
- package/dist/internal/aiProviders.d.ts +67 -0
- package/dist/internal/aiProviders.d.ts.map +1 -0
- package/dist/internal/aiProviders.js +220 -0
- package/dist/internal/appSettings.d.ts +237 -0
- package/dist/internal/appSettings.d.ts.map +1 -0
- package/dist/internal/appSettings.js +374 -0
- package/dist/internal/capabilities.d.ts +1344 -0
- package/dist/internal/capabilities.d.ts.map +1 -0
- package/dist/internal/capabilities.js +1521 -0
- package/dist/internal/devProviders.d.ts +49 -0
- package/dist/internal/devProviders.d.ts.map +1 -0
- package/dist/internal/devProviders.js +62 -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 +182 -0
- package/dist/internal/events.d.ts.map +1 -0
- package/dist/internal/events.js +324 -0
- package/dist/internal/gatewaySettings.d.ts +82 -0
- package/dist/internal/gatewaySettings.d.ts.map +1 -0
- package/dist/internal/gatewaySettings.js +209 -0
- package/dist/internal/identity.d.ts +18 -3
- package/dist/internal/identity.d.ts.map +1 -1
- package/dist/internal/identity.js +53 -14
- package/dist/internal/index.d.ts +17 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +17 -1
- package/dist/internal/members.d.ts +35 -0
- package/dist/internal/members.d.ts.map +1 -0
- package/dist/internal/members.js +7 -0
- package/dist/internal/oauthClient.d.ts +63 -0
- package/dist/internal/oauthClient.d.ts.map +1 -0
- package/dist/internal/oauthClient.js +194 -0
- package/dist/internal/oauthScopes.d.ts +117 -0
- package/dist/internal/oauthScopes.d.ts.map +1 -0
- package/dist/internal/oauthScopes.js +416 -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 +86 -2
- package/dist/internal/protocol.d.ts.map +1 -1
- package/dist/internal/protocol.js +112 -1
- 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 +147 -0
- package/dist/internal/providerRegistry.d.ts.map +1 -0
- package/dist/internal/providerRegistry.js +262 -0
- package/dist/internal/providerSpec.d.ts +55 -0
- package/dist/internal/providerSpec.d.ts.map +1 -0
- package/dist/internal/providerSpec.js +746 -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/tools.d.ts +115 -0
- package/dist/internal/tools.d.ts.map +1 -0
- package/dist/internal/tools.js +80 -0
- package/dist/server/attribution.d.ts +39 -0
- package/dist/server/attribution.d.ts.map +1 -0
- package/dist/server/attribution.js +67 -0
- package/dist/server/authorizeUrl.d.ts +43 -0
- package/dist/server/authorizeUrl.d.ts.map +1 -0
- package/dist/server/authorizeUrl.js +110 -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/everyApp.d.ts +38 -12
- package/dist/server/everyApp.d.ts.map +1 -1
- package/dist/server/everyApp.js +92 -28
- package/dist/server/gatewayFetch.d.ts +24 -8
- package/dist/server/gatewayFetch.d.ts.map +1 -1
- package/dist/server/gatewayFetch.js +81 -36
- package/dist/server/index.d.ts +10 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +8 -1
- package/dist/server/integrationFetch.d.ts +131 -0
- package/dist/server/integrationFetch.d.ts.map +1 -0
- package/dist/server/integrationFetch.js +526 -0
- package/dist/server/listMembers.d.ts +32 -0
- package/dist/server/listMembers.d.ts.map +1 -0
- package/dist/server/listMembers.js +74 -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/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 +231 -0
- package/package.json +30 -17
- 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,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The internal tools contract (v1) between the gateway's ToolBus and an app's
|
|
3
|
+
* `everyApp()` wrapper. Two reserved endpoints, reached only over the
|
|
4
|
+
* gateway's service binding and never public:
|
|
5
|
+
*
|
|
6
|
+
* POST /__everyapp/tools/list x-everyapp-system JWT (purpose "tools.list")
|
|
7
|
+
* POST /__everyapp/tools/call x-everyapp-identity JWT, chan "mcp" + tc claim
|
|
8
|
+
*
|
|
9
|
+
* MCP itself (protocol eras, headers, envelopes) stays in the gateway; apps
|
|
10
|
+
* only ever speak this small versioned JSON shape. Both sides import the
|
|
11
|
+
* shapes, paths and the catalog hash from here so they cannot drift.
|
|
12
|
+
*/
|
|
13
|
+
export const TOOLS_PROTOCOL_VERSION = 1;
|
|
14
|
+
export const TOOLS_PATH_PREFIX = "/__everyapp/tools";
|
|
15
|
+
export const TOOLS_LIST_PATH = `${TOOLS_PATH_PREFIX}/list`;
|
|
16
|
+
export const TOOLS_CALL_PATH = `${TOOLS_PATH_PREFIX}/call`;
|
|
17
|
+
export const TOOL_RISKS = ["read", "write", "destructive"];
|
|
18
|
+
/** Scopes the gateway mints on `chan: "mcp"` identities, one per risk. */
|
|
19
|
+
export const MCP_READ_SCOPE = "mcp:read";
|
|
20
|
+
export const MCP_WRITE_SCOPE = "mcp:write";
|
|
21
|
+
/** Never minted in v1: destructive tools are hidden until approvals exist. */
|
|
22
|
+
export const MCP_DESTRUCTIVE_SCOPE = "mcp:destructive";
|
|
23
|
+
/** Local tool names: lowercase snake_case, at most 48 characters. */
|
|
24
|
+
export const TOOL_NAME_PATTERN = /^[a-z][a-z0-9_]{0,47}$/;
|
|
25
|
+
export function isToolRisk(value) {
|
|
26
|
+
return (typeof value === "string" &&
|
|
27
|
+
TOOL_RISKS.includes(value));
|
|
28
|
+
}
|
|
29
|
+
/** The exact scope a `chan: "mcp"` identity must carry to call a tool. */
|
|
30
|
+
export function requiredScopeForRisk(risk) {
|
|
31
|
+
switch (risk) {
|
|
32
|
+
case "read":
|
|
33
|
+
return MCP_READ_SCOPE;
|
|
34
|
+
case "write":
|
|
35
|
+
return MCP_WRITE_SCOPE;
|
|
36
|
+
case "destructive":
|
|
37
|
+
return MCP_DESTRUCTIVE_SCOPE;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* JSON with object keys sorted at every depth, so equal values always
|
|
42
|
+
* serialize identically. `undefined` members are dropped, as JSON.stringify
|
|
43
|
+
* does.
|
|
44
|
+
*/
|
|
45
|
+
export function canonicalJson(value) {
|
|
46
|
+
return JSON.stringify(sortKeys(value));
|
|
47
|
+
}
|
|
48
|
+
function sortKeys(value) {
|
|
49
|
+
if (Array.isArray(value))
|
|
50
|
+
return value.map(sortKeys);
|
|
51
|
+
if (!value || typeof value !== "object")
|
|
52
|
+
return value;
|
|
53
|
+
const sorted = {};
|
|
54
|
+
for (const key of Object.keys(value).sort()) {
|
|
55
|
+
const member = value[key];
|
|
56
|
+
if (member !== undefined)
|
|
57
|
+
sorted[key] = sortKeys(member);
|
|
58
|
+
}
|
|
59
|
+
return sorted;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* `sha256:<hex>` over the canonical JSON of a catalog. The SDK reports it with
|
|
63
|
+
* every list and call; the gateway stores it at sync and re-syncs when a call
|
|
64
|
+
* reports a different one.
|
|
65
|
+
*/
|
|
66
|
+
export async function catalogHash(catalog) {
|
|
67
|
+
const canonical = canonicalJson({
|
|
68
|
+
instructions: catalog.instructions ?? null,
|
|
69
|
+
tools: catalog.tools,
|
|
70
|
+
});
|
|
71
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(canonical));
|
|
72
|
+
return `sha256:${toHex(digest)}`;
|
|
73
|
+
}
|
|
74
|
+
function toHex(buffer) {
|
|
75
|
+
let out = "";
|
|
76
|
+
for (const byte of new Uint8Array(buffer)) {
|
|
77
|
+
out += byte.toString(16).padStart(2, "0");
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whom a call through the gateway is for, which decides the organization
|
|
3
|
+
* it counts against:
|
|
4
|
+
*
|
|
5
|
+
* - the inbound `Request`: its person, by the identity the gateway put on
|
|
6
|
+
* it (forwarded as is);
|
|
7
|
+
* - `{ background: true, organizationId }`: work no request started (a
|
|
8
|
+
* cron, a Workflow step, a queue). A shared app's Worker serves every
|
|
9
|
+
* organization, so it names the one the work is for, which the gateway
|
|
10
|
+
* checks is active and has a live member. An organization's own app may
|
|
11
|
+
* leave it out (the gateway knows its organization) and may only name
|
|
12
|
+
* its own.
|
|
13
|
+
*/
|
|
14
|
+
export type GatewayCallFor = Request | {
|
|
15
|
+
background: true;
|
|
16
|
+
organizationId?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* A gateway call that doesn't say whom it is for where it must: from a
|
|
20
|
+
* shared app's Worker, with neither the request nor an organization.
|
|
21
|
+
*/
|
|
22
|
+
export declare class AttributionError extends Error {
|
|
23
|
+
readonly code = "attribution_required";
|
|
24
|
+
constructor(message: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check `target` before any call is made: a shared app's Worker must pass
|
|
28
|
+
* the request or name the organization, and anything else passed must be
|
|
29
|
+
* one of the two shapes.
|
|
30
|
+
*/
|
|
31
|
+
export declare function checkAttribution(env: object, target: GatewayCallFor | undefined, what: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Put the call's attribution on its headers: the request's identity, or the
|
|
34
|
+
* background work's organization, and never one the app set itself.
|
|
35
|
+
*/
|
|
36
|
+
export declare function applyAttribution(headers: Headers, target: GatewayCallFor | undefined): void;
|
|
37
|
+
/** Whether `for` is the inbound request (rather than background work). */
|
|
38
|
+
export declare function isRequest(value: unknown): value is Request;
|
|
39
|
+
//# sourceMappingURL=attribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribution.d.ts","sourceRoot":"","sources":["../../src/server/attribution.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GACtB,OAAO,GACP;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,0BAA0B;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,IAAI,EAAE,MAAM,GACX,IAAI,CAsBN;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,cAAc,GAAG,SAAS,GACjC,IAAI,CAUN;AASD,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAO1D"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { IDENTITY_HEADER, ORG_HEADER, SHARED_ENV } from "../internal/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* A gateway call that doesn't say whom it is for where it must: from a
|
|
4
|
+
* shared app's Worker, with neither the request nor an organization.
|
|
5
|
+
*/
|
|
6
|
+
export class AttributionError extends Error {
|
|
7
|
+
code = "attribution_required";
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "AttributionError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Check `target` before any call is made: a shared app's Worker must pass
|
|
15
|
+
* the request or name the organization, and anything else passed must be
|
|
16
|
+
* one of the two shapes.
|
|
17
|
+
*/
|
|
18
|
+
export function checkAttribution(env, target, what) {
|
|
19
|
+
if (target !== undefined && !isRequest(target)) {
|
|
20
|
+
if (target === null || typeof target !== "object" || !target.background) {
|
|
21
|
+
throw new AttributionError(`${what}: \`for\` is the inbound Request or { background: true, organizationId }.`);
|
|
22
|
+
}
|
|
23
|
+
if (target.organizationId !== undefined &&
|
|
24
|
+
!nonEmpty(target.organizationId)) {
|
|
25
|
+
throw new AttributionError(`${what}: { background: true, organizationId } needs a non-empty organization id.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (!isSharedWorker(env))
|
|
29
|
+
return;
|
|
30
|
+
if (target === undefined || (!isRequest(target) && !target.organizationId)) {
|
|
31
|
+
throw new AttributionError(`${what} in a shared app's Worker serves every organization, so it must say whom the call is for: for: request, or for: { background: true, organizationId } for work no request started.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Put the call's attribution on its headers: the request's identity, or the
|
|
36
|
+
* background work's organization, and never one the app set itself.
|
|
37
|
+
*/
|
|
38
|
+
export function applyAttribution(headers, target) {
|
|
39
|
+
headers.delete(IDENTITY_HEADER);
|
|
40
|
+
headers.delete(ORG_HEADER);
|
|
41
|
+
if (target === undefined)
|
|
42
|
+
return;
|
|
43
|
+
if (isRequest(target)) {
|
|
44
|
+
const identity = target.headers.get(IDENTITY_HEADER);
|
|
45
|
+
if (identity)
|
|
46
|
+
headers.set(IDENTITY_HEADER, identity);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (target.organizationId)
|
|
50
|
+
headers.set(ORG_HEADER, target.organizationId);
|
|
51
|
+
}
|
|
52
|
+
function isSharedWorker(env) {
|
|
53
|
+
const value = env[SHARED_ENV];
|
|
54
|
+
return value === "1" || value === "true" || value === true;
|
|
55
|
+
}
|
|
56
|
+
// Duck-typed: a Request from another realm (a test runner, a polyfill) is
|
|
57
|
+
// still the request.
|
|
58
|
+
/** Whether `for` is the inbound request (rather than background work). */
|
|
59
|
+
export function isRequest(value) {
|
|
60
|
+
return (typeof value === "object" &&
|
|
61
|
+
value !== null &&
|
|
62
|
+
"headers" in value &&
|
|
63
|
+
typeof value.headers?.get === "function");
|
|
64
|
+
}
|
|
65
|
+
function nonEmpty(value) {
|
|
66
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
67
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type OAuthClientCapabilityId } from "../internal/index.js";
|
|
2
|
+
import type { OAuthClientIntegrationStatus } from "./integrationFetch.js";
|
|
3
|
+
export interface AuthorizeUrlOptions {
|
|
4
|
+
/** The OAuth client, as listed in the manifest's `capabilities`. */
|
|
5
|
+
provider: OAuthClientCapabilityId;
|
|
6
|
+
/** What `integrationStatus()` answered for it, ready and with its `clientId`. */
|
|
7
|
+
status: OAuthClientIntegrationStatus;
|
|
8
|
+
/** One of the redirect URIs the operator registered on the client. */
|
|
9
|
+
redirectUri: string;
|
|
10
|
+
/** The app's own anti-forgery value, checked when the person comes back. */
|
|
11
|
+
state: string;
|
|
12
|
+
/** PKCE: the S256 challenge of the verifier the app keeps for the exchange. */
|
|
13
|
+
codeChallenge?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The provider's extras (`prompt`, `login_hint`, Google's `hd`). Never
|
|
16
|
+
* one of the parameters this helper sets (PKCE's and the provider's own
|
|
17
|
+
* included), nor Google's `include_granted_scopes`.
|
|
18
|
+
*/
|
|
19
|
+
params?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The provider's authorize URL to send a person to, for a client with
|
|
23
|
+
* scope sets (`google-workspace`, `microsoft-365`, `slack`), built from the
|
|
24
|
+
* capability's status: the registry's authorize endpoint (or the instance
|
|
25
|
+
* the status names), `client_id`, `response_type=code`, `redirect_uri`,
|
|
26
|
+
* `state`, and the scopes the status allows this app, which are exactly
|
|
27
|
+
* what the gateway will let the token carry. Each provider's own needs
|
|
28
|
+
* are added: Google's `access_type=offline` (a refresh token), Microsoft's
|
|
29
|
+
* `response_mode=query`, Slack's comma-joined `scope` and its `user_scope`
|
|
30
|
+
* (the status's `userScopes`, when the app's sets include a user set). With
|
|
31
|
+
* `codeChallenge`, PKCE as S256. The app keeps its `state` and verifier
|
|
32
|
+
* for the callback.
|
|
33
|
+
*
|
|
34
|
+
* A client without scope sets (LinkedIn, Mastodon, ...) is refused: the
|
|
35
|
+
* registry's checklist for one isn't what the gateway holds a token to,
|
|
36
|
+
* so an app builds that URL itself from the status's `clientId`.
|
|
37
|
+
*
|
|
38
|
+
* Throws a `TypeError` naming the fix when the client has no scope sets,
|
|
39
|
+
* when the status isn't ready or has no `clientId`, when the status lacks
|
|
40
|
+
* `scopes`, or when `params` names a parameter the helper sets.
|
|
41
|
+
*/
|
|
42
|
+
export declare function authorizeUrl({ provider, status, redirectUri, state, codeChallenge, params, }: AuthorizeUrlOptions): URL;
|
|
43
|
+
//# sourceMappingURL=authorizeUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorizeUrl.d.ts","sourceRoot":"","sources":["../../src/server/authorizeUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,QAAQ,EAAE,uBAAuB,CAAC;IAClC,iFAAiF;IACjF,MAAM,EAAE,4BAA4B,CAAC;IACrC,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAgCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,MAAM,EACN,WAAW,EACX,KAAK,EACL,aAAa,EACb,MAAM,GACP,EAAE,mBAAmB,GAAG,GAAG,CA2D3B"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { CAPABILITIES, ConfigurationError, } from "../internal/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parameters the helper owns: the status decides the scopes, the caller's
|
|
4
|
+
* other arguments decide the rest (PKCE from `codeChallenge`, always as
|
|
5
|
+
* S256), each provider's own are fixed (Google's `access_type=offline` is
|
|
6
|
+
* what gets a refresh token, Microsoft's `response_mode=query` is what
|
|
7
|
+
* the callback reads), and Google's `include_granted_scopes` would widen
|
|
8
|
+
* the token to every scope the person ever granted this client, which the
|
|
9
|
+
* gateway refuses (`integration_scope_exceeded`).
|
|
10
|
+
*/
|
|
11
|
+
const RESERVED_PARAMS = [
|
|
12
|
+
"scope",
|
|
13
|
+
"user_scope",
|
|
14
|
+
"client_id",
|
|
15
|
+
"redirect_uri",
|
|
16
|
+
"state",
|
|
17
|
+
"response_type",
|
|
18
|
+
"code_challenge",
|
|
19
|
+
"code_challenge_method",
|
|
20
|
+
"access_type",
|
|
21
|
+
"response_mode",
|
|
22
|
+
"include_granted_scopes",
|
|
23
|
+
];
|
|
24
|
+
/** The OAuth clients with scope sets: the ones this helper builds for. */
|
|
25
|
+
function scopedClientIds() {
|
|
26
|
+
return Object.entries(CAPABILITIES)
|
|
27
|
+
.filter(([, found]) => found.mode === "oauth_client" && found.scopePolicy)
|
|
28
|
+
.map(([id]) => id);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The provider's authorize URL to send a person to, for a client with
|
|
32
|
+
* scope sets (`google-workspace`, `microsoft-365`, `slack`), built from the
|
|
33
|
+
* capability's status: the registry's authorize endpoint (or the instance
|
|
34
|
+
* the status names), `client_id`, `response_type=code`, `redirect_uri`,
|
|
35
|
+
* `state`, and the scopes the status allows this app, which are exactly
|
|
36
|
+
* what the gateway will let the token carry. Each provider's own needs
|
|
37
|
+
* are added: Google's `access_type=offline` (a refresh token), Microsoft's
|
|
38
|
+
* `response_mode=query`, Slack's comma-joined `scope` and its `user_scope`
|
|
39
|
+
* (the status's `userScopes`, when the app's sets include a user set). With
|
|
40
|
+
* `codeChallenge`, PKCE as S256. The app keeps its `state` and verifier
|
|
41
|
+
* for the callback.
|
|
42
|
+
*
|
|
43
|
+
* A client without scope sets (LinkedIn, Mastodon, ...) is refused: the
|
|
44
|
+
* registry's checklist for one isn't what the gateway holds a token to,
|
|
45
|
+
* so an app builds that URL itself from the status's `clientId`.
|
|
46
|
+
*
|
|
47
|
+
* Throws a `TypeError` naming the fix when the client has no scope sets,
|
|
48
|
+
* when the status isn't ready or has no `clientId`, when the status lacks
|
|
49
|
+
* `scopes`, or when `params` names a parameter the helper sets.
|
|
50
|
+
*/
|
|
51
|
+
export function authorizeUrl({ provider, status, redirectUri, state, codeChallenge, params, }) {
|
|
52
|
+
const capability = oauthClientCapability(provider);
|
|
53
|
+
if (!capability.scopePolicy) {
|
|
54
|
+
throw new TypeError(`authorizeUrl() builds URLs for clients with scope sets (${scopedClientIds().join(", ")}); build ${capability.label}'s authorize URL yourself from the status's clientId.`);
|
|
55
|
+
}
|
|
56
|
+
if (!status.ready || !status.clientId) {
|
|
57
|
+
throw new TypeError(`authorizeUrl(${JSON.stringify(provider)}) needs a ready status with a clientId, and integrationStatus() answered ready: ${String(status.ready)}. Show ${capability.label} as not available instead: its operator sets the client up on the gateway, and an app lists the scope sets it uses in everyapp.config.ts.`);
|
|
58
|
+
}
|
|
59
|
+
if (!status.scopes) {
|
|
60
|
+
throw new TypeError(`authorizeUrl(${JSON.stringify(provider)}) takes ${capability.label}'s scopes from integrationStatus().scopes, which this status lacks: pass the status as the gateway (or everyapp dev) answered it.`);
|
|
61
|
+
}
|
|
62
|
+
for (const name of Object.keys(params ?? {})) {
|
|
63
|
+
if (!RESERVED_PARAMS.includes(name))
|
|
64
|
+
continue;
|
|
65
|
+
throw new TypeError(name === "include_granted_scopes"
|
|
66
|
+
? `authorizeUrl(${JSON.stringify(provider)}): include_granted_scopes would widen the token to every scope the person granted this client, which the gateway refuses (integration_scope_exceeded); leave it out of params.`
|
|
67
|
+
: `authorizeUrl(${JSON.stringify(provider)}) sets ${name} itself; leave it out of params.`);
|
|
68
|
+
}
|
|
69
|
+
const base = status.origin ?? capability.defaultOrigin;
|
|
70
|
+
if (!/^https:/.test(capability.authorize.url) && !base) {
|
|
71
|
+
throw new TypeError(`authorizeUrl(${JSON.stringify(provider)}) needs the instance ${capability.label} is on: the status carries it as origin once ${capability.hostSetting} is set.`);
|
|
72
|
+
}
|
|
73
|
+
const url = new URL(capability.authorize.url, base);
|
|
74
|
+
// The status speaks for the gateway: its scopes are the token's ceiling.
|
|
75
|
+
const scopes = status.scopes;
|
|
76
|
+
const slack = url.host === "slack.com";
|
|
77
|
+
url.searchParams.set("client_id", status.clientId);
|
|
78
|
+
url.searchParams.set("response_type", "code");
|
|
79
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
80
|
+
url.searchParams.set("state", state);
|
|
81
|
+
url.searchParams.set("scope", scopes.join(slack ? "," : " "));
|
|
82
|
+
if (status.userScopes && status.userScopes.length > 0) {
|
|
83
|
+
url.searchParams.set("user_scope", status.userScopes.join(","));
|
|
84
|
+
}
|
|
85
|
+
if (codeChallenge) {
|
|
86
|
+
url.searchParams.set("code_challenge", codeChallenge);
|
|
87
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
88
|
+
}
|
|
89
|
+
if (url.host === "accounts.google.com") {
|
|
90
|
+
// Without it Google issues no refresh token.
|
|
91
|
+
url.searchParams.set("access_type", "offline");
|
|
92
|
+
}
|
|
93
|
+
else if (url.host === "login.microsoftonline.com") {
|
|
94
|
+
url.searchParams.set("response_mode", "query");
|
|
95
|
+
}
|
|
96
|
+
for (const [name, value] of Object.entries(params ?? {})) {
|
|
97
|
+
url.searchParams.set(name, value);
|
|
98
|
+
}
|
|
99
|
+
return url;
|
|
100
|
+
}
|
|
101
|
+
/** The OAuth client `provider` names, from plain JavaScript or a stale type too. */
|
|
102
|
+
function oauthClientCapability(provider) {
|
|
103
|
+
const found = Object.hasOwn(CAPABILITIES, provider)
|
|
104
|
+
? CAPABILITIES[provider]
|
|
105
|
+
: undefined;
|
|
106
|
+
if (found?.mode !== "oauth_client") {
|
|
107
|
+
throw new ConfigurationError(`${JSON.stringify(String(provider))} isn't an OAuth client the gateway holds.`);
|
|
108
|
+
}
|
|
109
|
+
return found;
|
|
110
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `emit()`: an app's own event onto the gateway's event bus
|
|
3
|
+
* (docs/design/2026-10-events-out.md, section 7). It is shaped like
|
|
4
|
+
* `sendEmail()` on purpose: the same `{ env, for }` attribution, the same
|
|
5
|
+
* route over the EVERY_APP_GATEWAY binding, the same refusals thrown as
|
|
6
|
+
* `GatewayRefusalError`, and the same local-dev twin that checks what the
|
|
7
|
+
* gateway would check and prints instead of sending. The name and data
|
|
8
|
+
* rules live in `internal/events.ts`, which the gateway reads too, so the
|
|
9
|
+
* two can't drift.
|
|
10
|
+
*/
|
|
11
|
+
import { type EmitEventResult } from "../internal/index.js";
|
|
12
|
+
import { type GatewayCallFor } from "./attribution.js";
|
|
13
|
+
export interface EmitOptions {
|
|
14
|
+
/** The Worker env: the EVERY_APP_GATEWAY binding when deployed; EVERYAPP_DEV in local dev. */
|
|
15
|
+
env: object;
|
|
16
|
+
/**
|
|
17
|
+
* Whom the event is about: the inbound request (its user becomes the
|
|
18
|
+
* event's actor), or `{ background: true, organizationId }` for work no
|
|
19
|
+
* person started (a cron, a queue, a provider's webhook). An
|
|
20
|
+
* organization's own app may omit it for background work; a shared app's
|
|
21
|
+
* Worker must pass one or the other ({@link AttributionError}).
|
|
22
|
+
*/
|
|
23
|
+
for?: GatewayCallFor;
|
|
24
|
+
/**
|
|
25
|
+
* The app's own name for what happened: lowercase letters, digits and
|
|
26
|
+
* underscores in dotted segments (`invoice.paid`, `todo.completed`), at
|
|
27
|
+
* most 64 characters. The gateway delivers it as `app.<app id>.<event>`.
|
|
28
|
+
*/
|
|
29
|
+
event: string;
|
|
30
|
+
/**
|
|
31
|
+
* What a subscriber needs to act on it: a JSON object, at most 8 KiB
|
|
32
|
+
* serialized, nested at most 8 levels. Ids, names, amounts and states;
|
|
33
|
+
* never a credential. A key named like one at any depth (`token`,
|
|
34
|
+
* `secret`, `password`, `apiKey`, `session`, `cookie`, ...) is refused.
|
|
35
|
+
*/
|
|
36
|
+
data: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Put an event on the gateway's event bus, for the organization's webhook
|
|
40
|
+
* and email subscribers. The gateway names it `app.<app id>.<event>`, so an
|
|
41
|
+
* app can never emit one of the gateway's own types (`member.joined`);
|
|
42
|
+
* owners and admins choose `app.<app id>.*` (or one name) in Manage
|
|
43
|
+
* workspace, Events, or with `everyapp events add`. Nothing is declared in
|
|
44
|
+
* the manifest. Delivery happens after the call returns: a subscriber that
|
|
45
|
+
* is down doesn't slow or fail the app.
|
|
46
|
+
*
|
|
47
|
+
* `data` goes, as written, to every URL a subscriber chose (Slack, Zapier,
|
|
48
|
+
* an agent): put in it what a person or a workflow reads, never a
|
|
49
|
+
* credential, a session or a person's private content they didn't expect
|
|
50
|
+
* to leave the app. The gateway refuses a key named like a credential.
|
|
51
|
+
*
|
|
52
|
+
* Throws {@link GatewayRefusalError} when the gateway won't take it
|
|
53
|
+
* (`event_name_invalid`, `event_data_invalid`, `event_data_refused`,
|
|
54
|
+
* `event_data_too_large`, `event_rate_limited` past 600 an hour, ...), with
|
|
55
|
+
* the code and a message to show. An emit that must never fail the work
|
|
56
|
+
* around it goes under `ctx.waitUntil()` or a `.catch()`.
|
|
57
|
+
*
|
|
58
|
+
* In local dev (`everyapp dev`, no binding) the event is checked the way
|
|
59
|
+
* the gateway checks it, printed, and answered `{ id: "dev-…", type }`;
|
|
60
|
+
* nothing is delivered.
|
|
61
|
+
*/
|
|
62
|
+
export declare function emit({ env, for: target, event, data, }: EmitOptions): Promise<EmitEventResult>;
|
|
63
|
+
//# sourceMappingURL=emit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/server/emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EASL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,WAAW,WAAW;IAC1B,8FAA8F;IAC9F,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,IAAI,CAAC,EACzB,GAAG,EACH,GAAG,EAAE,MAAM,EACX,KAAK,EACL,IAAI,GACL,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAoBxC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `emit()`: an app's own event onto the gateway's event bus
|
|
3
|
+
* (docs/design/2026-10-events-out.md, section 7). It is shaped like
|
|
4
|
+
* `sendEmail()` on purpose: the same `{ env, for }` attribution, the same
|
|
5
|
+
* route over the EVERY_APP_GATEWAY binding, the same refusals thrown as
|
|
6
|
+
* `GatewayRefusalError`, and the same local-dev twin that checks what the
|
|
7
|
+
* gateway would check and prints instead of sending. The name and data
|
|
8
|
+
* rules live in `internal/events.ts`, which the gateway reads too, so the
|
|
9
|
+
* two can't drift.
|
|
10
|
+
*/
|
|
11
|
+
import { APP_EVENT_DATA_MAX_BYTES, APP_ID_ENV, ConfigurationError, EVENTS_EMIT_PATH, appEventNameProblem, appEventType, checkEventData, } from "../internal/index.js";
|
|
12
|
+
import { applyAttribution, checkAttribution, } from "./attribution.js";
|
|
13
|
+
import { BINDING_ORIGIN } from "./gatewayFetch.js";
|
|
14
|
+
import { GatewayRefusalError, gatewayRefusal } from "./integrationFetch.js";
|
|
15
|
+
/**
|
|
16
|
+
* Put an event on the gateway's event bus, for the organization's webhook
|
|
17
|
+
* and email subscribers. The gateway names it `app.<app id>.<event>`, so an
|
|
18
|
+
* app can never emit one of the gateway's own types (`member.joined`);
|
|
19
|
+
* owners and admins choose `app.<app id>.*` (or one name) in Manage
|
|
20
|
+
* workspace, Events, or with `everyapp events add`. Nothing is declared in
|
|
21
|
+
* the manifest. Delivery happens after the call returns: a subscriber that
|
|
22
|
+
* is down doesn't slow or fail the app.
|
|
23
|
+
*
|
|
24
|
+
* `data` goes, as written, to every URL a subscriber chose (Slack, Zapier,
|
|
25
|
+
* an agent): put in it what a person or a workflow reads, never a
|
|
26
|
+
* credential, a session or a person's private content they didn't expect
|
|
27
|
+
* to leave the app. The gateway refuses a key named like a credential.
|
|
28
|
+
*
|
|
29
|
+
* Throws {@link GatewayRefusalError} when the gateway won't take it
|
|
30
|
+
* (`event_name_invalid`, `event_data_invalid`, `event_data_refused`,
|
|
31
|
+
* `event_data_too_large`, `event_rate_limited` past 600 an hour, ...), with
|
|
32
|
+
* the code and a message to show. An emit that must never fail the work
|
|
33
|
+
* around it goes under `ctx.waitUntil()` or a `.catch()`.
|
|
34
|
+
*
|
|
35
|
+
* In local dev (`everyapp dev`, no binding) the event is checked the way
|
|
36
|
+
* the gateway checks it, printed, and answered `{ id: "dev-…", type }`;
|
|
37
|
+
* nothing is delivered.
|
|
38
|
+
*/
|
|
39
|
+
export async function emit({ env, for: target, event, data, }) {
|
|
40
|
+
checkAttribution(env, target, "emit");
|
|
41
|
+
const values = env;
|
|
42
|
+
const binding = values["EVERY_APP_GATEWAY"];
|
|
43
|
+
if (binding) {
|
|
44
|
+
if (typeof binding.fetch !== "function") {
|
|
45
|
+
throw new ConfigurationError("EVERY_APP_GATEWAY is configured but is not a valid service binding.");
|
|
46
|
+
}
|
|
47
|
+
return emitThroughGateway(binding, target, { event, data });
|
|
48
|
+
}
|
|
49
|
+
if (!values["EVERYAPP_DEV"]) {
|
|
50
|
+
throw new ConfigurationError("Events are unavailable: deploy with the EVERY_APP_GATEWAY binding (everyapp deploy), or run under everyapp dev.");
|
|
51
|
+
}
|
|
52
|
+
return emitInDev(values, { event, data });
|
|
53
|
+
}
|
|
54
|
+
async function emitThroughGateway(binding, target, body) {
|
|
55
|
+
const headers = new Headers({ "content-type": "application/json" });
|
|
56
|
+
applyAttribution(headers, target);
|
|
57
|
+
const response = await binding.fetch(new Request(`${BINDING_ORIGIN}${EVENTS_EMIT_PATH}`, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers,
|
|
60
|
+
body: JSON.stringify(body),
|
|
61
|
+
}));
|
|
62
|
+
const refusal = await gatewayRefusal(response);
|
|
63
|
+
if (refusal)
|
|
64
|
+
throw new GatewayRefusalError(refusal);
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
throw new GatewayRefusalError({
|
|
67
|
+
status: response.status,
|
|
68
|
+
code: "event_emit_failed",
|
|
69
|
+
message: `The Every App gateway answered ${response.status} to the event.`,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return (await response.json());
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* What the gateway would do, with no gateway: the same name and data
|
|
76
|
+
* rules, then one line on the console. The data isn't printed: it may hold
|
|
77
|
+
* a person's content, and the line is for "it fired", not for its payload.
|
|
78
|
+
*/
|
|
79
|
+
function emitInDev(values, { event, data }) {
|
|
80
|
+
const nameProblem = appEventNameProblem(event);
|
|
81
|
+
if (nameProblem) {
|
|
82
|
+
throw new GatewayRefusalError({
|
|
83
|
+
status: 400,
|
|
84
|
+
code: "event_name_invalid",
|
|
85
|
+
message: nameProblem,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const checked = checkEventData(data, APP_EVENT_DATA_MAX_BYTES);
|
|
89
|
+
if (!checked.ok) {
|
|
90
|
+
throw new GatewayRefusalError({
|
|
91
|
+
status: checked.code === "event_data_too_large" ? 413 : 400,
|
|
92
|
+
code: checked.code,
|
|
93
|
+
message: checked.message,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const appId = values[APP_ID_ENV];
|
|
97
|
+
// The gateway prefixes the manifest id; a dev env without it still shows the shape.
|
|
98
|
+
const type = appEventType(typeof appId === "string" && appId.trim() ? appId.trim() : "app", event);
|
|
99
|
+
console.info(`[everyapp dev] event ${type} (not delivered: no Gateway)`);
|
|
100
|
+
return { id: `dev-${crypto.randomUUID()}`, type };
|
|
101
|
+
}
|
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `everyApp()` — the app-side identity boundary.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* export default everyApp(handler, manifest);
|
|
4
|
+
* export default everyApp(handler, { tools });
|
|
6
5
|
*
|
|
7
6
|
* The wrapper verifies the gateway-injected identity before app code runs,
|
|
8
7
|
* stores the result on the original Request, and then delegates to the
|
|
9
|
-
* worker-style handler.
|
|
8
|
+
* worker-style handler. The expected audience is the Worker's own name in
|
|
9
|
+
* `env.EVERYAPP_AUDIENCE`, which `everyAppWorker()` sets at deploy (the
|
|
10
|
+
* gateway stamps every token it mints for the app with it); only in
|
|
11
|
+
* development, where `everyapp dev` mints for the app id, does the app id in
|
|
12
|
+
* `env.EVERYAPP_APP_ID` stand in. The Worker never imports
|
|
13
|
+
* `everyapp.config.ts` (the Cloudflare Vite plugin hides every file
|
|
14
|
+
* `cloudflare.config.ts` imports from the Worker in dev).
|
|
15
|
+
* It also answers the gateway's internal tools contract
|
|
16
|
+
* (`/__everyapp/tools/*`) for the app's `defineTools()` catalog.
|
|
10
17
|
*/
|
|
11
18
|
import { ConfigurationError, IdentityError, type EveryAppUser, type IdentityResult } from "../internal/index.js";
|
|
19
|
+
import type { ToolSet } from "./tools.js";
|
|
12
20
|
export { ConfigurationError, IdentityError };
|
|
13
21
|
export type { EveryAppUser, IdentityResult };
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
/**
|
|
23
|
+
* The runtime's `ExecutionContext`, which `everyApp()` passes to the handler
|
|
24
|
+
* as the Worker received it, so it goes on to Hono's `app.fetch(request,
|
|
25
|
+
* env, ctx)` or React Router's request handler as is. Tests that call
|
|
26
|
+
* `fetch` themselves pass a stub cast to it.
|
|
27
|
+
*/
|
|
28
|
+
export type ExecutionContextLike = ExecutionContext;
|
|
18
29
|
export interface EveryAppManifestLike {
|
|
19
30
|
id: string;
|
|
20
31
|
[key: string]: unknown;
|
|
@@ -31,13 +42,21 @@ export interface EveryAppOptions {
|
|
|
31
42
|
* Never enable this in production.
|
|
32
43
|
*/
|
|
33
44
|
allowDevIdentities?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Agent tools from `defineTools()`. The gateway snapshots them at deploy
|
|
47
|
+
* and serves them to MCP clients; see `defineTools`.
|
|
48
|
+
*/
|
|
49
|
+
tools?: ToolSet;
|
|
34
50
|
/** Override for tests. */
|
|
35
51
|
now?: number;
|
|
36
52
|
}
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
53
|
+
/**
|
|
54
|
+
* The handler accepted by everyApp, with the verified user as a 4th argument.
|
|
55
|
+
* `TCtx` narrows the context, e.g. to `ExecutionContext<Props>`.
|
|
56
|
+
*/
|
|
57
|
+
export type EveryAppHandler<TEnv = Record<string, unknown>, TCtx extends ExecutionContextLike = ExecutionContext> = (request: Request, env: TEnv, ctx: TCtx, user: EveryAppUser | null) => Response | Promise<Response>;
|
|
58
|
+
interface EveryAppExport<TEnv, TCtx extends ExecutionContextLike> {
|
|
59
|
+
fetch(request: Request, env: TEnv, ctx: TCtx): Promise<Response>;
|
|
41
60
|
}
|
|
42
61
|
/**
|
|
43
62
|
* Return the verified Every App user for this request, or null for a declared
|
|
@@ -51,5 +70,12 @@ export declare function getEveryAppUser(request: Request, env: object): Promise<
|
|
|
51
70
|
*/
|
|
52
71
|
export declare function requireEveryAppUser(request: Request, env: object): Promise<EveryAppUser>;
|
|
53
72
|
export declare function hasScope(user: EveryAppUser, scope: string): boolean;
|
|
54
|
-
|
|
73
|
+
/** Wrap a Worker fetch handler with Every App identity verification. */
|
|
74
|
+
export declare function everyApp<TEnv = Record<string, unknown>, TCtx extends ExecutionContextLike = ExecutionContext>(handler: EveryAppHandler<TEnv, TCtx>, options?: EveryAppOptions): EveryAppExport<TEnv, TCtx>;
|
|
75
|
+
/**
|
|
76
|
+
* @deprecated Drop the manifest: the app id now comes from
|
|
77
|
+
* `env.EVERYAPP_APP_ID` and the audience from `env.EVERYAPP_AUDIENCE`.
|
|
78
|
+
* When passed, it must match the app id.
|
|
79
|
+
*/
|
|
80
|
+
export declare function everyApp<TEnv = Record<string, unknown>, TCtx extends ExecutionContextLike = ExecutionContext>(handler: EveryAppHandler<TEnv, TCtx>, manifest: EveryAppManifestLike | undefined, options?: EveryAppOptions): EveryAppExport<TEnv, TCtx>;
|
|
55
81
|
//# sourceMappingURL=everyApp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"everyApp.d.ts","sourceRoot":"","sources":["../../src/server/everyApp.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"everyApp.d.ts","sourceRoot":"","sources":["../../src/server/everyApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAGL,kBAAkB,EAElB,aAAa,EAIb,KAAK,YAAY,EACjB,KAAK,cAAc,EAEpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AAEpD,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,iGAAiG;IACjG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,CACzB,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,IAAI,SAAS,oBAAoB,GAAG,gBAAgB,IAClD,CACF,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,IAAI,EACT,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,YAAY,GAAG,IAAI,KACtB,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAElC,UAAU,cAAc,CAAC,IAAI,EAAE,IAAI,SAAS,oBAAoB;IAC9D,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAClE;AAoHD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAS9B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,YAAY,CAAC,CAevB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnE;AAUD,wEAAwE;AACxE,wBAAgB,QAAQ,CACtB,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,IAAI,SAAS,oBAAoB,GAAG,gBAAgB,EAEpD,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,EACpC,OAAO,CAAC,EAAE,eAAe,GACxB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9B;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,IAAI,SAAS,oBAAoB,GAAG,gBAAgB,EAEpD,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,EACpC,QAAQ,EAAE,oBAAoB,GAAG,SAAS,EAC1C,OAAO,CAAC,EAAE,eAAe,GACxB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC"}
|