@every-app/sdk 0.3.0-rc.4 → 0.3.0-rc.5

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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cloudflare/catalogSettings.generated.d.ts +95 -0
  3. package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
  4. package/dist/cloudflare/catalogSettings.generated.js +221 -0
  5. package/dist/cloudflare/index.d.ts +1 -0
  6. package/dist/cloudflare/index.d.ts.map +1 -1
  7. package/dist/cloudflare/index.js +3 -0
  8. package/dist/cloudflare/worker.d.ts +15 -98
  9. package/dist/cloudflare/worker.d.ts.map +1 -1
  10. package/dist/cloudflare/worker.js +26 -126
  11. package/dist/index.d.ts +6 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +5 -0
  14. package/dist/internal/gatewaySettings.d.ts +7 -1
  15. package/dist/internal/gatewaySettings.d.ts.map +1 -1
  16. package/dist/internal/gatewaySettings.js +12 -1
  17. package/dist/manifest.d.ts +205 -0
  18. package/dist/manifest.d.ts.map +1 -0
  19. package/dist/manifest.js +30 -0
  20. package/dist/server/ai.d.ts +21 -0
  21. package/dist/server/ai.d.ts.map +1 -1
  22. package/dist/server/ai.js +37 -8
  23. package/dist/server/aiBinding.d.ts +68 -0
  24. package/dist/server/aiBinding.d.ts.map +1 -0
  25. package/dist/server/aiBinding.js +294 -0
  26. package/dist/server/emailBinding.d.ts +72 -0
  27. package/dist/server/emailBinding.d.ts.map +1 -0
  28. package/dist/server/emailBinding.js +124 -0
  29. package/dist/server/env.d.ts +41 -0
  30. package/dist/server/env.d.ts.map +1 -0
  31. package/dist/server/env.js +1 -0
  32. package/dist/server/gatewayFetch.d.ts +17 -13
  33. package/dist/server/gatewayFetch.d.ts.map +1 -1
  34. package/dist/server/gatewayFetch.js +4 -7
  35. package/dist/server/gatewayUrl.d.ts +13 -0
  36. package/dist/server/gatewayUrl.d.ts.map +1 -0
  37. package/dist/server/gatewayUrl.js +34 -0
  38. package/dist/server/index.d.ts +8 -2
  39. package/dist/server/index.d.ts.map +1 -1
  40. package/dist/server/index.js +6 -1
  41. package/dist/server/integrationFetch.d.ts +12 -1
  42. package/dist/server/integrationFetch.d.ts.map +1 -1
  43. package/dist/server/integrationFetch.js +3 -23
  44. package/dist/tanstack-start/index.d.ts +9 -0
  45. package/dist/tanstack-start/index.d.ts.map +1 -0
  46. package/dist/tanstack-start/index.js +29 -0
  47. package/dist/testing/index.d.ts +93 -0
  48. package/dist/testing/index.d.ts.map +1 -0
  49. package/dist/testing/index.js +156 -0
  50. package/package.json +34 -12
@@ -3,6 +3,10 @@ import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { parseEnv } from "node:util";
5
5
  import { DEV_ISSUER, DEV_ORG_ID, DEV_PUBLIC_KEY_PEM } from "../dev/keypair.js";
6
+ // The catalog's settings, generated from ../internal/capabilities.ts, which
7
+ // this file must not import (see ./index.ts: the Vite plugin hides whatever
8
+ // cloudflare.config.ts imports from the Worker).
9
+ import { DEV_GATEWAY_KEYS } from "./catalogSettings.generated.js";
6
10
  import { sentinelDeployTarget, } from "./sentinel.js";
7
11
  /** The names of the manifest's `secrets`, whichever form each took. */
