
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
offensive
Advanced tools
A human-readable, fast and boilerplate-free contract programming library for JavaScript.
Why would I want it?
.d.ts files).npm install --save offensive
// node-style require
const { contract } = require('offensive');
// or (with all assertions pre-loaded)
const { contract } = require('offensive/all');
// es6-style default import
import contract from 'offensive';
// or (with all assertions pre-loaded)
import contract from 'offensive/all';
In order to minimize the bundle payload, each assertion can be imported separately, either during application bootup or in each file where the specific assertions are used. The same assertion can be safely imported multiple times (importing an assertion second time is a no op).
// node-style require
require('offensive/assertions/aString/register');
// es6-style import
import 'offensive/assertions/aString/register';
When using the library on server-side, the bundle size is typically of no concern. For those situations, the library supports loading all assertions at once.
import 'offensive/assertions/register';
import { contract } from 'offensive';
// or even shorter
import { contract } from 'offensive/all';
Programming offensively is about throwing exceptions a lot. As soon as corrupted state or illegal parameter is detected, program is crashed with a descriptive error message. This technique greatly helps in finding bugs at their cause.
import 'offensive/assertions/fieldThat/register';
import 'offensive/assertions/aNumber/register';
import contract from 'offensive';
class Point2D {
/**
* @param init initializer object containing `x` and `y` properties.
*/
constructor(init) {
// Contract is satisfied if init contains
// `x` and `y` property of type number.
contract('init', init)
.has.fieldThat('x', x => x.is.aNumber)
.and.fieldThat('y', y => y.is.aNumber)
.check();
this.x = init.x;
this.y = init.y;
}
}
Now, following erroneus call...
const point = new Point2D({ x: 'a', y: null });
...will result in throwing following exception.
ContractError: init.x must be a number (got 'a') and init.y be a number (got null)
at operatorContext (offensives/ContextFactory.js:34:33)
at new Point2D (example.js:16:7)
at Object.<anonymous> (example.js:22:15)
Alternatively, above contract could be implemented using multiple checks, but the error would only contain information about first failed check.
contract('init', init).is.anObject.check();
contract('init.x', init.x).is.aNumber.check();
contract('init.y', init.y).is.aNumber.check();
Above examples use only .anObject, .aNumber
and .fieldThat assertions.
See full list of offensive.js built-in assertions.
Offensive programming is not applicable when collaborating with external components. A program should not crash in response to a bug in another program. Logging an error and trying to correct it by using default value or simply ignoring erroneus input would be a better way of handling such cases.
Following example is a fully functional HTTP-based ping server implemented using express.js with defensive checks on HTTP request implemented using offensive.js.
import * as express from 'express';
import * as bodyParser from 'body-parser';
import 'offensive/assertions/aString/register';
import 'offensive/assertions/fieldThat/register';
import contract from 'offensive';
const app = express();
app.use(bodyParser.json());
// A simple ping service which reflects messages sent to it.
app.post('/ping', function (req, res, next) {
// Contract is satisfied if body has a message which is a string
// (.propertyThat is an alias of .fieldThat assertion)
const error = contract('req.body', req.body)
.contains.propertyThat('message', message => message.is.aString)
.getError();
if (error) {
res.status(400).json({ error });
return;
}
const { message } = body;
res.json({ message });
});
Above code presents defensive programming on the server side, but the same technique is applicable in the client. Client-server contract should be tested both, after receiving request from the client, and after receiving response from the server.
Table of Contents
function contract<T>(varName : string, testedValue : T) : AssertionBuilder<T>;
Creates an instance of AssertionBuilder. Methods of returned
instance add assertions to the builder. Requested assertions
will be checked against given testedValue after [executing assertion
expression][call-operator]. In case some assertions fail, given name
will be used as part of error message.
import contract from 'offensive';
...
contract('arg', arg)...
.check() aliases: throwIfUnmet()interface AssertionBuilder<T> {
check(errorName?: string = 'ContractError') : T;
}
Executes built assert expression. Returns testedValue if assertion succeeds.
Throws ContractError in case it fails. intended for offensive programming.
import 'offensive/assertions/length';
import contract from 'offensive';
contract('arg', arg)
.has.length(10)
.check(); // <- executes built assert expression
NOTE: Assertion will not be run unless this method or .getError() is invoked.
interface AssertionBuilder<T> {
getError(errorName?: string = 'ContractError') : string | null;
}
Executes built assert expression. Returns error message if assertion fails.
Returns null in case it succeeds. Intended for defensive programming.
import 'offensive/assertions/length';
import contract from 'offensive';
const error = contract('arg', arg)
.has.length(10)
.getError(); // <- executes built assert expression
NOTE: Assertion will not be run unless this method or .check() is invoked.
offensive.js contains following built-in assertions.
Table of Contents
.Null.Undefined.Empty.ofType(requiredType).aBoolean.aNumber.anInteger.aString.anObject.aFunction.anArray.anInstanceOf(RequiredClass).aDate.aRegExp.True.False.truthy.falsy.matches(regexp).anEmail.aUUID.anEmptyString.aNonEmptyString.anIntegerString.startsWith(substring).endsWith(substring).substring(substring).equalTo.exactly.lessThan(rightBounds).lessThanOrEqualTo(rightBounds).greaterThan(leftBounds).greaterThanOrEqualTo(leftBounds).inRange(leftBounds, rightBounds).before(rightBounds, boundsVarName?).after(leftBounds, boundsVarName?).field(fieldName).fieldThat(fieldName, condition).allFieldsThat(condition).method(methodName).length(requiredLength).oneOf(set, name).elementThat(index, assertName, condition).allElementsThat(assertName, condition).includes(element).includesAllOf(element).includesElementThat(condition).Null aliases: .null, .Nil, .nilAsserts that checked value is null using ===.
Typically used in combination with .not operator.
contract('arg', arg).is.not.Null.check();
.Undefined aliases: .undefinedAsserts that checked value is undefined.
Typically used in combination with .not operator.
contract('arg', arg).is.not.Undefined.check();
.Empty aliases: .emptyAsserts that checked value is null or undefined.
Typically used in combination with .not operator.
contract('arg', arg).is.not.Empty.check();
.ofType(requiredType : string) aliases: .typeAsserts that checked value is of requiredType by ivoking typeof operator.
contract('arg', arg).is.ofType('boolean').check();
.aBoolean aliases: .Boolean, .booleanAsserts that checked value is a boolean by ivoking typeof operator.
contract('arg', arg).is.aBoolean.check();
.aNumber aliases: .Number, .numberAsserts that checked value is a number by ivoking typeof operator.
contract('arg', arg).is.aNumber.check();
.anInteger aliases: .Integer, .anInt, .intAsserts that checked value is an integer by ivoking Number.isInteger.
contract('arg', arg).is.anInteger.check();
.aString aliases: .String, .stringAsserts that checked value is a string by ivoking typeof operator.
contract('arg', arg).is.aString.check();
.anObject aliases: .Object, .objectAsserts that checked value is an object by ivoking typeof operator.
Be wary that this will be true also for array instances and null.
Use .anArray and .Null in order to test for these
specific cases.
contract('arg', arg).is.anObject.check();
.aFunction aliases: .Function, .functionAsserts that checked value is a function by ivoking typeof operator.
contract('arg', arg).is.aFunction.check();
.anArray aliases: .Array, .arrayAsserts that checked value is an array by invoking Array.isArray.
contract('arg', arg).is.anArray.check();
.anInstanceOf(RequiredClass : Function) aliases: .instanceOfAsserts that checked value is a instance of RequiredClass, by
using instanceof operator.
contract('arg', arg).is.anInstanceOf(RegExp).check();
.aDate aliases: .Date, .dateAsserts that checked value is a instance of Date, by
using instanceof operator.
contract('arg', arg).is.aDate.check();
.aRegExp aliases: .RegExp, .regexpAsserts that checked value is a instance of RegExp, by
using instanceof operator.
contract('arg', arg).is.aRegExp.check();
.True aliases: .trueAsserts that checked value is a boolean of value true.
contract('arg', arg).is.True.check();
.False aliases: .falseAsserts that checked value is a boolean of value false.
contract('arg', arg).is.False.check();
.truthy aliases: .Truthy, .truethy, .TruethyAsserts that checked value is truthy (converts to true).
contract('arg', arg).is.truthy.check();
.falsy aliases: .Falsy, .falsey, .FalseyAsserts that checked value is falsy (converts to false).
contract('arg', arg).is.falsy.check();
.matches(regexp : RegExp) aliases: .matchesRegexp, .matchesRegExpAsserts that checked value fully matches given regexp.
contract('arg', arg).matches(/[a-z]+/).check();
.anEmail aliases: .Email, .emailAsserts that checked value is a valid email.
contract('arg', arg).is.anEmail();
.aUUID aliases: .UUIDAsserts that checked value is a valid UUID.
contract('arg', arg).is.aUUID();
.anEmptyString aliases: .emptyStringAsserts that checked value is an empty string (string of length 0).
contract('arg', arg).is.anEmptyString.check();
.aNonEmptyString aliases: .nonEmptyStringAsserts that checked value is an non-empty string (string of length > 0).
contract('arg', arg).is.aNonEmptyString.check();
.anIntegerString aliases: .IntegerString, .intStringAsserts that checked value is a valid string form of an integer.
contract('arg', arg).is.anIntegerString.check();
.startsWith(substring : string) aliases: .startWith, .startingWithAsserts that checked value is a string that starts with given substring.
contract('arg', arg).is.startsWith('abc').check();
.endsWith(substring : string) aliases: .endWith, .endingWithAsserts that checked value is a string that ends with given substring.
contract('arg', arg).is.endsWith('xyz').check();
.substring(substring : string) aliases: .substrAsserts that checked value is a string that is contains given substring.
contract('arg', arg).has.substring('xyz').check();
.equalTo(another : any) aliases: .equal, .equalsAsserts that checked value is equal to another.
Comparison is made with == (double equals) operator.
contract('arg', arg).is.equalTo(100).check();
.exactly(another : any)Asserts that checked value is exactly the same as another.
Comparison is made with === (triple equals) operator.
contract('arg', arg).is.exactly(instance).check();
.lessThan(rightBounds : number) aliases: .lt, .lessAsserts that checked value is less than rightBounds.
contract('arg', arg).is.lessThan(100).check();
.lessThanOrEqualTo(rightBounds : number) aliases: .lte, .lessThanEqualAsserts that checked value is less than or equal to rightBounds.
contract('arg', arg).is.lessThanOrEqualTo(100).check();
.greaterThan(leftBounds : number) aliases: .gt, .greaterAsserts that checked value is greater than leftBounds.
contract('arg', arg).is.greaterThan(0).check();
.greaterThanOrEqualTo(leftBounds : number) aliases: .gte, .greaterThanEqualAsserts that checked value is greater than or equal to leftBounds.
contract('arg', arg).is.greaterThanOrEqualTo(0).check();
.inRange(leftBounds : number, rightBounds : number) aliases: .betweenAsserts that checked value is grater than or equal to leftBounds and less than rightBounds.
contract('arg', arg).is.inRange(0, 100).check();
.before(rightBounds : Date, boundsVarName ?: string)Asserts that checked value a Date chronologically before rightBounds.
contract('arg', arg).is.before(new Date(0), 'Epoch').check();
.after(leftBounds : Date, boundsVarName ?: string)Asserts that checked value a Date chronologically after leftBounds.
contract('arg', arg).is.after(new Date(0), 'Epoch').check();
.field(fieldName : string) aliases: .propertyAsserts that checked value has field of name propertyName.
contract('arg', arg).has.property('length').check();
.fieldThat(fieldName : string, builder : FieldAssertionBuilder)Asserts that checked value has field of name propertyName, which satisfied assertion created in gived builder.
contract('arg', arg)
.has.propertyThat('x', x => x.is.aNumber)
.check();
.allFieldsThat(builder : FieldAssertionBuilder)Asserts that:
contract('arg', arg)
.has.allFieldsThat(field => field.is.aNumber)
.check();
.method(methodName : string)Asserts that checked value has field of name methodName which is a function.
contract('arg', arg).has.method('toString').check();
.length(requiredLength : number) aliases: .lenAsserts that checked value has property of name "length" and value of requiredLength.
contract('arg', arg).has.length(0).check();
.oneOf(set : any[], name ?: string) aliases: .elementOf, .containedInAsserts that checked value is contained in given set. Given name (if present) is used as a name of set in produced error message.
contract('arg', arg)
.is.oneOf([ 'started', 'running', 'finished' ])
.check();
// or (with set name used in the error message)
contract('arg', arg)
.is.oneOf([ 'started', 'running', 'finished' ], 'valid status')
.check();
.elementThat(index : number, builder : ElemAssertionBuilder) aliases: .elementWhichIsAsserts that:
index + 1,contract('arg', arg)
.has.elementThat(0, elem => elem.is.anInteger)
.check();
.allElementsThat(builder : ElemAssertionBuilder) aliases: .allElementsWhichAsserts that:
contract('arg', arg)
.has.allElementsThat(elem => elem.is.anInteger)
.check();
.includes(element : any) aliases: .containsAsserts that:
contract('arg', arg)
.has.includes(elem)
.check();
.includesAllOf(elements : any[]) aliases: .includesAllAsserts that:
contract('categories', categories)
.has.includesAlOf(['functional', 'performance'])
.check();
.includesElementThat(builder: ElemAssertionBuilder) aliases: .includesElementAsserts that:
contract('arg', arg)
.includesElementThat(elem => elem.is.anInteger)
.check();
offensive.js implements following operators.
Table of Contents
.and aliases: .of, .withLogical conjunction of two boolean values which are separated by call to .and
operator.
contract('arg', arg)
.has.length(2)
.and.allElementsThat(elem => elem.is.aNumber)
.check();
.or()Logical alternative of two (or more) values which are separated by call to .or
operator.
contract('arg', arg)
.is.anObject.or.aFunction
.check();
.not aliases: .no, .dont, .doesntLogical negation of an assertion after .not operator.
contract('arg', arg).is.not.Undefined.check();
interface AssertionBuilder<T> {
() : T;
}
Alias for .check().
import 'offensive/assertions/aString';
import contract from 'offensive';
contract('arg', arg).is.aString.check(); // <- executes the expression
contract('arg', arg).is.aString(); // <- the same but with a call operator
The call operator was the only way to execute an offensive expression until version 2. Initially, it was seen as an elegant API with the least amount of boilerplate possible. While this is true for all assertions without arguments, assertions with arguments have their own call operator. This led to situations where two consecutive call operators were needed in order to execute the expression.
import 'offensive/assertions/length';
import contract from 'offensive';
contract('arg', arg).has.length(3)(); // <- double call operators weirdness
contract('arg', arg).has.length(3).check(); // <- this looks much better
.check() (introduced in version 3) solves the problem
of readability and adds a bit of explicitness at the cost of a little bit more
code. The call operator is still supported for backwards compatilibity.
offensive.js is extensible, but extension API is not documented yet.
If you wish to write an extension, take a look at the implementation
of built-in assertions, operators
and also at the interface of Registry class.
Released under MIT license.
FAQs
Fast and boilerplate-free precondition checks for javascript.
We found that offensive demonstrated a healthy version release cadence and project activity because the last version was released less than 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.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.