synapsestudios/lively — pull request #74 by paulstatezny (2014-08-19 20:41:11+00:00)
Title: Add "hash" parameter support

## As a developer, I can use "hash" as a parameter type, so that more of the GitHub endpoints can be implemented.

### Acceptance Criteria
1. User can set a param as a `hash`, and Lively renders the hash as a sub-object of the main request object. (Visually, it's indented.)
1. User can set a param as an `array[hash]`, and Lively renders it like a normal array (with the "Add Field" button).
- When the user clicks "Add Field", a new hash group is added below the array[hash] param.
- The hash has all of the fields specified in the config (In the `params` property.)

### Tasks
- Refactor `param-list` component to use recursion rather than sub-components to build markup.
- Modify form elements to be controlled components.
- Add logic in `param-list` to display and interact with hashes and arrays of hashes.

### Additional Notes
This story supports an infinite level of nesting -- hashes with hashes inside them, hashes with arrays of hashes inside them, etc.

`hash` and `array[hash]` params are expected to contain a `params` property in their configuration, to denote the sub-params inside them. Like so:

```JSON
{
"name" : "Method name",
"synopsis" : "Synopsis...",
"method" : "POST",
"uri" : "/etc/etc",
"params" : [
{
"name" : "name",
"type" : "string"
},
{
"name" : "some_hash_field",
"type" : "hash"
"params" : [
{
"name" : "date",
"type" : "string",
},
{
"name" : "email_addresses",
"type" : "array[string]"
},
{
"name" : "some_array_with_more_hashes_in_it",
"type" : "array[hash]",
"params" : [
{
"name" : "is_delicious",
"type" : "boolean"
},
{
"name" : "type",
"type" : "enum",
"enumValues" : [
"badger",
"raccoon",
"guacamole"
]
}
]
}
]
}
]
}
```

Such a configuration would result in request bodies like this:
```JSON
{
"name" : "Paul",
"some_hash_field" : {
"date" : "4/6/2014",
"email_addresses" : [
"test@example.com",
"test2@example.com"
],
"some_array_with_more_hashes_in_it" : [
{
"is_delicious" : false,
"type" : "raccoon"
},
{
"is_delicious" : true,
"type" : "guacamole"
},
{
"is_delicious" : false,
"type" : "badger"
},
]
}
}
```