effect-app 2.35.0 → 2.36.1
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.
- package/CHANGELOG.md +12 -0
- package/dist/Array.d.ts +1 -1
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +1 -1
- package/dist/Config/SecretURL.d.ts +1 -2
- package/dist/Config/SecretURL.d.ts.map +1 -1
- package/dist/Config/SecretURL.js +4 -1
- package/dist/Context.d.ts +1 -2
- package/dist/Context.d.ts.map +1 -1
- package/dist/Context.js +1 -1
- package/dist/Effect.d.ts +1 -2
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +1 -1
- package/dist/Inputify.type.d.ts.map +1 -1
- package/dist/NonEmptySetBase.d.ts +1 -2
- package/dist/NonEmptySetBase.d.ts.map +1 -1
- package/dist/NonEmptySetBase.js +1 -1
- package/dist/Option.d.ts +1 -1
- package/dist/Option.d.ts.map +1 -1
- package/dist/Option.js +5 -1
- package/dist/Schema/brand.d.ts.map +1 -1
- package/dist/Schema/brand.js +1 -1
- package/dist/Schema/ext.d.ts +1 -2
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/ext.js +3 -1
- package/dist/Schema/moreStrings.d.ts +1 -1
- package/dist/Schema/moreStrings.d.ts.map +1 -1
- package/dist/Schema/moreStrings.js +1 -1
- package/dist/Schema.d.ts +1 -2
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +1 -1
- package/dist/Set.d.ts +2 -3
- package/dist/Set.d.ts.map +1 -1
- package/dist/Set.js +1 -1
- package/dist/Widen.type.d.ts.map +1 -1
- package/dist/_ext/date.d.ts.map +1 -1
- package/dist/_ext/date.js +1 -1
- package/dist/_ext/ord.ext.d.ts +1 -2
- package/dist/_ext/ord.ext.d.ts.map +1 -1
- package/dist/_ext/ord.ext.js +1 -1
- package/dist/client/apiClientFactory.d.ts +37 -27
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +131 -91
- package/dist/client/clientFor.d.ts +1 -2
- package/dist/client/clientFor.d.ts.map +1 -1
- package/dist/client/clientFor.js +1 -1
- package/dist/ids.d.ts +1 -2
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +1 -2
- package/dist/internal/lib.d.ts.map +1 -1
- package/dist/internal/lib.js +1 -1
- package/dist/utils/effectify.d.ts.map +1 -1
- package/dist/utils/effectify.js +4 -2
- package/dist/utils/logger.d.ts +1 -2
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +3 -1
- package/dist/validation/validators.d.ts +1 -1
- package/dist/validation/validators.d.ts.map +1 -1
- package/dist/validation/validators.js +2 -1
- package/eslint.config.mjs +24 -0
- package/package.json +9 -9
- package/src/Array.ts +1 -2
- package/src/Config/SecretURL.ts +1 -2
- package/src/Context.ts +1 -2
- package/src/Effect.ts +1 -2
- package/src/Inputify.type.ts +0 -1
- package/src/NonEmptySetBase.ts +2 -18
- package/src/Option.ts +1 -2
- package/src/Schema/brand.ts +1 -0
- package/src/Schema/ext.ts +1 -2
- package/src/Schema/moreStrings.ts +1 -2
- package/src/Schema.ts +2 -14
- package/src/Set.ts +2 -4
- package/src/Widen.type.ts +1 -3
- package/src/_ext/date.ts +1 -16
- package/src/_ext/ord.ext.ts +1 -2
- package/src/client/apiClientFactory.ts +216 -144
- package/src/client/clientFor.ts +1 -2
- package/src/ids.ts +1 -3
- package/src/internal/lib.ts +1 -22
- package/src/utils/effectify.ts +1 -0
- package/src/utils/logger.ts +1 -2
- package/src/utils.ts +2 -0
- package/src/validation/validators.ts +1 -2
- package/.eslintrc.cjs +0 -11
|
@@ -1,48 +1,10 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import type { RequestResolver, Schema } from "../internal/lib.js"
|
|
7
|
-
import { Config, Context, Effect, flow, HashMap, Layer, Option, pipe, Predicate, S, Struct } from "../internal/lib.js"
|
|
8
|
-
import { typedKeysOf } from "../utils.js"
|
|
2
|
+
import { Rpc, RpcClient, RpcGroup, RpcSerialization } from "@effect/rpc"
|
|
3
|
+
import { HttpClient, HttpClientRequest } from "../http.js"
|
|
4
|
+
import { Config, Context, Effect, flow, HashMap, Layer, ManagedRuntime, Option, Predicate, S, Struct } from "../internal/lib.js"
|
|
5
|
+
import { typedKeysOf, typedValuesOf } from "../utils.js"
|
|
9
6
|
import type { Client, Requests } from "./clientFor.js"
|
|
10
7
|
|
|
11
|
-
export const make = <R extends RpcRouter<any, any>>(
|
|
12
|
-
client: HttpClient.HttpClient
|
|
13
|
-
): RequestResolver.RequestResolver<
|
|
14
|
-
Rpc.Request<RpcRouter.Request<R>>,
|
|
15
|
-
Schema.SerializableWithResult.Context<RpcRouter.Request<R>>
|
|
16
|
-
> =>
|
|
17
|
-
RpcResolverNoStream.make((requests) =>
|
|
18
|
-
client
|
|
19
|
-
.post("", {
|
|
20
|
-
body: HttpBody.unsafeJson(requests)
|
|
21
|
-
})
|
|
22
|
-
.pipe(
|
|
23
|
-
Effect.flatMap((_) =>
|
|
24
|
-
pipe(
|
|
25
|
-
_,
|
|
26
|
-
HttpClientResponse.filterStatus((_) => _ === 200 || _ === 418 || _ === 422)
|
|
27
|
-
// Effect.tapErrorCause(() =>
|
|
28
|
-
// _.text.pipe(
|
|
29
|
-
// Effect.orElseSucceed(() => undefined),
|
|
30
|
-
// Effect.flatMap((body) =>
|
|
31
|
-
// Effect.annotateCurrentSpan({ "response.headers": redactUnwrap(_.headers), "response.body": body }).pipe(
|
|
32
|
-
// Effect.andThen(
|
|
33
|
-
// Effect.logError("RPC error", { responseHeaders: redactUnwrap(_.headers), responseBody: body })
|
|
34
|
-
// )
|
|
35
|
-
// )
|
|
36
|
-
// )
|
|
37
|
-
// )
|
|
38
|
-
// )
|
|
39
|
-
)
|
|
40
|
-
),
|
|
41
|
-
Effect.flatMap((_) => _.json),
|
|
42
|
-
Effect.scoped
|
|
43
|
-
)
|
|
44
|
-
)<R>()
|
|
45
|
-
|
|
46
8
|
export interface ApiConfig {
|
|
47
9
|
url: string
|
|
48
10
|
headers: Option<HashMap<string, string>>
|
|
@@ -67,131 +29,240 @@ type Req = S.Schema.All & {
|
|
|
67
29
|
config?: Record<string, any>
|
|
68
30
|
}
|
|
69
31
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
32
|
+
class RequestName extends Context.Reference<RequestName>()("RequestName", {
|
|
33
|
+
defaultValue: () => ({ requestName: "Unspecified", moduleName: "Error" })
|
|
34
|
+
}) {}
|
|
35
|
+
|
|
36
|
+
const makeProtocol = (config: ApiConfig) =>
|
|
37
|
+
Effect
|
|
38
|
+
.gen(function*() {
|
|
39
|
+
const baseClient = yield* HttpClient.HttpClient
|
|
40
|
+
const client = baseClient.pipe(
|
|
41
|
+
HttpClient.mapRequest(HttpClientRequest.prependUrl(config.url + "/rpc")),
|
|
42
|
+
HttpClient.mapRequest(
|
|
43
|
+
HttpClientRequest.setHeaders(config.headers.pipe(Option.getOrElse(() => HashMap.empty())))
|
|
44
|
+
),
|
|
45
|
+
HttpClient.mapRequestEffect((req) =>
|
|
46
|
+
RequestName.pipe(
|
|
47
|
+
Effect.map((ctx) =>
|
|
48
|
+
flow(
|
|
49
|
+
HttpClientRequest.appendUrlParam("action", ctx.requestName),
|
|
50
|
+
HttpClientRequest.appendUrl("/" + ctx.moduleName)
|
|
51
|
+
)(req)
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
)
|
|
77
55
|
)
|
|
78
|
-
)
|
|
79
56
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (
|
|
87
|
-
Predicate.isObject(resource[cur])
|
|
88
|
-
&& (resource[cur].success)
|
|
89
|
-
) {
|
|
90
|
-
acc[cur as keyof Filtered] = resource[cur]
|
|
91
|
-
}
|
|
92
|
-
return acc
|
|
93
|
-
}, {} as Record<keyof Filtered, Req>)
|
|
57
|
+
return Layer.mergeAll(
|
|
58
|
+
RpcSerialization.layerJson,
|
|
59
|
+
Layer.succeed(HttpClient.HttpClient, client)
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
.pipe(Layer.unwrapEffect)
|
|
94
63
|
|
|
95
|
-
|
|
96
|
-
|
|
64
|
+
type RpcHandlers<M extends Requests> = {
|
|
65
|
+
[K in keyof M]: Rpc.Rpc<M[K]["_tag"], M[K], M[K]["success"], M[K]["failure"]>
|
|
66
|
+
}
|
|
97
67
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
68
|
+
const getFiltered = <M extends Requests>(resource: M) => {
|
|
69
|
+
type Filtered = {
|
|
70
|
+
[K in keyof M as M[K] extends Req ? K : never]: M[K] extends Req ? M[K] : never
|
|
71
|
+
}
|
|
72
|
+
// TODO: Record.filter
|
|
73
|
+
const filtered = typedKeysOf(resource).reduce((acc, cur) => {
|
|
74
|
+
if (
|
|
75
|
+
Predicate.isObject(resource[cur])
|
|
76
|
+
&& (resource[cur].success)
|
|
77
|
+
) {
|
|
78
|
+
acc[cur as keyof Filtered] = resource[cur]
|
|
79
|
+
}
|
|
80
|
+
return acc
|
|
81
|
+
}, {} as Record<keyof Filtered, Req>)
|
|
82
|
+
|
|
83
|
+
return filtered as unknown as Filtered
|
|
84
|
+
}
|
|
102
85
|
|
|
103
|
-
|
|
86
|
+
export const getMeta = <M extends Requests>(resource: M) => {
|
|
87
|
+
const meta = (resource as any).meta as { moduleName: string }
|
|
88
|
+
if (!meta) throw new Error("No meta defined in Resource!")
|
|
89
|
+
return meta as M["meta"]
|
|
90
|
+
}
|
|
104
91
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
92
|
+
export const makeRpcGroup = <M extends Requests>(resource: M) => {
|
|
93
|
+
const filtered = getFiltered(resource)
|
|
94
|
+
type newM = typeof filtered
|
|
108
95
|
|
|
109
|
-
|
|
110
|
-
|
|
96
|
+
const rpcs = RpcGroup.make(
|
|
97
|
+
...typedValuesOf(filtered).map((_) => {
|
|
98
|
+
return Rpc.fromTaggedRequest(_ as any)
|
|
99
|
+
})
|
|
100
|
+
) as RpcGroup.RpcGroup<RpcHandlers<newM>[keyof newM]>
|
|
101
|
+
return rpcs
|
|
102
|
+
}
|
|
111
103
|
|
|
112
|
-
|
|
113
|
-
|
|
104
|
+
const makeRpcTag = <M extends Requests>(resource: M) => {
|
|
105
|
+
const rpcs = makeRpcGroup(resource)
|
|
106
|
+
const meta = getMeta(resource)
|
|
114
107
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
108
|
+
return class TheClient extends Context.Tag(`RpcClient.${meta.moduleName}`)<
|
|
109
|
+
TheClient,
|
|
110
|
+
RpcClient.RpcClient<RpcGroup.Rpcs<typeof rpcs>>
|
|
111
|
+
>() {
|
|
112
|
+
static layer = Layer.scoped(TheClient, RpcClient.make(rpcs))
|
|
113
|
+
}
|
|
114
|
+
}
|
|
119
115
|
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
const makeApiClientFactory = Effect
|
|
117
|
+
.gen(function*() {
|
|
118
|
+
const ctx = yield* Effect.context<RpcSerialization.RpcSerialization | HttpClient.HttpClient>()
|
|
119
|
+
const makeClientFor = <M extends Requests>(resource: M, requestLevelLayers = Layer.empty) =>
|
|
120
|
+
Effect.gen(function*() {
|
|
121
|
+
const TheClient = makeRpcTag(resource)
|
|
122
|
+
|
|
123
|
+
const meta = getMeta(resource)
|
|
124
|
+
|
|
125
|
+
// TODO: somehow we need a protocol per REQUEST kind of it seems ...
|
|
126
|
+
// otherwise it locks up on the client, navigation remains empty...
|
|
127
|
+
const clientLayer = TheClient.layer.pipe(
|
|
128
|
+
// add ApiClientFactory for nested schemas
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
130
|
+
Layer.provide(Layer.succeed(ApiClientFactory, makeClientForCached as any)),
|
|
131
|
+
Layer.provide(
|
|
132
|
+
RpcClient
|
|
133
|
+
.layerProtocolHttp({
|
|
134
|
+
url: "" // why not here set meta.moduleName as root?
|
|
135
|
+
})
|
|
122
136
|
.pipe(
|
|
123
|
-
|
|
124
|
-
resolver
|
|
137
|
+
Layer.provideMerge(Layer.succeedContext(ctx))
|
|
125
138
|
)
|
|
139
|
+
)
|
|
140
|
+
)
|
|
141
|
+
const mr = ManagedRuntime.make(clientLayer)
|
|
142
|
+
|
|
143
|
+
const filtered = getFiltered(resource)
|
|
144
|
+
return {
|
|
145
|
+
mr,
|
|
146
|
+
client: (typedKeysOf(filtered)
|
|
147
|
+
.reduce((prev, cur) => {
|
|
148
|
+
const h = filtered[cur]!
|
|
149
|
+
|
|
150
|
+
const Request = h
|
|
151
|
+
const Response = h.success
|
|
126
152
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
captureStackTrace: false,
|
|
134
|
-
attributes: { "request.name": requestName }
|
|
135
|
-
}),
|
|
136
|
-
Effect.provide(requestLevelLayers)
|
|
137
|
-
),
|
|
138
|
-
...requestMeta,
|
|
139
|
-
raw: {
|
|
140
|
-
handler: client(new Request() as Schema.TaggedRequest.All).pipe(
|
|
141
|
-
Effect.flatMap((res) => S.encode(Response)(res)), // TODO,
|
|
142
|
-
Effect.withSpan("client.request " + requestName, {
|
|
143
|
-
captureStackTrace: false,
|
|
144
|
-
attributes: { "request.name": requestName }
|
|
145
|
-
}),
|
|
146
|
-
Effect.provide(requestLevelLayers)
|
|
147
|
-
),
|
|
148
|
-
...requestMeta
|
|
153
|
+
const requestName = `${meta.moduleName}.${cur as string}`
|
|
154
|
+
.replaceAll(".js", "")
|
|
155
|
+
|
|
156
|
+
const requestMeta = {
|
|
157
|
+
Request,
|
|
158
|
+
name: requestName
|
|
149
159
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
handler: (req: any) =>
|
|
164
|
-
client(new Request(req) as Schema.TaggedRequest.All).pipe(
|
|
165
|
-
Effect.flatMap((res) => S.encode(Response)(res)), // TODO,
|
|
160
|
+
|
|
161
|
+
const requestNameLayer = Layer.succeed(RequestName, {
|
|
162
|
+
requestName: cur as string,
|
|
163
|
+
moduleName: meta.moduleName
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
const fields = Struct.omit(Request.fields, "_tag")
|
|
167
|
+
const requestAttr = h._tag
|
|
168
|
+
// @ts-expect-error doc
|
|
169
|
+
prev[cur] = Object.keys(fields).length === 0
|
|
170
|
+
? {
|
|
171
|
+
handler: TheClient.pipe(
|
|
172
|
+
Effect.flatMap((client) => (client as any)[requestAttr]!(new Request()) as Effect<any, any, never>),
|
|
166
173
|
Effect.withSpan("client.request " + requestName, {
|
|
167
174
|
captureStackTrace: false,
|
|
168
175
|
attributes: { "request.name": requestName }
|
|
169
176
|
}),
|
|
170
|
-
Effect.provide(requestLevelLayers)
|
|
177
|
+
Effect.provide(requestLevelLayers),
|
|
178
|
+
Effect.provide(mr),
|
|
179
|
+
Effect.provide(requestNameLayer)
|
|
171
180
|
),
|
|
181
|
+
...requestMeta,
|
|
182
|
+
raw: {
|
|
183
|
+
handler: TheClient.pipe(
|
|
184
|
+
Effect.flatMap((client) =>
|
|
185
|
+
(client as any)[requestAttr]!(new Request()) as Effect<any, any, never>
|
|
186
|
+
),
|
|
187
|
+
Effect.flatMap((res) => S.encode(Response)(res)), // TODO,
|
|
188
|
+
Effect.withSpan("client.request " + requestName, {
|
|
189
|
+
captureStackTrace: false,
|
|
190
|
+
attributes: { "request.name": requestName }
|
|
191
|
+
}),
|
|
192
|
+
Effect.provide(requestLevelLayers),
|
|
193
|
+
Effect.provide(mr),
|
|
194
|
+
Effect.provide(requestNameLayer)
|
|
195
|
+
),
|
|
172
196
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
197
|
+
...requestMeta
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
: {
|
|
201
|
+
handler: (req: any) =>
|
|
202
|
+
TheClient.pipe(
|
|
203
|
+
Effect.flatMap((client) =>
|
|
204
|
+
(client as any)[requestAttr]!(new Request(req)) as Effect<any, any, never>
|
|
205
|
+
),
|
|
206
|
+
Effect.withSpan("client.request " + requestName, {
|
|
207
|
+
captureStackTrace: false,
|
|
208
|
+
attributes: { "request.name": requestName }
|
|
209
|
+
}),
|
|
210
|
+
Effect.provide(requestLevelLayers),
|
|
211
|
+
Effect.provide(mr),
|
|
212
|
+
Effect.provide(requestNameLayer)
|
|
213
|
+
),
|
|
176
214
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
215
|
+
...requestMeta,
|
|
216
|
+
raw: {
|
|
217
|
+
handler: (req: any) =>
|
|
218
|
+
TheClient.pipe(
|
|
219
|
+
Effect.flatMap((client) =>
|
|
220
|
+
(client as any)[requestAttr]!(new Request(req)) as Effect<any, any, never>
|
|
221
|
+
),
|
|
222
|
+
Effect.flatMap((res) => S.encode(Response)(res)), // TODO,
|
|
223
|
+
Effect.withSpan("client.request " + requestName, {
|
|
224
|
+
captureStackTrace: false,
|
|
225
|
+
attributes: { "request.name": requestName }
|
|
226
|
+
}),
|
|
227
|
+
Effect.provide(requestLevelLayers),
|
|
228
|
+
Effect.provide(mr),
|
|
229
|
+
Effect.provide(requestNameLayer)
|
|
230
|
+
),
|
|
231
|
+
|
|
232
|
+
...requestMeta
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return prev
|
|
237
|
+
}, {} as Client<M>))
|
|
238
|
+
}
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
const register: ManagedRuntime.ManagedRuntime<any, any>[] = []
|
|
242
|
+
yield* Effect.addFinalizer(() => Effect.forEach(register, (mr) => mr.disposeEffect))
|
|
243
|
+
|
|
244
|
+
const cacheL = new Map<any, Map<any, Client<any>>>()
|
|
180
245
|
|
|
181
246
|
function makeClientForCached(requestLevelLayers: Layer.Layer<never, never, never>) {
|
|
182
|
-
|
|
247
|
+
let cache = cacheL.get(requestLevelLayers)
|
|
248
|
+
if (!cache) {
|
|
249
|
+
cache = new Map<any, Client<any>>()
|
|
250
|
+
cacheL.set(requestLevelLayers, cache)
|
|
251
|
+
}
|
|
183
252
|
|
|
184
253
|
return <M extends Requests>(
|
|
185
254
|
models: M
|
|
186
|
-
): Client<Omit<M, "meta"
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
255
|
+
): Effect<Client<Omit<M, "meta">>> =>
|
|
256
|
+
Effect.gen(function*() {
|
|
257
|
+
const found = cache.get(models)
|
|
258
|
+
if (found) {
|
|
259
|
+
return found
|
|
260
|
+
}
|
|
261
|
+
const m = yield* makeClientFor(models, requestLevelLayers)
|
|
262
|
+
cache.set(models, m.client)
|
|
263
|
+
register.push(m.mr)
|
|
264
|
+
return m.client
|
|
265
|
+
})
|
|
195
266
|
}
|
|
196
267
|
|
|
197
268
|
return makeClientForCached
|
|
@@ -201,14 +272,15 @@ const makeApiClientFactory = (config: ApiConfig) =>
|
|
|
201
272
|
* Used to create clients for resource modules.
|
|
202
273
|
*/
|
|
203
274
|
export class ApiClientFactory
|
|
204
|
-
extends Context.TagId("ApiClientFactory")<ApiClientFactory, Effect.Success<
|
|
275
|
+
extends Context.TagId("ApiClientFactory")<ApiClientFactory, Effect.Success<typeof makeApiClientFactory>>()
|
|
205
276
|
{
|
|
206
|
-
static readonly layer = (config: ApiConfig) =>
|
|
277
|
+
static readonly layer = (config: ApiConfig) =>
|
|
278
|
+
this.toLayerScoped(makeApiClientFactory).pipe(Layer.provide(makeProtocol(config)))
|
|
207
279
|
static readonly layerFromConfig = DefaultApiConfig.pipe(Effect.map(this.layer), Layer.unwrapEffect)
|
|
208
280
|
|
|
209
281
|
static readonly makeFor =
|
|
210
282
|
(requestLevelLayers: Layer.Layer<never, never, never>) => <M extends Requests>(resource: M) =>
|
|
211
283
|
this
|
|
212
284
|
.use((apiClientFactory) => apiClientFactory(requestLevelLayers))
|
|
213
|
-
.pipe(Effect.
|
|
285
|
+
.pipe(Effect.flatMap((f) => f(resource))) // don't rename f to clientFor or integration in vue project linked fucks up
|
|
214
286
|
}
|
package/src/client/clientFor.ts
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
import type * as Request from "effect/Request"
|
|
5
5
|
import type { Path } from "path-parser"
|
|
6
6
|
import qs from "query-string"
|
|
7
|
-
import type
|
|
8
|
-
import { Record } from "../internal/lib.js"
|
|
7
|
+
import { type Effect, Record, type Schema } from "../internal/lib.js"
|
|
9
8
|
import type * as S from "../Schema.js"
|
|
10
9
|
|
|
11
10
|
export function makePathWithQuery(
|
package/src/ids.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { brandedStringId, NonEmptyString255, StringId, withDefaultMake } from "effect-app/Schema"
|
|
2
|
-
import type { Schema, StringIdBrand } from "effect-app/Schema"
|
|
1
|
+
import { brandedStringId, NonEmptyString255, type Schema, StringId, type StringIdBrand, withDefaultMake } from "effect-app/Schema"
|
|
3
2
|
import type { B } from "effect-app/Schema/schema"
|
|
4
3
|
import type { Simplify } from "effect/Types"
|
|
5
4
|
import { S } from "./index.js"
|
|
@@ -13,7 +12,6 @@ export type RequestId = NonEmptyString255
|
|
|
13
12
|
// a request id may be made from a span id, which does not comply with StringId schema.
|
|
14
13
|
export const RequestId = extendM(
|
|
15
14
|
Object
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
17
15
|
.assign(Object.create(NonEmptyString255) as {}, NonEmptyString255 as Schema<NonEmptyString255, string>),
|
|
18
16
|
(s) => {
|
|
19
17
|
const make = StringId.make as () => NonEmptyString255
|
package/src/internal/lib.ts
CHANGED
|
@@ -5,28 +5,7 @@ export * as Utils from "../utils.js"
|
|
|
5
5
|
// for app land, it may make sense to create an app/prelude?
|
|
6
6
|
export * from "./Prelude.js"
|
|
7
7
|
|
|
8
|
-
export {
|
|
9
|
-
Array,
|
|
10
|
-
Cause,
|
|
11
|
-
Chunk,
|
|
12
|
-
Config,
|
|
13
|
-
Context,
|
|
14
|
-
Duration,
|
|
15
|
-
Effect,
|
|
16
|
-
Either,
|
|
17
|
-
Equal,
|
|
18
|
-
Equivalence,
|
|
19
|
-
Exit,
|
|
20
|
-
FiberRef,
|
|
21
|
-
HashMap,
|
|
22
|
-
Layer,
|
|
23
|
-
Option,
|
|
24
|
-
Order,
|
|
25
|
-
Record,
|
|
26
|
-
Ref,
|
|
27
|
-
Schema,
|
|
28
|
-
Scope
|
|
29
|
-
} from "./Prelude.js"
|
|
8
|
+
export { Array, Cause, Chunk, Config, Context, Duration, Effect, Either, Equal, Equivalence, Exit, FiberRef, HashMap, Layer, Option, Order, Record, Ref, Schema, Scope } from "./Prelude.js"
|
|
30
9
|
|
|
31
10
|
export * as Struct from "../Struct.js"
|
|
32
11
|
export type * as Types from "../Types.js"
|
package/src/utils/effectify.ts
CHANGED
|
@@ -242,6 +242,7 @@ export const effectify: {
|
|
|
242
242
|
onSyncError: (error: unknown, args: Parameters<F>) => E2
|
|
243
243
|
): Effectify<F, E | E2>
|
|
244
244
|
} =
|
|
245
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
245
246
|
(<A>(fn: Function, onError?: (e: any, args: any) => any, onSyncError?: (e: any, args: any) => any) =>
|
|
246
247
|
(...args: Array<any>) =>
|
|
247
248
|
Effect.async<A, Error>((resume) => {
|
package/src/utils/logger.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
3
|
|
|
4
|
-
import type
|
|
5
|
-
import { Context, Effect } from "effect"
|
|
4
|
+
import { Context, Effect, type LogLevel } from "effect"
|
|
6
5
|
|
|
7
6
|
type Levels = "info" | "debug" | "warn" | "error"
|
|
8
7
|
|
package/src/utils.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
1
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-redundant-type-constituents */
|
|
2
4
|
import { Effect, Option, Record } from "effect"
|
|
3
5
|
import * as Either from "effect/Either"
|
|
4
6
|
import { dual, isFunction } from "effect/Function"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// Not importing from /es/lib because they are .js files and bundlers probably assume they're cjs :(
|
|
2
|
-
import
|
|
3
|
-
import isEmail from "validator/lib/isEmail.js"
|
|
2
|
+
import isEmail, { type IsEmailOptions } from "validator/lib/isEmail.js"
|
|
4
3
|
|
|
5
4
|
// Source https://emailregex.com/
|
|
6
5
|
// eslint-disable-next-line no-control-regex
|
package/.eslintrc.cjs
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const makeBase = require("../../.eslintrc.base")
|
|
2
|
-
const base = makeBase(__dirname, true)
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
...base,
|
|
6
|
-
rules: {
|
|
7
|
-
...base.rules,
|
|
8
|
-
'codegen/codegen': ['error', { presets: require('@effect-app/eslint-codegen-model') }],
|
|
9
|
-
"@typescript-eslint/no-empty-interface": "off"
|
|
10
|
-
}
|
|
11
|
-
}
|