New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

can-type

Package Overview
Dependencies
Maintainers
4
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

can-type - npm Package Compare versions

Comparing version 1.0.0-pre.4 to 1.0.0-pre.5

106

can-type-test.js

@@ -7,10 +7,13 @@ var canSymbol = require("can-symbol");

var newSymbol = canSymbol.for("can.new");
var isMemberSymbol = canSymbol.for("can.isMember");
QUnit.module('can-type - Type methods');
function equal(assert, result, expected) {
assert.equal(expected, result, "Result matches expected");
assert.equal(result, expected, "Result matches expected");
}
function strictEqual(assert, result, expected) {
assert.strictEqual(expected, result, "Result matches expected strictly");
assert.strictEqual(result, expected, "Result matches expected strictly");
}

@@ -28,2 +31,6 @@

function notOk(assert, reason) {
assert.ok(false, reason || "Expected to throw");
}
function throwsBecauseOfWrongType(assert) {

@@ -33,2 +40,6 @@ ok(assert, "Throws when the wrong type is provided");

function shouldHaveThrownBecauseOfWrongType(assert) {
notOk(assert, "Should have thrown because the wrong type was provided");
}
var checkIsNaN = {

@@ -44,2 +55,10 @@ check: isNaN

var checkValue = function(comparison) {
return {
check: function(assert, result) {
assert.strictEqual(result, comparison, "value has been correctly converted");
}
};
};
var checkBoolean = function (comparison) {

@@ -87,7 +106,8 @@ return {

var Integer = {};
Integer[canSymbol.for("can.new")] = function(val) {
Integer[newSymbol] = function(val) {
return parseInt(val);
};
Integer[canSymbol.for("can.isMember")] = function(val) {
return Number.isInteger(val);
Integer[isMemberSymbol] = function(value) {
// “polyfill” for Number.isInteger because it’s not supported in IE11
return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
};

@@ -135,2 +155,48 @@ canReflect.setName(Integer, "Integer");

maybeConvert: checkNumber(44)
},
{
Type: type.check(Number),
value: "44",
convert: checkNumber(44),
maybeConvert: checkNumber(44),
check: {
check: shouldHaveThrownBecauseOfWrongType,
throws: throwsBecauseOfWrongType
}
},
{
Type: type.maybe(Number),
value: "44",
convert: checkNumber(44),
check: throwsBecauseOfWrongType,
maybe: throwsBecauseOfWrongType
},
{
Type: type.maybe(Number),
value: null,
convert: checkValue(null),
check: checkValue(null)
},
{
Type: type.convert(Number),
value: "33",
check: throwsBecauseOfWrongType,
maybe: throwsBecauseOfWrongType,
convert: checkNumber(33),
maybeConvert: checkNumber(33)
},
{
Type: type.convert(Number),
value: null,
check: throwsBecauseOfWrongType,
maybe: throwsBecauseOfWrongType,
convert: checkNumber(0),
maybeConvert: checkValue(null)
},
{
Type: type.check(Integer), value: 44.4,
convert: checkNumber(44),
maybeConvert: checkNumber(44),
check: throwsBecauseOfWrongType,
maybe: throwsBecauseOfWrongType
}

@@ -243,1 +309,31 @@ ];

});
QUnit.test("Type equality", function(assert) {
assert.strictEqual(type.convert(type.check(String)), type.convert(type.check(String)));
assert.strictEqual(type.maybe(String), type.maybe(String));
});
QUnit.test("TypeObjects do not need to throw themselves", function(assert) {
assert.expect(2);
function isABC(str) {
return "ABC".indexOf(str.toString()) !== -1;
}
var OnlyABC = {};
OnlyABC[newSymbol] = function() {
return "A";
};
OnlyABC[isMemberSymbol] = isABC;
var StrictABC = type.check(OnlyABC);
try {
canReflect.convert("D", StrictABC);
} catch(e) {
assert.ok(true, "Throw because isMember failed");
}
var NotStrictABC = type.convert(StrictABC);
var val = canReflect.convert("D", NotStrictABC);
assert.equal(val, "A", "converted");
});

259

can-type.js

@@ -6,18 +6,5 @@ var canReflect = require("can-reflect");

var newSymbol = canSymbol.for("can.new");
var getSchemaSymbol = canSymbol.for("can.getSchema");
var type = exports;
var primitives = new Map();
canReflect.each({
"boolean": Boolean,
"number": Number,
"string": String
}, function(Type, typeString) {
primitives.set(Type, {
isMember: function(val) {
return typeof val === typeString;
}
});
});
function makeSchema(values) {

@@ -32,100 +19,182 @@ return function(){

function makeTypeFactory(createSchema) {
return function makeTypeWithAction(action) {
var typeCache = new Map();
// Make an isMember function that prefers a isMemberSymbol on the Type.
function makeIsMember(check) {
return function isMember(value) {
var Type = this.Type;
if(Type[isMemberSymbol]) {
return Type[isMemberSymbol](value);
}
if(check.call(this, value)) {
return true;
}
return false;
};
}
return function createType(Type) {
if(typeCache.has(Type)) {
return typeCache.get(Type);
}
// Default isMember for non-maybe, non-primitives
function isMember(value) {
return value instanceof this.Type;
}
var isMember = function() { return false; };
if(primitives.has(Type)) {
isMember = primitives.get(Type).isMember;
}
// isMember for maybe non-primitives
function maybeIsMember(value) {
return value == null || value instanceof this.Type;
}
var createTypeWithSchema = createSchema(Type, action, isMember);
typeCache.set(Type, createTypeWithSchema);
return createTypeWithSchema;
};
};
// Default "can.new"
function canNew(value) {
if(this.isStrict && !this[isMemberSymbol](value)) {
return check(this.Type, value);
}
return canReflect.convert(value, this.Type);
}
var createMaybe = makeTypeFactory(function createMaybe(Type, action, isMember) {
var typeObject = {};
// "can.new" for Booleans
function booleanNew(value) {
if(this.isStrict && !this[isMemberSymbol](value)) {
return check(Boolean, value);
}
if (value === "false" || value=== "0") {
return false;
}
return Boolean(value);
}
var values = [Type, null, undefined];
if (Type === Boolean) {
values = [true, false, null, undefined];
var maybeValues = Object.freeze([null, undefined]);
function check(Type, val) {
throw new Error('Type value ' + typeof val === "string" ? '"' + val + '"' : val + ' is not of type ' + canReflect.getName(Type) + '.' );
}
/* Base converting proto */
var baseType = {};
canReflect.assignSymbols(baseType, {
isStrict: false,
"can.new": canNew,
"can.isMember": makeIsMember(isMember)
});
/* Descriptor for applying strictness */
var strictDescriptor = {
isStrict: {
enumerable: true,
value: true
}
};
strictDescriptor[newSymbol] = {
enumerable: true,
value: canNew
};
return canReflect.assignSymbols(typeObject, {
"can.new": function(val) {
if (val == null) {
return val;
}
var isInstance = typeof Type === "function" && val instanceof Type;
if (isInstance || isMember(val)) {
return val;
}
// Convert `'false'` into `false`
if (Type === Boolean && (val === 'false' || val === '0')) {
return false;
}
return action(Type, val);
},
"can.getSchema": makeSchema(values),
"can.getName": function(){
return canReflect.getName(Type);
},
"can.isMember": function(value) {
if(Type[isMemberSymbol]) {
return Type[isMemberSymbol](value);
}
return value == null || value instanceof Type || isMember(value);
/* Descriptor for applying nonstrictness */
var unStrictDescriptor = {
isStrict: {
enumerable: true,
value: false
}
};
/* Descriptor for maybe types */
var maybeDescriptors = {};
maybeDescriptors[isMemberSymbol] = {
enumerable: false,
value: makeIsMember(maybeIsMember)
};
/* Base maybe type */
var baseMaybeType = Object.create(baseType, maybeDescriptors);
var strictMaybeDescriptor = {
isStrict: strictDescriptor.isStrict
};
strictMaybeDescriptor[isMemberSymbol] = maybeDescriptors[isMemberSymbol];
strictMaybeDescriptor[newSymbol] = {
enumerable: true,
value: canNew
};
var unStrictMaybeDescriptor = {
isStrict: unStrictDescriptor.isStrict
};
unStrictMaybeDescriptor[isMemberSymbol] = maybeDescriptors[isMemberSymbol];
var primitiveBaseTypes = new Map();
canReflect.each({
"boolean": Boolean,
"number": Number,
"string": String
}, function(Type, typeString) {
var noMaybeDescriptor = {};
var maybeDescriptor = {};
noMaybeDescriptor[isMemberSymbol] = {
enumerable: true,
value: function isMember(val) {
return typeof val === typeString;
}
});
});
};
var createNoMaybe = makeTypeFactory(function createNoMaybe(Type, action, isMember) {
var typeObject = {};
maybeDescriptor[isMemberSymbol] = {
enumerable: true,
value: function isMaybeMember(val) {
return val == null || typeof val === typeString;
}
};
var values = [Type];
if (Type === Boolean) {
values = [true, false];
if(Type === Boolean) {
noMaybeDescriptor[newSymbol] = maybeDescriptor[newSymbol] = {
enumerable: true,
value: booleanNew
};
maybeDescriptor[getSchemaSymbol] = makeSchema([true, false, null, undefined]);
noMaybeDescriptor[getSchemaSymbol] = makeSchema([true, false]);
}
return canReflect.assignSymbols(typeObject, {
"can.new": function(val) {
var isInstance = typeof Type === "function" && val instanceof Type;
if (isInstance || isMember(val)) {
return val;
}
// Convert `'false'` into `false`
if (Type === Boolean && (val === 'false' || val === '0')) {
return false;
}
return action(Type, val);
},
"can.getSchema": makeSchema(values),
"can.getName": function(){
return canReflect.getName(Type);
},
"can.isMember": function(value) {
if(Type[isMemberSymbol]) {
return Type[isMemberSymbol](value);
}
return value instanceof Type || isMember(value);
}
primitiveBaseTypes.set(Type, {
noMaybe: Object.create(baseType, noMaybeDescriptor),
maybe: Object.create(baseMaybeType, maybeDescriptor)
});
});
function check(Type, val) {
throw new Error('Type value ' + typeof val === "string" ? '"' + val + '"' : val + ' is not of type ' + canReflect.getName(Type) + '.' );
function addType(typeObject, Type) {
if(!('Type' in typeObject)) {
Object.defineProperty(typeObject, 'Type', {
value: Type
});
}
}
function convert(Type, val) {
return canReflect.convert(val, Type);
function getBase(Type, baseType, basePrimitiveName) {
if(primitiveBaseTypes.has(Type)) {
return primitiveBaseTypes.get(Type)[basePrimitiveName];
} else if(isTypeObject(Type)) {
return Type;
} else {
return baseType;
}
}
function makeTypeFactory(name, baseType, childDescriptors, primitiveMaybe, schemaValues) {
var typeCache = new WeakMap();
return function(Type) {
if(typeCache.has(Type)) {
return typeCache.get(Type);
}
var base = getBase(Type, baseType, primitiveMaybe);
var typeObject = Object.create(base, childDescriptors);
addType(typeObject, Type);
typeObject[getSchemaSymbol] = makeSchema([Type].concat(schemaValues));
canReflect.setName(typeObject, "type." + name + "(" + canReflect.getName(Type) + ")");
typeCache.set(Type, typeObject);
return typeObject;
};
}
exports.check = makeTypeFactory("check", baseType, strictDescriptor, "noMaybe", []);
exports.convert = makeTypeFactory("convert", baseType, unStrictDescriptor, "noMaybe", []);
exports.maybe = makeTypeFactory("maybe", baseMaybeType, strictMaybeDescriptor, "maybe", maybeValues);
exports.maybeConvert = makeTypeFactory("maybeConvert", baseMaybeType, unStrictMaybeDescriptor, "maybe", maybeValues);
function isTypeObject(Type) {

@@ -172,8 +241,2 @@ if(canReflect.isPrimitive(Type)) {

exports.check = createNoMaybe(check);
exports.maybe = createMaybe(check);
exports.convert = createNoMaybe(convert);
exports.maybeConvert = createMaybe(convert);
// type checking should not throw in production

@@ -180,0 +243,0 @@ if(process.env.NODE_ENV === 'production') {

@@ -198,1 +198,31 @@ @module {Object} can-type

- `type.convert` and `type.maybeConvert` will convert the value using [can-reflect.convert].
## Applying multiple type functions
The type functions [can-type/check], [can-type/convert], [can-type/maybe], and [can-type/maybeConvert] all return a [can-type.typeobject]. Since they also can take a TypeObject as an argument, this means you can apply multiple type functions.
For example, using [can-type/convert] and [can-type/maybe] is equivalent to using [can-type/maybeConvert]:
```js
import { Reflect, type } from "can";
const MaybeConvertString = type.convert(type.maybe(String));
console.log(2, Reflect.convert(2, MaybeConvertString)); // "2"
console.log(null, Reflect.convert(2, MaybeConvertString)); // null
```
@codepen
Another example is taking a strict type and making it a converter type by wrapping with [can-type/convert]:
```js
import { Reflect, can } from "can";
const StrictString = type.check(String);
const NonStrictString = type.convert(StrictString);
console.log("Converting: ", Reflect.convert(5, NonStrictString)); // "5"
```
@codepen
This works because the type functions all keep a reference to the underlying type and simply toggle the *strictness* of the newly created TypeObject. When [can-symbol/symbols/new] is called the strictness is checked.
{
"name": "can-type",
"version": "1.0.0-pre.4",
"version": "1.0.0-pre.5",
"description": "Type definitions",

@@ -5,0 +5,0 @@ "homepage": "https://canjs.com/doc/can-type.html",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc