1import { PrismaClient, type PrismaManagementClient } from "@/Prisma/Client";
2import * as Prisma from "@/Prisma/Operations";
3import { describe, expect, it } from "alchemy-test";
4import * as Effect from "effect/Effect";
5import * as Redacted from "effect/Redacted";
6import { Credentials } from "@/Prisma/Credentials";
7
8type AssertNever<T extends never> = T;
9type ClientOperation = Exclude<
10 keyof PrismaManagementClient,
11 "request" | "paginate"
12>;
13export type PrismaOperationCoverage = [
14 AssertNever<Exclude<ClientOperation, keyof typeof Prisma>>,
15 AssertNever<Exclude<keyof typeof Prisma, ClientOperation>>,
16];
17
18const expectedOperationHelpers = [
19 "listWorkspaces",
20 "getWorkspace",
21 "getCurrentPrincipal",
22 "listRegions",
23 "listPostgresRegions",
24 "listAccelerateRegions",
25 "listProjects",
26 "getProject",
27 "createProject",
28 "updateProject",
29 "deleteProject",
30 "transferProject",
31 "listDatabases",
32 "listProjectDatabases",
33 "getDatabase",
34 "createDatabase",
35 "createProjectDatabase",
36 "updateDatabase",
37 "deleteDatabase",
38 "listBackups",
39 "restoreDatabase",
40 "getDatabaseUsage",
41 "listConnections",
42 "listDatabaseConnections",
43 "getConnection",
44 "createConnection",
45 "createDatabaseConnection",
46 "deleteConnection",
47 "rotateConnection",
48 "listBranches",
49 "getBranch",
50 "createBranch",
51 "updateBranch",
52 "deleteBranch",
53 "listBuckets",
54 "getBucket",
55 "createBucket",
56 "deleteBucket",
57 "listBucketKeys",
58 "createBucketKey",
59 "deleteBucketKey",
60 "getCustomDomain",
61 "deleteCustomDomain",
62 "retryCustomDomain",
63 "listApps",
64 "getApp",
65 "createApp",
66 "updateApp",
67 "deleteApp",
68 "promoteApp",
69 "rollbackApp",
70 "listAppDomains",
71 "createAppDomain",
72 "listAppDeployments",
73 "createAppDeployment",
74 "getDeployment",
75 "deleteDeployment",
76 "startDeployment",
77 "stopDeployment",
78 "getDeploymentLogsRequest",
79 "getBuildLogsRequest",
80 "listEnvironmentVariables",
81 "getEnvironmentVariable",
82 "createEnvironmentVariable",
83 "updateEnvironmentVariable",
84 "deleteEnvironmentVariable",
85 "listIntegrations",
86 "listWorkspaceIntegrations",
87 "getIntegration",
88 "deleteIntegration",
89 "revokeWorkspaceIntegration",
90 "listScmInstallations",
91 "createScmInstallIntent",
92 "listScmInstallationRepositories",
93 "listSourceRepositories",
94 "getSourceRepository",
95 "createSourceRepository",
96 "deleteSourceRepository",
97];
98
99describe(
100 "Prisma operation helpers",
101 { tags: ["unit", "provider:prisma", "local"] },
102 () => {
103 it.effect("delegate every public operation helper to PrismaClient", () => {
104 const calls: Array<[string, unknown[]]> = [];
105 const client = new Proxy(
106 {},
107 {
108 get:
109 (_target, prop) =>
110 (...args: unknown[]) =>
111 Effect.sync(() => {
112 calls.push([String(prop), args]);
113 return { ok: true };
114 }),
115 },
116 ) as unknown as PrismaManagementClient;
117
118 return Effect.gen(function* () {
119 yield* Prisma.listWorkspaces({ limit: 1 });
120 yield* Prisma.getWorkspace("workspace-1");
121 yield* Prisma.getCurrentPrincipal();
122 yield* Prisma.listRegions({ product: "postgres" });
123 yield* Prisma.listPostgresRegions();
124 yield* Prisma.listAccelerateRegions();
125
126 yield* Prisma.listProjects({ limit: 1 });
127 yield* Prisma.getProject("project-1");
128 yield* Prisma.createProject({ name: "app" });
129 yield* Prisma.updateProject("project-1", { name: "renamed" });
130 yield* Prisma.deleteProject("project-1");
131 yield* Prisma.transferProject("project-1", {
132 recipientAccessToken: "recipient-token",
133 });
134
135 yield* Prisma.listDatabases({ projectId: "project-1" });
136 yield* Prisma.listProjectDatabases("project-1", { limit: 1 });
137 yield* Prisma.getDatabase("database-1");
138 yield* Prisma.createDatabase({ projectId: "project-1" });
139 yield* Prisma.createProjectDatabase("project-1", {
140 region: "us-east-1",
141 source: {
142 type: "backup",
143 databaseId: "database-source",
144 backupId: "backup-1",
145 },
146 });
147 yield* Prisma.updateDatabase("database-1", { name: "renamed" });
148 yield* Prisma.deleteDatabase("database-1");
149 yield* Prisma.listBackups("database-1", { limit: 1 });
150 yield* Prisma.restoreDatabase("database-1", {
151 source: {
152 type: "backup",
153 databaseId: "source-database",
154 backupId: "backup-1",
155 },
156 });
157 yield* Prisma.getDatabaseUsage("database-1", {
158 startDate: "2026-01-01",
159 endDate: "2026-01-02",
160 });
161
162 yield* Prisma.listConnections({ databaseId: "database-1" });
163 yield* Prisma.listDatabaseConnections("database-1", { limit: 1 });
164 yield* Prisma.getConnection("connection-1");
165 yield* Prisma.createConnection({
166 databaseId: "database-1",
167 name: "api",
168 });
169 yield* Prisma.createDatabaseConnection("database-1", { name: "api" });
170 yield* Prisma.deleteConnection("connection-1");
171 yield* Prisma.rotateConnection("connection-1");
172
173 yield* Prisma.listBranches("project-1", { gitName: "main" });
174 yield* Prisma.getBranch("branch-1");
175 yield* Prisma.createBranch("project-1", { gitName: "main" });
176 yield* Prisma.updateBranch("branch-1", { isDefault: true });
177 yield* Prisma.deleteBranch("branch-1");
178
179 yield* Prisma.listBuckets({ projectId: "project-1" });
180 yield* Prisma.getBucket("bucket-1");
181 yield* Prisma.createBucket({ projectId: "project-1", name: "uploads" });
182 yield* Prisma.deleteBucket("bucket-1");
183 yield* Prisma.listBucketKeys("bucket-1", { limit: 1 });
184 yield* Prisma.createBucketKey("bucket-1", { role: "read_write" });
185 yield* Prisma.deleteBucketKey("bucket-1", "key-1");
186
187 yield* Prisma.getCustomDomain("domain-1");
188 yield* Prisma.deleteCustomDomain("domain-1");
189 yield* Prisma.retryCustomDomain("domain-1");
190
191 yield* Prisma.listApps({ projectId: "project-1" });
192 yield* Prisma.getApp("app-1");
193 yield* Prisma.createApp({ projectId: "project-1", displayName: "web" });
194 yield* Prisma.updateApp("app-1", { displayName: "renamed" });
195 yield* Prisma.deleteApp("app-1");
196 yield* Prisma.promoteApp("app-1", { deploymentId: "deployment-1" });
197 yield* Prisma.rollbackApp("app-1", { deploymentId: "deployment-1" });
198 yield* Prisma.listAppDomains("app-1");
199 yield* Prisma.createAppDomain("app-1", { hostname: "web.example.com" });
200 yield* Prisma.listAppDeployments("app-1", { limit: 1 });
201 yield* Prisma.createAppDeployment("app-1", { skipCodeUpload: true });
202 yield* Prisma.getDeployment("deployment-1");
203 yield* Prisma.deleteDeployment("deployment-1");
204 yield* Prisma.startDeployment("deployment-1");
205 yield* Prisma.stopDeployment("deployment-1");
206 yield* Prisma.getDeploymentLogsRequest("deployment-1", { tail: 10 });
207 yield* Prisma.getBuildLogsRequest("build-1", { follow: true });
208
209 yield* Prisma.listEnvironmentVariables({ projectId: "project-1" });
210 yield* Prisma.getEnvironmentVariable("env-1");
211 yield* Prisma.createEnvironmentVariable({
212 projectId: "project-1",
213 class: "production",
214 key: "TOKEN",
215 value: "secret",
216 });
217 yield* Prisma.updateEnvironmentVariable("env-1", { value: "next" });
218 yield* Prisma.deleteEnvironmentVariable("env-1");
219
220 yield* Prisma.listIntegrations({ workspaceId: "workspace-1" });
221 yield* Prisma.listWorkspaceIntegrations("workspace-1", { limit: 1 });
222 yield* Prisma.getIntegration("integration-1");
223 yield* Prisma.deleteIntegration("integration-1");
224 yield* Prisma.revokeWorkspaceIntegration("workspace-1", "client-1");
225
226 yield* Prisma.listScmInstallations({ workspaceId: "workspace-1" });
227 yield* Prisma.createScmInstallIntent({
228 provider: "github",
229 workspaceId: "workspace-1",
230 });
231 yield* Prisma.listScmInstallationRepositories("scminstall-1", {
232 limit: 10,
233 });
234
235 yield* Prisma.listSourceRepositories({ projectId: "project-1" });
236 yield* Prisma.getSourceRepository("repo-1");
237 yield* Prisma.createSourceRepository({
238 projectId: "project-1",
239 provider: "github",
240 providerRepositoryId: 123,
241 });
242 yield* Prisma.deleteSourceRepository("repo-1");
243
244 expect(Object.keys(Prisma).sort()).toEqual(
245 [...expectedOperationHelpers].sort(),
246 );
247 // The log-request builders resolve the distilled Credentials service
248 // directly instead of delegating to the client, so they never appear in
249 // `calls`.
250 expect(calls.map(([name]) => name)).toEqual(
251 expectedOperationHelpers.filter(
252 (name) =>
253 name !== "getDeploymentLogsRequest" &&
254 name !== "getBuildLogsRequest",
255 ),
256 );
257 }).pipe(
258 Effect.provideService(PrismaClient, client),
259 Effect.provideService(
260 Credentials,
261 Effect.succeed({
262 apiToken: Redacted.make("test-token"),
263 apiBaseUrl: "https://api.prisma.test",
264 }),
265 ),
266 );
267 });
268 },
269);