diff --git a/package.json b/package.json index 8d56d1c..5fbf89b 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ { "name": "@uci-utils/type", - "version": "0.6.2", + "version": "0.6.3", "description": "A variable type check and casting utility - extension of typechecker package plus type casting", "main": "src/index.js", "type": "module", "scripts": { "test": "./node_modules/.bin/mocha --timeout 30000", - "testd": "UCI_ENV=dev ./node_modules/.bin/nodemon --exec './node_modules/.bin/mocha --timeout 30000' || exit 0", - "testdd": "UCI_LOG_LEVEL='trace' npm run testd", - "testde": "UCI_LOG_LEVEL='warn' npm run testd", - "testl": "UCI_ENV=pro UCI_LOG_PATH=./test/test.log 0 npm run test || exit 0" + "test:dev": "UCI_ENV=dev ./node_modules/.bin/nodemon --exec './node_modules/.bin/mocha --timeout 30000' || exit 0", + "test:dev:trace": "UCI_LOG_LEVEL='trace' npm run test:dev", + "test:dev:warn": "UCI_LOG_LEVEL='warn' npm run test:dev", + "test:log": "UCI_ENV=pro UCI_LOG_PATH=./test/test.log 0 npm run test || exit 0" }, "author": "David Kebler", "license": "MIT", @@ -32,11 +32,14 @@ "homepage": "https://github.com/uCOMmandIt/uci-utils#readme", "dependencies": { "@uci-utils/to-boolean": "^0.2.0", + "is-observable": "^2.1.0", + "observable-to-promise": "^1.0.0", "typechecker": "^7.17.0" }, "devDependencies": { "chai": "^4.3.4", "mocha": "^8.4.0", - "nodemon": "^2.0.7" + "nodemon": "^2.0.7", + "rxjs": "^7.1.0" } } diff --git a/src/cast.js b/src/cast.js index d87a747..e2b8dfb 100644 --- a/src/cast.js +++ b/src/cast.js @@ -1,4 +1,6 @@ import { toBoolean } from '@uci-utils/to-boolean' +import otp from 'observable-to-promise' +import isObservable from 'is-observable' // adapted from "https://github.com/eivindfjeldstad/const git" /** @@ -61,6 +63,14 @@ const toArray = function (val) { return arr } + +// cast Observable to promise +const toPromise = function (obs) { + if (!isObservable(obs)) throw new Error('not an observable, can not cast to promise') + return otp(obs) +} + + /** * Cast given `val` to `type` * @@ -69,15 +79,15 @@ const toArray = function (val) { * @api public */ -const typecast={string:toString,number:toNumber,date:toDate,boolean:toBoolean,array:toArray} +const typecast = { string: toString, number: toNumber, date: toDate, boolean: toBoolean, array: toArray, promise: toPromise } -function cast (val, type) { +function cast(val, type) { var fn = typecast[type] if (typeof fn != 'function') throw new Error('cannot cast to ' + type) return fn(val) } -export { cast, typecast, toBoolean, toArray, toDate, toNumber, toString } +export { cast, typecast, toBoolean, toArray, toDate, toNumber, toString, toPromise } // TODO support registering alternative casting functions with a register function diff --git a/src/check.js b/src/check.js index 12407d8..6bfe4f1 100644 --- a/src/check.js +++ b/src/check.js @@ -1,4 +1,5 @@ import * as typechecker from 'typechecker' +import observable from 'is-observable' // TODO add observable types and other custom uci types @@ -18,10 +19,15 @@ customTypeChecker.isSymbol = function isSymbol(x) { || typeof x === 'object' && Object.prototype.toString.call(x) === '[object Symbol]'; } +customTypeChecker.isObservable = observable + + // Add custom types to typeMap let customTypeMap = { buffer: customTypeChecker.isBuffer, - promise: customTypeChecker.isPromise + promise: customTypeChecker.isPromise, + symbol: customTypeChecker.isSymbol, + observable: customTypeChecker.isObservable } customTypeMap = Object.assign(customTypeMap, customTypeChecker.typeMap) diff --git a/test/cast.test.js b/test/cast.test.js index db3c81e..ea255a2 100644 --- a/test/cast.test.js +++ b/test/cast.test.js @@ -1,8 +1,6 @@ import assert from 'assert' -import { check, typecast, cast, toString, toBoolean } from '../src/index.js' - -console.log(typecast.boolean) -console.log(toBoolean) +import { check, typecast, cast, toString, toBoolean, toPromise } from '../src/index.js' +import { of } from 'rxjs' describe('symbol', function () { it('should support isSymbol', function () { @@ -26,10 +24,13 @@ describe('.string()', function () { assert(check.isString(toString(2))) }) + it('convert an observable to promise with toPromise', function () { + assert.throws(() => { toPromise(() => { }) }, Error) + assert(check.isPromise(toPromise(of(1, 2, 3)))) + }) + }) - - describe('.number()', function () { it('should return a number', function () { assert(typecast.number('123') === 123) diff --git a/test/check.test.js b/test/check.test.js index 0180696..ecd614a 100644 --- a/test/check.test.js +++ b/test/check.test.js @@ -1,5 +1,7 @@ import { expect } from 'chai' -import u, {typeOf} from '../src/index.js' +import u, { typeOf } from '../src/index.js' +import { of } from 'rxjs' +console.log(of) describe('Type Check Library - ', function () { @@ -8,6 +10,8 @@ describe('Type Check Library - ', function () { expect(u.getType(Buffer.from('this is a test'))).to.equal('buffer') expect(u.isPromise(Promise.resolve(2))).to.equal(true) expect(u.getType(Promise.resolve(2))).to.equal('promise') + expect(u.isObservable(of(1, 2, 3))).to.equal(true) + expect(u.getType(of(1, 2, 3))).to.equal('observable') }) it('Should export typeOf for .getType', function () { @@ -16,7 +20,7 @@ describe('Type Check Library - ', function () { console.log(typeOf(typeOf)) - it('Should include typechecker methods', function () { + it('Should include base typechecker methods', function () { expect(u.isPlainObject([1])).to.equal(false) expect(u.getType(true)).to.equal('boolean') expect(u.getObjectType('a string')).to.equal('[object String]')