@form2js/core

March 21, 2026 ยท View on GitHub

@form2js/core is the path parsing engine behind the rest of the package family. Use it when you already have key/value entries, need to turn them into nested objects, or want to flatten nested data back into entry form.

Installation

npm install @form2js/core

Standalone/global build is not shipped for this package.

General Example

import { entriesToObject, objectToEntries } from "@form2js/core";

const data = entriesToObject([
  { key: "person.name.first", value: "Esme" },
  { key: "person.roles[]", value: "witch" },
]);

const flat = objectToEntries(data);

Types and Properties

Exported Surface

ExportKindWhat it does
createMergeContextfunctionCreates merge state used while parsing indexed arrays.
setPathValuefunctionApplies one path/value into an object tree.
entriesToObjectfunctionMain parser for iterable entries.
objectToEntriesfunctionFlattens nested object/array data into { key, value } entries.
processNameValuesfunctionCompatibility helper for { name, value } input.
Entry, EntryInput, EntryValue, NameValuePair, ObjectTree, ParseOptions, MergeContext, MergeOptions, SchemaValidator, ValidationOptions, InferSchemaOutputtypesPublic type surface for parser inputs, options, and results.
export function createMergeContext(): MergeContext;

export function setPathValue(
  target: ObjectTree,
  path: string,
  value: EntryValue,
  options?: MergeOptions
): ObjectTree;

export function entriesToObject(entries: Iterable<EntryInput>, options?: ParseOptions): ObjectTree;
export function entriesToObject<TSchema extends SchemaValidator>(
  entries: Iterable<EntryInput>,
  options: ParseOptions & { schema: TSchema }
): InferSchemaOutput<TSchema>;

export function objectToEntries(value: unknown): Entry[];

export function processNameValues(
  nameValues: Iterable<NameValuePair>,
  skipEmpty?: boolean,
  delimiter?: string
): ObjectTree;

Options And Defaults

OptionDefaultWhereWhy this matters
delimiter"."entriesToObject, setPathValue, processNameValuesControls how dot-like path chunks are split.
skipEmptytrueentriesToObject, processNameValuesDrops "" and null values unless you opt out.
allowUnsafePathSegmentsfalseentriesToObject, setPathValueBlocks prototype-pollution path segments unless you explicitly trust the source.
schemaunsetentriesToObjectRuns schema.parse(parsedObject) and returns schema output type.
contextfresh merge contextsetPathValueKeeps indexed array compaction stable across multiple writes.

Schema validation

Use schema when you want parsing and validation in the same step. The parser only requires a structural { parse(unknown) } contract, so this works with Zod and similar validators.

import { z } from "zod";
import { entriesToObject } from "@form2js/core";

const PersonSchema = z.object({
  person: z.object({
    age: z.coerce.number().int().min(0),
    email: z.string().email()
  })
});

const rawEntries = [
  { key: "person.age", value: "17" },
  { key: "person.email", value: "esk@example.com" }
];

const result = entriesToObject(rawEntries, { schema: PersonSchema });

skipEmpty: false

Opt out of the default empty-value filtering when blank strings are meaningful in your payload.

import { entriesToObject } from "@form2js/core";

const result = entriesToObject(
  [{ key: "person.nickname", value: "" }],
  { skipEmpty: false }
);

Behavior Notes

  • Indexed array keys are compacted by encounter order, not preserved by numeric index.
  • EntryInput accepts [key, value], { key, value }, and { name, value }.
  • If schema is provided, parser output is passed to schema.parse() and schema errors are rethrown.
  • objectToEntries emits bracket indexes for arrays such as emails[0] and only serializes own enumerable properties.