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

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 (98) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cloudflare/catalogSettings.generated.d.ts +80 -0
  3. package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
  4. package/dist/cloudflare/catalogSettings.generated.js +172 -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 +29 -98
  9. package/dist/cloudflare/worker.d.ts.map +1 -1
  10. package/dist/cloudflare/worker.js +45 -132
  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/aiDefault.d.ts +70 -7
  15. package/dist/internal/aiDefault.d.ts.map +1 -1
  16. package/dist/internal/aiDefault.js +145 -15
  17. package/dist/internal/aiProviders.d.ts +3 -1
  18. package/dist/internal/aiProviders.d.ts.map +1 -1
  19. package/dist/internal/aiProviders.js +12 -3
  20. package/dist/internal/appSettings.d.ts +65 -5
  21. package/dist/internal/appSettings.d.ts.map +1 -1
  22. package/dist/internal/appSettings.js +141 -23
  23. package/dist/internal/capabilities.d.ts +52 -433
  24. package/dist/internal/capabilities.d.ts.map +1 -1
  25. package/dist/internal/capabilities.js +25 -558
  26. package/dist/internal/catalog/index.d.ts +6 -6
  27. package/dist/internal/catalog/inference.d.ts +6 -6
  28. package/dist/internal/catalog/inference.d.ts.map +1 -1
  29. package/dist/internal/catalog/inference.js +9 -6
  30. package/dist/internal/events.d.ts.map +1 -1
  31. package/dist/internal/events.js +1 -0
  32. package/dist/internal/gatewaySettings.d.ts +1 -1
  33. package/dist/internal/gatewaySettings.d.ts.map +1 -1
  34. package/dist/internal/gatewaySettings.js +1 -3
  35. package/dist/internal/identity.d.ts +12 -1
  36. package/dist/internal/identity.d.ts.map +1 -1
  37. package/dist/internal/identity.js +11 -1
  38. package/dist/internal/oauthClient.d.ts +10 -12
  39. package/dist/internal/oauthClient.d.ts.map +1 -1
  40. package/dist/internal/oauthClient.js +20 -81
  41. package/dist/internal/oauthPresets.d.ts +7 -3
  42. package/dist/internal/oauthPresets.d.ts.map +1 -1
  43. package/dist/internal/oauthPresets.js +533 -3
  44. package/dist/internal/oauthSpec.d.ts +44 -1
  45. package/dist/internal/oauthSpec.d.ts.map +1 -1
  46. package/dist/internal/oauthSpec.js +147 -34
  47. package/dist/internal/protocol.d.ts +14 -0
  48. package/dist/internal/protocol.d.ts.map +1 -1
  49. package/dist/internal/protocol.js +7 -0
  50. package/dist/internal/providerRegistry.d.ts +61 -1
  51. package/dist/internal/providerRegistry.d.ts.map +1 -1
  52. package/dist/internal/providerRegistry.js +127 -6
  53. package/dist/internal/providerSpec.d.ts +14 -7
  54. package/dist/internal/providerSpec.d.ts.map +1 -1
  55. package/dist/internal/providerSpec.js +306 -7
  56. package/dist/manifest.d.ts +226 -0
  57. package/dist/manifest.d.ts.map +1 -0
  58. package/dist/manifest.js +30 -0
  59. package/dist/server/ai.d.ts +66 -0
  60. package/dist/server/ai.d.ts.map +1 -1
  61. package/dist/server/ai.js +113 -8
  62. package/dist/server/aiBinding.d.ts +68 -0
  63. package/dist/server/aiBinding.d.ts.map +1 -0
  64. package/dist/server/aiBinding.js +294 -0
  65. package/dist/server/authorizeUrl.d.ts +1 -1
  66. package/dist/server/authorizeUrl.d.ts.map +1 -1
  67. package/dist/server/authorizeUrl.js +2 -6
  68. package/dist/server/emailBinding.d.ts +72 -0
  69. package/dist/server/emailBinding.d.ts.map +1 -0
  70. package/dist/server/emailBinding.js +124 -0
  71. package/dist/server/emit.js +1 -1
  72. package/dist/server/env.d.ts +41 -0
  73. package/dist/server/env.d.ts.map +1 -0
  74. package/dist/server/env.js +1 -0
  75. package/dist/server/gatewayFetch.d.ts +17 -13
  76. package/dist/server/gatewayFetch.d.ts.map +1 -1
  77. package/dist/server/gatewayFetch.js +24 -14
  78. package/dist/server/gatewayUrl.d.ts +13 -0
  79. package/dist/server/gatewayUrl.d.ts.map +1 -0
  80. package/dist/server/gatewayUrl.js +34 -0
  81. package/dist/server/index.d.ts +10 -3
  82. package/dist/server/index.d.ts.map +1 -1
  83. package/dist/server/index.js +8 -2
  84. package/dist/server/integrationFetch.d.ts +16 -32
  85. package/dist/server/integrationFetch.d.ts.map +1 -1
  86. package/dist/server/integrationFetch.js +47 -65
  87. package/dist/server/listMembers.js +1 -1
  88. package/dist/server/refusal.d.ts +55 -0
  89. package/dist/server/refusal.d.ts.map +1 -0
  90. package/dist/server/refusal.js +193 -0
  91. package/dist/server/sendEmail.js +1 -1
  92. package/dist/tanstack-start/index.d.ts +9 -0
  93. package/dist/tanstack-start/index.d.ts.map +1 -0
  94. package/dist/tanstack-start/index.js +29 -0
  95. package/dist/testing/index.d.ts +93 -0
  96. package/dist/testing/index.d.ts.map +1 -0
  97. package/dist/testing/index.js +156 -0
  98. package/package.json +34 -12
