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 🙏

© 2024 – Pkg Stats / Ryan Hefner

html-json-form

v0.1.0

Published

Server side library for harmonising JSON and HTML form submissions

Downloads

2

Readme

html-json-form

Server side library for harmonising JSON and HTML form submissions

Parses client-side HTML form submissions, with object structure marked up in field names, to structured objects on the server to harmonise handling both HTML forms and JSON on a single endpoint.

Given the following form:

<input type="text" name="a[]" value="foo">
<input type="text" name="a[]" value="bar">
<input type="text" name="b[baz]" value="woo">

The resulting object would be:

{
  a: ['foo', 'bar'],
  b: {
    baz: 'woo'
  }
}

Introduction

It can be desirable to have an HTTP endpoint which can handle either both a JSON payload and an HTML form submission, to allow for a programmatic API and web- based interactions.

This may typically involve creating logic that handles each separately, considering HTML forms off a flat key-value approach, versus the potentially complex structuring JSON can offer.

In 2015 a W3C working group proposed a standard for HTML JSON form submissions, but sadly this project was abandoned.

https://www.w3.org/TR/html-json-forms/#form-submission

This project adopts the same approach as the proposal, but implemented on the server-side. Using the same naming convention for HTML form fields, the server can then interpret and build complex objects from. This simplies the downstream logic to validate and process the incoming request, as your object can end up in the same structure as your JSON payload design.

Installation

npm install html-json-form

Usage

To parse an existing query string:

import parse from 'html-json-form'

const form = 'a[]=foo&a[]=bar&b[baz]=woo'
parse(form) // { a: ['foo', 'bar'], b: { baz: 'woo' } }

const json = '{"a":["foo","bar"],"b":{"bar":"woo"}}'
parse(json) // { a: ['foo', 'bar'], b: { baz: 'woo' } }

If you're writing logic for inside an AWS Lambda function with an API Gateway proxy, there is also a middleware to help simplify your implementation, which will parse and replace the body attribute of the handler's event argument with the resulting object for a submitted form or JSON payload.

import { middleware } from 'html-json-form'

export const handler = middlware(async (event) => {
  console.log(event.body) // { a: ['foo', 'bar'], b: { baz: 'woo' } }
})

If you prefer to not use the supplied middleware, you can still utilise the internal Lambda handling behaviour as follows:

import { parseLambdaEvent } from 'html-json-form'

export const handler = async (event) => {
  console.log(parseLambdaEvent(event)) // { a: ['foo', 'bar'], b: { baz: 'woo' } }
}

For detailed information on the field name structure, check out the original proposal. This library includes one minor extension to the specification, where types can be declared via hidden fields.

The original client-side spec can read the type of any field when building the JSON object, but these are never part of the HTTP request and available server side. Instead, this library introduces a special property name that can optionally be included in your form, ideally via hidden inputs so as not to be surfaced to the user within a form:

<input type="hidden" name="_type[foo]" value="number">
<input type="number" name="foo" value="1">

This would produce the output:

{ foo: 1 }

If you need to define multiple types, this can be done as follows:

<input type="number" name="foo" value="1">
<input type="hidden" name="_type[foo]" value="number">
<input type="checkbox" name="bar[baz]" checked>
<input type="hidden" name="_type[bar][baz]" value="boolean">

And would return the object:

{
  foo: 1, 
  bar: {
    baz: true
  }
}