alchemy 2.0.0-beta.66 → 2.0.0-beta.67

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 (81) hide show
  1. package/bin/exec.js +145 -43
  2. package/bin/exec.js.map +1 -1
  3. package/lib/Cli/commands/_shared.d.ts.map +1 -1
  4. package/lib/Cli/commands/_shared.js +2 -1
  5. package/lib/Cli/commands/_shared.js.map +1 -1
  6. package/lib/Cloudflare/D1/Database.d.ts +1 -1
  7. package/lib/Cloudflare/D1/Database.d.ts.map +1 -1
  8. package/lib/Cloudflare/D1/Database.js +3 -3
  9. package/lib/Cloudflare/D1/Database.js.map +1 -1
  10. package/lib/Cloudflare/DNS/Record.d.ts +3 -1
  11. package/lib/Cloudflare/DNS/Record.d.ts.map +1 -1
  12. package/lib/Cloudflare/DNS/Record.js +23 -4
  13. package/lib/Cloudflare/DNS/Record.js.map +1 -1
  14. package/lib/Prisma/App.d.ts +16 -3
  15. package/lib/Prisma/App.d.ts.map +1 -1
  16. package/lib/Prisma/App.js +16 -3
  17. package/lib/Prisma/App.js.map +1 -1
  18. package/lib/Prisma/Branch.d.ts +21 -0
  19. package/lib/Prisma/Branch.d.ts.map +1 -1
  20. package/lib/Prisma/Branch.js +20 -0
  21. package/lib/Prisma/Branch.js.map +1 -1
  22. package/lib/Prisma/Compute.d.ts +6 -4
  23. package/lib/Prisma/Compute.d.ts.map +1 -1
  24. package/lib/Prisma/Compute.js +6 -4
  25. package/lib/Prisma/Compute.js.map +1 -1
  26. package/lib/Prisma/Connect.d.ts +23 -0
  27. package/lib/Prisma/Connect.d.ts.map +1 -1
  28. package/lib/Prisma/Connect.js.map +1 -1
  29. package/lib/Prisma/Connection.d.ts +23 -6
  30. package/lib/Prisma/Connection.d.ts.map +1 -1
  31. package/lib/Prisma/Connection.js +19 -5
  32. package/lib/Prisma/Connection.js.map +1 -1
  33. package/lib/Prisma/CustomDomain.d.ts +11 -1
  34. package/lib/Prisma/CustomDomain.d.ts.map +1 -1
  35. package/lib/Prisma/CustomDomain.js +9 -0
  36. package/lib/Prisma/CustomDomain.js.map +1 -1
  37. package/lib/Prisma/Database.d.ts +18 -4
  38. package/lib/Prisma/Database.d.ts.map +1 -1
  39. package/lib/Prisma/Database.js +15 -2
  40. package/lib/Prisma/Database.js.map +1 -1
  41. package/lib/Prisma/Deployment.d.ts +8 -2
  42. package/lib/Prisma/Deployment.d.ts.map +1 -1
  43. package/lib/Prisma/Deployment.js +6 -1
  44. package/lib/Prisma/Deployment.js.map +1 -1
  45. package/lib/Prisma/EnvironmentVariable.d.ts +20 -4
  46. package/lib/Prisma/EnvironmentVariable.d.ts.map +1 -1
  47. package/lib/Prisma/EnvironmentVariable.js +20 -4
  48. package/lib/Prisma/EnvironmentVariable.js.map +1 -1
  49. package/lib/Prisma/Postgres.d.ts +3 -2
  50. package/lib/Prisma/Postgres.d.ts.map +1 -1
  51. package/lib/Prisma/Postgres.js +3 -2
  52. package/lib/Prisma/Postgres.js.map +1 -1
  53. package/lib/Prisma/Project.d.ts +8 -2
  54. package/lib/Prisma/Project.d.ts.map +1 -1
  55. package/lib/Prisma/Project.js +5 -0
  56. package/lib/Prisma/Project.js.map +1 -1
  57. package/lib/Prisma/Providers.d.ts +5 -3
  58. package/lib/Prisma/Providers.d.ts.map +1 -1
  59. package/lib/Prisma/Providers.js +31 -7
  60. package/lib/Prisma/Providers.js.map +1 -1
  61. package/lib/Prisma/SourceRepository.d.ts +24 -1
  62. package/lib/Prisma/SourceRepository.d.ts.map +1 -1
  63. package/lib/Prisma/SourceRepository.js +18 -0
  64. package/lib/Prisma/SourceRepository.js.map +1 -1
  65. package/package.json +1 -1
  66. package/src/Cli/commands/_shared.ts +2 -0
  67. package/src/Cloudflare/D1/Database.ts +18 -3
  68. package/src/Cloudflare/DNS/Record.ts +30 -4
  69. package/src/Prisma/App.ts +16 -3
  70. package/src/Prisma/Branch.ts +21 -0
  71. package/src/Prisma/Compute.ts +6 -4
  72. package/src/Prisma/Connect.ts +23 -0
  73. package/src/Prisma/Connection.ts +23 -6
  74. package/src/Prisma/CustomDomain.ts +11 -1
  75. package/src/Prisma/Database.ts +18 -4
  76. package/src/Prisma/Deployment.ts +8 -2
  77. package/src/Prisma/EnvironmentVariable.ts +20 -4
  78. package/src/Prisma/Postgres.ts +3 -2
  79. package/src/Prisma/Project.ts +8 -2
  80. package/src/Prisma/Providers.ts +67 -7
  81. package/src/Prisma/SourceRepository.ts +24 -1
