Skip to content

toomuchdesign/json-schema-fns

Repository files navigation

@toomuchdesign/json-schema-fns

Build Status Npm version Coveralls

@toomuchdesign/json-schema-fns is a type-safe immutable utility library for transforming JSON Schemas.

It ensures that schema transformations not only update the runtime schema correctly but also preserve accurate TypeScript type inference. This makes it especially useful when paired with tools like json-schema-to-ts.

import { omitProps } from '@toomuchdesign/json-schema-fns';
import type { FromSchema } from 'json-schema-to-ts';

const userSchema = {
  type: 'object',
  properties: {
    id: { type: 'string' },
    password: { type: 'string' },
  },
  required: ['id', 'password'],
} as const;

const publicUserSchema = omitProps(userSchema, ['password']);
type PublicUser = FromSchema<typeof publicUserSchema>;
// { id: string }

Why?

Manipulating JSON Schemas directly can be verbose and error-prone.

This library provides small, focused utilities that keep runtime schemas and TypeScript types in sync — especially when paired with json-schema-to-ts.

Installation

npm install @toomuchdesign/json-schema-fns

API

  • omitProps – Omit specific properties from an object JSON schema
  • pickProps – Pick only specific properties from an object JSON schema
  • mergeProps – Merge two object JSON schemas properties and patternProperties props into one. If the same property key exists in both schemas, the property from schema2 takes precedence
  • requireProps – Mark specific properties in a object JSON schema as required. If no keys provided, all properties become required
  • optionalProps – Make specific properties of a object JSON schema optional. If no keys provided, all properties become optional
  • sealSchemaDeep – Recursively set additionalProperties: false on all object JSON schema schemas
  • unsealSchemaDeep – Recursively remove additionalProperties from all object JSON schema schemas

omitProps

Omit specific properties from an object JSON schema.

import { omitProps } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'number' },
  },
  required: ['a', 'b'],
} as const;

const result = omitProps(schema, ['b']);

pickProps

Pick only specific properties from an object JSON schema.

import { pickProps } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'number' },
  },
  required: ['a', 'b'],
} as const;

const result = pickProps(schema, ['b']);

mergeProps

Merge two object JSON schemas properties and patternProperties props into one. If the same property key exists in both schemas, the property from schema2 takes precedence.

import { mergeProps } from '@toomuchdesign/json-schema-fns';

const schema1 = {
  type: 'object',
  properties: {
    a: { type: 'string' },
  },
  required: ['a'],
} as const;

const schema2 = {
  type: 'object',
  properties: {
    b: { type: 'number' },
  },
  required: ['b'],
} as const;

const result = mergeProps(schema1, schema2);

requireProps

Mark specific properties in a object JSON schema as required. If no keys provided, all properties become required.

import { requireProps } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'string' },
    c: { type: 'string' },
  },
  required: ['b'],
} as const;

const result = requireProps(schema, ['a', 'c']);

optionalProps

Make specific properties of a object JSON schema optional. If no keys provided, all properties become optional.

import { optionalProps } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'string' },
    c: { type: 'string' },
  },
  required: ['a', 'b', 'c'],
} as const;

const result = optionalProps(schema, ['b', 'c']);

sealSchemaDeep

Recursively set additionalProperties: false on all object JSON schema schemas.

import { sealSchemaDeep } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  required: ['name'],
  properties: {
    name: { type: 'string' },
    address: {
      type: 'object',
      properties: {
        street: { type: 'string' },
      },
    },
  },
} as const;

const result = sealSchemaDeep(schema);

unsealSchemaDeep

Recursively remove additionalProperties from all object JSON schema schemas.

import { unsealSchemaDeep } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  additionalProperties: false,
  required: ['name'],
  properties: {
    name: { type: 'string' },
    address: {
      type: 'object',
      additionalProperties: false,
      properties: {
        street: { type: 'string' },
      },
    },
  },
} as const;

const result = unsealSchemaDeep(schema);

Composition & pipe-friendly API

In addition to the standard functional API, json-schema-fns also offers a composition-friendly counterpart that enables schema transformations through a pipeable interface.

Note: The library does not include its own pipe utility. You are free to use any composition library you prefer, such as pipe-ts, ts-functional-pipe or even bigger libraries like effect or remeda. See composition tests.

Functional API Example

import {
  mergeProps,
  omitProps,
  requireProps,
  sealSchemaDeep,
} from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'string' },
  },
  required: ['a'],
} as const;

const result = sealSchemaDeep(
  requireProps(
    omitProps(
      mergeProps(schema, {
        type: 'object',
        properties: {
          c: { type: 'string' },
        },
      }),
      ['a'],
    ),
    ['b'],
  ),
);

Pipeable API Example

import {
  pipeMergeProps,
  pipeOmitProps,
  pipeRequireProps,
  pipeSealSchemaDeep,
} from '@toomuchdesign/json-schema-fns';
import { pipeWith } from 'pipe-ts';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'string' },
  },
  required: ['a'],
} as const;

const result = pipeWith(
  schema,
  pipeMergeProps({
    type: 'object',
    properties: {
      c: { type: 'string' },
    },
  }),
  pipeOmitProps(['a']),
  pipeRequireProps(['b']),
  pipeSealSchemaDeep(),
);

Similar packages

Contributing

Contributions are welcome! Before opening a PR, please run:

npx changeset

About

JSON Schema utility library with full TypeScript support

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •