1import { GetProduct } from "@distilled.cloud/stripe/stripe";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Binding from "../Binding.ts";
5import type { ResourceLike } from "../Resource.ts";
6import type { Product } from "./Product.ts";
7import { RetrieveProduct } from "./RetrieveProduct.ts";
8import {
9 asStringEffect,
10 attachStripeToken,
11 authorizeWith,
12 resolveStripeAuth,
13} from "./StripeHttp.ts";
14
15type ProductInput = string | Product;
16
17/**
18 * HTTP implementation of {@link RetrieveProduct}. Provide it on the
19 * Function or Worker Effect. Accepts a Product resource, a `prod_…` id
20 * string, or an Effect resolving to a Product.
21 *
22 * @layer
23 * @product Product
24 * @provides Stripe.RetrieveProduct
25 */
26export const RetrieveProductHttp = Layer.effect(
27 RetrieveProduct,
28 Effect.gen(function* () {
29 const ambient = yield* resolveStripeAuth;
30
31 return Effect.fn(function* (product: ProductInput) {
32 const host = yield* Binding.Host;
33 const isId = typeof product === "string";
34 const resource = isId ? undefined : (product as unknown as ResourceLike);
35 const bound = yield* attachStripeToken(
36 resource,
37 ["products_read"],
38 "Stripe.RetrieveProduct",
39 );
40 const id = yield* asStringEffect(
41 isId ? product : (product as Product).id,
42 );
43 const auth =
44 host !== undefined ? authorizeWith(bound) : ambient.authorize;
45 const label = isId ? product : (product as Product).LogicalId;
46
47 return Effect.fn(`Stripe.RetrieveProduct(${label})`)(
48 function* (request?: { expand?: string[] }) {
49 return yield* auth(
50 GetProduct({
51 ...(request ?? {}),
52 id: yield* id,
53 }),
54 );
55 },
56 );
57 });
58 }),
59);