@effect/platform 0.69.25 → 0.69.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,7 @@ import * as Effect from "effect/Effect"
6
6
  import { identity } from "effect/Function"
7
7
  import * as Option from "effect/Option"
8
8
  import * as ParseResult from "effect/ParseResult"
9
+ import type * as Predicate from "effect/Predicate"
9
10
  import * as Schema from "effect/Schema"
10
11
  import type * as AST from "effect/SchemaAST"
11
12
  import type { Scope } from "effect/Scope"
@@ -27,15 +28,11 @@ import type { HttpApiMiddleware } from "./index.js"
27
28
  */
28
29
  export type Client<Groups extends HttpApiGroup.Any, ApiError> = Simplify<
29
30
  & {
30
- readonly [Group in Extract<Groups, { readonly topLevel: false }> as HttpApiGroup.Name<Group>]: [Group] extends
31
- [HttpApiGroup<infer _GroupName, infer _Endpoints, infer _GroupError, infer _GroupErrorR>] ? {
32
- readonly [Endpoint in _Endpoints as HttpApiEndpoint.Name<Endpoint>]: Client.Method<
33
- Endpoint,
34
- ApiError,
35
- _GroupError
36
- >
37
- } :
38
- never
31
+ readonly [Group in Extract<Groups, { readonly topLevel: false }> as HttpApiGroup.Name<Group>]: Client.Group<
32
+ Group,
33
+ Group["identifier"],
34
+ ApiError
35
+ >
39
36
  }
