@nunofyobiz/effect-extras 2.0.0 → 3.0.0
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/README.md +38 -3
- package/dist/ArrayX.d.ts +381 -0
- package/dist/ArrayX.d.ts.map +1 -0
- package/dist/ArrayX.js +493 -0
- package/dist/ArrayX.js.map +1 -0
- package/dist/BigIntX.d.ts +24 -0
- package/dist/BigIntX.d.ts.map +1 -0
- package/dist/BigIntX.js +30 -0
- package/dist/BigIntX.js.map +1 -0
- package/dist/BooleanX.d.ts +25 -0
- package/dist/BooleanX.d.ts.map +1 -0
- package/dist/BooleanX.js +25 -0
- package/dist/BooleanX.js.map +1 -0
- package/dist/DurationX.d.ts +73 -0
- package/dist/DurationX.d.ts.map +1 -0
- package/dist/DurationX.js +91 -0
- package/dist/DurationX.js.map +1 -0
- package/dist/EffectX.d.ts +120 -0
- package/dist/EffectX.d.ts.map +1 -0
- package/dist/EffectX.js +140 -0
- package/dist/EffectX.js.map +1 -0
- package/dist/FormDataX.d.ts +49 -0
- package/dist/FormDataX.d.ts.map +1 -0
- package/dist/FormDataX.js +42 -0
- package/dist/FormDataX.js.map +1 -0
- package/dist/InclusiveOr.d.ts +1123 -0
- package/dist/InclusiveOr.d.ts.map +1 -0
- package/dist/InclusiveOr.js +1074 -0
- package/dist/InclusiveOr.js.map +1 -0
- package/dist/MapX.d.ts +32 -0
- package/dist/MapX.d.ts.map +1 -0
- package/dist/MapX.js +49 -0
- package/dist/MapX.js.map +1 -0
- package/dist/NonNullableX.d.ts +174 -0
- package/dist/NonNullableX.d.ts.map +1 -0
- package/dist/NonNullableX.js +217 -0
- package/dist/NonNullableX.js.map +1 -0
- package/dist/NumberX.d.ts +178 -0
- package/dist/NumberX.d.ts.map +1 -0
- package/dist/NumberX.js +214 -0
- package/dist/NumberX.js.map +1 -0
- package/dist/OptionX.d.ts +187 -0
- package/dist/OptionX.d.ts.map +1 -0
- package/dist/OptionX.js +201 -0
- package/dist/OptionX.js.map +1 -0
- package/dist/OrderX.d.ts +32 -0
- package/dist/OrderX.d.ts.map +1 -0
- package/dist/OrderX.js +32 -0
- package/dist/OrderX.js.map +1 -0
- package/dist/PredicateX.d.ts +108 -0
- package/dist/PredicateX.d.ts.map +1 -0
- package/dist/PredicateX.js +111 -0
- package/dist/PredicateX.js.map +1 -0
- package/dist/PromiseX.d.ts +32 -0
- package/dist/PromiseX.d.ts.map +1 -0
- package/dist/PromiseX.js +32 -0
- package/dist/PromiseX.js.map +1 -0
- package/dist/RecordX.d.ts +450 -0
- package/dist/RecordX.d.ts.map +1 -0
- package/dist/RecordX.js +487 -0
- package/dist/RecordX.js.map +1 -0
- package/dist/ResultX.d.ts +50 -0
- package/dist/ResultX.d.ts.map +1 -0
- package/dist/ResultX.js +50 -0
- package/dist/ResultX.js.map +1 -0
- package/dist/SchemaX.d.ts +249 -0
- package/dist/SchemaX.d.ts.map +1 -0
- package/dist/SchemaX.js +243 -0
- package/dist/SchemaX.js.map +1 -0
- package/dist/SetX.d.ts +121 -0
- package/dist/SetX.d.ts.map +1 -0
- package/dist/SetX.js +137 -0
- package/dist/SetX.js.map +1 -0
- package/dist/StringX.d.ts +131 -0
- package/dist/StringX.d.ts.map +1 -0
- package/dist/StringX.js +149 -0
- package/dist/StringX.js.map +1 -0
- package/dist/StructX.d.ts +219 -0
- package/dist/StructX.d.ts.map +1 -0
- package/dist/StructX.js +173 -0
- package/dist/StructX.js.map +1 -0
- package/dist/WarnResult.d.ts +1191 -0
- package/dist/WarnResult.d.ts.map +1 -0
- package/dist/WarnResult.js +991 -0
- package/dist/WarnResult.js.map +1 -0
- package/dist/index.d.ts +23 -3772
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -1011
- package/dist/index.js.map +1 -1
- package/package.json +18 -5
- package/src/{ArrayX/ArrayX.ts → ArrayX.ts} +6 -88
- package/src/{DurationX/DurationX.ts → DurationX.ts} +1 -1
- package/src/InclusiveOr.ts +1255 -0
- package/src/{NonNullableX/NonNullableX.ts → NonNullableX.ts} +5 -0
- package/src/{OptionX/OptionX.ts → OptionX.ts} +8 -2
- package/src/{PredicateX/PredicateX.ts → PredicateX.ts} +41 -0
- package/src/{RecordX/RecordX.ts → RecordX.ts} +184 -2
- package/src/StringX.ts +210 -0
- package/src/{WarnResult/WarnResult.ts → WarnResult.ts} +297 -227
- package/src/index.ts +22 -20
- package/src/ArrayX/index.ts +0 -1
- package/src/BigIntX/index.ts +0 -1
- package/src/BooleanX/index.ts +0 -1
- package/src/DurationX/index.ts +0 -1
- package/src/EffectX/index.ts +0 -1
- package/src/FormDataX/index.ts +0 -1
- package/src/MapX/index.ts +0 -1
- package/src/NonNullableX/index.ts +0 -2
- package/src/NumberX/index.ts +0 -1
- package/src/OptionX/index.ts +0 -1
- package/src/OrderX/index.ts +0 -1
- package/src/PredicateX/index.ts +0 -1
- package/src/PromiseX/index.ts +0 -1
- package/src/RecordX/index.ts +0 -1
- package/src/ResultX/index.ts +0 -1
- package/src/SchemaX/index.ts +0 -1
- package/src/SetX/index.ts +0 -1
- package/src/StringX/StringX.ts +0 -97
- package/src/StringX/index.ts +0 -1
- package/src/StructX/index.ts +0 -1
- package/src/WarnResult/index.ts +0 -1
- /package/src/{BigIntX/BigIntX.ts → BigIntX.ts} +0 -0
- /package/src/{BooleanX/BooleanX.ts → BooleanX.ts} +0 -0
- /package/src/{EffectX/EffectX.ts → EffectX.ts} +0 -0
- /package/src/{FormDataX/FormDataX.ts → FormDataX.ts} +0 -0
- /package/src/{MapX/MapX.ts → MapX.ts} +0 -0
- /package/src/{NumberX/NumberX.ts → NumberX.ts} +0 -0
- /package/src/{OrderX/OrderX.ts → OrderX.ts} +0 -0
- /package/src/{PromiseX/PromiseX.ts → PromiseX.ts} +0 -0
- /package/src/{ResultX/ResultX.ts → ResultX.ts} +0 -0
- /package/src/{SchemaX/SchemaX.ts → SchemaX.ts} +0 -0
- /package/src/{SetX/SetX.ts → SetX.ts} +0 -0
- /package/src/{StructX/StructX.ts → StructX.ts} +0 -0
package/dist/StructX.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic, framework-agnostic extensions to Effect's `Struct` module.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.0.0
|
|
5
|
+
*/
|
|
6
|
+
import { Option, Predicate, Record, pipe } from "effect";
|
|
7
|
+
import { dual } from "effect/Function";
|
|
8
|
+
/**
|
|
9
|
+
* Builds a singleton record `{ [name]: value }` when `value` is defined, or an
|
|
10
|
+
* empty object `{}` when it is `undefined` — meant to be spread into an object
|
|
11
|
+
* literal.
|
|
12
|
+
*
|
|
13
|
+
* This is the canonical fix for `exactOptionalPropertyTypes: true` (which this
|
|
14
|
+
* repo enables for Effect Schema). Under that flag, spreading
|
|
15
|
+
* `{ key: maybeUndefined }` into an object whose key is `key?: T` is a type
|
|
16
|
+
* error: the property must be *absent*, not present-but-`undefined`. Spreading
|
|
17
|
+
* `...defined("key", maybeUndefined)` instead conditionally omits the property
|
|
18
|
+
* altogether. Note that `null` and other falsy-but-defined values (`0`, `""`,
|
|
19
|
+
* `false`) are kept — only `undefined` is dropped.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
24
|
+
*
|
|
25
|
+
* // Defined value → singleton record
|
|
26
|
+
* assert.deepStrictEqual(StructX.defined("name", "Ada"), { name: "Ada" })
|
|
27
|
+
*
|
|
28
|
+
* // undefined → property omitted entirely
|
|
29
|
+
* assert.deepStrictEqual(StructX.defined("name", undefined), {})
|
|
30
|
+
*
|
|
31
|
+
* // Falsy-but-defined values are kept
|
|
32
|
+
* assert.deepStrictEqual(StructX.defined("name", 0), { name: 0 })
|
|
33
|
+
*
|
|
34
|
+
* // Typical use: spread to conditionally include an optional field
|
|
35
|
+
* const maybeAge: number | undefined = undefined
|
|
36
|
+
* assert.deepStrictEqual({ id: 1, ...StructX.defined("age", maybeAge) }, {
|
|
37
|
+
* id: 1,
|
|
38
|
+
* })
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @category constructors
|
|
42
|
+
* @since 0.0.0
|
|
43
|
+
*/
|
|
44
|
+
export const defined = (name, value) => Predicate.isUndefined(value) ? {} : Record.singleton(name, value);
|
|
45
|
+
/**
|
|
46
|
+
* Removes every property whose value is `undefined` from `record`, narrowing
|
|
47
|
+
* each remaining property type to exclude `undefined`.
|
|
48
|
+
*
|
|
49
|
+
* The bulk counterpart of {@link defined}: instead of building one optional
|
|
50
|
+
* field, it filters a whole object. Very useful for update/patch actions where
|
|
51
|
+
* `undefined` means "leave this field unchanged" while every other value —
|
|
52
|
+
* including `null`, `0`, `""`, `false`, and `Option.none()` — means "set the
|
|
53
|
+
* field to exactly this".
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
58
|
+
*
|
|
59
|
+
* // Drops `b` (undefined) but keeps every other value, including null/0/false
|
|
60
|
+
* assert.deepStrictEqual(
|
|
61
|
+
* StructX.filterDefined({ a: "x", b: undefined, c: 0, d: null, e: false }),
|
|
62
|
+
* { a: "x", c: 0, d: null, e: false },
|
|
63
|
+
* )
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @category filtering
|
|
67
|
+
* @since 0.0.0
|
|
68
|
+
*/
|
|
69
|
+
export const filterDefined = record => Object.entries(record).reduce((accumulator, [key, value]) => ({
|
|
70
|
+
...accumulator,
|
|
71
|
+
...defined(key, value)
|
|
72
|
+
}), {});
|
|
73
|
+
/**
|
|
74
|
+
* Builds a singleton record `{ [name]: value }` when `value` is `Some`, or an
|
|
75
|
+
* empty object `{}` when it is `None` — meant to be spread into an object
|
|
76
|
+
* literal.
|
|
77
|
+
*
|
|
78
|
+
* The `Option`-valued sibling of {@link defined}: where `defined` keys off
|
|
79
|
+
* `undefined`, this keys off `Option` presence. Spread `...some("key", opt)` to
|
|
80
|
+
* conditionally include a field only when the `Option` carries a value, which
|
|
81
|
+
* stays correct under `exactOptionalPropertyTypes: true`.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* import { Option } from "effect"
|
|
86
|
+
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
87
|
+
*
|
|
88
|
+
* // Some → singleton record
|
|
89
|
+
* assert.deepStrictEqual(StructX.some("name", Option.some("Ada")), {
|
|
90
|
+
* name: "Ada",
|
|
91
|
+
* })
|
|
92
|
+
*
|
|
93
|
+
* // None → property omitted entirely
|
|
94
|
+
* assert.deepStrictEqual(StructX.some("name", Option.none()), {})
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* @category constructors
|
|
98
|
+
* @since 0.0.0
|
|
99
|
+
*/
|
|
100
|
+
export const some = (name, value) => Option.match(value, {
|
|
101
|
+
onSome: someValue => Record.singleton(name, someValue),
|
|
102
|
+
onNone: () => ({})
|
|
103
|
+
});
|
|
104
|
+
/**
|
|
105
|
+
* Like {@link some}, but with swapped argument order for piping. Returns a
|
|
106
|
+
* singleton record `{ [name]: value }` when the Option is `Some`, or an
|
|
107
|
+
* empty object `{}` when `None`.
|
|
108
|
+
*
|
|
109
|
+
* Internal-only — exists to support {@link pickSome} in data-last form.
|
|
110
|
+
* Not exported because the codebase has no direct callers.
|
|
111
|
+
*/
|
|
112
|
+
const someSingleton = /*#__PURE__*/dual(2, (value, name) => some(name, value));
|
|
113
|
+
export function pickSome(record, key, renameKeyTo) {
|
|
114
|
+
return pipe(Record.get(record, key), Option.flatten, someSingleton(renameKeyTo ?? key));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Builds a singleton record `{ [name]: value }` when `value` is truthy, or an
|
|
118
|
+
* empty object `{}` otherwise — meant to be spread into an object literal.
|
|
119
|
+
*
|
|
120
|
+
* Stricter than {@link defined}: it drops not just `undefined` but every falsy
|
|
121
|
+
* value (`null`, `false`, `0`, `""`, `NaN`), and narrows the value type
|
|
122
|
+
* accordingly. Use it to spread a field only when it carries a meaningful,
|
|
123
|
+
* non-falsy value.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
128
|
+
*
|
|
129
|
+
* // Truthy value → singleton record
|
|
130
|
+
* assert.deepStrictEqual(StructX.truthy("name", "Ada"), { name: "Ada" })
|
|
131
|
+
*
|
|
132
|
+
* // Falsy values → property omitted entirely
|
|
133
|
+
* assert.deepStrictEqual(StructX.truthy("name", ""), {})
|
|
134
|
+
* assert.deepStrictEqual(StructX.truthy("name", 0), {})
|
|
135
|
+
* assert.deepStrictEqual(StructX.truthy("name", false), {})
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* @category constructors
|
|
139
|
+
* @since 0.0.0
|
|
140
|
+
*/
|
|
141
|
+
export const truthy = (name, value) => Predicate.isTruthy(value) ? Record.singleton(name, value) : {};
|
|
142
|
+
/**
|
|
143
|
+
* Returns `true` when `object` has `key` set to a non-nullish value, narrowing
|
|
144
|
+
* that property to `NonNullable` on the type level.
|
|
145
|
+
*
|
|
146
|
+
* A type guard combining `hasProperty` with a nullish check: after a successful
|
|
147
|
+
* test, TypeScript treats `object[key]` as present and free of `null` /
|
|
148
|
+
* `undefined`. Handy as a predicate passed to `Array.filter` to keep only the
|
|
149
|
+
* elements whose `key` is populated.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* import { pipe } from "effect"
|
|
154
|
+
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
155
|
+
*
|
|
156
|
+
* // data-first
|
|
157
|
+
* assert.deepStrictEqual(
|
|
158
|
+
* StructX.hasNotNullableProperty({ id: "1" }, "id"),
|
|
159
|
+
* true,
|
|
160
|
+
* )
|
|
161
|
+
*
|
|
162
|
+
* // data-last (pipeable); a null value fails the guard
|
|
163
|
+
* assert.deepStrictEqual(
|
|
164
|
+
* pipe({ id: null }, StructX.hasNotNullableProperty("id")),
|
|
165
|
+
* false,
|
|
166
|
+
* )
|
|
167
|
+
* ```
|
|
168
|
+
*
|
|
169
|
+
* @category refinements
|
|
170
|
+
* @since 0.0.0
|
|
171
|
+
*/
|
|
172
|
+
export const hasNotNullableProperty = /*#__PURE__*/dual(2, (object, key) => Predicate.hasProperty(object, key) && Predicate.isNotNullish(object[key]));
|
|
173
|
+
//# sourceMappingURL=StructX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StructX.js","names":["Option","Predicate","Record","pipe","dual","defined","name","value","isUndefined","singleton","filterDefined","record","Object","entries","reduce","accumulator","key","some","match","onSome","someValue","onNone","someSingleton","pickSome","renameKeyTo","get","flatten","truthy","isTruthy","hasNotNullableProperty","object","hasProperty","isNotNullish"],"sources":["../src/StructX.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;AAKA,SAASA,MAAM,EAAEC,SAAS,EAAEC,MAAM,EAAEC,IAAI,QAAQ,QAAQ;AACxD,SAASC,IAAI,QAAQ,iBAAiB;AAkCtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,OAAO,MAAMC,OAAO,GAAGA,CACrBC,IAAO,EACPC,KAAoB,KAEpBN,SAAS,CAACO,WAAW,CAACD,KAAK,CAAC,GACxB,EAAE,GACFL,MAAM,CAACO,SAAS,CAACH,IAAI,EAAEC,KAA8B,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,OAAO,MAAMG,aAAa,GACxBC,MAAS,IAETC,MAAM,CAACC,OAAO,CAACF,MAAM,CAAC,CAACG,MAAM,CAC3B,CAACC,WAAW,EAAE,CAACC,GAAG,EAAET,KAAK,CAAC,MAAM;EAAE,GAAGQ,WAAW;EAAE,GAAGV,OAAO,CAACW,GAAG,EAAET,KAAK;AAAC,CAAE,CAAC,EAC3E,EAA2D,CAC5D;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,OAAO,MAAMU,IAAI,GAAGA,CAClBX,IAAO,EACPC,KAAuB,KAEvBP,MAAM,CAACkB,KAAK,CAACX,KAAK,EAAE;EAClBY,MAAM,EAAGC,SAAS,IAAKlB,MAAM,CAACO,SAAS,CAACH,IAAI,EAAEc,SAAS,CAAC;EACxDC,MAAM,EAAEA,CAAA,MAAO,EAAE;CAClB,CAAC;AAEJ;;;;;;;;AAQA,MAAMC,aAAa,gBAQflB,IAAI,CACN,CAAC,EACD,CACEG,KAAuB,EACvBD,IAAO,KACmBW,IAAI,CAACX,IAAI,EAAEC,KAAK,CAAC,CAC9C;AA6CD,OAAM,SAAUgB,QAAQA,CACtBZ,MAAoC,EACpCK,GAAO,EACPQ,WAAgB;EAEhB,OAAOrB,IAAI,CACTD,MAAM,CAACuB,GAAG,CAACd,MAAM,EAAEK,GAAG,CAAC,EACvBhB,MAAM,CAAC0B,OAAO,EACdJ,aAAa,CAACE,WAAW,IAAIR,GAAG,CAAC,CAClC;AACH;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,OAAO,MAAMW,MAAM,GAAGA,CACpBrB,IAAO,EACPC,KAAQ,KAERN,SAAS,CAAC2B,QAAQ,CAACrB,KAAK,CAAC,GACrBL,MAAM,CAACO,SAAS,CAACH,IAAI,EAAEC,KAAgD,CAAC,GACxE,EAAE;AAER;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,OAAO,MAAMsB,sBAAsB,gBAAGzB,IAAI,CASxC,CAAC,EACD,CACE0B,MAAS,EACTd,GAAM,KAENf,SAAS,CAAC8B,WAAW,CAACD,MAAM,EAAEd,GAAG,CAAC,IAAIf,SAAS,CAAC+B,YAAY,CAACF,MAAM,CAACd,GAAG,CAAC,CAAC,CAC5E","ignoreList":[]}
|