@@ -6,11 +6,15 @@
6
6
  * JSON into an {@link ApiKeyCapability} or names every problem; nothing
7
7
  * here reads a value: a spec names Gateway settings, never holds one.
8
8
  *
9
- * Two kinds parse: API-key providers (`auth.kind` bearer, header, query
10
- * or basic) and OAuth providers (`auth.kind` oauth2-user, the half in
9
+ * Three kinds parse: API-key providers (`auth.kind` bearer, header, query
10
+ * or basic), OAuth providers (`auth.kind` oauth2-user, the half in
11
11
  * ./oauthSpec.ts: the Gateway runs the flow and holds the tokens,
12
- * docs/design/2026-10-oauth-providers.md). An AI provider is a catalog
13
- * entry only; the parser says so rather than guessing.
12
+ * docs/design/2026-10-oauth-providers.md), and OpenAI-compatible model
13
+ * providers (`mode: "ai"`: a `baseUrl`, the key's placement, the models
14
+ * it serves and the default, its inference routes; the AI proxy serves a
15
+ * row exactly as it serves a catalog `ai` entry, inference POSTs alone,
16
+ * `store: false` on chat, the usage tap, so a new model vendor is a
17
+ * registered spec, not a catalog release).
14
18
  *
15
19
  * The rules that make a row safe on a particular gateway (its secret names
16
20
  * are its own, its hosts are public, it shadows no catalog entry) are the
@@ -60,6 +64,15 @@ const RESERVED_HEADERS = new Set([
60
64
  ]);
61
65
  const MAX_HOSTS = 20;
62
66
  const MAX_ACCOUNT_WIDE_PATHS = 50;
