@every-app/sdk 0.2.0 → 0.3.0-rc.2

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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +608 -2
  3. package/dist/cloudflare/index.d.ts +22 -0
  4. package/dist/cloudflare/index.d.ts.map +1 -0
  5. package/dist/cloudflare/index.js +21 -0
  6. package/dist/cloudflare/sentinel.d.ts +69 -0
  7. package/dist/cloudflare/sentinel.d.ts.map +1 -0
  8. package/dist/cloudflare/sentinel.js +50 -0
  9. package/dist/cloudflare/worker.d.ts +592 -0
  10. package/dist/cloudflare/worker.d.ts.map +1 -0
  11. package/dist/cloudflare/worker.js +817 -0
  12. package/dist/dev/index.d.ts +8 -0
  13. package/dist/dev/index.d.ts.map +1 -0
  14. package/dist/dev/index.js +7 -0
  15. package/dist/dev/keypair.d.ts +24 -0
  16. package/dist/dev/keypair.d.ts.map +1 -0
  17. package/dist/dev/keypair.js +60 -0
  18. package/dist/internal/aiProviders.d.ts +67 -0
  19. package/dist/internal/aiProviders.d.ts.map +1 -0
  20. package/dist/internal/aiProviders.js +220 -0
  21. package/dist/internal/appSettings.d.ts +237 -0
  22. package/dist/internal/appSettings.d.ts.map +1 -0
  23. package/dist/internal/appSettings.js +374 -0
  24. package/dist/internal/capabilities.d.ts +3249 -0
  25. package/dist/internal/capabilities.d.ts.map +1 -0
  26. package/dist/internal/capabilities.js +1532 -0
  27. package/dist/internal/catalog/commerce.d.ts +394 -0
  28. package/dist/internal/catalog/commerce.d.ts.map +1 -0
  29. package/dist/internal/catalog/commerce.js +477 -0
  30. package/dist/internal/catalog/comms.d.ts +338 -0
  31. package/dist/internal/catalog/comms.d.ts.map +1 -0
  32. package/dist/internal/catalog/comms.js +477 -0
  33. package/dist/internal/catalog/index.d.ts +1899 -0
  34. package/dist/internal/catalog/index.d.ts.map +1 -0
  35. package/dist/internal/catalog/index.js +19 -0
  36. package/dist/internal/catalog/inference.d.ts +356 -0
  37. package/dist/internal/catalog/inference.d.ts.map +1 -0
  38. package/dist/internal/catalog/inference.js +425 -0
  39. package/dist/internal/catalog/infra.d.ts +423 -0
  40. package/dist/internal/catalog/infra.d.ts.map +1 -0
  41. package/dist/internal/catalog/infra.js +543 -0
  42. package/dist/internal/catalog/search.d.ts +400 -0
  43. package/dist/internal/catalog/search.d.ts.map +1 -0
  44. package/dist/internal/catalog/search.js +463 -0
  45. package/dist/internal/devProviders.d.ts +49 -0
  46. package/dist/internal/devProviders.d.ts.map +1 -0
  47. package/dist/internal/devProviders.js +62 -0
  48. package/dist/internal/email.d.ts +280 -0
  49. package/dist/internal/email.d.ts.map +1 -0
  50. package/dist/internal/email.js +613 -0
  51. package/dist/internal/events.d.ts +182 -0
  52. package/dist/internal/events.d.ts.map +1 -0
  53. package/dist/internal/events.js +326 -0
  54. package/dist/internal/gatewaySettings.d.ts +83 -0
  55. package/dist/internal/gatewaySettings.d.ts.map +1 -0
  56. package/dist/internal/gatewaySettings.js +217 -0
  57. package/dist/internal/identity.d.ts +18 -3
  58. package/dist/internal/identity.d.ts.map +1 -1
  59. package/dist/internal/identity.js +53 -14
  60. package/dist/internal/index.d.ts +18 -1
  61. package/dist/internal/index.d.ts.map +1 -1
  62. package/dist/internal/index.js +18 -1
  63. package/dist/internal/members.d.ts +35 -0
  64. package/dist/internal/members.d.ts.map +1 -0
  65. package/dist/internal/members.js +7 -0
  66. package/dist/internal/oauthClient.d.ts +63 -0
  67. package/dist/internal/oauthClient.d.ts.map +1 -0
  68. package/dist/internal/oauthClient.js +194 -0
  69. package/dist/internal/oauthScopes.d.ts +117 -0
  70. package/dist/internal/oauthScopes.d.ts.map +1 -0
  71. package/dist/internal/oauthScopes.js +416 -0
  72. package/dist/internal/organizationName.d.ts +18 -0
  73. package/dist/internal/organizationName.d.ts.map +1 -0
  74. package/dist/internal/organizationName.js +24 -0
  75. package/dist/internal/protocol.d.ts +86 -2
  76. package/dist/internal/protocol.d.ts.map +1 -1
  77. package/dist/internal/protocol.js +112 -1
  78. package/dist/internal/providerApps.d.ts +75 -0
  79. package/dist/internal/providerApps.d.ts.map +1 -0
  80. package/dist/internal/providerApps.js +59 -0
  81. package/dist/internal/providerRegistry.d.ts +147 -0
  82. package/dist/internal/providerRegistry.d.ts.map +1 -0
  83. package/dist/internal/providerRegistry.js +266 -0
  84. package/dist/internal/providerSpec.d.ts +55 -0
  85. package/dist/internal/providerSpec.d.ts.map +1 -0
  86. package/dist/internal/providerSpec.js +758 -0
  87. package/dist/internal/remoteMcp.d.ts +188 -0
  88. package/dist/internal/remoteMcp.d.ts.map +1 -0
  89. package/dist/internal/remoteMcp.js +543 -0
  90. package/dist/internal/signInProviders.d.ts +104 -0
  91. package/dist/internal/signInProviders.d.ts.map +1 -0
  92. package/dist/internal/signInProviders.js +238 -0
  93. package/dist/internal/tools.d.ts +115 -0
  94. package/dist/internal/tools.d.ts.map +1 -0
  95. package/dist/internal/tools.js +80 -0
  96. package/dist/server/attribution.d.ts +39 -0
  97. package/dist/server/attribution.d.ts.map +1 -0
  98. package/dist/server/attribution.js +67 -0
  99. package/dist/server/authorizeUrl.d.ts +43 -0
  100. package/dist/server/authorizeUrl.d.ts.map +1 -0
  101. package/dist/server/authorizeUrl.js +110 -0
  102. package/dist/server/emit.d.ts +63 -0
  103. package/dist/server/emit.d.ts.map +1 -0
  104. package/dist/server/emit.js +101 -0
  105. package/dist/server/everyApp.d.ts +38 -12
  106. package/dist/server/everyApp.d.ts.map +1 -1
  107. package/dist/server/everyApp.js +92 -28
  108. package/dist/server/gatewayFetch.d.ts +24 -8
  109. package/dist/server/gatewayFetch.d.ts.map +1 -1
  110. package/dist/server/gatewayFetch.js +81 -36
  111. package/dist/server/index.d.ts +10 -1
  112. package/dist/server/index.d.ts.map +1 -1
  113. package/dist/server/index.js +8 -1
  114. package/dist/server/integrationFetch.d.ts +131 -0
  115. package/dist/server/integrationFetch.d.ts.map +1 -0
  116. package/dist/server/integrationFetch.js +526 -0
  117. package/dist/server/listMembers.d.ts +32 -0
  118. package/dist/server/listMembers.d.ts.map +1 -0
  119. package/dist/server/listMembers.js +74 -0
  120. package/dist/server/nodeServer.d.ts +48 -0
  121. package/dist/server/nodeServer.d.ts.map +1 -0
  122. package/dist/server/nodeServer.js +45 -0
  123. package/dist/server/sendEmail.d.ts +39 -0
  124. package/dist/server/sendEmail.d.ts.map +1 -0
  125. package/dist/server/sendEmail.js +114 -0
  126. package/dist/server/tools.d.ts +184 -0
  127. package/dist/server/tools.d.ts.map +1 -0
  128. package/dist/server/tools.js +347 -0
  129. package/dist/server/toolsEndpoint.d.ts +32 -0
  130. package/dist/server/toolsEndpoint.d.ts.map +1 -0
  131. package/dist/server/toolsEndpoint.js +231 -0
  132. package/package.json +19 -6
  133. package/dist/server/mcp.d.ts +0 -66
  134. package/dist/server/mcp.d.ts.map +0 -1
  135. package/dist/server/mcp.js +0 -147
