npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sass-valid

v2.0.0

Published

Sass schema-driven validation — per the Error Message Specification

Readme

sass-valid

Sass schema-driven validation — per the Error Message Specification.


Installation

npm install sass-valid sass-funcs sass-error

Requires sass or sass-embedded >= 1.33.0 — install one, not both (sass-embedded recommended). Also requires sass-funcs and sass-error.


Configuration

All constants are configurable via @use ... with (...):

@use 'sass-valid' as v with (
  $VALIDATION_MODE_SELECTED: 'strict',
  $ERROR_HINT_TEXT: 'Refer to the schema'
);

| Variable | Default | Description | | --------------------------- | --------------------------------- | ------------------------------------------------------------------ | | $VALUE_ID_ALLOWED_TYPES | ('string', 'number', 'bool') | Allowed Sass types for map keys (entity attributes, schema fields) | | $FIELD_REQUIRED | 'is-required' | Schema field name for the required flag | | $FIELD_ALLOWED_TYPES | 'allowed-types' | Schema field name for allowed types | | $FIELD_ALLOWED_VALUES | 'allowed-values' | Schema field name for allowed values | | $FIELD_VALIDATOR | 'validator' | Schema field name for the custom validator name | | $ERROR_HINT_TEXT | 'See schema for allowed values' | Hint appended when the options list is truncated | | $ERROR_LABEL_ENTRY | 'ENTRY' | Default label for collection member keys in error codes | | $ERROR_LABEL_FIELD | 'FIELD' | Default label for schema field keys in error codes | | $ERROR_ENTRY_LABELS | ('ENTRY', 'FIELD') | Allowed values for $custom-entry-label | | $VALIDATION_MODE_SELECTED | 'rigid' | Default validation mode |

Note: See the Error Message Specification for details on how error codes and labels are structured.


Module: Valid

@use 'sass-valid' as v;

| Function | Description | | -------------------------------------- | --------------------------------------------------- | | validate | Validates an entity map against a schema definition |


v.validate($schema, $entity, ...)

Validates an entity map against a schema. The schema is checked against a built-in metaschema on first use and the result is cached — repeated calls with the same schema incur no extra cost.

| Parameter | Type | Default | Description | | --------------------- | ---------------- | --------------------------- | ------------------------------------------------------------------------------ | | $schema | Map | | Schema definition map | | $entity | Map | | Entity map to validate | | $entity-type | String | 'entity' | Label for the entity type in error messages | | $entity-name | String | 'unnamed' | Label for the entity name in error messages | | $mode | String | $VALIDATION_MODE_SELECTED | Validation mode: 'permissive', 'rigid', or 'strict' | | $custom-entry-label | String | $ERROR_LABEL_ENTRY | Label for entry-level error codes: 'ENTRY' or 'FIELD' | | $schema-id | String \| Null | null | Cache key override; use when the same $entity-type maps to different schemas | | $validators | Map | () | Map of validator name strings to Sass function references |

Returns Null on success, String error message on failure (see Error Message Specification) — pass to @error to raise.

$schema: (
  'name': ('is-required': true,  'allowed-types': 'string'),
  'role': ('is-required': true,  'allowed-types': 'string', 'allowed-values': ('admin', 'user', 'guest')),
  'age':  ('is-required': false, 'allowed-types': 'number'),
);

v.validate($schema, ('name': 'Alice', 'role': 'admin'), 'person', 'Alice')
// → null

v.validate($schema, ('name': 'Alice', 'role': 42), 'person', 'Alice')
// → '[PERSON_ROLE_TYPE] Person "Alice" @ role: Incorrect type "number" → Expected: string'

v.validate($schema, ('name': 'Alice', 'role': 'owner'), 'person', 'Alice')
// → '[PERSON_ROLE_VALUE] Person "Alice" @ role: Invalid value "owner" → Allowed: admin | user | guest'

v.validate($schema, ('name': 'Alice', 'role': 'admin', 'rank': 1), 'person', 'Alice')
// → '[PERSON_RANK_UNKNOWN] Person "Alice": Unknown attribute "rank" → Remove "rank" [context: mode "rigid"]'

Schema Definition

A schema is a Sass map where each key is an attribute name and each value is a rules map:

$schema: (
  '<attribute>': (
    'is-required': <bool>,
    // optional — defaults to false
    'allowed-types': '<type>',
    // required — Sass type name or list of names
    'allowed-values': (
        <val>,
        ...,
      ),
    // optional — allowed values, or a nested schema map
    'validator': '<name>',
    // optional — custom validator key
  ),
  ...,
);

