JavaScript
This document provides code examples to help you play with JavaScript templates.
Prerequisites
Before reading this article, we recommend that you read the documentation about JavaScript templates.
Creating indexes for MongoDB
This template will produce a JSON containing all the indexes that must be created in MongoDB based on the field attributes. It creates an index for searchable, sortable fields or references. It also creates a unique index for unique fields and a text index for searchable string fields.
/** Generate indexes for a model */
function _model(out, model) {
const modelName = model.names.snake;
const strings = { fields: {} };
const uniques = {
fields: {},
options: { unique: true }
};
// Even if no fields have indexes, Include this collection
// Get fields objects
out[modelName] = model.fields.list.reduce((p, field) => {
// Non primary fields
if (field.primary) {
return p;
}
// Only if the field is searchable, sortable a reference or is unique
if (!(field.sortable || field.searchable || field.type === 'entity' || field.unique)) {
return p;
}
const fieldName = field.names.snake;
// Special text index for strings
if (field.type === 'string' && field.searchable) {
strings.fields[fieldName] = 'text';
}
// Normal indexes
p[`${modelName}_${fieldName}`] = { fields: { [fieldName]: 1 } };
if (field.unique) {
p[`${modelName}_${fieldName}`].options = { unique: true };
uniques.fields[fieldName] = 1;
}
return p;
}, {});
// Add labels
if (Object.keys(strings.fields).length > 0) {
out[modelName][`${modelName}__text`] = strings;
}
// Optimize unique indexes
if (Object.keys(uniques.fields).length > 1) {
// Remove unique from other indexes
model.fields.unique.map(field => {
const fieldName = field.names.snake;
if (out[modelName][`${modelName}_${fieldName}`]) {
delete out[modelName][`${modelName}_${fieldName}`].options;
}
});
// Add unique
out[modelName][`${modelName}__uniques`] = uniques;
}
return out;
}
const _output = models.reduce(_model, {});
return JSON.stringify(_output, null, 2);
{
"service": {
"service_created_at": {
"fields": {
"created_at": 1
}
},
"service_name": {
"fields": {
"name": 1
},
"options": {
"unique": true
}
},
"service__text": {
"fields": {
"name": "text"
}
}
},
"user": {
"user_created_at": {
"fields": {
"created_at": 1
}
},
"user_name": {
"fields": {
"name": 1
}
},
"user_email": {
"fields": {
"email": 1
},
"options": {
"unique": true
}
},
"user_role": {
"fields": {
"role": 1
}
},
"user_banned": {
"fields": {
"banned": 1
}
},
"user__text": {
"fields": {
"name": "text",
"email": "text",
"role": "text"
}
}
}
}
Generate a JSON description of the data model
This template will produce a JSON that lists the fields and resolves the dependencies between the models.
const _output = models.map((m) => {
return {
collection: m.names.snake,
dependencies: m.dependencies.list.map((d) => {
return d.names.snake
}),
fields: m.fields.list.map((f) => {
const out = {
name: f.names.snake,
notes: f.notes,
type: f.type,
subtype: f.subtype,
properties: []
};
// Convert boolean properties to list
for (const prop of Object.keys(f)) {
if (typeof f[prop] === 'boolean' && f[prop]) {
out.properties.push(prop)
}
}
// Append model reference if any
if (f.model) {
out.reference = f.model.names.snake;
}
return out;
})
};
});
return JSON.stringify(_output, null, 4);
[
{
"collection": "bookmark",
"dependencies": [
"user",
"place"
],
"fields": [
{
"name": "_id",
"notes": null,
"type": "string",
"subtype": null,
"properties": [
"primary",
"internal"
]
},
{
"name": "created_at",
"notes": null,
"type": "datetime",
"subtype": null,
"properties": [
"sortable",
"internal"
]
},
{
"name": "owner",
"notes": "Current user when creating the bookmark",
"type": "entity",
"subtype": null,
"properties": [
"unique",
"searchable",
"internal",
"ownership"
],
"reference": "user"
},
{
"name": "place",
"notes": null,
"type": "entity",
"subtype": null,
"properties": [
"unique",
"searchable"
],
"reference": "place"
}
]
}
]