67
+ /** An inference route an `ai` row names: `/v1/chat/completions`, segments of lowercase letters, digits, `_` and `-`. */
68
+ const AI_ROUTE = /^(?:\/[a-z0-9_-]+)+$/;
69
+ const MAX_AI_ROUTES = 20;
70
+ const MAX_MODELS = 100;
71
+ /** A model name as OpenAI-compatible APIs spell them: `gpt-6-luna`, `meta-llama/llama-4`, `claude-haiku-5-5:beta`. */
72
+ const MODEL_NAME = /^[A-Za-z0-9][A-Za-z0-9._:/@-]{0,199}$/;
73
+ /** What an `ai` row serves by default: chat, and embeddings when it names an embeddings model. */
74
+ export const AI_SPEC_CHAT_ROUTE = "/v1/chat/completions";
75
+ export const AI_SPEC_EMBEDDINGS_ROUTE = "/v1/embeddings";
63
76
  const KNOWN_FIELDS = new Set([
64
77
  "id",
65
78
  "mode",
@@ -87,7 +100,39 @@ const KNOWN_FIELDS = new Set([
87
100
  "scopeSets",
88
101
  "alwaysRequested",
89
102
  "tolerated",
103
+ // An `ai` spec's own.
104
+ "baseUrl",
105
+ "models",
106
+ "defaultModel",
107
+ "embeddingsModel",
108
+ "routes",
109
+ "chatRoute",
110
+ "embeddingsRoute",
90
111
  ]);
112
+ /** Fields only an `ai` spec has. */
113
+ const AI_ONLY_FIELDS = [
114
+ "baseUrl",
115
+ "models",
116
+ "defaultModel",
117
+ "embeddingsModel",
118
+ "routes",
119
+ "chatRoute",
120
+ "embeddingsRoute",
121
+ ];
122
+ /** Fields an `ai` spec never has: the key goes to one base URL, and the AI proxy's rules replace the capability proxy's. */
123
+ const NOT_AI_FIELDS = [
124
+ "hosts",
125
+ "hostSetting",
126
+ "data",
127
+ "access",
128
+ "readMethods",
129
+ "writeMethods",
130
+ "accountWidePaths",
131
+ ...OAUTH_ONLY_FIELDS_LIST(),
132
+ ];
133
+ function OAUTH_ONLY_FIELDS_LIST() {
134
+ return ["scopeSets", "alwaysRequested", "tolerated"];
135
+ }
91
136
  /** Fields an API-key spec has that an `oauth2-user` spec does not. */
92
137
  const API_KEY_ONLY_FIELDS = [
93
138
  "hostSetting",
@@ -624,13 +669,20 @@ export function parseProviderSpec(input) {
624
669
  });
625
670
  }
626
671
  const isOAuth = isRecord(input["auth"]) && input["auth"]["kind"] === "oauth2-user";
672
+ const isAi = input["mode"] === "ai";
627
673
  const expectedMode = isOAuth ? "oauth_client" : "api_key";
628
- if (input["mode"] !== undefined && input["mode"] !== expectedMode) {
674
+ if (!isAi && input["mode"] !== undefined && input["mode"] !== expectedMode) {
629
675
  problems.push({
630
676
  path: "mode",
631
677
  message: isOAuth
632
678
  ? "an oauth2-user spec's mode is oauth_client (or left out)"
633
- : "this gateway registers api_key and oauth_client (auth.kind oauth2-user) providers; an AI provider is a catalog entry",
679
+ : 'this gateway registers api_key, oauth_client (auth.kind oauth2-user) and ai (mode: "ai", an OpenAI-compatible model provider) providers',
680
+ });
681
+ }
682
+ if (isAi && isOAuth) {
683
+ problems.push({
684
+ path: "auth.kind",
685
+ message: "an ai spec's key is a bearer, header, query or basic key, never oauth2-user",
634
686
  });
635
687
  }
636
688
  const name = text(input["name"], "name", problems, { max: 64 });
@@ -659,6 +711,9 @@ export function parseProviderSpec(input) {
659
711
  }
660
712
  },
661
713
  });
714
+ if (isAi && !isOAuth) {
715
+ return parseAiSpec(input, problems, { id, name, description, docs, api });
716
+ }
662
717
  if (isOAuth) {
663
718
  const { access, readMethods, writeMethods } = grants(input, problems);
664
719
  const hint = text(input["hint"], "hint", problems, { max: 500 });
@@ -789,6 +844,197 @@ export function parseProviderSpec(input) {
789
844
  };
790
845
  return { ok: true, id, capability };
791
846
  }
