effect-app 4.0.0-beta.13 → 4.0.0-beta.131
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 +503 -0
- package/dist/Config/SecretURL.js +2 -2
- package/dist/Config.d.ts +7 -0
- package/dist/Config.d.ts.map +1 -0
- package/dist/Config.js +6 -0
- package/dist/ConfigProvider.d.ts +39 -0
- package/dist/ConfigProvider.d.ts.map +1 -0
- package/dist/ConfigProvider.js +42 -0
- package/dist/{ServiceMap.d.ts → Context.d.ts} +14 -18
- package/dist/Context.d.ts.map +1 -0
- package/dist/Context.js +66 -0
- package/dist/Effect.d.ts +8 -9
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +3 -6
- package/dist/Layer.d.ts +5 -4
- package/dist/Layer.d.ts.map +1 -1
- package/dist/Layer.js +1 -1
- package/dist/Operations.d.ts +198 -33
- package/dist/Operations.d.ts.map +1 -1
- package/dist/Pure.d.ts +2 -2
- package/dist/Pure.d.ts.map +1 -1
- package/dist/Pure.js +13 -13
- package/dist/Schema/Class.d.ts +48 -10
- package/dist/Schema/Class.d.ts.map +1 -1
- package/dist/Schema/Class.js +120 -16
- package/dist/Schema/SpecialJsonSchema.d.ts +33 -0
- package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
- package/dist/Schema/SpecialJsonSchema.js +122 -0
- package/dist/Schema/SpecialOpenApi.d.ts +32 -0
- package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
- package/dist/Schema/SpecialOpenApi.js +123 -0
- package/dist/Schema/brand.d.ts +10 -1
- package/dist/Schema/brand.d.ts.map +1 -1
- package/dist/Schema/brand.js +1 -1
- package/dist/Schema/email.d.ts.map +1 -1
- package/dist/Schema/email.js +9 -4
- package/dist/Schema/ext.d.ts +112 -47
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/ext.js +115 -53
- package/dist/Schema/moreStrings.d.ts +110 -10
- package/dist/Schema/moreStrings.d.ts.map +1 -1
- package/dist/Schema/moreStrings.js +19 -10
- package/dist/Schema/numbers.d.ts +126 -14
- package/dist/Schema/numbers.d.ts.map +1 -1
- package/dist/Schema/numbers.js +10 -9
- package/dist/Schema/phoneNumber.d.ts.map +1 -1
- package/dist/Schema/phoneNumber.js +8 -3
- package/dist/Schema/strings.d.ts +36 -4
- package/dist/Schema/strings.d.ts.map +1 -1
- package/dist/Schema/strings.js +1 -1
- package/dist/Schema.d.ts +74 -55
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +85 -64
- package/dist/client/apiClientFactory.d.ts +12 -28
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +16 -17
- package/dist/client/clientFor.d.ts +6 -5
- package/dist/client/clientFor.d.ts.map +1 -1
- package/dist/client/errors.d.ts +18 -9
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +35 -10
- package/dist/client/makeClient.d.ts +73 -28
- package/dist/client/makeClient.d.ts.map +1 -1
- package/dist/client/makeClient.js +49 -23
- package/dist/http/Request.d.ts.map +1 -1
- package/dist/http/Request.js +5 -5
- package/dist/ids.d.ts +2 -2
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +3 -2
- package/dist/index.d.ts +3 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -8
- package/dist/middleware.d.ts +2 -2
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +3 -3
- package/dist/rpc/MiddlewareMaker.d.ts +4 -3
- package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
- package/dist/rpc/MiddlewareMaker.js +23 -24
- package/dist/rpc/RpcContextMap.d.ts +2 -2
- package/dist/rpc/RpcContextMap.d.ts.map +1 -1
- package/dist/rpc/RpcContextMap.js +4 -4
- package/dist/rpc/RpcMiddleware.d.ts +4 -3
- package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
- package/dist/rpc/RpcMiddleware.js +1 -1
- package/dist/utils/gen.d.ts +1 -1
- package/dist/utils/gen.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +2 -2
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +3 -3
- package/dist/utils.d.ts +7 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +8 -2
- package/package.json +30 -14
- package/src/Config/SecretURL.ts +1 -1
- package/src/Config.ts +14 -0
- package/src/ConfigProvider.ts +48 -0
- package/src/{ServiceMap.ts → Context.ts} +51 -59
- package/src/Effect.ts +11 -14
- package/src/Layer.ts +5 -4
- package/src/Pure.ts +17 -18
- package/src/Schema/Class.ts +157 -30
- package/src/Schema/SpecialJsonSchema.ts +137 -0
- package/src/Schema/SpecialOpenApi.ts +130 -0
- package/src/Schema/brand.ts +18 -3
- package/src/Schema/email.ts +10 -2
- package/src/Schema/ext.ts +196 -87
- package/src/Schema/moreStrings.ts +31 -17
- package/src/Schema/numbers.ts +14 -13
- package/src/Schema/phoneNumber.ts +8 -1
- package/src/Schema/strings.ts +4 -4
- package/src/Schema.ts +195 -104
- package/src/client/apiClientFactory.ts +104 -112
- package/src/client/clientFor.ts +6 -1
- package/src/client/errors.ts +42 -17
- package/src/client/makeClient.ts +150 -61
- package/src/http/Request.ts +7 -4
- package/src/ids.ts +2 -1
- package/src/index.ts +3 -10
- package/src/middleware.ts +2 -2
- package/src/rpc/MiddlewareMaker.ts +33 -44
- package/src/rpc/RpcContextMap.ts +6 -5
- package/src/rpc/RpcMiddleware.ts +5 -4
- package/src/utils/gen.ts +1 -1
- package/src/utils/logger.ts +2 -2
- package/src/utils.ts +8 -4
- package/test/dist/moreStrings.test.d.ts.map +1 -0
- package/test/dist/rpc.test.d.ts.map +1 -1
- package/test/dist/secretURL.test.d.ts.map +1 -0
- package/test/dist/special.test.d.ts.map +1 -0
- package/test/moreStrings.test.ts +17 -0
- package/test/rpc.test.ts +30 -6
- package/test/schema.test.ts +517 -4
- package/test/secretURL.test.ts +157 -0
- package/test/special.test.ts +862 -0
- package/test/utils.test.ts +2 -2
- package/tsconfig.base.json +0 -1
- package/tsconfig.json +0 -1
- package/dist/ServiceMap.d.ts.map +0 -1
- package/dist/ServiceMap.js +0 -91
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import * as Config from "effect/Config"
|
|
3
2
|
import { flow } from "effect/Function"
|
|
4
3
|
import * as Layer from "effect/Layer"
|
|
5
4
|
import * as ManagedRuntime from "effect/ManagedRuntime"
|
|
@@ -7,13 +6,14 @@ import * as Predicate from "effect/Predicate"
|
|
|
7
6
|
import * as Schema from "effect/Schema"
|
|
8
7
|
import * as Struct from "effect/Struct"
|
|
9
8
|
import { Rpc, RpcClient, RpcGroup, RpcSerialization } from "effect/unstable/rpc"
|
|
9
|
+
import * as Config from "../Config.js"
|
|
10
|
+
import * as Context from "../Context.js"
|
|
10
11
|
import * as Effect from "../Effect.js"
|
|
11
12
|
import { HttpClient, HttpClientRequest } from "../http.js"
|
|
12
13
|
import * as Option from "../Option.js"
|
|
13
14
|
import type * as S from "../Schema.js"
|
|
14
|
-
import * as ServiceMap from "../ServiceMap.js"
|
|
15
15
|
import { typedKeysOf, typedValuesOf } from "../utils.js"
|
|
16
|
-
import type { Client, ClientForOptions,
|
|
16
|
+
import type { Client, ClientForOptions, ExtractModuleName, RequestsAny } from "./clientFor.js"
|
|
17
17
|
|
|
18
18
|
export interface ApiConfig {
|
|
19
19
|
url: string
|
|
@@ -37,10 +37,13 @@ export type Req = S.Top & {
|
|
|
37
37
|
success: S.Top
|
|
38
38
|
error: S.Top
|
|
39
39
|
config?: Record<string, any>
|
|
40
|
+
readonly id: string
|
|
41
|
+
readonly moduleName: string
|
|
42
|
+
readonly type: "command" | "query"
|
|
40
43
|
readonly "~decodingServices"?: unknown
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
class RequestName extends
|
|
46
|
+
class RequestName extends Context.Reference("RequestName", {
|
|
44
47
|
defaultValue: () => ({ requestName: "Unspecified", moduleName: "Error" })
|
|
45
48
|
}) {}
|
|
46
49
|
|
|
@@ -84,7 +87,7 @@ type RpcHandlers<M extends RequestsAny> = {
|
|
|
84
87
|
[K in keyof M]: Rpc.Rpc<M[K]["_tag"], M[K], M[K]["success"], M[K]["error"]>
|
|
85
88
|
}
|
|
86
89
|
|
|
87
|
-
const getFiltered = <M extends
|
|
90
|
+
const getFiltered = <M extends RequestsAny>(resource: M) => {
|
|
88
91
|
type Filtered = {
|
|
89
92
|
[K in keyof M as M[K] extends Req ? K : never]: M[K] extends Req ? M[K] : never
|
|
90
93
|
}
|
|
@@ -102,13 +105,13 @@ const getFiltered = <M extends Requests>(resource: M) => {
|
|
|
102
105
|
return filtered as unknown as Filtered
|
|
103
106
|
}
|
|
104
107
|
|
|
105
|
-
export const getMeta = <M extends
|
|
106
|
-
const
|
|
107
|
-
if (
|
|
108
|
-
|
|
108
|
+
export const getMeta = <M extends RequestsAny>(resource: M): { moduleName: ExtractModuleName<M> } => {
|
|
109
|
+
const first = typedValuesOf(getFiltered(resource))[0]
|
|
110
|
+
if (first && "moduleName" in first) return { moduleName: first.moduleName }
|
|
111
|
+
throw new Error("No moduleName on requests!")
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
export const makeRpcGroupFromRequestsAndModuleName = <M extends
|
|
114
|
+
export const makeRpcGroupFromRequestsAndModuleName = <M extends RequestsAny, const ModuleName extends string>(
|
|
112
115
|
resource: M,
|
|
113
116
|
moduleName: ModuleName
|
|
114
117
|
) => {
|
|
@@ -126,20 +129,13 @@ export const makeRpcGroupFromRequestsAndModuleName = <M extends Requests, const
|
|
|
126
129
|
return rpcs
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
|
|
130
|
-
M extends Requests,
|
|
131
|
-
const ModuleName extends string
|
|
132
|
-
>(
|
|
133
|
-
resource: M & { meta: { moduleName: ModuleName } }
|
|
134
|
-
) => makeRpcGroupFromRequestsAndModuleName(resource, resource.meta.moduleName)
|
|
135
|
-
|
|
136
|
-
const makeRpcTag = <M extends Requests>(resource: M) => {
|
|
132
|
+
const makeRpcTag = <M extends RequestsAny>(resource: M) => {
|
|
137
133
|
const meta = getMeta(resource)
|
|
138
134
|
const rpcs = makeRpcGroupFromRequestsAndModuleName(resource, meta.moduleName)
|
|
139
135
|
|
|
140
136
|
// Use Object.assign instead of class extension to avoid TS2509 with complex generic return types.
|
|
141
137
|
// The first type arg is `any` because this is a dynamically created tag — its identity is the string key.
|
|
142
|
-
const TheClient =
|
|
138
|
+
const TheClient = Context.Opaque<
|
|
143
139
|
any,
|
|
144
140
|
RpcClient.RpcClient<RpcGroup.Rpcs<typeof rpcs>>
|
|
145
141
|
>()(`RpcClient.${meta.moduleName}`)
|
|
@@ -153,99 +149,98 @@ const makeRpcTag = <M extends Requests>(resource: M) => {
|
|
|
153
149
|
|
|
154
150
|
const makeApiClientFactory = Effect
|
|
155
151
|
.gen(function*() {
|
|
156
|
-
const ctx = yield* Effect.
|
|
157
|
-
const makeClientFor =
|
|
152
|
+
const ctx = yield* Effect.context<RpcSerialization.RpcSerialization | HttpClient.HttpClient>()
|
|
153
|
+
const makeClientFor = Effect.fnUntraced(function*<M extends RequestsAny>(
|
|
158
154
|
resource: M,
|
|
159
155
|
requestLevelLayers = Layer.empty,
|
|
160
156
|
options?: ClientForOptions
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
.
|
|
179
|
-
|
|
180
|
-
)
|
|
181
|
-
)
|
|
157
|
+
) {
|
|
158
|
+
const TheClient = makeRpcTag(resource)
|
|
159
|
+
|
|
160
|
+
const meta = getMeta(resource)
|
|
161
|
+
|
|
162
|
+
// TODO: somehow we need a protocol per REQUEST kind of it seems ...
|
|
163
|
+
// otherwise it locks up on the client, navigation remains empty...
|
|
164
|
+
const clientLayer = TheClient.layer.pipe(
|
|
165
|
+
// add ApiClientFactory for nested schemas
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
167
|
+
Layer.provide(Layer.succeed(ApiClientFactory, makeClientForCached as any)),
|
|
168
|
+
Layer.provide(
|
|
169
|
+
RpcClient
|
|
170
|
+
.layerProtocolHttp({
|
|
171
|
+
url: "" // why not here set meta.moduleName as root?
|
|
172
|
+
})
|
|
173
|
+
.pipe(
|
|
174
|
+
Layer.provideMerge(Layer.succeedContext(ctx))
|
|
175
|
+
)
|
|
182
176
|
)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
177
|
+
)
|
|
178
|
+
const mr = ManagedRuntime.make(clientLayer)
|
|
179
|
+
|
|
180
|
+
const filtered = getFiltered(resource)
|
|
181
|
+
return {
|
|
182
|
+
mr,
|
|
183
|
+
client: typedKeysOf(filtered)
|
|
184
|
+
.reduce((prev, cur) => {
|
|
185
|
+
const h = filtered[cur]!
|
|
186
|
+
|
|
187
|
+
const Request = h
|
|
188
|
+
|
|
189
|
+
const id = `${meta.moduleName}.${cur as string}`
|
|
190
|
+
.replaceAll(".js", "")
|
|
191
|
+
|
|
192
|
+
const requestMeta = {
|
|
193
|
+
Request,
|
|
194
|
+
id,
|
|
195
|
+
options
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const requestNameLayer = Layer.succeed(RequestName, {
|
|
199
|
+
requestName: cur as string,
|
|
200
|
+
moduleName: meta.moduleName
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
const layers = requestLevelLayers.pipe(Layer.provideMerge(requestNameLayer))
|
|
204
|
+
|
|
205
|
+
const fields = Struct.omit(Request.fields, ["_tag"] as const)
|
|
206
|
+
const requestAttr = `${meta.moduleName}.${h._tag}`
|
|
207
|
+
// @ts-expect-error doc
|
|
208
|
+
prev[cur] = Object.keys(fields).length === 0
|
|
209
|
+
? {
|
|
210
|
+
handler: mr.contextEffect.pipe(
|
|
211
|
+
Effect.flatMap((svcs) =>
|
|
212
|
+
TheClient
|
|
213
|
+
.use((client) => (client as any)[requestAttr]!(new Request()) as Effect.Effect<any, any, never>)
|
|
214
|
+
.pipe(
|
|
215
|
+
Effect.provide(layers),
|
|
216
|
+
Effect.provide(svcs)
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
),
|
|
220
|
+
...requestMeta
|
|
201
221
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
moduleName: meta.moduleName
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
const layers = requestLevelLayers.pipe(Layer.provideMerge(requestNameLayer))
|
|
209
|
-
|
|
210
|
-
const fields = Struct.omit(Request.fields, ["_tag"] as const)
|
|
211
|
-
const requestAttr = `${meta.moduleName}.${h._tag}`
|
|
212
|
-
// @ts-expect-error doc
|
|
213
|
-
prev[cur] = Object.keys(fields).length === 0
|
|
214
|
-
? {
|
|
215
|
-
handler: mr.servicesEffect.pipe(
|
|
222
|
+
: {
|
|
223
|
+
handler: (req: any) =>
|
|
224
|
+
mr.contextEffect.pipe(
|
|
216
225
|
Effect.flatMap((svcs) =>
|
|
217
226
|
TheClient
|
|
218
|
-
.use((client) =>
|
|
227
|
+
.use((client) =>
|
|
228
|
+
(client as any)[requestAttr]!(new Request(req)) as Effect.Effect<any, any, never>
|
|
229
|
+
)
|
|
219
230
|
.pipe(
|
|
220
231
|
Effect.provide(layers),
|
|
221
232
|
Effect.provide(svcs)
|
|
222
233
|
)
|
|
223
234
|
)
|
|
224
235
|
),
|
|
225
|
-
...requestMeta
|
|
226
|
-
}
|
|
227
|
-
: {
|
|
228
|
-
handler: (req: any) =>
|
|
229
|
-
mr.servicesEffect.pipe(
|
|
230
|
-
Effect.flatMap((svcs) =>
|
|
231
|
-
TheClient
|
|
232
|
-
.use((client) =>
|
|
233
|
-
(client as any)[requestAttr]!(new Request(req)) as Effect.Effect<any, any, never>
|
|
234
|
-
)
|
|
235
|
-
.pipe(
|
|
236
|
-
Effect.provide(layers),
|
|
237
|
-
Effect.provide(svcs)
|
|
238
|
-
)
|
|
239
|
-
)
|
|
240
|
-
),
|
|
241
236
|
|
|
242
|
-
|
|
243
|
-
|
|
237
|
+
...requestMeta
|
|
238
|
+
}
|
|
244
239
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
240
|
+
return prev
|
|
241
|
+
}, {} as Client<M, ExtractModuleName<M>>)
|
|
242
|
+
}
|
|
243
|
+
})
|
|
249
244
|
|
|
250
245
|
const register: ManagedRuntime.ManagedRuntime<any, any>[] = []
|
|
251
246
|
yield* Effect.addFinalizer(() => Effect.forEach(register, (mr) => mr.disposeEffect))
|
|
@@ -259,19 +254,16 @@ const makeApiClientFactory = Effect
|
|
|
259
254
|
cacheL.set(requestLevelLayers, cache)
|
|
260
255
|
}
|
|
261
256
|
|
|
262
|
-
return
|
|
263
|
-
models
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
register.push(m.mr)
|
|
273
|
-
return m.client
|
|
274
|
-
})
|
|
257
|
+
return Effect.fnUntraced(function*<M extends RequestsAny>(models: M) {
|
|
258
|
+
const found = cache.get(models) as Client<M, ExtractModuleName<M>> | undefined
|
|
259
|
+
if (found) {
|
|
260
|
+
return found
|
|
261
|
+
}
|
|
262
|
+
const m = yield* makeClientFor(models, requestLevelLayers, options)
|
|
263
|
+
cache.set(models, m.client)
|
|
264
|
+
register.push(m.mr)
|
|
265
|
+
return m.client
|
|
266
|
+
})
|
|
275
267
|
}
|
|
276
268
|
|
|
277
269
|
return makeClientForCached
|
|
@@ -281,7 +273,7 @@ const makeApiClientFactory = Effect
|
|
|
281
273
|
* Used to create clients for resource modules.
|
|
282
274
|
*/
|
|
283
275
|
export class ApiClientFactory
|
|
284
|
-
extends
|
|
276
|
+
extends Context.Opaque<ApiClientFactory, Effect.Success<typeof makeApiClientFactory>>()("ApiClientFactory")
|
|
285
277
|
{
|
|
286
278
|
static readonly layer = (config: ApiConfig) =>
|
|
287
279
|
ApiClientFactory.toLayer(makeApiClientFactory).pipe(Layer.provide(RpcSerializationLayer(config)))
|
|
@@ -294,7 +286,7 @@ export class ApiClientFactory
|
|
|
294
286
|
|
|
295
287
|
static readonly makeFor =
|
|
296
288
|
(requestLevelLayers: Layer.Layer<never, never, never>, options?: ClientForOptions) =>
|
|
297
|
-
<M extends
|
|
289
|
+
<M extends RequestsAny>(
|
|
298
290
|
resource: M
|
|
299
291
|
) =>
|
|
300
292
|
ApiClientFactory.use((apiClientFactory) => {
|
package/src/client/clientFor.ts
CHANGED
|
@@ -48,9 +48,14 @@ export function makePathWithBody(
|
|
|
48
48
|
return path.build(pars, { ignoreSearch: true, ignoreConstraints: true })
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
export type Requests
|
|
51
|
+
export type Requests = RequestsAny
|
|
52
52
|
export type RequestsAny = Record<string, any>
|
|
53
53
|
|
|
54
|
+
export type ExtractModuleName<M extends RequestsAny> =
|
|
55
|
+
{ [K in keyof M]: M[K] extends { moduleName: infer N extends string } ? N : never }[keyof M] extends
|
|
56
|
+
infer R extends string ? R
|
|
57
|
+
: string
|
|
58
|
+
|
|
54
59
|
export type Client<M extends RequestsAny, ModuleName extends string> = RequestHandlers<
|
|
55
60
|
never,
|
|
56
61
|
never,
|
package/src/client/errors.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @effect-diagnostics overriddenSchemaConstructor:skip-file */
|
|
2
|
-
import {
|
|
2
|
+
import { TaggedErrorClass } from "effect-app/Schema"
|
|
3
3
|
import * as Cause from "effect/Cause"
|
|
4
4
|
import * as S from "../Schema.js"
|
|
5
5
|
|
|
@@ -21,7 +21,7 @@ export const tryToJson = (error: { toJSON(): unknown; toString(): string }) => {
|
|
|
21
21
|
|
|
22
22
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
23
23
|
// @ts-expect-error type not used
|
|
24
|
-
export class NotFoundError<ItemType = string> extends
|
|
24
|
+
export class NotFoundError<ItemType = string> extends TaggedErrorClass<NotFoundError<ItemType>>()("NotFoundError", {
|
|
25
25
|
type: S.String,
|
|
26
26
|
id: S.Unknown
|
|
27
27
|
}) {
|
|
@@ -29,76 +29,97 @@ export class NotFoundError<ItemType = string> extends TaggedError<NotFoundError<
|
|
|
29
29
|
props: { type: string; id: unknown; cause?: unknown },
|
|
30
30
|
disableValidation?: boolean
|
|
31
31
|
) {
|
|
32
|
-
super(props
|
|
32
|
+
super(props, disableValidation as any)
|
|
33
33
|
}
|
|
34
34
|
override get message() {
|
|
35
35
|
return `Didn't find ${(this as any).type}#${JSON.stringify((this as any).id)}`
|
|
36
36
|
}
|
|
37
|
+
override toString() {
|
|
38
|
+
return `NotFoundError: ${this.message}`
|
|
39
|
+
}
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
const messageFallback = (messageOrObject?: string | { message: string }) =>
|
|
40
43
|
typeof messageOrObject === "object" ? messageOrObject : { message: messageOrObject ?? "" }
|
|
41
44
|
|
|
42
|
-
export class InvalidStateError extends
|
|
45
|
+
export class InvalidStateError extends TaggedErrorClass<InvalidStateError>()("InvalidStateError", {
|
|
43
46
|
message: S.String
|
|
44
47
|
}) {
|
|
45
48
|
constructor(messageOrObject: string | { message: string; cause?: unknown }, disableValidation?: boolean) {
|
|
46
49
|
super(
|
|
47
|
-
typeof messageOrObject === "object" ? messageOrObject : { message: messageOrObject }
|
|
50
|
+
typeof messageOrObject === "object" ? messageOrObject : { message: messageOrObject },
|
|
48
51
|
disableValidation as any
|
|
49
52
|
)
|
|
50
53
|
}
|
|
54
|
+
override toString() {
|
|
55
|
+
return `InvalidStateError: ${this.message}`
|
|
56
|
+
}
|
|
51
57
|
}
|
|
52
58
|
|
|
53
|
-
export class ServiceUnavailableError extends
|
|
59
|
+
export class ServiceUnavailableError extends TaggedErrorClass<ServiceUnavailableError>()("ServiceUnavailableError", {
|
|
54
60
|
message: S.String
|
|
55
61
|
}) {
|
|
56
62
|
constructor(messageOrObject: string | { message: string; cause?: unknown }, disableValidation?: boolean) {
|
|
57
63
|
super(
|
|
58
|
-
typeof messageOrObject === "object" ? messageOrObject : { message: messageOrObject }
|
|
64
|
+
typeof messageOrObject === "object" ? messageOrObject : { message: messageOrObject },
|
|
59
65
|
disableValidation as any
|
|
60
66
|
)
|
|
61
67
|
}
|
|
68
|
+
override toString() {
|
|
69
|
+
return `ServiceUnavailableError: ${this.message}`
|
|
70
|
+
}
|
|
62
71
|
}
|
|
63
72
|
|
|
64
|
-
export class ValidationError extends
|
|
73
|
+
export class ValidationError extends TaggedErrorClass<ValidationError>()("ValidationError", {
|
|
65
74
|
errors: S.Array(S.Unknown)
|
|
66
75
|
}) {
|
|
67
76
|
constructor(
|
|
68
77
|
props: { errors: ReadonlyArray<unknown>; cause?: unknown },
|
|
69
78
|
disableValidation?: boolean
|
|
70
79
|
) {
|
|
71
|
-
super(props
|
|
80
|
+
super(props, disableValidation as any)
|
|
72
81
|
}
|
|
73
82
|
override get message() {
|
|
74
83
|
return `Validation failed: ${(this as any).errors.map((e: any) => JSON.stringify(e, undefined, 2)).join(",\n")}`
|
|
75
84
|
}
|
|
85
|
+
override toString() {
|
|
86
|
+
return `ValidationError: ${this.message}`
|
|
87
|
+
}
|
|
76
88
|
}
|
|
77
89
|
|
|
78
|
-
export class NotLoggedInError extends
|
|
90
|
+
export class NotLoggedInError extends TaggedErrorClass<NotLoggedInError>()("NotLoggedInError", {
|
|
79
91
|
message: S.String
|
|
80
92
|
}) {
|
|
81
93
|
constructor(messageOrObject?: string | { message: string; cause?: unknown }, disableValidation?: boolean) {
|
|
82
|
-
super(messageFallback(messageOrObject)
|
|
94
|
+
super(messageFallback(messageOrObject), disableValidation as any)
|
|
95
|
+
}
|
|
96
|
+
override toString() {
|
|
97
|
+
return `NotLoggedInError: ${this.message}`
|
|
83
98
|
}
|
|
84
99
|
}
|
|
85
100
|
|
|
86
101
|
/**
|
|
87
102
|
* The user carries a valid Userprofile, but there is a problem with the login none the less.
|
|
88
103
|
*/
|
|
89
|
-
export class LoginError extends
|
|
104
|
+
export class LoginError extends TaggedErrorClass<LoginError>()("NotLoggedInError", {
|
|
90
105
|
message: S.String
|
|
91
106
|
}) {
|
|
92
107
|
constructor(messageOrObject?: string | { message: string; cause?: unknown }, disableValidation?: boolean) {
|
|
93
|
-
super(messageFallback(messageOrObject)
|
|
108
|
+
super(messageFallback(messageOrObject), disableValidation as any)
|
|
109
|
+
}
|
|
110
|
+
override toString() {
|
|
111
|
+
return `LoginError: ${this.message}`
|
|
94
112
|
}
|
|
95
113
|
}
|
|
96
114
|
|
|
97
|
-
export class UnauthorizedError extends
|
|
115
|
+
export class UnauthorizedError extends TaggedErrorClass<UnauthorizedError>()("UnauthorizedError", {
|
|
98
116
|
message: S.String
|
|
99
117
|
}) {
|
|
100
118
|
constructor(messageOrObject?: string | { message: string; cause?: unknown }, disableValidation?: boolean) {
|
|
101
|
-
super(messageFallback(messageOrObject)
|
|
119
|
+
super(messageFallback(messageOrObject), disableValidation as any)
|
|
120
|
+
}
|
|
121
|
+
override toString() {
|
|
122
|
+
return `UnauthorizedError: ${this.message}`
|
|
102
123
|
}
|
|
103
124
|
}
|
|
104
125
|
|
|
@@ -110,7 +131,7 @@ type OptimisticConcurrencyDetails = {
|
|
|
110
131
|
readonly found?: string | undefined
|
|
111
132
|
}
|
|
112
133
|
|
|
113
|
-
export class OptimisticConcurrencyException extends
|
|
134
|
+
export class OptimisticConcurrencyException extends TaggedErrorClass<OptimisticConcurrencyException>()(
|
|
114
135
|
"OptimisticConcurrencyException",
|
|
115
136
|
{ message: S.String }
|
|
116
137
|
) {
|
|
@@ -123,13 +144,16 @@ export class OptimisticConcurrencyException extends TaggedError<OptimisticConcur
|
|
|
123
144
|
disableValidation?: boolean
|
|
124
145
|
) {
|
|
125
146
|
super(
|
|
126
|
-
"message" in args ? args : { message: `Existing ${args.type} ${args.id} record changed` }
|
|
147
|
+
"message" in args ? args : { message: `Existing ${args.type} ${args.id} record changed` },
|
|
127
148
|
disableValidation as any
|
|
128
149
|
)
|
|
129
150
|
if (!("message" in args)) {
|
|
130
151
|
this.details = args
|
|
131
152
|
}
|
|
132
153
|
}
|
|
154
|
+
override toString() {
|
|
155
|
+
return `OptimisticConcurrencyException: ${this.message}`
|
|
156
|
+
}
|
|
133
157
|
}
|
|
134
158
|
|
|
135
159
|
const MutationOnlyErrors = [
|
|
@@ -183,6 +207,7 @@ export class CauseException<E> extends Error {
|
|
|
183
207
|
Error.stackTraceLimit = 0
|
|
184
208
|
super()
|
|
185
209
|
Error.stackTraceLimit = limit
|
|
210
|
+
this.cause = Cause.squash(originalCause)
|
|
186
211
|
// v4: makeFiberFailure removed — use Cause.prettyErrors instead
|
|
187
212
|
const errors = Cause.prettyErrors(originalCause)
|
|
188
213
|
const first = errors[0]
|