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

@finsys/core

v1.2.0

Published

Convert unified form configurations into Zod schemas, React Hook Form defaults, and SurveyJS JSON

Readme

@finsys/core

Convert unified form configurations into Zod schemas, React Hook Form defaults, and SurveyJS JSON.

Features

  • Unified Form Configuration — Single JSON format for defining form fields and multi-step page layouts
  • React Hook Form Generator — Generate Zod schemas, default values, and step configurations from a form config
  • SurveyJS Generator — Generate SurveyJS-compatible JSON from the same config
  • Schema Validation — Validate form configurations against a strict JSON Schema (AJV)
  • Visibility-Aware Validation — Conditional fields are only validated when visible (visibleIf expressions)
  • TypeScript-First — Full type exports for all config types and generator outputs

Installation

npm install @finsys/core

If you use the SurveyJS generator, install the peer dependency:

npm install survey-core

Quick Start

React Hook Form

import { generateRHFSchema } from '@finsys/core';
import formConfig from './form-config.json';

const { zodSchema, defaultValues, steps, groupedFields } = generateRHFSchema(formConfig);

// Use with React Hook Form + zodResolver
// zodSchema     — Zod schema for the entire form
// defaultValues — Default values for all fields
// steps         — Array of step metadata (title, description, field names)
// groupedFields — Fields grouped by category per step

SurveyJS

import { generateSurveyJson } from '@finsys/core';
import formConfig from './form-config.json';

const surveyJson = generateSurveyJson(formConfig);
// Pass surveyJson to SurveyJS Model

Config Validation

import { validateFormConfig } from '@finsys/core';
import formConfig from './form-config.json';

const result = validateFormConfig(formConfig);
if (!result.valid) {
  console.error('Validation errors:', result.errors);
}

Expression Evaluation

import { evaluateExpression } from '@finsys/core';

// Evaluate SurveyJS-style visibility expressions
const visible = evaluateExpression('{totalFinancing} > 50000', { totalFinancing: 75000 });
// true

Form Configuration Schema

A form config JSON has three required top-level keys: categories, fields, and pages.

{
  "$schema": "node_modules/@finsys/core/dist/schema/unified-form.schema.json",
  "schemaVersion": "2.0",
  "displayName": "My Application Form",
  "categories": [
    { "id": "contact", "name": "Contact Information" },
    { "id": "business", "name": "Business Details" }
  ],
  "fields": {
    "fullName": {
      "type": "text",
      "displayName": "Full Name",
      "category": "contact",
      "required": true
    },
    "email": {
      "type": "text",
      "inputType": "email",
      "displayName": "Email Address",
      "category": "contact",
      "validators": [{ "type": "email", "text": "Please enter a valid email" }]
    },
    "companyName": {
      "type": "text",
      "displayName": "Company Name",
      "category": "business"
    }
  },
  "pages": [
    {
      "id": "step1",
      "title": "Your Information",
      "fields": ["fullName", "email"]
    },
    {
      "id": "step2",
      "title": "Business Details",
      "fields": [
        "companyName",
        { "ref": "email", "displayName": "Business Email", "readOnly": true }
      ]
    }
  ]
}

Field References

Pages reference fields in three ways:

| Format | Example | Description | |--------|---------|-------------| | String | "fullName" | Simple reference to a field in fields | | Ref with overrides | { "ref": "email", "displayName": "Work Email" } | Reference with per-page property overrides | | Inline definition | { "definition": { "name": "note", "type": "html", "html": "..." } } | Page-specific field not in master fields |

Supported Field Types

text, number, email, file, dropdown, checkbox, boolean, comment, radiogroup, range, html, slider

Validator Types

regex, email, numeric, text, expression, answercount, custom

API Reference

generateRHFSchema(config: UnifiedFormConfig): RHFSchemaOutput

Converts a form config into Zod schemas and React Hook Form metadata.

Returns { zodSchema, baseSchema, defaultValues, fields, groupedFields, steps, displayName, categories, templateIcon }

getStepSchema(step: RHFStep, fullSchema: ZodObject): ZodTypeAny

Extracts the Zod schema for a specific form step.

getStepDefaultValues(step: RHFStep, allDefaults: Record<string, any>): Record<string, any>

Extracts default values for a specific form step.

generateSurveyJson(config: UnifiedFormConfig): SurveyJSON

Converts a form config into SurveyJS-compatible JSON. Requires survey-core peer dependency.

validateFormConfig(data: unknown): ValidationResult

Validates a form config object against the unified form JSON schema. Returns { valid, errors, message? }.

evaluateExpression(expression: string, data: any): boolean

Evaluates a SurveyJS-style expression (e.g., {fieldName} > 100) against a data object.

resolvePageFields(page: PageConfig, fields: Record<string, FieldData>): ResolvedField[]

Resolves all field references in a page to full field definitions.

groupFieldsByCategory(fields: ResolvedField[], categories: Category[]): FieldGroup[]

Groups resolved fields by their category, maintaining order.

applyDynamicTitles(field: ResolvedField): ResolvedField

Applies dynamic display names for known naming patterns (e.g., bank_statement_t1 gets a month label).

Utility Functions

  • getPastMonthLabel(monthsAgo: number): string — Returns the month name N months ago
  • getPastYearLabel(yearsAgo: number): string — Returns the year N years ago
  • getCategoryName(categoryId: string | undefined, categories: Category[]): string — Looks up category display name

Exported Types

// Config types
UnifiedFormConfig, FieldData, FieldReference, PageConfig, Category, Choice, Validator

// Output types
ResolvedField, FieldGroup, RHFStep, RHFSchemaOutput
SurveyElementJSON, SurveyPageJSON, SurveyJSON

// Re-exported from survey-core
IQuestion, IPage, ISurvey, IPanel, IElement

Development

npm install
npm run build    # Compile TypeScript + copy schema
npm run dev      # Watch mode
npm test         # Run tests (Vitest)
npm run lint     # Type-check without emitting

Contributing

See CONTRIBUTING.md.

Security

Expression Evaluation

The evaluateExpression() function uses new Function() internally to evaluate SurveyJS-style visibility expressions. Expression strings must come from trusted, developer-authored sources (e.g., your own form configuration files). Never pass untrusted or user-supplied strings as expressions, as this could allow arbitrary code execution.

Disclaimer

This library provides form configuration utilities and does not constitute financial, legal, or investment advice. It does not perform financial calculations, risk assessments, or lending decisions. The creators and contributors accept no liability for decisions made using forms generated by this library. See the LICENSE file for warranty and liability terms.

License

Apache-2.0