package/src/Prisma/App.ts CHANGED
@@ -92,13 +92,26 @@ export interface App extends Resource<
92
92
  /**
93
93
  * A Prisma App, the long-lived application configuration that owns deployments.
94
94
  *
95
+ * Omit `branchId` and `branchGitName` to attach the App to the project's
96
+ * current default branch. App regions are immutable; create a second App and
97
+ * cut traffic over when moving regions. Use `Prisma.Compute` for the usual
98
+ * build, deployment, health-check, and promotion workflow; use `App` directly
99
+ * when managing standalone `Prisma.Deployment` resources.
100
+ *
95
101
  * @resource
96
102
  * @section Creating an App
97
- * @example App attached to a branch
103
+ * @example App on the default branch
98
104
  * ```typescript
99
105
  * const app = yield* Prisma.App("web", {
100
- * project: project.projectId,
101
- * branchGitName: "main",
106
+ * project,
107
+ * });
108
+ * ```
109
+ *
110
+ * @example App on a preview branch
111
+ * ```typescript
112
+ * const app = yield* Prisma.App("preview-web", {
113
+ * project,
114
+ * branchId: preview.branchId,
102
115
  * });
103
116
  * ```
104
117
  */
@@ -35,6 +35,7 @@ export interface BranchProps {
35
35
  * Promote this branch to be the project's default branch. Setting this to
36
36
  * `false` does not demote a current default because the Management API only
37
37
  * supports promotion; promoting another branch atomically demotes it.
38
+ * Promotion changes `isDefault`, not the branch's immutable `preview` role.
38
39
  *
39
40
  * @default false
40
41
  */
@@ -86,6 +87,10 @@ export interface Branch extends Resource<
86
87
  /**
87
88
  * A Prisma project branch for preview-class databases and compute resources.
88
89
  *
90
+ * Standalone Branch resources always have the `preview` role. Promotion
91
+ * changes only the default branch; Alchemy restores the previous default
92
+ * before deleting a promoted branch.
93
+ *
89
94
  * @resource
90
95
  * @section Creating a Branch
91
96
  * @example Preview branch
@@ -94,6 +99,22 @@ export interface Branch extends Resource<
94
99
  * project: project.projectId,
95
100
  * gitName: "feature/search", // optional — omitted, a stable name is generated
96
101
  * });
102
+ *
103
+ * branch.role; // "preview"
104
+ * branch.isDefault; // false
105
+ * ```
106
+ *
107
+ * @section Promoting a Branch
108
+ * @example Make a preview branch the default
109
+ * ```typescript
110
+ * const release = yield* Prisma.Branch("release", {
111
+ * project,
112
+ * gitName: "release/next",
113
+ * isDefault: true,
114
+ * });
115
+ *
116
+ * release.role; // still "preview"
117
+ * release.isDefault; // true
97
118
  * ```
98
119
  */
99
120
  export const Branch = Resource<Branch>("Prisma.Branch");
@@ -545,7 +545,7 @@ const isEffectNativeCompute = (props: ComputeProps) =>
545
545
  hasEffectNativeComputeInput(props);
546
546
 
547
547
  /**
548
- * A Prisma Compute deployment resource.
548
+ * Build and deploy an application to Prisma Compute.
549
549
  *
550
550
  * Prisma's create-deployment API exposes neither an idempotency key nor a
551
551
  * caller-defined recovery key. If the API commits a deployment but its create
@@ -578,7 +578,7 @@ const isEffectNativeCompute = (props: ComputeProps) =>
578
578
  * },
579
579
  * Effect.gen(function* () {
580
580
  * return {
581
- * fetch: HttpServerResponse.text("ok"),
581
+ * fetch: Effect.succeed(HttpServerResponse.text("ok")),
582
582
  * };
583
583
  * }),
584
584
  * );
@@ -601,7 +601,7 @@ const isEffectNativeCompute = (props: ComputeProps) =>
601
601
  * return {
602
602
  * fetch: Effect.gen(function* () {
603
603
  * const users = yield* sql`SELECT * FROM users`;
604
- * return HttpServerResponse.json(users);
604
+ * return yield* HttpServerResponse.json(users);
605
605
  * }),
606
606
  * };
607
607
  * }).pipe(Effect.provide(Prisma.ConnectBinding)),
@@ -620,7 +620,9 @@ const isEffectNativeCompute = (props: ComputeProps) =>
620
620
  * },
621
621
  * port: 8080,
622
622
  * env: {
623
- * DATABASE_URL: database.directConnectionString,
623
+ * // Use this for a standalone Connection. A project's default database
624
+ * // is injected by Prisma without an explicit DATABASE_URL entry.
625
+ * DATABASE_URL: connection.databaseUrl,
624
626
  * },
625
627
  * destroyOldDeployment: true,
626
628
  * });
@@ -85,6 +85,29 @@ export interface ConnectClient {
85
85
  * Context tag, its type, and the callable —
86
86
  * `yield* Prisma.Connect(connection)`.
87
87
  *
88
+ * Provide `Prisma.ConnectBinding` on the host implementation so Alchemy can
89
+ * register the deploy-time binding and resolve the client at runtime.
90
+ *
91
+ * @section Binding a Connection
92
+ * @example Use a connection inside Prisma Compute
93
+ * ```typescript
94
+ * export default Prisma.Compute(
95
+ * "api",
96
+ * { project, main: import.meta.filename },
97
+ * Effect.gen(function* () {
98
+ * const db = yield* Prisma.Connect(connection);
99
+ * const sql = yield* SQL.Postgres({ url: db.databaseUrl });
100
+ *
101
+ * return {
102
+ * fetch: Effect.gen(function* () {
103
+ * const users = yield* sql`SELECT * FROM users`;
104
+ * return yield* HttpServerResponse.json(users);
105
+ * }),
106
+ * };
107
+ * }).pipe(Effect.provide(Prisma.ConnectBinding)),
108
+ * );
109
+ * ```
110
+ *
88
111
  * @binding
89
112
  */
90
113
  export interface Connect extends Binding.Service<
@@ -47,7 +47,10 @@ export interface ConnectionProps {
47
47
  */
48
48
  name?: string;
49
49
  /**
50
- * Rotate credentials during the next update while keeping the connection ID.
50
+ * Rotate credentials when this value changes from `false` to `true` while
51
+ * keeping the connection ID. Prisma revokes the previous credentials on a
52
+ * best-effort basis. Deploy `false` before changing back to `true` for a
53
+ * later rotation.
51
54
  *
52
55
  * @default false
53
56
  */
@@ -129,6 +132,11 @@ export interface Connection extends Resource<
129
132
  /**
130
133
  * A Prisma database connection/API key.
131
134
  *
135
+ * Prisma returns connection credentials only when it creates or rotates a
136
+ * connection. Alchemy stores those outputs as `Redacted` values. Changing the
137
+ * database or name replaces the connection; changing `rotate` from `false` to
138
+ * `true` keeps the connection ID and requests fresh credentials.
139
+ *
132
140
  * @section Creating a Connection
133
141
  * @example Application connection
134
142
  * ```typescript
@@ -146,8 +154,7 @@ export interface Connection extends Resource<
146
154
  *
147
155
  * const app = yield* Prisma.Compute("api", {
148
156
  * project,
149
- * appName: "api",
150
- * main: import.meta.filename,
157
+ * path: "./apps/api",
151
158
  * env: {
152
159
  * DATABASE_URL: connection.databaseUrl,
153
160
  * DIRECT_URL: connection.directConnectionString,
@@ -195,19 +202,29 @@ export interface Connection extends Resource<
195
202
  * ```typescript
196
203
  * export default Cloudflare.Worker(
197
204
  * "api",
198
- * { main: import.meta.filename },
205
+ * { main: import.meta.filename, compatibility: { flags: ["nodejs_compat"] } },
199
206
  * Effect.gen(function* () {
200
207
  * const db = yield* Prisma.Connect(connection);
208
+ * const sql = yield* SQL.Postgres({ url: db.databaseUrl });
201
209
  * return {
202
210
  * fetch: Effect.gen(function* () {
203
- * const databaseUrl = yield* db.databaseUrl;
204
- * return yield* HttpServerResponse.text("connected");
211
+ * const result = yield* sql`SELECT 1 AS ok`;
212
+ * return yield* HttpServerResponse.json(result);
205
213
  * }),
206
214
  * };
207
215
  * }).pipe(Effect.provide(Prisma.ConnectBinding)),
208
216
  * );
209
217
  * ```
210
218
  *
219
+ * @section Rotating Credentials
220
+ * @example Request one rotation
221
+ * ```typescript
222
+ * const connection = yield* Prisma.Connection("api", {
223
+ * database,
224
+ * rotate: true,
225
+ * });
226
+ * ```
227
+ *
211
228
  * @section Connecting over Hyperdrive
212
229
  * @example Front Prisma Postgres with Cloudflare Hyperdrive
213
230
  * ```typescript
@@ -25,7 +25,8 @@ type AppReference = string | App | Compute;
25
25
 
26
26
  export interface CustomDomainProps {
27
27
  /**
28
- * App ID or Compute output that owns the domain.
28
+ * App ID or Compute output that owns the domain. The App must be attached to
29
+ * the project's current default branch.
29
30
  */
30
31
  app: AppReference;
31
32
  /**
@@ -90,6 +91,15 @@ export interface CustomDomain extends Resource<
90
91
  /**
91
92
  * A Prisma app custom domain.
92
93
  *
94
+ * Domains can only attach to Apps on the project's current default branch.
95
+ * Creating this resource starts asynchronous DNS and certificate provisioning;
96
+ * configure the returned `dnsRecords` and inspect `status`, `foundryStatus`,
97
+ * and `failureReason` before routing production traffic.
98
+ *
99
+ * App and hostname changes are intentionally rejected because the Management
100
+ * API cannot replace a live domain atomically. Create a second resource,
101
+ * verify DNS and TLS, cut traffic over, and then remove the old resource.
102
+ *
93
103
  * @resource
94
104
  * @section Creating a Custom Domain
95
105
  * @example Attach a hostname to an app
@@ -150,8 +150,9 @@ export interface DatabaseProps {
150
150
  dev?: false | DatabaseDev;
151
151
  /**
152
152
  * Rotate the adopted database's default connection to recover its one-time
153
- * credentials. Rotation revokes the previous key and may interrupt existing
154
- * consumers, so adoption leaves credentials unset unless explicitly opted in.
153
+ * credentials. Prisma revokes the previous key on a best-effort basis and
154
+ * rotation may interrupt existing consumers, so adoption leaves credentials
155
+ * unset unless explicitly opted in.
155
156
  *
156
157
  * @default false
157
158
  */
@@ -230,17 +231,30 @@ export interface Database extends Resource<
230
231
  /**
231
232
  * A Prisma Postgres database inside a Prisma project.
232
233
  *
234
+ * Standalone `Prisma.Database` resources cannot be the project's default
235
+ * database. Use `Prisma.Project` when the project should own a default
236
+ * database. Project, region, and source changes require replacement; display
237
+ * name and branch attachment can converge in place. Destroying this resource
238
+ * deletes its database and data.
239
+ *
233
240
  * @resource
234
241
  * @section Creating a Database
235
242
  * @example Database in a project
236
243
  * ```typescript
237
244
  * const project = yield* Prisma.Project("app", { createDatabase: false });
238
245
  * const database = yield* Prisma.Database("db", {
239
- * project: project.projectId,
240
- * name: "production",
246
+ * project,
241
247
  * region: "us-east-1",
242
248
  * });
243
249
  * ```
250
+ *
251
+ * @example Database attached to a preview branch
252
+ * ```typescript
253
+ * const database = yield* Prisma.Database("preview-db", {
254
+ * project,
255
+ * branchId: preview.branchId,
256
+ * });
257
+ * ```
244
258
  */
245
259
  export const Database = Resource<Database>("Prisma.Database");
246
260
 
@@ -55,7 +55,8 @@ export interface DeploymentProps {
55
55
  */
56
56
  portMapping?: { http?: number | null };
57
57
  /**
58
- * Create the deployment by reusing the latest artifact instead of uploading code.
58
+ * Create the deployment by reusing the App's currently promoted artifact
59
+ * instead of uploading code. Requires an existing promoted deployment.
59
60
  */
60
61
  skipCodeUpload?: boolean;
61
62
  /**
@@ -128,6 +129,11 @@ export interface Deployment extends Resource<
128
129
  /**
129
130
  * A Prisma deployment owned by an App.
130
131
  *
132
+ * This is the low-level resource: it can upload or reuse an artifact, start it,
133
+ * and promote it, but it does not provide `Prisma.Compute`'s preview/stable
134
+ * health checks or automatic rollback. Prefer `Prisma.Compute` for production
135
+ * application deployments.
136
+ *
131
137
  * Prisma's create-deployment API currently exposes neither an idempotency key
132
138
  * nor a caller-defined natural key. After a crash that loses state immediately
133
139
  * after creation, Alchemy deliberately does not adopt the App's latest
@@ -137,7 +143,7 @@ export interface Deployment extends Resource<
137
143
  *
138
144
  * @resource
139
145
  * @section Creating a Deployment
140
- * @example Fork the latest uploaded artifact
146
+ * @example Fork the currently promoted artifact
141
147
  * ```typescript
142
148
  * const deployment = yield* Prisma.Deployment("web-v2", {
143
149
  * app: app.appId,
@@ -97,15 +97,31 @@ export interface EnvironmentVariable extends Resource<
97
97
  /**
98
98
  * A Prisma compute environment variable.
99
99
  *
100
+ * Values are write-only in Prisma. Alchemy stores them as `Redacted` values
101
+ * and reapplies the desired value to repair drift.
102
+ *
100
103
  * @resource
101
104
  * @section Creating a Variable
102
- * @example Production secret
105
+ * @example Project-level production variable
103
106
  * ```typescript
104
- * yield* Prisma.EnvironmentVariable("database-url", {
107
+ * yield* Prisma.EnvironmentVariable("api-url", {
105
108
  * project: project.projectId,
109
+ * // No branchId: this is a project-level template.
106
110
  * class: "production",
107
- * key: "DATABASE_URL",
108
- * value: Redacted.make("postgres://..."),
111
+ * key: "API_URL",
112
+ * value: Redacted.make("https://api.example.com"),
113
+ * });
114
+ * ```
115
+ *
116
+ * @example Preview branch override
117
+ * ```typescript
118
+ * yield* Prisma.EnvironmentVariable("preview-api-url", {
119
+ * project,
120
+ * branchId: preview.branchId,
121
+ * // Branch overrides always use the preview class.
122
+ * class: "preview",
123
+ * key: "API_URL",
124
+ * value: Redacted.make("https://preview.example.com"),
109
125
  * });
110
126
  * ```
111
127
  */
@@ -6,14 +6,15 @@ import { Database } from "./Database.ts";
6
6
  * `Prisma.Postgres(...)` and `Prisma.Database(...)` use the same underlying
7
7
  * Prisma Postgres resource provider. Prefer `Postgres` when you want the code
8
8
  * to read like the Prisma product name, and `Database` when you want to mirror
9
- * the Management API route names.
9
+ * the Management API route names. Like `Database`, this standalone resource
10
+ * cannot be the project's default database; use `Prisma.Project` to own the
11
+ * default.
10
12
  *
11
13
  * @example
12
14
  * ```typescript
13
15
  * const project = yield* Prisma.Project("app", { createDatabase: false });
14
16
  * const postgres = yield* Prisma.Postgres("db", {
15
17
  * project,
16
- * name: "main",
17
18
  * region: "us-east-1",
18
19
  * });
19
20
  * ```
@@ -54,8 +54,9 @@ export interface ProjectProps {
54
54
  settings?: Record<string, unknown>;
55
55
  /**
56
56
  * Rotate the adopted default database connection to recover its one-time
57
- * credentials. Rotation revokes the previous key and may interrupt existing
58
- * consumers, so adoption leaves credentials unset unless explicitly opted in.
57
+ * credentials. Prisma revokes the previous key on a best-effort basis and
58
+ * rotation may interrupt existing consumers, so adoption leaves credentials
59
+ * unset unless explicitly opted in.
59
60
  *
60
61
  * @default false
61
62
  */
@@ -126,6 +127,11 @@ export interface Project extends Resource<
126
127
  /**
127
128
  * A Prisma project, optionally with a default Prisma Postgres database.
128
129
  *
130
+ * A Project is the ownership boundary for its databases, branches, apps, and
131
+ * repository link. Destroying this resource deletes the project and its
132
+ * contained data. Set `createDatabase: false` when you want standalone
133
+ * `Prisma.Database` resources with independent lifecycles.
134
+ *
129
135
  * @resource
130
136
  * @section Creating a Project
131
137
  * @example Project with a default database
@@ -1,3 +1,4 @@
1
+ import * as Context from "effect/Context";
1
2
  import * as Effect from "effect/Effect";
2
3
  import * as Layer from "effect/Layer";
3
4
  import type * as Path from "effect/Path";
@@ -7,18 +8,24 @@ import type { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSp
7
8
  import { AlchemyContext } from "../AlchemyContext.ts";
8
9
  import { AuthProviders } from "../Auth/AuthProvider.ts";
9
10
  import { CredentialsStoreLive } from "../Auth/Credentials.ts";
10
- import { ProfileLive } from "../Auth/Profile.ts";
11
+ import { AlchemyProfile, ProfileLive } from "../Auth/Profile.ts";
11
12
  import * as Provider from "../Provider.ts";
12
13
  import type { ResourceClass, ResourceLike } from "../Resource.ts";
13
14
  import { PlatformServices } from "../Util/PlatformServices.ts";
15
+ import { proxyChain } from "../Util/proxy-chain.ts";
14
16
  import { PrismaAuth } from "./AuthProvider.ts";
15
17
  import { App, AppProvider } from "./App.ts";
16
18
  import { Branch, BranchProvider } from "./Branch.ts";
17
- import { Compute, ComputeDevProvider, ComputeProvider } from "./Compute.ts";
18
- import { Deployment, DeploymentProvider } from "./Deployment.ts";
19
+ import {
20
+ PrismaClient,
21
+ PrismaClientLive,
22
+ type PrismaManagementClient,
23
+ } from "./Client.ts";
19
24
  import { Connection, ConnectionProvider } from "./Connection.ts";
25
+ import { Compute, ComputeDevProvider, ComputeProvider } from "./Compute.ts";
20
26
  import { CustomDomain, CustomDomainProvider } from "./CustomDomain.ts";
21
27
  import { Database, DatabaseProvider } from "./Database.ts";
28
+ import { Deployment, DeploymentProvider } from "./Deployment.ts";
22
29
  import {
23
30
  EnvironmentVariable,
24
31
  EnvironmentVariableProvider,
@@ -28,7 +35,6 @@ import {
28
35
  closePrismaDevDatabase,
29
36
  ensurePrismaDevDatabase,
30
37
  } from "./PrismaDevDatabase.ts";
31
- import { PrismaClientLive } from "./Client.ts";
32
38
  import {
33
39
  PrismaHttpClientLive,
34
40
  PrismaUploadClientLive,
@@ -48,7 +54,12 @@ export class Providers extends Provider.ProviderCollection<Providers>()(
48
54
 
49
55
  export type ProviderRequirements = Layer.Services<ReturnType<typeof providers>>;
50
56
 
51
- const managementApiLayer = () =>
57
+ /**
58
+ * Standalone operation helpers own a private auth registry because they run
59
+ * outside a Stack. Credential resolution stays eager here so constructing
60
+ * `managementApi()` preserves its existing fail-fast behavior.
61
+ */
62
+ const standaloneManagementApiLayer = () =>
52
63
  PrismaClientLive.pipe(
53
64
  Layer.provideMerge(fromProfile()),
54
65
  Layer.provideMerge(PrismaAuth),
@@ -71,6 +82,54 @@ const managementApiLayer = () =>
71
82
  Layer.provide(PrismaHttpClientLive),
72
83
  );
73
84
 
85
+ /**
86
+ * Stack provider discovery must register auth without requiring credentials.
87
+ * The management client is resolved on its first API operation, after
88
+ * `alchemy login` has had a chance to configure the registered Prisma auth
89
+ * provider. The nested client layer shares the provider layer's lifetime.
90
+ */
91
+ const stackManagementApiLayer = () =>
92
+ Layer.effect(
93
+ PrismaClient,
94
+ Effect.gen(function* () {
95
+ const scope = yield* Effect.scope;
96
+ const authProviders = yield* AuthProviders;
97
+ const profile = yield* AlchemyProfile;
98
+ const client = Layer.buildWithScope(
99
+ PrismaClientLive.pipe(
100
+ Layer.provideMerge(
101
+ fromProfile().pipe(
102
+ Layer.provide(
103
+ Layer.mergeAll(
104
+ Layer.succeed(AuthProviders, authProviders),
105
+ Layer.succeed(AlchemyProfile, profile),
106
+ ),
107
+ ),
108
+ ),
109
+ ),
110
+ Layer.provide(PrismaHttpClientLive),
111
+ ),
112
+ scope,
113
+ ).pipe(
114
+ Effect.map((context) => Context.get(context, PrismaClient)),
115
+ Effect.orDie,
116
+ );
117
+ const cached = yield* Effect.cached(client);
118
+ return proxyChain(cached) as PrismaManagementClient;
119
+ }),
120
+ ).pipe(
121
+ Layer.provideMerge(PrismaAuth),
122
+ Layer.provideMerge(
123
+ Layer.mergeAll(
124
+ // The Prisma-scoped upload client (node transport) rides the
125
+ // providers' output so artifact uploads can reach it at op time.
126
+ PrismaUploadClientLive,
127
+ Layer.provide(ProfileLive, PlatformServices),
128
+ Layer.provide(CredentialsStoreLive, PlatformServices),
129
+ ),
130
+ ),
131
+ );
132
+
74
133
  /**
75
134
  * Build a layer for Prisma Management API operation helpers.
76
135
  *
@@ -88,7 +147,8 @@ const managementApiLayer = () =>
88
147
  * );
89
148
  * ```
90
149
  */
91
- export const managementApi = () => managementApiLayer().pipe(Layer.orDie);
150
+ export const managementApi = () =>
151
+ standaloneManagementApiLayer().pipe(Layer.orDie);
92
152
 
93
153
  /**
94
154
  * Build a layer that registers all Prisma Management API resource providers,
@@ -408,4 +468,4 @@ const liveProviderLayer = () =>
408
468
  CustomDomainProvider(),
409
469
  EnvironmentVariableProvider(),
410
470
  SourceRepositoryProvider(),
411
- ).pipe(Layer.provideMerge(managementApiLayer()), Layer.orDie);
471
+ ).pipe(Layer.provideMerge(stackManagementApiLayer()), Layer.orDie);
@@ -38,7 +38,12 @@ export interface SourceRepositoryProps {
38
38
  */
39
39
  provider?: "github";
40
40
  /**
41
- * Numeric provider repository ID.
41
+ * GitHub's permanent numeric repository ID, not `owner/repo`, a Prisma
42
+ * project ID, or an SCM installation ID. Retrieve it with:
43
+ *
44
+ * ```bash
45
+ * gh api repos/OWNER/REPO --jq '.id'
46
+ * ```
42
47
  */
43
48
  providerRepositoryId: number;
44
49
  /**
@@ -104,6 +109,12 @@ export interface SourceRepository extends Resource<
104
109
  /**
105
110
  * A linked source repository for Prisma apps.
106
111
  *
112
+ * GitHub is currently the only supported provider. Linking requires an
113
+ * existing Prisma SCM installation. `providerRepositoryId` is GitHub's
114
+ * permanent numeric repository ID; retrieve it with
115
+ * `gh api repos/OWNER/REPO --jq '.id'`. When `installationId` is omitted,
116
+ * Prisma selects the workspace installation.
117
+ *
107
118
  * Linking creates or renames the repository-owned default branch. Observe
108
119
  * that branch through the Management API; do not declare it again as a
109
120
  * separate `Prisma.Branch` resource. Use this resource's outputs to order
@@ -111,12 +122,24 @@ export interface SourceRepository extends Resource<
111
122
  * Deleting the link does not roll those side effects back: existing branches,
112
123
  * databases, and apps remain in the project.
113
124
  *
125
+ * The project, repository ID, provider, and installation form an immutable
126
+ * link identity. Alchemy refuses an automatic relink because unlinking cannot
127
+ * roll back branch and resource attachments. Existing links require explicit
128
+ * adoption.
129
+ *
114
130
  * @resource
131
+ * @section Finding the Repository ID
132
+ * @example Read the numeric GitHub repository ID
133
+ * ```bash
134
+ * gh api repos/OWNER/REPO --jq '.id'
135
+ * ```
136
+ *
115
137
  * @section Linking a Repository
116
138
  * @example GitHub repository
117
139
  * ```typescript
118
140
  * const repo = yield* Prisma.SourceRepository("repo", {
119
141
  * project: project.projectId,
142
+ * // Replace with the value returned by the GitHub command above.
120
143
  * providerRepositoryId: 123456789,
121
144
  * });
122
145
  * const database = yield* Prisma.Database("database", {