@@ -1,44 +1,58 @@
1
- import { ConfigurationError, IDENTITY_HEADER } from "../internal/index.js";
2
- const BINDING_ORIGIN = "http://every-app-gateway.internal";
3
- const OPENAI_UPSTREAM_ORIGIN = "https://api.openai.com";
4
- const OPENAI_PROXY_PREFIX = "/api/ai/openai";
1
+ import { aiProviderSettings, authorizationOf, ConfigurationError, DEV_AI_PROVIDERS, devAiProvider, joinProviderUrl, } from "../internal/index.js";
2
+ import { applyAttribution, checkAttribution, } from "./attribution.js";
3
+ export const BINDING_ORIGIN = "http://every-app-gateway.internal";
4
+ const AI_PROXY_PREFIX = "/api/ai/";
5
5
  /**
6
- * Create an OpenAI-compatible fetch function backed by the private gateway
7
- * service binding. In local dev only, the developer's own OPENAI_API_KEY is a
8
- * direct-provider fallback when no binding exists.
6
+ * Create a fetch for the gateway's AI providers (`/api/ai/<provider>/…`),
7
+ * backed by the private gateway service binding. In local dev only, the
8
+ * developer's own provider key from `.dev.vars` is a direct-provider
9
+ * fallback when no binding exists.
9
10
  */
