@alchemy.run/boat 0.0.0 → 2.0.0-beta.87

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 (154) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +66 -4
  3. package/lib/AiProxy.d.ts +89 -0
  4. package/lib/AiProxy.d.ts.map +1 -0
  5. package/lib/AiProxy.js +125 -0
  6. package/lib/AiProxy.js.map +1 -0
  7. package/lib/ApiKey.d.ts +105 -0
  8. package/lib/ApiKey.d.ts.map +1 -0
  9. package/lib/ApiKey.js +134 -0
  10. package/lib/ApiKey.js.map +1 -0
  11. package/lib/AuthProvider.d.ts +71 -0
  12. package/lib/AuthProvider.d.ts.map +1 -0
  13. package/lib/AuthProvider.js +322 -0
  14. package/lib/AuthProvider.js.map +1 -0
  15. package/lib/BoatBindings.d.ts +52 -0
  16. package/lib/BoatBindings.d.ts.map +1 -0
  17. package/lib/BoatBindings.js +104 -0
  18. package/lib/BoatBindings.js.map +1 -0
  19. package/lib/Bootstrap.d.ts +8 -0
  20. package/lib/Bootstrap.d.ts.map +1 -0
  21. package/lib/Bootstrap.js +28 -0
  22. package/lib/Bootstrap.js.map +1 -0
  23. package/lib/ConnectSandbox.d.ts +56 -0
  24. package/lib/ConnectSandbox.d.ts.map +1 -0
  25. package/lib/ConnectSandbox.js +3 -0
  26. package/lib/ConnectSandbox.js.map +1 -0
  27. package/lib/ConnectSandboxHttp.d.ts +21 -0
  28. package/lib/ConnectSandboxHttp.d.ts.map +1 -0
  29. package/lib/ConnectSandboxHttp.js +46 -0
  30. package/lib/ConnectSandboxHttp.js.map +1 -0
  31. package/lib/Contributions.d.ts +7 -0
  32. package/lib/Contributions.d.ts.map +1 -0
  33. package/lib/Contributions.js +6 -0
  34. package/lib/Contributions.js.map +1 -0
  35. package/lib/CreateSandbox.d.ts +134 -0
  36. package/lib/CreateSandbox.d.ts.map +1 -0
  37. package/lib/CreateSandbox.js +3 -0
  38. package/lib/CreateSandbox.js.map +1 -0
  39. package/lib/CreateSandboxHttp.d.ts +21 -0
  40. package/lib/CreateSandboxHttp.d.ts.map +1 -0
  41. package/lib/CreateSandboxHttp.js +93 -0
  42. package/lib/CreateSandboxHttp.js.map +1 -0
  43. package/lib/CredentialProfile.d.ts +157 -0
  44. package/lib/CredentialProfile.d.ts.map +1 -0
  45. package/lib/CredentialProfile.js +245 -0
  46. package/lib/CredentialProfile.js.map +1 -0
  47. package/lib/Credentials.d.ts +15 -0
  48. package/lib/Credentials.d.ts.map +1 -0
  49. package/lib/Credentials.js +23 -0
  50. package/lib/Credentials.js.map +1 -0
  51. package/lib/Environment.d.ts +219 -0
  52. package/lib/Environment.d.ts.map +1 -0
  53. package/lib/Environment.js +273 -0
  54. package/lib/Environment.js.map +1 -0
  55. package/lib/Errors.d.ts +50 -0
  56. package/lib/Errors.d.ts.map +1 -0
  57. package/lib/Errors.js +17 -0
  58. package/lib/Errors.js.map +1 -0
  59. package/lib/Providers.d.ts +33 -0
  60. package/lib/Providers.d.ts.map +1 -0
  61. package/lib/Providers.js +47 -0
  62. package/lib/Providers.js.map +1 -0
  63. package/lib/Sandbox.d.ts +205 -0
  64. package/lib/Sandbox.d.ts.map +1 -0
  65. package/lib/Sandbox.js +368 -0
  66. package/lib/Sandbox.js.map +1 -0
  67. package/lib/SandboxClient.d.ts +159 -0
  68. package/lib/SandboxClient.d.ts.map +1 -0
  69. package/lib/SandboxClient.js +1 -0
  70. package/lib/SandboxClient.js.map +1 -0
  71. package/lib/SandboxEvents.d.ts +111 -0
  72. package/lib/SandboxEvents.d.ts.map +1 -0
  73. package/lib/SandboxEvents.js +60 -0
  74. package/lib/SandboxEvents.js.map +1 -0
  75. package/lib/SandboxEventsLive.d.ts +13 -0
  76. package/lib/SandboxEventsLive.d.ts.map +1 -0
  77. package/lib/SandboxEventsLive.js +63 -0
  78. package/lib/SandboxEventsLive.js.map +1 -0
  79. package/lib/Snapshot.d.ts +123 -0
  80. package/lib/Snapshot.d.ts.map +1 -0
  81. package/lib/Snapshot.js +173 -0
  82. package/lib/Snapshot.js.map +1 -0
  83. package/lib/Webhook.d.ts +56 -0
  84. package/lib/Webhook.d.ts.map +1 -0
  85. package/lib/Webhook.js +98 -0
  86. package/lib/Webhook.js.map +1 -0
  87. package/lib/index.d.ts +19 -0
  88. package/lib/index.d.ts.map +1 -0
  89. package/lib/index.js +19 -0
  90. package/lib/index.js.map +1 -0
  91. package/lib/internal/Declared.d.ts +34 -0
  92. package/lib/internal/Declared.d.ts.map +1 -0
  93. package/lib/internal/Declared.js +38 -0
  94. package/lib/internal/Declared.js.map +1 -0
  95. package/lib/internal/Org.d.ts +22 -0
  96. package/lib/internal/Org.d.ts.map +1 -0
  97. package/lib/internal/Org.js +23 -0
  98. package/lib/internal/Org.js.map +1 -0
  99. package/lib/internal/Ownership.d.ts +29 -0
  100. package/lib/internal/Ownership.d.ts.map +1 -0
  101. package/lib/internal/Ownership.js +50 -0
  102. package/lib/internal/Ownership.js.map +1 -0
  103. package/lib/internal/Program.d.ts +69 -0
  104. package/lib/internal/Program.d.ts.map +1 -0
  105. package/lib/internal/Program.js +178 -0
  106. package/lib/internal/Program.js.map +1 -0
  107. package/lib/internal/Ref.d.ts +14 -0
  108. package/lib/internal/Ref.d.ts.map +1 -0
  109. package/lib/internal/Ref.js +7 -0
  110. package/lib/internal/Ref.js.map +1 -0
  111. package/lib/internal/SandboxHandle.d.ts +17 -0
  112. package/lib/internal/SandboxHandle.d.ts.map +1 -0
  113. package/lib/internal/SandboxHandle.js +238 -0
  114. package/lib/internal/SandboxHandle.js.map +1 -0
  115. package/lib/internal/SavedSnapshot.d.ts +10 -0
  116. package/lib/internal/SavedSnapshot.d.ts.map +1 -0
  117. package/lib/internal/SavedSnapshot.js +22 -0
  118. package/lib/internal/SavedSnapshot.js.map +1 -0
  119. package/lib/internal/WebhookDelivery.d.ts +16 -0
  120. package/lib/internal/WebhookDelivery.d.ts.map +1 -0
  121. package/lib/internal/WebhookDelivery.js +109 -0
  122. package/lib/internal/WebhookDelivery.js.map +1 -0
  123. package/package.json +67 -3
  124. package/src/AiProxy.ts +171 -0
  125. package/src/ApiKey.ts +250 -0
  126. package/src/AuthProvider.ts +472 -0
  127. package/src/BoatBindings.ts +136 -0
  128. package/src/Bootstrap.ts +55 -0
  129. package/src/ConnectSandbox.ts +60 -0
  130. package/src/ConnectSandboxHttp.ts +59 -0
  131. package/src/Contributions.ts +9 -0
  132. package/src/CreateSandbox.ts +143 -0
  133. package/src/CreateSandboxHttp.ts +115 -0
  134. package/src/CredentialProfile.ts +350 -0
  135. package/src/Credentials.ts +33 -0
  136. package/src/Environment.ts +416 -0
  137. package/src/Errors.ts +34 -0
  138. package/src/Providers.ts +71 -0
  139. package/src/Sandbox.ts +647 -0
  140. package/src/SandboxClient.ts +200 -0
  141. package/src/SandboxEvents.ts +125 -0
  142. package/src/SandboxEventsLive.ts +88 -0
  143. package/src/Snapshot.ts +264 -0
  144. package/src/Webhook.ts +163 -0
  145. package/src/globals.d.ts +2 -0
  146. package/src/index.ts +18 -0
  147. package/src/internal/Declared.ts +87 -0
  148. package/src/internal/Org.ts +31 -0
  149. package/src/internal/Ownership.ts +75 -0
  150. package/src/internal/Program.ts +250 -0
  151. package/src/internal/Ref.ts +15 -0
  152. package/src/internal/SandboxHandle.ts +407 -0
  153. package/src/internal/SavedSnapshot.ts +34 -0
  154. package/src/internal/WebhookDelivery.ts +179 -0
