Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
mongoose-formulate
Advanced tools
Mongoose plugins to faciliate dynamic form based input based on custom templates
Mongoose Formulate is a package of 2 mongoose plugins that allow you to bake a programmable CMS into your existing applications. It's intended to be used to build a framework that allows dynamic creation of form templates that in turn structure input that is stored in entries.
If you need a system for allowing users of your application to define custom form templates based on common input formats and a flexible way to store data submitted against those templates, Formulate is for you. Think of it as a pluggable CMS. If your looking for a full-blown CMS solution then it's not for you. There is no UI component, everything is powered programmtically and the UIs for the fieldtypes, templates and forms must be implemented by you. This is by design.
npm install mongooose-formulate
First you need to setup the template plugin:
// install the template plugin on an existing collection, or create a generic 'templates collection'
var mongoose = require('mongoose');
var formulate = require('mongoose-formulate')
var Schema = mongoose.Schema;
// the plugin only adds additional fields to your schema, so you can add
// specific custom schema fields as you wish. Name would be an obvious one
var schema = {
name: String
};
schema.plugin(formulate.templatePlugin);
var TemplateModel = mongoose.model('template', schema);
Next setup the entry plugin. This is where your form content will be stored. Because this is just a mongoose plugin you add it to any of your exisiting collections (giving your form content 'context') or create a generic entries collection for ultimate flexiblity.
var mongoose = require('mongoose');
var formulate = require('mongoose-formulate')
var Schema = mongoose.Schema;
var myExistingSchema = {
name: String,
created: Date
};
schema.plugin(formulate.entryPlugin);
var MyModel = mongoose.model('my-model', schema);
Once the two plugins are setup, you can start adding custom templates. Here is an example of a Resume template:
There is an explanation of the formGroups, fieldGroups and fields properties below.
TemplateModel.new({
name: Resume Template',
template: {
formGroups: [{
label: 'Personal Information',
description: 'Enter you personal information for your Resume',
// repeatable: 1, will default to 1 when not specified
fieldGroups: [
{
fields: [
{
label: 'First Name',
fieldtype: 'text'
},
{
label: 'Last Name',
fieldtype: 'text'
},
{
label: 'Date of Birth',
fieldtype: 'datetime'
},
{
label: 'Email',
fieldtype: text
}
]
}
]
}, {
label: 'Employment History',
description: 'Specify your 3 previous employers',
repeatable: 3,
fieldGroups: [
{
fields: [
{
label: 'Company',
fieldtype: 'text',
validation: {
required: true
}
},
{
label: 'Start Date',
fieldtype: datetime,
validation: {
required: true
}
},
{
label: 'End Date',
description: 'Leave blank if not applicable',
fieldtype: 'datetime'
},
{
label: 'Company Contact Name / Number',
fieldtype: 'text'
}
]
}
]
}]
}
})
You could then use this resuable template to generate 'entries' via your client applications, e.g. Mobile App or Web App. Your client will need to interpret these templates (this is the part you have to write yourself) so they can display some kind of form to the end user.
The entry mimicks the schema of the template, with the addition of a value property on the fields. An entry document might be created like so:
MyModel.new({
name: 'Custom entry name',
content: {
formGroups: [{
label: 'Personal Information',
description: 'Enter you personal information for your Resume',
repeatable: 1,
fieldGroups: [
{
fields: [
{
label: 'First Name',
fieldtype: 'text',
value: 'Joe'
},
{
label: 'Last Name',
fieldtype: 'text',
value: 'Bloggs'
},
{
label: 'Date of Birth',
fieldtype: 'datetime',
value: 'Fri Apr 24 1987 13:44:48 GMT+1000 (AEST)'
},
{
label: 'Email',
fieldtype: text,
value: 'info@example.com'
}
]
}
]
}, {
label: 'Employment History',
description: 'Specify your 3 previous employers',
repeatable: 3,
fieldGroups: [
{
fields: [
{
label: 'Company',
fieldtype: 'text',
validation: {
required: true
},
value: 'IBM'
},
{
label: 'Start Date',
fieldtype: datetime,
validation: {
required: true
},
value: 'Mon Jan 01 2000 00:00:00 GMT+1000 (AEST)'
},
{
label: 'End Date',
description: 'Leave blank if not applicable',
fieldtype: 'datetime',
value: 'Mon Jan 01 2005 00:00:00 GMT+1000 (AEST)'
},
{
label: 'Company Contact Name / Number',
fieldtype: 'text',
value: 'Mary Jones mary@example.com'
}
]
},
{
fields: [
{
label: 'Company',
fieldtype: 'text',
validation: {
required: true
},
value: 'Microsoft'
},
{
label: 'Start Date',
fieldtype: datetime,
validation: {
required: true
},
value: 'Mon Jan 01 2005 00:00:00 GMT+1000 (AEST)'
},
{
label: 'End Date',
description: 'Leave blank if not applicable',
fieldtype: 'datetime',
value: 'Mon Jan 01 2010 00:00:00 GMT+1000 (AEST)'
},
{
label: 'Company Contact Name / Number',
fieldtype: 'text',
value: 'Mary Jones mary@example.com'
}
]
},
{
fields: [
{
label: 'Company',
fieldtype: 'text',
validation: {
required: true
},
value: Google
},
{
label: 'Start Date',
fieldtype: datetime,
validation: {
required: true
},
value: 'Mon Jan 01 2010 00:00:00 GMT+1000 (AEST)'
},
{
label: 'End Date',
description: 'Leave blank if not applicable',
fieldtype: 'datetime'
},
{
label: 'Company Contact Name / Number',
fieldtype: 'text',
value: 'Mary Jones mary@example.com'
}
]
}
]
}]
}
})
As you can see it is a very flexible way to store data based on freeform data (e.g. data you will cannot define a schema for in advance).
There are 3 components to Formulate: Fieldtypes, Templates and Entries.
Fieldtypes are the building blocks of your templates. They are a basic from of common inputs that should be flexible enough to handle most 'form content'.
Currently Formulate has the following fieldtypes:
Each of the fields has validation (required, min, max) options which allows customisation of input you store in your entries.
Templates can be thought of as a Form Builder. Imagine templates as a way to programmatically store your content structures as you would in your CMS – Heads up: Formulate handles only the logic of structuring and storing your content. There is no UI component to this package, that part is up to you!
Entries are where the data for a submitted template is stored. Entries mimick the schema used for the template they were based on, but there is no definite relationship between the two. E.g. Once an entry is created, it holds a copy of the template it was based on, so existing templates can be safely updated without affecting historical entries.
As you can see form the example above, the schema for templates features the following properties which make up a form template:
Each is a child of the previous and helps to build a flexible form structure to handle most types of input data. The following illustrates the structure of a form:
The top level array that holds 'sections' of your forms. Imagine form group items as being independant sections of your form. E.g. if you were creating resume input, your formGroups
might be 'Personal Information', 'Work History' and 'Education'.
Field Groups are an array as well, which is important as it allows us to accept repeatable input based on a single template.
Take the resume example again, the work history section would be based on a template (Company, Start, End, Contact) that can be repeated. That is a fieldGroup
. If you don't want the group of fields to be repeated, e.g. for Personal Information you wouldn't want to repeat the input, then you just set the repeatable
property of the formGroup
to 1.
For unlimited inputs, set repeatable
to 0 and for anything else set the number you want to limit by, e.g. 4.
Fields make up your fieldGroups and represent an individual input for the form. For the resume example, the Personal Information form group would be made up of one fieldGroup
with the fields
First Name, Last Name, DoB, Address, Email etc.
Fields have a fieldtype property which is explained here
FAQs
Mongoose plugins to faciliate dynamic form based input based on custom templates
The npm package mongoose-formulate receives a total of 0 weekly downloads. As such, mongoose-formulate popularity was classified as not popular.
We found that mongoose-formulate demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.