gear-blueprint
v0.0.10
Published
Adds blueprint goodness to Gearbox.
Downloads
8
Readme
gear-blueprint
A gear for the Gearbox Dependency Injection container.
Installation
$ npm install gear-blueprint
Description
Adds blueprint goodness to Gearbox.
Introduction to blueprints
Blueprints are a way to arrange gears into a hierarchical tree structure via JSON-based definitions. The driving idea here is that an organisation can collaborate and define all their back-office software requirements via a collection of blueprints - Gearbox in-turn can then deliver all the necessary functionality.
Blueprint basics
There are a few steps to creating a blueprint...
File naming-convention
All file and directory names are to be dasherized, e.g.:
filename.json
my-filename.json
The blueprint.json
file
To get going, all that's required is a new directory to hold your blueprint files, and for that directory to contain a blueprint.json
file. Other than this you're free to organise your blueprint structure as you see fit (not at all dissimilar to an NPM package and a package.json
file).
An example /blueprint.json
file:
{
"namespace": "myCompanyName",
"name": "hr",
"version": 1,
"label": "MyCompany HR",
"author": "John Doe",
"organisation": "myCompanyName",
"description": "Blueprint for maintaining employee details at myCompanyName",
"tags": ["hr"]
}
| Attribute | Type | Description
| --------- | ---------- | -----------
| namespace
| string
| Used to group and segregate blueprints - so a vendor name or similar. Use camelCase for multiple words.
| name
| string
| The name of the blueprint - must be unique within a namespace
(use camelCase again).
| version
| number
| An integer denoting the version of the blueprint.
| label
| string
| A short-ish description of what the blueprint's about
| author
| string
| Name of the person who created the blueprint
| organisation
| string
| Organisation which developed the blueprint
| description
| string
| A short-and-punchy description of what the blueprint is about
| tags
| [string]
| An array of strings that can be used to categorise/discover the blueprint
Blueprint folder structure
Once you have a blueprint.json
file in place, you're free to arrange the content of your blueprint directory as you like. Gearbox will recursively grab all .json
files, no matter how your folder structure is arranged. As such, all files should be self-contained, and nothing should be inferred from it's place in the folder structure.
Blueprint .json
files
The meat of developing a blueprint lies in defining .json
files (there's a good tutorial for JSON here). Here's a simple example of a json file that might be seen in an HR blueprint:
{ // Each file should define a JSON object
"employees.model": { // This defines a "model" gear, with the id "employees"
".pk": { // This defines a "pk" (primary key) gear, and Gearbox will generate an id for it
"fields": [ "employeeId" ] // Because there's no "." Gearbox knows this is configuration for the nested "pk" gear
},
"employeeId.field": {
"type": "number",
".comment": "Number which uniquely identifies an employee" // Shorthand for gears with just one configurable value
},
"firstName.field": {
"type": "string",
".comment": "First name of the employee"
},
"lastName.field": {
"type": "string",
".comment": "Last name of the employee"
},
"departmentId.field": {
"type": "number",
".comment": "Number which uniquely identifies a department"
},
".comment": "Table to store employee details",
}
}
So what do we have here?
//
Comments are used above to help illustrate these notes (be mindful JSON doesn't do comments)Note each
.json
file is expected to provide an object (i.e. all content is within{
}
)The name of the name/value pairs is important.
An important rule... if the name has a
.
symbol, Gearbox will interpret that as defining a new gear. To the right of the.
is the name of the gear. Optionally, to the left, is the id you want to assign to the gear.- Defining a gear id is highly recommended, but optional (Gearbox will assign a unique id if one hasn't been provided).
- How an id is used depends on the gear involved (for example the id for the schema gear will ultimately translate into a table name)
- Gear ids should be camelCase.
These things can be nested, certain gears only make sense "under" another gear.
Given the example JSON above, the table below explains what's going on:
| Name | Description
| ---- | -----------
| employees.model
| This defines a new model
gear, with the id employees
. It's on the root of the blueprint (i.e. it's not "under" any other gear)
| .pk
| So this is defining a new pk
gear (for identifying primary keys). It's not been given an id
explicitly (i.e. there's nothing to the left of the .
symbol - so Gearbox will assign a unique id. Importantly: Note this gear is nested under the model
gear (because defining a primary key outside of a model doesn't make any sense).
| fields
| This name doesn't have a .
symbol, so Gearbox knows not to interpret it as a request for a new gear. Instead, this is config for the gear to consume as it's created. In this case, the list of fields that form the primary key are defined. Please consult each individual gear for details about the values you can provide to configure it. Note that the usual gear-specific defaults are still applied in the absence of values defined in the JSON.
|firstName.field
| Very much the same again, in that this field
gear is nested underneath a model
gear, except this time an explicit id has been provided (firstName
). Note that camelCase is used again. In this instance the field
gear will use the id to generate a column for storing an employee's first name within the employees
table.
| type
| As always, no .
character is used , so this means type
should be considered a configuration value for the gear it's defined within.
More advanced features
Config shorthand
Note the ".comment": "First name of the employee"
definition under firstName.field
in the previous example. The implication here is that a new comment
gear should be created, and the id assigned to it can be generated by Gearbox. However, the associated value is just a plain string and not an object like the rest of the gear definitions. This is a shorthand for gears that require a single configurable property to be defined. The exact-same definition, but in longhand, would equate to:
{
".comment": {
"text" : "First name of the employee"
}
}
The _seq
configuration value
By default Gearbox will order gears in the order they were defined in the JSON files. However there's this to consider, and a few other edge cases (e.g. when working with blueprint macros as explained later).
- To address the situation where Gear-order needs to be made explicit (i.e. to override the normal order Gearbox would ordinarily allocate) use the special
_seq
configuration value. - The value of
_seq
should be an integer value (assume "normal" gears are sequenced from index1
). - Gearbox will order by
_seq
when initializing a blueprint.
Blueprint Macros
You may need to define lots of models like our employees
example, and there may be some common fields required for all of them. It would be a pain to define them each time - this is where "blueprint macros" come in. The idea here is to reduce duplication by creating a block of reusable gear-definitions.
For example, this could be the contents of a file such as /macros/standard-fields.json
:
{
"standardFields.macro": {
"createdUser.field": {
"type": "text",
"_seq": 9996,
".comment": "User who created this [[thing]]"
},
"createdTimestamp.field": {
"type": "timestamp",
"_seq": 9997,
".comment": "When this [[thing]] was created"
},
"modifiedUser.field": {
"type": "text",
"_seq": 9998,
".comment": "User who last changed this [[thing]]"
},
"modifiedTimestamp.field": {
"type": "timestamp",
"_seq": 9999,
".comment": "When this [[thing]] was last changed"
}
}
}
Here we are using a pseudo-gear called macro
and the gear-content of that macro is nested in the usual way. It doesn't make sense to let Gearbox generate an id (i.e. you could never refer to it later) so in this instance we have defined a macro
gear with the id of standardfields
.
- Simple templating is also available here, note the
[[
and]]
syntax. This will be replaced later.
Wherever a macro should be "pasted" into a blueprint definition, the @
symbol should be used. Consider an abridged version of the employees
model:
{
"employees.model": {
"firstName.field": {
"type": "string",
".comment": "First name of the employee"
},
"@standardFields": { // So at this point the standardFields macro should be expanded/pasted
"thing": "employee"
}
}
}
- Note the name syntax here is a slight departure, where the string to the right of the
@
is the name of the macro to paste (or insert) at that point. - The value must be an object: the keys of which will be used as part of the templating touched on previously.
- If no templating is required, just provide an empty object
{}
.
Gearbox will expand the above to something like:
{
"employees.model": {
"firstName.field": {
"type": "string",
".comment": "First name of the employee"
},
// ------------------- Expanded standardFields macro starts here -------------------
"createdUser.field": {
"type": "text",
"_seq": 9996,
".comment": "User who created this employee" // Note the "employee" string has appeared through templating
},
"createdTimestamp.field": {
"type": "timestamp",
"_seq": 9997,
".comment": "When this employee was created"
},
"modifiedUser.field": {
"type": "text",
"_seq": 9998,
".comment": "User who last changed this employee"
},
"modifiedTimestamp.field": {
"type": "timestamp",
"_seq": 9999,
".comment": "When this employee was last changed"
}
// ------------------- Expanded standardFields macro ends here -------------------
}
}
- Note that instances of
[[thing]]
have now been replaced with the stringemployee
. - The underlying templating engine here is Nunjucks (although the default
{{...}}
syntax has been globally re-configured to be hard brackets[[...]]
as to avoid conflicts with AngularJS V1).