'use strict'; //////////////////////////////////////////////////////////////////////////////// /// @brief Foxx template engine /// /// @file /// /// DISCLAIMER /// /// Copyright 2013-2015 triagens GmbH, Cologne, Germany /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// /// Copyright holder is triAGENS GmbH, Cologne, Germany /// /// @author Lucas Dohmen /// @author Michael Hackstein /// @author Alan Plum /// @author Copyright 2013-2015, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// var _ = require('lodash'); var fs = require('fs'); var internal = require('internal'); var i = require('i')(); var templatePath = fs.join( internal.startupPath, 'server', 'modules', '@arangodb', 'foxx', 'templates' ); function Engine(opts) { this._path = templatePath; this.folder = opts.path; this.name = opts.name; this.authenticated = opts.authenticated; this.author = opts.author; this.description = opts.description; this.license = opts.license; this.determineFromCollectionNames(opts.collectionNames); } _.extend(Engine.prototype, { write: function() { fs.makeDirectory(this.folder); fs.makeDirectory(fs.join(this.folder, 'controllers')); fs.makeDirectory(fs.join(this.folder, 'models')); fs.makeDirectory(fs.join(this.folder, 'repositories')); fs.makeDirectory(fs.join(this.folder, 'scripts')); fs.makeDirectory(fs.join(this.folder, 'test')); fs.write(fs.join(this.folder, 'manifest.json'), this.buildManifest()); _.each(this.repositories, function (repository) { fs.write(fs.join(this.folder, repository.path), this.buildRepository()); }, this); _.each(this.models, function (model) { fs.write(fs.join(this.folder, model.path), this.buildModel()); }, this); _.each(this.controllers, function (controller) { fs.write(fs.join(this.folder, controller.path), this.buildController(controller)); }, this); fs.write(fs.join(this.folder, 'scripts', 'setup.js'), this.buildSetup(this.collectionNames)); fs.write(fs.join(this.folder, 'scripts', 'teardown.js'), this.buildTeardown(this.collectionNames)); fs.write(fs.join(this.folder, 'test', 'example.js'), this.buildTest()); }, template: function(name) { return _.template(fs.read(fs.join(this._path, name))); }, determineFromCollectionNames: function (collectionNames) { this.collectionNames = []; this.controllers = []; this.repositories = []; this.models = []; _.each(collectionNames, function (collectionName) { var modelBase = i.singularize(collectionName).substr(1), collectionStart, repositoryBase = collectionName.substr(1), repositoryName, repositoryPath, repositoryInstance, modelPath, modelName, modelInstance; collectionStart = collectionName.charAt(0); if (collectionStart.match(/[a-z]/i) === null) { throw new Error('Collection name has to start with a letter'); } if (modelBase === repositoryBase) { repositoryBase += 'Repo'; } modelName = collectionStart.toUpperCase() + modelBase; modelInstance = collectionStart.toLowerCase() + modelBase; repositoryName = collectionStart.toUpperCase() + repositoryBase; repositoryInstance = collectionStart.toLowerCase() + repositoryBase; repositoryPath = 'repositories/' + collectionName; modelPath = 'models/' + modelName.toLowerCase(); this.collectionNames.push(collectionName); this.controllers.push({ url: '/' + collectionName, path: 'controllers/' + collectionName + '.js', repositoryInstance: repositoryInstance, repository: repositoryName, repositoryPath: repositoryPath, modelInstance: modelInstance, model: modelName, modelPath: modelPath, basePath: collectionName, collectionName: collectionName }); this.repositories.push({ path: repositoryPath + '.js' }); this.models.push({ path: modelPath + '.js' }); }, this); }, buildManifest: function() { var manifest = { name: this.name, version: '0.0.1', description: this.description, engines: { arangodb: '^2.8.0' }, author: this.author, license: this.license, controllers: {}, scripts: { setup: 'scripts/setup.js', teardown: 'scripts/teardown.js' }, tests: 'test/**/*.js' }; _.each(this.controllers, function (controller) { manifest.controllers[controller.url] = controller.path; }); return JSON.stringify(manifest, 0, 2); }, buildSetup: function(collections) { var templ = this.template('setup.js.tmpl'); return templ({ collections: collections }); }, buildTeardown: function(collections) { var templ = this.template('teardown.js.tmpl'); return templ({ collections: collections }); }, buildController: function(controller) { var templ = this.template('controller.js.tmpl'); return templ(controller); }, buildRepository: function() { var templ = this.template('repository.js.tmpl'); return templ(); }, buildModel: function() { var templ = this.template('model.js.tmpl'); return templ(); }, buildTest: function () { var templ = this.template('test.js.tmpl'); return templ(); } }); exports.Engine = Engine;