@karmaniverous/entity-tools
Advanced tools
Comparing version 0.1.1 to 0.2.0
'use strict'; | ||
var defaultTranscodes = require('./defaultTranscodes.js'); | ||
var Nil = require('./Nil.js'); | ||
@@ -8,3 +9,4 @@ var sort = require('./sort.js'); | ||
exports.defaultTranscodes = defaultTranscodes.defaultTranscodes; | ||
exports.isNil = Nil.isNil; | ||
exports.sort = sort.sort; |
/** | ||
* Null or undefined. | ||
* Relates transcode keys to the types transcoded. | ||
* | ||
* @category Utilities | ||
*/ | ||
type Nil = null | undefined; | ||
/** | ||
* Tests whether a value is {@link Nil | `Nil`}. | ||
* | ||
* @param value - Value. | ||
* | ||
* @returns true if `value` is `null` or `undefined`. | ||
* | ||
* @category Utilities | ||
*/ | ||
declare const isNil: (value: unknown) => value is Nil; | ||
/** | ||
* The base TypeMap type. Relates types to the string token identifying the type in runtime code. All TypeMaps should extend this type. | ||
* | ||
* @example | ||
* ``` | ||
* interface StringifiableTypes extends TypeMap { | ||
* interface DefaultTranscodeMap extends TranscodeMap { | ||
* bigint20: bigint; | ||
* boolean: boolean; | ||
* fix6: number; | ||
* int: number; | ||
* string: string; | ||
* number: number; | ||
* boolean: boolean; | ||
* bigint: bigint; | ||
* } | ||
* ``` | ||
* | ||
* @category Type Maps | ||
* @category Transcoding | ||
*/ | ||
type TypeMap = Record<string, unknown>; | ||
type TranscodeMap = Record<string, unknown>; | ||
/** | ||
* The default {@link TypeMap | `TypeMap`} representing indexable types. | ||
* Default {@link TranscodeMap | `TranscodeMap`} supporting {@link defaultTranscodes | `defaultTranscodes`}. | ||
* | ||
* @category Type Maps | ||
* @see {@link Transcodes | `Transcodes`} | ||
* | ||
* @category Transcoding | ||
*/ | ||
interface StringifiableTypes extends TypeMap { | ||
interface DefaultTranscodeMap extends TranscodeMap { | ||
/** | ||
* Supports transcoding of `BigInt` values of up to 20 digits. See {@link defaultTranscodes | `defaultTranscodes`} for implementation details. | ||
*/ | ||
bigint20: bigint; | ||
/** | ||
* Supports transcoding of `boolean` values. See {@link defaultTranscodes | `defaultTranscodes`} for implementation details. | ||
*/ | ||
boolean: boolean; | ||
/** | ||
* Supports transcoding of fixed `number` values with up to 6 decimal places. See {@link defaultTranscodes | `defaultTranscodes`} for implementation details. | ||
*/ | ||
fix6: number; | ||
/** | ||
* Supports transcoding of integer values. See {@link defaultTranscodes | `defaultTranscodes`} for implementation details. | ||
*/ | ||
int: number; | ||
/** | ||
* Supports transcoding of `string` values. See {@link defaultTranscodes | `defaultTranscodes`} for implementation details. | ||
*/ | ||
string: string; | ||
number: number; | ||
boolean: boolean; | ||
bigint: bigint; | ||
} | ||
/** | ||
@@ -57,3 +61,76 @@ * Strips the generic `[x: string]: unknown` property from `Record<string, unknown>` type. | ||
}; | ||
/** | ||
* Maps transcode keys to their respective encoding and decoding functions. | ||
* | ||
* @typeParam T - The {@link TranscodeMap | `TranscodeMap`} type. | ||
* | ||
* @remarks | ||
* The keys of this object must exactly match the keys of the {@link TranscodeMap | `TranscodeMap`}. | ||
* | ||
* Each `encode` function must take the mapped type as an argument and return a `string`. Invalid values should throw an error. | ||
* | ||
* Each `decode` function must take a `string` as an argument and return the mapped type. | ||
* | ||
* Encoded strings should be articulated such that they sort alphanumerically is the same order as the mapped type. Numerical values should therefore be encoded at a foxed length. | ||
* | ||
* @example | ||
* ``` | ||
* interface MyTranscodeMap extends TranscodeMap { | ||
* fix6: number; | ||
* } | ||
* | ||
* const myTranscodes extends Transcodes<MyTranscodeMap> = { | ||
* fix6: { | ||
* encode: (value) => { | ||
* if ( | ||
* !isNumber(value) || | ||
* value > Number.MAX_SAFE_INTEGER / 1000000 || | ||
* value < Number.MIN_SAFE_INTEGER / 1000000 | ||
* ) | ||
* throw new Error('invalid fix6'); | ||
* | ||
* const [prefix, abs] = value < 0 ? ['n', -value] : ['p', value]; | ||
* | ||
* return `${prefix}${abs.toFixed(6).padStart(17, '0')}`; | ||
* }, | ||
* decode: (value) => { | ||
* if (!isString(value) || !/^[np][0-9]{10}\.[0-9]{6}$/.test(value)) | ||
* throw new Error('invalid encoded fix6'); | ||
* | ||
* return (value.startsWith('n') ? -1 : 1) * Number(value.slice(1)); | ||
* }, | ||
* }, | ||
* }; | ||
* | ||
* console.log(myTranscodes.fix6.encode(-123.45)); // n0000000123.450000 | ||
* console.log(myTranscodes.fix6.encode(123.45)); // p0000000123.450000 | ||
* console.log(myTranscodes.fix6.encode(100000000000123.45)); // throws error | ||
* console.log(myTranscodes.fix6.encode('foo')); // throws error | ||
* | ||
* console.log(myTranscodes.fix6.decode('n0000000123.450000')); // -123.45 (number) | ||
* console.log(myTranscodes.fix6.decode('p0000000123.450000')); // 123 (number) | ||
* console.log(myTranscodes.fix6.decode('q0000000123.450000')); // throws error | ||
* console.log(myTranscodes.fix6.decode('foo')); // throws error | ||
* ``` | ||
* | ||
* @category Transcoding | ||
*/ | ||
type Transcodes<T extends TranscodeMap> = { | ||
[P in keyof Exactify<T>]: { | ||
encode: (value: T[P]) => string; | ||
decode: (value: string) => T[P]; | ||
}; | ||
}; | ||
/** | ||
* {@link Transcodes | `Transcodes`} for {@link DefaultTranscodeMap | `DefaultTranscodeMap`}. | ||
* | ||
* See {@link https://github.com/karmaniverous/entity-tools/blob/main/src/defaultTranscodes.ts | implementation details}. | ||
* | ||
* @category Transcoding | ||
*/ | ||
declare const defaultTranscodes: Transcodes<DefaultTranscodeMap>; | ||
/** | ||
* The base Entity type. All Entities should extend this type. | ||
@@ -64,17 +141,22 @@ * | ||
type Entity = Record<string, unknown>; | ||
/** | ||
* Generates a union of the keys of an {@link Entity | `Entity`} type whose values are of a given type. | ||
* Null or undefined. | ||
* | ||
* @typeParam E - The {@link Entity | `Entity`} type. | ||
* @typeParam T - The type to filter by. | ||
* @category Utilities | ||
*/ | ||
type Nil = null | undefined; | ||
/** | ||
* Tests whether a value is {@link Nil | `Nil`}. | ||
* | ||
* @returns A union of the keys of {@link Entity | `Entity`} `E` whose values are of type `T`. | ||
* @param value - Value. | ||
* | ||
* @category Entities | ||
* @returns true if `value` is `null` or `undefined`. | ||
* | ||
* @category Utilities | ||
*/ | ||
type PropertiesOfType<E extends Entity, T> = keyof { | ||
[Property in keyof Exactify<E> as [T] extends [never] ? [NonNullable<E[Property]>] extends [never] ? Property : never : [NonNullable<E[Property]>] extends [never] ? never : NonNullable<E[Property]> extends T ? Property : never]: never; | ||
}; | ||
declare const isNil: (value: unknown) => value is Nil; | ||
/** | ||
* Generates a union of the keys of an {@link Entity | `Entity`} type whose values are not of a given type. | ||
* Returns the properties of {@link Entity | `Entity`} `E` of types that do not extend type `T`. Ignores `undefined` types. | ||
* | ||
@@ -84,4 +166,2 @@ * @typeParam E - The {@link Entity | `Entity`} type. | ||
* | ||
* @returns A union of the keys of {@link Entity | `Entity`} `E` whose values are not of type `T`. | ||
* | ||
* @category Entities | ||
@@ -92,26 +172,14 @@ */ | ||
}; | ||
/** | ||
* Generates a union of the keys of an {@link Entity | `Entity`} type that are represented in a given {@link TypeMap | `TypeMap`}. | ||
* Returns the properties of {@link Entity | `Entity`} `E` of types that extend type `T`. Ignores `undefined` types. | ||
* | ||
* @typeParam E - The {@link Entity | `Entity`} type. | ||
* @typeParam T - The {@link TypeMap | `TypeMap`}. | ||
* @typeParam T - The type to filter by. | ||
* | ||
* @returns A union of the keys of {@link Entity | `Entity`} `E` whose types are in {@link TypeMap | `TypeMap`} `T`. | ||
* | ||
* @category Entities | ||
* @category Type Maps | ||
*/ | ||
type PropertiesInTypeMap<E extends Entity, T extends TypeMap> = PropertiesOfType<E, T[keyof Exactify<T>]>; | ||
/** | ||
* Generates a union of the keys of an {@link Entity | `Entity`} type that are not represented in a given {@link TypeMap | `TypeMap`}. | ||
* | ||
* @typeParam E - The {@link Entity | `Entity`} type. | ||
* @typeParam T - The {@link TypeMap | `TypeMap`}. | ||
* | ||
* @returns A union of the keys of {@link Entity | `Entity`} `E` whose types are not in {@link TypeMap | `TypeMap`} `T`. | ||
* | ||
* @category Entities | ||
* @category Type Maps | ||
*/ | ||
type PropertiesNotInTypeMap<E extends Entity, T extends TypeMap> = PropertiesNotOfType<E, T[keyof Exactify<T>]>; | ||
type PropertiesOfType<E extends Entity, T> = keyof { | ||
[Property in keyof Exactify<E> as [T] extends [never] ? [NonNullable<E[Property]>] extends [never] ? Property : never : [NonNullable<E[Property]>] extends [never] ? never : NonNullable<E[Property]> extends T ? Property : never]: never; | ||
}; | ||
@@ -129,2 +197,3 @@ /** | ||
}[]; | ||
/** | ||
@@ -153,2 +222,24 @@ * Sort an array of `Item` progressively by `sort`. | ||
export { type Entity, type Exactify, type Nil, type PropertiesInTypeMap, type PropertiesNotInTypeMap, type PropertiesNotOfType, type PropertiesOfType, type SortOrder, type StringifiableTypes, type TypeMap, isNil, sort }; | ||
/** | ||
* Returns the properties of {@link Entity | `Entity`} `E` whose types are covered by {@link TranscodeMap | `TranscodeMap`} `T`. | ||
* | ||
* @typeParam E - The {@link Entity | `Entity`} type. | ||
* @typeParam T - The {@link TranscodeMap | `TranscodeMap`}. | ||
* | ||
* @category Transcoding | ||
* @category Entities | ||
*/ | ||
type TranscodableProperties<E extends Entity, T extends TranscodeMap> = PropertiesOfType<E, T[keyof Exactify<T>]>; | ||
/** | ||
* Returns the properties of {@link Entity | `Entity`} `E` whose types are not covered by {@link TranscodeMap | `TranscodeMap`} `T`. | ||
* | ||
* @typeParam E - The {@link Entity | `Entity`} type. | ||
* @typeParam T - The {@link TranscodeMap | `TranscodeMap`}. | ||
* | ||
* @category Transcoding | ||
* @category Entities | ||
*/ | ||
type UntranscodableProperties<E extends Entity, T extends TranscodeMap> = PropertiesNotOfType<E, T[keyof Exactify<T>]>; | ||
export { type DefaultTranscodeMap, type Entity, type Exactify, type Nil, type PropertiesNotOfType, type PropertiesOfType, type SortOrder, type TranscodableProperties, type TranscodeMap, type Transcodes, type UntranscodableProperties, defaultTranscodes, isNil, sort }; |
@@ -0,2 +1,3 @@ | ||
export { defaultTranscodes } from './defaultTranscodes.js'; | ||
export { isNil } from './Nil.js'; | ||
export { sort } from './sort.js'; |
@@ -130,3 +130,3 @@ { | ||
"types": "dist/index.d.ts", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"dependencies": { | ||
@@ -133,0 +133,0 @@ "radash": "^12.1.0" |
23118
11
513