Noncommital Premarital Mischief

    gear-blueprint

    0.0.10 • Public • Published

    gear-blueprint

    Build Status

    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 index 1).
    • 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 string employee.
    • 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).

    License

    MIT

    Install

    npm i gear-blueprint

    DownloadsWeekly Downloads

    10

    Version

    0.0.10

    License

    MIT

    Last publish

    Collaborators

    • timneedham