8
12
  function manifestSecretNames(manifest) {
@@ -12,131 +16,6 @@ function manifestSecretNames(manifest) {
12
16
  function manifestProviderIds(manifest) {
13
17
  return (manifest.providers ?? []).map((entry) => typeof entry === "string" ? entry : entry.id);
14
18
  }
15
- /**
16
- * The gateway secrets holding the keys of the AI providers and capabilities
17
- * an app may ask for, with the settings a provider needs besides its key
18
- * (Workers AI's account, a Basic username held as a setting, a host
19
- * setting). With no gateway in development, the SDK reaches them with the
20
- * developer's own values under the same names. A copy of the catalog's
21
- * settings (`capabilitySettings()` over every entry of
22
- * ../internal/capabilities.ts), which the Worker loads and this file must
23
- * not import (see ./index.ts: the Vite plugin hides whatever
24
- * cloudflare.config.ts imports from the Worker). worker.test.ts keeps the
25
- * copy in step: a provider added to the catalog is added here.
26
- */
27
- const DEV_GATEWAY_KEYS = {
28
- providers: {
29
- openai: ["OPENAI_API_KEY"],
30
- openrouter: ["OPENROUTER_API_KEY"],
31
- "workers-ai": ["WORKERS_AI_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID"],
32
- // Not Cloudflare AI Gateway (the proxy entry): dev goes to the
33
- // providers directly, so its settings are the Gateway's alone.
34
- // The AI providers of ../internal/catalog/inference.ts.
35
- anthropic: ["ANTHROPIC_API_KEY"],
36
- gemini: ["GEMINI_API_KEY"],
37
- mistral: ["MISTRAL_API_KEY"],
38
- groq: ["GROQ_API_KEY"],
39
- cohere: ["COHERE_API_KEY"],
40
- },
41
- capabilities: {
42
- dataforseo: ["DATAFORSEO_API_KEY"],
43
- context: ["CONTEXT_API_KEY"],
44
- // The sender, and the developer's own Email Sending account: set all
45
- // but the name and sendEmail() really sends; otherwise it prints.
46
- // Resend's key and EMAIL_PROVIDER pick the provider integrationStatus()
47
- // names, as the gateway would.
48
- // TODO(integration): the last two added by the email-providers lane
49
- // (this file is outside its ownership list).
50
- email: [
51
- "EMAIL_FROM",
52
- "EMAIL_FROM_NAME",
53
- "EMAIL_REST_API_TOKEN",
54
- "CLOUDFLARE_ACCOUNT_ID",
55
- "RESEND_API_KEY",
56
- "EMAIL_PROVIDER",
57
- ],
58
- // The organization's members: nothing to set; listMembers() answers
59
- // from the dev identity.
60
- members: [],
61
- // OAuth clients: the id, the secret, and the instance a provider with
62
- // no fixed host is on.
63
- linkedin: ["LINKEDIN_CLIENT_ID", "LINKEDIN_CLIENT_SECRET"],
64
- facebook: ["FACEBOOK_APP_ID", "FACEBOOK_APP_SECRET"],
65
- instagram: ["INSTAGRAM_APP_ID", "INSTAGRAM_APP_SECRET"],
66
- threads: ["THREADS_APP_ID", "THREADS_APP_SECRET"],
67
- youtube: ["YOUTUBE_CLIENT_ID", "YOUTUBE_CLIENT_SECRET"],
68
- tiktok: ["TIKTOK_CLIENT_ID", "TIKTOK_CLIENT_SECRET"],
69
- "tiktok-business": [
70
- "TIKTOK_BUSINESS_CLIENT_ID",
71
- "TIKTOK_BUSINESS_CLIENT_SECRET",
72
- ],
73
- reddit: ["REDDIT_CLIENT_ID", "REDDIT_CLIENT_SECRET"],
74
- pinterest: ["PINTEREST_CLIENT_ID", "PINTEREST_CLIENT_SECRET"],
75
- discord: ["DISCORD_CLIENT_ID", "DISCORD_CLIENT_SECRET"],
76
- slack: ["SLACK_CLIENT_ID", "SLACK_CLIENT_SECRET"],
77
- mastodon: ["MASTODON_CLIENT_ID", "MASTODON_CLIENT_SECRET", "MASTODON_URL"],
78
- kick: ["KICK_CLIENT_ID", "KICK_CLIENT_SECRET"],
79
- twitch: ["TWITCH_CLIENT_ID", "TWITCH_CLIENT_SECRET"],
80
- tumblr: ["TUMBLR_CLIENT_ID", "TUMBLR_CLIENT_SECRET"],
81
- dribbble: ["DRIBBBLE_CLIENT_ID", "DRIBBBLE_CLIENT_SECRET"],
82
- "google-workspace": [
83
- "GOOGLE_WORKSPACE_CLIENT_ID",
84
- "GOOGLE_WORKSPACE_CLIENT_SECRET",
85
- ],
86
- "microsoft-365": ["MICROSOFT_365_CLIENT_ID", "MICROSOFT_365_CLIENT_SECRET"],
87
- // The API-key providers of ../internal/catalog/*.ts, in catalog order:
88
- // the key, then a Basic username held as a setting, then the host
89
- // setting of a provider whose host is the operator's.
90
- stripe: ["STRIPE_API_KEY"],
91
- lemonsqueezy: ["LEMONSQUEEZY_API_KEY"],
92
- paddle: ["PADDLE_API_KEY"],
93
- shopify: ["SHOPIFY_API_TOKEN", "SHOPIFY_HOST"],
94
- plaid: ["PLAID_SECRET"],
95
- attio: ["ATTIO_API_KEY"],
96
- hubspot: ["HUBSPOT_API_TOKEN"],
97
- pipedrive: ["PIPEDRIVE_API_TOKEN"],
98
- airtable: ["AIRTABLE_API_TOKEN"],
99
- notion: ["NOTION_API_TOKEN"],
100
- postmark: ["POSTMARK_API_TOKEN"],
101
- sendgrid: ["SENDGRID_API_KEY"],
102
- twilio: ["TWILIO_API_SECRET", "TWILIO_API_KEY"],
103
- intercom: ["INTERCOM_API_TOKEN"],
104
- crisp: ["CRISP_API_KEY", "CRISP_API_IDENTIFIER"],
105
- linear: ["LINEAR_API_KEY"],
106
- github: ["GITHUB_API_TOKEN"],
107
- gitlab: ["GITLAB_API_TOKEN"],
108
- vercel: ["VERCEL_API_TOKEN"],
109
- cloudflare: ["CLOUDFLARE_PROVIDER_API_TOKEN"],
110
- posthog: ["POSTHOG_PERSONAL_API_KEY"],
111
- mixpanel: [
112
- "MIXPANEL_SERVICE_ACCOUNT_SECRET",
113
- "MIXPANEL_SERVICE_ACCOUNT_USERNAME",
114
- ],
115
- segment: ["SEGMENT_WRITE_KEY"],
116
- supabase: ["SUPABASE_SECRET_KEY", "SUPABASE_HOST"],
117
- turso: ["TURSO_API_TOKEN"],
118
- "turso-db": ["TURSO_DB_AUTH_TOKEN", "TURSO_DB_HOST"],
119
- neon: ["NEON_API_KEY"],
120
- pinecone: ["PINECONE_API_KEY", "PINECONE_HOST"],
121
- mapbox: ["MAPBOX_ACCESS_TOKEN"],
122
- openweather: ["OPENWEATHER_API_KEY"],
123
- voyage: ["VOYAGE_API_KEY"],
124
- perplexity: ["PERPLEXITY_API_KEY"],
125
- jina: ["JINA_API_KEY"],
126
- replicate: ["REPLICATE_API_TOKEN"],
127
- huggingface: ["HUGGINGFACE_API_TOKEN"],
128
- firecrawl: ["FIRECRAWL_API_KEY"],
129
- exa: ["EXA_API_KEY"],
130
- tavily: ["TAVILY_API_KEY"],
131
- serper: ["SERPER_API_KEY"],
132
- "brave-search": ["BRAVE_SEARCH_API_KEY"],
133
- apify: ["APIFY_API_TOKEN"],
134
- deepgram: ["DEEPGRAM_API_KEY"],
135
- elevenlabs: ["ELEVENLABS_API_KEY"],
136
- assemblyai: ["ASSEMBLYAI_API_KEY"],
137
- newsapi: ["NEWSAPI_API_KEY"],
138
- },
139
- };
140
19
  /**
141
20
  * Observability every Every App Worker ships with: logs (with invocation
142
21
  * logs), sampled traces and Workers Issues, with query strings redacted so
@@ -166,6 +45,19 @@ const BUILD_ENV = "EVERYAPP_BUILD";
166
45
  const RESERVED_SECRET_NAME = /^(GATEWAY_URL|CF_VERSION_METADATA|EVERYAPP_\w*|EVERY_APP_\w*|APP__\w*)$/i;
167
46
  const GATEWAY_WORKER_NAME = "every-app-gateway";
168
47
  const GATEWAY_ENTRYPOINT = "AppGateway";
48
+ /**
49
+ * Where `everyapp dev` serves its launcher, which it passes to the app's dev
50
+ * server in EVERYAPP_DEV_GATEWAY_URL; its default address otherwise. The
51
+ * deployed Worker gets the Gateway's URL from the deploy instead.
52
+ */
53
+ const DEV_GATEWAY_URL_ENV = "EVERYAPP_DEV_GATEWAY_URL";
54
+ const DEFAULT_DEV_GATEWAY_URL = "http://localhost:8787";
55
+ function devGatewayUrl() {
56
+ return {
57
+ type: "text",
58
+ value: process.env[DEV_GATEWAY_URL_ENV] || DEFAULT_DEV_GATEWAY_URL,
59
+ };
60
+ }
169
61
  /**
170
62
  * The manifest's `capabilities` as the SDK's local-dev twin of the gateway
171
63
  * reads them: with no gateway to hold an OAuth client's calls to the scope
@@ -177,7 +69,7 @@ function devCapabilities(manifest) {
177
69
  /**
178
70
  * The binding the dev Worker gets the specs of providers registered on a
179
71
  * gateway in (`DEV_PROVIDERS_ENV` in ../internal/devProviders.ts; a copy,
180
- * kept in step by a test, for the reason {@link DEV_GATEWAY_KEYS} is one).
72
+ * kept in step by a test, since this file may not import ../internal).
181
73
  */
182
74
  const DEV_PROVIDERS_ENV = "EVERYAPP_DEV_PROVIDERS";
183
75
  /**
@@ -291,6 +183,12 @@ export function everyAppWorker(options) {
291
183
  const { deploy, name } = appWorkerName(options, "everyAppWorker");
292
184
  const env = {
293
185
  EVERYAPP_APP_ID: { type: "text", value: manifest.id },
186
+ // The manifest itself, for a page that shows what the app asked for:
187
+ // the Worker can't import everyapp.config.ts (see ./index.ts).
188
+ EVERYAPP_MANIFEST: {
189
+ type: "json",
190
+ value: manifest,
191
+ },
294
192
  CF_VERSION_METADATA: { type: "version-metadata" },
295
193
  };
296
194
  if (deploy) {
@@ -317,6 +215,7 @@ export function everyAppWorker(options) {
317
215
  value: JSON.stringify([DEV_PUBLIC_KEY_PEM]),
318
216
  };
319
217
  env["EVERYAPP_IDENTITY_ISSUER"] = { type: "text", value: DEV_ISSUER };
218
+ env["GATEWAY_URL"] = devGatewayUrl();
320
219
  // The stub gateway's organization, as the deploy's secret would be, so
321
220
  // background work's withOrganization(env.EVERY_APP_ORG_ID, …) runs
322
221
  // here too. Not a pin: under the dev opt-in everyApp() enforces none,
@@ -436,6 +335,7 @@ export function everyAppAuxiliaryWorker(options) {
436
335
  else {
437
336
  env["EVERYAPP_DEV"] = { type: "text", value: "1" };
438
337
  env["EVERYAPP_DEV_CAPABILITIES"] = devCapabilities(manifest);
338
+ env["GATEWAY_URL"] = devGatewayUrl();
439
339
  env["EVERY_APP_ORG_ID"] = { type: "text", value: DEV_ORG_ID };
440
340
  addDevProviders(env, options.root);
441
341
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @every-app/sdk — what `everyapp.config.ts` imports: `defineEveryApp` and
3
+ * the manifest's types. A leaf, like the config itself (see ./manifest.ts).
4
+ */
5
+ export { defineEveryApp, type EveryAppCapabilityEntry, type EveryAppClassResource, type EveryAppManifest, type EveryAppPublicRoute, type EveryAppQueueConsumer, type EveryAppResources, type EveryAppSecretEntry, type EveryAppSettingNeed, type EveryAppWorkerLimits, } from "./manifest.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,cAAc,EACd,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @every-app/sdk — what `everyapp.config.ts` imports: `defineEveryApp` and
3
+ * the manifest's types. A leaf, like the config itself (see ./manifest.ts).
4
+ */
5
+ export { defineEveryApp, } from "./manifest.js";
@@ -52,7 +52,13 @@ export declare function isSettableGatewaySetting(name: string): boolean;
52
52
  * are typed and check their shape; anything else is a credential and
53
53
  * stays hidden.
54
54
  */
55
- export declare const PLAIN_GATEWAY_SETTINGS: readonly ["EMAIL_FROM", "EMAIL_FROM_NAME", "EMAIL_PROVIDER", "EMAIL_PASSWORD_SIGN_IN", "MASTODON_URL", "AI_PROXY_EXTRA_ROUTES", "MCP_OAUTH_ENABLED", "MCP_DCR_ENABLED", "MCP_ALLOWED_ORIGINS", "MCP_AUDIT_RETENTION_DAYS", "CLOUDFLARE_ACCESS_OIDC_ISSUER", "CLOUDFLARE_ACCESS_OIDC_CLIENT_ID", "CLOUDFLARE_ACCESS_OIDC_LABEL", "CLOUDFLARE_ACCESS_TEAM_DOMAIN", "CLOUDFLARE_ACCESS_AUD", "CLOUDFLARE_ACCESS_APPS_AUD", "CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS", "CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN", "HOSTED_OPEN_SIGNUP", "BROWSER_APP_INSTALLS", "DISPATCH_NAMESPACE", "THIRD_PARTY_DOMAIN", "EVENTS_ALLOW_PRIVATE_TARGETS"];
55
+ export declare const PLAIN_GATEWAY_SETTINGS: readonly ["EMAIL_FROM", "EMAIL_FROM_NAME", "EMAIL_PROVIDER", "EMAIL_PASSWORD_SIGN_IN", "AI_PROXY_EXTRA_ROUTES", "MCP_OAUTH_ENABLED", "MCP_DCR_ENABLED", "MCP_ALLOWED_ORIGINS", "MCP_AUDIT_RETENTION_DAYS", "CLOUDFLARE_ACCESS_OIDC_ISSUER", "CLOUDFLARE_ACCESS_OIDC_CLIENT_ID", "CLOUDFLARE_ACCESS_OIDC_LABEL", "CLOUDFLARE_ACCESS_TEAM_DOMAIN", "CLOUDFLARE_ACCESS_AUD", "CLOUDFLARE_ACCESS_APPS_AUD", "CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS", "CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN", "HOSTED_OPEN_SIGNUP", "BROWSER_APP_INSTALLS", "DISPATCH_NAMESPACE", "THIRD_PARTY_DOMAIN", "EVENTS_ALLOW_PRIVATE_TARGETS"];
56
+ /**
57
+ * The settings naming the instance an OAuth client is registered on
58
+ * (`hostSetting` in the catalog: Mastodon's `MASTODON_URL`), in catalog
59
+ * order: an origin, a plain value.
60
+ */
61
+ export declare const OAUTH_CLIENT_HOST_SETTINGS: readonly string[];
56
62
  /** Whether a settable Gateway setting's value is a plain value, not a credential. */
57
63
  export declare function isPlainGatewaySetting(name: string): boolean;
58
64
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"gatewaySettings.d.ts","sourceRoot":"","sources":["../../src/internal/gatewaySettings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAM3B;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,mLASjC,CAAC;AAMX,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElE;AAoBD,mGAAmG;AACnG,eAAO,MAAM,oBAAoB,yrBAkCvB,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAC9B,OAAO,CAAC,gBAAgB,EAAE,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC,GAC1E,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,sBAAsB,EAItE,CAAC;AAIF;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAAgC,CAAC;AAEvE,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,omBAwBmB,CAAC;AASvD,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,eAAO,MAAM,4BAA4B,6EAIa,CAAC;AAIvD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED,iGAAiG;AACjG,eAAO,MAAM,yBAAyB,yDAI5B,CAAC;AAEX,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAmBD,iDAAiD;AACjD,eAAO,MAAM,8BAA8B,sFAC0C,CAAC;AAEtF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAQ5E"}
1
+ {"version":3,"file":"gatewaySettings.d.ts","sourceRoot":"","sources":["../../src/internal/gatewaySettings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAM3B;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,mLASjC,CAAC;AAMX,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElE;AAoBD,mGAAmG;AACnG,eAAO,MAAM,oBAAoB,yrBAkCvB,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAC9B,OAAO,CAAC,gBAAgB,EAAE,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC,GAC1E,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,sBAAsB,EAItE,CAAC;AAIF;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAAgC,CAAC;AAEvE,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,olBAuBmB,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAMpD,CAAC;AAUL,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,eAAO,MAAM,4BAA4B,6EAIa,CAAC;AAIvD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED,iGAAiG;AACjG,eAAO,MAAM,yBAAyB,yDAI5B,CAAC;AAEX,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAmBD,iDAAiD;AACjD,eAAO,MAAM,8BAA8B,sFAC0C,CAAC;AAEtF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAQ5E"}
@@ -127,7 +127,6 @@ export const PLAIN_GATEWAY_SETTINGS = [
127
127
  "EMAIL_FROM_NAME",
128
128
  "EMAIL_PROVIDER",
129
129
  "EMAIL_PASSWORD_SIGN_IN",
130
- "MASTODON_URL",
131
130
  "AI_PROXY_EXTRA_ROUTES",
132
131
  "MCP_OAUTH_ENABLED",
133
132
  "MCP_DCR_ENABLED",
@@ -147,8 +146,20 @@ export const PLAIN_GATEWAY_SETTINGS = [
147
146
  "THIRD_PARTY_DOMAIN",
148
147
  "EVENTS_ALLOW_PRIVATE_TARGETS",
149
148
  ];
149
+ /**
150
+ * The settings naming the instance an OAuth client is registered on
151
+ * (`hostSetting` in the catalog: Mastodon's `MASTODON_URL`), in catalog
152
+ * order: an origin, a plain value.
153
+ */
154
+ export const OAUTH_CLIENT_HOST_SETTINGS = CAPABILITY_IDS.flatMap((id) => {
155
+ const capability = CAPABILITIES[id];
156
+ return capability.mode === "oauth_client" && capability.hostSetting
157
+ ? [capability.hostSetting]
158
+ : [];
159
+ });
150
160
  const PLAIN = new Set([
151
161
  ...PLAIN_GATEWAY_SETTINGS,
162
+ ...OAUTH_CLIENT_HOST_SETTINGS,
152
163
  // The sign-in providers' ids, issuer, label and tenant; their client
153
164
  // secrets are credentials.
154
165
  ...PLAIN_SIGN_IN_SETTINGS,
@@ -0,0 +1,205 @@
1
+ /**
2
+ * The manifest an app author writes as `everyapp.config.ts`, typed:
3
+ *
4
+ * import { defineEveryApp } from "@every-app/sdk";
5
+ *
6
+ * export default defineEveryApp({
7
+ * id: "notes",
8
+ * name: "Notes",
9
+ * resources: { d1: ["DB"] },
10
+ * });
11
+ *
12
+ * Types only, and a leaf module: `cloudflare.config.ts` imports the manifest,
13
+ * and the Cloudflare Vite plugin hides from the Worker every file the config
14
+ * imports. The rules beyond the shape (which ids exist, which names are
15
+ * reserved, which scope sets a provider has) are the CLI's: `everyapp deploy`
16
+ * and `everyapp dev` validate the manifest and say what is wrong. The
17
+ * perimeter's schema (`@every-app/perimeter/manifest`) is held to this type
18
+ * by a test there.
19
+ *
20
+ * The Worker reads the manifest back as `env.EVERYAPP_MANIFEST`, which
21
+ * `everyAppWorker()` sets and `cf workers types` types from the file.
22
+ */
23
+ /** Why a setting is needed and whether the app opens without it (the settings model). */
24
+ export interface EveryAppSettingNeed {
25
+ /** Why the app needs it, for whoever sets it. At most 200 characters. */
26
+ readonly why?: string;
27
+ /** An https page that says where the key or client comes from. */
28
+ readonly docs?: string;
29
+ /** The app opens without it; the feature using it says what is missing. */
30
+ readonly optional?: boolean;
31
+ /** The group of which one member is enough ("AI model"). */
32
+ readonly anyOf?: string;
33
+ }
34
+ /** A route reachable without a signed-in member. */
35
+ export interface EveryAppPublicRoute {
36
+ /** Absolute glob: `*` matches one segment, `**` one or more. */
37
+ readonly path: string;
38
+ /** The methods it answers; `["GET"]` when left out. */
39
+ readonly methods?: readonly string[];
40
+ }
41
+ /** A Durable Object or Workflow class: its binding, the class, and the helper Worker that defines it. */
42
+ export interface EveryAppClassResource {
43
+ readonly name: string;
44
+ readonly className: string;
45
+ readonly worker?: string;
46
+ }
47
+ /** A Cloudflare Queue's consumer settings. */
48
+ export interface EveryAppQueueConsumer {
49
+ readonly worker?: string;
50
+ readonly maxBatchSize?: number;
51
+ readonly maxBatchTimeout?: number;
52
+ readonly maxRetries?: number;
53
+ readonly maxConcurrency?: number | null;
54
+ readonly retryDelay?: number;
55
+ readonly visibilityTimeoutMs?: number;
56
+ readonly deadLetterQueue?: string;
57
+ }
58
+ /** Cloudflare's limits for one of the app's Workers. */
59
+ export interface EveryAppWorkerLimits {
60
+ /** CPU milliseconds an invocation may use, up to 300000. */
61
+ readonly cpuMs?: number;
62
+ }
63
+ /** The Cloudflare resources the app's Workers bind; the deploy creates them. */
64
+ export interface EveryAppResources {
65
+ readonly d1?: readonly string[];
66
+ readonly kv?: readonly string[];
67
+ readonly r2?: readonly string[];
68
+ readonly durableObjects?: readonly EveryAppClassResource[];
69
+ readonly workflows?: readonly EveryAppClassResource[];
70
+ readonly hyperdrive?: readonly {
71
+ readonly name: string;
72
+ readonly worker?: string;
73
+ readonly caching?: "off" | "default";
74
+ }[];
75
+ readonly queues?: readonly {
76
+ readonly name: string;
77
+ readonly consumer?: true | EveryAppQueueConsumer;
78
+ }[];
79
+ readonly ai?: readonly string[];
80
+ readonly browser?: readonly string[];
81
+ readonly images?: readonly string[];
82
+ readonly vectorize?: readonly {
83
+ readonly name: string;
84
+ readonly dimensions?: number;
85
+ readonly metric?: "cosine" | "euclidean" | "dot-product";
86
+ /** A Workers AI embedding model's shape, instead of `dimensions` and `metric`. */
87
+ readonly preset?: "@cf/baai/bge-small-en-v1.5" | "@cf/baai/bge-base-en-v1.5" | "@cf/baai/bge-large-en-v1.5" | "openai/text-embedding-ada-002" | "cohere/embed-multilingual-v2.0";
88
+ }[];
89
+ readonly aiGateway?: readonly {
90
+ readonly name: string;
91
+ readonly collectLogs?: boolean;
92
+ readonly cacheTtl?: number;
93
+ }[];
94
+ readonly sendEmail?: readonly {
95
+ readonly name: string;
96
+ readonly allowedSenderAddresses: readonly string[];
97
+ readonly destinationAddress?: string;
98
+ readonly allowedDestinationAddresses?: readonly string[];
99
+ }[];
100
+ readonly secretsStore?: readonly {
101
+ readonly name: string;
102
+ }[];
103
+ readonly analyticsEngine?: readonly {
104
+ readonly name: string;
105
+ readonly dataset?: string;
106
+ }[];
107
+ }
108
+ /** One capability the Gateway serves the app with keys it holds. */
109
+ export interface EveryAppCapabilityEntry extends EveryAppSettingNeed {
110
+ readonly access: "read" | "write";
111
+ /** An OAuth client's scope sets, by name (`["gmail.read"]`). */
112
+ readonly scopes?: readonly string[];
113
+ }
114
+ /** One of the app's own secrets, with its need. */
115
+ export interface EveryAppSecretEntry extends EveryAppSettingNeed {
116
+ readonly name: string;
117
+ /** Its guide in the everyapp skill (`"setup/main-secret.md"`). */
118
+ readonly setup?: string;
119
+ }
120
+ /** `everyapp.config.ts`. */
121
+ export interface EveryAppManifest {
122
+ /** Stable id, kebab-case: the app's hostname and Worker. */
123
+ readonly id: string;
124
+ readonly name?: string;
125
+ /** The one line the Gateway's app library shows under the name. */
126
+ readonly description?: string;
127
+ /** The path of an SVG the app serves (`"/everyapp-icon.svg"`). */
128
+ readonly icon?: string;
129
+ /** Legacy: the entry comes from `cloudflare.config.ts`. */
130
+ readonly main?: string;
131
+ /** YYYY-MM-DD. */
132
+ readonly compatibilityDate?: string;
133
+ readonly resources?: EveryAppResources;
134
+ /** Helper Workers deployed beside the app's as `<app worker>--<name>`. */
135
+ readonly workers?: readonly {
136
+ readonly name: string;
137
+ readonly binding?: string;
138
+ readonly limits?: EveryAppWorkerLimits;
139
+ }[];
140
+ readonly database?: {
141
+ readonly provider: "d1" | "postgres";
142
+ /** A cloud region such as `"aws:us-east-1"`. */
143
+ readonly region?: string;
144
+ };
145
+ readonly limits?: EveryAppWorkerLimits;
146
+ /** Routes open without a signed-in member. Default: none. */
147
+ readonly public?: readonly EveryAppPublicRoute[];
148
+ /** AI providers the Gateway calls for the app, by id or with their need. */
149
+ readonly providers?: readonly (string | (EveryAppSettingNeed & {
150
+ readonly id: string;
151
+ }))[];
152
+ /** Capabilities by id (`members`, `email`, `dataforseo`, …). */
153
+ readonly capabilities?: {
154
+ readonly [id: string]: EveryAppCapabilityEntry;
155
+ };
156
+ /** The app's own secrets, by name or with their need. */
157
+ readonly secrets?: readonly (string | EveryAppSecretEntry)[];
158
+ /** App-domain scopes personal access tokens may request, with descriptions. */
159
+ readonly scopes?: {
160
+ readonly [scope: string]: string;
161
+ };
162
+ readonly ai?: {
163
+ /** Model ids the app may request; any other is `model_not_allowed`. */
164
+ readonly models?: readonly string[];
165
+ /** OpenAI API paths beyond inference (`"/v1/files"`). */
166
+ readonly routes?: readonly string[];
167
+ /** The app takes the Gateway's default chat model (`ai()`). */
168
+ readonly chat?: boolean | EveryAppSettingNeed;
169
+ };
170
+ /** `inbound: true`: the Worker exports an `email()` handler. */
171
+ readonly email?: {
172
+ readonly inbound?: boolean;
173
+ };
174
+ /** Who can open the app once registered; `"admins"` by default. */
175
+ readonly access?: "everyone" | "admins";
176
+ readonly serverFnGuard?: boolean;
177
+ readonly serverFnBase?: string;
178
+ /** Shell command that builds the app; `cf build` by default. */
179
+ readonly build?: string;
180
+ /** Shell command `everyapp dev` starts; it must listen on PORT. */
181
+ readonly dev?: string;
182
+ /** Legacy: the port comes from PORT. */
183
+ readonly devPort?: number;
184
+ /** Dependency install command; false skips it. */
185
+ readonly install?: false | string;
186
+ readonly migrations?: {
187
+ readonly engine: "drizzle" | "d1-sql" | "prisma";
188
+ readonly dialect?: "sqlite" | "postgresql";
189
+ readonly dir?: string;
190
+ readonly config?: string;
191
+ readonly binding?: string;
192
+ };
193
+ /** Who answers `/mcp` on the app's own host, and why it needs to. */
194
+ readonly mcp?: {
195
+ readonly by: "gateway" | "app";
196
+ readonly why: string;
197
+ };
198
+ }
199
+ /**
200
+ * Type `everyapp.config.ts` without widening it: the literal binding names
201
+ * stay, so `everyAppWorker()` types `env.DB` and `env.EVERYAPP_MANIFEST`
202
+ * from them. Returns the manifest as given.
203
+ */
204
+ export declare function defineEveryApp<const M extends EveryAppManifest>(manifest: M): M;
205
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The manifest an app author writes as `everyapp.config.ts`, typed:
3
+ *
4
+ * import { defineEveryApp } from "@every-app/sdk";
5
+ *
6
+ * export default defineEveryApp({
7
+ * id: "notes",
8
+ * name: "Notes",
9
+ * resources: { d1: ["DB"] },
10
+ * });
11
+ *
12
+ * Types only, and a leaf module: `cloudflare.config.ts` imports the manifest,
13
+ * and the Cloudflare Vite plugin hides from the Worker every file the config
14
+ * imports. The rules beyond the shape (which ids exist, which names are
15
+ * reserved, which scope sets a provider has) are the CLI's: `everyapp deploy`
16
+ * and `everyapp dev` validate the manifest and say what is wrong. The
17
+ * perimeter's schema (`@every-app/perimeter/manifest`) is held to this type
18
+ * by a test there.
19
+ *
20
+ * The Worker reads the manifest back as `env.EVERYAPP_MANIFEST`, which
21
+ * `everyAppWorker()` sets and `cf workers types` types from the file.
22
+ */
23
+ /**
24
+ * Type `everyapp.config.ts` without widening it: the literal binding names
25
+ * stay, so `everyAppWorker()` types `env.DB` and `env.EVERYAPP_MANIFEST`
26
+ * from them. Returns the manifest as given.
27
+ */
28
+ export function defineEveryApp(manifest) {
29
+ return manifest;
30
+ }
@@ -41,5 +41,26 @@ export declare const AI_DEFAULT_BASE_URL = "http://every-app-gateway.internal/ap
41
41
  * `createGatewayFetch` does (no binding and no dev key) and
42
42
  * `AttributionError` where a shared app's call says nobody's.
43
43
  */
44
+ export declare function ai(options: CreateGatewayFetchOptions & {
45
+ optional: true;
46
+ }): AiClient | null;
44
47
  export declare function ai(options: CreateGatewayFetchOptions): AiClient;
48
+ /**
49
+ * A provider's root behind the Gateway, `http://every-app-gateway.internal/api/ai/<provider>`:
50
+ * join the provider's own paths onto it (`/api/v1/chat/completions` for
51
+ * OpenRouter) and send them with `createGatewayFetch()`. For an OpenAI
52
+ * client's `baseURL`, use {@link aiBaseUrl}.
53
+ */
54
+ export declare function providerBaseUrl(provider: string): string;
55
+ /**
56
+ * The OpenAI-compatible base URL of `provider` behind the Gateway, for an
57
+ * OpenAI client's `baseURL` (with `fetch: createGatewayFetch(...)`):
58
+ * `default` (the default) is {@link AI_DEFAULT_BASE_URL},
59
+ * `…/api/ai/default/v1`; a catalog provider's is its root and the prefix
60
+ * of its chat route (`…/api/ai/openrouter/api/v1`, `…/api/ai/workers-ai/v1`,
61
+ * `…/api/ai/openai/v1`). Throws `ConfigurationError` for a provider with
62
+ * no OpenAI-compatible chat route (Cohere): call {@link providerBaseUrl}
63
+ * with its own paths instead.
64
+ */
65
+ export declare function aiBaseUrl(provider?: string): string;
45
66
  //# sourceMappingURL=ai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/server/ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,gBAAgB,EAAuB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAGL,KAAK,yBAAyB,EAC/B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,QAAQ;IACvB,0FAA0F;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,gFAAgF;IAChF,KAAK,EAAE,OAAO,gBAAgB,CAAC;IAC/B,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,wDAAuD,CAAC;AAExF;;;;;GAKG;AACH,wBAAgB,EAAE,CAAC,OAAO,EAAE,yBAAyB,GAAG,QAAQ,CAQ/D"}
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/server/ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EACL,gBAAgB,EAIjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,KAAK,yBAAyB,EAC/B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,QAAQ;IACvB,0FAA0F;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,gFAAgF;IAChF,KAAK,EAAE,OAAO,gBAAgB,CAAC;IAC/B,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,wDAAuD,CAAC;AAExF;;;;;GAKG;AACH,wBAAgB,EAAE,CAChB,OAAO,EAAE,yBAAyB,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GACtD,QAAQ,GAAG,IAAI,CAAC;AACnB,wBAAgB,EAAE,CAAC,OAAO,EAAE,yBAAyB,GAAG,QAAQ,CAAC;AAejE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,QAAQ,GAAE,MAA4B,GAAG,MAAM,CAaxE"}
package/dist/server/ai.js CHANGED
@@ -19,22 +19,51 @@
19
19
  * fallback). An app that needs one provider in particular keeps listing it
20
20
  * under `providers` and calling `/api/ai/<provider>/…`.
21
21
  */
22
- import { AI_DEFAULT_MODEL, AI_DEFAULT_PROVIDER } from "../internal/index.js";
22
+ import { AI_DEFAULT_MODEL, AI_DEFAULT_PROVIDER, CATALOG, ConfigurationError, } from "../internal/index.js";
23
23
  import { BINDING_ORIGIN, createGatewayFetch, } from "./gatewayFetch.js";
24
24
  /** The base URL of the default route, as the SDK and the docs name it. */
25
25
  export const AI_DEFAULT_BASE_URL = `${BINDING_ORIGIN}/api/ai/${AI_DEFAULT_PROVIDER}/v1`;
26
- /**
27
- * The Gateway's default chat model as a client: a base URL, a fetch and
28
- * the model name to send. Throws `ConfigurationError` where
29
- * `createGatewayFetch` does (no binding and no dev key) and
30
- * `AttributionError` where a shared app's call says nobody's.
31
- */
32
26
  export function ai(options) {
27
+ const fetch = createGatewayFetch(options);
28
+ if (!fetch)
29
+ return null;
33
30
  return {
34
31
  baseURL: AI_DEFAULT_BASE_URL,
35
- fetch: createGatewayFetch(options),
32
+ fetch,
36
33
  model: AI_DEFAULT_MODEL,
37
34
  chatCompletionsUrl: `${AI_DEFAULT_BASE_URL}/chat/completions`,
38
35
  embeddingsUrl: `${AI_DEFAULT_BASE_URL}/embeddings`,
39
36
  };
40
37
  }
38
+ const CHAT_COMPLETIONS = "/chat/completions";
39
+ /**
40
+ * A provider's root behind the Gateway, `http://every-app-gateway.internal/api/ai/<provider>`:
41
+ * join the provider's own paths onto it (`/api/v1/chat/completions` for
42
+ * OpenRouter) and send them with `createGatewayFetch()`. For an OpenAI
43
+ * client's `baseURL`, use {@link aiBaseUrl}.
44
+ */
45
+ export function providerBaseUrl(provider) {
46
+ return `${BINDING_ORIGIN}/api/ai/${encodeURIComponent(provider)}`;
47
+ }
48
+ /**
49
+ * The OpenAI-compatible base URL of `provider` behind the Gateway, for an
50
+ * OpenAI client's `baseURL` (with `fetch: createGatewayFetch(...)`):
51
+ * `default` (the default) is {@link AI_DEFAULT_BASE_URL},
52
+ * `…/api/ai/default/v1`; a catalog provider's is its root and the prefix
53
+ * of its chat route (`…/api/ai/openrouter/api/v1`, `…/api/ai/workers-ai/v1`,
54
+ * `…/api/ai/openai/v1`). Throws `ConfigurationError` for a provider with
55
+ * no OpenAI-compatible chat route (Cohere): call {@link providerBaseUrl}
56
+ * with its own paths instead.
57
+ */
58
+ export function aiBaseUrl(provider = AI_DEFAULT_PROVIDER) {
59
+ if (provider === AI_DEFAULT_PROVIDER)
60
+ return AI_DEFAULT_BASE_URL;
61
+ const capability = CATALOG.get(provider);
62
+ const chat = capability?.mode === "ai" && "chat" in capability
63
+ ? capability.chat
64
+ : undefined;
65
+ if (!chat?.path.endsWith(CHAT_COMPLETIONS)) {
66
+ throw new ConfigurationError(`${provider} has no OpenAI-compatible chat route in the catalog: join its own paths onto providerBaseUrl("${provider}") instead.`);
67
+ }
68
+ return `${providerBaseUrl(provider)}${chat.path.slice(0, -CHAT_COMPLETIONS.length)}`;
69
+ }