From 740f37aebde170525307f0f603d912e530583adc Mon Sep 17 00:00:00 2001
From: bertrand <bpinel@ippon.fr>
Date: Sun, 16 Dec 2018 12:35:01 +0100
Subject: [PATCH] Introduce constraints on attribute and foreign key in
 relation

---
 README.md                          |  40 ++++++++--
 blueprints/entity-factory/index.js |  11 ++-
 blueprints/jdl-importer/index.js   | 119 +++++++++++++++++------------
 jdl/jhipster_user.jh               |   4 +-
 package.json                       |   6 +-
 5 files changed, 118 insertions(+), 62 deletions(-)

diff --git a/README.md b/README.md
index e245833..292eea4 100644
--- a/README.md
+++ b/README.md
@@ -16,18 +16,42 @@ ember install ember-aws-ehipster
 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
-    cd test-ember-aws-ehipster
-    ember install ember-aws-ehipster
+  rules: {
+    "attribute-indentation": false,
+    "block-indentation": false
+  }
 ```
 
+### Generating simple entities
+
 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 post title:string content:string order:number visible: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`
+
+### 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
 ------------------------------------------------------------------------------
diff --git a/blueprints/entity-factory/index.js b/blueprints/entity-factory/index.js
index 220ec00..33ad98a 100644
--- a/blueprints/entity-factory/index.js
+++ b/blueprints/entity-factory/index.js
@@ -74,8 +74,10 @@ module.exports = {
     for (let name in entityOptions) {
       let type = entityOptions[name] || '';
       let foreignModel = name;
+      let foreignKey = 'id';
       if (type.indexOf(':') > -1) {
         foreignModel = type.split(':')[1];
+        foreignKey = type.split(':')[2];
         type = type.split(':')[0];
       }
       let dasherizedName = stringUtils.dasherize(name);
@@ -98,12 +100,17 @@ module.exports = {
         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 + "'");
+        // Populate form with belongs-to relationship --> multi selector
+
       }
       if (!/has-many/.test(dasherizedType) && !/belongs-to/.test(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";
         if (type === 'boolean') {
           buttonType = "checkbox";
diff --git a/blueprints/jdl-importer/index.js b/blueprints/jdl-importer/index.js
index 2b33c6d..969b020 100644
--- a/blueprints/jdl-importer/index.js
+++ b/blueprints/jdl-importer/index.js
@@ -1,6 +1,6 @@
 /* eslint-env node */
 
-const jhipster = require('jhipster-core'); 
+const jhipster = require('jhipster-core');
 const inflection = require('inflection');
 const shelljs = require('shelljs');
 
@@ -19,106 +19,131 @@ module.exports = {
   },
 
   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
 
     // Parse provided JDL file
-    var files= this.fileName.split(this.SEPARATOR);
+    var files = this.fileName.split(this.SEPARATOR);
     var jdlModel = jhipster.parseFromFiles(files);
     //this.ui.writeLine(JSON.stringify(jdlModel));
 
     let entities = jdlModel.entities;
     let relationships = jdlModel.relationships;
 
-    for (var i=0; i<entities.length;i++) {
+    for (var i = 0; i < entities.length; i++) {
       let entity = entities[i];
       // Add an array field to further hold options to pass to entity-factory blueprint
       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 propertyType;
         switch (property.type) {
           case 'String':
           case 'TextBlob':
-            entity.options.push(property.name+':string');
+            propertyType = ':string';
             break;
 
           case 'LocalDate':
           case 'Instant':
-            entity.options.push(property.name+':date');
+            propertyType = ':date';
             break;
 
           case 'Integer':
           case 'Float':
           case 'Double':
-            entity.options.push(property.name+':number');
+            propertyType = ':number';
             break;
 
           case 'Boolean':
-            entity.options.push(property.name+':number');
+            propertyType = ':number';
             break;
 
           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;
         }
+        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
       // First see the 'from' relationships
       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) {
           case "one-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;
 
           case "one-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;
 
           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;
         }
-       });
-       // Do the same for to relationships
-       relationships.filter(relation => relation.to.name == entity.name).forEach(relation => {
-       let toObjectName = relation.from.name.toLowerCase();
-          switch (relation.cardinality) {
-            case "one-to-one":
-            case "one-to-many":
-              entity.options.push(toObjectName+':has-many:'+toObjectName);
-              break;
-  
-            case "many-to-one":  
-            case "many-to-many":
-              entity.options.push(inflection.pluralize(toObjectName)+':has-many:'+toObjectName);
-              break;
-  
-            default:
-              this.ui.writeLine("Huston, we have a problem with unknow relationship type "+relation.cardinality);
-              break;
-          }
-        });
-        let cmd = 'ember g entity-factory ' + entity.name.toLowerCase() + ' ' + entity.options.join(" ");
-        if (options.dummy) {
-          cmd += ' --dummy';
+      });
+      // Do the same for to relationships
+      relationships.filter(relation => relation.to.name == entity.name).forEach(relation => {
+        let toObjectName = relation.from.name.toLowerCase();
+        switch (relation.cardinality) {
+          case "one-to-one":
+          case "one-to-many":
+            entity.options.push(toObjectName + ':has-many:' + toObjectName);
+            break;
+
+          case "many-to-one":
+          case "many-to-many":
+            entity.options.push(inflection.pluralize(toObjectName) + ':has-many:' + toObjectName);
+            break;
+
+          default:
+            this.ui.writeLine("Huston, we have a problem with unknow relationship type " + relation.cardinality);
+            break;
         }
-        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) {
-    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
diff --git a/jdl/jhipster_user.jh b/jdl/jhipster_user.jh
index 9dbced5..60eb3ca 100644
--- a/jdl/jhipster_user.jh
+++ b/jdl/jhipster_user.jh
@@ -10,9 +10,9 @@ entity User {
  activationKey String,
  resetKey String,
  createdBy String,
- createdDate Date,
+ createdDate Instant,
  lastModifiedBy String
- lastModifiedDate String
+ lastModifiedDate Instant
 }
 
 entity Authority {
diff --git a/package.json b/package.json
index 82988c2..6a83c49 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,9 @@
 {
   "name": "ember-aws-ehipster",
-  "version": "0.2.18",
-  "description": "The default blueprint for ember-cli addons.",
+  "version": "0.2.21",
+  "description": "Attempt to build a complete web application using serverless architecture on AWS",
   "keywords": [
-    "ember-addon"
+    "ember-addon", "aws", "jhipster", "generator", "serverless"
   ],
   "repository": "",
   "license": "MIT",
-- 
GitLab