2.3.0 • Published 30 days ago

alwz v2.3.0

Weekly downloads
-
License
ISC
Repository
github
Last release
30 days ago

Extendable library for typecasting.

Usage

Import

Examples

import * as a from 'alwz';
// or
const a = require('alwz');

Cast

convert data with presetted converters

Examples

a.byte('3'); // 3
a.short(false); // 0
a.int(true); // 1
a.uint(Infinity); // 4294967295
a.long(NaN); // 0
a.long(['1', '2', '3']); // 1 | ['1','2','3'] => '1' => 1
a.array('abc'); // ['abc']
a.array([123, 'abc', {}, Math.max]); // [123, 'abc', {}, Math.max]

Utils

construct complex data

Examples

ensure an array output

const array = a.utils.array;
const ArrayOfUByte = array(a.ubyte);
ArrayOfUByte([undefined, true, 2.3, '4', Infinity]); // [0, 1, 2, 4, 255]

simplify multidimensional arrays processing

const array = a.utils.array;

const Bytes3dArray = array(array(array(a.byte)));

Bytes3dArray(1); // [[[1]]];
Bytes3dArray([[[null, NaN, 'a'], [true, '2', 3]], [[Infinity]]]); // [[[0, 0, 0], [1, 2, 3]], [[127]]];

create tuples

const tuple = a.utils.tuple;
const PairOfUint = tuple([a.uint, a.uint]);
PairOfUint(['abc', 3.5, 100]); // [0, 3]

const PairOfNumbers = tuple([Number, Number]);
PairOfNumbers(['abc', 3.5, 100]); // [NaN, 3.5]

Transform

create custom converters

Examples

extend an existing converter

// make boolean smarter
const bool = a.default.get('boolean')
  .clone()
  .string(function(v) { // string input processing
    if (v === 'true' || v === 'yes') {
      return true;
    } else if (v === 'false' || v === 'no') {
      return false;
    } else {
      return this.types.number(Number(v));
    }
  })
  .convert;

bool('yes'); // true
bool('no'); // false
bool('false'); // false

create specific converters

const even = new a.Converter(
  (input) => typeof input === 'number' && input % 2 === 0, // initial input check
  (input) => Number(input) % 2 === 0 ? Number(input) : 0 // fallback value generator
);

even
  .undefined(() => -2)
  .boolean((input) => input ? -4 : -6)
  .number(function(input) {
    const result = Math.trunc(Math.abs(input || 0) / 2) * 2;
    return this.is(result) ? result : this.fallback(input);
  })
  .string((input) => even.convert(Number(input)))
  .register(Array.isArray, (input) => even.convert(input[0])); // take first and try again

even.convert(8); // 8
even.convert(undefined); // -2
even.convert(true); // -4
even.convert(false); // -6
even.convert(NaN); // 0
even.convert(11); // 10
even.convert('15'); // 14
even.convert([17, 18, 19]); // 16

converters

Examples

parse colon-separated number/string records

const PathArray = a.default.get('array')
  .clone()
  .string((i) => [...i.matchAll(/\/(\w+)/g)].map((i) => i[1]))
  .convert;

const DSV2Tuple = a.utils.tuple(
  [String, String, Number, Number, String, PathArray, PathArray],
  a.default.get('array')
    .clone()
    .string((i) => i.split(':'))
    .convert
);

const input = 'user:12345:1000:1000:ordinar user:/home/user:/bin/sh';
DSV2Tuple(input); // ['user', '12345', 1000, 1000, 'ordinar user', ['home', 'user'], ['bin', 'sh']];

Selector

dynamically select convert function (based on predefined converters)

Examples

a.to('int')('24.5'); // 24
a.to('byte')(Infinity); // 127
a.to('bigint')('42.5'); // 42n

Converters

registry of predefined converters

Examples

// get list of predefined converters
Array.from(a.default.keys()); // ['boolean', 'byte', 'int', 'long', 'double', 'string', ...];

// retrieving with existence check
const Num = a.default.converter('number'); // Converter<number>
const Str = a.default.converter('string'); // Converter<string>
a.default.converter('123'); // Error

// direct retrieving
const Arr = a.default.get('array'); // Converter<Array>
const Unknown = a.default.get('123'); // undefined

presets

boolean

