@gucciogucci/contented
Advanced tools
Comparing version 2.1.0 to 3.0.0
@@ -7,3 +7,10 @@ import { ContentedError } from './ContentedError'; | ||
import { HasAtKeyInvalidCoercion, InvalidCoercion } from './InvalidCoercion'; | ||
export declare function at<T, E extends ContentedError>(pathOrKey: Path | Key, type: Type<T, E>): Type<T, InvalidCoercion | MissingKey | HasAtKeyInvalidCoercion<E, never> | HasJointAtKey<E>>; | ||
export declare type At<T> = T extends Type<infer R, infer E> ? Type<R, MissingKey | InvalidCoercion | HasAtKeyInvalidCoercion<E> | HasJointAtKey<E>> : never; | ||
export declare function at<T, E extends ContentedError, K extends Key>(pathOrKey: K, type: Type<T, E>): At<typeof type, [K]>; | ||
export declare function at<T, E extends ContentedError, P extends Path>(pathOrKey: [...P], type: Type<T, E>): At<typeof type, [...P]>; | ||
export declare type At<T, P = []> = T extends Type<infer R, infer E> ? Type<PossiblyUndefined<R, P>, MissingKeyInPath<P> | InvalidCoercion | HasAtKeyInvalidCoercion<E> | HasJointAtKey<E>> : never; | ||
declare type PossiblyUndefined<R, P> = SomeAreOptional<P> extends true ? R | undefined : R; | ||
declare type MissingKeyInPath<P> = AllAreOptional<P> extends true ? never : MissingKey; | ||
declare type SomeAreOptional<T, A = false> = A extends true ? A : T extends [infer Head, ...infer Tail] ? SomeAreOptional<Tail, IsOptional<Head>> : A; | ||
declare type AllAreOptional<T, A = true> = A extends false ? A : T extends [infer Head, ...infer Tail] ? AllAreOptional<Tail, IsOptional<Head>> : A; | ||
declare type IsOptional<T> = T extends `${any}?` ? true : false; | ||
export {}; |
@@ -5,2 +5,3 @@ "use strict"; | ||
const ContentedError_1 = require("./ContentedError"); | ||
const Path_1 = require("./Path"); | ||
const Type_1 = require("./Type"); | ||
@@ -16,9 +17,14 @@ const MissingKey_1 = require("./MissingKey"); | ||
} | ||
const path = [pathOrKey].flat(); | ||
const path = Array.isArray(pathOrKey) ? pathOrKey : [pathOrKey]; | ||
for (const [key, pos] of (0, _enumerate_1.enumerate)(path)) { | ||
if (value[key] === undefined) { | ||
const missingKey = path.slice(0, pos + 1); | ||
return new MissingKey_1.MissingKey(missingKey); | ||
value = (0, Path_1.access)(value, key); | ||
if (value === undefined) { | ||
if ((0, Path_1.isOptional)(key)) { | ||
return undefined; | ||
} | ||
else { | ||
const missingKey = (0, Path_1.slicePath)(path, pos); | ||
return new MissingKey_1.MissingKey(missingKey); | ||
} | ||
} | ||
value = value[key]; | ||
} | ||
@@ -25,0 +31,0 @@ const res = (0, Type_1.coerceTo)(type, value); |
import { ContentedError } from './ContentedError'; | ||
import { ExpectedType, Type } from './Type'; | ||
import { MissingKey } from './MissingKey'; | ||
export declare function fallback<T, E extends ContentedError>(type: Type<T, IncludesMissingKey<E>>, fallback: Fallback<T>): Type<T, Exclude<E, MissingKey>>; | ||
declare type IncludesMissingKey<E> = [MissingKey] extends [E] ? E : 'Must include MissingKey'; | ||
declare type Fallback<T> = ExpectedType<T>; | ||
export declare function fallback<T, E extends ContentedError>(type: Type<T, E>, fallback: Fallback<T>): Type<Exclude<ExpectedType<T>, undefined>, E>; | ||
declare type Fallback<T> = Exclude<ExpectedType<T>, undefined>; | ||
export {}; |
@@ -5,7 +5,6 @@ "use strict"; | ||
const Type_1 = require("./Type"); | ||
const MissingKey_1 = require("./MissingKey"); | ||
function fallback(type, fallback) { | ||
const coerce = (value) => { | ||
const res = (0, Type_1.coerceTo)(type, value); | ||
if (res instanceof MissingKey_1.MissingKey) { | ||
if (res === undefined) { | ||
return fallback; | ||
@@ -12,0 +11,0 @@ } |
import { At } from './at'; | ||
import { ContentedError } from './ContentedError'; | ||
import { InvalidCoercion } from './InvalidCoercion'; | ||
import { MissingKey } from './MissingKey'; | ||
import { ErrorType, ExpectedType, NonFatalErrorType, Type } from './Type'; | ||
@@ -9,9 +8,5 @@ import { Expand } from './_typefunc'; | ||
declare type AtInObject<O extends ObjectOfTypes> = { | ||
[K in keyof O]: K extends `${any}?` ? RemoveMissingKey<At<O[K]>> : At<O[K]>; | ||
[K in keyof O]: At<O[K], [K]>; | ||
}; | ||
declare type RemoveMissingKey<T> = [T] extends [Type<infer A, infer E>] ? Type<A, Exclude<E, MissingKey>> : never; | ||
export declare type ObjectOf<O extends ObjectOfTypes> = IsWithoutNonFatalErrors<O> extends true ? Expand<EnforceOptionality<ExpectedTypeInObject<O>>> : Expand<EnforceOptionality<ExpectedTypeInObject<O>>> | [Expand<EnforceOptionality<ExpectedTypeInObject<O>>>, NonFatalErrorTypeInObject<O>[]]; | ||
export declare type ObjectOfError<O extends ObjectOfTypes> = { | ||
[K in keyof O]: ErrorType<O[K]>; | ||
}[keyof O] | never; | ||
declare type IsWithoutNonFatalErrors<O extends ObjectOfTypes> = NonFatalErrorTypeInObject<O> extends never ? true : false; | ||
@@ -21,3 +16,3 @@ declare type NonFatalErrorTypeInObject<O extends ObjectOfTypes> = { | ||
}[keyof O]; | ||
export declare type ExpectedTypeInObject<O extends ObjectOfTypes> = { | ||
declare type ExpectedTypeInObject<O extends ObjectOfTypes> = { | ||
[K in keyof O]: ExpectedType<O[K]>; | ||
@@ -24,0 +19,0 @@ }; |
export declare type Key = string | symbol | number; | ||
export declare type Path = Key[]; | ||
export declare function access(obj: { | ||
[key: Key]: unknown; | ||
}, key: Key): unknown; | ||
export declare function isOptional(key: Key): key is string; | ||
export declare function slicePath(path: Path, pos: number): Key[]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.slicePath = exports.isOptional = exports.access = void 0; | ||
function access(obj, key) { | ||
key = removeQuestionMarkIfPresent(key); | ||
return obj[key]; | ||
} | ||
exports.access = access; | ||
function isOptional(key) { | ||
return typeof key === 'string' && key.endsWith('?'); | ||
} | ||
exports.isOptional = isOptional; | ||
function slicePath(path, pos) { | ||
return path.slice(0, pos + 1).map(removeQuestionMarkIfPresent); | ||
} | ||
exports.slicePath = slicePath; | ||
function removeQuestionMarkIfPresent(key) { | ||
return isOptional(key) ? key.slice(0, -1) : key; | ||
} |
{ | ||
"name": "@gucciogucci/contented", | ||
"description": "A library to coerce values at run-time.", | ||
"version": "2.1.0", | ||
"version": "3.0.0", | ||
"author": "Gucci <npm@gucci.com>", | ||
@@ -6,0 +6,0 @@ "license": "LGPL-3.0-only", |
@@ -238,2 +238,4 @@ <div align="center"> | ||
const isOdd = (x: any): x is number => typeof x != 'number' ? false : x % 2 === 1 | ||
coerceTo(satisfy(isOdd), 11); | ||
@@ -285,5 +287,19 @@ // 11 | ||
Similarly to [`object`](#object), optional properties are marked by adding a `?` at the end of their names; `at` returns `undefined` is some optional key is missing. | ||
```typescript | ||
import { string, at, coerceTo } from '@gucciogucci/contented'; | ||
const stringAtAB = at(['a?', 'b'], string); | ||
coerceTo(stringAtAB, { d: 3 }) | ||
// undefined | ||
coerceTo(stringAtAB, { a: { c: 'hello' } }); | ||
// MissingKey { missingKey: [ 'a', 'b' ] } | ||
``` | ||
#### `fallback(T, substitute)` | ||
`fallback` works in tandem with `at` to provide a fallback value in case the input data does not contain the specified keys. Apart from removing the possibility of a `MissingKey` error, `fallback` retains the same behavior as the `at` it wraps. | ||
`fallback` works in tandem with `at` to provide a fallback value in case the input data does not contain the specified keys. Apart from replacing possible `undefined` return value with `substitute`, `fallback` preserves the behavior of the `at` it wraps. | ||
@@ -293,3 +309,3 @@ ```typescript | ||
const numberAtAB = fallback(at(['a', 'b'], number), 42); | ||
const numberAtAB = fallback(at(['a', 'b?'], number), 42); | ||
@@ -303,3 +319,2 @@ coerceTo(numberAtAB, { a: { c: 3 } }); | ||
### Combinations | ||
@@ -306,0 +321,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
53187
704
459