Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

class-wrapper

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

class-wrapper - npm Package Compare versions

Comparing version 2.0.0 to 2.1.0

dest/class-wrapper.amd.min.js

114

dest/class-wrapper.amd.js

@@ -0,15 +1,21 @@

/**
* class-wrapper v2.1.0
* Copyright (c) 2016-2019 Valerii Zinchenko
* License: MIT http://valerii-zinchenko.gitlab.io/observer/blob/master/LICENSE.txt
* All source files are available at: https://gitlab.com/valerii-zinchenko/class-wrapper#readme
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global['class-wrapper'] = {})));
}(this, (function (exports) { 'use strict';
(global = global || self, factory(global['class-wrapper'] = {}));
}(this, function (exports) { 'use strict';
/*
Copyright (c) 2016-2018 Valerii Zinchenko
* Copyright (c) 2016-2019 Valerii Zinchenko
*
* Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)
*
* All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)
All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
/**

@@ -95,3 +101,3 @@ * @file It contains some [utility functions]{@link utils}.

/*
* Copyright (c) 2016-2018 Valerii Zinchenko
* Copyright (c) 2016-2019 Valerii Zinchenko
*

@@ -101,3 +107,3 @@ * Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)

* All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
*/

@@ -113,8 +119,10 @@

* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous, even the parent properties. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Provide the interface(s) that the class should implement. Interface can be any object with or without the implementation of the methods. It will be used just to get the method name and check if that method is implemented. If it is not, then the default method will be added to the class and it could be treated as an abstract metod. By calling this abstract method it will throw an exception with the message, that this method is abstract.
*
* @see {@link Class}
* @see {@link Interface}
*
* @throws {TypeError} Incorrect input arguments. It should be: ClassBuilder(Function, [Function], Function | null, Object)
* @throws {TypeError} Some of the items for encapsulation are incorrect. An item can be: Object, Function, Class
* @throws {TypeError} Class extends value ${value} is not a constructor or null
* @throws {Error} Class "${name}" must implement "${key}" method, but it is already set as a property.
*

@@ -126,2 +134,3 @@ * @param {Function} constructorTemplate - Function that defines how instances will be created, i.e. how the parent and the provided constructors will be executed.

* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class.
* @param {Object | Object[] | Interface | Interface[]} [props.Implements] - Defines what interface(s) this class is implementing. Only the first level object methods will be taken into account, other properties will be ignored.
* @param {String} [props.__name = "Class"] - Specify the class name what will be visible near the variables during the debugging.

@@ -213,3 +222,31 @@ * @returns {class} ES6 class.

// Go through the interfaces, that this class should implement
// --------------------------------------------------
if (!(props.Implements instanceof Array)) {
props.Implements = [props.Implements];
}
props.Implements.forEach(Interface => {
if (!(Interface instanceof Object)) {
return;
}
for (let key in Interface) {
const value = Interface[key];
if (
!(value instanceof Function)
|| Class.prototype[key] instanceof Function
) {
continue;
}
if (Class.prototype.__defaults[key] !== undefined) ;
Class.prototype[key] = function() {
throw new Error(`"${name}::${key}" is not implemented`);
};
console.warn(`Implementation of "${name}::${key}" is not found. This method will be treated as abstract method and will throw an error by execution.`);
}
});
// --------------------------------------------------
return Class;

@@ -232,7 +269,2 @@ }

