1import * as Neon from "@/Neon";
2import * as Test from "@/Test/Alchemy";
3import * as SDK from "@distilled.cloud/neon";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import * as HttpClient from "effect/http/HttpClient";
7import BackendEffect from "./fixtures/backend-effect.ts";
8import { backendBranch, backendDataApi } from "./fixtures/backend-resources.ts";
9
10const { test } = Test.make({ providers: Neon.providers() });
11
12test.provider(
13 "native and Effect backend configuration use injected credentials without account keys",
14 (stack) =>
15 Effect.gen(function* () {
16 yield* stack.destroy();
17 const deployed = yield* stack.deploy(
18 Effect.gen(function* () {
19 const branch = yield* backendBranch;
20 const data = yield* backendDataApi;
21 const native = yield* Neon.Function("BackendNative", {
22 branch: { projectId: data.projectId, branchId: data.branchId },
23 main: "./test/Neon/fixtures/backend-native.ts",
24 });
25 const effect = yield* BackendEffect;
26 return { branch, native, effect };
27 }),
28 );
29 const http = yield* HttpClient.HttpClient;
30 const native = yield* http
31 .get(deployed.native.url)
32 .pipe(Effect.flatMap((response) => response.json));
33 const effect = yield* http
34 .get(deployed.effect.url)
35 .pipe(Effect.flatMap((response) => response.json));
36 expect(native).toMatchObject({ hasToken: true, hasDeploymentKey: false });
37 expect(effect).toMatchObject({ hasToken: true });
38 const credentials = yield* SDK.listCredentials({
39 project_id: deployed.branch.projectId,
40 branch_id: deployed.branch.branchId,
41 });
42 expect(
43 credentials.credentials.filter(
44 (item) =>
45 item.principal_type === "user" &&
46 item.branch_id === deployed.branch.branchId &&
47 !item.revoked_at,
48 ),
49 ).toHaveLength(0);
50 const rejected = yield* http
51 .get(`${deployed.effect.url}/data-foreign-origin`)
52 .pipe(Effect.flatMap((response) => response.json));
53 expect(rejected).toEqual({ rejected: true });
54 const unauthorized = yield* http
55 .get(`${deployed.effect.url}/data-invalid-token`)
56 .pipe(Effect.flatMap((response) => response.text));
57 expect(unauthorized).toBe("400");
58 yield* stack.destroy();
59 expect(
60 yield* SDK.getProjectBranch({
61 project_id: deployed.branch.projectId,
62 branch_id: deployed.branch.branchId,
63 }).pipe(
64 Effect.as(false),
65 Effect.catchTag("NotFound", () => Effect.succeed(true)),
66 ),
67 ).toBe(true);
68 yield* stack.destroy();
69 }),
70 {
71 tags: [
72 "provider:neon",
73 "provider:neon:aigateway",
74 "provider:neon:auth",
75 "provider:neon:branch",
76 "provider:neon:dataapi",
77 "provider:neon:function",
78 "provider:neon:project",
79 "live",
80 ],
81 timeout: 120_000,
82 },
83);