Examples

boolean.convert('abc'); // true
boolean.convert(Symbol.for('')); // false
boolean.convert([]); // false
boolean.convert([0]); // false
boolean.convert([false, true]); // false
boolean.convert([123]); // true

number

Examples

number.convert(Infinity); // Infinity
number.convert('42'); // 42
number.convert('abc'); // NaN
number.convert(Symbol.for('42')); // 42
number.convert(new Date('1970-01-01T00:00:00.042Z')); // 42
number.convert(['42']); // 42
number.convert([ [ [ 42 ] ] ]); // 42
number.convert(new Date('1970-01-01T00:00:00.999Z')); // 999

integers

|--------|------------------|------------------|
| type   |              min |              max |
|--------|------------------|------------------|
| byte   |             -128 |              127 |
| short  |           -32768 |            32767 |
| int    |      -2147483648 |       2147483647 |
| long   | MIN_SAFE_INTEGER | MAX_SAFE_INTEGER |
|--------|------------------|------------------|
| ubyte  |                0 |              255 |
| ushort |                0 |            65535 |
| uint   |                0 |       4294967295 |
| ulong  |                0 | MAX_SAFE_INTEGER |
|--------|------------------|------------------|

Examples

int.convert(undefined); // 0
int.convert(null); // 0
int.convert(NaN); // 0
int.convert('abc'); // 0
int.convert(true); // 1
int.convert(42.5); // 42
int.convert('42.5'); // 42
int.convert(['42.5']); // 42
int.convert(Symbol.for('42.5')); // 42
int.convert(new Date('1970-01-01T00:00:00.042Z')); // 42
int.convert(new Date(NaN)); // 0

signed

cast to byte, short (2 bytes), int (4 bytes) or long (8 bytes)

Examples

byte.convert(128); // 127
byte.convert(Infinity); // 127
byte.convert(-Infinity); // -128
short.convert(Infinity); // 32767
short.convert(-Infinity); // -32768
int.convert(Infinity); // 2147483647
int.convert(-Infinity); // -2147483648
long.convert(Infinity); // MAX_SAFE_INTEGER
long.convert(-Infinity); // MIN_SAFE_INTEGER

unsigned

cast to ubyte, ushort (2 bytes), uint (4 bytes) or ulong (8 bytes)

Examples

ubyte.convert(-7); // 0
ubyte.convert('a'); // 0
ubyte.convert(Infinity); // 255
ubyte.convert(-Infinity); // 0
ushort.convert(Infinity); // 65535
ushort.convert(-Infinity); // 0
uint.convert(Infinity); // 4294967295
uint.convert(-Infinity); // 0
ulong.convert(Infinity); // MAX_SAFE_INTEGER
ulong.convert(-Infinity); // 0

double

Examples

double.convert('42.5'); // 42.5
double.convert(Infinity); // Number.MAX_VALUE
double.convert(NaN); // 0

bigint

Examples

bigint.convert(42.5); // 42n
bigint.convert('42'); // 42n
bigint.convert('42.5'); // 0n
bigint.convert(Symbol.for('42')); // 42n
bigint.convert(new Date('1970-01-01T00:00:00.999Z')); // 999n

string

Examples

string.convert(); // ''
string.convert(null); // ''
string.convert(false); // ''
string.convert(true); // ' '
string.convert(42.5); // '42.5'
string.convert([1, 2, 3]); // '1'
string.convert(Symbol.for('42')); // '42'
string.convert(new Date('1970-01-01T00:00:00.999Z')); // '1970-01-01T00:00:00.999Z'

symbol

Examples

symbol.convert(false); // Symbol('')
symbol.convert(42.5); // Symbol('42.5')
symbol.convert('42.5'); // Symbol('42.5')
symbol.convert([1.5, 2, 3]); // Symbol('1.5')
symbol.convert(new Date('1970-01-01T00:00:00.999Z')); // Symbol('1970-01-01T00:00:00.999Z')

array

Examples

array.convert(); // []
array.convert(null); // []
array.convert(false); // [false]
array.convert(123); // [123]
array.convert('1,2,3'); // ['1,2,3']
array.convert(new Set([1, 2, 3])); // [1, 2, 3]
array.convert(new Map([[1, 2], [3, 4], [5, 6]])); // [[1, 2], [3, 4], [5, 6]]