for (let key in from) {
// Note! 'constructor' is excluded to not override the real class constructor.
if (!from.hasOwnProperty(key) && key === 'constructor') {
continue;
}
const value = from[key];

@@ -268,9 +300,9 @@ switch (Object.prototype.toString.call(value)) {

/*
Copyright (c) 2016-2018 Valerii Zinchenko
* Copyright (c) 2016-2019 Valerii Zinchenko
*
* Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)
*
* All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)
All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
// Storage of base parent classes. It is used to identify the root parent class when the constructor should have to copy default properties into `this`

@@ -295,3 +327,3 @@ const baseClasses = [];

* @throws {TypeError} Some of the items for encapsulation are incorrect. An item can be: Object, Function, Class
* @throws {TypeError} Class extends value ${value} is not a constructor or null
* @throws {Error} Class "${name}" must implement "${key}" method, but it is already set as a property.
*

@@ -302,2 +334,3 @@ * @param {Function | class} [Parent = Object] - Parent class.

* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class.
* @param {Object | Object[] | Interface | Interface[]} [props.Implements] - Defines what interface(s) this class is implementing. Only the first level object methods will be taken into account, other properties will be ignored.
* @param {String} [props.__name = "Class"] - Specify the class name what will be visible near the variables during the debugging.

@@ -319,8 +352,41 @@ * @returns {class} ES6 class

/*
* Copyright (c) 2016-2019 Valerii Zinchenko
*
* Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)
*
* All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
/**
* @file Implementation of [Interface]{@link Interface}.
*
* @see {@link Interface}
*
* @author Valerii Zinchenko
*/
/**
* Interface.
* It produces a new interface without affecting the parent interface.
*
* @function Interface
* @see {@link ClassBuilder}
*
* @param {Object} [Parent] - Parent interface.
* @param {Object} props - Defines the new methods for an interface.
* @returns {Object} Interface object that contains parent and new methods together. If Parent argument is provided, then a new object will be returned.
*/
function Interface(Parent, props) {
return props ? {...Parent, ...props} : Parent;
}
exports.utils = utils;
exports.ClassBuilder = ClassBuilder;
exports.Class = Class;
exports.Interface = Interface;
Object.defineProperty(exports, '__esModule', { value: true });
})));
}));
/*
Copyright (c) 2016-2018 Valerii Zinchenko
* Copyright (c) 2016-2019 Valerii Zinchenko
*
* Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)
*
* All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)
All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
/**

@@ -18,3 +18,3 @@ * @file Implementation of a [class]{@link Class} wrapper.

import ClassBuilder from './ClassBuilder';
import ClassBuilder from './ClassBuilder.js';

@@ -40,3 +40,3 @@ // Storage of base parent classes. It is used to identify the root parent class when the constructor should have to copy default properties into `this`

* @throws {TypeError} Some of the items for encapsulation are incorrect. An item can be: Object, Function, Class
* @throws {TypeError} Class extends value ${value} is not a constructor or null
* @throws {Error} Class "${name}" must implement "${key}" method, but it is already set as a property.
*

@@ -47,2 +47,3 @@ * @param {Function | class} [Parent = Object] - Parent class.

* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class.
* @param {Object | Object[] | Interface | Interface[]} [props.Implements] - Defines what interface(s) this class is implementing. Only the first level object methods will be taken into account, other properties will be ignored.
* @param {String} [props.__name = "Class"] - Specify the class name what will be visible near the variables during the debugging.

@@ -49,0 +50,0 @@ * @returns {class} ES6 class

/*
* Copyright (c) 2016-2018 Valerii Zinchenko
* Copyright (c) 2016-2019 Valerii Zinchenko
*

@@ -7,4 +7,5 @@ * Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)

* All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
*/
/**

@@ -14,2 +15,3 @@ * @file Implementation of [ClassBuilder]{@link ClassBuilder}

* @see {@link Class}
* @see {@link Interface}
*

@@ -19,5 +21,6 @@ * @author Valerii Zinchenko

import utils from './utils';
import utils from './utils.js';
/**

@@ -31,8 +34,10 @@ * Main class builder.

* - Define the classes/functions/objects that are going to be encapsulated into the resulting class. The last encapsulated object will have a precedence over the previous, even the parent properties. Only the new used-defined properties for the new class will have the highest precedence. This gives the possibility to add other methods and properties into the class without touching the inheritance chain.
* - Provide the interface(s) that the class should implement. Interface can be any object with or without the implementation of the methods. It will be used just to get the method name and check if that method is implemented. If it is not, then the default method will be added to the class and it could be treated as an abstract metod. By calling this abstract method it will throw an exception with the message, that this method is abstract.
*
* @see {@link Class}
* @see {@link Interface}
*
* @throws {TypeError} Incorrect input arguments. It should be: ClassBuilder(Function, [Function], Function | null, Object)
* @throws {TypeError} Some of the items for encapsulation are incorrect. An item can be: Object, Function, Class
* @throws {TypeError} Class extends value ${value} is not a constructor or null
* @throws {Error} Class "${name}" must implement "${key}" method, but it is already set as a property.
*

@@ -44,2 +49,3 @@ * @param {Function} constructorTemplate - Function that defines how instances will be created, i.e. how the parent and the provided constructors will be executed.

* @param {Object | Function | Class | Array} [props.Encapsulate] - Define which object/function/class or an array of objects/functions/classes should be encapsulated into the new class.
* @param {Object | Object[] | Interface | Interface[]} [props.Implements] - Defines what interface(s) this class is implementing. Only the first level object methods will be taken into account, other properties will be ignored.
* @param {String} [props.__name = "Class"] - Specify the class name what will be visible near the variables during the debugging.

@@ -131,3 +137,33 @@ * @returns {class} ES6 class.

// Go through the interfaces, that this class should implement
// --------------------------------------------------
if (!(props.Implements instanceof Array)) {
props.Implements = [props.Implements];
}
props.Implements.forEach(Interface => {
if (!(Interface instanceof Object)) {
return;
}
for (let key in Interface) {
const value = Interface[key];
if (
!(value instanceof Function)
|| Class.prototype[key] instanceof Function
) {
continue;
}
if (Class.prototype.__defaults[key] !== undefined) {
throw new Error(`Class "${name}" must implement "${key}" method, but it is already set as a property.`);
}
Class.prototype[key] = function() {
throw new Error(`"${name}::${key}" is not implemented`);
};
console.warn(`Implementation of "${name}::${key}" is not found. This method will be treated as abstract method and will throw an error by execution.`);
}
});
// --------------------------------------------------
return Class;

@@ -150,7 +186,2 @@ }

for (let key in from) {
// Note! 'constructor' is excluded to not override the real class constructor.
if (!from.hasOwnProperty(key) && key === 'constructor') {
continue;
}
const value = from[key];

@@ -185,2 +216,3 @@ switch (Object.prototype.toString.call(value)) {

export default ClassBuilder;
/*
Copyright (c) 2016-2018 Valerii Zinchenko
* Copyright (c) 2016-2019 Valerii Zinchenko
*
* Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)
*
* All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
Licensed under MIT (https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/LICENSE.txt)
All source files are available at: http://gitlab.com/valerii-zinchenko/class-wrapper
*/
/**

@@ -10,0 +10,0 @@ * @file It contains some [utility functions]{@link utils}.

The MIT License (MIT)
Copyright (c) 2016-2018 Valerii Zinchenko
Copyright (c) 2016-2019 Valerii Zinchenko

@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -1,7 +0,11 @@

import utils from './lib/utils';
import ClassBuilder from './lib/ClassBuilder';
import Class from './lib/Class';
import utils from './lib/utils.js';
import ClassBuilder from './lib/ClassBuilder.js';
import Class from './lib/Class.js';
import Interface from './lib/Interface.js';
export { utils };
export { ClassBuilder };
export { Class };
export {
utils,
ClassBuilder,
Class,
Interface
};
{
"name": "class-wrapper",
"version": "2.0.0",
"version": "2.1.0",
"description": "Set of wrappers to create classes with construction behaviour like in C++",

@@ -14,6 +14,6 @@ "main": "main.js",

"build": "rollup --config rollup.config.js",
"pretest": "rollup --config rollup.config.unit-tests.js && grunt copy",
"test": "mocha-headless-chrome -a no-sandbox --file test/index.html --reporter spec",
"pretest": "rm -rf .nyc_output && grunt copy",
"test": "node test/run-tests.js",
"posttest": "nyc report --reporter=text --reporter=html",
"doc": "grunt jsdoc:nightly",
"publish-html": "npm run doc && npm run pretest",
"preversion": "npm test",

@@ -28,3 +28,2 @@ "postversion": "grunt jsdoc:version",

"chai": "^4.1.2",
"globby": "^8.0.1",
"grunt": "1.x",

@@ -34,9 +33,12 @@ "grunt-cli": "1.x",

"grunt-jsdoc": "^2.1.0",
"http-server": "^0.11.1",
"load-grunt-tasks": "^3.5.2",
"mocha": "^5.1.0",
"mocha-headless-chrome": "^2.0.0",
"nyc": "^13.0.0",
"portfinder": "^1.0.20",
"puppeteer": "^1.11.0",
"puppeteer-to-istanbul": "^1.2.2",
"rollup": "^0.59.1",
"rollup-plugin-node-resolve": "^3.3.0",
"rollup": "^1.1.2",
"rollup-plugin-banner": "^0.2.0",
"rollup-plugin-terser": "^4.0.3",
"sinon": "^4.5.0"

@@ -43,0 +45,0 @@ },

# {class}
[![pipeline status](https://gitlab.com/valerii-zinchenko/class-wrapper/badges/master/pipeline.svg)](https://gitlab.com/valerii-zinchenko/class-wrapper/commits/master)[![coverage report](https://gitlab.com/valerii-zinchenko/class-wrapper/badges/master/coverage.svg)](https://gitlab.com/valerii-zinchenko/class-wrapper/commits/master)
The main goal of this library is to automate some construction routines, that a developer is usually writing by himself, and to provide more flexibility to create new classes.

@@ -24,3 +26,3 @@ This library suppies:

Via [NPM (Node Package Manager)](https://www.npmjs.com/)
Via [NPM](https://www.npmjs.com/)
```

@@ -30,3 +32,3 @@ $ npm install class-wrapper --save

Then just import the required component
Then just import the required component, for example `Class`.
```js

@@ -36,5 +38,5 @@ import {Class} from 'class-wrapper';

Or
or
```js
const Class = require('class-wrapper/dest/class-wrapper.amd').Class;
const {Class} = require('class-wrapper/dest/class-wrapper.amd');
```

@@ -45,75 +47,22 @@

```js
import {Class} from 'class-wrapper';
Example can be found in [`example.js`](https://gitlab.com/valerii-zinchenko/class-wrapper/blob/master/example.js).
To see it in live, create an empty folder and copy `example.js` file there. Install `class-wrapper` package:
// Define a Figure class:
const Figure = Class(function() {
console.log(`Figure::constructor(${[...arguments].join()})`);
}, {
// this will set the name for the class, so by debugging you will see correct name of the class, othervise "Class" will be displayed
__name: 'Figure',
```
npm i class-wrapper
```
// abstract function for a calculating an area of a figure
calcArea() {}
});
and run the example
// Define Rectangle class derived from a Figure class:
const Rectangle = Class(Figure, function(width, height) {
console.log('Rectangle::constructor(${[...arguments].join()})');
if (width !== undefined) {
this._width = width;
}
if(height !== undefined) {
this._height = height;
}
}, {
__name: 'Rectangle',
_width: 0,
_height: 0,
calcArea() {
return this._width * this._height;
}
});
// Define Square class as a special case of Rectangle:
const Square = Class(Rectangle, function(length) {
console.log('Square::constructor(${[...arguments].join()})');
this._height = length;
}, {
__name: 'Square'
});
// Create a rectangle with width 2 and height 4
const someRect = new Rectangle(2, 4);
// console will print:
// --> Figure::constructor(2,4)
// --> Rectangle::constructor(2,4)
console.log(someRect.calcArea()); // --> 8
// Create a rectangle with default width and height
console.log((new Rectangle()).calcArea()); // --> 0
// Create a square with an edge length 5
const someSqrt = new Square(5);
// console will print:
// --> Figure::constructor(5)
// --> Rectangle::constructor(5)
// --> Square::constructor(5)
console.log(someSqrt.calcArea()); // --> 25
```
node example.js
```
## Links
* [wiki](https://gitlab.com/valerii-zinchenko/class-wrapper/wikis/home)
* [API](http://valerii-zinchenko.gitlab.io/class-wrapper/doc/nightly/index.html)
* [Run unit tests](http://valerii-zinchenko.gitlab.io/class-wrapper/test/index.html)
* [API](http://valerii-zinchenko.gitlab.io/class-wrapper/)
* [Run unit tests](http://valerii-zinchenko.gitlab.io/class-wrapper/test/)
* [Code coverage report](http://valerii-zinchenko.gitlab.io/class-wrapper/coverage/)

@@ -1,2 +0,2 @@

import Class from '../lib/Class';
import {Class} from '../main.js';

@@ -3,0 +3,0 @@

@@ -1,2 +0,2 @@

import ClassBuilder from '../lib/ClassBuilder';
import {ClassBuilder} from '../main.js';

@@ -215,6 +215,10 @@

{
title: '"constructor" should be ignored',
title: 'not own properties should be ignored',
input: [null, {
constructor: function(){},
p0: 'p0'
Encapsulate: (() => {
function A() {};
A.prototype.p0 = 'p0';
return A;
})()
}],

@@ -352,2 +356,108 @@ expected: {

});
suite('Implements', () => {
test('Class properties and Interface interference', () => {
const I = {
method() {}
};
assert.throw(() => {
ClassBuilder(function(){}, null, {
__name: 'TestClass',
Implements: I,
method: 'property'
});
}, Error, 'Class "TestClass" must implement "method" method, but it is already set as a property.');
});
test('Single interface', () => {
const ISomeInterface = {
methodToImplement() {}
};
const implementedMethod = sinon.spy();
const SomeClass = ClassBuilder(function(){}, null, {
Implements: ISomeInterface,
methodToImplement: implementedMethod
});
assert.equal(SomeClass.prototype.methodToImplement, implementedMethod);
});
test('Not implemented method', () => {
const IInterface = {
methodToImplement() {}
};
const SomeClass = ClassBuilder(function(){}, null, {
Implements: IInterface
});
assert.throws(SomeClass.prototype.methodToImplement, Error, '"Class::methodToImplement" is not implemented');
});
test('Few interfaces', () => {
const IInterface1 = {
methodToImplement1() {}
};
const IInterface2 = {
methodToImplement2() {}
};
const implementedMethod1 = sinon.spy();
const implementedMethod2 = sinon.spy();
const SomeClass = ClassBuilder(function(){}, null, {
Implements: [IInterface1, IInterface2],
methodToImplement1: implementedMethod1,
methodToImplement2: implementedMethod2
});
assert.equal(SomeClass.prototype.methodToImplement1, implementedMethod1);
assert.equal(SomeClass.prototype.methodToImplement2, implementedMethod2);
});
test('"Falsy" interfaces should be skipped without errors', () => {
assert.doesNotThrow(() => {
ClassBuilder(function(){}, null, {
Implements: [ , undefined, null, false, 0, ""]
});
});
});
test('Non-function interface properties should be ignored', () => {
const Interface = {
p0: 0,
p1: 1,
p2: false,
p3: true,
p4: '',
p5: 'str',
p6: null,
p7: undefined,
p8: {},
p9: [],
p10: () => {},
p11() {}
};
const SomeClass = ClassBuilder(function(){}, null, {
Implements: Interface
});
assert.isUndefined(SomeClass.prototype.p0);
assert.isUndefined(SomeClass.prototype.p1);
assert.isUndefined(SomeClass.prototype.p2);
assert.isUndefined(SomeClass.prototype.p3);
assert.isUndefined(SomeClass.prototype.p4);
assert.isUndefined(SomeClass.prototype.p5);
assert.isUndefined(SomeClass.prototype.p6);
assert.isUndefined(SomeClass.prototype.p7);
assert.isUndefined(SomeClass.prototype.p8);
assert.isUndefined(SomeClass.prototype.p9);
assert.isDefined(SomeClass.prototype.p10);
assert.isDefined(SomeClass.prototype.p11);
});
});
});

@@ -354,0 +464,0 @@

@@ -1,2 +0,2 @@

import utils from '../lib/utils';
import {utils} from '../main.js';

@@ -3,0 +3,0 @@

Sorry, the diff of this file is not supported yet

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