
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
single-schema
Advanced tools
single-schema is a library that allows you to describe the shape of your data, then use the data shape in various ways via plugins. It's designed primarily for complex data shapes with a deep hierarchy.
single-schema is a library that allows you to describe the shape of your data, then use the data shape in various ways via plugins. It's designed primarily for complex data shapes with a deep hierarchy.
This began as a validation library that optimized for a small, easy to remember API, customization of primitive type validation, and simplicity of schema composition. As this library progressed, I realized that my schema had to stay in sync in a number of other uses. My schema had to match the objects that held state in the browser. It also had to match the schema I used on the server. To help with synchronizing the schema across various use cases, I developed a modular system that would allow the schema to be used for more than just validation.
So today, the main goals of this library are:
This library is unstable. I highly recommend that you use the exact version of this library in your package.json. See the versioning and compatibility section below for details.
Creating a schema has two main parts:
/* schema.js */
// details on setup below
import { combine, array } from './setup';
const string = {
validate: value => typeof value == 'string'
? null
: `Expected string, got ${typeof value}`,
coerce: value => String(value),
};
const person = combine({
name: string,
});
const people = array(person);
export const family = combine({
adults: people,
children: people,
});
/* app.js */
import { family } from './schema';
// returns: null
family.validate({
adults: ['Bob Saget'],
children: [],
});
const invalidFamily = {
adults: [123],
children: [],
};
/*
returns: {
adults: ['Expected string, got number']
}
*/
family.validate(invalidFamily);
/*
returns: {
adults: ['123'],
children: [],
};
*/
const coercedInvalidFamily = family.coerce({
adults: [123],
children: [],
});
// returns: null
family.validate(coercedInvalidFamily);
single-schema is modular, so we need to set it up with the modules we're using.
/* setup.js */
import create from 'single-schema';
import Coercer from 'single-schema/lib/flatteners/coercer';
import Validator from 'single-schema/lib/flatteners/validator';
const flatteners = {
validate: Validator(),
coerce: Coercer(),
};
const { combine, array, map, and, maybe } = create(flatteners);
export {
combine,
array,
map,
and,
maybe,
};
You can run the examples with npm install, then npm run storybook
Reducers: dictate the structure of the schema - leaf nodes are reducers as well
Operators: act on 1 or more reducers, returning a single reducer
Modules: provide the concrete functionality of the schema
Meta-modules: act on modules to modify their functionality
Operators provide the structure in a schema. Operators work differently depending on the module context that they are run in, so this section simply describes what the operator represents. Some operators/module combinations are not supported.
single-schama ships with 6 modules. Ultimately, I'd like to have a public API for modules, but I have some planned changes to the internals of the library before opening it up.
Note that most of the examples for the modules are fairly flat, but the schemas can have arbitrary depth. See the complete use cases for more complex examples.
Note: if you're viewing this on NPM, you may need to switch to the repository to open these links, since NPM doesn't seem to handle relative links to docs.
Right now there is only one meta-module: Async, which adds asynchronous leaf resolution.
This library is a work in progress and the various portions have different levels of API stability. The way the schema is described will likely stay the same, but the rest of the API is subject to change.
There is reasonbly good test coverage, but I imagine there are bugs that I haven't hit yet. In particular, there are likely parts that work but would be more useful with alternate logic.
Because of the current unstability, minor releases in this package before it hits 1.0 will have breaking changes that will likely require changes to run without errors. Minor could be changes as significant as moving files or changing exports.
Patch fixes should still run without changes, but may change the logic in such a way that it breaks your code anyway. An example of this would be changing the way a module handles the difference between {key: undefined}, {key: null}, and {}.
The upside of this situation is that I'm more likely to consider breaking changes if they make sense to merge in. In any case, I recommend that you use the exact version of this library in your package.json.
Also, it's fairly likely there are minor mistakes in the docs here at this point. File an issue if you find something that seems off!
FAQs
single-schema is a library that allows you to describe the shape of your data, then use the data shape in various ways via plugins. It's designed primarily for complex data shapes with a deep hierarchy.
The npm package single-schema receives a total of 2 weekly downloads. As such, single-schema popularity was classified as not popular.
We found that single-schema 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
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

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.