fn

Examples

fn.convert((a, b) => a + b); // (a, b) => a + b
fn.convert(123); // () => 123

date

Examples

date.convert(111); // Date('1970-01-01T00:00:00.111Z')
date.convert([222, 333]); // Date('1970-01-01T00:00:00.222Z')
date.convert('abc'); // Date(NaN)

object

Examples

object.convert(undefined); // {}
object.convert(null); // {}
object.convert(false); // Boolean { false }
object.convert(1); // Number { 1 }
object.convert('2'); // String { 2 }
object.convert([1, '2', 3n]); // [1, '2', 3n]

map

Examples

map.convert([ [true, 1], 2, '3']); // Map { [true, 1] }

weakmap

Examples

weakmap.convert([ [Boolean, 'bool'], [Number, 'num'], [String, 'str'], [true, 1], 2, '3']); // WeakMap { [Boolean, 'bool'], [Number, 'num'], [String, 'str'] }

set

Examples

set.convert([1, '2', 3]); // Set {1, "2", 3}

weakset

Examples

weakset.convert([Boolean, Number, String, true, 2, '3']); // WeakSet { Boolean, Number, String }

promise

Examples

promise.convert(Promise.resolve(1)); // Promise { 1 }
promise.convert(42); // Promise { 42 }

Converter

converts input data to specific type

  • at first checks if conversion is necessary
  • then attempts conversion based on the input data type
  • searches among registered conversions if no matching type is found
  • generates a fallback value if no suitable conversion can be found

Parameters

  • is IS\ initial input data type checker(predicate). determines if any conversion is necessary
  • fallback Fallback\ fallback value generator. runs if none of the available conversions are suitable

Examples

converter creation

const positive = new Converter(
  (input) => typeof input === 'number' && input > 0,
  (input) => input === 0 ? 0.1 : 0.2
);

positive
  .undefined(() => 0.3)
  .boolean((i) => i ? 1 : 0.4)
  .number(function(i) {
    const result = Math.abs(i)
    return this.is(result) ? result : this.fallback(i);
  })
  .string((i) => positive.convert(Number(i)))
  .symbol((i) => positive.convert(Symbol.keyFor(i)))
  .bigint((i) => positive.convert(Number(i)))
  .register(Array.isArray, (i) => positive.convert(i[0]))
  .register((i) => i === null, (i) => 0.5);

positive.convert(1); // 1
positive.convert(0); // 0.1 (fallback)
positive.convert(NaN); // 0.2 (fallback)
positive.convert(undefined); // 0.3 (has own handler)
positive.convert(false); // 0.4 (has own handler)
positive.convert(null); // 0.5 (has own handler)
positive.convert(2n); // 2
positive.convert(-3); // 3
positive.convert('4'); // 4
positive.convert([5, 6]); // 5

conversion with prohibited input types

const converter = new Converter(
  (input) => typeof input === 'number',
  (input) => {
    throw new Error('unknown input data type:' + input);
  })
  .string((i) => {
    throw new Error('string input is forbidden:' + i);
  })
  .boolean(Number)
  .register(Array.isArray, (i) => converter.convert(i[0]));

converter.convert(true); // 1
converter.convert(2); // 2
converter.convert('3'); // Error
converter.convert([4]); // 4
converter.convert(Promise.resolve(5)); // Error

convert

converts data according to saved conversion rules

Parameters

  • input any input data

register

adds conversion function for INPUT type

Parameters

  • is IS\ input data type checker(predicate), determines if input can be processed by conversion
  • conversion Conversion\<INPUT, T> INPUT to T conversion function

unregister

removes conversion for INPUT type

Parameters

  • is IS\ input type checker(predicate)

undefined

conversion rule setter for undefined input

Parameters

  • conversion

boolean

conversion rule setter for boolean input

Parameters

  • conversion

number

conversion rule setter for number input

Parameters

  • conversion

bigint

conversion rule setter for bigint input

Parameters

  • conversion

string

conversion rule setter for string input

Parameters

  • conversion

symbol

conversion rule setter for symbol input

Parameters

  • conversion

clone

Examples

const converter = new Converter(
  (i) => typeof i === 'number',
  () => 0
)
  .undefined(() => 1);

