Commit 740f37ae authored by Bertrand PINEL's avatar Bertrand PINEL
Browse files

Introduce constraints on attribute and foreign key in relation

parent 93cdfa80
...@@ -16,18 +16,42 @@ ember install ember-aws-ehipster ...@@ -16,18 +16,42 @@ ember install ember-aws-ehipster
Usage Usage
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
For generating a application, first use the standard command : ### Generating the application
For generating an application, first use the standard command :
* `ember new test-ember-aws-ehipster --no-welcome`
* `cd test-ember-aws-ehipster`
* `ember install ember-aws-ehipster`
To avoid some error message sent by lint about the templates, you can just add in the file .template-lintrc.js the following rules :
``` ```
ember new test-ember-aws-ehipster --no-welcome rules: {
cd test-ember-aws-ehipster "attribute-indentation": false,
ember install ember-aws-ehipster "block-indentation": false
}
``` ```
### Generating simple entities
Then generate a few entity through provided blueprints using the same syntax as the model blueprint : Then generate a few entity through provided blueprints using the same syntax as the model blueprint :
```
ember g entity-factory blog title:string content:string order:number isVisible:boolean * `ember g entity-factory blog title:string content:string order:number isVisible:boolean`
ember g entity-factory post title:string content:string order:number visible:boolean * `ember g entity-factory post title:string content:string order:number visible:boolean`
```
### Generating a complete model
You can also use the JDL-Studio (https://start.jhipster.tech/jdl-studio/) provided by JHipster to design your entities and their relationships. After downloading the JDL file simply type the command:
* `ember g jdl-importer <jdl-file>`
### Using a JSON API server on AWS for backend
Just read the README file in the cloud/terraform directory to set up the right infrastructure on AWS.
Then got to the API Gateway interface to retrieve the URL for your staging environnement.
You should need to start ember in proxy mode to take benefit of this backend storing data in DynamoDB
* `ember s --proxy <url staging>`
Contributing Contributing
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
......
...@@ -74,8 +74,10 @@ module.exports = { ...@@ -74,8 +74,10 @@ module.exports = {
for (let name in entityOptions) { for (let name in entityOptions) {
let type = entityOptions[name] || ''; let type = entityOptions[name] || '';
let foreignModel = name; let foreignModel = name;
let foreignKey = 'id';
if (type.indexOf(':') > -1) { if (type.indexOf(':') > -1) {
foreignModel = type.split(':')[1]; foreignModel = type.split(':')[1];
foreignKey = type.split(':')[2];
type = type.split(':')[0]; type = type.split(':')[0];
} }
let dasherizedName = stringUtils.dasherize(name); let dasherizedName = stringUtils.dasherize(name);
...@@ -98,12 +100,17 @@ module.exports = { ...@@ -98,12 +100,17 @@ module.exports = {
tableCols.push("EmberObject.create({\n\tpropertyName: \""+camelizedName+"\",\n\ttitle: \""+name+"\"\n}),"); tableCols.push("EmberObject.create({\n\tpropertyName: \""+camelizedName+"\",\n\ttitle: \""+name+"\"\n}),");
} }
if (/has-many|belongs-to/.test(dasherizedType)) { if (/has-many/.test(dasherizedType)) {
needs.push("'model:" + dasherizedForeignModelSingular + "'");
// Populate form with hasMany relationship --> single choice selector
} else if (/belongs-to/.test(dasherizedType)) {
needs.push("'model:" + dasherizedForeignModelSingular + "'"); needs.push("'model:" + dasherizedForeignModelSingular + "'");
// Populate form with belongs-to relationship --> multi selector
} }
if (!/has-many/.test(dasherizedType) && !/belongs-to/.test(dasherizedType)) { if (!/has-many/.test(dasherizedType) && !/belongs-to/.test(dasherizedType)) {
factories.push('\n\t' + camelizedName + fakerize(dasherizedType)); factories.push('\n\t' + camelizedName + fakerize(dasherizedType));
// todo Generate input form for creating entity (without any relationship) // Populate form with simple attribute
let buttonType = "text"; let buttonType = "text";
if (type === 'boolean') { if (type === 'boolean') {
buttonType = "checkbox"; buttonType = "checkbox";
......
/* eslint-env node */ /* eslint-env node */
const jhipster = require('jhipster-core'); const jhipster = require('jhipster-core');
const inflection = require('inflection'); const inflection = require('inflection');
const shelljs = require('shelljs'); const shelljs = require('shelljs');
...@@ -19,106 +19,131 @@ module.exports = { ...@@ -19,106 +19,131 @@ module.exports = {
}, },
beforeInstall(options) { beforeInstall(options) {
this.ui.writeLine("afterInstall processing for jdlimporter module with file "+this.fileName); this.ui.writeLine("afterInstall processing for jdlimporter module with file " + this.fileName);
// TODO Check options contains a link on a JDL file // TODO Check options contains a link on a JDL file
// Parse provided JDL file // Parse provided JDL file
var files= this.fileName.split(this.SEPARATOR); var files = this.fileName.split(this.SEPARATOR);
var jdlModel = jhipster.parseFromFiles(files); var jdlModel = jhipster.parseFromFiles(files);
//this.ui.writeLine(JSON.stringify(jdlModel)); //this.ui.writeLine(JSON.stringify(jdlModel));
let entities = jdlModel.entities; let entities = jdlModel.entities;
let relationships = jdlModel.relationships; let relationships = jdlModel.relationships;
for (var i=0; i<entities.length;i++) { for (var i = 0; i < entities.length; i++) {
let entity = entities[i]; let entity = entities[i];
// Add an array field to further hold options to pass to entity-factory blueprint // Add an array field to further hold options to pass to entity-factory blueprint
entity.options = []; entity.options = [];
for (var j=0; j<entity.body.length;j++) { for (var j = 0; j < entity.body.length; j++) {
let property = entity.body[j]; let property = entity.body[j];
let propertyType;
switch (property.type) { switch (property.type) {
case 'String': case 'String':
case 'TextBlob': case 'TextBlob':
entity.options.push(property.name+':string'); propertyType = ':string';
break; break;
case 'LocalDate': case 'LocalDate':
case 'Instant': case 'Instant':
entity.options.push(property.name+':date'); propertyType = ':date';
break; break;
case 'Integer': case 'Integer':
case 'Float': case 'Float':
case 'Double': case 'Double':
entity.options.push(property.name+':number'); propertyType = ':number';
break; break;
case 'Boolean': case 'Boolean':
entity.options.push(property.name+':number'); propertyType = ':number';
break; break;
default: default:
this.ui.writeLine("Huston, we have a problem with unknow type "+property.name); this.ui.writeLine("Huston, we have a problem with unknow type " + property.name);
break; break;
} }
let validations = property.validations;
let validationRules = [];
for (var k = 0; k < validations.length; k++) {
validation = validations[k];
let validationRule = validation.key;
if (validation.value) {
validationRule +='§' + validation.value;
}
validationRules.push(validationRule)
}
let validationString='';
if (validationRules.length>0) {
validationString = ":"+validationRules.join(',');
}
entity.options.push(property.name + propertyType + validationString);
} }
// Check if current object is involved in a relationship // Check if current object is involved in a relationship
// First see the 'from' relationships // First see the 'from' relationships
relationships.filter(relation => relation.from.name == entity.name).forEach(relation => { relationships.filter(relation => relation.from.name == entity.name).forEach(relation => {
let toObjectName = relation.to.name.toLowerCase(); let toObjectName = relation.to.name.toLowerCase();
// Process injectedField to better handle the relationship
let injectedField = relation.from.injectedField;
let field = null;
if (injectedField != null && injectedField.indexOf('(') != -1) {
field = injectedField.substring(injectedField.indexOf('(')+1, injectedField.indexOf(')'));
}
switch (relation.cardinality) { switch (relation.cardinality) {
case "one-to-one": case "one-to-one":
case "many-to-one": case "many-to-one":
entity.options.push(toObjectName+':belongs-to:'+toObjectName); if (field)
entity.options.push(toObjectName + ':belongs-to:' + toObjectName + ':'+field);
else
entity.options.push(toObjectName + ':belongs-to:' + toObjectName);
break; break;
case "one-to-many": case "one-to-many":
case "many-to-many": case "many-to-many":
entity.options.push(inflection.pluralize(toObjectName)+':has-many:'+toObjectName); if (field)
entity.options.push(inflection.pluralize(toObjectName) + ':has-many:' + toObjectName + ':'+field);
else
entity.options.push(inflection.pluralize(toObjectName) + ':has-many:' + toObjectName);
break; break;
default: default:
this.ui.writeLine("Huston, we have a problem with unknow relationship type "+relation.cardinality); this.ui.writeLine("Huston, we have a problem with unknow relationship type " + relation.cardinality);
break; break;
} }
}); });
// Do the same for to relationships // Do the same for to relationships
relationships.filter(relation => relation.to.name == entity.name).forEach(relation => { relationships.filter(relation => relation.to.name == entity.name).forEach(relation => {
let toObjectName = relation.from.name.toLowerCase(); let toObjectName = relation.from.name.toLowerCase();
switch (relation.cardinality) { switch (relation.cardinality) {
case "one-to-one": case "one-to-one":
case "one-to-many": case "one-to-many":
entity.options.push(toObjectName+':has-many:'+toObjectName); entity.options.push(toObjectName + ':has-many:' + toObjectName);
break; break;
case "many-to-one": case "many-to-one":
case "many-to-many": case "many-to-many":
entity.options.push(inflection.pluralize(toObjectName)+':has-many:'+toObjectName); entity.options.push(inflection.pluralize(toObjectName) + ':has-many:' + toObjectName);
break; break;
default: default:
this.ui.writeLine("Huston, we have a problem with unknow relationship type "+relation.cardinality); this.ui.writeLine("Huston, we have a problem with unknow relationship type " + relation.cardinality);
break; break;
}
});
let cmd = 'ember g entity-factory ' + entity.name.toLowerCase() + ' ' + entity.options.join(" ");
if (options.dummy) {
cmd += ' --dummy';
} }
console.log(cmd); });
shelljs.exec(cmd); let cmd = 'ember g entity-factory ' + entity.name.toLowerCase() + ' ' + entity.options.join(" ");
if (options.dummy) {
cmd += ' --dummy';
}
console.log(cmd);
shelljs.exec(cmd);
} }
}, },
locals: function(options) { locals: function (options) {},
},
afterInstall(options) { afterInstall(options) {
this.ui.writeLine("Real stuff begins here !"); // Check ENV value to add AWS stuff
// Check ENV value to add AWS stuff
// Perform extra work here. // Perform extra work here.
} }
}; };
\ No newline at end of file
...@@ -10,9 +10,9 @@ entity User { ...@@ -10,9 +10,9 @@ entity User {
activationKey String, activationKey String,
resetKey String, resetKey String,
createdBy String, createdBy String,
createdDate Date, createdDate Instant,
lastModifiedBy String lastModifiedBy String
lastModifiedDate String lastModifiedDate Instant
} }
entity Authority { entity Authority {
......
{ {
"name": "ember-aws-ehipster", "name": "ember-aws-ehipster",
"version": "0.2.18", "version": "0.2.21",
"description": "The default blueprint for ember-cli addons.", "description": "Attempt to build a complete web application using serverless architecture on AWS",
"keywords": [ "keywords": [
"ember-addon" "ember-addon", "aws", "jhipster", "generator", "serverless"
], ],
"repository": "", "repository": "",
"license": "MIT", "license": "MIT",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment