
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.
@aeroview-io/rtype
Advanced tools
Simple and extensible runtime input validation for TS/JS, written in TS, fried in batter.
❗️This package has moved to
typura. To get the latest version, please installtypurainstead of@aeroview-io/r-type. This package will no longer be maintained.
Simple and extensible runtime input validation for TS/JS, written in TS, fried in batter.
Sponsored by https://aeroview.io
🚀 Fast & reliable performance
😀 User-friendly & defensive
🔋 Batteries included
npm i typura
import {predicates as p, Infer} from 'typura';
enum FavoriteColor {
Red = 'red',
Blue = 'blue',
Green = 'green',
}
const validator = p.object({
email: p.email(),
password: p.password(),
name: p.string({len: {min: 1, max: 100}}),
phone: p.optional(p.string()),
favoriteColor: p.enumValue(FavoriteColor),
mustBe42: p.custom((input: number) => input === 42, 'must be 42'),
});
type User = Infer<typeof validator>; // {email: string, password: string, name: string, phone?: string, favoriteColor: FavoriteColor, mustBe42: number}
validator({
email: 'oopsie',
password: 'password',
name: 'John Doe',
favoriteColor: 'red',
});
/* The above throws ValidationError:
{
email: 'must be a valid email address',
password: 'must include at least one uppercase letter',
mustBe42: 'must be 42',
}
*/
/* demonstrating type narrowing */
const input = {
email: 'john@smith.com',
password: 'Password1$',
name: 'John Doe',
favoriteColor: 'red',
mustBe42: 42,
} as unknown; // unknown type to simulate unknown user input
try {
if (validator(input)) {
// input is now typed as User
input.favoriteColor; // FavoriteColor
}
} catch (e) {
if (e instanceof ValidationError) {
console.log(e.messages);
}
throw e; // don't forget to rethrow your unhanded errors!
}
import {predicates as p, ValidationError, toResult} from 'typura';
const validator = p.object({
email: p.email(),
password: p.password(),
});
const input = {
email: '',
password: '',
}
const [err] = toResult(() => validator(input));
if (err instanceof ValidationError) {
console.log(err.messages); // {email: 'must be a valid email address', password: 'must include at least one uppercase letter'}
}
R-type is tree-shakeable. This means that you can import only the predicates you need and the rest of the library will not be included in your bundle.
This is useful for frontend applications where bundle size is a concern. As a bonus, this allows our repo to contain a large number of predicates for convenience without bloating your bundle. Best of both worlds!
import {email} from 'typura/dist/predicates';
const isEmail = email();
You can nest objects by using the object predicate. This allows you to create complex validation rules for nested objects. The ValidationError object will be flattened to include the nested object keys with a dot separator.
import {predicates as p, Infer} from 'typura';
const validator = p.object({
email: p.email(),
address: p.object({
line1: p.string(),
line2: p.optional(p.string()),
street: p.string(),
state: p.string(),
city: p.string({len: {min: 2, max: 2}}),
zip: p.string(),
})
});
type User = Infer<typeof validator>; // {email: string, address: {line1: string, line2?: string, street: string, city: string, zip: string}}
validator({
email: 'blah',
address: {}
});
/* The above throws ValidationError:
{
email: 'must be a valid email address',
'address.line1': 'must be a string',
'address.street': 'must be a string',
'address.state': 'must be a string',
'address.city': 'must be between 2 and 2 characters long', // Yeah, we should probably fix this :)
'address.zip': 'must be a string',
}
*/
Infer<T>Infer is a utility type that extracts the type of the input from a predicate function. See the example above for usage.
Pred<T>A type gaurd that takes an input and returns a boolean. It is used to narrow the type of the input to the type that the predicate is checking for. Every predicate function in our API returns a Pred<T>.
Example:
import {Pred} from 'typura';
const isNumber: Pred<number> = (input: unknown): input is number => typeof input === 'number';
boolean(): Pred<boolean>
Returns a predicate that checks if the input is a boolean.
number(opts?: Options): Pred<number>
Returns a predicate that checks if the input is a number.
Options:
range: {min: number, max: number} | undefined - checks if the input is within the specified rangeExample:
import {number} from 'typura/dist/predicates';
const isNumber = number({range: {min: 0, max: 100}});
string(opts?: Options): Pred<string>
Returns a predicate that checks if the input is a string.
Options:
len: {min: number, max: number} | undefined - checks if the input is within the specified lengthobject<T>(predicates: {[K in keyof T]: Pred<T[K]>}, opts?: Options): Pred<T>
Returns a predicate that checks if the input is an object with the specified keys and values.
Options:
allowUnknownKeys - allows unspecified/unexpected keys in the object, default is falsearray<T>(predicate: Pred<T>): Pred<T[]>
Returns a predicate that checks if the input is an array of the specified type.
enumValue<T>(enumType: T): Pred<T[keyof T]>
Returns a predicate that checks if the input is a value of the specified enum.
optional<T>(predicate: Pred<T>): Pred<T | undefined>
Returns a predicate that checks if the input is either the type of the predicate or undefined.
custom<T>(predicate: (input: T) => boolean, message: string): Pred<T>
Returns a predicate that checks if the input passes a custom function.
Example:
import {custom} from 'typura/dist/predicates';
const is42 = custom((input: number) => input === 42, 'must be 42');
is42(42); // true
is42(43); // throws ValidationError: 'must be 42'
chain<T>(...predicates: Pred<T>[]): Pred<T>
Returns a predicate that chains multiple predicates together. The input must pass all predicates. Predicates are checked in order. If a predicate fails, the rest of the predicates are not checked. Predicates must be of the same type T.
Example:
import {chain, email, custom} from 'typura/dist/predicates';
const isSchoolEmail = chain(
email(),
custom((input: string) => /.+[.edu]$/.test(input), 'must be a school email')
);
email(): Pred<string>
Returns a predicate that checks if the input is a valid email address.
password(): Pred<string>
Returns a predicate that checks if the input is a valid password. A valid password must:
uuid(): Pred<string>
Returns a predicate that checks if the input is a valid UUID v4.
url(opts?: Options): Pred<string>
Returns a predicate that checks if the input is a valid URL.
Options:
allowLocalhost - allows localhost URLs, default is falsemain and request review. Make sure all tests pass and coverage is good.typura in your blog, tweet about it, or share it with your friends!Aeroview is a developer-friendly, AI-powered observability platform that helps you monitor, troubleshoot, and optimize your applications. Get started for free at https://aeroview.io.
FAQs
Simple and extensible runtime input validation for TS/JS, written in TS, fried in batter.
We found that @aeroview-io/rtype demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers 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.