@effect-app/vue 4.0.0-beta.4 → 4.0.0-beta.40
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 +262 -0
- package/dist/experimental/commander.d.ts +1 -1
- package/dist/experimental/commander.d.ts.map +1 -1
- package/dist/experimental/commander.js +4 -5
- package/dist/form.d.ts +9 -0
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +24 -7
- package/dist/makeClient.d.ts +2 -2
- package/dist/makeClient.d.ts.map +1 -1
- package/dist/makeClient.js +5 -4
- package/dist/mutate.d.ts +1 -1
- package/dist/mutate.d.ts.map +1 -1
- package/dist/mutate.js +2 -2
- package/dist/query.d.ts +1 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +16 -7
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +8 -2
- package/package.json +9 -9
- package/src/experimental/commander.ts +4 -5
- package/src/form.ts +23 -6
- package/src/makeClient.ts +4 -3
- package/src/mutate.ts +1 -1
- package/src/query.ts +16 -9
- package/src/runtime.ts +13 -1
- package/test/dist/stubs.d.ts +30 -47
- package/test/dist/stubs.d.ts.map +1 -1
- package/test/dist/stubs.js +2 -2
- package/test/form-validation-errors.test.ts +23 -19
- package/test/stubs.ts +2 -2
- package/tsconfig.json +0 -1
- package/test/form.test.ts +0 -261
package/src/form.ts
CHANGED
|
@@ -22,6 +22,7 @@ function getObjectsAST(ast: S.AST.AST): S.AST.Objects | null {
|
|
|
22
22
|
return null
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/** @deprecated Use OmegaForm instead */
|
|
25
26
|
export function convertIn(v: string | null, type?: "text" | "float" | "int") {
|
|
26
27
|
return v === null ? "" : type === "text" ? v : `${v}`
|
|
27
28
|
}
|
|
@@ -30,8 +31,10 @@ export function convertIn(v: string | null, type?: "text" | "float" | "int") {
|
|
|
30
31
|
* Makes sure our international number format is converted to js int/float format.
|
|
31
32
|
* Right now assumes . for thousands and , for decimal.
|
|
32
33
|
*/
|
|
34
|
+
/** @deprecated Use OmegaForm instead */
|
|
33
35
|
export const prepareNumberForLocale = (v: string) => v.replace(/\./g, "").replace(/,/g, ".")
|
|
34
36
|
|
|
37
|
+
/** @deprecated Use OmegaForm instead */
|
|
35
38
|
export function convertOutInt(v: string, type?: "text" | "float" | "int") {
|
|
36
39
|
v = v == null ? v : v.trim()
|
|
37
40
|
const c = v === ""
|
|
@@ -49,6 +52,7 @@ export function convertOutInt(v: string, type?: "text" | "float" | "int") {
|
|
|
49
52
|
return c
|
|
50
53
|
}
|
|
51
54
|
|
|
55
|
+
/** @deprecated Use OmegaForm instead */
|
|
52
56
|
export function convertOut(v: string, set: (v: {} | null) => void, type?: "text" | "float" | "int") {
|
|
53
57
|
return set(convertOutInt(v, type))
|
|
54
58
|
}
|
|
@@ -143,10 +147,18 @@ function handlePropertySignature(
|
|
|
143
147
|
const typeLiteral = getObjectsAST(ps.type)
|
|
144
148
|
|
|
145
149
|
const tagPropertySignature = typeLiteral?.propertySignatures.find((_) => _.name === "_tag")
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
// unwrap single-element Union to Literal (S.Struct({ _tag: S.Literal("x") }) wraps as Union([Literal("x")]))
|
|
151
|
+
const tagType = tagPropertySignature
|
|
152
|
+
? S.AST.isUnion(tagPropertySignature.type)
|
|
153
|
+
&& tagPropertySignature.type.types.length === 1
|
|
154
|
+
&& S.AST.isLiteral(tagPropertySignature.type.types[0]!)
|
|
155
|
+
? tagPropertySignature.type.types[0]!
|
|
156
|
+
: tagPropertySignature.type
|
|
157
|
+
: undefined
|
|
158
|
+
const tagLiteral = tagType
|
|
159
|
+
&& S.AST.isLiteral(tagType)
|
|
160
|
+
&& typeof tagType.literal === "string"
|
|
161
|
+
? tagType.literal
|
|
150
162
|
: void 0
|
|
151
163
|
|
|
152
164
|
const toRet = handlePropertySignature(ps)
|
|
@@ -189,6 +201,7 @@ function handlePropertySignature(
|
|
|
189
201
|
}
|
|
190
202
|
}
|
|
191
203
|
|
|
204
|
+
/** @deprecated Use OmegaForm instead */
|
|
192
205
|
export function buildFieldInfoFromFields<
|
|
193
206
|
From extends Record<PropertyKey, any>,
|
|
194
207
|
To extends Record<PropertyKey, any>
|
|
@@ -198,6 +211,7 @@ export function buildFieldInfoFromFields<
|
|
|
198
211
|
return buildFieldInfoFromFieldsRoot(schema).fields
|
|
199
212
|
}
|
|
200
213
|
|
|
214
|
+
/** @deprecated Use OmegaForm instead */
|
|
201
215
|
export function buildFieldInfoFromFieldsRoot<
|
|
202
216
|
From extends Record<PropertyKey, any>,
|
|
203
217
|
To extends Record<PropertyKey, any>,
|
|
@@ -235,7 +249,9 @@ abstract class PhantomTypeParameter<
|
|
|
235
249
|
|
|
236
250
|
const defaultIntl = createIntl({ locale: "en" })
|
|
237
251
|
|
|
252
|
+
/** @deprecated Use OmegaForm instead */
|
|
238
253
|
export const translate = ref<IntlFormatters["formatMessage"]>(defaultIntl.formatMessage)
|
|
254
|
+
/** @deprecated Use OmegaForm instead */
|
|
239
255
|
export const customSchemaErrors = ref<Map<S.AST.AST | string, (message: string, e: unknown, v: unknown) => string>>(
|
|
240
256
|
new Map()
|
|
241
257
|
)
|
|
@@ -269,7 +285,7 @@ function buildFieldInfo(
|
|
|
269
285
|
}
|
|
270
286
|
|
|
271
287
|
// parse specific error types for better translation support
|
|
272
|
-
const integerMatch = err.match(/Expected.*integer.*actual\s+(
|
|
288
|
+
const integerMatch = err.match(/Expected.*integer.*(?:actual|got)\s+([^)]+)/i)
|
|
273
289
|
if (integerMatch) {
|
|
274
290
|
return translate.value(
|
|
275
291
|
{ defaultMessage: "Expected an integer, actual {actualValue}", id: "validation.integer.expected" },
|
|
@@ -277,7 +293,7 @@ function buildFieldInfo(
|
|
|
277
293
|
)
|
|
278
294
|
}
|
|
279
295
|
|
|
280
|
-
const numberMatch = err.match(/Expected.*number.*actual\s+(
|
|
296
|
+
const numberMatch = err.match(/Expected.*number.*(?:actual|got)\s+([^)]+)/i)
|
|
281
297
|
if (numberMatch) {
|
|
282
298
|
return translate.value(
|
|
283
299
|
{ defaultMessage: "Expected a number, actual {actualValue}", id: "validation.number.expected" },
|
|
@@ -398,6 +414,7 @@ function buildFieldInfo(
|
|
|
398
414
|
return info as any
|
|
399
415
|
}
|
|
400
416
|
|
|
417
|
+
/** @deprecated Use OmegaForm instead */
|
|
401
418
|
export function getMetadataFromSchema(
|
|
402
419
|
ast: S.AST.AST
|
|
403
420
|
): {
|
package/src/makeClient.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
3
2
|
import { type InvalidateOptions, type InvalidateQueryFilters, isCancelledError, type QueryObserverResult, type RefetchOptions, type UseQueryReturnType } from "@tanstack/vue-query"
|
|
4
3
|
import { camelCase } from "change-case"
|
|
5
4
|
import { Cause, Data, Effect, Exit, Layer, type ManagedRuntime, Match, Option, S, ServiceMap, Struct } from "effect-app"
|
|
@@ -10,6 +9,7 @@ import { constant, identity, pipe, tuple } from "effect-app/Function"
|
|
|
10
9
|
import { type OperationFailure, OperationSuccess } from "effect-app/Operations"
|
|
11
10
|
import { dropUndefinedT, extendM } from "effect-app/utils"
|
|
12
11
|
import { type Fiber } from "effect/Fiber"
|
|
12
|
+
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
13
13
|
import { computed, type ComputedRef, onBeforeUnmount, type Ref, ref, watch, type WatchSource } from "vue"
|
|
14
14
|
import { reportMessage } from "./errorReporter.js"
|
|
15
15
|
import { type Commander, CommanderStatic } from "./experimental/commander.js"
|
|
@@ -20,6 +20,7 @@ import { buildFieldInfoFromFieldsRoot } from "./form.js"
|
|
|
20
20
|
import { reportRuntimeError } from "./lib.js"
|
|
21
21
|
import { asResult, makeMutation, type MutationOptions, type MutationOptionsBase, mutationResultToVue, type Res, useMakeMutation } from "./mutate.js"
|
|
22
22
|
import { type CustomUndefinedInitialQueryOptions, makeQuery } from "./query.js"
|
|
23
|
+
import { makeRunPromise } from "./runtime.js"
|
|
23
24
|
|
|
24
25
|
const mapHandler = <A, E, R, I = void, A2 = A, E2 = E, R2 = R>(
|
|
25
26
|
handler: Effect.Effect<A, E, R> | ((i: I) => Effect.Effect<A, E, R>),
|
|
@@ -1023,7 +1024,7 @@ export class LegacyMutationImpl<RT> {
|
|
|
1023
1024
|
const isDirty = ref(false)
|
|
1024
1025
|
const isValid = ref(true)
|
|
1025
1026
|
const isLoading = ref(false)
|
|
1026
|
-
const runPromise =
|
|
1027
|
+
const runPromise = makeRunPromise(this.getRuntime())
|
|
1027
1028
|
|
|
1028
1029
|
const submit1 =
|
|
1029
1030
|
(onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, never>) =>
|
|
@@ -1163,7 +1164,7 @@ export class QueryImpl<R> {
|
|
|
1163
1164
|
} = <Arg, E, A, Request extends Req, Name extends string>(
|
|
1164
1165
|
self: RequestHandlerWithInput<Arg, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>
|
|
1165
1166
|
) => {
|
|
1166
|
-
const runPromise =
|
|
1167
|
+
const runPromise = makeRunPromise(this.getRuntime())
|
|
1167
1168
|
const q = this.useQuery(self as any) as any
|
|
1168
1169
|
return (argOrOptions?: any, options?: any) => {
|
|
1169
1170
|
const [resultRef, latestRef, fetch, uqrt] = q(argOrOptions, { ...options, suspense: true } // experimental_prefetchInRender: true }
|
package/src/mutate.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
3
2
|
import { type InvalidateOptions, type InvalidateQueryFilters, type QueryClient, useQueryClient } from "@tanstack/vue-query"
|
|
4
3
|
import { type Cause, Effect, type Exit, Option } from "effect-app"
|
|
5
4
|
import { type Req } from "effect-app/client"
|
|
6
5
|
import type { ClientForOptions, RequestHandler, RequestHandlerWithInput } from "effect-app/client/clientFor"
|
|
7
6
|
import { tuple } from "effect-app/Function"
|
|
7
|
+
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
8
8
|
import { computed, type ComputedRef, shallowRef } from "vue"
|
|
9
9
|
import { makeQueryKey } from "./lib.js"
|
|
10
10
|
|
package/src/query.ts
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
5
|
-
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
6
5
|
import { type DefaultError, type Enabled, type InitialDataFunction, type NonUndefinedGuard, type PlaceholderDataFunction, type QueryKey, type QueryObserverOptions, type QueryObserverResult, type RefetchOptions, useQuery as useTanstackQuery, useQueryClient, type UseQueryDefinedReturnType, type UseQueryReturnType } from "@tanstack/vue-query"
|
|
7
|
-
import { Array, Cause, Effect,
|
|
6
|
+
import { Array, Cause, Effect, Option, S, type ServiceMap } from "effect-app"
|
|
8
7
|
import { type Req } from "effect-app/client"
|
|
9
8
|
import type { RequestHandler, RequestHandlerWithInput } from "effect-app/client/clientFor"
|
|
10
9
|
import { ServiceUnavailableError } from "effect-app/client/errors"
|
|
11
10
|
import { type Span } from "effect/Tracer"
|
|
12
11
|
import { isHttpClientError } from "effect/unstable/http/HttpClientError"
|
|
12
|
+
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
13
13
|
import { computed, type ComputedRef, type MaybeRefOrGetter, ref, shallowRef, watch, type WatchSource } from "vue"
|
|
14
14
|
import { makeQueryKey, reportRuntimeError } from "./lib.js"
|
|
15
|
+
import { makeRunPromise } from "./runtime.js"
|
|
15
16
|
|
|
16
17
|
// we must use interface extends, or we get the dreaded typescript error of isn't portable blabla @tanstack/vue-query/build/modern/types.js
|
|
17
18
|
// but because how they are dealing with some extends clause, we loose all properties except initialData
|
|
@@ -131,13 +132,7 @@ export const makeQuery = <R>(getRuntime: () => ServiceMap.ServiceMap<R>) => {
|
|
|
131
132
|
// TODO
|
|
132
133
|
) => {
|
|
133
134
|
// we wrap into KnownFiberFailure because we want to keep the full cause of the failure.
|
|
134
|
-
const runPromise =
|
|
135
|
-
_.then(
|
|
136
|
-
Exit.match({
|
|
137
|
-
onFailure: (cause) => Promise.reject(new KnownFiberFailure(cause)),
|
|
138
|
-
onSuccess: (value) => Promise.resolve(value)
|
|
139
|
-
})
|
|
140
|
-
))
|
|
135
|
+
const runPromise = makeRunPromise(getRuntime())
|
|
141
136
|
const arr = arg
|
|
142
137
|
const req: { value: I } = !arg
|
|
143
138
|
? undefined
|
|
@@ -151,9 +146,20 @@ export const makeQuery = <R>(getRuntime: () => ServiceMap.ServiceMap<R>) => {
|
|
|
151
146
|
const queryKey = makeQueryKey(q)
|
|
152
147
|
const handler = q.handler
|
|
153
148
|
|
|
149
|
+
const defaultOptions = {
|
|
150
|
+
// we do not want to throw errors, because we turn the success and error responses into a Result type
|
|
151
|
+
// why don't we turn the error/success response into a Result type before returning to tanstack query? because we want to leverage tanstack query's retry and caching mechanism, which relies on throwing errors to trigger retries, and we don't want to interfere with that by catching the errors too early.
|
|
152
|
+
// but if we allow tanstack query to throw, it will trigger the error boundary in Vue - via a "watcher callback" error - which we currently report and log, which is not what we want.
|
|
153
|
+
// TODO: we might want to rethink the strategy of how to handle errors that happen after the initial load.
|
|
154
|
+
// For suspense, the initial load is captured by the suspense boundary.
|
|
155
|
+
// For subsequent loads (or non suspense use) we currently are required to use the QueryResult component to conditionally render error/loading/etc.
|
|
156
|
+
throwOnError: false
|
|
157
|
+
}
|
|
158
|
+
|
|
154
159
|
const r = useTanstackQuery<A, KnownFiberFailure<E>, TData>(
|
|
155
160
|
Effect.isEffect(handler)
|
|
156
161
|
? {
|
|
162
|
+
...defaultOptions,
|
|
157
163
|
...options,
|
|
158
164
|
retry: (retryCount, error) => {
|
|
159
165
|
if (error instanceof KnownFiberFailure) {
|
|
@@ -177,6 +183,7 @@ export const makeQuery = <R>(getRuntime: () => ServiceMap.ServiceMap<R>) => {
|
|
|
177
183
|
)
|
|
178
184
|
}
|
|
179
185
|
: {
|
|
186
|
+
...defaultOptions,
|
|
180
187
|
...options,
|
|
181
188
|
retry: (retryCount, error) => {
|
|
182
189
|
if (error instanceof KnownFiberFailure) {
|
package/src/runtime.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { ManagedRuntime } from "effect"
|
|
1
|
+
import { Exit, flow, ManagedRuntime } from "effect"
|
|
2
2
|
import { Effect, Layer, Logger } from "effect-app"
|
|
3
|
+
import { type ServiceMap } from "effect-app/ServiceMap"
|
|
4
|
+
import { KnownFiberFailure } from "./query.js"
|
|
3
5
|
|
|
4
6
|
export function makeAppRuntime<A, E>(layer: Layer.Layer<A, E>) {
|
|
5
7
|
return Effect.gen(function*() {
|
|
@@ -29,3 +31,13 @@ export function initializeAsync<A, E>(layer: Layer.Layer<A, E, never>) {
|
|
|
29
31
|
return Effect
|
|
30
32
|
.runPromise(makeAppRuntime(layer))
|
|
31
33
|
}
|
|
34
|
+
|
|
35
|
+
// we wrap into KnownFiberFailure because we want to keep the full cause of the failure.
|
|
36
|
+
export const makeRunPromise = <T>(services: ServiceMap<T>) =>
|
|
37
|
+
flow(Effect.runPromiseExitWith(services), (_) =>
|
|
38
|
+
_.then(
|
|
39
|
+
Exit.match({
|
|
40
|
+
onFailure: (cause) => Promise.reject(new KnownFiberFailure(cause)),
|
|
41
|
+
onSuccess: (value) => Promise.resolve(value)
|
|
42
|
+
})
|
|
43
|
+
))
|
package/test/dist/stubs.d.ts
CHANGED
|
@@ -23,16 +23,12 @@ declare const RequestContextMap_base: (new () => {
|
|
|
23
23
|
};
|
|
24
24
|
export declare class RequestContextMap extends RequestContextMap_base {
|
|
25
25
|
}
|
|
26
|
-
export declare const Req: <
|
|
26
|
+
export declare const Req: <Self>() => {
|
|
27
27
|
<Tag extends string, Payload extends S.Struct.Fields, C extends {
|
|
28
28
|
success: S.Top | S.Struct.Fields;
|
|
29
29
|
error: S.Top | S.Struct.Fields;
|
|
30
|
-
}>(tag: Tag, fields: Payload, config: RpcContextMap.GetContextConfig<{}> & C): S.TaggedStruct<Tag, Payload> & {
|
|
31
|
-
new (...args: any[]): any;
|
|
30
|
+
}>(tag: Tag, fields: Payload, config: RpcContextMap.GetContextConfig<{}> & C): S.EnhancedClass<Self, S.TaggedStruct<Tag, Payload>, {}> & {
|
|
32
31
|
readonly _tag: Tag;
|
|
33
|
-
readonly fields: {
|
|
34
|
-
readonly _tag: S.tag<Tag>;
|
|
35
|
-
} & Payload;
|
|
36
32
|
readonly success: C["success"] extends infer T ? T extends C["success"] ? T extends S.Top ? T : T extends S.Struct.Fields ? S.Struct<T> : S.Void : never : never;
|
|
37
33
|
readonly error: C extends {
|
|
38
34
|
error: infer E;
|
|
@@ -41,16 +37,15 @@ export declare const Req: <_Self>() => {
|
|
|
41
37
|
readonly "~decodingServices": S.Codec.DecodingServices<C["success"] extends infer T_1 ? T_1 extends C["success"] ? T_1 extends S.Top ? T_1 : T_1 extends S.Struct.Fields ? S.Struct<T_1> : S.Void : never : never> | S.Codec.DecodingServices<C extends {
|
|
42
38
|
error: infer E;
|
|
43
39
|
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never>;
|
|
40
|
+
readonly "~encodingServices": S.Codec.EncodingServices<C["success"] extends infer T_2 ? T_2 extends C["success"] ? T_2 extends S.Top ? T_2 : T_2 extends S.Struct.Fields ? S.Struct<T_2> : S.Void : never : never> | S.Codec.EncodingServices<C extends {
|
|
41
|
+
error: infer E;
|
|
42
|
+
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never>;
|
|
44
43
|
};
|
|
45
44
|
<Tag extends string, Payload_1 extends S.Struct.Fields, C_1 extends Pick<{
|
|
46
45
|
success: S.Top | S.Struct.Fields;
|
|
47
46
|
error: S.Top | S.Struct.Fields;
|
|
48
|
-
}, "success">>(tag: Tag, fields: Payload_1, config: RpcContextMap.GetContextConfig<{}> & C_1): S.TaggedStruct<Tag, Payload_1> & {
|
|
49
|
-
new (...args: any[]): any;
|
|
47
|
+
}, "success">>(tag: Tag, fields: Payload_1, config: RpcContextMap.GetContextConfig<{}> & C_1): S.EnhancedClass<Self, S.TaggedStruct<Tag, Payload_1>, {}> & {
|
|
50
48
|
readonly _tag: Tag;
|
|
51
|
-
readonly fields: {
|
|
52
|
-
readonly _tag: S.tag<Tag>;
|
|
53
|
-
} & Payload_1;
|
|
54
49
|
readonly success: C_1["success"] extends infer T ? T extends C_1["success"] ? T extends S.Top ? T : T extends S.Struct.Fields ? S.Struct<T> : S.Void : never : never;
|
|
55
50
|
readonly error: C_1 extends {
|
|
56
51
|
error: infer E;
|
|
@@ -59,17 +54,16 @@ export declare const Req: <_Self>() => {
|
|
|
59
54
|
readonly "~decodingServices": S.Codec.DecodingServices<C_1["success"] extends infer T_1 ? T_1 extends C_1["success"] ? T_1 extends S.Top ? T_1 : T_1 extends S.Struct.Fields ? S.Struct<T_1> : S.Void : never : never> | S.Codec.DecodingServices<C_1 extends {
|
|
60
55
|
error: infer E;
|
|
61
56
|
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never>;
|
|
57
|
+
readonly "~encodingServices": S.Codec.EncodingServices<C_1["success"] extends infer T_2 ? T_2 extends C_1["success"] ? T_2 extends S.Top ? T_2 : T_2 extends S.Struct.Fields ? S.Struct<T_2> : S.Void : never : never> | S.Codec.EncodingServices<C_1 extends {
|
|
58
|
+
error: infer E;
|
|
59
|
+
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never>;
|
|
62
60
|
};
|
|
63
61
|
<Tag extends string, Payload_2 extends S.Struct.Fields, C_2 extends Pick<{
|
|
64
62
|
success: S.Top | S.Struct.Fields;
|
|
65
63
|
error: S.Top | S.Struct.Fields;
|
|
66
|
-
}, "error">>(tag: Tag, fields: Payload_2, config: RpcContextMap.GetContextConfig<{}> & C_2): S.TaggedStruct<Tag, Payload_2> & {
|
|
67
|
-
new (...args: any[]): any;
|
|
64
|
+
}, "error">>(tag: Tag, fields: Payload_2, config: RpcContextMap.GetContextConfig<{}> & C_2): S.EnhancedClass<Self, S.TaggedStruct<Tag, Payload_2>, {}> & {
|
|
68
65
|
readonly _tag: Tag;
|
|
69
|
-
readonly
|
|
70
|
-
readonly _tag: S.tag<Tag>;
|
|
71
|
-
} & Payload_2;
|
|
72
|
-
readonly success: S.Codec<void, void, never, never>;
|
|
66
|
+
readonly success: S.decodeTo<S.Any, S.declare<unknown, unknown>, never, never>;
|
|
73
67
|
readonly error: C_2 extends {
|
|
74
68
|
error: infer E;
|
|
75
69
|
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never;
|
|
@@ -77,14 +71,13 @@ export declare const Req: <_Self>() => {
|
|
|
77
71
|
readonly "~decodingServices": S.Codec.DecodingServices<C_2 extends {
|
|
78
72
|
error: infer E;
|
|
79
73
|
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never>;
|
|
74
|
+
readonly "~encodingServices": S.Codec.EncodingServices<C_2 extends {
|
|
75
|
+
error: infer E;
|
|
76
|
+
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never>;
|
|
80
77
|
};
|
|
81
|
-
<Tag extends string, Payload_3 extends S.Struct.Fields, C_3 extends Record<string, any>>(tag: Tag, fields: Payload_3, config: C_3 & RpcContextMap.GetContextConfig<{}>): S.TaggedStruct<Tag, Payload_3> & {
|
|
82
|
-
new (...args: any[]): any;
|
|
78
|
+
<Tag extends string, Payload_3 extends S.Struct.Fields, C_3 extends Record<string, any>>(tag: Tag, fields: Payload_3, config: C_3 & RpcContextMap.GetContextConfig<{}>): S.EnhancedClass<Self, S.TaggedStruct<Tag, Payload_3>, {}> & {
|
|
83
79
|
readonly _tag: Tag;
|
|
84
|
-
readonly
|
|
85
|
-
readonly _tag: S.tag<Tag>;
|
|
86
|
-
} & Payload_3;
|
|
87
|
-
readonly success: S.Codec<void, void, never, never>;
|
|
80
|
+
readonly success: S.decodeTo<S.Any, S.declare<unknown, unknown>, never, never>;
|
|
88
81
|
readonly error: C_3 extends {
|
|
89
82
|
error: infer E;
|
|
90
83
|
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never;
|
|
@@ -92,48 +85,37 @@ export declare const Req: <_Self>() => {
|
|
|
92
85
|
readonly "~decodingServices": S.Codec.DecodingServices<C_3 extends {
|
|
93
86
|
error: infer E;
|
|
94
87
|
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never>;
|
|
88
|
+
readonly "~encodingServices": S.Codec.EncodingServices<C_3 extends {
|
|
89
|
+
error: infer E;
|
|
90
|
+
} ? E extends S.Top ? E : E extends S.Struct.Fields ? S.Struct<E> : S.Void : never>;
|
|
95
91
|
};
|
|
96
|
-
<Tag extends string, Payload_4 extends S.Struct.Fields>(tag: Tag, fields: Payload_4): S.TaggedStruct<Tag, Payload_4> & {
|
|
97
|
-
new (...args: any[]): any;
|
|
92
|
+
<Tag extends string, Payload_4 extends S.Struct.Fields>(tag: Tag, fields: Payload_4): S.EnhancedClass<Self, S.TaggedStruct<Tag, Payload_4>, {}> & {
|
|
98
93
|
readonly _tag: Tag;
|
|
99
|
-
readonly
|
|
100
|
-
readonly _tag: S.tag<Tag>;
|
|
101
|
-
} & Payload_4;
|
|
102
|
-
readonly success: S.Codec<void, void, never, never>;
|
|
94
|
+
readonly success: S.decodeTo<S.Any, S.declare<unknown, unknown>, never, never>;
|
|
103
95
|
readonly error: never;
|
|
104
96
|
readonly config: Record<string, never>;
|
|
105
97
|
readonly "~decodingServices": never;
|
|
98
|
+
readonly "~encodingServices": never;
|
|
106
99
|
};
|
|
107
100
|
};
|
|
108
|
-
declare const GetSomething2_base: S.TaggedStruct<"GetSomething2", {
|
|
101
|
+
declare const GetSomething2_base: S.EnhancedClass<GetSomething2, S.TaggedStruct<"GetSomething2", {
|
|
109
102
|
id: S.String;
|
|
110
|
-
}> & {
|
|
111
|
-
new (...args: any[]): any;
|
|
103
|
+
}>, {}> & {
|
|
112
104
|
readonly _tag: "GetSomething2";
|
|
113
|
-
readonly
|
|
114
|
-
readonly _tag: S.tag<"GetSomething2">;
|
|
115
|
-
} & {
|
|
116
|
-
id: S.String;
|
|
117
|
-
};
|
|
118
|
-
readonly success: S.NumberFromString;
|
|
105
|
+
readonly success: S.FiniteFromString;
|
|
119
106
|
readonly error: never;
|
|
120
107
|
readonly config: Omit<{
|
|
121
|
-
success: S.
|
|
108
|
+
success: S.FiniteFromString;
|
|
122
109
|
}, "success" | "error">;
|
|
123
110
|
readonly "~decodingServices": never;
|
|
111
|
+
readonly "~encodingServices": never;
|
|
124
112
|
};
|
|
125
113
|
export declare class GetSomething2 extends GetSomething2_base {
|
|
126
114
|
}
|
|
127
|
-
declare const GetSomething2WithDependencies_base: S.TaggedStruct<"GetSomething2", {
|
|
115
|
+
declare const GetSomething2WithDependencies_base: S.EnhancedClass<GetSomething2WithDependencies, S.TaggedStruct<"GetSomething2", {
|
|
128
116
|
id: S.String;
|
|
129
|
-
}> & {
|
|
130
|
-
new (...args: any[]): any;
|
|
117
|
+
}>, {}> & {
|
|
131
118
|
readonly _tag: "GetSomething2";
|
|
132
|
-
readonly fields: {
|
|
133
|
-
readonly _tag: S.tag<"GetSomething2">;
|
|
134
|
-
} & {
|
|
135
|
-
id: S.String;
|
|
136
|
-
};
|
|
137
119
|
readonly success: S.Codec<number, string, "dep-a", never>;
|
|
138
120
|
readonly error: S.String;
|
|
139
121
|
readonly config: Omit<{
|
|
@@ -141,6 +123,7 @@ declare const GetSomething2WithDependencies_base: S.TaggedStruct<"GetSomething2"
|
|
|
141
123
|
error: S.String;
|
|
142
124
|
}, "success" | "error">;
|
|
143
125
|
readonly "~decodingServices": "dep-a";
|
|
126
|
+
readonly "~encodingServices": never;
|
|
144
127
|
};
|
|
145
128
|
export declare class GetSomething2WithDependencies extends GetSomething2WithDependencies_base {
|
|
146
129
|
}
|
package/test/dist/stubs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stubs.d.ts","sourceRoot":"","sources":["../stubs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,oCAAoC,CAAA;AAE9E,OAAO,EAAU,KAAK,EAA0B,CAAC,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAiB,MAAM,mBAAmB,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAG9C,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAElD,OAAO,KAAK,KAAK,MAAM,8BAA8B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAc,MAAM,sBAAsB,CAAA;AACjE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;AA8CxD,eAAO,MAAM,YAAY,GAAI,WAAU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAM,KAepG,UAAU,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAClD,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,WAAU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAM,oCACpC,CAAA;AAExE,eAAO,MAAM,eAAe,GAC1B,UAAU;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,GAAG,EAAE,CAAA;CAAE,6GASxG,CAAA;;;;;;;;AAED,qBAAa,iBAAkB,SAAQ,sBAAyB;CAAG;AACnE,eAAO,MAAuB,GAAG
|
|
1
|
+
{"version":3,"file":"stubs.d.ts","sourceRoot":"","sources":["../stubs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,oCAAoC,CAAA;AAE9E,OAAO,EAAU,KAAK,EAA0B,CAAC,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAiB,MAAM,mBAAmB,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAG9C,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAElD,OAAO,KAAK,KAAK,MAAM,8BAA8B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAc,MAAM,sBAAsB,CAAA;AACjE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;AA8CxD,eAAO,MAAM,YAAY,GAAI,WAAU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAM,KAepG,UAAU,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAClD,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,WAAU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAM,oCACpC,CAAA;AAExE,eAAO,MAAM,eAAe,GAC1B,UAAU;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,GAAG,EAAE,CAAA;CAAE,6GASxG,CAAA;;;;;;;;AAED,qBAAa,iBAAkB,SAAQ,sBAAyB;CAAG;AACnE,eAAO,MAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAqC,CAAA;;;;;;;;;;;;;AACtE,qBAAa,aAAc,SAAQ,kBAEA;CAAG;;;;;;;;iBAML,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC;;;;;;AAJjE,qBAAa,6BAA8B,SAAQ,kCAMjD;CAAG;AAEL,eAAO,MAAM,SAAS;;;;;;CAA+F,CAAA;AAErH,eAAO,MAAM,SAAS,GACpB,UAAU;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,GAAG,EAAE,CAAA;CAAE;;;;;;;;;CAcxG,CAAA"}
|
package/test/dist/stubs.js
CHANGED
|
@@ -79,13 +79,13 @@ export class RequestContextMap extends RpcContextMap.makeMap({}) {
|
|
|
79
79
|
export const { TaggedRequest: Req } = makeRpcClient(RequestContextMap);
|
|
80
80
|
export class GetSomething2 extends Req()("GetSomething2", {
|
|
81
81
|
id: S.String
|
|
82
|
-
}, { success: S.
|
|
82
|
+
}, { success: S.FiniteFromString }) {
|
|
83
83
|
}
|
|
84
84
|
export class GetSomething2WithDependencies extends Req()("GetSomething2", {
|
|
85
85
|
id: S.String
|
|
86
86
|
}, {
|
|
87
87
|
// this is intentilally fake, to simulate a codec that requires a dependency
|
|
88
|
-
success: S.
|
|
88
|
+
success: S.FiniteFromString,
|
|
89
89
|
error: S.String
|
|
90
90
|
}) {
|
|
91
91
|
}
|
|
@@ -4,7 +4,7 @@ import { buildFieldInfoFromFieldsRoot, translate } from "../src/form.js"
|
|
|
4
4
|
// test schema with integer field
|
|
5
5
|
class TestSchema extends S.Class<TestSchema>("TestSchema")({
|
|
6
6
|
integerField: S.Int,
|
|
7
|
-
numberField: S.
|
|
7
|
+
numberField: S.Finite,
|
|
8
8
|
stringField: S.String
|
|
9
9
|
}) {}
|
|
10
10
|
|
|
@@ -137,22 +137,26 @@ it("validates integer field with valid integer", () =>
|
|
|
137
137
|
.pipe(Effect.runPromise))
|
|
138
138
|
|
|
139
139
|
it("error message format matches regex pattern", () => {
|
|
140
|
-
// test the actual error message format from Effect Schema
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
expect(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const
|
|
156
|
-
expect(
|
|
157
|
-
expect(
|
|
140
|
+
// test the actual error message format from Effect Schema (both old "actual" and new "got" formats)
|
|
141
|
+
const errorMessageOld = `Expected an integer, actual 59.5`
|
|
142
|
+
const errorMessageNew = `SchemaError(Expected an integer, got 59.5)`
|
|
143
|
+
|
|
144
|
+
const oldMatch = errorMessageOld.match(/Expected.*integer.*(?:actual|got)\s+([^)]+)/i)
|
|
145
|
+
expect(oldMatch).toBeTruthy()
|
|
146
|
+
expect(oldMatch![1]).toBe("59.5")
|
|
147
|
+
|
|
148
|
+
const newMatch = errorMessageNew.match(/Expected.*integer.*(?:actual|got)\s+([^)]+)/i)
|
|
149
|
+
expect(newMatch).toBeTruthy()
|
|
150
|
+
expect(newMatch![1]).toBe("59.5")
|
|
151
|
+
|
|
152
|
+
const numberErrorOld = `Expected a number, actual "not-a-number"`
|
|
153
|
+
const numberErrorNew = `SchemaError(Expected a finite number, got "not-a-number")`
|
|
154
|
+
|
|
155
|
+
const numOldMatch = numberErrorOld.match(/Expected.*number.*(?:actual|got)\s+([^)]+)/i)
|
|
156
|
+
expect(numOldMatch).toBeTruthy()
|
|
157
|
+
expect(numOldMatch![1]).toBe("\"not-a-number\"")
|
|
158
|
+
|
|
159
|
+
const numNewMatch = numberErrorNew.match(/Expected.*number.*(?:actual|got)\s+([^)]+)/i)
|
|
160
|
+
expect(numNewMatch).toBeTruthy()
|
|
161
|
+
expect(numNewMatch![1]).toBe("\"not-a-number\"")
|
|
158
162
|
})
|
package/test/stubs.ts
CHANGED
|
@@ -95,13 +95,13 @@ export class RequestContextMap extends RpcContextMap.makeMap({}) {}
|
|
|
95
95
|
export const { TaggedRequest: Req } = makeRpcClient(RequestContextMap)
|
|
96
96
|
export class GetSomething2 extends Req<GetSomething2>()("GetSomething2", {
|
|
97
97
|
id: S.String
|
|
98
|
-
}, { success: S.
|
|
98
|
+
}, { success: S.FiniteFromString }) {}
|
|
99
99
|
|
|
100
100
|
export class GetSomething2WithDependencies extends Req<GetSomething2WithDependencies>()("GetSomething2", {
|
|
101
101
|
id: S.String
|
|
102
102
|
}, {
|
|
103
103
|
// this is intentilally fake, to simulate a codec that requires a dependency
|
|
104
|
-
success: S.
|
|
104
|
+
success: S.FiniteFromString as S.Codec<number, string, "dep-a">,
|
|
105
105
|
error: S.String
|
|
106
106
|
}) {}
|
|
107
107
|
|