const clone = converter
  .clone()
  .undefined(() => 2);

converter.convert(); // 1
clone.convert(); // 2

utils

extra utils functions

Examples

const { array, tuple } = a.utils;

array

constrain data to an array elements of a given type

Parameters

  • conversion Conversion\<any, T> item conversion
  • initiator Conversion\<any, Array\> input data initial conversion (optional, default presets.array.convert)

Examples

const numArray = array(Number);
numArray(); // []
numArray([]); // []
numArray([true, 2, "3", {}]); // [1, 2, 3, NaN]

sparse arrays behavior

// Be aware of sparse arrays behavior - conversion is not performed for empty items
numArray[1, , 3] // [1, , 3]

Returns Conversion\<any, Array\>

tuple

constrain data to a tuple with given types

Parameters

  • conversions Array\<Conversion\<any, any>> tuple elemets conversions
  • initiator Conversion\<any, Array\> input data initial conversion (optional, default presets.array.convert)

Examples

const tupleNumStrBool = tuple([Number, String, Boolean]);
tupleNumStrBool(); // [NaN, 'undefined', false]
tupleNumStrBool(null); // [NaN, 'undefined', false]
tupleNumStrBool([]); // [NaN, '', false]
tupleNumStrBool('5'); // [5, 'undefined', false]
tupleNumStrBool(['1', '2', '3']); // [1, '2', true]

Returns Conversion\<any, Array\>

range

constrain variable value within a given range

Parameters

  • lower T lower range border (optional, default -Number.MAX_VALUE)
  • upper T upper range border (optional, default Number.MAX_VALUE)
  • fallback Fallback\ fallback value generator
  • conversion Conversion\<any, T> input data conversion (optional, default presets.double.convert)

Examples

const range37 = range(3, 7);
range37(1); // 3
range37(5); // 5
range37(9); // 7

const range37WithCustomFallback = range(3, 7, () => -1);
range37WithCustomFallback(1); // -1
range37WithCustomFallback(5); // 5
range37WithCustomFallback(9); // -1

const rangeString = range('k', 'w', undefined, String);
rangeString('a'); // k
rangeString('n'); // n
rangeString('z'); // w

Returns Conversion\<any, T>

variant

constrain variable to given variants

Parameters

  • values Array\ valid values list
  • fallback Fallback\ fallback value generator (optional, default ()=>values[0])
  • conversion Conversion\<any, T> input data conversion (optional, default presets.double.convert)

Examples

const var123 = variant([1, 2, 3]);
var123(1); // 1
var123(2); // 2
var123(3); // 3
var123(4); // 1
var123(-5); // 1

const var123WithCustomFallback = variant([1, 2, 3], () => -1);
var123WithCustomFallback(4); // -1

var123WithStrictFallback([1, 2, 3], () => {
  throw new Error('invalid input');
});
var123WithStrictFallback(4); // throws an Error

const varABC = variant(['a', 'b'], (i) => ['a', 'b'][i], String);
varABC('a'); // 'a'
varABC('b'); // 'b'
varABC(0); // 'a'
varABC(1); // 'b'

Returns Conversion\<any, T>

object

cast data into an object with a given schema

Parameters

  • schema Record<string, Conversion\<any, T>>
  • conversion Conversion\<any, T> input data conversion (optional, default presets.object.convert)

Examples

const objABC = utils.object({
  a: a.ubyte,
  b: utils.array(utils.object({
    c: a.int,
    d: utils.array(a.string),
  })),
});
objABC(undefined); // { a: 0, b: [] }
objABC({ a: 999, b: [{ c: 2.5, d: 3 }, null] }); // { a: 255, b: [{ c: 2, d: ['3'] }, { c: 0, d: [] }] }

Returns Conversion\<any, T>

2.3.0

30 days ago

2.2.0

3 months ago

2.1.0

4 months ago

2.0.0

5 months ago

1.5.5

6 months ago

1.5.3

6 months ago

1.6.0

6 months ago

1.5.6

6 months ago

1.5.2

1 year ago

1.5.1

1 year ago

1.5.0

1 year ago

1.4.0

1 year ago

1.3.0

1 year ago

1.2.0

1 year ago

1.1.0

1 year ago

1.0.0

1 year ago