| 1 | import * as Neon from "@/Neon"; |
| 2 | import * as Effect from "effect/Effect"; |
| 3 | import * as Layer from "effect/Layer"; |
| 4 | import * as Redacted from "effect/Redacted"; |
| 5 | import * as FetchHttpClient from "effect/http/FetchHttpClient"; |
| 6 | import * as HttpClientRequest from "effect/http/HttpClientRequest"; |
| 7 | import * as HttpServerRequest from "effect/http/HttpServerRequest"; |
| 8 | import * as HttpServerResponse from "effect/http/HttpServerResponse"; |
| 9 | import { |
| 10 | backendAuth, |
| 11 | backendBranch, |
| 12 | backendDataApi, |
| 13 | backendGateway, |
| 14 | } from "./backend-resources.ts"; |
| 15 | |
| 16 | const bindings = Layer.mergeAll( |
| 17 | Neon.ConnectAuthHttp, |
| 18 | Neon.QueryDataApiHttp, |
| 19 | Neon.QueryAIGatewayHttp, |
| 20 | ).pipe(Layer.provide(FetchHttpClient.layer)); |
| 21 | |
| 22 | export default class BackendEffect extends Neon.Function<BackendEffect>()( |
| 23 | "BackendEffect", |
| 24 | Effect.gen(function* () { |
| 25 | return { branch: yield* backendBranch, main: import.meta.url }; |
| 26 | }), |
| 27 | Effect.gen(function* () { |
| 28 | const auth = yield* Neon.ConnectAuth(backendAuth); |
| 29 | const data = yield* Neon.QueryDataApi(backendDataApi); |
| 30 | const ai = yield* Neon.QueryAIGateway(backendGateway); |
| 31 | return { |
| 32 | fetch: Effect.gen(function* () { |
| 33 | const request = yield* HttpServerRequest.HttpServerRequest; |
| 34 | if (request.url === "/data-invalid-token") { |
| 35 | const response = yield* data.execute( |
| 36 | HttpClientRequest.get(""), |
| 37 | Redacted.make("invalid-end-user-token"), |
| 38 | ); |
| 39 | return HttpServerResponse.text(String(response.status)); |
| 40 | } |
| 41 | if (request.url === "/data-foreign-origin") { |
| 42 | const rejected = yield* data |
| 43 | .execute( |
| 44 | HttpClientRequest.get("https://example.com/"), |
| 45 | Redacted.make("invalid-end-user-token"), |
| 46 | ) |
| 47 | .pipe( |
| 48 | Effect.as(false), |
| 49 | Effect.catchTag("DataApiRequestError", () => |
| 50 | Effect.succeed(true), |
| 51 | ), |
| 52 | ); |
| 53 | return yield* HttpServerResponse.json({ rejected }); |
| 54 | } |
| 55 | return yield* HttpServerResponse.json({ |
| 56 | authUrl: yield* auth.baseUrl, |
| 57 | jwksUrl: yield* auth.jwksUrl, |
| 58 | dataUrl: yield* data.baseUrl, |
| 59 | aiUrl: yield* ai.baseUrl, |
| 60 | chatUrl: yield* ai.chatBaseUrl, |
| 61 | responsesUrl: yield* ai.responsesBaseUrl, |
| 62 | hasToken: Redacted.value(yield* ai.token).length > 0, |
| 63 | }); |
| 64 | }).pipe(Effect.orDie), |
| 65 | }; |
| 66 | }).pipe(Effect.provide(bindings)), |
| 67 | ) {} |