
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Spritzr is an inheritance/traits/talents library for node.js and the browser.
It aims to provide three things:
Spritzr was inspired by a great traits/talents library CocktailJS https://github.com/CocktailJS/cocktail.
Spritzr is automatically unit tested against the following browsers:
It is also tested on node.js version 0.10 and PhantomJS (headless webkit).
Special thanks to BrowserStack for providing a free account to run our automated tests on all these different browsers and operating systems!
Spritzr has an extend function which implements a basic single inheritance model.
The prototype chain is maintained so that instanceof works as expected.
function Animal(type) {
this.type = type;
};
Animal.prototype.type = null;
Animal.prototype.greet = function() {
return "Hi, I'm a " + this.type + " called " + this.name;
};
// We need to explicitly call the super constructor using a handy $super property.
function Person(name) {
this.$super("person");
this.name = name;
};
Person.prototype.name = null;
Spritzr.extend(Person, Animal);
var steve = new Person("Steve");
expect(steve.greet()).toBe("Hi, I'm a person called Steve");
expect(steve instanceof Person).toBe(true);
expect(steve instanceof Animal).toBe(true);
// Spritzr also provides an isa() function which acts like instanceof
expect(Spritzr.isa(steve, Animal)).toBe(true);
// We can also override methods and properties of the super class
// but still access them using $super
var Tony = function Tony() {
this.$super("Tony");
};
Spritzr.extend(Tony, Person);
Tony.prototype.greet = function() {
var normalGreeting = this.$super.greet();
return normalGreeting + ", y'all!";
};
var tony = new Tony();
expect(tony.greet()).toBe("Hi, I'm a person called Tony, y'all!");
When extending a class, the super class constructor will not be implicitly called when the sub class is instantiated. Therefor you should call the $super() constructor from within the subclass constructor; for example:
var Animal = function() {
// Set up animaly stuff
};
var Mammal = function() {
this.$super(); // Call the Animal() constructor
// Set up mammalian stuff like live babies and stuff.
};
Spritzr.extend(Mammal, Animal);
When you call a super class method using this.$super.method() then the scope gets lost somewhere along the way, which means that this within the super method is not pointing to the correct object. There are two ways around this:
this.$super() from within the constructor. This has access to the real object and will cache it for later within the $super object. You can then just call this.$super.method() to call the super class method.this.$super.method.call(this, arg1, arg2 ... ).Classes can be extended with multiple traits, which are a bit like interfaces in Java but can also contain method implementations and properties.
var Animal = function() { };
var Mammal = function() { };
Spritzr.extend(Mammal, Animal); // Mammal is an extension of Animal
var Amphibian = function() { };
Spritzr.extend(Amphibian, Animal); // Amphibian is an extension of Animal
var Bird = function() { };
Spritzr.extend(Bird, Animal); // Bird is an extension of Animal
// We create a LaysEggs trait, which can be a class or a plain old object
var LaysEggs = function() { };
LaysEggs.prototype.layEgg = function() {
return new Egg();
};
// And we can apply the trait to specific classes
Spritzr.spritz(Amphibian, LaysEggs); // All Amphibians can now lay eggs
Spritzr.spritz(Bird, LaysEggs); // All Birds can now lay eggs
// Then we can use isa() to work out if an object has a specific trait
var cat = new Mammal();
expect(Spritzr.isa(cat, LaysEggs)).toBe(false);
var frog = new Amphibian();
expect(Spritzr.isa(frog, LaysEggs)).toBe(true);
var parrot = new Bird();
expect(Spritzr.isa(parrot, LaysEggs)).toBe(true);
// Traits are also inherited through class extension
var Emu = function() { };
Spritzr.extend(Emu, Bird); // Emu extends Bird
var emu = new Emu();
expect(Spritzr.isa(emu, LaysEggs)).toBe(true);
// or from other traits
var Monotreme = function() { };
Spritzr.spritz(Monotreme, LaysEggs);
var Platypus = function() { };
Spritzr.extend(Platypus, Mammal); // A platypus is a mammal
Spritzr.spritz(Platypus, Monotreme); // But also a monotreme
var ducky = new Platypus();
expect(Spritzr.isa(ducky, LaysEggs)).toBe(true);
Talents are a bit like traits, but they are applied to instances rather than classes. They can also be removed at any point.
// We have a class describing people
var Person = function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
Person.prototype.firstName = null;
Person.prototype.lastName = null;
Person.prototype.getDisplayName = function() {
return this.firstName + ' ' + this.lastName;
};
var sharon = new Person("Sharon", "Ackerman");
var tony = new Person("Tony", "Jones");
// We can define a talent to describe friendship
var Friend = function(nickname) {
this.nickname = nickname;
};
Friend.prototype.nickname = null;
Friend.prototype.getDisplayName = function() {
return this.firstName + ' "' + this.nickname + '" ' + this.lastName;
};
// And add a new talent to our friends
Spritzr.spritz(sharon, new Friend('The Shazza'));
// We can then check for existence of the talent to find out if a person is our friend
expect(Spritzr.isa(sharon, Friend)).toBe(true);
expect(Spritzr.isa(tony, Friend)).toBe(false);
// And the methods should be overridden appropriately
expect(sharon.getDisplayName()).toBe('Sharon "The Shazza" Ackerman');
expect(tony.getDisplayName()).toBe('Tony Jones');
// We can also remove talents from an instance using the amazing titled unspritz function
Spritzr.unspritz(sharon, Friend);
expect(sharon.getDisplayName()).toBe('Sharon Ackerman');
// We don't need to instantiate the talent first either - the constructor will automatically be called
var HasAccount = function() {
this.username = (this.firstName.substr(0,1) + this.lastName).toLowerCase();
};
HasAccount.prototype.username = null;
Spritzr.spritz(tony, HasAccount); // This adds the methods/properties and calls the constructor
expect(Spritzr.isa(tony, HasAccount)).toBe(true);
expect(tony.username).toBe("tjones");
The library is reasonably well tested, but there are some flows which haven't been thought about much so far:
The intention is to overcome these caveats in the future - it should be possible.
FAQs
Provides an inheritance/traits/talents library
The npm package spritzr receives a total of 10 weekly downloads. As such, spritzr popularity was classified as not popular.
We found that spritzr demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.