847
+ /**
848
+ * The `ai` half of `parseProviderSpec`: an OpenAI-compatible model
849
+ * provider. `baseUrl` is where the app's path is joined (`https://api.groq.com/openai`:
850
+ * the origin, and a base path the proxy keeps in front of every route);
851
+ * `auth` places the key as an API-key spec does; `models` lists what the
852
+ * provider serves (1 to 100; the proxy refuses any other) with
853
+ * `defaultModel` the one the Gateway's default route fills in and
854
+ * `embeddingsModel` the one for `/api/ai/default/v1/embeddings`; `routes`
855
+ * are the inference paths apps may POST to (default chat, and embeddings
856
+ * with an embeddings model), `chatRoute` and `embeddingsRoute` which of
857
+ * them the default route maps onto. Chat answers are never stored
858
+ * (`store: false` on the chat route). `cost.responseField` is where the
859
+ * answer carries the call's price, read by the usage tap as OpenRouter's
860
+ * `usage.cost` is.
861
+ */
862
+ function parseAiSpec(input, problems, common) {
863
+ for (const field of NOT_AI_FIELDS) {
864
+ if (input[field] !== undefined) {
865
+ problems.push({ path: field, message: "not a field of an ai spec" });
866
+ }
867
+ }
868
+ const base = httpsUrl(input["baseUrl"], "baseUrl", problems);
869
+ let origin;
870
+ let basePath;
871
+ if (input["baseUrl"] === undefined) {
872
+ problems.push({
873
+ path: "baseUrl",
874
+ message: "required: the https URL the app's paths are joined onto (https://api.groq.com/openai)",
875
+ });
876
+ }
877
+ else if (base !== undefined) {
878
+ const url = new URL(base);
879
+ if (url.search || url.hash || url.username || url.password || url.port) {
880
+ problems.push({
881
+ path: "baseUrl",
882
+ message: "must be an https URL with no query, fragment, credentials or port",
883
+ });
884
+ }
885
+ else if (!PROVIDER_HOST.test(url.hostname)) {
886
+ problems.push({
887
+ path: "baseUrl",
888
+ message: "must name a public host with a dot (api.groq.com)",
889
+ });
890
+ }
891
+ else {
892
+ origin = url.origin;
893
+ const path = url.pathname.replace(/\/+$/, "");
894
+ if (path && !AI_ROUTE.test(path)) {
895
+ problems.push({
896
+ path: "baseUrl",
897
+ message: "its path must be segments of lowercase letters, digits, _ and -",
898
+ });
899
+ }
900
+ else if (path) {
901
+ basePath = path;
902
+ }
903
+ }
904
+ }
905
+ const parsedAuth = auth(input["auth"], problems);
906
+ if (input["auth"] === undefined) {
907
+ problems.push({ path: "auth", message: "required" });
908
+ }
909
+ const secrets = secretDetails(input["secrets"], parsedAuth ? authSettingNames(parsedAuth) : [], problems);
910
+ const models = stringList(input["models"], "models", problems, {
911
+ max: MAX_MODELS,
912
+ each: (model, at) => {
913
+ if (!MODEL_NAME.test(model)) {
914
+ problems.push({
915
+ path: at,
916
+ message: "must be a model name (gpt-6-luna, meta-llama/llama-4)",
917
+ });
918
+ }
919
+ },
920
+ });
921
+ if (input["models"] === undefined || (models && models.length === 0)) {
922
+ problems.push({
923
+ path: "models",
924
+ message: "required: the models the provider serves, at least one",
925
+ });
926
+ }
927
+ const defaultModel = text(input["defaultModel"], "defaultModel", problems, {
928
+ max: 200,
929
+ });
930
+ if (input["defaultModel"] === undefined) {
931
+ problems.push({
932
+ path: "defaultModel",
933
+ message: "required: the chat model the Gateway fills in when an app names none; one of models",
934
+ });
935
+ }
936
+ else if (defaultModel !== undefined &&
937
+ models &&
938
+ !models.includes(defaultModel)) {
939
+ problems.push({ path: "defaultModel", message: "must be one of models" });
940
+ }
941
+ const embeddingsModel = text(input["embeddingsModel"], "embeddingsModel", problems, { max: 200 });
942
+ if (embeddingsModel !== undefined &&
943
+ models &&
944
+ !models.includes(embeddingsModel)) {
945
+ problems.push({
946
+ path: "embeddingsModel",
947
+ message: "must be one of models",
948
+ });
949
+ }
950
+ const routeList = (value, path) => stringList(value, path, problems, {
951
+ max: MAX_AI_ROUTES,
952
+ each: (route, at) => {
953
+ if (!AI_ROUTE.test(route)) {
954
+ problems.push({
955
+ path: at,
956
+ message: "must be a path of lowercase segments starting with / (/v1/chat/completions)",
957
+ });
958
+ }
959
+ },
960
+ });
961
+ const chatRoute = text(input["chatRoute"], "chatRoute", problems, { max: 200 }) ??
962
+ AI_SPEC_CHAT_ROUTE;
963
+ const embeddingsRoute = text(input["embeddingsRoute"], "embeddingsRoute", problems, { max: 200 }) ??
964
+ AI_SPEC_EMBEDDINGS_ROUTE;
965
+ for (const [field, route] of [
966
+ ["chatRoute", chatRoute],
967
+ ["embeddingsRoute", embeddingsRoute],
968
+ ]) {
969
+ if (!AI_ROUTE.test(route)) {
970
+ problems.push({
971
+ path: field,
972
+ message: "must be a path of lowercase segments starting with /",
973
+ });
974
+ }
975
+ }
976
+ const routes = routeList(input["routes"], "routes") ?? [
977
+ chatRoute,
978
+ ...(embeddingsModel !== undefined ? [embeddingsRoute] : []),
979
+ ];
980
+ if (routes.length === 0) {
981
+ problems.push({ path: "routes", message: "must list a route" });
982
+ }
983
+ if (!routes.includes(chatRoute)) {
984
+ problems.push({ path: "chatRoute", message: "must be one of routes" });
985
+ }
986
+ if (embeddingsModel !== undefined && !routes.includes(embeddingsRoute)) {
987
+ problems.push({
988
+ path: "embeddingsRoute",
989
+ message: "must be one of routes",
990
+ });
991
+ }
992
+ const hint = text(input["hint"], "hint", problems, { max: 500 });
993
+ const smokeRequest = smoke(input["smoke"], origin ? [new URL(origin).host] : [], problems);
994
+ const parsedCost = cost(input["cost"], problems);
995
+ const parsedRate = rate(input["rate"], problems);
996
+ const example = text(input["example"], "example", problems, { max: 200 });
997
+ const parsedVerified = verified(input["verified"], problems);
998
+ const tags = tagList(input["tags"], problems);
999
+ const { id, name, description, docs, api } = common;
1000
+ if (problems.length > 0 ||
1001
+ typeof id !== "string" ||
1002
+ name === undefined ||
1003
+ docs === undefined ||
1004
+ origin === undefined ||
1005
+ !parsedAuth ||
1006
+ !models ||
1007
+ defaultModel === undefined) {
1008
+ return { ok: false, problems };
1009
+ }
1010
+ const capability = {
1011
+ mode: "ai",
1012
+ label: name,
1013
+ auth: parsedAuth,
1014
+ docs,
1015
+ origin,
1016
+ ...(basePath === undefined ? {} : { basePath }),
1017
+ inferenceRoutes: routes,
1018
+ unstoredRoutes: [chatRoute],
1019
+ shape: "openai",
1020
+ chat: { path: chatRoute, seedModel: defaultModel },
1021
+ ...(embeddingsModel === undefined
1022
+ ? {}
1023
+ : { embeddings: { path: embeddingsRoute, seedModel: embeddingsModel } }),
1024
+ models,
1025
+ ...(description === undefined ? {} : { description }),
1026
+ ...(api === undefined ? {} : { api }),
1027
+ ...(secrets === undefined ? {} : { secrets }),
1028
+ ...(hint === undefined ? {} : { hint }),
1029
+ ...(smokeRequest === undefined ? {} : { smoke: smokeRequest }),
1030
+ ...(parsedCost === undefined ? {} : { cost: parsedCost }),
1031
+ ...(parsedRate === undefined ? {} : { rate: parsedRate }),
1032
+ ...(example === undefined ? {} : { example }),
1033
+ ...(parsedVerified === undefined ? {} : { verified: parsedVerified }),
1034
+ ...(tags === undefined ? {} : { tags }),
1035
+ };
1036
+ return { ok: true, id, capability };
1037
+ }
792
1038
  /** The problems as one line: `auth.secret: must name a Gateway setting; hosts.0: …`. */
