coffee-json-dsl
A tiny framework to define DSL to generate JSON from coffee-script
Overview
It's very annoying to write a valid JSON document, but many tools require configuration files in JSON format. You know you can generate JSON from JavaScript object literals like shown below.
var config = key: 'value' console;
It displays a valid JSON string like:
"key": "value"
coffee-json-dsl is a tiny framework to define DSL to generate JSON format string. You can write JSON document using coffee-script DSL.
Install
npm install coffee-json-dsl
Usage
- require and create a new instance of coffee-json-dsl
- declare plugins to use
- add or load parts of document
- generate JSON string and write it to a file
coffee-json-dsl merges all added or loaded parts into one JSON string.
The node.js code shown below generate AWS CloudFormation template JSON file.
const fs = ;const CoffeeJsonDsl = ;var coffeeJsonDsl = ; // setup pluginscoffeeJsonDsl; // you can load a part of document from a filecoffeeJsonDsl; // and also you can add inline document partcoffeeJsonDsl; // generate JSON format string and write it to a file.fs;
Plugins
Actually use() specifies plugins to use. It accepts npm module name prefixed by 'coffee-json-dsl-' and its options object, or an object literal. Plugin module is a function that takes options object as the argument and return an object literal to define DOCUMENT, DSL and HOOK properties.
DOCUMENT declares the top level properties of generated JSON. You have to use at least one plugin to declare DOCUMENT. In each part of document, you can only modify the properties declared in DOCUMENT. You cannot introduce any new propertiy which is not declared in any plugins.
DSL defines commands available as function properties of $ object in each part of document. HOOK defines some events to hook: 'init', 'beforeEach', 'afterEach' and 'finish'. 'init' and 'finish' takes a whole document object as the argument. 'beforeEach' and 'afterEach' takes a current part of document object as the argument.
DSL and HOOK functions share a same 'this' context. So you can write, for example, a command to generate a set of elements.
const Resources = Symbol; module { return DOCUMENT: Parameters: {} Resources: {} DSL: // add AWS::Lambda::Function and its AWS::IAM::Role resources at a time { let resources = thisResources; resources`Function`= Type: 'AWS::Lambda::Function' Properties: FunctionName: name Runtime: 'nodejs4.3' Code: S3Bucket: optionsbucket || this S3Key: `/.zip` Handler: 'index.handler' Runtime: 'nodejs4.3' Timeout: optionsTimeout || 10 Role: this FunctionName: this ; resources`Role`= Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version : '2012-10-17' 'Statement': Effect: 'Allow' Principal: Service: 'lambda.amazonaws.com' Action: 'sts:AssumeRole' Path: '/' Policies: PolicyDocument: Version: '2012-10-17' Statement: Resource: '*' Action: 'logs:CreateLogGroup' 'logs:CreateLogStream' 'logs:PutLogEvents' Effect: 'Allow' PolicyName: this ; } HOOK: { thisResources = partResources; } ;};
It is recommended using Symbol as a property identifier to avoid conflicts with other plugins. This plugin generates AWS::Lambda::Function and its AWS::IAM::Role in a command like:
input coffee template
Parameters.Environtment= Type: 'String' Description: 'environment name' Default: 'dev' Parameters.LambdaBucket= Type: 'String' Description: 'the name of bucket to store lambda function packages' Default: 'my-lambda-function-bucket' $lambda'Count' PolicyStatements: Resource: '*' Action: 's3:*' Effect: 'Allow' Timeout: 30;
generated JSON
Currently, I am working on AWS CloudFormation which requires a huge JSON document. I am developing a plugin to write CloudFormation template(coffee-json-dsl-cfn)