(query: UsageQuery)
| 117 | |
| 118 | export const makeAutumnSurface = (autumnUrl: string): AutumnSurface => { |
| 119 | const usageEvents = (query: UsageQuery) => |
| 120 | Effect.gen(function* () { |
| 121 | // The emulator's ledger endpoint returns every recorded track event; |
| 122 | // filter to this customer + feature. (autumn-js drives /v1/* RPC-style.) |
| 123 | const response = yield* Effect.promise(() => |
| 124 | fetch(`${autumnUrl}/v1/events.list`, { |
| 125 | method: "POST", |
| 126 | headers: { "content-type": "application/json" }, |
| 127 | body: "{}", |
| 128 | }), |
| 129 | ); |
| 130 | if (!response.ok) { |
| 131 | return yield* Effect.fail( |
| 132 | `autumn events.list responded ${response.status}: ${yield* Effect.promise(() => response.text())}`, |
| 133 | ); |
| 134 | } |
| 135 | const body = (yield* Effect.promise(() => response.json())) as { |
| 136 | readonly list?: ReadonlyArray<{ |
| 137 | readonly customer_id: string; |
| 138 | readonly feature_id: string; |
| 139 | readonly value: number; |
| 140 | }>; |
| 141 | }; |
| 142 | return (body.list ?? []) |
| 143 | .filter( |
| 144 | (event) => event.customer_id === query.customerId && event.feature_id === query.featureId, |
| 145 | ) |
| 146 | .map((event) => ({ |
| 147 | customerId: event.customer_id, |
| 148 | featureId: event.feature_id, |
| 149 | value: event.value, |
| 150 | })); |
| 151 | }); |
| 152 | |
| 153 | const customerIds = () => |
| 154 | Effect.gen(function* () { |
no test coverage detected