@fnet/object-from-schema
TypeScript icon, indicating that this package has built-in type declarations

0.1.25 • Public • Published

@fnet/object-from-schema

Introduction

@fnet/object-from-schema is a utility that assists users in generating structured data objects that are compliant with a specified JSON schema. This tool facilitates users by interactively gathering input through prompts, using the schema to ensure validation and format. It can be especially beneficial for those needing to create JSON or YAML configurations based on predefined standards.

How It Works

The tool operates by reading a JSON schema—either from a file, URL, or directly provided object—and guides the user to input data that conforms to this schema. By using dynamic prompts, it supports complex schema structures such as oneOf, anyOf, allOf, and conditional schemas like if/then/else. If a reference (ref) object is provided, its values are used as defaults, aiding users in completing similar forms more efficiently.

Key Features

  • Interactive Prompts: Collects user input interactively, ensuring data validity according to the schema.
  • Complex Schema Handling: Supports advanced JSON Schema features like oneOf, anyOf, allOf, dependencies, and conditional logic (if/then/else).
  • Custom Prompts: Allows customization of prompts using attributes like x-prompt.
  • Validation: Enforces schema-based validation, ensuring the input data meets all constraints.
  • Schema and Reference Loading: Loads schemas and reference data from various sources, including files and URLs.
  • Output Formats: Generates data in JSON or YAML format, or both, based on the user's preference.

Conclusion

@fnet/object-from-schema is a practical tool for users needing to generate valid structured data from a JSON schema. By ensuring compliance through guided input collection, it simplifies the creation of schema-based configurations, making it easier for users to adhere to standards in their data formats.

@fnet/object-from-schema Developer Guide

Overview

The @fnet/object-from-schema library is designed for developers who need to generate YAML or JSON formatted objects from a given JSON schema. This library simplifies the process by leveraging interactive user prompts for input values and supports complex schema features such as oneOf, anyOf, allOf, conditional schemas (if/then/else), and dependencies, along with the ability to use default values from reference objects.

Key features include:

  • Full JSON Schema validation (string, number, array, object constraints)
  • Support for complex schemas (oneOf, anyOf, allOf, if/then/else, dependencies)
  • Custom prompt types via x-prompt attribute
  • Reference resolution (local, remote, file)
  • Interactive navigation between prompts

Installation

To install the library, use either npm or yarn:

npm install @fnet/object-from-schema

or

yarn add @fnet/object-from-schema

Usage

Below is a step-by-step guide on using @fnet/object-from-schema to generate a YAML or JSON object based on a provided JSON schema.

Basic Example

To generate an object from a schema, you can call the main function exported by the library. Here’s a simple use case:

import objectFromSchema from '@fnet/object-from-schema';

const schema = {
  type: 'object',
  properties: {
    name: { type: 'string', description: 'Name of the person' },
    age: { type: 'number', description: 'Age of the person' },
  },
  required: ['name']
};

const ref = {
  name: 'John Doe'
};

(async () => {
  const result = await objectFromSchema({ schema, ref, format: 'yaml' });
  console.log(result); // Outputs a YAML string with comments
})();

Using a Reference Object

The function can accept a reference object that provides default values for the schema properties, allowing easy overriding and default value usages:

const ref = {
  name: 'Alice'
};

const result = await objectFromSchema({ schema, ref, format: 'json' });
console.log(result); // Outputs a JSON string with default values applied

Output Formats

The library supports different output formats through the format option:

  • json: Returns the result in JSON format.
  • yaml: Returns the result in YAML format.
  • all: Returns both formats.
const result = await objectFromSchema({ schema, format: 'all' });
console.log(result.json); // JSON format output
console.log(result.yaml); // YAML format output

Advanced Features

Custom Prompt Types with x-prompt

The library supports customizing the prompt experience using the x-prompt attribute in your JSON Schema. This allows you to specify the prompt type, message, and other options.

Basic Usage

const schema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
      description: 'Name of the person',
      x-prompt: 'What is your name?' // Simple string for custom message
    },
    favoriteColor: {
      type: 'string',
      enum: ['red', 'green', 'blue', 'yellow'],
      description: 'Favorite color',
      x-prompt: {
        type: 'select', // Use select prompt type
        message: 'Choose your favorite color:',
        choices: ['red', 'green', 'blue', 'yellow']
      }
    }
  }
};

Available Prompt Types

The library supports various prompt types from Enquirer through @fnet/prompt:

  • input: Standard text input (default for string)
  • password: Masked text input
  • number: Numeric input (default for number/integer)
  • confirm: Yes/No confirmation (default for boolean)
  • select: Single option selection from a list
  • multiselect: Multiple option selection from a list
  • text: Multi-line text input
  • list: Comma-separated list input
  • toggle: On/Off toggle switch

Advanced Configuration

const schema = {
  type: 'object',
  properties: {
    skills: {
      type: 'array',
      items: {
        type: 'string'
      },
      description: 'Your skills',
      x-prompt: {
        type: 'multiselect',
        message: 'Select your skills:',
        choices: [
          { name: 'JavaScript', value: 'javascript' },
          { name: 'Python', value: 'python' },
          { name: 'Java', value: 'java' },
          { name: 'C++', value: 'cpp' },
          { name: 'Ruby', value: 'ruby' }
        ],
        hint: 'Space to select, Enter to submit',
        prefix: '🔧'
      }
    }
  }
};

Conditional Schemas with if/then/else

The library supports conditional schemas using the if/then/else keywords:

const conditionalSchema = {
  type: 'object',
  properties: {
    userType: {
      type: 'string',
      enum: ['individual', 'company'],
      description: 'Type of user'
    },
    firstName: { type: 'string', description: 'First name' },
    lastName: { type: 'string', description: 'Last name' },
    ssn: { type: 'string', description: 'Social Security Number' },
    companyName: { type: 'string', description: 'Company name' },
    taxId: { type: 'string', description: 'Tax ID' }
  },
  required: ['userType'],
  allOf: [
    {
      if: {
        properties: { userType: { const: 'individual' } }
      },
      then: {
        required: ['firstName', 'lastName', 'ssn']
      }
    },
    {
      if: {
        properties: { userType: { const: 'company' } }
      },
      then: {
        required: ['companyName', 'taxId']
      }
    }
  ]
};

Dependencies

The library supports dependencies using the dependencies or dependentRequired keywords:

const dependenciesSchema = {
  type: 'object',
  properties: {
    creditCard: {
      type: 'boolean',
      description: 'Do you want to pay with credit card?'
    },
    cardNumber: {
      type: 'string',
      description: 'Credit card number'
    },
    expirationDate: {
      type: 'string',
      description: 'Expiration date'
    },
    cvv: {
      type: 'string',
      description: 'CVV code'
    }
  },
  required: ['creditCard'],
  dependentRequired: {
    creditCard: ['cardNumber', 'expirationDate', 'cvv']
  }
};

Examples

Example with oneOf

const schemaWithOneOf = {
  type: 'object',
  oneOf: [
    {
      properties: {
        type: { const: 'student' },
        grade: { type: 'number', description: 'Grade of the student' }
      },
    },
    {
      properties: {
        type: { const: 'teacher' },
        subject: { type: 'string', description: 'Subject taught by the teacher' }
      },
    },
  ],
};

const result = await objectFromSchema({ schema: schemaWithOneOf, format: 'yaml' });
console.log(result); // Outputs YAML with the selected option

Example with anyOf

const schemaWithAnyOf = {
  type: 'object',
  anyOf: [
    { properties: { skill: { type: 'string', description: 'A skill' } } },
    { properties: { hobby: { type: 'string', description: 'A hobby' } } }
  ],
};

const result = await objectFromSchema({ schema: schemaWithAnyOf, format: 'json' });
console.log(result); // Outputs JSON with multiple selected options

Acknowledgements

This library makes use of the following packages:

  • @fnet/yaml: For YAML document construction and manipulation
  • @fnet/prompt: For interactive command-line prompts (based on Enquirer)
  • Enquirer: For the underlying prompt types and interactive UI

Many thanks to the developers of these packages for their contributions to simplifying YAML manipulations and interactive command-line interfaces in JavaScript.

Input Schema

$schema: https://json-schema.org/draft/2020-12/schema
type: object
description: >
  Generate an object based on a JSON schema with interactive prompts.


  Features:

  - Full JSON Schema validation (string, number, array, object constraints)

  - Support for complex schemas (oneOf, anyOf, allOf, if/then/else,
  dependencies)

  - Custom prompt types via x-prompt attribute

  - Reference resolution (local, remote, file)

  - Interactive navigation between prompts
properties:
  schema:
    type:
      - string
      - object
    description: The JSON schema to base the user prompts on. Can be a file path,
      URL, or direct object.
    x-prompt:
      message: "Enter the JSON schema path or object:"
      type: input
  ref:
    type:
      - string
      - object
    description: Optional reference object or file path/URL to use for default values.
    x-prompt:
      message: "Enter a reference object path (optional):"
      type: input
  format:
    type: string
    enum:
      - json
      - yaml
      - all
    default: json
    description: The format of the output. Can be 'json', 'yaml', or 'all'.
    x-prompt:
      message: "Select the output format:"
      type: select
      choices:
        - name: JSON
          value: json
        - name: YAML
          value: yaml
        - name: Both JSON and YAML
          value: all
      initial: 0
required:
  - schema

Output Schema

$schema: https://json-schema.org/draft/2020-12/schema
description: |
  The output of the @fnet/object-from-schema library.

  The output format depends on the 'format' parameter provided in the input:
  - 'json': Returns a JavaScript object (default)
  - 'yaml': Returns a YAML string with comments
  - 'all': Returns an object with both 'json' and 'yaml' properties
oneOf:
  - type: object
    title: JSON Output
    description: When format is 'json' (default), returns a JavaScript object
    additionalProperties: true
    example: |
      {
        "name": "John Doe",
        "age": 30,
        "email": "john.doe@example.com",
        "isStudent": false
      }
  - type: string
    title: YAML Output
    description: When format is 'yaml', returns a YAML string with comments
    example: |
      # Your full name
      name: John Doe
      # Your age
      age: 30
      # Your email address
      email: john.doe@example.com
      # Are you a student?
      isStudent: false
  - type: object
    title: Combined Output
    description: When format is 'all', returns an object with both formats
    properties:
      json:
        type: object
        description: The generated object in JSON format
        additionalProperties: true
      yaml:
        type: string
        description: The generated YAML document as a string with comments
    required:
      - json
      - yaml
    example: >
      {
        "json": {
          "name": "John Doe",
          "age": 30,
          "email": "john.doe@example.com",
          "isStudent": false
        },
        "yaml": "# Your full name\nname: John Doe\n# Your age\nage: 30\n# Your email address\nemail: john.doe@example.com\n# Are you a student?\nisStudent: false"
      }

Readme

Keywords

none

Package Sidebar

Install

npm i @fnet/object-from-schema

Weekly Downloads

10

Version

0.1.25

License

MIT

Unpacked Size

245 kB

Total Files

8

Last publish

Collaborators

  • serdar986
  • serdark
  • gboyraz