@@ -0,0 +1,157 @@
1
+ import * as boat from "@distilled.cloud/boat-dev/boat";
2
+ import * as Provider from "alchemy/Provider";
3
+ import { Resource } from "alchemy/Resource";
4
+ import * as Redacted from "effect/Redacted";
5
+ import type { Providers } from "./Providers.ts";
6
+ type Secret = string | Redacted.Redacted<string>;
7
+ /** A secret for any HTTPS API, and the base URL it is sent to. */
8
+ export interface CredentialProfileApi {
9
+ /** The secret. A sandbox gets it as the variable the API is named after. */
10
+ key: Secret;
11
+ /**
12
+ * The API's base URL: HTTPS on the default port, with a public DNS name.
13
+ * A sandbox gets it as `<NAME>_BASE_URL`, and code there must send its
14
+ * requests to that variable: with the AI credentials proxy on it holds
15
+ * the proxy's URL, and only the proxy can swap the placeholder for `key`.
16
+ */
17
+ baseUrl: string;
18
+ }
19
+ export interface CredentialProfileProps {
20
+ /**
21
+ * Profile name, unique among its owner's profiles. If omitted, a unique
22
+ * name is generated from the stack, stage and logical ID. Renamed in
23
+ * place.
24
+ */
25
+ name?: string;
26
+ /** Anthropic API key. Sandboxes get it as `ANTHROPIC_API_KEY`. */
27
+ anthropic?: Secret;
28
+ /** OpenAI API key. Sandboxes get it as `OPENAI_API_KEY`. */
29
+ openai?: Secret;
30
+ /** OpenRouter API key. */
31
+ openrouter?: Secret;
32
+ /** LLM Gateway API key. */
33
+ llmgateway?: Secret;
34
+ /** DeepSeek API key. */
35
+ deepseek?: Secret;
36
+ /** Moonshot API key. */
37
+ moonshot?: Secret;
38
+ /** Mistral API key. */
39
+ mistral?: Secret;
40
+ /** xAI API key. */
41
+ xai?: Secret;
42
+ /** OpenCode API key. */
43
+ opencode?: Secret;
44
+ /**
45
+ * Secrets for any other HTTPS API, keyed by the environment variable a
46
+ * sandbox gets the secret as: `A-Z`, `0-9` and `_`, up to 64 characters.
47
+ * Provider names (`ANTHROPIC_*`, `OPENAI_*`, `AWS_*`, …) and names ending
48
+ * in `_BASE_URL` are reserved.
49
+ */
50
+ apis?: Record<string, CredentialProfileApi>;
51
+ }
52
+ export interface CredentialProfileAttributes {
53
+ /** Boat's profile id. */
54
+ credentialProfileId: string;
55
+ name: string;
56
+ /**
57
+ * The organization that owns the profile, as the stack's `org` named it;
58
+ * `undefined` for a personal profile.
59
+ */
60
+ org: string | undefined;
61
+ /** Whether it is its owner's default: what a sandbox gets when its environment names no profile. */
62
+ isDefault: boolean;
63
+ /** The credentials it holds, by Boat's ids (`anthropic-api-key`, `claude-subscription`, …). */
64
+ connected: string[];
65
+ /** The names of its custom APIs. */
66
+ customApis: string[];
67
+ }
68
+ export interface CredentialProfile extends Resource<"Boat.CredentialProfile", CredentialProfileProps, CredentialProfileAttributes, never, Providers, {
69
+ name: string;
70
+ }> {
71
+ }
72
+ /**
73
+ * A Boat credential profile: a named set of API keys that Boat stores
74
+ * encrypted and hands to the sandboxes of an environment that names it.
75
+ *
76
+ * A profile holds provider API keys (Anthropic, OpenAI, …) and custom APIs:
77
+ * a secret for any other HTTPS API, with the base URL it is sent to. Boat
78
+ * never returns a secret once it is stored.
79
+ *
80
+ * The API keys and custom APIs of a declared profile are exactly the ones
81
+ * its props list: a deploy removes any other. Sign-ins (a Claude or ChatGPT
82
+ * subscription) and Bedrock are connected on Boat's dashboard and left
83
+ * alone.
84
+ *
85
+ * A profile is personal, or owned by an organization. With an `org` on the
86
+ * stack (`Boat.providers({ org })`, or the profile's) the organization owns
87
+ * it: every member's sandboxes can use it, and only owners change it.
88
+ * Without one it is yours. Changing the stack's `org` replaces it.
89
+ *
90
+ * ### Creating a profile
91
+ * **Example:** Provider API keys
92
+ * ```typescript
93
+ * export const MyProfile = Boat.CredentialProfile("MyProfile", {
94
+ * anthropic: Config.Redacted("ANTHROPIC_API_KEY"),
95
+ * openai: Config.Redacted("OPENAI_API_KEY"),
96
+ * });
97
+ * ```
98
+ *
99
+ * **Example:** A secret for any other API
100
+ * ```typescript
101
+ * export const Payments = Boat.CredentialProfile("Payments", {
102
+ * apis: {
103
+ * STRIPE_KEY: {
104
+ * key: Config.Redacted("STRIPE_KEY"),
105
+ * baseUrl: "https://api.stripe.com/v1",
106
+ * },
107
+ * },
108
+ * });
109
+ * ```
110
+ *
111
+ * A sandbox gets `STRIPE_KEY` and `STRIPE_KEY_BASE_URL`. Send requests to
112
+ * `$STRIPE_KEY_BASE_URL`, not to the API's own address, so the same code
113
+ * works when the AI credentials proxy replaces both.
114
+ *
115
+ * ### Giving sandboxes a profile
116
+ * **Example:** Name it on an environment
117
+ * ```typescript
118
+ * export const MyProfile = Boat.CredentialProfile("MyProfile", {
119
+ * anthropic: Config.Redacted("ANTHROPIC_API_KEY"),
120
+ * });
121
+ *
122
+ * export const MyEnv = Boat.Environment("MyEnv", { credentialProfile: MyProfile });
123
+ *
124
+ * export const Box = Boat.Sandbox("Box", { environment: MyEnv });
125
+ * ```
126
+ *
127
+ * **Example:** Placeholders instead of real keys
128
+ * ```typescript
129
+ * export const MyProfile = Boat.CredentialProfile("MyProfile", {
130
+ * anthropic: Config.Redacted("ANTHROPIC_API_KEY"),
131
+ * });
132
+ *
133
+ * // Billed: $1 a day, plus $1 per 1,000 proxied requests.
134
+ * export const Proxy = Boat.AiProxy("Proxy", { enabled: true });
135
+ *
136
+ * export const Tenants = Boat.Environment("Tenants", {
137
+ * safeForThirdParties: true,
138
+ * credentialProfile: MyProfile,
139
+ * proxyAiCredentials: Proxy,
140
+ * });
141
+ * ```
142
+ *
143
+ * ### Referencing a profile the stack doesn't manage
144
+ * **Example:** The default profile, with the sign-ins made on the dashboard
145
+ * ```typescript
146
+ * export const MyEnv = Boat.Environment("MyEnv", {
147
+ * credentialProfile: Boat.CredentialProfile.lookup({ name: "default" }),
148
+ * });
149
+ * ```
150
+ *
151
+ * @resource
152
+ * @product Credential Profile
153
+ */
154
+ export declare const CredentialProfile: import("alchemy/Resource").ResourceClass<CredentialProfile>;
155
+ export declare const CredentialProfileProvider: () => import("effect/Layer").Layer<Provider.Provider<CredentialProfile>, never, import("alchemy/Stack").Stack | import("alchemy/Stage").Stage | boat.BoatOpContext>;
156
+ export {};
157
+ //# sourceMappingURL=CredentialProfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CredentialProfile.d.ts","sources":["../src/CredentialProfile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,gCAAgC,CAAC;AAEvD,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAI5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,KAAK,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAEjD,kEAAkE;AAClE,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,2BAA2B;IAC1C,yBAAyB;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,oGAAoG;IACpG,SAAS,EAAE,OAAO,CAAC;IACnB,+FAA+F;IAC/F,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oCAAoC;IACpC,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAkB,SAAQ,QAAQ,CACjD,wBAAwB,EACxB,sBAAsB,EACtB,2BAA2B,EAC3B,KAAK,EACL,SAAS,EACT;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CACjB;CAAG;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiFG;AACH,eAAO,MAAM,iBAAiB,6DAAwD,CAAC;AAmDvF,eAAO,MAAM,yBAAyB,qKAkInC,CAAC"}
@@ -0,0 +1,245 @@
1
+ import * as boat from "@distilled.cloud/boat-dev/boat";
2
+ import { Unowned } from "alchemy/AdoptPolicy";
3
+ import * as Provider from "alchemy/Provider";
4
+ import { Resource } from "alchemy/Resource";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Redacted from "effect/Redacted";
7
+ import { BoatUnexpectedResponse } from "./Errors.js";
8
+ import { inOrg, isOrgAccount, sameOrg, stackOrg } from "./internal/Org.js";
9
+ import { boatName, isGeneratedName } from "./internal/Ownership.js";
10
+ /**
11
+ * A Boat credential profile: a named set of API keys that Boat stores
12
+ * encrypted and hands to the sandboxes of an environment that names it.
13
+ *
14
+ * A profile holds provider API keys (Anthropic, OpenAI, …) and custom APIs:
15
+ * a secret for any other HTTPS API, with the base URL it is sent to. Boat
16
+ * never returns a secret once it is stored.
17
+ *
18
+ * The API keys and custom APIs of a declared profile are exactly the ones
19
+ * its props list: a deploy removes any other. Sign-ins (a Claude or ChatGPT
20
+ * subscription) and Bedrock are connected on Boat's dashboard and left
21
+ * alone.
22
+ *
23
+ * A profile is personal, or owned by an organization. With an `org` on the
24
+ * stack (`Boat.providers({ org })`, or the profile's) the organization owns
25
+ * it: every member's sandboxes can use it, and only owners change it.
26
+ * Without one it is yours. Changing the stack's `org` replaces it.
27
+ *
28
+ * ### Creating a profile
29
+ * **Example:** Provider API keys
30
+ * ```typescript
31
+ * export const MyProfile = Boat.CredentialProfile("MyProfile", {
32
+ * anthropic: Config.Redacted("ANTHROPIC_API_KEY"),
33
+ * openai: Config.Redacted("OPENAI_API_KEY"),
34
+ * });
35
+ * ```
36
+ *
37
+ * **Example:** A secret for any other API
38
+ * ```typescript
39
+ * export const Payments = Boat.CredentialProfile("Payments", {
40
+ * apis: {
41
+ * STRIPE_KEY: {
42
+ * key: Config.Redacted("STRIPE_KEY"),
43
+ * baseUrl: "https://api.stripe.com/v1",
44
+ * },
45
+ * },
46
+ * });
47
+ * ```
48
+ *
49
+ * A sandbox gets `STRIPE_KEY` and `STRIPE_KEY_BASE_URL`. Send requests to
50
+ * `$STRIPE_KEY_BASE_URL`, not to the API's own address, so the same code
51
+ * works when the AI credentials proxy replaces both.
52
+ *
53
+ * ### Giving sandboxes a profile
54
+ * **Example:** Name it on an environment
55
+ * ```typescript
56
+ * export const MyProfile = Boat.CredentialProfile("MyProfile", {
57
+ * anthropic: Config.Redacted("ANTHROPIC_API_KEY"),
58
+ * });
59
+ *
60
+ * export const MyEnv = Boat.Environment("MyEnv", { credentialProfile: MyProfile });
61
+ *
62
+ * export const Box = Boat.Sandbox("Box", { environment: MyEnv });
63
+ * ```
64
+ *
65
+ * **Example:** Placeholders instead of real keys
66
+ * ```typescript
67
+ * export const MyProfile = Boat.CredentialProfile("MyProfile", {
68
+ * anthropic: Config.Redacted("ANTHROPIC_API_KEY"),
69
+ * });
70
+ *
71
+ * // Billed: $1 a day, plus $1 per 1,000 proxied requests.
72
+ * export const Proxy = Boat.AiProxy("Proxy", { enabled: true });
73
+ *
74
+ * export const Tenants = Boat.Environment("Tenants", {
75
+ * safeForThirdParties: true,
76
+ * credentialProfile: MyProfile,
77
+ * proxyAiCredentials: Proxy,
78
+ * });
79
+ * ```
80
+ *
81
+ * ### Referencing a profile the stack doesn't manage
82
+ * **Example:** The default profile, with the sign-ins made on the dashboard
83
+ * ```typescript
84
+ * export const MyEnv = Boat.Environment("MyEnv", {
85
+ * credentialProfile: Boat.CredentialProfile.lookup({ name: "default" }),
86
+ * });
87
+ * ```
88
+ *
89
+ * @resource
90
+ * @product Credential Profile
91
+ */
92
+ export const CredentialProfile = Resource("Boat.CredentialProfile");
93
+ /** Props that hold a provider API key, and the credential Boat stores each as. */
94
+ const PROVIDER_KEYS = {
95
+ anthropic: "anthropic-api-key",
96
+ openai: "openai-api-key",
97
+ openrouter: "openrouter-api-key",
98
+ llmgateway: "llmgateway-api-key",
99
+ deepseek: "deepseek-api-key",
100
+ moonshot: "moonshot-api-key",
101
+ mistral: "mistral-api-key",
102
+ xai: "xai-api-key",
103
+ opencode: "opencode-api-key",
104
+ };
105
+ const providerKeys = Object.entries(PROVIDER_KEYS);
106
+ const reveal = (value) => Redacted.isRedacted(value) ? Redacted.value(value) : value;
107
+ /** The profiles of the stack's owner: the organization, or you. */
108
+ const listProfiles = Effect.fn(function* (org) {
109
+ const { profiles } = yield* boat.listCredentialProfiles({});
110
+ return profiles.filter((profile) => isOrgAccount(profile.owner, org));
111
+ });
112
+ const findProfile = Effect.fn(function* (org, match) {
113
+ const profiles = yield* listProfiles(org);
114
+ return (profiles.find((profile) => profile.id === match.credentialProfileId) ??
115
+ profiles.find((profile) => profile.name === match.name));
116
+ });
117
+ const toAttributes = (profile, org) => ({
118
+ credentialProfileId: profile.id,
119
+ name: profile.name,
120
+ org,
121
+ isDefault: profile.isDefault,
122
+ connected: [...profile.connected],
123
+ customApis: [...profile.customApis],
124
+ });
125
+ export const CredentialProfileProvider = () => Provider.effect(CredentialProfile, Effect.gen(function* () {
126
+ return {
127
+ stables: ["credentialProfileId", "org"],
128
+ // A profile belongs to one organization (or to you) for life.
129
+ diff: Effect.fn(function* ({ output }) {
130
+ if (output !== undefined && !sameOrg(output.org, yield* stackOrg)) {
131
+ return { action: "replace" };
132
+ }
133
+ }),
134
+ read: Effect.fn(function* ({ id, olds, output }) {
135
+ const name = output?.name ?? (yield* boatName(id, olds?.name, 64));
136
+ const org = output ? output.org : yield* stackOrg;
137
+ const profile = yield* findProfile(org, {
138
+ credentialProfileId: output?.credentialProfileId,
139
+ name,
140
+ });
141
+ if (profile === undefined)
142
+ return undefined;
143
+ const attrs = toAttributes(profile, org);
144
+ return output !== undefined || isGeneratedName(profile.name) ? attrs : Unowned(attrs);
145
+ }),
146
+ lookup: Effect.fn(function* ({ name }) {
147
+ const org = yield* stackOrg;
148
+ const profile = yield* findProfile(org, { name });
149
+ return profile === undefined ? undefined : toAttributes(profile, org);
150
+ }),
151
+ reconcile: Effect.fn(function* ({ id, news, olds, output, session }) {
152
+ const name = yield* boatName(id, news.name ?? output?.name, 64);
153
+ // A different org replaces (see diff), so this is the org that owns it.
154
+ const org = yield* stackOrg;
155
+ // Observe — by id once we have one (it survives renames), else by name.
156
+ let profile = yield* findProfile(org, {
157
+ credentialProfileId: output?.credentialProfileId,
158
+ name,
159
+ });
160
+ // Ensure — a concurrent create of the same name is a race, not a failure.
161
+ if (profile === undefined) {
162
+ yield* session.note(`Creating credential profile ${name}...`);
163
+ const created = yield* boat
164
+ // Without an `org`, the profile is yours.
165
+ .createCredentialProfile({ name, ...inOrg(org) })
166
+ .pipe(Effect.catchTag("Conflict", () => Effect.succeed(undefined)));
167
+ profile = created?.profile ?? (yield* findProfile(org, { name }));
168
+ if (profile === undefined) {
169
+ return yield* new BoatUnexpectedResponse({
170
+ message: `Boat credential profile ${name} vanished after create`,
171
+ });
172
+ }
173
+ }
174
+ // Sync the name.
175
+ if (profile.name !== name) {
176
+ profile = (yield* boat.updateCredentialProfile({ profile: profile.id, name })).profile;
177
+ }
178
+ // Sync provider keys. Boat never returns a key, so what it holds is
179
+ // observed (`connected`) and the value is compared with the one last
180
+ // deployed. An adopted profile has none, so every key is written.
181
+ for (const [prop, credential] of providerKeys) {
182
+ const value = reveal(news[prop]);
183
+ if (value === undefined) {
184
+ if (profile.connected.includes(credential)) {
185
+ profile =
186
+ (yield* boat
187
+ .deleteCredentialProfileKey({ profile: profile.id, credential })
188
+ .pipe(Effect.catchTag("NotFound", () => Effect.succeed(undefined))))?.profile ??
189
+ profile;
190
+ }
191
+ }
192
+ else if (olds === undefined ||
193
+ !profile.connected.includes(credential) ||
194
+ reveal(olds[prop]) !== value) {
195
+ profile = (yield* boat.setCredentialProfileKey({
196
+ profile: profile.id,
197
+ credential,
198
+ value,
199
+ })).profile;
200
+ }
201
+ }
202
+ // Sync custom APIs, the same way.
203
+ const apis = news.apis ?? {};
204
+ for (const apiName of profile.customApis) {
205
+ if (apiName in apis)
206
+ continue;
207
+ profile =
208
+ (yield* boat
209
+ .deleteCredentialProfileCustomApi({ profile: profile.id, name: apiName })
210
+ .pipe(Effect.catchTag("NotFound", () => Effect.succeed(undefined))))?.profile ??
211
+ profile;
212
+ }
213
+ for (const [apiName, api] of Object.entries(apis)) {
214
+ const old = olds?.apis?.[apiName];
215
+ if (old !== undefined &&
216
+ profile.customApis.includes(apiName) &&
217
+ reveal(old.key) === reveal(api.key) &&
218
+ old.baseUrl === api.baseUrl) {
219
+ continue;
220
+ }
221
+ profile = (yield* boat.setCredentialProfileCustomApi({
222
+ profile: profile.id,
223
+ name: apiName,
224
+ value: reveal(api.key) ?? "",
225
+ baseUrl: api.baseUrl,
226
+ })).profile;
227
+ }
228
+ return toAttributes(profile, org);
229
+ }),
230
+ // An environment that still names the profile fails the delete with
231
+ // Boat's own `in_use`; the engine deletes dependents first.
232
+ delete: Effect.fn(function* ({ output }) {
233
+ yield* boat
234
+ .deleteCredentialProfile({ profile: output.credentialProfileId })
235
+ .pipe(Effect.catchTag("NotFound", () => Effect.void));
236
+ }),
237
+ list: Effect.fn(function* () {
238
+ const org = yield* stackOrg;
239
+ return (yield* listProfiles(org))
240
+ .filter((profile) => isGeneratedName(profile.name))
241
+ .map((profile) => toAttributes(profile, org));
242
+ }),
243
+ };
244
+ }));
245
+ //# sourceMappingURL=CredentialProfile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CredentialProfile.js","sources":["../src/CredentialProfile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { Credentials } from "@distilled.cloud/boat-dev/Credentials";
2
+ import * as Layer from "effect/Layer";
3
+ export { Credentials, CredentialsFromEnv, DEFAULT_API_BASE_URL, fromApiKey, } from "@distilled.cloud/boat-dev/Credentials";
4
+ /**
5
+ * Build Boat `Credentials` that resolve through the Alchemy AuthProvider:
6
+ * `BOAT_API_KEY` (+ `BOAT_ORG`) when set, otherwise the selected profile,
7
+ * whose `org` every call sends as `X-Boat-Org`; `options.org` overrides
8
+ * it. Resolution is
9
+ * deferred until the first API call, so building the provider layers never
10
+ * needs a profile.
11
+ */
12
+ export declare const fromAuthProvider: (options?: {
13
+ readonly org?: string;
14
+ }) => Layer.Layer<Credentials, never, import("alchemy/Auth/Registry").AuthProviders | import("alchemy/Auth/Profile").ProfileStore>;
15
+ //# sourceMappingURL=Credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Credentials.d.ts","sources":["../src/Credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAGpE,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,oBAAoB,EACpB,UAAU,GACX,MAAM,uCAAuC,CAAC;AAE/C;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,aAAc;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,iIAWjE,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { Credentials } from "@distilled.cloud/boat-dev/Credentials";
2
+ import { ConfigError } from "@distilled.cloud/core/errors";
3
+ import { lazyCredentials } from "alchemy/Auth/Resolve";
4
+ import * as Layer from "effect/Layer";
5
+ import { BOAT_AUTH_PROVIDER_NAME } from "./AuthProvider.js";
6
+ export { Credentials, CredentialsFromEnv, DEFAULT_API_BASE_URL, fromApiKey, } from "@distilled.cloud/boat-dev/Credentials";
7
+ /**
8
+ * Build Boat `Credentials` that resolve through the Alchemy AuthProvider:
9
+ * `BOAT_API_KEY` (+ `BOAT_ORG`) when set, otherwise the selected profile,
10
+ * whose `org` every call sends as `X-Boat-Org`; `options.org` overrides
11
+ * it. Resolution is
12
+ * deferred until the first API call, so building the provider layers never
13
+ * needs a profile.
14
+ */
15
+ export const fromAuthProvider = (options) => Layer.effect(Credentials, lazyCredentials()(BOAT_AUTH_PROVIDER_NAME, (creds) => {
16
+ const org = options?.org ?? creds.org;
17
+ return {
18
+ apiKey: creds.apiKey,
19
+ apiBaseUrl: creds.apiBaseUrl,
20
+ ...(org ? { org } : {}),
21
+ };
22
+ }));
23
+ //# sourceMappingURL=Credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Credentials.js","sources":["../src/Credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAgC,MAAM,mBAAmB,CAAC;AAE1F,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,oBAAoB,EACpB,UAAU,GACX,MAAM,uCAAuC,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAmC,EAAE,EAAE,CACtE,KAAK,CAAC,MAAM,CACV,WAAW,EACX,eAAe,EAAwC,CAAC,uBAAuB,EAAE,CAAC,KAAK,EAAE,EAAE;IACzF,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC;IACtC,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxB,CAAC;AACJ,CAAC,CAAC,CACH,CAAC"}