@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.
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.
- 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.
@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.
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
To install the library, use either npm or yarn:
npm install @fnet/object-from-schema
or
yarn add @fnet/object-from-schema
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.
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
})();
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
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
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.
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']
}
}
}
};
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
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: '🔧'
}
}
}
};
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']
}
}
]
};
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']
}
};
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
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
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.
$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
$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"
}