Skip to content

Commit

Permalink
feat(generators/api): add a subgenerator for creating API instances
Browse files Browse the repository at this point in the history
  • Loading branch information
cueedee committed Nov 14, 2016
1 parent 5ca66f2 commit a04056c
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 0 deletions.
179 changes: 179 additions & 0 deletions generators/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
'use strict';

//
// Yeoman bat:api sub-generator.
//

var generators = require( 'yeoman-generator' )
, yosay = require( 'yosay' )
, youtil = require( './../../lib/youtil.js' )
, chalk = require( 'chalk' )
, _ = require( 'lodash' )
;

var decapitalize = require( 'underscore.string/decapitalize' );

var ApiGenerator = generators.Base.extend(
{
constructor: function ()
{
generators.Base.apply( this, arguments );

this.description = this._description( 'API-instance' );

this.argument(
'apiName'
, {
type: String
, required: false
, desc: 'The name of the API-instance to create.'
}
);

// Also add 'apiName' as a - hidden - option, defaulting to the positional argument's value.
// This way `_promptsPruneByOptions()` can filter away prompting for the API name too.
//
this.option(
'apiName'
, {
type: String
, desc: 'The name of the API-instance to create.'
, default: this.apiName
, hide: true
}
);

// Normal options.
//
this.option(
'description'
, {
type: String
, desc: 'The purpose of this API.'
}
);

this.option(
'url'
, {
type: String
, desc: 'The base URL for this API.'
}
);

}

, initializing: function ()
{
this._assertBatApp();

// Container for template expansion data.
//
this.templateData = {};
}

, prompting:
{
askSomeQuestions: function ()
{
// Ask only those question that have not yet been provided with answers via the command line.
//
var prompts = this._promptsPruneByOptions(
[
{
type: 'input'
, name: 'apiName'
, message: 'What is the name of this API-instance you so desire?'
, default: youtil.definedToString( this.options.apiName )
, validate: youtil.isIdentifier
, filter: function ( value )
{
return decapitalize( _.trim( value ).replace( /api$/i, '' ));
}
}
, {
type: 'input'
, name: 'description'
, message: 'What is the purpose (description) of this API?'
, default: function ( answers )
{
return (
youtil.definedToString( this.options.description )
|| (
'A collection of services\' endpoints available on the '
+ ( answers.apiName || this.templateData.apiName )
+ ' API.'
)
);
}.bind( this )
, validate: youtil.isNonBlank
, filter: youtil.sentencify
}
, {
type: 'input'
, name: 'url'
, message: 'What is the base URL for this API? ' + chalk.gray( ' - please enter as code:' )
, default: youtil.definedToString( this.options.url )
, validate: youtil.isCoffeeScript
}
]
)
;

if ( prompts.length )
{
// Have Yeoman greet the user.
//
this.log( yosay( 'So you want a BAT API-instance?' ) );

return (
this
.prompt( prompts )
.then( function ( answers ) { _.extend( this.templateData, answers ); }.bind( this ) )
);
}
}
}

, configuring: function ()
{
var data = this.templateData
, apiName = data.apiName
;

_.extend(
data
, {
className: _.capitalize( apiName ) + 'Api'
, fileBase: _.kebabCase( _.deburr( apiName ))

, userName: this.user.git.name()

}
);
}

, writing:
{
createApi: function ()
{
var data = this.templateData
, templates =
{
'api.coffee': [ 'src/apis/' + data.fileBase + '.coffee' ]
}
;

this._templatesProcess( templates );
}
}
}
);

_.extend(
ApiGenerator.prototype
, require( './../../lib/generator.js' )
, require( './../../lib/sub-generator.js' )
);

module.exports = ApiGenerator;
54 changes: 54 additions & 0 deletions generators/api/templates/api.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
( ( factory ) ->
if typeof exports is 'object'
module.exports = factory(

require( './../collections/api-services.coffee' )
)
else if typeof define is 'function' and define.amd
define( [

'./../collections/api-services.coffee'
], factory )
return
)((

ApiServicesCollection
) ->

###*
# @author <%- userName %>
# @module App
# @submodule Apis
###

'use strict'


###*<% if ( description ) { %>
# <%- description %>
#<% } %>
# @class <%- className %>
# @static
###

new ApiServicesCollection(

[
]

,
###*
# The `<%- className %>`'s base url.
#
# @property url
# @type String
# @final
#
# @default <%- url %>
###

url: <%- url %>

)

)
14 changes: 14 additions & 0 deletions lib/youtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ module.exports =
return (( value == null ) ? value : '' + value );
}

, isCoffeeScript: function ( value )
{
try
{
require( 'coffee-script' ).compile( value );
}
catch ( e )
{
return false;
}

return true;
}

, isIdentifier: function ( value )
{
return /^[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*$/.test(( '' + value ).trim() );
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
},
"dependencies": {
"chalk": "^1.1.3",
"coffee-script": "^1.11.0",
"language-tags": "^1.0.5",
"lodash": "^4.14.1",
"mkdirp": "^0.5.1",
Expand Down

0 comments on commit a04056c

Please sign in to comment.