793
1039
  export function describeSpecProblems(problems) {
794
1040
  return problems
@@ -809,6 +1055,58 @@ export function providerSpecOf(id, capability) {
809
1055
  }
810
1056
  return spec;
811
1057
  }
1058
+ if (capability.mode === "ai") {
1059
+ if (!capability.chat || !capability.models) {
1060
+ throw new Error(`${id} is a catalog AI entry without a model list: it has no spec`);
1061
+ }
1062
+ return {
1063
+ id,
1064
+ mode: "ai",
1065
+ name: capability.label,
1066
+ ...(capability.description === undefined
1067
+ ? {}
1068
+ : { description: capability.description }),
1069
+ docs: capability.docs,
1070
+ ...(capability.api === undefined ? {} : { api: capability.api }),
1071
+ baseUrl: `${capability.origin}${capability.basePath ?? ""}`,
1072
+ auth: { ...capability.auth },
1073
+ ...(capability.secrets === undefined
1074
+ ? {}
1075
+ : { secrets: capability.secrets.map((detail) => ({ ...detail })) }),
1076
+ models: [...capability.models],
1077
+ defaultModel: capability.chat.seedModel,
1078
+ ...(capability.embeddings === undefined
1079
+ ? {}
1080
+ : { embeddingsModel: capability.embeddings.seedModel }),
1081
+ routes: [...capability.inferenceRoutes],
1082
+ chatRoute: capability.chat.path,
1083
+ ...(capability.embeddings === undefined
1084
+ ? {}
1085
+ : { embeddingsRoute: capability.embeddings.path }),
1086
+ ...(capability.hint === undefined ? {} : { hint: capability.hint }),
1087
+ ...(capability.smoke === undefined
1088
+ ? {}
1089
+ : {
1090
+ smoke: {
1091
+ ...capability.smoke,
1092
+ expect: [...capability.smoke.expect],
1093
+ },
1094
+ }),
1095
+ ...(capability.cost === undefined
1096
+ ? {}
1097
+ : { cost: { ...capability.cost } }),
1098
+ ...(capability.rate === undefined
1099
+ ? {}
1100
+ : { rate: { ...capability.rate } }),
1101
+ ...(capability.example === undefined
1102
+ ? {}
1103
+ : { example: capability.example }),
1104
+ ...(capability.verified === undefined
1105
+ ? {}
1106
+ : { verified: capability.verified }),
1107
+ ...(capability.tags === undefined ? {} : { tags: [...capability.tags] }),
1108
+ };
1109
+ }
812
1110
  return {
813
1111
  id,
814
1112
  name: capability.label,
@@ -851,5 +1149,6 @@ export function providerSpecOf(id, capability) {
851
1149
  }
852
1150
  /** The methods an app with `access: "write"` may use on `capability` besides its read methods. */
853
1151
  export function writeMethodsOf(capability) {
854
- return capability.writeMethods ?? DEFAULT_WRITE_METHODS;
1152
+ return ((capability.mode === "ai" ? undefined : capability.writeMethods) ??
1153
+ DEFAULT_WRITE_METHODS);
855
1154
  }
@@ -0,0 +1,226 @@
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
+ /**
115
+ * One of the app's plain settings: a value that isn't a secret and
116
+ * differs per install (a PostHog host, a region), set with `everyapp
117
+ * configure <app>` and read from `env`.
118
+ */
119
+ export interface EveryAppSettingEntry {
120
+ readonly name: string;
121
+ /** Why the app needs it: what whoever installs the app reads. */
122
+ readonly why: string;
123
+ readonly docs?: string;
124
+ readonly optional?: boolean;
125
+ /** What it takes; text when not given. */
126
+ readonly type?: "text" | "url" | "number" | "boolean";
127
+ /** The values a text setting may take. */
128
+ readonly values?: readonly string[];
129
+ /** What the app reads while nobody has set it; the deploy writes it. */
130
+ readonly default?: string;
131
+ }
132
+ /** One of the app's own secrets, with its need. */
133
+ export interface EveryAppSecretEntry extends EveryAppSettingNeed {
134
+ readonly name: string;
135
+ /** Its guide in the everyapp skill (`"setup/main-secret.md"`). */
136
+ readonly setup?: string;
137
+ }
138
+ /** `everyapp.config.ts`. */
139
+ export interface EveryAppManifest {
140
+ /** Stable id, kebab-case: the app's hostname and Worker. */
141
+ readonly id: string;
142
+ readonly name?: string;
143
+ /** The one line the Gateway's app library shows under the name. */
144
+ readonly description?: string;
145
+ /** The path of an SVG the app serves (`"/everyapp-icon.svg"`). */
146
+ readonly icon?: string;
147
+ /** Legacy: the entry comes from `cloudflare.config.ts`. */
148
+ readonly main?: string;
149
+ /** YYYY-MM-DD. */
150
+ readonly compatibilityDate?: string;
151
+ readonly resources?: EveryAppResources;
152
+ /** Helper Workers deployed beside the app's as `<app worker>--<name>`. */
153
+ readonly workers?: readonly {
154
+ readonly name: string;
155
+ readonly binding?: string;
156
+ readonly limits?: EveryAppWorkerLimits;
157
+ }[];
158
+ readonly database?: {
159
+ readonly provider: "d1" | "postgres";
160
+ /** A cloud region such as `"aws:us-east-1"`. */
161
+ readonly region?: string;
162
+ };
163
+ readonly limits?: EveryAppWorkerLimits;
164
+ /** Routes open without a signed-in member. Default: none. */
165
+ readonly public?: readonly EveryAppPublicRoute[];
166
+ /**
167
+ * Static files of the asset bundle anyone may fetch (favicons, icons, an
168
+ * OG image): path patterns, GET and HEAD, never Worker code.
169
+ */
170
+ readonly publicAssets?: readonly string[];
171
+ /** AI providers the Gateway calls for the app, by id or with their need. */
172
+ readonly providers?: readonly (string | (EveryAppSettingNeed & {
173
+ readonly id: string;
174
+ }))[];
175
+ /** Capabilities by id (`members`, `email`, `dataforseo`, …). */
176
+ readonly capabilities?: {
177
+ readonly [id: string]: EveryAppCapabilityEntry;
178
+ };
179
+ /** The app's own secrets, by name or with their need. */
180
+ readonly secrets?: readonly (string | EveryAppSecretEntry)[];
181
+ /** The app's plain settings: per-install values that aren't secrets. */
182
+ readonly settings?: readonly EveryAppSettingEntry[];
183
+ readonly ai?: {
184
+ /** Model ids the app may request; any other is `model_not_allowed`. */
185
+ readonly models?: readonly string[];
186
+ /** OpenAI API paths beyond inference (`"/v1/files"`). */
187
+ readonly routes?: readonly string[];
188
+ /** The app takes the Gateway's default chat model (`ai()`). */
189
+ readonly chat?: boolean | EveryAppSettingNeed;
190
+ };
191
+ /** `inbound: true`: the Worker exports an `email()` handler. */
192
+ readonly email?: {
193
+ readonly inbound?: boolean;
194
+ };
195
+ /** Who can open the app once registered; `"admins"` by default. */
196
+ readonly access?: "everyone" | "admins";
197
+ readonly serverFnGuard?: boolean;
198
+ readonly serverFnBase?: string;
199
+ /** Shell command that builds the app; `cf build` by default. */
200
+ readonly build?: string;
201
+ /** Shell command `everyapp dev` starts; it must listen on PORT. */
202
+ readonly dev?: string;
203
+ /** Legacy: the port comes from PORT. */
204
+ readonly devPort?: number;
205
+ /** Dependency install command; false skips it. */
206
+ readonly install?: false | string;
207
+ readonly migrations?: {
208
+ readonly engine: "drizzle" | "d1-sql" | "prisma";
209
+ readonly dialect?: "sqlite" | "postgresql";
210
+ readonly dir?: string;
211
+ readonly config?: string;
212
+ readonly binding?: string;
213
+ };
214
+ /** Who answers `/mcp` on the app's own host, and why it needs to. */
215
+ readonly mcp?: {
216
+ readonly by: "gateway" | "app";
217
+ readonly why: string;
218
+ };
219
+ }
220
+ /**
221
+ * Type `everyapp.config.ts` without widening it: the literal binding names
222
+ * stay, so `everyAppWorker()` types `env.DB` and `env.EVERYAPP_MANIFEST`
223
+ * from them. Returns the manifest as given.
224
+ */
225
+ export declare function defineEveryApp<const M extends EveryAppManifest>(manifest: M): M;
226
+ //# 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
+ }