effect 4.0.0-beta.15 → 4.0.0-beta.17
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/dist/Schema.d.ts +43 -0
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +40 -2
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaParser.d.ts +5 -0
- package/dist/SchemaParser.d.ts.map +1 -1
- package/dist/SchemaParser.js +10 -0
- package/dist/SchemaParser.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +70 -3
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +79 -4
- package/dist/SchemaTransformation.js.map +1 -1
- package/dist/internal/schema/schema.js +1 -0
- package/dist/internal/schema/schema.js.map +1 -1
- package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
- package/dist/unstable/httpapi/OpenApi.js +11 -1
- package/dist/unstable/httpapi/OpenApi.js.map +1 -1
- package/package.json +1 -1
- package/src/Schema.ts +64 -2
- package/src/SchemaParser.ts +11 -0
- package/src/SchemaTransformation.ts +85 -4
- package/src/internal/schema/schema.ts +1 -0
- package/src/unstable/httpapi/OpenApi.ts +18 -1
package/src/Schema.ts
CHANGED
|
@@ -153,6 +153,7 @@ export interface Bottom<
|
|
|
153
153
|
* @throws {Error} The issue is contained in the error cause.
|
|
154
154
|
*/
|
|
155
155
|
makeUnsafe(input: this["~type.make.in"], options?: MakeOptions): this["Type"]
|
|
156
|
+
makeOption(input: this["~type.make.in"], options?: MakeOptions): Option_.Option<this["Type"]>
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
/**
|
|
@@ -1735,11 +1736,12 @@ export function encodeKeys<
|
|
|
1735
1736
|
const fields: any = {}
|
|
1736
1737
|
const reverseMapping: any = {}
|
|
1737
1738
|
for (const k in self.fields) {
|
|
1739
|
+
const encoded = toEncoded(self.fields[k])
|
|
1738
1740
|
if (Object.hasOwn(mapping, k)) {
|
|
1739
|
-
fields[mapping[k]!] =
|
|
1741
|
+
fields[mapping[k]!] = encoded
|
|
1740
1742
|
reverseMapping[mapping[k]!] = k
|
|
1741
1743
|
} else {
|
|
1742
|
-
fields[k] =
|
|
1744
|
+
fields[k] = encoded
|
|
1743
1745
|
}
|
|
1744
1746
|
}
|
|
1745
1747
|
return Struct(fields).pipe(decodeTo(
|
|
@@ -5419,6 +5421,63 @@ export function OptionFromNullOr<S extends Top>(schema: S): OptionFromNullOr<S>
|
|
|
5419
5421
|
))
|
|
5420
5422
|
}
|
|
5421
5423
|
|
|
5424
|
+
/**
|
|
5425
|
+
* @since 4.0.0
|
|
5426
|
+
*/
|
|
5427
|
+
export interface OptionFromUndefinedOr<S extends Top> extends decodeTo<Option<toType<S>>, UndefinedOr<S>> {}
|
|
5428
|
+
|
|
5429
|
+
/**
|
|
5430
|
+
* Decodes an undefined-or value `T` to a required `Option<T>` value.
|
|
5431
|
+
*
|
|
5432
|
+
* Decoding:
|
|
5433
|
+
* - `undefined` is decoded as `None`
|
|
5434
|
+
* - other values are decoded as `Some`
|
|
5435
|
+
*
|
|
5436
|
+
* Encoding:
|
|
5437
|
+
* - `None` is encoded as `undefined`
|
|
5438
|
+
* - `Some` is encoded as the value
|
|
5439
|
+
*
|
|
5440
|
+
* @category Option
|
|
5441
|
+
* @since 4.0.0
|
|
5442
|
+
*/
|
|
5443
|
+
export function OptionFromUndefinedOr<S extends Top>(schema: S): OptionFromUndefinedOr<S> {
|
|
5444
|
+
return UndefinedOr(schema).pipe(decodeTo(
|
|
5445
|
+
Option(toType(schema)),
|
|
5446
|
+
Transformation.optionFromUndefinedOr()
|
|
5447
|
+
))
|
|
5448
|
+
}
|
|
5449
|
+
|
|
5450
|
+
/**
|
|
5451
|
+
* @since 4.0.0
|
|
5452
|
+
*/
|
|
5453
|
+
export interface OptionFromNullishOr<S extends Top> extends decodeTo<Option<toType<S>>, NullishOr<S>> {}
|
|
5454
|
+
|
|
5455
|
+
/**
|
|
5456
|
+
* Decodes a nullish value `T` to a required `Option<T>` value.
|
|
5457
|
+
*
|
|
5458
|
+
* Decoding:
|
|
5459
|
+
* - `null` and `undefined` are decoded as `None`
|
|
5460
|
+
* - other values are decoded as `Some`
|
|
5461
|
+
*
|
|
5462
|
+
* Encoding:
|
|
5463
|
+
* - `None` is encoded as `null` or `undefined` depending on the provided `options.onNoneEncoding` (defaults to `undefined`)
|
|
5464
|
+
* - `Some` is encoded as the value
|
|
5465
|
+
*
|
|
5466
|
+
* @category Option
|
|
5467
|
+
* @since 4.0.0
|
|
5468
|
+
*/
|
|
5469
|
+
export function OptionFromNullishOr<S extends Top>(
|
|
5470
|
+
schema: S,
|
|
5471
|
+
options?: {
|
|
5472
|
+
onNoneEncoding: null | undefined
|
|
5473
|
+
}
|
|
5474
|
+
): OptionFromNullishOr<S> {
|
|
5475
|
+
return NullishOr(schema).pipe(decodeTo(
|
|
5476
|
+
Option(toType(schema)),
|
|
5477
|
+
Transformation.optionFromNullishOr(options)
|
|
5478
|
+
))
|
|
5479
|
+
}
|
|
5480
|
+
|
|
5422
5481
|
/**
|
|
5423
5482
|
* @since 4.0.0
|
|
5424
5483
|
*/
|
|
@@ -7978,6 +8037,9 @@ function makeClass<
|
|
|
7978
8037
|
static makeUnsafe(input: S["~type.make.in"], options?: MakeOptions): Self {
|
|
7979
8038
|
return new this(input, options)
|
|
7980
8039
|
}
|
|
8040
|
+
static makeOption(input: S["~type.make.in"], options?: MakeOptions): Option_.Option<Self> {
|
|
8041
|
+
return Parser.makeOption(getClassSchema(this) as any)(input, options) as any
|
|
8042
|
+
}
|
|
7981
8043
|
static annotate(annotations: Annotations.Declaration<Self, readonly [S]>) {
|
|
7982
8044
|
return this.rebuild(AST.annotate(this.ast, annotations))
|
|
7983
8045
|
}
|
package/src/SchemaParser.ts
CHANGED
|
@@ -53,6 +53,17 @@ export function makeEffect<S extends Schema.Top>(schema: S) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @category Constructing
|
|
58
|
+
* @since 4.0.0
|
|
59
|
+
*/
|
|
60
|
+
export function makeOption<S extends Schema.Top>(schema: S) {
|
|
61
|
+
const parser = makeEffect(schema)
|
|
62
|
+
return (input: S["~type.make.in"], options?: Schema.MakeOptions): Option.Option<S["Type"]> => {
|
|
63
|
+
return Exit.getSuccess(Effect.runSyncExit(parser(input, options) as any))
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
56
67
|
/**
|
|
57
68
|
* @category Constructing
|
|
58
69
|
* @since 4.0.0
|
|
@@ -1006,8 +1006,7 @@ export const errorFromErrorJsonEncoded = (options?: {
|
|
|
1006
1006
|
* ```
|
|
1007
1007
|
*
|
|
1008
1008
|
* See also:
|
|
1009
|
-
* - {@link
|
|
1010
|
-
* - {@link optionFromOptional}
|
|
1009
|
+
* - {@link optionFromNullishOr}
|
|
1011
1010
|
*
|
|
1012
1011
|
* @since 4.0.0
|
|
1013
1012
|
*/
|
|
@@ -1018,6 +1017,88 @@ export function optionFromNullOr<T>(): Transformation<Option.Option<T>, T | null
|
|
|
1018
1017
|
})
|
|
1019
1018
|
}
|
|
1020
1019
|
|
|
1020
|
+
/**
|
|
1021
|
+
* Decodes `T | undefined` into `Option<T>` and encodes `Option<T>` back
|
|
1022
|
+
* to `T | undefined`.
|
|
1023
|
+
*
|
|
1024
|
+
* When to use this:
|
|
1025
|
+
* - Converting undefined-or API fields to `Option`.
|
|
1026
|
+
*
|
|
1027
|
+
* Behavior:
|
|
1028
|
+
* - Decode: `undefined` → `Option.none()`, non-undefined → `Option.some(value)`.
|
|
1029
|
+
* - Encode: `Option.none()` → `undefined`, `Option.some(value)` → `value`.
|
|
1030
|
+
* - Pure and synchronous.
|
|
1031
|
+
*
|
|
1032
|
+
* **Example** (Option from undefined-or)
|
|
1033
|
+
*
|
|
1034
|
+
* ```ts
|
|
1035
|
+
* import { Schema, SchemaTransformation } from "effect"
|
|
1036
|
+
*
|
|
1037
|
+
* const schema = Schema.UndefinedOr(Schema.String).pipe(
|
|
1038
|
+
* Schema.decodeTo(
|
|
1039
|
+
* Schema.Option(Schema.String),
|
|
1040
|
+
* SchemaTransformation.optionFromUndefinedOr()
|
|
1041
|
+
* )
|
|
1042
|
+
* )
|
|
1043
|
+
* ```
|
|
1044
|
+
*
|
|
1045
|
+
* See also:
|
|
1046
|
+
* - {@link optionFromOptionalKey}
|
|
1047
|
+
* - {@link optionFromOptional}
|
|
1048
|
+
*
|
|
1049
|
+
* @since 4.0.0
|
|
1050
|
+
*/
|
|
1051
|
+
export function optionFromUndefinedOr<T>(): Transformation<Option.Option<T>, T | undefined> {
|
|
1052
|
+
return transform({
|
|
1053
|
+
decode: Option.fromUndefinedOr,
|
|
1054
|
+
encode: Option.getOrUndefined
|
|
1055
|
+
})
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
/**
|
|
1059
|
+
* Decodes `T | null | undefined` into `Option<T>` and encodes `Option<T>`
|
|
1060
|
+
* back to `T | null` or `T | undefined` depending on the provided `options.onNoneEncoding` (defaults to `undefined`).
|
|
1061
|
+
*
|
|
1062
|
+
* When to use this:
|
|
1063
|
+
* - Converting nullish API fields to `Option` when both `null` and
|
|
1064
|
+
* `undefined` represent absence.
|
|
1065
|
+
*
|
|
1066
|
+
* Behavior:
|
|
1067
|
+
* - Decode: `null` or `undefined` → `Option.none()`, otherwise → `Option.some(value)`.
|
|
1068
|
+
* - Encode: `Option.none()` → `null` or `undefined` (per `options.onNoneEncoding`),
|
|
1069
|
+
* `Option.some(value)` → `value`.
|
|
1070
|
+
* - Pure and synchronous.
|
|
1071
|
+
*
|
|
1072
|
+
* **Example** (Option from nullish, encoding None as null)
|
|
1073
|
+
*
|
|
1074
|
+
* ```ts
|
|
1075
|
+
* import { Schema, SchemaTransformation } from "effect"
|
|
1076
|
+
*
|
|
1077
|
+
* const schema = Schema.NullishOr(Schema.String).pipe(
|
|
1078
|
+
* Schema.decodeTo(
|
|
1079
|
+
* Schema.Option(Schema.String),
|
|
1080
|
+
* SchemaTransformation.optionFromNullishOr({ onNoneEncoding: null })
|
|
1081
|
+
* )
|
|
1082
|
+
* )
|
|
1083
|
+
* ```
|
|
1084
|
+
*
|
|
1085
|
+
* See also:
|
|
1086
|
+
* - {@link optionFromNullOr}
|
|
1087
|
+
* - {@link optionFromUndefinedOr}
|
|
1088
|
+
*
|
|
1089
|
+
* @since 4.0.0
|
|
1090
|
+
*/
|
|
1091
|
+
export function optionFromNullishOr<T>(
|
|
1092
|
+
options?: {
|
|
1093
|
+
onNoneEncoding: null | undefined
|
|
1094
|
+
}
|
|
1095
|
+
): Transformation<Option.Option<T>, T | null | undefined> {
|
|
1096
|
+
return transform({
|
|
1097
|
+
decode: Option.fromNullishOr,
|
|
1098
|
+
encode: options?.onNoneEncoding === null ? Option.getOrNull : Option.getOrUndefined
|
|
1099
|
+
})
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1021
1102
|
/**
|
|
1022
1103
|
* Decodes an optional struct key into `Option<T>` and encodes `Option<T>`
|
|
1023
1104
|
* back to an optional key.
|
|
@@ -1047,8 +1128,8 @@ export function optionFromNullOr<T>(): Transformation<Option.Option<T>, T | null
|
|
|
1047
1128
|
* ```
|
|
1048
1129
|
*
|
|
1049
1130
|
* See also:
|
|
1050
|
-
* - {@link optionFromNullOr}
|
|
1051
1131
|
* - {@link optionFromOptional}
|
|
1132
|
+
* - {@link optionFromUndefinedOr}
|
|
1052
1133
|
* - {@link transformOptional}
|
|
1053
1134
|
*
|
|
1054
1135
|
* @since 4.0.0
|
|
@@ -1088,8 +1169,8 @@ export function optionFromOptionalKey<T>(): Transformation<Option.Option<T>, T>
|
|
|
1088
1169
|
* ```
|
|
1089
1170
|
*
|
|
1090
1171
|
* See also:
|
|
1091
|
-
* - {@link optionFromNullOr}
|
|
1092
1172
|
* - {@link optionFromOptionalKey}
|
|
1173
|
+
* - {@link optionFromUndefinedOr}
|
|
1093
1174
|
* - {@link transformOptional}
|
|
1094
1175
|
*
|
|
1095
1176
|
* @since 4.0.0
|
|
@@ -635,9 +635,26 @@ function toEncodingAST(ast: AST.AST, _tag: HttpApiSchema.Encoding["_tag"]): AST.
|
|
|
635
635
|
return Schema.String.ast
|
|
636
636
|
case "FormUrlEncoded":
|
|
637
637
|
case "Json":
|
|
638
|
-
case "Multipart":
|
|
639
638
|
return ast
|
|
639
|
+
case "Multipart":
|
|
640
|
+
return persistedFileToBinaryEncoding(ast)
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
function persistedFileToBinaryEncoding(ast: AST.AST): AST.AST {
|
|
645
|
+
if (
|
|
646
|
+
AST.isDeclaration(ast) &&
|
|
647
|
+
((ast.annotations as (Schema.Annotations.Declaration<unknown, readonly []> | undefined))?.typeConstructor?._tag ===
|
|
648
|
+
"effect/http/PersistedFile")
|
|
649
|
+
) {
|
|
650
|
+
return Uint8ArrayEncoding.ast
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
if (typeof (ast as any)?.recur === "function") {
|
|
654
|
+
return (ast as any).recur(persistedFileToBinaryEncoding)
|
|
640
655
|
}
|
|
656
|
+
|
|
657
|
+
return ast
|
|
641
658
|
}
|
|
642
659
|
|
|
643
660
|
const makeSecurityScheme = (security: HttpApiSecurity): OpenAPISecurityScheme => {
|