The field names 'is-required', 'allowed-types', 'allowed-values', and 'validator' are configurable via $FIELD_REQUIRED, $FIELD_ALLOWED_TYPES, $FIELD_ALLOWED_VALUES, and $FIELD_VALIDATOR.

| Field | Type | Required | Description | | ------------------ | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 'is-required' | Bool | No | Whether the attribute must be present. Always true in 'strict' mode. | | 'allowed-types' | String \| List | Yes | One or more Sass type names: 'number', 'string', 'list', 'bool', 'map' | | 'allowed-values' | * \| Map | No | Allowed values as a flat list, or a nested schema map when the attribute type is 'map'. When a list, each element of the attribute value is checked individually. | | 'validator' | String | No | Name key matching an entry in $validators |

Nested Schemas

When 'allowed-values' is a map and the attribute value is also a map, validate recurses into the nested schema using the same mode and custom validators:

$schema: (
  'config': (
    'is-required': true,
    'allowed-types': 'map',
    'allowed-values': (
      'theme': ('is-required': true,  'allowed-types': 'string', 'allowed-values': ('light', 'dark')),
      'scale': ('is-required': false, 'allowed-types': 'number'),
    ),
  ),
);

v.validate($schema, ('config': ('theme': 'dark', 'scale': 1.5)), 'settings', 'app')
// → null

v.validate($schema, ('config': ('theme': 'blue')), 'settings', 'app')
// → '[SETTINGS_THEME_VALUE] Settings "app" @ config > theme: Invalid value "blue" → Allowed: light | dark'

Validation Modes

| Mode | Unknown attributes | Missing optional attributes | | -------------- | ------------------ | --------------------------- | | 'permissive' | Allowed | Skipped | | 'rigid' | Error | Skipped | | 'strict' | Error | Error |

The default mode is 'rigid'. Override per-call via $mode, or globally via $VALIDATION_MODE_SELECTED:

v.validate($schema, $entity, 'person', 'Alice', $mode: 'permissive')  // extra fields allowed
v.validate($schema, $entity, 'person', 'Alice', $mode: 'rigid')       // default
v.validate($schema, $entity, 'person', 'Alice', $mode: 'strict')      // all fields required

Custom Validators

A custom validator is a Sass function that performs checks on an attribute value beyond type and 'allowed-values' validation. It is called after both pass and must return null on success or an error string on failure.

Register validators by passing a map of name strings to Sass function references via $validators. A validator name present in a schema but absent from this map triggers an "unresolved function" error at runtime.

Custom validator functions receive these positional arguments:

| Position | Name | Type | Description | | -------- | --------------------- | -------- | ----------------------------------------- | | 1 | $entity | Map | The full entity map | | 2 | $attribute | String | The attribute name being validated | | 3 | $attribute-rules | Map | The schema rules map for this attribute | | 4 | $code-base | String | Error code prefix (e.g. 'PERSON_AGE') | | 5 | $entity-type-cap | String | Capitalized entity type (e.g. 'Person') | | 6 | $entity-name | String | The entity name (e.g. 'Alice') | | 7 | $current-path | List | Current path list (e.g. ('age',)) | | 8 | $custom-entry-label | String | Entry label for error codes |

Returns Null on success, String error message on failure.

@use 'sass-valid' as v;
@use 'sass:meta';
@use 'sass:map';

@function -positive-number($entity, $attribute, $rules, $code, $type, $name, $path, $label) {
  $value: map.get($entity, $attribute);
  @if $value <= 0 {
    @return '[#{$code}_VALUE] #{$type} "#{$name}" @ #{$attribute}: Invalid value "#{$value}" → Expected: positive number';
  }
  @return null;
}

$schema: (
  'count': ('is-required': true, 'allowed-types': 'number', 'validator': 'positive-number'),
);

$validators: ('positive-number': meta.get-function('-positive-number'));

v.validate($schema, ('count': 5),  'item', 'box', $validators: $validators)
// → null

v.validate($schema, ('count': -1), 'item', 'box', $validators: $validators)
// → '[ITEM_COUNT_VALUE] Item "box" @ count: Invalid value "-1" → Expected: positive number'

Migration

v1 → v2

  • $custom-validators renamed to $validators
  • ARGUMENT_CUSTOM_VALIDATORS_TYPE renamed to ARGUMENT_VALIDATORS_TYPE

Back to top