10
- export function createGatewayFetch({ env, request: inboundRequest, }) {
11
+ export function createGatewayFetch({ env, for: target, }) {
12
+ checkAttribution(env, target, "createGatewayFetch");
11
13
  const binding = env.EVERY_APP_GATEWAY;
12
- const devProviderKey = env.EVERYAPP_DEV
13
- ? env.OPENAI_API_KEY?.trim()
14
- : undefined;
14
+ const devProviders = env.EVERYAPP_DEV ? localProviders(env) : {};
15
15
  if (binding && typeof binding.fetch !== "function") {
16
16
  throw new ConfigurationError("EVERY_APP_GATEWAY is configured but is not a valid service binding.");
17
17
  }
18
- if (!binding && !devProviderKey) {
19
- throw new ConfigurationError("AI gateway unavailable: deploy with the EVERY_APP_GATEWAY binding, or set OPENAI_API_KEY in .dev.vars for direct local development.");
18
+ if (!binding && Object.keys(devProviders).length === 0) {
19
+ throw new ConfigurationError(`AI gateway unavailable: deploy with the EVERY_APP_GATEWAY binding, or set the provider's key (${listOf(Object.values(DEV_AI_PROVIDERS).map((spec) => settingsNames(spec, "with")), "or")}) in .dev.vars for direct local development.`);
20
20
  }
21
21
  return async (input, init) => {
22
22
  const outbound = new Request(input, init);
23
23
  const headers = new Headers(outbound.headers);
24
24
  headers.delete("authorization");
25
- const identity = inboundRequest.headers.get(IDENTITY_HEADER);
26
- if (identity)
27
- headers.set(IDENTITY_HEADER, identity);
28
- else
29
- headers.delete(IDENTITY_HEADER);
30
25
  if (binding) {
31
- const target = new URL(outbound.url);
32
- const bindingRequest = streamingRequest(`${BINDING_ORIGIN}${target.pathname}${target.search}`, outbound, headers);
26
+ applyAttribution(headers, target);
27
+ const url = new URL(outbound.url);
28
+ const bindingRequest = streamingRequest(`${BINDING_ORIGIN}${url.pathname}${url.search}`, outbound, headers);
33
29
  return binding.fetch(bindingRequest);
34
30
  }
35
- const providerUrl = directOpenAiUrl(outbound.url);
36
- headers.delete(IDENTITY_HEADER);
37
- headers.set("authorization", `Bearer ${devProviderKey}`);
38
- return fetch(streamingRequest(providerUrl, outbound, headers));
31
+ const { provider, spec, path, search } = directProviderPath(outbound.url);
32
+ const dev = devProviders[provider];
33
+ if (!dev) {
34
+ throw new ConfigurationError(`Set ${settingsNames(spec)} in .dev.vars to call ${provider} in local development.`);
35
+ }
36
+ const url = joinProviderUrl(`${spec.origin}${dev.basePath}`, path, search);
37
+ if (!url)
38
+ throw new ConfigurationError("Invalid provider proxy path.");
39
+ applyAttribution(headers, undefined);
40
+ // The developer's key, put where the provider's entry says (a bearer
41
+ // token for the three today), as the gateway would put its own.
42
+ const auth = authorizationOf(spec.auth, { [spec.keyEnv]: dev.key });
43
+ for (const [name, value] of Object.entries(auth?.headers ?? {})) {
44
+ headers.set(name, value);
45
+ }
46
+ for (const [name, value] of Object.entries(auth?.query ?? {})) {
47
+ url.searchParams.set(name, value);
48
+ }
49
+ const response = await fetch(streamingRequest(url.toString(), outbound, headers));
50
+ // What the gateway does to the provider's answer, so dev behaves alike.
51
+ return spec.normalizeResponse?.(path, response) ?? response;
39
52
  };
40
53
  }
41
- function streamingRequest(url, source, headers) {
54
+ /** A copy of `source` aimed at `url`, streaming its body rather than buffering it. */
55
+ export function streamingRequest(url, source, headers) {
42
56
  const body = canIncludeBody(source.method) ? source.body : undefined;
43
57
  const init = {
44
58
  method: source.method,
@@ -49,20 +63,51 @@ function streamingRequest(url, source, headers) {
49
63
  };
50
64
  return new Request(url, init);
51
65
  }
52
- function directOpenAiUrl(input) {
66
+ /** The providers `.dev.vars` sets every setting of, with their key and base path. */
67
+ function localProviders(env) {
68
+ const providers = {};
69
+ for (const [provider, spec] of Object.entries(DEV_AI_PROVIDERS)) {
70
+ const settings = {};
71
+ for (const name of aiProviderSettings(spec)) {
72
+ const value = env[name];
73
+ if (typeof value === "string" && value.trim()) {
74
+ settings[name] = value.trim();
75
+ }
76
+ }
77
+ const key = settings[spec.keyEnv];
78
+ // A provider is reachable only with every setting it needs.
79
+ if (!key || Object.keys(settings).length < aiProviderSettings(spec).length)
80
+ continue;
81
+ providers[provider] = { key, basePath: spec.basePath?.(settings) ?? "" };
82
+ }
83
+ return providers;
84
+ }
85
+ function directProviderPath(input) {
53
86
  const incoming = new URL(input);
54
- if (incoming.pathname !== OPENAI_PROXY_PREFIX &&
55
- !incoming.pathname.startsWith(`${OPENAI_PROXY_PREFIX}/`)) {
56
- throw new ConfigurationError(`Direct local provider fallback only supports ${OPENAI_PROXY_PREFIX} paths.`);
87
+ const match = incoming.pathname.match(/^\/api\/ai\/([a-z][a-z0-9-]*)(\/.*)?$/);
88
+ const provider = match?.[1];
89
+ const spec = provider ? devAiProvider(provider) : undefined;
90
+ if (!provider || !spec) {
91
+ throw new ConfigurationError(`Direct local provider fallback only supports ${listOf(Object.keys(DEV_AI_PROVIDERS).map((name) => `${AI_PROXY_PREFIX}${name}`), "and")} paths.`);
57
92
  }
58
- const upstreamPath = incoming.pathname.slice(OPENAI_PROXY_PREFIX.length) || "/";
59
- if (!upstreamPath.startsWith("/") || upstreamPath.startsWith("//")) {
60
- throw new ConfigurationError("Invalid OpenAI proxy path.");
93
+ const path = match?.[2] || "/";
94
+ if (path.startsWith("//") || path.includes("\\")) {
95
+ throw new ConfigurationError("Invalid provider proxy path.");
61
96
  }
62
- const upstream = new URL(OPENAI_UPSTREAM_ORIGIN);
63
- upstream.pathname = upstreamPath;
64
- upstream.search = incoming.search;
65
- return upstream.toString();
97
+ return { provider, spec, path, search: incoming.search };
98
+ }
99
+ /** A provider's settings as a person reads them: `KEY`, or `KEY and SETTING`. */
100
+ function settingsNames(spec, conjunction = "and") {
101
+ const [key, ...others] = aiProviderSettings(spec);
102
+ return others.length
103
+ ? `${key} ${conjunction} ${listOf(others, "and")}`
104
+ : key;
105
+ }
106
+ /** `a`, `a and b`, `a, b and c`. */
107
+ function listOf(items, conjunction) {
108
+ return items.length < 2
109
+ ? (items[0] ?? "")
110
+ : `${items.slice(0, -1).join(", ")} ${conjunction} ${items.at(-1)}`;
66
111
  }
67
112
  function canIncludeBody(method) {
68
113
  const normalized = method.toUpperCase();
@@ -4,6 +4,15 @@
4
4
  * There is intentionally no client-side export.
5
5
  */
6
6
  export { ConfigurationError, IdentityError, everyApp, getEveryAppUser, hasScope, requireEveryAppUser, type EveryAppOptions, type EveryAppManifestLike, type EveryAppHandler, type EveryAppUser, type IdentityResult, } from "./everyApp.js";
7
+ export { AttributionError, type GatewayCallFor } from "./attribution.js";
8
+ export { authorizeUrl, type AuthorizeUrlOptions } from "./authorizeUrl.js";
7
9
  export { createGatewayFetch, type CreateGatewayFetchOptions, type GatewayFetchEnv, } from "./gatewayFetch.js";
8
- export { createMcpHandler, type CreateMcpHandlerOptions, type McpToolContext, type McpToolDefinition, type McpRequestHandler, } from "./mcp.js";
10
+ export { GatewayRefusalError, gatewayRefusal, integrationFetch, integrationStatus, type EmailIntegrationStatus, type GatewayRefusal, type IntegrationFetchOptions, type IntegrationStatus, type IntegrationStatusOf, type OAuthClientIntegrationStatus, } from "./integrationFetch.js";
11
+ export { nodeServerHandler, type NodeServer, type NodeServerHandlerOptions, } from "./nodeServer.js";
12
+ export { sendEmail, type SendEmailOptions } from "./sendEmail.js";
13
+ export { listMembers, type ListMembersOptions } from "./listMembers.js";
14
+ export { emit, type EmitOptions } from "./emit.js";
15
+ export type { ApiKeyCapabilityId, CapabilityId, OAuthClientCapabilityId, EmailAddressInput, EmailAttachmentInput, SendEmailMessage, SendEmailResult, ListMembersResult, OrganizationMember, OrganizationMemberRole, EmitEventResult, } from "../internal/index.js";
16
+ export { ToolError, defineTools, toolResult, type DefineToolsOptions, type PlainToolSchema, type StandardSchemaWithJSON, type ToolContext, type ToolDefinition, type ToolResult, type ToolSchema, type ToolSet, } from "./tools.js";
17
+ export type { ToolRisk } from "../internal/index.js";
9
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,GACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,GACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,GAClC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,iBAAiB,EACjB,KAAK,UAAU,EACf,KAAK,wBAAwB,GAC9B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,YAAY,EACV,kBAAkB,EAClB,YAAY,EACZ,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,SAAS,EACT,WAAW,EACX,UAAU,EACV,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,OAAO,GACb,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC"}
@@ -4,5 +4,12 @@
4
4
  * There is intentionally no client-side export.
5
5
  */
6
6
  export { ConfigurationError, IdentityError, everyApp, getEveryAppUser, hasScope, requireEveryAppUser, } from "./everyApp.js";
7
+ export { AttributionError } from "./attribution.js";
8
+ export { authorizeUrl } from "./authorizeUrl.js";
7
9
  export { createGatewayFetch, } from "./gatewayFetch.js";
8
- export { createMcpHandler, } from "./mcp.js";
10
+ export { GatewayRefusalError, gatewayRefusal, integrationFetch, integrationStatus, } from "./integrationFetch.js";
11
+ export { nodeServerHandler, } from "./nodeServer.js";
12
+ export { sendEmail } from "./sendEmail.js";
13
+ export { listMembers } from "./listMembers.js";
14
+ export { emit } from "./emit.js";
15
+ export { ToolError, defineTools, toolResult, } from "./tools.js";
@@ -0,0 +1,131 @@
1
+ import { type ApiKeyCapabilityId, type CapabilityId, type EmailCapabilityStatus, type OAuthClientCapabilityId } from "../internal/index.js";
2
+ import { type GatewayCallFor } from "./attribution.js";
3
+ export interface IntegrationFetchOptions {
4
+ /**
5
+ * The Worker env: the EVERY_APP_GATEWAY binding when deployed, or in local
6
+ * dev EVERYAPP_DEV and the provider's key (e.g. DATAFORSEO_API_KEY in
7
+ * `.dev.vars`).
8
+ */
9
+ env: object;
10
+ /**
11
+ * A provider the app lists in its manifest's `capabilities`: one whose
12
+ * key the gateway holds, or one whose OAuth client it holds (its token
13
+ * endpoints only). The built-in catalog's ids complete; a provider
14
+ * registered on the gateway (`everyapp provider add`) is any other id,
15
+ * reached through the binding, which checks it. The `email` capability
16
+ * is sent with `sendEmail()` instead.
17
+ */
18
+ provider: ApiKeyCapabilityId | OAuthClientCapabilityId | (string & {});
19
+ /**
20
+ * Whom the call is for: the inbound request (its user), or
21
+ * `{ background: true, organizationId }` for work no person started
22
+ * (crons, Workflows, queues). An organization's own app may omit it for
23
+ * background work, which is then the app's; a shared app's Worker must
24
+ * pass one or the other ({@link AttributionError}).
25
+ */
26
+ for?: GatewayCallFor;
27
+ }
28
+ /**
29
+ * A `fetch` for one of the gateway's capabilities. Call the provider's real
30
+ * URLs (`https://api.dataforseo.com/v3/…`); this sends them over the
31
+ * AppGateway binding, which checks the app's manifest lists the capability,
32
+ * injects the key the gateway holds and forwards the call. The app never
33
+ * sees the key. A refusal the gateway makes itself comes back as a response
34
+ * {@link gatewayRefusal} recognizes; anything else is the provider's answer.
35
+ *
36
+ * For an OAuth client (`linkedin`, `mastodon`, ...) it reaches the
37
+ * provider's token endpoints only, and the gateway puts its client on the
38
+ * request: send the code (or refresh token) without `client_id` or
39
+ * `client_secret`. Build the authorize URL with {@link authorizeUrl} from
40
+ * {@link integrationStatus}, and call the provider's API with the user's
41
+ * token directly.
42
+ *
43
+ * In local dev only, with no binding, the developer's own key or client
44
+ * from `.dev.vars` reaches the provider directly, under the gateway's names:
45
+ * a catalog provider's from the catalog, a provider registered on the
46
+ * gateway from its spec in `.everyapp/providers/<id>.json` (`everyapp
47
+ * provider show <id> --save` writes it), put on the call as the gateway's
48
+ * spec says.
49
+ */
50
+ export declare function integrationFetch({ env, provider, for: target, }: IntegrationFetchOptions): typeof fetch;
51
+ export interface IntegrationStatus {
52
+ /** The app's manifest lists the capability. */
53
+ requested: boolean;
54
+ /** The gateway holds a key for it (in local dev: `.dev.vars` sets one). */
55
+ configured: boolean;
56
+ /** Calls would go through. */
57
+ ready: boolean;
58
+ }
59
+ /**
60
+ * The email capability's status: as {@link IntegrationStatus}, plus the
61
+ * From a message without `from` gets, the `from` patterns the gateway
62
+ * accepts from this app (its installation's senders, `everyapp email set
63
+ * --sender`) and the provider mail goes out with (`cloudflare` or `resend`).
64
+ */
65
+ export type EmailIntegrationStatus = IntegrationStatus & Pick<EmailCapabilityStatus, "sender" | "senders" | "provider">;
66
+ /**
67
+ * An OAuth client's status: as {@link IntegrationStatus}, plus what the app
68
+ * needs to send people to the provider's authorize page, present only when
69
+ * the app lists the capability and the gateway holds the client.
70
+ */
71
+ export interface OAuthClientIntegrationStatus extends IntegrationStatus {
72
+ /** The client's public id, for the authorize URL (and Twitch's `Client-Id`). */
73
+ clientId?: string;
74
+ /**
75
+ * The provider's origin when the operator chose it (Mastodon's instance,
76
+ * `MASTODON_URL`): the authorize page, token endpoint and API are on it.
77
+ */
78
+ origin?: string;
79
+ /**
80
+ * For a client with scope sets (`google-workspace`, `microsoft-365`): the
81
+ * set names the app's manifest entry declares, `[]` when the entry voids
82
+ * its grant (no `scopes`, or a set this gateway doesn't offer), in which
83
+ * case `ready` is false and no token call can complete.
84
+ */
85
+ scopeSets?: readonly string[];
86
+ /**
87
+ * The provider's scope strings those sets ask for, in the provider's
88
+ * spelling and the registry's order, for the authorize URL
89
+ * ({@link authorizeUrl} puts them on). The gateway refuses a token that
90
+ * carries more.
91
+ */
92
+ scopes?: readonly string[];
93
+ /** Slack's `user_scope` strings, when the sets name any. */
94
+ userScopes?: readonly string[];
95
+ }
96
+ /** The status of a capability: email's carries its senders, an OAuth client's its id. */
97
+ export type IntegrationStatusOf<P extends string> = P extends "email" ? EmailIntegrationStatus : P extends OAuthClientCapabilityId ? OAuthClientIntegrationStatus : IntegrationStatus;
98
+ /**
99
+ * Whether the app can use an integration right now, without calling the
100
+ * provider: show "an admin needs to set up DataForSEO" (or "sending isn't
101
+ * set up") up front instead of failing mid-task. An OAuth client's status
102
+ * carries its public `clientId` for the authorize URL.
103
+ */
104
+ export declare function integrationStatus<P extends CapabilityId | (string & {})>({ env, provider, }: {
105
+ env: object;
106
+ provider: P;
107
+ }): Promise<IntegrationStatusOf<P>>;
108
+ /** A refusal the AppGateway binding made itself, not the provider. */
109
+ export interface GatewayRefusal {
110
+ status: number;
111
+ /** e.g. `capability_not_requested`, `integration_not_configured`. */
112
+ code: string;
113
+ message: string;
114
+ }
115
+ /**
116
+ * A refusal the AppGateway binding made, thrown: what `sendEmail()` throws
117
+ * when the gateway won't send (`email_sender_not_allowed`,
118
+ * `email_budget_exhausted`, ...). The thrown twin of {@link gatewayRefusal}.
119
+ */
120
+ export declare class GatewayRefusalError extends Error implements GatewayRefusal {
121
+ readonly status: number;
122
+ readonly code: string;
123
+ constructor({ status, code, message }: GatewayRefusal);
124
+ }
125
+ /**
126
+ * The gateway's own refusal in `response`, or null when the response is the
127
+ * provider's answer (which may be an error of its own). Reads the body only
128
+ * for a refusal, so call it before reading the body yourself.
129
+ */
130
+ export declare function gatewayRefusal(response: Response): Promise<GatewayRefusal | null>;
131
+ //# sourceMappingURL=integrationFetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrationFetch.d.ts","sourceRoot":"","sources":["../../src/server/integrationFetch.ts"],"names":[],"mappings":"AAAA,OAAO,EA2BL,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAE1B,KAAK,uBAAuB,EAO7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAO1B,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,QAAQ,EAAE,kBAAkB,GAAG,uBAAuB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACvE;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,cAAc,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,QAAQ,EACR,GAAG,EAAE,MAAM,GACZ,EAAE,uBAAuB,GAAG,OAAO,KAAK,CAkGxC;AA+XD,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,UAAU,EAAE,OAAO,CAAC;IACpB,8BAA8B;IAC9B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GACpD,IAAI,CAAC,qBAAqB,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,4BAA6B,SAAQ,iBAAiB;IACrE,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,4DAA4D;IAC5D,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,yFAAyF;AACzF,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,OAAO,GACjE,sBAAsB,GACtB,CAAC,SAAS,uBAAuB,GAC/B,4BAA4B,GAC5B,iBAAiB,CAAC;AAExB;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,CAAC,SAAS,YAAY,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,EACtC,EACA,GAAG,EACH,QAAQ,GACT,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,CAAC,CAAC;CACb,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAoElC;AA2FD,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAM,YAAW,cAAc;IACtE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,cAAc;CAMtD;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAWhC"}