40
37
  & {
41
38
  readonly [Method in Client.TopLevelMethods<Groups, ApiError> as Method[0]]: Method[1]
@@ -47,6 +44,21 @@ export type Client<Groups extends HttpApiGroup.Any, ApiError> = Simplify<
47
44
  * @category models
48
45
  */
49
46
  export declare namespace Client {
47
+ /**
48
+ * @since 1.0.0
49
+ * @category models
50
+ */
51
+ export type Group<Groups extends HttpApiGroup.Any, GroupName extends Groups["identifier"], ApiError> =
52
+ [HttpApiGroup.WithName<Groups, GroupName>] extends
53
+ [HttpApiGroup<infer _GroupName, infer _Endpoints, infer _GroupError, infer _GroupErrorR>] ? {
54
+ readonly [Endpoint in _Endpoints as HttpApiEndpoint.Name<Endpoint>]: Method<
55
+ Endpoint,
56
+ ApiError,
57
+ _GroupError
58
+ >
59
+ } :
60
+ never
61
+
50
62
  /**
51
63
  * @since 1.0.0
52
64
  * @category models
@@ -79,18 +91,34 @@ export declare namespace Client {
79
91
  export type TopLevelMethods<Groups extends HttpApiGroup.Any, ApiError> =
80
92
  Extract<Groups, { readonly topLevel: true }> extends
81
93
  HttpApiGroup<infer _Id, infer _Endpoints, infer _Error, infer _ErrorR, infer _TopLevel> ?
82
- _Endpoints extends infer Endpoint ? [HttpApiEndpoint.Name<Endpoint>, Client.Method<Endpoint, ApiError, _Error>]
94
+ _Endpoints extends infer Endpoint ? [HttpApiEndpoint.Name<Endpoint>, Method<Endpoint, ApiError, _Error>]
83
95
  : never :
84
96
  never
85
97
  }
86
98
 
87
99
  /**
88
- * @since 1.0.0
89
- * @category constructors
100
+ * @internal
90
101
  */
91
- export const make = <Groups extends HttpApiGroup.Any, ApiError, ApiR>(
102
+ const makeClient = <Groups extends HttpApiGroup.Any, ApiError, ApiR>(
92
103
  api: HttpApi.HttpApi<Groups, ApiError, ApiR>,
93
- options?: {
104
+ options: {
105
+ readonly predicate?: Predicate.Predicate<{
106
+ readonly endpoint: HttpApiEndpoint.AnyWithProps
107
+ readonly group: HttpApiGroup.AnyWithProps
108
+ }>
109
+ readonly onGroup?: (options: {
110
+ readonly group: HttpApiGroup.AnyWithProps
111
+ readonly mergedAnnotations: Context.Context<never>
112
+ }) => void
113
+ readonly onEndpoint: (options: {
114
+ readonly group: HttpApiGroup.AnyWithProps
115
+ readonly endpoint: HttpApiEndpoint<string, HttpMethod.HttpMethod>
116
+ readonly mergedAnnotations: Context.Context<never>
117
+ readonly middleware: ReadonlySet<HttpApiMiddleware.TagClassAny>
118
+ readonly successes: ReadonlyMap<number, Option.Option<AST.AST>>
119
+ readonly errors: ReadonlyMap<number, Option.Option<AST.AST>>
120
+ readonly endpointFn: Function
121
+ }) => void
94
122
  readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
95
123
  readonly transformResponse?:
96
124
  | ((effect: Effect.Effect<unknown, unknown, Scope>) => Effect.Effect<unknown, unknown, Scope>)
@@ -98,7 +126,7 @@ export const make = <Groups extends HttpApiGroup.Any, ApiError, ApiR>(
98
126
  readonly baseUrl?: string | undefined
99
127
  }
100
128
  ): Effect.Effect<
101
- Simplify<Client<Groups, ApiError>>,
129
+ void,
102
130
  never,
103
131
  HttpApiMiddleware.HttpApiMiddleware.Without<ApiR | HttpApiGroup.ClientContext<Groups>> | HttpClient.HttpClient
104
132
  > =>
@@ -108,13 +136,13 @@ export const make = <Groups extends HttpApiGroup.Any, ApiError, ApiR>(
108
136
  options?.baseUrl === undefined ? identity : HttpClient.mapRequest(HttpClientRequest.prependUrl(options.baseUrl)),
109
137
  options?.transformClient === undefined ? identity : options.transformClient
110
138
  )
111
- const client: Record<string, Record<string, any>> = {}
112
139
  HttpApi.reflect(api as any, {
113
- onGroup({ group }) {
114
- if (group.topLevel) return
115
- client[group.identifier] = {}
140
+ predicate: options?.predicate,
141
+ onGroup(onGroupOptions) {
142
+ options.onGroup?.(onGroupOptions)
116
143
  },
117
- onEndpoint({ endpoint, errors, group, successes }) {
144
+ onEndpoint(onEndpointOptions) {
145
+ const { endpoint, errors, successes } = onEndpointOptions
118
146
  const makeUrl = compilePath(endpoint.path)
119
147
  const decodeMap: Record<
120
148
  number | "orElse",
@@ -146,7 +174,7 @@ export const make = <Groups extends HttpApiGroup.Any, ApiError, ApiR>(
146
174
  const encodeUrlParams = endpoint.urlParamsSchema.pipe(
147
175
  Option.map(Schema.encodeUnknown)
148
176
  )
149
- ;(group.topLevel ? client : client[group.identifier])[endpoint.name] = (request: {
177
+ const endpointFn = (request: {
150
178
  readonly path: any
151
179
  readonly urlParams: any
152
180
  readonly payload: any
@@ -178,7 +206,7 @@ export const make = <Groups extends HttpApiGroup.Any, ApiError, ApiR>(
178
206
  )
179
207
  }
180
208
  const response = yield* httpClient.execute(httpRequest)
181
- const value = yield* (options?.transformResponse === undefined
209
+ const value = yield* (options.transformResponse === undefined
182
210
  ? decodeResponse(response)
183
211
  : options.transformResponse(decodeResponse(response)))
184
212
  return request?.withResponse === true ? [value, response] : value
@@ -187,11 +215,131 @@ export const make = <Groups extends HttpApiGroup.Any, ApiError, ApiR>(
187
215
  Effect.catchIf(ParseResult.isParseError, Effect.die),
188
216
  Effect.mapInputContext((input) => Context.merge(context, input))
189
217
  )
218
+
219
+ options.onEndpoint({
220
+ ...onEndpointOptions,
221
+ endpointFn
222
+ })
190
223
  }
191
224
  })
192
- return client as any
193
225
  })
194
226
 
227
+ /**
228
+ * @since 1.0.0
229
+ * @category constructors
230
+ */
231
+ export const make = <Groups extends HttpApiGroup.Any, ApiError, ApiR>(
232
+ api: HttpApi.HttpApi<Groups, ApiError, ApiR>,
233
+ options?: {
234
+ readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
235
+ readonly transformResponse?:
236
+ | ((effect: Effect.Effect<unknown, unknown, Scope>) => Effect.Effect<unknown, unknown, Scope>)
237
+ | undefined
238
+ readonly baseUrl?: string | undefined
239
+ }
240
+ ): Effect.Effect<
241
+ Simplify<Client<Groups, ApiError>>,
242
+ never,
243
+ HttpApiMiddleware.HttpApiMiddleware.Without<ApiR | HttpApiGroup.ClientContext<Groups>> | HttpClient.HttpClient
244
+ > => {
245
+ const client: Record<string, Record<string, any>> = {}
246
+ return makeClient(api, {
247
+ ...options,
248
+ onGroup({ group }) {
249
+ if (group.topLevel) return
250
+ client[group.identifier] = {}
251
+ },
252
+ onEndpoint({ endpoint, endpointFn, group }) {
253
+ ;(group.topLevel ? client : client[group.identifier])[endpoint.name] = endpointFn
254
+ }
255
+ }).pipe(Effect.map(() => client)) as any
256
+ }
257
+
258
+ /**
259
+ * @since 1.0.0
260
+ * @category constructors
261
+ */
262
+ export const group = <
263
+ Groups extends HttpApiGroup.Any,
264
+ ApiError,
265
+ ApiR,
266
+ const GroupName extends Groups["identifier"]
267
+ >(
268
+ api: HttpApi.HttpApi<Groups, ApiError, ApiR>,
269
+ groupId: GroupName,
270
+ options?: {
271
+ readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
272
+ readonly transformResponse?:
273
+ | ((effect: Effect.Effect<unknown, unknown, Scope>) => Effect.Effect<unknown, unknown, Scope>)
274
+ | undefined
275
+ readonly baseUrl?: string | undefined
276
+ }
277
+ ): Effect.Effect<
278
+ Client.Group<Groups, GroupName, ApiError>,
279
+ never,
280
+ HttpApiMiddleware.HttpApiMiddleware.Without<
281
+ | ApiR
282
+ | HttpApiGroup.ClientContext<
283
+ HttpApiGroup.WithName<Groups, GroupName>
284
+ >
285
+ > | HttpClient.HttpClient
286
+ > => {
287
+ const client: Record<string, any> = {}
288
+ return makeClient(api, {
289
+ ...options,
290
+ predicate: ({ group }) => group.identifier === groupId,
291
+ onEndpoint({ endpoint, endpointFn }) {
292
+ client[endpoint.name] = endpointFn
293
+ }
294
+ }).pipe(Effect.map(() => client)) as any
295
+ }
296
+
297
+ /**
298
+ * @since 1.0.0
299
+ * @category constructors
300
+ */
301
+ export const endpoint = <
302
+ Groups extends HttpApiGroup.Any,
303
+ ApiError,
304
+ ApiR,
305
+ const GroupName extends HttpApiGroup.Name<Groups>,
306
+ const EndpointName extends HttpApiEndpoint.Name<HttpApiGroup.EndpointsWithName<Groups, GroupName>>
307
+ >(
308
+ api: HttpApi.HttpApi<Groups, ApiError, ApiR>,
309
+ groupName: GroupName,
310
+ endpointName: EndpointName,
311
+ options?: {
312
+ readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined
313
+ readonly transformResponse?:
314
+ | ((effect: Effect.Effect<unknown, unknown, Scope>) => Effect.Effect<unknown, unknown, Scope>)
315
+ | undefined
316
+ readonly baseUrl?: string | undefined
317
+ }
318
+ ): Effect.Effect<
319
+ Client.Method<
320
+ HttpApiEndpoint.WithName<HttpApiGroup.Endpoints<HttpApiGroup.WithName<Groups, GroupName>>, EndpointName>,
321
+ HttpApiGroup.Error<HttpApiGroup.WithName<Groups, GroupName>>,
322
+ ApiError
323
+ >,
324
+ never,
325
+ | HttpApiMiddleware.HttpApiMiddleware.Without<
326
+ | ApiR
327
+ | HttpApiGroup.Context<HttpApiGroup.WithName<Groups, GroupName>>
328
+ | HttpApiEndpoint.ContextWithName<HttpApiGroup.EndpointsWithName<Groups, GroupName>, EndpointName>
329
+ | HttpApiEndpoint.ErrorContextWithName<HttpApiGroup.EndpointsWithName<Groups, GroupName>, EndpointName>
330
+ >
331
+ | HttpClient.HttpClient
332
+ > => {
333
+ let client: any = undefined
334
+ return makeClient(api, {
335
+ ...options,
336
+ predicate: ({ endpoint, group }) => group.identifier === groupName && endpoint.name === endpointName,
337
+ onEndpoint({ endpointFn }) {
338
+ client = endpointFn
339
+ }
340
+ }).pipe(Effect.map(() => client)) as any
341
+ }
342
+
195
343
  // ----------------------------------------------------------------------------
196
344
 
197
345
  const paramsRegex = /:(\w+)[^/]*/g
@@ -514,6 +514,12 @@ export declare namespace HttpApiEndpoint {
514
514
  */
515
515
  export type ContextWithName<Endpoints extends Any, Name extends string> = Context<WithName<Endpoints, Name>>
516
516
 
517
+ /**
518
+ * @since 1.0.0
519
+ * @category models
520
+ */
521
+ export type ErrorContextWithName<Endpoints extends Any, Name extends string> = ErrorContext<WithName<Endpoints, Name>>
522
+
517
523
  /**
518
524
  * @since 1.0.0
519
525
  * @category models
@@ -221,7 +221,7 @@ export declare namespace HttpApiGroup {
221
221
  * @since 1.0.0
222
222
  * @category models
223
223
  */
224
- export type Provides<Group extends Any> = HttpApiMiddleware.HttpApiMiddleware.ExtractProvides<Context<Group>>
224
+ export type Provides<Group extends Any> = HttpApiMiddleware.HttpApiMiddleware.ExtractProvides<Middleware<Group>>
225
225
 
226
226
  /**
227
227
  * @since 1.0.0
@@ -234,6 +234,15 @@ export declare namespace HttpApiGroup {
234
234
  * @category models
235
235
  */
236
236
  export type Context<Group> = Group extends
237
+ HttpApiGroup<infer _Name, infer _Endpoints, infer _Error, infer _R, infer _TopLevel> ?
238
+ HttpApiMiddleware.HttpApiMiddleware.Without<_R> :
239
+ never
240
+
241
+ /**
242
+ * @since 1.0.0
243
+ * @category models
244
+ */
245
+ export type Middleware<Group> = Group extends
237
246
  HttpApiGroup<infer _Name, infer _Endpoints, infer _Error, infer _R, infer _TopLevel> ?
238
247
  HttpApiMiddleware.HttpApiMiddleware.Only<_R> :
239
248
  never
@@ -263,6 +272,14 @@ export declare namespace HttpApiGroup {
263
272
  * @category models
264
273
  */
265
274
  export type ContextWithName<Group extends Any, Name extends string> = Context<WithName<Group, Name>>
275
+
276
+ /**
277
+ * @since 1.0.0
278
+ * @category models
279
+ */
280
+ export type MiddlewareWithName<Group extends Any, Name extends string> = Middleware<
281
+ WithName<Group, Name>
282
+ >
266
283
  }
267
284
 
268
285
  const Proto = {