UNPKG

autocode

Version:

spec-driven code generator

330 lines (296 loc) 8.23 kB
# # process.coffee # processes crystal spec # # @author Chris Tate <chris@autocode.run> # @copyright 2015 Autocode # @license MIT # # load deps crystal = { format: require './format' } changecase = require 'change-case' cson = require 'season' debug = require('debug')('build') fs = require 'fs' merge = require 'merge' mkdirp = require 'mkdirp' mustache = require 'mustache' pluralize = require 'pluralize' # valid detail types detail_types = [ 'bool' 'child' 'created' 'date' 'deleted' 'decimal' 'email' 'id' 'model' 'number' 'parent' 'password' 'select' 'string' 'text' 'time' 'updated' ] access_exists = (role, arr) -> for obj in arr if obj.role.id == role return true false process = (config, spec) -> # get config config = config or this.config if !config then throw new Error '"config" required for process(config, spec)' # get spec spec = spec or this.spec if !spec then throw new Error '"spec" required for process(config, spec)' # create gen object gen = {} # process models spec = merge.recursive spec, config.spec or {} if spec.models gen.model = {} gen.models = [] for model_name of spec.models model = processModel model_name, spec gen.model[model_name] = model gen.models.push model # display processed spec in console #console.log JSON.stringify gen, null, "\t" gen processModel = (model_name, spec) -> # get model model = spec.models[model_name] # pluralize model name if !model.plural model.plural = pluralize model_name model_gen = { access: {} has: {} id: model_name name: crystal.format model_name, model.plural } model_gen.model = model_gen if model.details model_gen.detail = {} model_gen.details = [] for detail_name of model.details detail = model.details[detail_name] if !detail.plural detail.plural = pluralize detail_name detail_gen = { access: {} default: detail.default id: detail_name name: crystal.format detail_name, detail.plural } detail_gen.detail = detail_gen detail_gen.model = model_gen if model.access for role of model.access if Object.prototype.toString.call model.access[role].permissions == '[object Object]' role_data = { role: { access: { create: false read: false update: false delete: false } name: crystal.format role } } for access of model.access[role].permissions if model.access[role].permissions[access] == '*' or model.access[role].permissions[access].indexOf(detail_name) != -1 if !detail_gen.access[access] detail_gen.access[access] = { roles: [] } if !model_gen.access[access] model_gen.access[access] = { roles: [] } if !access_exists role, detail_gen.access[access].roles detail_gen.access[access].roles.push { role: { id: role name: crystal.format(role) } } if !access_exists role, model_gen.access[access].roles model_gen.access[access].roles.push { role: { id: role, name: crystal.format(role) } } else if model.access[role].permissions == '*' or model.access[role].permissions.indexOf(detail_name) != -1 if !detail_gen.access.create detail_gen.access.create = { roles: [] } detail_gen.access.create.detail = detail_gen detail_gen.access.create.model = model_gen if !detail_gen.access.read detail_gen.access.read = { roles: [] } detail_gen.access.read.detail = detail_gen detail_gen.access.read.model = model_gen if !detail_gen.access.update detail_gen.access.update = { roles: [] } detail_gen.access.update.detail = detail_gen detail_gen.access.update.model = model_gen if !detail_gen.access.delete detail_gen.access.delete = { roles: [] } detail_gen.access.delete.detail = detail_gen detail_gen.access.delete.model = model_gen if !access_exists role, detail_gen.access.create.roles detail_gen.access.create.roles.push { role: { id: role name: crystal.format role } } if !access_exists role, detail_gen.access.read.roles detail_gen.access.read.roles.push { role: { id: role name: crystal.format role } } if !access_exists role, detail_gen.access.update.roles detail_gen.access.update.roles.push { role: { id: role name: crystal.format role } } if !access_exists role, detail_gen.access.delete.roles detail_gen.access.delete.roles.push { role: { id: role name: crystal.format role } } if !model_gen.access.create model_gen.access.create = { roles: [] } if !model_gen.access.read model_gen.access.read = { roles: [] } if !model_gen.access.update model_gen.access.update = { roles: [] } if !model_gen.access.delete model_gen.access.delete = { roles: [] } if !access_exists role, model_gen.access.create.roles model_gen.access.create.roles.push { role: { id: role name: crystal.format role } } if !access_exists role, model_gen.access.read.roles model_gen.access.read.roles.push { role: { id: role name: crystal.format role } } if !access_exists role, model_gen.access.update.roles model_gen.access.update.roles.push { role: { id: role name: crystal.format role } } if !access_exists role, model_gen.access.delete.roles model_gen.access.delete.roles.push { role: { id: role name: crystal.format role } } if !detail_gen.access.create and !detail_gen.access.read and !detail_gen.access.update and !detail_gen.access.delete delete detail_gen.access if detail.detail detail_gen.association = {} detail_gen.association.detail = { name: crystal.format detail.detail } if detail.model if !detail_gen.association detail_gen.association = {} detail_gen.association.model = { name: crystal.format detail.model } if detail.multiple != undefined if detail.multiple == true detail_gen.multiple = true else if detail.multiple == false detail_gen.multiple = false else debug 'Invalid value for "multiple": %s', detail.multiple if detail.options detail_options = [] for i of detail.options detail_options.push { option: detail.options[i] } detail_gen.options = detail_options if detail.required != undefined if detail.required == true detail_gen.required = true else if detail.required == false detail_gen.required = false else debug 'Invalid value for "required": %s', detail.required if detail.type if detail_types.indexOf(detail.type) == -1 console.log "Unknown type (#{detail.type}) for detail (#{detail_name})" else detail_gen.is = {} detail_gen.is[detail.type] = true detail_gen.type = detail.type model_gen.has[detail.type] = true if detail.unique != undefined if detail.unique == true detail_gen.unique = { is: { bool: true } value: true } else if detail.unique == false detail_gen.unique = { is: { bool: true } value: false } else detail_gen.unique = { is: { model: true } model: { name: crystal.format detail.unique }, value: detail.unique } model_gen.detail[detail_name] = detail_gen model_gen.details.push detail_gen if !model_gen.access.create and !model_gen.access.read and !model_gen.access.update and !model_gen.access.delete delete model_gen.access model_gen module.exports = process