diff --git a/.travis.yml b/.travis.yml index 46a65f4df..b048dd2f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,7 @@ env: - JHI_LIB_BRANCH=release # if JHI_GEN_BRANCH value is release, use the release from NPM - JHI_GEN_REPO=https://github.com/jhipster/generator-jhipster.git - - JHI_GEN_BRANCH=v6.2.0 + - JHI_GEN_BRANCH=v6.3.1 # specific config - SPRING_OUTPUT_ANSI_ENABLED=ALWAYS - SPRING_JPA_SHOW_SQL=false diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5fdd72b00..e6588d206 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -31,7 +31,7 @@ jobs: JHI_LIB_BRANCH: release # if JHI_GEN_BRANCH value is release, use the release from NPM JHI_GEN_REPO: https://github.com/jhipster/generator-jhipster.git - JHI_GEN_BRANCH: v6.2.0 + JHI_GEN_BRANCH: v6.3.1 # specific config SPRING_OUTPUT_ANSI_ENABLED: NEVER SPRING_JPA_SHOW_SQL: false @@ -87,7 +87,7 @@ jobs: JHI_APP: ngx-h2mem-ws-nol2 JHI_ENTITY: sql webflux-mongodb: - JHI_APP: webflux-mongodb + JHI_APP: kotlin-webflux-mongo JHI_ENTITY: mongodb ms-micro-eureka-uaa: JHI_APP: ms-micro-eureka-uaa diff --git a/generators/entity-server/files.js b/generators/entity-server/files.js index 6ade8c4e0..1168e21e0 100644 --- a/generators/entity-server/files.js +++ b/generators/entity-server/files.js @@ -225,7 +225,7 @@ function writeFiles() { const serverCacheKt = new NeedleServerChacheKt(this); - if (['ehcache', 'infinispan'].includes(this.cacheProvider) && this.enableHibernateCache) { + if (['ehcache', 'caffeine', 'infinispan'].includes(this.cacheProvider) && this.enableHibernateCache) { serverCacheKt.addEntityToCache( this.asEntity(this.entityClass), this.relationships, diff --git a/generators/entity-server/templates/src/main/kotlin/package/common/save_template.ejs b/generators/entity-server/templates/src/main/kotlin/package/common/save_template.ejs index 5dee32cc9..42f8ca525 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/common/save_template.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/common/save_template.ejs @@ -42,7 +42,7 @@ if (!viaService) { resultEntity = asEntity(entityInstance) %> var <%= asEntity(entityInstance) %> = <%= dtoToEntity %>(<%= instanceName %>) <%_ if (isUsingMapsId === true) { _%> - val <%= otherEntityName %>Id = <%= instanceName %>.<%= mapsIdAssoc.relationshipName%>Id + val <%= otherEntityName %>Id = <%= instanceName %>.<%= mapsIdAssoc.relationshipName %>Id if (<%= otherEntityName %>Id != null) { <%= mapsIdRepoInstance %>.findById(<%= otherEntityName %>Id) .ifPresent { <%= asEntity(entityInstance) %>.<%= otherEntityName %> = it } diff --git a/generators/entity-server/templates/src/main/kotlin/package/domain/Entity.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/domain/Entity.kt.ejs index a385fae33..96d824e34 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/domain/Entity.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/domain/Entity.kt.ejs @@ -23,6 +23,7 @@ let importJsonIgnoreProperties = false; let importSet = false; let hasDto = dto === 'mapstruct'; let isUsingMapsId = false; +let primaryKeyType = pkType; let hasTextBlob = false; let hasRelationship = relationships.length !== 0; let fieldsContainEnum = false; @@ -48,6 +49,7 @@ const uniqueEnums = {}; %><%- include imports -%> for (idx in relationships) { isUsingMapsId = relationships[idx].useJPADerivedIdentifier; if ( isUsingMapsId === true) { + primaryKeyType = (relationships[idx].otherEntityName === 'user' && authenticationType === 'oauth2') ? 'String' : pkType; break; } isUsingMapsId = false; @@ -216,7 +218,7 @@ class <%= asEntity(entityClass) %>( <%_ if (searchEngine === 'elasticsearch') { _%> @org.springframework.data.elasticsearch.annotations.Field(type = FieldType.Keyword) <%_ } _%> - var id: <%= pkType %>? = null, + var id: <%= primaryKeyType %>? = null, <%_ for (var idx in fields) { diff --git a/generators/entity-server/templates/src/main/kotlin/package/repository/EntityRepository.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/repository/EntityRepository.kt.ejs index dd7754e54..cce11c1de 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/repository/EntityRepository.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/repository/EntityRepository.kt.ejs @@ -16,8 +16,9 @@ See the License for the specific language governing permissions and limitations under the License. -%> -package <%=packageName%>.repository - +package <%=packageName%>.repository<% +const primaryKeyType = getPkTypeBasedOnDBAndAssociation(authenticationType, databaseType, relationships); +%> import <%=packageName%>.domain.<%= asEntity(entityClass) %> <%_ if (fieldsContainOwnerManyToMany) { _%> import org.springframework.data.domain.Page @@ -59,7 +60,7 @@ import java.util.UUID @Suppress("unused") <%_ } _%> @Repository -interface <%=entityClass%>Repository : <% if (databaseType === 'sql') { %>JpaRepository<% } %><% if (databaseType === 'mongodb') { %>MongoRepository<% } %><% if (databaseType === 'cassandra') { %>CassandraRepository<% } %><% if (databaseType === 'couchbase') { %>N1qlCouchbaseRepository<% } %><<%=asEntity(entityClass)%>, <%= pkType %>><% if (jpaMetamodelFiltering) { %>, JpaSpecificationExecutor<<%= asEntity(entityClass) %>><% } %> { +interface <%=entityClass%>Repository : <% if (databaseType === 'sql') { %>JpaRepository<% } %><% if (databaseType === 'mongodb') { %>MongoRepository<% } %><% if (databaseType === 'cassandra') { %>CassandraRepository<% } %><% if (databaseType === 'couchbase') { %>N1qlCouchbaseRepository<% } %><<%=asEntity(entityClass)%>, <%= primaryKeyType %>><% if (jpaMetamodelFiltering) { %>, JpaSpecificationExecutor<<%= asEntity(entityClass) %>><% } %> { <%_ for (idx in relationships) { if (relationships[idx].relationshipType === 'many-to-one' && relationships[idx].otherEntityName === 'user' && databaseType === 'sql') { _%> @@ -82,7 +83,7 @@ interface <%=entityClass%>Repository : <% if (databaseType === 'sql') { %>JpaRep @Query("select <%= entityInstance %> from <%= asEntity(entityClass) %> <%= entityInstance %><% for (idx in relationships) { if (relationships[idx].relationshipType === 'many-to-many' && relationships[idx].ownerSide === true) { %> left join fetch <%=entityInstance%>.<%=relationships[idx].relationshipFieldNamePlural%><%} }%> where <%=entityInstance%>.id =:id") - fun findOneWithEagerRelationships(@Param("id") id: <%= pkType %>): Optional<<%= asEntity(entityClass) %>> + fun findOneWithEagerRelationships(@Param("id") id: <%= primaryKeyType %>): Optional<<%= asEntity(entityClass) %>> <%_ } else if (databaseType === 'mongodb') { _%> @@ -93,7 +94,7 @@ interface <%=entityClass%>Repository : <% if (databaseType === 'sql') { %>JpaRep fun findAllWithEagerRelationships(): MutableList<<%= asEntity(entityClass) %>> @Query("{'id': ?0}") - fun findOneWithEagerRelationships(id: <%= pkType %>): Optional<<%= asEntity(entityClass) %>> + fun findOneWithEagerRelationships(id: <%= primaryKeyType %>): Optional<<%= asEntity(entityClass) %>> <%_ } } _%> } diff --git a/generators/entity-server/templates/src/main/kotlin/package/repository/reactive/EntityReactiveRepository.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/repository/reactive/EntityReactiveRepository.kt.ejs index 5579d8ec7..7d8dcd1c0 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/repository/reactive/EntityReactiveRepository.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/repository/reactive/EntityReactiveRepository.kt.ejs @@ -16,8 +16,9 @@ See the License for the specific language governing permissions and limitations under the License. -%> -package <%= packageName %>.repository.reactive - +package <%= packageName %>.repository.reactive<% +const primaryKeyType = getPkTypeBasedOnDBAndAssociation(authenticationType, databaseType, relationships); +%> import <%= packageName %>.domain.<%= asEntity(entityClass) %> <%_ if (databaseType === 'cassandra') { _%> import org.springframework.data.cassandra.repository.ReactiveCassandraRepository @@ -43,7 +44,7 @@ import java.util.UUID */ @Suppress("unused") @Repository -interface <%= entityClass %>ReactiveRepository: Reactive<% if (databaseType === 'mongodb') { %>Mongo<% } if (databaseType === 'couchbase') { %>CouchbaseSorting<% } if (databaseType === 'cassandra') { %>Cassandra<% } %>Repository<<%= asEntity(entityClass) %>, <%= pkType %>> { +interface <%= entityClass %>ReactiveRepository: Reactive<% if (databaseType === 'mongodb') { %>Mongo<% } if (databaseType === 'couchbase') { %>CouchbaseSorting<% } if (databaseType === 'cassandra') { %>Cassandra<% } %>Repository<<%= asEntity(entityClass) %>, <%= primaryKeyType %>> { <%_ if (databaseType === 'couchbase') { _%> @Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter}") diff --git a/generators/entity-server/templates/src/main/kotlin/package/repository/search/EntitySearchRepository.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/repository/search/EntitySearchRepository.kt.ejs index 75f0f6d97..1108ba2c4 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/repository/search/EntitySearchRepository.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/repository/search/EntitySearchRepository.kt.ejs @@ -16,7 +16,9 @@ See the License for the specific language governing permissions and limitations under the License. -%> -package <%=packageName%>.repository.search +package <%=packageName%>.repository.search<% +const primaryKeyType = getPkTypeBasedOnDBAndAssociation(authenticationType, databaseType, relationships); +%> import <%=packageName%>.domain.<%= asEntity(entityClass) %> import org.springframework.data.elasticsearch.repository.ElasticsearchRepository<% if (databaseType === 'cassandra') { %> @@ -26,4 +28,4 @@ import java.util.UUID<% } %> /** * Spring Data Elasticsearch repository for the [<%= asEntity(entityClass) %>] entity. */ -interface <%=entityClass%>SearchRepository : ElasticsearchRepository<<%= asEntity(entityClass) %>, <% if (databaseType === 'sql') { %>Long<% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>String<% } %><% if (databaseType === 'cassandra') { %>UUID<% } %>> +interface <%=entityClass%>SearchRepository : ElasticsearchRepository<<%= asEntity(entityClass) %>, <% if (databaseType === 'sql') { %><%=primaryKeyType%><% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>String<% } %><% if (databaseType === 'cassandra') { %>UUID<% } %>> diff --git a/generators/entity-server/templates/src/main/kotlin/package/service/EntityQueryService.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/service/EntityQueryService.kt.ejs index 01ce44d05..cc48489b2 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/service/EntityQueryService.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/service/EntityQueryService.kt.ejs @@ -125,7 +125,7 @@ class <%= serviceClassName %>( } /** - * Function to convert ConsumerCriteria to a [Specification]. + * Function to convert [<%= criteria %>] to a [Specification]. * @param criteria The object which holds all the filters, which the entities should match. * @return the matching [Specification] of the entity. */ diff --git a/generators/entity-server/templates/src/main/kotlin/package/service/EntityService.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/service/EntityService.kt.ejs index f1026e9b8..6470abd1a 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/service/EntityService.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/service/EntityService.kt.ejs @@ -16,7 +16,9 @@ See the License for the specific language governing permissions and limitations under the License. -%> -package <%=packageName%>.service +package <%=packageName%>.service<% +const primaryKeyType = getPkTypeBasedOnDBAndAssociation(authenticationType, databaseType, relationships); +%> <% const instanceType = (dto === 'mapstruct') ? asDto(entityClass) : asEntity(entityClass); const instanceName = (dto === 'mapstruct') ? asDto(entityInstance) : asEntity(entityInstance); %> <%_ if (dto === 'mapstruct') { _%> @@ -90,14 +92,14 @@ interface <%= entityClass %>Service { * @param id the id of the entity. * @return the entity. */ - fun findOne(id: <%= pkType %>): Optional<<%= instanceType %>> + fun findOne(id: <%= primaryKeyType %>): Optional<<%= instanceType %>> /** * Delete the "id" <%= entityInstance %>. * * @param id the id of the entity. */ - fun delete(id: <%= pkType %>)<% if (searchEngine === 'elasticsearch') { %> + fun delete(id: <%= primaryKeyType %>)<% if (searchEngine === 'elasticsearch') { %> /** * Search for the <%= entityInstance %> corresponding to the query. diff --git a/generators/entity-server/templates/src/main/kotlin/package/service/dto/EntityCriteria.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/service/dto/EntityCriteria.kt.ejs index 6c58fa391..3528ff608 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/service/dto/EntityCriteria.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/service/dto/EntityCriteria.kt.ejs @@ -50,8 +50,9 @@ import io.github.jhipster.service.filter.ZonedDateTimeFilter <%_ } _%> <%_ - const referenceFilterType = '' + pkType + 'Filter'; - var filterVariables = [{name:'id', type: pkType, filterType:referenceFilterType,fieldInJavaBeanMethod:'Id' } ]; + const primaryKeyType = getPkTypeBasedOnDBAndAssociation(authenticationType, databaseType, relationships); + const referenceFilterType = '' + primaryKeyType + 'Filter'; + var filterVariables = [{name:'id', type: primaryKeyType, filterType:referenceFilterType,fieldInJavaBeanMethod:'Id' } ]; var extraFilters = {}; fields.forEach((field) => { const fieldType = field.fieldType; diff --git a/generators/entity-server/templates/src/main/kotlin/package/service/dto/EntityDTO.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/service/dto/EntityDTO.kt.ejs index 187456565..d98003b70 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/service/dto/EntityDTO.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/service/dto/EntityDTO.kt.ejs @@ -21,6 +21,7 @@ let importApiModelProperty = false; let importJsonIgnore = false; let importJsonIgnoreProperties = false; let importSet = false; +const primaryKeyType = getPkTypeBasedOnDBAndAssociation(authenticationType, databaseType, relationships); const uniqueEnums = {}; %><%- include ../../domain/imports -%> @@ -63,9 +64,9 @@ import java.util.UUID <%_ if (fieldsContainBlob && databaseType === 'sql') { _%> import javax.persistence.Lob <%_ } _%> -<%_ for (idx in fields) { if (fields[idx].fieldIsEnum) { _%> -import <%=packageName%>.domain.enumeration.<%= fields[idx].fieldType %> -<%_ } } _%> +<%_ Object.keys(uniqueEnums).forEach(function(element) { _%> + import <%=packageName%>.domain.enumeration.<%= element %> +<%_ }); _%> <%_ var mappedRels = []; relationships.forEach((relationship) => { @@ -85,7 +86,7 @@ _%> <%_ } _%> data class <%= asDto(entityClass) %>( - var id: <%= pkType %>? = null, + var id: <%= primaryKeyType %>? = null, <%_ for (idx in fields) { if (typeof fields[idx].javadoc !== 'undefined') { _%> <%- formatAsFieldJavadoc(fields[idx].javadoc) %> @@ -147,7 +148,7 @@ data class <%= asDto(entityClass) %>( } _%> - var <%= relationshipFieldName %>Id: <% if (relationshipFieldName === 'user' && authenticationType === 'oauth2') { %>String<% } else { %><%= pkType %><% } %>? = null<%= comma %> + var <%= relationshipFieldName %>Id: <% if (relationshipFieldName === 'user' && authenticationType === 'oauth2') { %>String<% } else { %><%= primaryKeyType %><% } %>? = null<%= comma %> <%_ if (otherEntityFieldCapitalized !== 'Id' && otherEntityFieldCapitalized !== '') { comma = index === (mappedRels.length - 1) ? '' : ','; _%> diff --git a/generators/entity-server/templates/src/main/kotlin/package/service/impl/EntityServiceImpl.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/service/impl/EntityServiceImpl.kt.ejs index 12e7679fe..d158cb57d 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/service/impl/EntityServiceImpl.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/service/impl/EntityServiceImpl.kt.ejs @@ -28,11 +28,13 @@ package <%= packageName %>.service<% if (service === 'serviceImpl') { %>.impl<% const repository = entityInstance + 'Repository'; const searchRepository = entityInstance + 'SearchRepository'; let isUsingMapsId = false; + let primaryKeyType = pkType; let mapsIdAssoc; for (idx in relationships) { isUsingMapsId = relationships[idx].useJPADerivedIdentifier; if ( isUsingMapsId === true) { mapsIdAssoc = relationships[idx]; + primaryKeyType = (relationships[idx].otherEntityName === 'user' && authenticationType === 'oauth2') ? 'String' : pkType; break; } isUsingMapsId = false; @@ -151,7 +153,7 @@ class <%= serviceClassName %>( <%_ if (databaseType === 'sql') { _%> @Transactional(readOnly = true) <%_ } _%> - <% if (service === 'serviceImpl') { %>override <% } %>fun findOne(id: <%= pkType %>): Optional<<%= instanceType %>> { + <% if (service === 'serviceImpl') { %>override <% } %>fun findOne(id: <%= primaryKeyType %>): Optional<<%= instanceType %>> { log.debug("Request to get <%= entityClass %> : {}", id)<%- include('../../common/get_template', {asEntity, asDto, viaService, returnDirectly:true}); -%> } @@ -160,7 +162,7 @@ class <%= serviceClassName %>( * * @param id the id of the entity. */ - <% if (service === 'serviceImpl') { %>override <% } %>fun delete(id: <%= pkType %>) { + <% if (service === 'serviceImpl') { %>override <% } %>fun delete(id: <%= primaryKeyType %>) { log.debug("Request to delete <%= entityClass %> : {}", id) <%- include('../../common/delete_template', {viaService: viaService}); -%> } diff --git a/generators/entity-server/templates/src/main/kotlin/package/service/mapper/EntityMapper.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/service/mapper/EntityMapper.kt.ejs index ece2c9490..63e4f3997 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/service/mapper/EntityMapper.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/service/mapper/EntityMapper.kt.ejs @@ -73,9 +73,13 @@ _%> <%_ // DTO -> entity mapping var mappedRelsDto = []; +let primaryKeyType = pkType; for (idx in relationships) { const relationshipType = relationships[idx].relationshipType; + const otherEntityName = relationships[idx].otherEntityName; const ownerSide = relationships[idx].ownerSide; + const isUsingMapsId = relationships[idx].useJPADerivedIdentifier; + primaryKeyType = (isUsingMapsId === true && otherEntityName === 'user' && authenticationType === 'oauth2') ? 'String' : primaryKeyType; if (relationshipType === 'many-to-one' || (relationshipType === 'one-to-one' && ownerSide === true) || (relationshipType === 'many-to-many' && ownerSide === false) || relationshipType === 'one-to-many' || @@ -119,6 +123,6 @@ _%> <%_ } _%> <%_ if (databaseType === 'sql' || databaseType === 'mongodb') { _%> - fun fromId(id: <%= pkType %>?) = id?.let { <%= asEntity(entityClass) %>(it) } + fun fromId(id: <%= primaryKeyType %>?) = id?.let { <%= asEntity(entityClass) %>(it) } <%_ } _%> } diff --git a/generators/entity-server/templates/src/main/kotlin/package/web/rest/EntityResource.kt.ejs b/generators/entity-server/templates/src/main/kotlin/package/web/rest/EntityResource.kt.ejs index 62416411f..a7e52ed14 100644 --- a/generators/entity-server/templates/src/main/kotlin/package/web/rest/EntityResource.kt.ejs +++ b/generators/entity-server/templates/src/main/kotlin/package/web/rest/EntityResource.kt.ejs @@ -21,10 +21,12 @@ package <%=packageName%>.web.rest <%_ const viaService = service !== 'no'; let isUsingMapsId = false; let mapsIdAssoc; + let primaryKeyType = pkType; for (idx in relationships) { isUsingMapsId = relationships[idx].useJPADerivedIdentifier; if ( isUsingMapsId === true) { mapsIdAssoc = relationships[idx]; + primaryKeyType = (relationships[idx].otherEntityName === 'user' && authenticationType === 'oauth2') ? 'String' : pkType; break; } isUsingMapsId = false; @@ -247,7 +249,7 @@ _%><%- include('../../common/inject_template', {viaService: viaService, construc <%_ if (databaseType === 'sql' && isUsingMapsId === true && !viaService) { _%> @Transactional(readOnly = true) <%_ } _%> - fun get<%= entityClass %>(@PathVariable id: <%= pkType %>): ResponseEntity<<%= instanceType %>> { + fun get<%= entityClass %>(@PathVariable id: <%= primaryKeyType %>): ResponseEntity<<%= instanceType %>> { log.debug("REST request to get <%= entityClass %> : {}", id)<%- include('../../common/get_template', {asEntity, asDto, viaService, returnDirectly:false}); -%> return ResponseUtil.wrapOrNotFound(<%= instanceName %>) } @@ -259,7 +261,7 @@ _%><%- include('../../common/inject_template', {viaService: viaService, construc * @return the [ResponseEntity] with status `204 (NO_CONTENT)`. */ @DeleteMapping("/<%= entityApiUrl %>/{id}") - fun delete<%= entityClass %>(@PathVariable id: <%= pkType %>): ResponseEntity { + fun delete<%= entityClass %>(@PathVariable id: <%= primaryKeyType %>): ResponseEntity { log.debug("REST request to delete <%= entityClass %> : {}", id) <%- include('../../common/delete_template', {viaService: viaService}); -%> return ResponseEntity.noContent() diff --git a/generators/entity-server/templates/src/test/kotlin/package/web/rest/EntityResourceIT.kt.ejs b/generators/entity-server/templates/src/test/kotlin/package/web/rest/EntityResourceIT.kt.ejs index 747833fe7..f64bd5e23 100644 --- a/generators/entity-server/templates/src/test/kotlin/package/web/rest/EntityResourceIT.kt.ejs +++ b/generators/entity-server/templates/src/test/kotlin/package/web/rest/EntityResourceIT.kt.ejs @@ -23,6 +23,7 @@ package <%=packageName%>.web.rest let mapsIdEntity; let mapsIdEntityInstance; let mapsIdRepoInstance; + let hasOauthUser = false; for (idx in relationships) { isUsingMapsId = relationships[idx].useJPADerivedIdentifier; if ( isUsingMapsId === true) { @@ -30,6 +31,7 @@ package <%=packageName%>.web.rest mapsIdEntity = mapsIdAssoc.otherEntityNameCapitalized; mapsIdEntityInstance = mapsIdEntity.charAt(0).toLowerCase() + mapsIdEntity.slice(1); mapsIdRepoInstance = `${mapsIdEntityInstance}Repository`; + hasOauthUser = relationships[idx].otherEntityName === 'user' && authenticationType === 'oauth2'; break; } } @@ -126,7 +128,7 @@ import java.time.ZonedDateTime import java.time.ZoneOffset<% } %><% if (fieldsContainLocalDate === true || fieldsContainZonedDateTime === true) { %> import java.time.ZoneId<% } %><% if (fieldsContainInstant === true) { %> import java.time.temporal.ChronoUnit<% } %> -<%_ if (databaseType === 'cassandra' || fieldsContainUUID === true) { _%> +<%_ if (databaseType === 'cassandra' || fieldsContainUUID === true || (databaseType === 'sql' && hasOauthUser === true)) { _%> import java.util.UUID <%_ } _%> @@ -320,7 +322,7 @@ class <%= entityClass %>ResourceIT <% if (databaseType === 'cassandra') { %>: Ab val databaseSizeBeforeCreate = <%= entityInstance %>Repository.findAll().size // Create the <%= entityClass %> with an existing ID - <%= asEntity(entityInstance) %>.id = <% if (databaseType === 'sql') { %>1L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"existing_id"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> + <%= asEntity(entityInstance) %>.id = <% if (databaseType === 'sql' && hasOauthUser === true) { %>UUID.randomUUID().toString()<% } else if (databaseType === 'sql') { %>1L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"existing_id"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> <%_ if (dto === 'mapstruct') { _%> val <%= asDto(entityInstance) %> = <%= entityInstance %>Mapper.toDto(<%= asEntity(entityInstance) %>) <%_ } _%> @@ -442,7 +444,8 @@ class <%= entityClass %>ResourceIT <% if (databaseType === 'cassandra') { %>: Ab // Get all the <%= entityInstance %>List rest<%= entityClass %>MockMvc.perform(get("/api/<%= entityApiUrl %><% if (databaseType !== 'cassandra') { %>?sort=id,desc<% } %>")) .andExpect(status().isOk) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))<% if (databaseType === 'sql') { %> + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))<% if (databaseType === 'sql' && hasOauthUser === true) { %> + .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %>.id)))<% } else if (databaseType === 'sql') { %> .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %>.id?.toInt())))<% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { %> .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %>.id)))<% } %><% if (databaseType === 'cassandra') { %> .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %>.id?.toString())))<% } %><% for (idx in fields) {%> @@ -519,7 +522,8 @@ class <%= entityClass %>ResourceIT <% if (databaseType === 'cassandra') { %>: Ab // Get the <%= entityInstance %> rest<%= entityClass %>MockMvc.perform(get("/api/<%= entityApiUrl %>/{id}", id)) .andExpect(status().isOk) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))<% if (databaseType === 'sql') { %> + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))<% if (databaseType === 'sql' && hasOauthUser === true) { %> + .andExpect(jsonPath("$.id").value(<%= asEntity(entityInstance) %>.id))<% } else if (databaseType === 'sql') { %> .andExpect(jsonPath("$.id").value(id.toInt()))<% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { %> .andExpect(jsonPath("$.id").value(id))<% } %><% if (databaseType === 'cassandra') { %> .andExpect(jsonPath("$.id").value(id.toString()))<% } %><% for (idx in fields) {%> @@ -687,7 +691,7 @@ class <%= entityClass %>ResourceIT <% if (databaseType === 'cassandra') { %>: Ab rest<%= entityClass %>MockMvc.perform(get("/api/<%= entityApiUrl %>?sort=id,desc&$filter")) .andExpect(status().isOk) .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) - .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %>.id?.toInt())))<% fields.forEach((field) => { %> + .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %><% if (databaseType === 'sql' && hasOauthUser === true) { %>.id?<% } else { %>.id?.toInt()<% } %>)))<% fields.forEach((field) => { %> <%_ if ((field.fieldType === 'byte[]' || field.fieldType === 'ByteBuffer') && field.fieldTypeBlobContent !== 'text') { _%> .andExpect(jsonPath("$.[*].<%=field.fieldName%>ContentType").value(hasItem(<%='DEFAULT_' + field.fieldNameUnderscored.toUpperCase()%>_CONTENT_TYPE))) <%_ } _%> @@ -914,7 +918,8 @@ class <%= entityClass %>ResourceIT <% if (databaseType === 'cassandra') { %>: Ab // Search the <%= entityInstance %> rest<%= entityClass %>MockMvc.perform(get("/api/_search/<%= entityApiUrl %>?query=id:" + <%= asEntity(entityInstance) %>.id)) .andExpect(status().isOk) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))<% if (databaseType === 'sql') { %> + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))<% if (databaseType === 'sql' && hasOauthUser === true) { %> + .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %>.getId())))<% } else if (databaseType === 'sql') { %> .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %>.id?.toInt())))<% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { %> .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %>.id)))<% } %><% if (databaseType === 'cassandra') { %> .andExpect(jsonPath("$.[*].id").value(hasItem(<%= asEntity(entityInstance) %>.id.toString())))<% } %><% for (idx in fields) {%> @@ -930,11 +935,11 @@ class <%= entityClass %>ResourceIT <% if (databaseType === 'cassandra') { %>: Ab fun equalsVerifier() { equalsVerifier(<%= asEntity(entityClass) %>::class) val <%= asEntity(entityInstance) %>1 = <%= asEntity(entityClass) %>() - <%= asEntity(entityInstance) %>1.id = <% if (databaseType === 'sql') { %>1L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"id1"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> + <%= asEntity(entityInstance) %>1.id = <% if (databaseType === 'sql' && hasOauthUser === true) { %>UUID.randomUUID().toString()<% } else if (databaseType === 'sql') { %>1L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"id1"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> val <%= asEntity(entityInstance) %>2 = <%= asEntity(entityClass) %>() <%= asEntity(entityInstance) %>2.id = <%= asEntity(entityInstance) %>1.id assertThat(<%= asEntity(entityInstance) %>1).isEqualTo(<%= asEntity(entityInstance) %>2) - <%= asEntity(entityInstance) %>2.id = <% if (databaseType === 'sql') { %>2L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"id2"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> + <%= asEntity(entityInstance) %>2.id = <% if (databaseType === 'sql' && hasOauthUser === true) { %>UUID.randomUUID().toString()<% } else if (databaseType === 'sql') { %>2L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"id2"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> assertThat(<%= asEntity(entityInstance) %>1).isNotEqualTo(<%= asEntity(entityInstance) %>2) <%= asEntity(entityInstance) %>1.id = null assertThat(<%= asEntity(entityInstance) %>1).isNotEqualTo(<%= asEntity(entityInstance) %>2) @@ -946,23 +951,28 @@ class <%= entityClass %>ResourceIT <% if (databaseType === 'cassandra') { %>: Ab fun dtoEqualsVerifier() { equalsVerifier(<%= asDto(entityClass) %>::class) val <%= asDto(entityInstance) %>1 = <%= asDto(entityClass) %>() - <%= asDto(entityInstance) %>1.id = <% if (databaseType === 'sql') { %>1L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"id1"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> + <%= asDto(entityInstance) %>1.id = <% if (databaseType === 'sql' && hasOauthUser === true) { %>UUID.randomUUID().toString()<% } else if (databaseType === 'sql') { %>1L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"id1"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> val <%= asDto(entityInstance) %>2 = <%= asDto(entityClass) %>() assertThat(<%= asDto(entityInstance) %>1).isNotEqualTo(<%= asDto(entityInstance) %>2) <%= asDto(entityInstance) %>2.id = <%= asDto(entityInstance) %>1.id assertThat(<%= asDto(entityInstance) %>1).isEqualTo(<%= asDto(entityInstance) %>2) - <%= asDto(entityInstance) %>2.id = <% if (databaseType === 'sql') { %>2L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"id2"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> + <%= asDto(entityInstance) %>2.id = <% if (databaseType === 'sql' && hasOauthUser === true) { %>UUID.randomUUID().toString()<% } else if (databaseType === 'sql') { %>2L<% } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>"id2"<% } else if (databaseType === 'cassandra') { %>UUID.randomUUID()<% } %> assertThat(<%= asDto(entityInstance) %>1).isNotEqualTo(<%= asDto(entityInstance) %>2) <%= asDto(entityInstance) %>1.id = null assertThat(<%= asDto(entityInstance) %>1).isNotEqualTo(<%= asDto(entityInstance) %>2) } <%_ if (databaseType === 'sql') { _%> - @Test - @Transactional + @Test<% if (databaseType === 'sql') { %> + @Transactional<% } %> fun testEntityFromId() { + <%_ if (databaseType === 'sql' && hasOauthUser === true) { _%> + assertThat(<%= entityInstance %>Mapper.fromId("42L")?.id).isEqualTo("42L"); + assertThat(<%= entityInstance %>Mapper.fromId(null)).isNull(); + <%_ } else if (databaseType === 'sql') { _%> assertThat(<%= entityInstance %>Mapper.fromId(42L)?.id).isEqualTo(42) assertThat(<%= entityInstance %>Mapper.fromId(null)).isNull() + <%_ } _%> } <%_ } _%> <%_ } _%> diff --git a/generators/server/files.js b/generators/server/files.js index 9ce372e1c..c3e3b2134 100644 --- a/generators/server/files.js +++ b/generators/server/files.js @@ -178,7 +178,8 @@ const serverFiles = { serverJavaAuthConfig: [ { condition: generator => - generator.databaseType === 'sql' || generator.databaseType === 'mongodb' || generator.databaseType === 'couchbase', + !generator.reactive && + (generator.databaseType === 'sql' || generator.databaseType === 'mongodb' || generator.databaseType === 'couchbase'), path: SERVER_MAIN_KOTLIN_SRC_DIR, templates: [ { @@ -617,7 +618,8 @@ const serverFiles = { ] }, { - condition: generator => generator.authenticationType === 'oauth2' && generator.applicationType === 'gateway', + condition: generator => + generator.authenticationType === 'oauth2' && generator.applicationType === 'gateway' && generator.serviceDiscoveryType, path: SERVER_MAIN_KOTLIN_SRC_DIR, templates: [ { @@ -706,6 +708,16 @@ const serverFiles = { useBluePrint: true } ] + }, + { + path: SERVER_TEST_SRC_KOTLIN_DIR, + templates: [ + { + file: 'package/ArchTest.kt', + renameTo: generator => `${generator.testDir}ArchTest.kt`, + useBluePrint: true + } + ] } ], serverJavaConfig: [ @@ -794,7 +806,7 @@ const serverFiles = { }, { condition: generator => - ['ehcache', 'hazelcast', 'infinispan', 'memcached'].includes(generator.cacheProvider) || + ['ehcache', 'caffeine', 'hazelcast', 'infinispan', 'memcached'].includes(generator.cacheProvider) || generator.applicationType === 'gateway', path: SERVER_MAIN_KOTLIN_SRC_DIR, templates: [ @@ -957,6 +969,29 @@ const serverFiles = { } ], serverJavaPackageInfo: [], + serverJavaServiceError: [ + { + condition: generator => !generator.skipUserManagement, + path: SERVER_MAIN_KOTLIN_SRC_DIR, + templates: [ + { + file: 'package/service/EmailAlreadyUsedException.kt', + renameTo: generator => `${generator.javaDir}service/EmailAlreadyUsedException.kt`, + useBluePrint: true + }, + { + file: 'package/service/InvalidPasswordException.kt', + renameTo: generator => `${generator.javaDir}service/InvalidPasswordException.kt`, + useBluePrint: true + }, + { + file: 'package/service/UsernameAlreadyUsedException.kt', + renameTo: generator => `${generator.javaDir}service/UsernameAlreadyUsedException.kt`, + useBluePrint: true + } + ] + } + ], serverJavaService: [ { condition: generator => !generator.skipUserManagement, @@ -1491,11 +1526,6 @@ const serverFiles = { condition: generator => generator.authenticationType === 'oauth2' && ['sql', 'mongodb'].includes(generator.databaseType), path: SERVER_MAIN_KOTLIN_SRC_DIR, templates: [ - { - file: 'package/repository/CustomAuditEventRepository.kt', - renameTo: generator => `${generator.javaDir}repository/CustomAuditEventRepository.kt`, - useBluePrint: true - }, { file: 'package/repository/AuthorityRepository.kt', renameTo: generator => `${generator.javaDir}repository/AuthorityRepository.kt`, @@ -1503,7 +1533,8 @@ const serverFiles = { }, { file: 'package/repository/PersistenceAuditEventRepository.kt', - renameTo: generator => `${generator.javaDir}repository/PersistenceAuditEventRepository.kt`, + renameTo: generator => + `${generator.javaDir}repository/${generator.reactiveRepository}PersistenceAuditEventRepository.kt`, useBluePrint: true }, { @@ -1519,14 +1550,33 @@ const serverFiles = { ] }, { - condition: generator => generator.authenticationType === 'oauth2' && ['sql', 'mongodb'].includes(generator.databaseType), + condition: generator => + !generator.reactive && generator.authenticationType === 'oauth2' && ['sql', 'mongodb'].includes(generator.databaseType), + path: SERVER_MAIN_KOTLIN_SRC_DIR, + templates: [ + { + file: 'package/repository/CustomAuditEventRepository.kt', + renameTo: generator => `${generator.javaDir}repository/CustomAuditEventRepository.kt`, + useBluePrint: true + } + ] + }, + { + condition: generator => + !generator.reactive && generator.authenticationType === 'oauth2' && ['sql', 'mongodb'].includes(generator.databaseType), path: SERVER_TEST_SRC_KOTLIN_DIR, templates: [ { file: 'package/repository/CustomAuditEventRepositoryIT.kt', renameTo: generator => `${generator.testDir}repository/CustomAuditEventRepositoryIT.kt`, useBluePrint: true - }, + } + ] + }, + { + condition: generator => generator.authenticationType === 'oauth2' && ['sql', 'mongodb'].includes(generator.databaseType), + path: SERVER_TEST_SRC_KOTLIN_DIR, + templates: [ { file: 'package/web/rest/AuditResourceIT.kt', renameTo: generator => `${generator.testDir}web/rest/AuditResourceIT.kt`, @@ -1552,11 +1602,6 @@ const serverFiles = { renameTo: generator => `${generator.javaDir}domain/Authority.kt`, useBluePrint: true }, - { - file: 'package/repository/CustomAuditEventRepository.kt', - renameTo: generator => `${generator.javaDir}repository/CustomAuditEventRepository.kt`, - useBluePrint: true - }, { file: 'package/repository/AuthorityRepository.kt', renameTo: generator => `${generator.javaDir}repository/${generator.reactiveRepository}AuthorityRepository.kt`, @@ -1564,7 +1609,8 @@ const serverFiles = { }, { file: 'package/repository/PersistenceAuditEventRepository.kt', - renameTo: generator => `${generator.javaDir}repository/PersistenceAuditEventRepository.kt`, + renameTo: generator => + `${generator.javaDir}repository/${generator.reactiveRepository}PersistenceAuditEventRepository.kt`, useBluePrint: true }, { @@ -1579,6 +1625,18 @@ const serverFiles = { } ] }, + { + condition: generator => + !generator.reactive && !generator.skipUserManagement && ['sql', 'mongodb', 'couchbase'].includes(generator.databaseType), + path: SERVER_MAIN_KOTLIN_SRC_DIR, + templates: [ + { + file: 'package/repository/CustomAuditEventRepository.kt', + renameTo: generator => `${generator.javaDir}repository/CustomAuditEventRepository.kt`, + useBluePrint: true + } + ] + }, { condition: generator => !generator.skipUserManagement, path: SERVER_MAIN_KOTLIN_SRC_DIR, @@ -1704,11 +1762,17 @@ const serverFiles = { file: 'package/web/rest/AuditResourceIT.kt', renameTo: generator => `${generator.testDir}web/rest/AuditResourceIT.kt`, useBluePrint: true + }, + { + file: 'package/service/AuditEventServiceIT.kt', + renameTo: generator => `${generator.testDir}service/AuditEventServiceIT.kt`, + useBluePrint: true } ] }, { - condition: generator => !generator.skipUserManagement && ['sql', 'mongodb', 'couchbase'].includes(generator.databaseType), + condition: generator => + !generator.reactive && !generator.skipUserManagement && ['sql', 'mongodb', 'couchbase'].includes(generator.databaseType), path: SERVER_TEST_SRC_KOTLIN_DIR, templates: [ { diff --git a/generators/server/templates/src/main/kotlin/package/config/CacheConfiguration.kt.ejs b/generators/server/templates/src/main/kotlin/package/config/CacheConfiguration.kt.ejs index c9c54e34a..bec91e59f 100644 --- a/generators/server/templates/src/main/kotlin/package/config/CacheConfiguration.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/config/CacheConfiguration.kt.ejs @@ -28,6 +28,17 @@ import org.ehcache.jsr107.Eh107Configuration import io.github.jhipster.config.JHipsterProperties +<%_ } _%> +<%_ if (cacheProvider === 'caffeine') { _%> +import com.github.benmanes.caffeine.jcache.configuration.CaffeineConfiguration +import java.util.OptionalLong +import java.util.concurrent.TimeUnit + +<%_ if (enableHibernateCache) { _%> +import org.hibernate.cache.jcache.ConfigSettings +<%_ } _%> +import io.github.jhipster.config.JHipsterProperties + <%_ } _%> <%_ if (cacheProvider === 'hazelcast') { _%> import io.github.jhipster.config.JHipsterConstants @@ -46,7 +57,7 @@ import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired <%_ } _%> <%_ } _%> -<%_ if (cacheProvider === 'ehcache') { _%> +<%_ if (cacheProvider === 'ehcache' || cacheProvider === 'caffeine') { _%> import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer <%_ } _%> <%_ if (cacheProvider === 'hazelcast') { _%> @@ -135,14 +146,15 @@ import io.github.jhipster.config.JHipsterProperties <%_ if (cacheProvider === 'infinispan') { _%> @Import(InfinispanEmbeddedCacheManagerAutoConfiguration::class) <%_ } _%> -class CacheConfiguration<%_ if (cacheProvider === 'ehcache') { _%>(jHipsterProperties: JHipsterProperties)<%_ } %><%_ if (cacheProvider === 'hazelcast') { %>(private val env: Environment<%_ if (serviceDiscoveryType === 'eureka' || serviceDiscoveryType === 'consul') { %>, +class CacheConfiguration<%_ if (cacheProvider === 'ehcache' || cacheProvider === 'caffeine') { _%>(jHipsterProperties: JHipsterProperties)<%_ } %><%_ if (cacheProvider === 'hazelcast') { %>(private val env: Environment<%_ if (serviceDiscoveryType === 'eureka' || serviceDiscoveryType === 'consul') { %>, private val serverProperties: ServerProperties, private val discoveryClient: DiscoveryClient<%_ } %>)<% } %><% if (cacheProvider === 'hazelcast') { %> : DisposableBean<% } %> { - <%_ if (cacheProvider === 'ehcache') { _%> + <%_ if (cacheProvider === 'ehcache' || cacheProvider === 'caffeine') { _%> private val jcacheConfiguration: javax.cache.configuration.Configuration init { + <%_ if (cacheProvider === 'ehcache') { _%> val ehcache = jHipsterProperties.cache.ehcache jcacheConfiguration = Eh107Configuration.fromEhcacheCacheConfiguration( @@ -153,6 +165,16 @@ class CacheConfiguration<%_ if (cacheProvider === 'ehcache') { _%>(jHipsterPrope .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(ehcache.timeToLiveSeconds.toLong()))) .build() ) + <%_ } else { _%> + val caffeine = jHipsterProperties.cache.caffeine + + val caffeineConfiguration = CaffeineConfiguration() + caffeineConfiguration.maximumSize = OptionalLong.of(caffeine.maxEntries) + caffeineConfiguration.expireAfterWrite = OptionalLong.of(TimeUnit.SECONDS.toNanos(caffeine.timeToLiveSeconds.toLong())) + caffeineConfiguration.isStatisticsEnabled = true + jcacheConfiguration = caffeineConfiguration + + <%_ } _%> } @Bean @@ -174,7 +196,12 @@ class CacheConfiguration<%_ if (cacheProvider === 'ehcache') { _%>(jHipsterPrope <%_ } _%> <%_ } _%> <%_ } _%> + <%_ if (cacheProvider === 'ehcache') { _%> // jhipster-needle-ehcache-add-entry + <%_ } _%> + <%_ if (cacheProvider === 'caffeine') { _%> + // jhipster-needle-caffeine-add-entry + <%_ } _%> } } diff --git a/generators/server/templates/src/main/kotlin/package/config/DatabaseConfiguration.kt.ejs b/generators/server/templates/src/main/kotlin/package/config/DatabaseConfiguration.kt.ejs index 871766def..3711632cd 100644 --- a/generators/server/templates/src/main/kotlin/package/config/DatabaseConfiguration.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/config/DatabaseConfiguration.kt.ejs @@ -71,7 +71,9 @@ import org.springframework.core.convert.converter.Converter<% } %> import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories <%_ } _%> <%_ if (databaseType === 'mongodb') { _%> + <%_ if (!reactive) { _%> import org.springframework.data.mongodb.config.EnableMongoAuditing + <%_ } _%> import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.convert.MongoCustomConversions import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener @@ -89,7 +91,9 @@ import org.springframework.data.convert.WritingConverter import org.springframework.data.couchbase.config.BeanNames import org.springframework.data.couchbase.core.convert.CouchbaseCustomConversions import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener + <%_ if (!reactive) { _%> import org.springframework.data.couchbase.repository.auditing.EnableCouchbaseAuditing + <%_ } _%> import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories <%_ if (reactive) { _%> import org.springframework.data.couchbase.repository.config.EnableReactiveCouchbaseRepositories @@ -144,8 +148,8 @@ import java.util.UUID @Import(value = [MongoAutoConfiguration::class, MongoReactiveAutoConfiguration::class]) <%_ } else { _%> @Import(value = [MongoAutoConfiguration::class]) - <%_ } _%> @EnableMongoAuditing(auditorAwareRef = "springSecurityAuditorAware") + <%_ } _%> <%_ } _%> <%_ if (databaseType === 'couchbase') { _%> @EnableCouchbaseRepositories( @@ -159,7 +163,9 @@ import java.util.UUID ) <%_ } _%> @Import(value = [CouchbaseAutoConfiguration::class]) + <%_ if (!reactive) { _%> @EnableCouchbaseAuditing(auditorAwareRef = "springSecurityAuditorAware") + <%_ } _%> <%_ } _%> class DatabaseConfiguration<%_ if (databaseType === 'sql' && (devDatabaseType === 'h2Disk' || devDatabaseType === 'h2Memory') ) { _%>(private val env: Environment) { <%_ } else if (databaseType === 'mongodb' || databaseType === 'couchbase') { %> {<% } %> <%_ if (databaseType === 'sql' && (devDatabaseType === 'h2Disk' || devDatabaseType === 'h2Memory')) { _%> diff --git a/generators/server/templates/src/main/kotlin/package/config/LiquibaseConfiguration.kt.ejs b/generators/server/templates/src/main/kotlin/package/config/LiquibaseConfiguration.kt.ejs index a59193a60..0f7b8242c 100644 --- a/generators/server/templates/src/main/kotlin/package/config/LiquibaseConfiguration.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/config/LiquibaseConfiguration.kt.ejs @@ -19,14 +19,15 @@ package <%=packageName%>.config import io.github.jhipster.config.JHipsterConstants +import io.github.jhipster.config.liquibase.SpringLiquibaseUtil import io.github.jhipster.config.liquibase.AsyncSpringLiquibase import liquibase.integration.spring.SpringLiquibase import org.slf4j.LoggerFactory +import org.springframework.beans.factory.ObjectProvider import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties +import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties -<%_ if (enableHibernateCache) { _%> -import org.springframework.cache.CacheManager -<%_ } _%> import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.env.Environment @@ -36,24 +37,33 @@ import javax.sql.DataSource import java.util.concurrent.Executor @Configuration -class LiquibaseConfiguration(private val env: Environment<% if (enableHibernateCache) { %>, private val cacheManager: CacheManager<% } %>) { +class LiquibaseConfiguration(private val env: Environment) { private val log = LoggerFactory.getLogger(javaClass) @Bean fun liquibase( @Qualifier("taskExecutor") executor: Executor, - dataSource: DataSource, - liquibaseProperties: LiquibaseProperties + @LiquibaseDataSource liquibaseDataSource: ObjectProvider, + liquibaseProperties: LiquibaseProperties, + dataSource: ObjectProvider, + dataSourceProperties: DataSourceProperties ) = - // Use liquibase.integration.spring.SpringLiquibase if you don't want Liquibase to start asynchronously - AsyncSpringLiquibase(executor, env).apply { - this.dataSource = dataSource + // If you don't want Liquibase to start asynchronously, substitute by this: + // SpringLiquibaseUtil.createSpringLiquibase(liquibaseDataSource.ifAvailable, liquibaseProperties, dataSource.ifUnique, dataSourceProperties); + SpringLiquibaseUtil.createAsyncSpringLiquibase(env, executor, liquibaseDataSource.ifAvailable, liquibaseProperties, dataSource.ifUnique, dataSourceProperties).apply { changeLog = "classpath:config/liquibase/master.xml" contexts = liquibaseProperties.contexts defaultSchema = liquibaseProperties.defaultSchema + liquibaseSchema = liquibaseProperties.liquibaseSchema + liquibaseTablespace = liquibaseProperties.liquibaseTablespace + databaseChangeLogLockTable = liquibaseProperties.databaseChangeLogLockTable + databaseChangeLogTable = liquibaseProperties.databaseChangeLogTable isDropFirst = liquibaseProperties.isDropFirst + labels = liquibaseProperties.labels setChangeLogParameters(liquibaseProperties.parameters) + setRollbackFile(liquibaseProperties.rollbackFile) + isTestRollbackOnUpdate = liquibaseProperties.isTestRollbackOnUpdate if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE))) { setShouldRun(false) diff --git a/generators/server/templates/src/main/kotlin/package/config/ReactiveSecurityConfiguration.kt.ejs b/generators/server/templates/src/main/kotlin/package/config/ReactiveSecurityConfiguration.kt.ejs index 3a0082b5f..c8cd3286b 100644 --- a/generators/server/templates/src/main/kotlin/package/config/ReactiveSecurityConfiguration.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/config/ReactiveSecurityConfiguration.kt.ejs @@ -24,6 +24,7 @@ import <%= packageName %>.security.jwt.JWTFilter import <%= packageName %>.security.jwt.TokenProvider <%_ } _%> <%_ if (authenticationType === 'session') { _%> +import <%= packageName %>.service.AuditEventService import io.github.jhipster.web.filter.reactive.CookieCsrfFilter <%_ } _%> import org.springframework.context.annotation.Bean @@ -41,10 +42,17 @@ import org.springframework.security.config.annotation.method.configuration.Enabl import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity import org.springframework.security.config.web.server.SecurityWebFiltersOrder import org.springframework.security.config.web.server.ServerHttpSecurity +<%_ if (authenticationType === 'session') { _%> +import org.springframework.security.core.Authentication +import org.springframework.security.core.AuthenticationException +<%_ } _%> <%_ if (!skipUserManagement) { _%> import org.springframework.security.core.userdetails.ReactiveUserDetailsService import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder <%_ } _%> +<%_ if (authenticationType === 'session') { _%> +import org.springframework.security.core.userdetails.User +<%_ } _%> import org.springframework.security.web.server.SecurityWebFilterChain <%_ if (authenticationType === 'session') { _%> import org.springframework.security.web.server.WebFilterExchange @@ -71,6 +79,9 @@ class SecurityConfiguration( <%_ } _%> <%_ if (authenticationType === 'jwt') { _%> private val tokenProvider: TokenProvider, +<%_ } _%> +<%_ if (authenticationType === 'session') { _%> + private val auditEventService: AuditEventService, <%_ } _%> private val problemSupport: SecurityProblemSupport ) { @@ -120,8 +131,8 @@ class SecurityConfiguration( .formLogin() .requiresAuthenticationMatcher(pathMatchers(HttpMethod.POST, "/api/authentication")) .authenticationEntryPoint(HttpStatusServerEntryPoint(HttpStatus.OK)) - .authenticationSuccessHandler { exchange, _ -> setStatusCode(exchange, HttpStatus.OK) } - .authenticationFailureHandler { exchange, _ -> setStatusCode(exchange, HttpStatus.UNAUTHORIZED) } + .authenticationSuccessHandler { exchange, authentication -> onAuthenticationSuccess(exchange, authentication) } + .authenticationFailureHandler { exchange, exception -> onAuthenticationError(exchange, exception) } .and() .logout() .logoutUrl("/api/logout") @@ -153,11 +164,24 @@ class SecurityConfiguration( } <%_ if (authenticationType === 'session') { _%> - companion object { + private fun onAuthenticationError(exchange: WebFilterExchange, e: AuthenticationException): Mono { + exchange.exchange.response.statusCode = HttpStatus.UNAUTHORIZED + return exchange.exchange() + .formData + .map { it.getFirst("username") } + .filter { !Constants.ANONYMOUS_USER.equals(it) } + .flatMap { auditEventService.saveAuthenticationError(it, e) } + .then() + } - @JvmStatic - private fun setStatusCode(exchange: WebFilterExchange, status: HttpStatus): Mono = - Mono.fromRunnable { exchange.exchange.response.statusCode = status } + private fun onAuthenticationSuccess(exchange: WebFilterExchange, authentication: Authentication): Mono { + exchange.exchange.response.statusCode = HttpStatus.OK + return Mono.just(authentication.principal) + .filter { it instanceof User } + .map { (it as User).username } + .filter { !Constants.ANONYMOUS_USER.equals(it) } + .flatMap { auditEventService.saveAuthenticationSuccess(it) } + .then() } <%_ } _%> } diff --git a/generators/server/templates/src/main/kotlin/package/config/SecurityConfiguration.kt.ejs b/generators/server/templates/src/main/kotlin/package/config/SecurityConfiguration.kt.ejs index 12ee7ae39..e3a68ffc9 100644 --- a/generators/server/templates/src/main/kotlin/package/config/SecurityConfiguration.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/config/SecurityConfiguration.kt.ejs @@ -20,7 +20,9 @@ package <%= packageName %>.config <%_ if (authenticationType === 'session' || authenticationType === 'jwt' || authenticationType === 'oauth2') { _%> import <%= packageName %>.security.ADMIN +<%_ if (authenticationType === 'oauth2' && applicationType !== 'microservice') { _%> import <%= packageName %>.security.extractAuthorityFromClaims +<%_ } _%> <%_ if (authenticationType === 'jwt') { _%> import <%= packageName %>.security.jwt.JWTConfigurer import <%= packageName %>.security.jwt.TokenProvider @@ -61,7 +63,7 @@ import org.springframework.security.oauth2.jwt.JwtDecoder import org.springframework.security.oauth2.jwt.JwtDecoders import org.springframework.security.oauth2.jwt.JwtValidators import org.springframework.security.oauth2.jwt.NimbusJwtDecoderJwkSupport - <%_ if (applicationType === 'gateway') { _%> + <%_ if (applicationType === 'gateway' && serviceDiscoveryType) { _%> import <%=packageName%>.security.oauth2.AuthorizationHeaderFilter import <%=packageName%>.security.oauth2.AuthorizationHeaderUtil <%_ } _%> @@ -198,9 +200,9 @@ class SecurityConfiguration( .and() .headers() <%_ if (clientTheme !== 'none') { _%> - .contentSecurityPolicy("default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com data:") + .contentSecurityPolicy("default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com data:") <%_ } else { _%> - .contentSecurityPolicy("default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:") + .contentSecurityPolicy("default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:") <%_ } _%> .and() .referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN) @@ -297,7 +299,7 @@ class SecurityConfiguration( return jwtDecoder } - <%_ if (applicationType === 'gateway') { _%> + <%_ if (applicationType === 'gateway' && serviceDiscoveryType) { _%> @Bean fun authHeaderFilter(headerUtil: AuthorizationHeaderUtil) = AuthorizationHeaderFilter(headerUtil) diff --git a/generators/server/templates/src/main/kotlin/package/config/WebConfigurer.kt.ejs b/generators/server/templates/src/main/kotlin/package/config/WebConfigurer.kt.ejs index d6ab5872b..8573c7135 100644 --- a/generators/server/templates/src/main/kotlin/package/config/WebConfigurer.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/config/WebConfigurer.kt.ejs @@ -58,7 +58,9 @@ import org.springframework.core.annotation.Order <%_ if (!reactive) { _%> import org.springframework.core.env.Environment import org.springframework.core.env.Profiles + <%_ if (!skipClient) { _%> import org.springframework.http.MediaType + <%_ } _%> <%_ } _%> <%_ if (reactive && !skipClient) { _%> import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher @@ -97,15 +99,11 @@ import reactor.core.publisher.Mono import javax.servlet.DispatcherType import javax.servlet.ServletContext import javax.servlet.ServletException -<%_ if (!skipClient) { _%> + <%_ if (!skipClient) { _%> import java.io.File import java.io.UnsupportedEncodingException - <%_ } _%> import java.nio.charset.StandardCharsets - <%_ if (!skipClient) { _%> import java.nio.file.Paths - <%_ } _%> - <%_ if (!skipClient) { _%> import java.util.EnumSet import java.net.URLDecoder.decode @@ -129,7 +127,7 @@ class WebConfigurer( private val env: Environment, <%_ } _%> private val jHipsterProperties: JHipsterProperties -) : <% if (!reactive) { %>ServletContextInitializer, WebServerFactoryCustomizer<% } %><% if (reactive) { %>WebFluxConfigurer<% } %> { +) : <% if (!reactive) { %>ServletContextInitializer<% if (!skipClient) { %>, WebServerFactoryCustomizer<% } %><% } %><% if (reactive) { %>WebFluxConfigurer<% } %> { private val log = LoggerFactory.getLogger(javaClass) <%_ if (!reactive) { _%> @@ -152,16 +150,15 @@ class WebConfigurer( <%_ } _%> log.info("Web application fully configured") } + <%_ if (!skipClient) { _%> /** * Customize the Servlet engine: Mime types, the document root, the cache. */ override fun customize(server: WebServerFactory) { setMimeMappings(server) - <%_ if (!skipClient) { _%> // When running in an IDE or with <% if (buildTool === 'gradle') { %>./gradlew bootRun<% } else { %>./mvnw spring-boot:run<% } %>, set location of the static web assets. setLocationForStaticAssets(server) - <%_ } _%> } private fun setMimeMappings(server: WebServerFactory) { @@ -174,7 +171,6 @@ class WebConfigurer( server.setMimeMappings(mappings) } } - <%_ if (!skipClient) { _%> private fun setLocationForStaticAssets(server: WebServerFactory) { if (server is ConfigurableServletWebServerFactory) { diff --git a/generators/server/templates/src/main/kotlin/package/domain/AbstractAuditingEntity.kt.ejs b/generators/server/templates/src/main/kotlin/package/domain/AbstractAuditingEntity.kt.ejs index 56801c7b1..76a026d67 100644 --- a/generators/server/templates/src/main/kotlin/package/domain/AbstractAuditingEntity.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/domain/AbstractAuditingEntity.kt.ejs @@ -22,9 +22,6 @@ package <%=packageName%>.domain import com.couchbase.client.java.repository.annotation.Field <%_ } _%> import com.fasterxml.jackson.annotation.JsonIgnore -<%_ if (databaseType === 'sql') { _%> -import org.hibernate.envers.Audited -<%_ } _%> <%_ if (!reactive) { _%> import org.springframework.data.annotation.CreatedBy <%_ } _%> @@ -54,7 +51,6 @@ import javax.persistence.MappedSuperclass */ <%_ if (databaseType === 'sql') { _%> @MappedSuperclass -@Audited @EntityListeners(AuditingEntityListener::class) <%_ } _%> abstract class AbstractAuditingEntity( diff --git a/generators/server/templates/src/main/kotlin/package/repository/PersistenceAuditEventRepository.kt.ejs b/generators/server/templates/src/main/kotlin/package/repository/PersistenceAuditEventRepository.kt.ejs index 3f041dbe9..56ea1c0ce 100644 --- a/generators/server/templates/src/main/kotlin/package/repository/PersistenceAuditEventRepository.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/repository/PersistenceAuditEventRepository.kt.ejs @@ -16,41 +16,54 @@ See the License for the specific language governing permissions and limitations under the License. -%> -package <%=packageName%>.repository +package <%=packageName%>.repository<% if (reactive) { %>.reactive<% } %> import <%=packageName%>.domain.PersistentAuditEvent +<%_ if (!reactive) { _%> import org.springframework.data.domain.Page -import org.springframework.data.domain.Pageable<% if (databaseType === 'sql') { %> -import org.springframework.data.jpa.repository.JpaRepository<% } %><% if (databaseType === 'mongodb') { %> -import org.springframework.data.mongodb.repository.MongoRepository<% } %> +<%_ } _%> +import org.springframework.data.domain.Pageable +<%_ if (databaseType === 'sql') { _%> +import org.springframework.data.jpa.repository.JpaRepository +<%_ } _%> + +<%_ if (databaseType === 'mongodb') { _%> +import org.springframework.data.mongodb.repository.<% if (reactive) { %>Reactive<% } %>MongoRepository +<%_ } _%> +<%_ if (reactive) { _%> +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono +<%_ } _%> import java.time.Instant -<% if (databaseType === 'sql') { %>/** - * Spring Data JPA repository for the [PersistentAuditEvent] entity. - */<% } %><% if (databaseType === 'mongodb') { %>/** - * Spring Data MongoDB repository for the [PersistentAuditEvent] entity. - */<% } %><% if (databaseType === 'couchbase') { %>/** - * Spring Data Couchbase repository for the [PersistentAuditEvent] entity. - */<% } %> -interface PersistenceAuditEventRepository : <% if (databaseType === 'sql') { %>JpaRepository<% } %><% if (databaseType === 'mongodb') { %>MongoRepository<% } %><% if (databaseType === 'couchbase') { %>N1qlCouchbaseRepository<% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { +/** + * Spring Data <% if (databaseType === 'sql') { %>JPA<% } else if (databaseType === 'mongodb') { %>MongoDB<% } else if (databaseType === 'couchbase') { %>Couchbase<% } %> repository for the [PersistentAuditEvent] entity. + */ +interface PersistenceAuditEventRepository : <% if (reactive) { %>Reactive<% } %><% if (databaseType === 'sql') { %>JpaRepository<% } %><% if (databaseType === 'mongodb') { %>MongoRepository<% } %><% if (databaseType === 'couchbase') { %>N1qlCouchbaseRepository<% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { %><% } %> { + <%_ if (!reactive) { _%> fun findByPrincipal(principal: String): List - fun findByAuditEventDateAfter(after: Instant): List - - fun findByPrincipalAndAuditEventDateAfter(principal: String, after: Instant): List - fun findByPrincipalAndAuditEventDateAfterAndAuditEventType( principal: String, after: Instant, type: String ): List + <%_ } _%> fun findAllByAuditEventDateBetween( fromDate: Instant, toDate: Instant, pageable: Pageable - ): Page + ): <% if (reactive) { %>Flux<% } else { %>Page<% } %> + + fun findByAuditEventDateBefore(before: Instant): <% if (reactive) { %>Flux<% } else { %>List<% } %> + <%_ if (reactive) { _%> + + fun findAllBy(pageable: Pageable): Flux + + fun countByAuditEventDateBetween(fromDate: Instant, toDate: Instant): Mono + <%_ } _%> } diff --git a/generators/server/templates/src/main/kotlin/package/repository/UserRepository.kt.ejs b/generators/server/templates/src/main/kotlin/package/repository/UserRepository.kt.ejs index 551e22947..5935821b1 100644 --- a/generators/server/templates/src/main/kotlin/package/repository/UserRepository.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/repository/UserRepository.kt.ejs @@ -106,7 +106,7 @@ import <%=packageName%>.config.ID_DELIMITER _%> <%_ if (databaseType === 'sql' || databaseType === 'mongodb' || databaseType === 'couchbase') { _%> @Repository -interface UserRepository : <% if (databaseType === 'sql') { %>JpaRepository<<%= asEntity('User') %>, <% if (authenticationType === 'oauth2') { %>String<% } else { %>Long<% } %>><% } %><% if (reactive) { %>Reactive<% } %><% if (databaseType === 'mongodb') { %>MongoRepository<<%= asEntity('User') %>, String><% } %><% if (databaseType === 'couchbase') { %>N1qlCouchbaseRepository<<%= asEntity('User') %>, String><% } %> { +interface UserRepository : <% if (databaseType === 'sql') { %>JpaRepository<<%= asEntity('User') %>, <% if (authenticationType === 'oauth2') { %>String<% } else { %>Long<% } %>><% } %><% if (databaseType === 'mongodb') { %><% if (reactive) { %>Reactive<% } %>MongoRepository<<%= asEntity('User') %>, String><% } %><% if (databaseType === 'couchbase') { %>N1qlCouchbaseRepository<<%= asEntity('User') %>, String><% } %> { <%_ if (authenticationType !== 'oauth2') { _%> fun findOneByActivationKey(activationKey: String): <%= optionalOrMono %><<%= asEntity('User') %>> diff --git a/generators/server/templates/src/main/kotlin/package/security/SpringSecurityAuditorAware.kt.ejs b/generators/server/templates/src/main/kotlin/package/security/SpringSecurityAuditorAware.kt.ejs index 85f1d052a..7a8153818 100644 --- a/generators/server/templates/src/main/kotlin/package/security/SpringSecurityAuditorAware.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/security/SpringSecurityAuditorAware.kt.ejs @@ -30,12 +30,5 @@ import org.springframework.stereotype.Component */ @Component class SpringSecurityAuditorAware : AuditorAware { - -<%_ if (reactive) { _%> - // There is currently no reactive AuditorAware implementation so we can't - // extract the currently logged-in user from the Reactor Context. - // Therefore createdBy and lastModifiedBy will have to be set explicitly. - // See https://jira.spring.io/browse/DATACMNS-1231 -<%_ } _%> - override fun getCurrentAuditor(): Optional = <% if (reactive) { %>Optional.of(SYSTEM_ACCOUNT)<% } else { %>Optional.of(getCurrentUserLogin().orElse(SYSTEM_ACCOUNT))<% } %> + override fun getCurrentAuditor(): Optional = Optional.of(getCurrentUserLogin().orElse(SYSTEM_ACCOUNT)) } diff --git a/generators/server/templates/src/main/kotlin/package/service/AuditEventService.kt.ejs b/generators/server/templates/src/main/kotlin/package/service/AuditEventService.kt.ejs index 1b142780a..1a7043392 100644 --- a/generators/server/templates/src/main/kotlin/package/service/AuditEventService.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/service/AuditEventService.kt.ejs @@ -18,16 +18,40 @@ -%> package <%=packageName%>.service +import io.github.jhipster.config.JHipsterProperties import <%=packageName%>.config.audit.AuditEventConverter -import <%=packageName%>.repository.PersistenceAuditEventRepository +<%_ if (reactive) { _%> +import <%= packageName %>.domain.PersistentAuditEvent +<%_ } _%> +import <%=packageName%>.repository.<% if (reactive) { %>reactive.<% } %>PersistenceAuditEventRepository +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.boot.actuate.audit.AuditEvent +<%_ if (!reactive) { _%> import org.springframework.data.domain.Page +<%_ } _%> import org.springframework.data.domain.Pageable -import org.springframework.stereotype.Service<% if (databaseType === 'sql') { %> -import org.springframework.transaction.annotation.Transactional<% } %> - +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Service +<%_ if (databaseType === 'sql') { _%> +import org.springframework.transaction.annotation.Transactional +<%_ } _%> +<%_ if (reactive) { _%> +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono +<%_ } _%> import java.time.Instant +import java.time.temporal.ChronoUnit +<%_ if (!reactive) { _%> import java.util.Optional +<%_ } _%> +<%_ if (reactive) { _%> +import java.util.HashMap +import java.util.Map + +import org.springframework.boot.actuate.security.AuthenticationAuditListener.AUTHENTICATION_FAILURE +import org.springframework.boot.actuate.security.AuthenticationAuditListener.AUTHENTICATION_SUCCESS +<%_ } _%> /** * Service for managing audit events. @@ -38,20 +62,101 @@ import java.util.Optional @Transactional<% } %> class AuditEventService( private val persistenceAuditEventRepository: PersistenceAuditEventRepository, - private val auditEventConverter: AuditEventConverter + private val auditEventConverter: AuditEventConverter, + private val jHipsterProperties: JHipsterProperties ) { - fun findAll(pageable: Pageable): Page = - persistenceAuditEventRepository.findAll(pageable) + <%_ if (reactive) { _%> + /** + * Should be the same as in Liquibase migration. + */ + private val EVENT_DATA_COLUMN_MAX_LENGTH = 255 + <%_ } _%> + + private val log = LoggerFactory.getLogger(javaClass) + + /** + * Old audit events should be automatically deleted after 30 days. + * + * This is scheduled to get fired at 12:00 (am). + */ + @Scheduled(cron = "0 0 12 * * ?") + fun removeOldAuditEvents() { + persistenceAuditEventRepository + .findByAuditEventDateBefore(Instant.now().minus(jHipsterProperties.auditEvents.retentionPeriod.toLong(), ChronoUnit.DAYS)) + <%_ if (!reactive) { _%> + .forEach{ + log.debug("Deleting audit data {}", it) + persistenceAuditEventRepository.delete(it) + } + <%_ } else { _%> + .flatMap { + log.debug("Deleting audit data {}", it); + persistenceAuditEventRepository.delete(it); + }.blockLast() + <%_ } _%> + } + + fun findAll(pageable: Pageable): <% if (reactive) { %>Flux<% } else { %>Page<% } %> = + persistenceAuditEventRepository.findAll<% if (reactive) { %>By<% } %>(pageable) .map { auditEventConverter.convertToAuditEvent(it) } - fun findByDates(fromDate: Instant, toDate: Instant, pageable: Pageable): Page = + fun findByDates(fromDate: Instant, toDate: Instant, pageable: Pageable): <% if (reactive) { %>Flux<% } else { %>Page<% } %> = persistenceAuditEventRepository.findAllByAuditEventDateBetween(fromDate, toDate, pageable) .map { auditEventConverter.convertToAuditEvent(it) } - fun find(id: <% if (databaseType === 'sql') { %>Long<% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>String<% } %>): Optional = - Optional.ofNullable(persistenceAuditEventRepository.findById(id)) - .filter { it.isPresent } - .map { it.get() } + fun find(id: <% if (databaseType === 'sql') { %>Long<% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>String<% } %>): <% if (reactive) { %>Mono<% } else { %>Optional<% } %> = + persistenceAuditEventRepository.findById(id) .map { auditEventConverter.convertToAuditEvent(it) } + + <%_ if (reactive) { _%> + + fun count(): Mono { + return persistenceAuditEventRepository.count() + } + + fun countByDates(fromDate: Instant, toDate: Instant): Mono { + return persistenceAuditEventRepository.countByAuditEventDateBetween(fromDate, toDate) + } + + fun saveAuthenticationSuccess(login: String): Mono { + val persistentAuditEvent = PersistentAuditEvent() + persistentAuditEvent.principal = login + persistentAuditEvent.auditEventType = AUTHENTICATION_SUCCESS + persistentAuditEvent.auditEventDate = Instant.now() + return persistenceAuditEventRepository.save(persistentAuditEvent) + } + + fun saveAuthenticationError(login: String, e: Throwable): Mono { + val persistentAuditEvent = PersistentAuditEvent() + persistentAuditEvent.principal = login + persistentAuditEvent.auditEventType = AUTHENTICATION_FAILURE + persistentAuditEvent.auditEventDate = Instant.now() + val eventData = mutableMapOf() + eventData["type"] = e::class.java.name + eventData["message"] = e.message + persistentAuditEvent.data = truncate(eventData) + return persistenceAuditEventRepository.save(persistentAuditEvent) + } + + /** + * Truncate event data that might exceed column length. + */ + private fun truncate(data: MutableMap): MutableMap { + val results = mutableMapOf() + data.entries.forEach { + var value = it.value + if (value != null) { + val length = value.length + if (length > EVENT_DATA_COLUMN_MAX_LENGTH) { + value = value.substring(0, EVENT_DATA_COLUMN_MAX_LENGTH) + log.warn("Event data for {} too long ({}) has been truncated to {}. Consider increasing column width.", + it.key, length, EVENT_DATA_COLUMN_MAX_LENGTH) + } + } + results[it.key] = value + } + return results + } + <%_ } _%> } diff --git a/generators/server/templates/src/main/kotlin/package/service/EmailAlreadyUsedException.kt.ejs b/generators/server/templates/src/main/kotlin/package/service/EmailAlreadyUsedException.kt.ejs new file mode 100644 index 000000000..edd778729 --- /dev/null +++ b/generators/server/templates/src/main/kotlin/package/service/EmailAlreadyUsedException.kt.ejs @@ -0,0 +1,21 @@ +<%# + Copyright 2013-2019 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + 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. +-%> +package <%=packageName%>.service + +class EmailAlreadyUsedException: RuntimeException("Email is already in use!") diff --git a/generators/server/templates/src/main/kotlin/package/service/InvalidPasswordException.kt.ejs b/generators/server/templates/src/main/kotlin/package/service/InvalidPasswordException.kt.ejs new file mode 100644 index 000000000..c59ee9ec3 --- /dev/null +++ b/generators/server/templates/src/main/kotlin/package/service/InvalidPasswordException.kt.ejs @@ -0,0 +1,21 @@ +<%# + Copyright 2013-2019 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + 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. +-%> +package <%=packageName%>.service + +class InvalidPasswordException: RuntimeException("Incorrect password") diff --git a/generators/server/templates/src/main/kotlin/package/service/UserService.kt.ejs b/generators/server/templates/src/main/kotlin/package/service/UserService.kt.ejs index e2e662c45..808de31db 100644 --- a/generators/server/templates/src/main/kotlin/package/service/UserService.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/service/UserService.kt.ejs @@ -46,9 +46,6 @@ import <%=packageName%>.service.dto.<%= asDto('User') %> import <%=packageName%>.service.util.generateActivationKey import <%=packageName%>.service.util.generatePassword import <%=packageName%>.service.util.generateResetKey -import <%=packageName%>.web.rest.errors.EmailAlreadyUsedException -import <%=packageName%>.web.rest.errors.InvalidPasswordException -import <%=packageName%>.web.rest.errors.LoginAlreadyUsedException <%_ } _%> <%_ if (databaseType !== 'no') { _%> @@ -203,7 +200,7 @@ class UserService<% if (databaseType !== 'no') { %>( userRepository.findOneByLogin(login.toLowerCase()).ifPresent { existingUser -> val removed = removeNonActivatedUser(existingUser) if (!removed) { - throw LoginAlreadyUsedException() + throw UsernameAlreadyUsedException() } } userRepository.findOneByEmailIgnoreCase(email).ifPresent { existingUser -> @@ -255,7 +252,7 @@ class UserService<% if (databaseType !== 'no') { %>( <%_ } _%> userRepository.delete(existingUser) } else { - throw LoginAlreadyUsedException() + throw UsernameAlreadyUsedException() } } .then(userRepository.findOneByEmailIgnoreCase(email)) @@ -621,7 +618,7 @@ class UserService<% if (databaseType !== 'no') { %>( <%_ if (databaseType === 'sql') { _%> @Transactional(readOnly = true) <%_ } _%> - fun getUserWithAuthorities(id: <%= pkType %>): <% if (reactive) { %>Mono<% } else { %>Optional<% } %><<%= asEntity('User') %>> = + fun getUserWithAuthorities(id: <% if (pkType === 'UUID') { %>String<% } else { %><%= pkType %><% } %>): <% if (reactive) { %>Mono<% } else { %>Optional<% } %><<%= asEntity('User') %>> = userRepository.<% if (databaseType === 'sql') { %>findOneWithAuthoritiesById(id)<% } else { %>findById(id)<% } %> <%_ if (databaseType === 'sql') { _%> @@ -755,7 +752,7 @@ class UserService<% if (databaseType !== 'no') { %>( val user = getUser(attributes) user.authorities = authToken.authorities.asSequence() .map(GrantedAuthority::getAuthority) - <%_ if (databaseType !== 'no') { _%> + <%_ if (databaseType === 'sql' || databaseType === 'mongodb') { _%> .map { Authority(name = it) } <%_ } _%> .toMutableSet() diff --git a/generators/server/templates/src/main/kotlin/package/service/UsernameAlreadyUsedException.kt.ejs b/generators/server/templates/src/main/kotlin/package/service/UsernameAlreadyUsedException.kt.ejs new file mode 100644 index 000000000..6c439eace --- /dev/null +++ b/generators/server/templates/src/main/kotlin/package/service/UsernameAlreadyUsedException.kt.ejs @@ -0,0 +1,21 @@ +<%# + Copyright 2013-2019 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + 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. +-%> +package <%=packageName%>.service + +class UsernameAlreadyUsedException: RuntimeException("Login name already used!") diff --git a/generators/server/templates/src/main/kotlin/package/service/util/RandomUtil.kt.ejs b/generators/server/templates/src/main/kotlin/package/service/util/RandomUtil.kt.ejs index 9b6457fc7..49812e8a0 100644 --- a/generators/server/templates/src/main/kotlin/package/service/util/RandomUtil.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/service/util/RandomUtil.kt.ejs @@ -20,44 +20,49 @@ package <%=packageName%>.service.util +import java.security.SecureRandom import org.apache.commons.lang3.RandomStringUtils private const val DEF_COUNT = 20 +private val secureRandom: SecureRandom = SecureRandom().apply{ nextBytes(ByteArray(64)) } + +private fun generateRandomAlphanumericString() = RandomStringUtils.random(DEF_COUNT, 0, 0, true, true, null, secureRandom) + /** - * Generate a password. - * - * @return the generated password. - */ -fun generatePassword(): String = RandomStringUtils.randomAlphanumeric(DEF_COUNT) +* Generate a password. +* +* @return the generated password. +*/ +fun generatePassword() = generateRandomAlphanumericString() /** - * Generate an activation key. - * - * @return the generated activation key. - */ -fun generateActivationKey(): String = RandomStringUtils.randomNumeric(DEF_COUNT) +* Generate an activation key. +* +* @return the generated activation key. +*/ +fun generateActivationKey() = generateRandomAlphanumericString() /** - * Generate a reset key. - * - * @return the generated reset key. - */ -fun generateResetKey(): String = RandomStringUtils.randomNumeric(DEF_COUNT) +* Generate a reset key. +* +* @return the generated reset key. +*/ +fun generateResetKey(): String = generateRandomAlphanumericString() <%_ if (authenticationType === 'session' && !reactive) { _%> /** - * Generate a unique series to validate a persistent token, used in the - * authentication remember-me mechanism. - * - * @return the generated series data. - */ -fun generateSeriesData(): String = RandomStringUtils.randomAlphanumeric(DEF_COUNT) +* Generate a unique series to validate a persistent token, used in the +* authentication remember-me mechanism. +* +* @return the generated series data. +*/ +fun generateSeriesData(): String = generateRandomAlphanumericString() /** - * Generate a persistent token, used in the authentication remember-me mechanism. - * - * @return the generated token data. - */ -fun generateTokenData(): String = RandomStringUtils.randomAlphanumeric(DEF_COUNT) +* Generate a persistent token, used in the authentication remember-me mechanism. +* +* @return the generated token data. +*/ +fun generateTokenData(): String = generateRandomAlphanumericString() <%_ } _%> diff --git a/generators/server/templates/src/main/kotlin/package/web/rest/AuditResource.kt.ejs b/generators/server/templates/src/main/kotlin/package/web/rest/AuditResource.kt.ejs index 927512ca4..9919f10c5 100644 --- a/generators/server/templates/src/main/kotlin/package/web/rest/AuditResource.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/web/rest/AuditResource.kt.ejs @@ -21,12 +21,15 @@ package <%=packageName%>.web.rest import <%=packageName%>.service.AuditEventService import io.github.jhipster.web.util.PaginationUtil +<%_ if (!reactive) { _%> import io.github.jhipster.web.util.ResponseUtil +<%_ } _%> import org.springframework.boot.actuate.audit.AuditEvent import org.springframework.data.domain.Pageable import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity <%_ if (reactive) { _%> +import org.springframework.data.domain.PageImpl import org.springframework.http.server.reactive.ServerHttpRequest <%_ } _%> import org.springframework.web.bind.annotation.GetMapping @@ -37,9 +40,14 @@ import org.springframework.web.bind.annotation.RestController <%_ if (!reactive) { _%> import org.springframework.web.servlet.support.ServletUriComponentsBuilder <%_ } else { _%> +import org.springframework.web.server.ResponseStatusException import org.springframework.web.util.UriComponentsBuilder +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono +import reactor.core.publisher.switchIfEmpty <%_ } _%> +import java.time.Instant import java.time.LocalDate import java.time.ZoneId @@ -60,14 +68,20 @@ class AuditResource(private val auditEventService: AuditEventService) { * @return the `ResponseEntity` with status `200 (OK)` and the list of `AuditEvent`s in body. */ @GetMapping - fun getAll( - <% if (reactive) { %>request: ServerHttpRequest, <% } %> - pageable: Pageable - ): ResponseEntity> { + <%_ if (!reactive) { _%> + fun getAll(pageable: Pageable): ResponseEntity> { val page = auditEventService.findAll(pageable) - val headers = PaginationUtil.generatePaginationHttpHeaders(<% if (!reactive) { %>ServletUriComponentsBuilder.fromCurrentRequest()<% } else { %>UriComponentsBuilder.fromHttpRequest(request)<% } %>, page) + val headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page) return ResponseEntity(page.content, headers, HttpStatus.OK) } + <%_ } else { _%> + fun getAll(request: ServerHttpRequest, pageable: Pageable): Mono>> { + return auditEventService.count() + .map { PageImpl(listOf(), pageable, it) } + .map { PaginationUtil.generatePaginationHttpHeaders(UriComponentsBuilder.fromHttpRequest(request), it) } + .map { ResponseEntity.ok().headers(it).body(auditEventService.findAll(pageable)) } + } + <%_ } _%> /** * `GET /audits` : get a page of `AuditEvent`s between the `fromDate` and `toDate`. @@ -88,15 +102,22 @@ class AuditResource(private val auditEventService: AuditEventService) { request: ServerHttpRequest, <%_ } _%> pageable: Pageable - ): ResponseEntity> { + ): <% if (!reactive) { %>ResponseEntity><% } else { %>Mono>><% } %> { - val page = auditEventService.findByDates( - fromDate.atStartOfDay(ZoneId.systemDefault()).toInstant(), - toDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant(), - pageable - ) - val headers = PaginationUtil.generatePaginationHttpHeaders(<% if (!reactive) { %>ServletUriComponentsBuilder.fromCurrentRequest()<% } else { %>UriComponentsBuilder.fromHttpRequest(request)<% } %>, page) - return ResponseEntity(page.content, headers, HttpStatus.OK) + val from = fromDate.atStartOfDay(ZoneId.systemDefault()).toInstant() + val to = toDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant() + + <%_ if (!reactive) { _%> + val page = auditEventService.findByDates(from, to, pageable) + val headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page) + return ResponseEntity(page.content, headers, HttpStatus.OK); + <%_ } else { _%> + val events = auditEventService.findByDates(from, to, pageable) + return auditEventService.countByDates(from, to) + .map { PageImpl(listOf(), pageable, it) } + .map { PaginationUtil.generatePaginationHttpHeaders(UriComponentsBuilder.fromHttpRequest(request), it) } + .map { ResponseEntity.ok().headers(it).body(events) } + <%_ } _%> } /** @@ -106,6 +127,11 @@ class AuditResource(private val auditEventService: AuditEventService) { * @return the `ResponseEntity` with status `200 (OK)` and the AuditEvent in body, or status `404 (Not Found)`. */ @GetMapping("/{id:.+}") + <%_ if (!reactive) { _%> fun get(@PathVariable id: <% if (databaseType === 'sql') { %>Long<% } %><% if (databaseType === 'mongodb' || databaseType === 'couchbase') { %>String<% } %>?): ResponseEntity = ResponseUtil.wrapOrNotFound(auditEventService.find(id!!)) + <%_ } else { _%> + fun get(@PathVariable id: String?) = auditEventService.find(id!!) + .switchIfEmpty { Mono.error(ResponseStatusException(HttpStatus.NOT_FOUND)) } + <%_ } _%> } diff --git a/generators/server/templates/src/main/kotlin/package/web/rest/UserJWTController.kt.ejs b/generators/server/templates/src/main/kotlin/package/web/rest/UserJWTController.kt.ejs index e627690ae..7e6b2dbe3 100644 --- a/generators/server/templates/src/main/kotlin/package/web/rest/UserJWTController.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/web/rest/UserJWTController.kt.ejs @@ -18,8 +18,14 @@ -%> package <%= packageName %>.web.rest +<%_ if (reactive) { _%> +import <%= packageName %>.config.ANONYMOUS_USER +<%_ } _%> import <%= packageName %>.security.jwt.JWTFilter import <%= packageName %>.security.jwt.TokenProvider +<%_ if (reactive) { _%> +import <%= packageName %>.service.AuditEventService +<%_ } _%> import <%= packageName %>.web.rest.vm.LoginVM import com.fasterxml.jackson.annotation.JsonProperty @@ -31,6 +37,9 @@ import org.springframework.http.ResponseEntity import org.springframework.security.authentication.ReactiveAuthenticationManager <%_ } _%> import org.springframework.security.authentication.UsernamePasswordAuthenticationToken +<%_ if (reactive) { _%> +import org.springframework.security.core.Authentication +<%_ } _%> <%_ if (!reactive) { _%> import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder import org.springframework.security.core.context.SecurityContextHolder @@ -44,9 +53,6 @@ import reactor.core.publisher.Mono <%_ } _%> import javax.validation.Valid -<%_ if (reactive) { _%> -import java.util.Optional -<%_ } _%> /** * Controller to authenticate users. @@ -55,7 +61,10 @@ import java.util.Optional @RequestMapping("/api") class UserJWTController( private val tokenProvider: TokenProvider, - <% if (!reactive) { %>private val authenticationManagerBuilder: AuthenticationManagerBuilder <% } else { %>private val authenticationManager: ReactiveAuthenticationManager <% } %> + <% if (!reactive) { %>private val authenticationManagerBuilder: AuthenticationManagerBuilder <% } else { %> + private val authenticationManager: ReactiveAuthenticationManager, + private val auditEventService: AuditEventService + <% } %> ) { <%_ if (!reactive) { _%> @PostMapping("/authenticate") @@ -74,17 +83,34 @@ class UserJWTController( <%_ } else { _%> @PostMapping("/authenticate") fun authorize(@Valid @RequestBody loginVM: Mono): Mono> = - loginVM - .flatMap { login -> - authenticationManager - .authenticate(UsernamePasswordAuthenticationToken(login.username, login.password)) - .map { auth -> tokenProvider.createToken(auth, Optional.ofNullable(login.isRememberMe).orElse(false)) } - } - .map { jwt -> - val httpHeaders = HttpHeaders() - httpHeaders.add(JWTFilter.AUTHORIZATION_HEADER, "Bearer $jwt") - ResponseEntity(JWTToken(jwt), httpHeaders, HttpStatus.OK) - } + loginVM.flatMap { login -> + authenticationManager.authenticate(UsernamePasswordAuthenticationToken(login.username, login.password)) + .onErrorResume { onAuthenticationError(login, it) } + .flatMap { onAuthenticationSuccess(login, it) } + .map { tokenProvider.createToken(it, true == login.isRememberMe) } + }.map{ + jwt -> + val httpHeaders = HttpHeaders() + httpHeaders.add(JWTFilter.AUTHORIZATION_HEADER, "Bearer $jwt") + ResponseEntity(JWTToken(jwt), httpHeaders, HttpStatus.OK) + } + + private fun onAuthenticationSuccess(login: LoginVM, auth: Authentication): Mono { + return Mono.just(login) + .map {it.username} + .filter { ANONYMOUS_USER != it } + .flatMap { auditEventService.saveAuthenticationSuccess(it!!) } + .thenReturn(auth) + } + + private fun onAuthenticationError(login: LoginVM, throwable: Throwable): Mono { + return Mono.just(login) + .map {it.username} + .filter { ANONYMOUS_USER != it } + .flatMap { auditEventService.saveAuthenticationError(it!!, throwable) } + .then(Mono.error(throwable)) + } + <%_ } _%> /** diff --git a/generators/server/templates/src/main/kotlin/package/web/rest/errors/ExceptionTranslator.kt.ejs b/generators/server/templates/src/main/kotlin/package/web/rest/errors/ExceptionTranslator.kt.ejs index fd0610152..8f1a11c9b 100644 --- a/generators/server/templates/src/main/kotlin/package/web/rest/errors/ExceptionTranslator.kt.ejs +++ b/generators/server/templates/src/main/kotlin/package/web/rest/errors/ExceptionTranslator.kt.ejs @@ -136,7 +136,7 @@ _%> : <%- returnType %> { <%_ } _%> val result = ex.bindingResult - val fieldErrors = result.fieldErrors.map { FieldErrorVM(it.objectName, it.field, it.code) } + val fieldErrors = result.fieldErrors.map { FieldErrorVM(it.objectName.replaceFirst(Regex("<%= dtoSuffix %>$"), ""), it.field, it.code) } val problem = Problem.builder() .withType(CONSTRAINT_VIOLATION_TYPE) @@ -159,9 +159,29 @@ _%> } <%_ } _%> + <%_ if (!skipUserManagement) { _%> + @ExceptionHandler + fun handleEmailAlreadyUsedException(ex: <%=packageName%>.service.EmailAlreadyUsedException, request: <%= requestClass %>): <%- returnType %> { + val problem = EmailAlreadyUsedException() + return create(problem, request, HeaderUtil.createFailureAlert(applicationName, <%= enableTranslation %>, problem.entityName, problem.errorKey, problem.message)) + } + + @ExceptionHandler + fun handleUsernameAlreadyUsedException(ex: <%=packageName%>.service.UsernameAlreadyUsedException, request: <%= requestClass %>): <%- returnType %> { + val problem = LoginAlreadyUsedException() + return create(problem, request, HeaderUtil.createFailureAlert(applicationName, <%= enableTranslation %>, problem.entityName, problem.errorKey, problem.message)) + } + + @ExceptionHandler + fun handleInvalidPasswordException(ex: <%=packageName%>.service.InvalidPasswordException, request: <%= requestClass %>): <%- returnType %> { + return create(InvalidPasswordException(), request) + } + <%_ } _%> + @ExceptionHandler fun handleBadRequestAlertException( - ex: BadRequestAlertException, request: <%= requestClass %> + ex: BadRequestAlertException, + request: <%= requestClass %> ): <%- returnType %> = create( ex, request, diff --git a/generators/server/templates/src/test/kotlin/package/ArchTest.kt.ejs b/generators/server/templates/src/test/kotlin/package/ArchTest.kt.ejs new file mode 100644 index 000000000..48426cd93 --- /dev/null +++ b/generators/server/templates/src/test/kotlin/package/ArchTest.kt.ejs @@ -0,0 +1,47 @@ +<%# + Copyright 2013-2019 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + 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. +-%> +package <%=packageName%> + +import com.tngtech.archunit.core.domain.JavaClasses +import com.tngtech.archunit.core.importer.ClassFileImporter +import com.tngtech.archunit.core.importer.ImportOption +import org.junit.jupiter.api.Test + +import com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses + +class ArchTest { + + @Test + fun servicesAndRepositoriesShouldNotDependOnWebLayer() { + + val importedClasses = ClassFileImporter() + .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) + .importPackages("<%=packageName%>") + + noClasses() + .that() + .resideInAnyPackage("..service..") + .or() + .resideInAnyPackage("..repository..") + .should().dependOnClassesThat() + .resideInAnyPackage("..<%=packageName%>.web..") + .because("Services and repositories should not depend on web layer") + .check(importedClasses) + } +} diff --git a/generators/server/templates/src/test/kotlin/package/config/WebConfigurerTest.kt.ejs b/generators/server/templates/src/test/kotlin/package/config/WebConfigurerTest.kt.ejs index 9b8b05763..c441aecb5 100644 --- a/generators/server/templates/src/test/kotlin/package/config/WebConfigurerTest.kt.ejs +++ b/generators/server/templates/src/test/kotlin/package/config/WebConfigurerTest.kt.ejs @@ -28,7 +28,9 @@ import org.h2.server.web.WebServlet <%_ } _%> import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +<%_ if (!skipClient) { _%> import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory +<%_ } _%> import org.springframework.http.HttpHeaders import org.springframework.mock.env.MockEnvironment import org.springframework.mock.web.MockServletContext @@ -41,9 +43,9 @@ import javax.servlet.ServletException import javax.servlet.ServletRegistration <%_ if (!skipClient) { _%> import java.io.File -<%_ } _%> import org.assertj.core.api.Assertions.assertThat +<%_ } _%> import org.mockito.ArgumentMatchers import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyString @@ -117,6 +119,7 @@ class WebConfigurerTest { <%_ } _%> } + <%_ if (!skipClient) { _%> @Test fun testCustomizeServletContainer() { env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION) @@ -131,6 +134,7 @@ class WebConfigurerTest { } <%_ } _%> } + <%_ } _%> @Test @Throws(Exception::class) diff --git a/generators/server/templates/src/test/kotlin/package/service/AuditEventServiceIT.kt.ejs b/generators/server/templates/src/test/kotlin/package/service/AuditEventServiceIT.kt.ejs new file mode 100644 index 000000000..70e61e1fa --- /dev/null +++ b/generators/server/templates/src/test/kotlin/package/service/AuditEventServiceIT.kt.ejs @@ -0,0 +1,119 @@ + +<%# + Copyright 2013-2019 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + 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. +-%> +package <%= packageName %>.service + +import <%= packageName %>.domain.PersistentAuditEvent +import <%= packageName %>.repository.PersistenceAuditEventRepository +import <%=packageName%>.<%= mainClass %> +import io.github.jhipster.config.JHipsterProperties +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +<%_ if (databaseType === 'sql') { _%> +import org.springframework.transaction.annotation.Transactional +<%_ } _%> +<%_ if (databaseType === 'couchbase') { _%> +import <%= packageName %>.web.rest.mockAuthentication +<%_ } _%> +<%_ if (messageBroker === 'kafka') { _%> +import org.springframework.kafka.test.context.EmbeddedKafka +<%_ } _%> +<%_ if (authenticationType === 'oauth2') { _%> +import <%= packageName %>.config.TestSecurityConfiguration +<%_ } _%> +import java.time.Instant +import java.time.temporal.ChronoUnit + +import org.assertj.core.api.Assertions.assertThat + +/** + * Integration tests for {@link AuditEventService}. + */ +<%_ if (messageBroker === 'kafka') { _%> +@EmbeddedKafka +<%_ } _%> +<%_ if (authenticationType === 'oauth2') { _%> +@SpringBootTest(classes = [<%= mainClass %>::class, TestSecurityConfiguration::class]) +<%_ } else { _%> +@SpringBootTest(classes = [<%= mainClass %>::class]) +<%_ } _%> +<%_ if (databaseType === 'sql') { _%> +@Transactional +<%_ } _%> +class AuditEventServiceIT { + @Autowired + private lateinit var auditEventService: AuditEventService + + @Autowired + private lateinit var persistenceAuditEventRepository: PersistenceAuditEventRepository + + @Autowired + private lateinit var jHipsterProperties: JHipsterProperties + + private lateinit var auditEventOld: PersistentAuditEvent + + private lateinit var auditEventWithinRetention: PersistentAuditEvent + + private lateinit var auditEventNew: PersistentAuditEvent + + @BeforeEach + fun init() { + <%_ if (databaseType === 'couchbase') { _%> + mockAuthentication() + <%_ } _%> + auditEventOld = PersistentAuditEvent() + auditEventOld.auditEventDate = Instant.now().minus((jHipsterProperties.auditEvents.retentionPeriod + 1).toLong(), ChronoUnit.DAYS) + auditEventOld.principal = "test-user-old" + auditEventOld.auditEventType = "test-type" + + auditEventWithinRetention = PersistentAuditEvent() + auditEventWithinRetention.auditEventDate = Instant.now().minus((jHipsterProperties.auditEvents.retentionPeriod - 1).toLong(), ChronoUnit.DAYS) + auditEventWithinRetention.principal = "test-user-retention" + auditEventWithinRetention.auditEventType = "test-type" + + auditEventNew = PersistentAuditEvent() + auditEventNew.auditEventDate = Instant.now() + auditEventNew.principal = "test-user-new" + auditEventNew.auditEventType = "test-type" + } + + @Test + <%_ if (databaseType === 'sql') { _%> + @Transactional + <%_ } _%> + fun verifyOldAuditEventsAreDeleted() { + persistenceAuditEventRepository.deleteAll() + persistenceAuditEventRepository.save(auditEventOld) + persistenceAuditEventRepository.save(auditEventWithinRetention) + persistenceAuditEventRepository.save(auditEventNew) + <% if (databaseType === 'sql') { %> + persistenceAuditEventRepository.flush() + <% } %> + auditEventService.removeOldAuditEvents() + <% if (databaseType === 'sql') { %> + persistenceAuditEventRepository.flush() + <% } %> + assertThat(persistenceAuditEventRepository.findAll().size).isEqualTo(2) + assertThat(persistenceAuditEventRepository.findByPrincipal("test-user-old")).isEmpty() + assertThat(persistenceAuditEventRepository.findByPrincipal("test-user-retention")).isNotEmpty() + assertThat(persistenceAuditEventRepository.findByPrincipal("test-user-new")).isNotEmpty() + } +} diff --git a/generators/server/templates/src/test/kotlin/package/service/UserServiceIT.kt.ejs b/generators/server/templates/src/test/kotlin/package/service/UserServiceIT.kt.ejs index 8c72f1761..7c2d058d4 100644 --- a/generators/server/templates/src/test/kotlin/package/service/UserServiceIT.kt.ejs +++ b/generators/server/templates/src/test/kotlin/package/service/UserServiceIT.kt.ejs @@ -489,7 +489,7 @@ class UserServiceIT <% if (databaseType === 'cassandra') { %>: AbstractCassandra <%_ if (databaseType === 'sql') { _%> @Transactional <%_ } _%> - fun testUserDetailsWithUSLocale() { + fun testUserDetailsWithUSLocaleUnderscore() { userDetails["locale"] = "en_US" val authentication = createMockOAuth2AuthenticationToken(userDetails) val userDTO = userService.getUserFromAuthentication(authentication) @@ -500,7 +500,7 @@ class UserServiceIT <% if (databaseType === 'cassandra') { %>: AbstractCassandra <%_ if (databaseType === 'sql') { _%> @Transactional <%_ } _%> - fun testUserDetailsWithUSLocale2() { + fun testUserDetailsWithUSLocaleDash() { userDetails["locale"] = "en-US" val authentication = createMockOAuth2AuthenticationToken(userDetails) val userDTO = userService.getUserFromAuthentication(authentication) diff --git a/generators/server/templates/src/test/kotlin/package/web/rest/AuditResourceIT.kt.ejs b/generators/server/templates/src/test/kotlin/package/web/rest/AuditResourceIT.kt.ejs index f8031c0e0..145a285da 100644 --- a/generators/server/templates/src/test/kotlin/package/web/rest/AuditResourceIT.kt.ejs +++ b/generators/server/templates/src/test/kotlin/package/web/rest/AuditResourceIT.kt.ejs @@ -22,6 +22,7 @@ import <%=packageName%>.<%= mainClass %> <%_ if (authenticationType === 'oauth2') { _%> import <%=packageName%>.config.TestSecurityConfiguration <%_ } _%> +import io.github.jhipster.config.JHipsterProperties import <%=packageName%>.config.audit.AuditEventConverter import <%=packageName%>.domain.PersistentAuditEvent import <%=packageName%>.repository.PersistenceAuditEventRepository @@ -85,6 +86,9 @@ class AuditResourceIT { @Autowired private lateinit var jacksonMessageConverter: MappingJackson2HttpMessageConverter + @Autowired + private lateinit var jhipsterProperties: JHipsterProperties + @Autowired @Qualifier("mvcConversionService") private lateinit var formattingConversionService: FormattingConversionService @@ -99,7 +103,7 @@ class AuditResourceIT { @BeforeEach fun setup() { MockitoAnnotations.initMocks(this) - val auditEventService = AuditEventService(auditEventRepository, auditEventConverter) + val auditEventService = AuditEventService(auditEventRepository, auditEventConverter, jhipsterProperties) val auditResource = AuditResource(auditEventService) this.restAuditMockMvc = MockMvcBuilders.standaloneSetup(auditResource) .setCustomArgumentResolvers(pageableArgumentResolver) diff --git a/generators/server/templates/src/test/kotlin/package/web/rest/KafkaResourceIT.kt.ejs b/generators/server/templates/src/test/kotlin/package/web/rest/KafkaResourceIT.kt.ejs index 105b8f79f..f25186e15 100644 --- a/generators/server/templates/src/test/kotlin/package/web/rest/KafkaResourceIT.kt.ejs +++ b/generators/server/templates/src/test/kotlin/package/web/rest/KafkaResourceIT.kt.ejs @@ -19,8 +19,11 @@ package <%= packageName %>.web.rest import <%= packageName %>.<%= mainClass %> +<%_ if (authenticationType === 'uaa') { _%> +import <%=packageName%>.config.SecurityBeanOverrideConfiguration +<%_ } _%> <%_ if (authenticationType === 'oauth2') { _%> -import <%=packageName%>.config.TestSecurityConfiguration; +import <%=packageName%>.config.TestSecurityConfiguration <%_ } _%> import <%= packageName %>.service.<%= upperFirstCamelCase(baseName) %>KafkaProducer import org.junit.jupiter.api.BeforeEach @@ -38,6 +41,8 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status @EmbeddedKafka <%_ if (authenticationType === 'oauth2') { _%> @SpringBootTest(classes = [<%= mainClass %>::class, TestSecurityConfiguration::class]) +<%_ } else if (authenticationType === 'uaa' && applicationType !== 'uaa') { _%> +@SpringBootTest(classes = [SecurityBeanOverrideConfiguration::class, <%= mainClass %>::class]) <%_ } else { _%> @SpringBootTest(classes = [<%= mainClass %>::class]) <%_ } _%> diff --git a/generators/server/templates/src/test/kotlin/package/web/rest/UserJWTControllerIT.kt.ejs b/generators/server/templates/src/test/kotlin/package/web/rest/UserJWTControllerIT.kt.ejs index e3385906b..49a9e8a38 100644 --- a/generators/server/templates/src/test/kotlin/package/web/rest/UserJWTControllerIT.kt.ejs +++ b/generators/server/templates/src/test/kotlin/package/web/rest/UserJWTControllerIT.kt.ejs @@ -26,6 +26,9 @@ import <%=packageName%>.<%= mainClass %> import <%=packageName%>.domain.<%= asEntity('User') %> import <%=packageName%>.repository<% if (reactive) { %>.reactive<% } %>.UserRepository <%_ } _%> +<%_ if (reactive) { _%> +import <%= packageName %>.service.AuditEventService +<%_ } _%> import <%=packageName%>.security.jwt.TokenProvider import <%=packageName%>.web.rest.errors.ExceptionTranslator import <%=packageName%>.web.rest.vm.LoginVM @@ -85,6 +88,12 @@ class UserJWTControllerIT <% if (databaseType === 'cassandra') { %>: AbstractCas @Autowired private lateinit var authenticationManager: <% if (reactive) { %>Reactive<% } %>AuthenticationManager<% if (!reactive) { %>Builder<% } %> + <%_ if (reactive) { _%> + @Autowired + private lateinit var auditEventService: AuditEventService + + <%_ } _%> + <%_ if (!skipUserManagement) { _%> @Autowired private lateinit var userRepository: UserRepository @@ -104,7 +113,7 @@ class UserJWTControllerIT <% if (databaseType === 'cassandra') { %>: AbstractCas @BeforeEach fun setup() { - val userJWTController = UserJWTController(tokenProvider, authenticationManager) + val userJWTController = UserJWTController(tokenProvider, authenticationManager<% if (reactive) { %>, auditEventService<% } %>) <%_ if (!reactive) { _%> this.mockMvc = MockMvcBuilders.standaloneSetup(userJWTController) .setControllerAdvice(exceptionTranslator) diff --git a/generators/server/templates/src/test/kotlin/package/web/rest/errors/ExceptionTranslatorIT.kt.ejs b/generators/server/templates/src/test/kotlin/package/web/rest/errors/ExceptionTranslatorIT.kt.ejs index 734487a93..4801f1673 100644 --- a/generators/server/templates/src/test/kotlin/package/web/rest/errors/ExceptionTranslatorIT.kt.ejs +++ b/generators/server/templates/src/test/kotlin/package/web/rest/errors/ExceptionTranslatorIT.kt.ejs @@ -99,7 +99,7 @@ class ExceptionTranslatorIT <% if (databaseType === 'cassandra') { %>: AbstractC .andExpect(status().isBadRequest) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("\$.message").value(ERR_VALIDATION)) - .andExpect(jsonPath("\$.fieldErrors.[0].objectName").value("testDTO")) + .andExpect(jsonPath("\$.fieldErrors.[0].objectName").value("test")) .andExpect(jsonPath("\$.fieldErrors.[0].field").value("test")) .andExpect(jsonPath("\$.fieldErrors.[0].message").value("NotNull")) } @@ -245,7 +245,7 @@ class ExceptionTranslatorIT { .expectHeader().contentType(MediaType.APPLICATION_PROBLEM_JSON) .expectBody() .jsonPath("\$.message").isEqualTo(ERR_VALIDATION) - .jsonPath("\$.fieldErrors.[0].objectName").isEqualTo("testDTO") + .jsonPath("\$.fieldErrors.[0].objectName").isEqualTo("test") .jsonPath("\$.fieldErrors.[0].field").isEqualTo("test") .jsonPath("\$.fieldErrors.[0].message").isEqualTo("NotNull") } diff --git a/generators/server/templates/src/test/kotlin/package/web/rest/errors/ExceptionTranslatorTestController.kt.ejs b/generators/server/templates/src/test/kotlin/package/web/rest/errors/ExceptionTranslatorTestController.kt.ejs index a833da83e..b2458a81f 100644 --- a/generators/server/templates/src/test/kotlin/package/web/rest/errors/ExceptionTranslatorTestController.kt.ejs +++ b/generators/server/templates/src/test/kotlin/package/web/rest/errors/ExceptionTranslatorTestController.kt.ejs @@ -44,7 +44,7 @@ class ExceptionTranslatorTestController { <%_ } _%> @PostMapping("/test/method-argument") - fun methodArgument(@Valid @RequestBody testDTO: TestDTO) = Unit + fun methodArgument(@Valid @RequestBody test<%= dtoSuffix %>: Test<%= dtoSuffix %> ) = Unit @GetMapping("/test/missing-servlet-request-part") fun missingServletRequestPartException(@RequestPart part: String) = Unit @@ -64,7 +64,7 @@ class ExceptionTranslatorTestController { @GetMapping("/test/internal-server-error") fun internalServerError(): Unit = throw RuntimeException() - class TestDTO { + class Test<%= dtoSuffix %> { @field:NotNull var test: String? = null } diff --git a/package-lock.json b/package-lock.json index ed65f20ee..d91cba866 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,18 +5,18 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "dev": true, "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "dev": true, "requires": { "chalk": "^2.0.0", @@ -44,9 +44,9 @@ "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==" }, "@sinonjs/commons": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", - "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.6.0.tgz", + "integrity": "sha512-w4/WHG7C4WWFyE5geCieFJF6MZkbW4VAriol5KlmQXpAQdxvV0p26sqNZOW6Qyw6Y0l9K4g+cHvvczR2sEEpqg==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -62,14 +62,22 @@ } }, "@sinonjs/samsam": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.2.tgz", - "integrity": "sha512-ILO/rR8LfAb60Y1Yfp9vxfYAASK43NFC2mLzpvLUbCQY/Qu8YwReboseu8aheCEkyElZF2L2T9mHcR2bgdvZyA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", "dev": true, "requires": { - "@sinonjs/commons": "^1.0.2", + "@sinonjs/commons": "^1.3.0", "array-from": "^2.1.1", - "lodash": "^4.17.11" + "lodash": "^4.17.15" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + } } }, "@sinonjs/text-encoding": { @@ -78,45 +86,59 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, + "@types/concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=", + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "requires": { + "@types/node": "*" + } + }, "@types/node": { - "version": "12.0.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.10.tgz", - "integrity": "sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ==" + "version": "12.7.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.8.tgz", + "integrity": "sha512-FMdVn84tJJdV+xe+53sYiZS4R5yn1mAIxfj+DVoNiQjTYz1+OYmjwEZr1ev9nU0axXwda0QDbYl06QHanRVH3A==" }, - "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", - "dev": true + "@types/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-Jugo5V/1bS0fRhy2z8+cUAHEyWOATaz4rbyLVvcFs7+dXp5HfwpEwzF1Q11bB10ApUqHf+yTauxI0UXQDwGrbA==" }, - "acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "acorn": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", "dev": true }, "acorn-node": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.7.0.tgz", - "integrity": "sha512-XhahLSsCB6X6CJbe+uNu3Mn9sJBNFxtBN9NLgAOQovfS6Kh0lDUtmlclhjn9CvEK7A7YyRU13PXlNcpSiLI9Yw==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", "dev": true, "requires": { - "acorn": "^6.1.1", - "acorn-dynamic-import": "^4.0.0", - "acorn-walk": "^6.1.1", - "xtend": "^4.0.1" + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" } }, "acorn-walk": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.0.0.tgz", + "integrity": "sha512-7Bv1We7ZGuU79zZbb6rRqcpxo3OY+zrdtloZWoyD8fmGX+FeXRjE+iuGkZjSXLVovLzrsvMGMy0EkwA0E0umxg==", "dev": true }, "aggregate-error": { @@ -129,9 +151,9 @@ } }, "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -220,6 +242,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -301,6 +328,11 @@ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -331,11 +363,18 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" }, "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.14" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + } } }, "asynckit": { @@ -476,6 +515,11 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, + "boolean": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-1.0.0.tgz", + "integrity": "sha512-IB1lgIywn37N9Aff8CciCblVpMUflgL42vyxPUH0IvaDdIi/QwBHKv1lq/HOkATHCfa7c4MbMYJ7Bo7hGuoI+w==" + }, "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", @@ -868,6 +912,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -929,9 +978,9 @@ "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" }, "colors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" }, "colorspace": { "version": "1.1.2", @@ -995,6 +1044,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -1050,6 +1104,11 @@ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, + "core-js": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz", + "integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1202,7 +1261,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -1264,6 +1322,11 @@ "resolved": "https://registry.npmjs.org/detect-conflict/-/detect-conflict-1.0.1.tgz", "integrity": "sha1-CIZXpmqWHAUBnbfEIwiDsca0F24=" }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==" + }, "diagnostics": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", @@ -1360,22 +1423,6 @@ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, - "each-async": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/each-async/-/each-async-1.1.1.tgz", - "integrity": "sha1-3uUim98KtrogEqOV4bhpq/iBNHM=", - "requires": { - "onetime": "^1.0.0", - "set-immediate-shim": "^1.0.0" - }, - "dependencies": { - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" - } - } - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1386,12 +1433,19 @@ } }, "editions": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/editions/-/editions-2.1.3.tgz", - "integrity": "sha512-xDZyVm0A4nLgMNWVVLJvcwMjI80ShiH/27RyLiCnW1L273TcJIA25C4pwJ33AWV01OX6UriP35Xu+lH4S7HWQw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/editions/-/editions-2.2.0.tgz", + "integrity": "sha512-RYg3iEA2BDLCNVe8PUkD+ox5vAKxB9XS/mAhx1bdxGCF0CpX077C0pyTA9t5D6idCYA3avl5/XDHKPsHFrygfw==", "requires": { - "errlop": "^1.1.1", - "semver": "^5.6.0" + "errlop": "^1.1.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, "ejs": { @@ -1467,9 +1521,9 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "requires": { "once": "^1.4.0" } @@ -1490,20 +1544,19 @@ "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" }, "errlop": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/errlop/-/errlop-1.1.1.tgz", - "integrity": "sha512-WX7QjiPHhsny7/PQvrhS5VMizXXKoKCS3udaBp8gjlARdbn+XmK300eKBAAN0hGyRaTCtRpOaxK+xFVPUJ3zkw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/errlop/-/errlop-1.1.2.tgz", + "integrity": "sha512-djkRp+urJ+SmqDBd7F6LUgm4Be1TTYBxia2bhjNdFBuBDQtJDHExD2VbxR6eyst3h1TZy3qPRCdqb6FBoFttTA==", "requires": { - "editions": "^2.1.2" + "editions": "^2.1.3" } }, "error": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", - "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.0.tgz", + "integrity": "sha512-M6t3j3Vt3uDicrViMP5fLq2AeADNrCVFD8Oj4Qt2MHsX0mPYG7D5XdnEfSdRpaHQzjAJ19wu+I1mw9rQYMTAPg==", "requires": { - "string-template": "~0.2.1", - "xtend": "~4.0.0" + "string-template": "~0.2.1" } }, "error-ex": { @@ -1522,17 +1575,21 @@ } }, "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz", + "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==", "dev": true, "requires": { "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", "has": "^1.0.3", + "has-symbols": "^1.0.0", "is-callable": "^1.1.4", "is-regex": "^1.0.4", - "object-keys": "^1.0.12" + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.0.0", + "string.prototype.trimright": "^2.0.0" } }, "es-to-primitive": { @@ -1546,6 +1603,11 @@ "is-symbol": "^1.0.2" } }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" + }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -1622,9 +1684,9 @@ } }, "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { "chardet": "^0.7.0", @@ -1639,9 +1701,9 @@ "dev": true }, "inquirer": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz", - "integrity": "sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, "requires": { "ansi-escapes": "^3.2.0", @@ -1650,7 +1712,7 @@ "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.17.11", + "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rxjs": "^6.4.0", @@ -1677,9 +1739,9 @@ "dev": true }, "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -1705,6 +1767,14 @@ "dev": true, "requires": { "get-stdin": "^6.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } } }, "eslint-import-resolver-node": { @@ -1729,9 +1799,9 @@ } }, "eslint-module-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", - "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", "dev": true, "requires": { "debug": "^2.6.8", @@ -1880,9 +1950,9 @@ } }, "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "dev": true }, "espree": { @@ -1894,6 +1964,14 @@ "acorn": "^6.0.7", "acorn-jsx": "^5.0.0", "eslint-visitor-keys": "^1.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + } } }, "esprima": { @@ -1920,15 +1998,15 @@ } }, "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "execa": { @@ -2131,9 +2209,9 @@ "dev": true }, "fast-safe-stringify": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", - "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" }, "fecha": { "version": "2.3.3", @@ -2222,6 +2300,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -2250,12 +2333,23 @@ "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "flatted": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", - "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, "follow-redirects": { @@ -2322,6 +2416,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -2404,8 +2503,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -2426,9 +2524,9 @@ } }, "generator-jhipster": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/generator-jhipster/-/generator-jhipster-6.2.0.tgz", - "integrity": "sha512-anTcNyVZmu8wb2B+v8t4LMp6w4Ua2p1L3pIFnRL4uq+jUShHEjaN93Vqn7iL1IJma4iC4+ug+tKVbmUNwk1sNg==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/generator-jhipster/-/generator-jhipster-6.3.1.tgz", + "integrity": "sha512-1v3vbk5/C+vrBvEGw2pl4TfgPe2YHhr1T3ROfEjCItgbo9hBWdhcwbAZOLCvaNAc8eYN4DYz+fOoTBnuNnjipw==", "requires": { "axios": "0.19.0", "chalk": "2.4.2", @@ -2440,7 +2538,7 @@ "glob": "7.1.3", "gulp-filter": "5.1.0", "insight": "0.10.1", - "jhipster-core": "4.2.0", + "jhipster-core": "4.3.0", "js-object-pretty-print": "0.3.0", "js-yaml": "3.13.1", "lodash": "4.17.13", @@ -2453,12 +2551,13 @@ "randexp": "0.5.3", "semver": "5.6.0", "shelljs": "0.8.3", + "sync-request": "6.0.0", "tabtab": "2.2.2", "through2": "3.0.1", "uuid": "3.3.2", "yeoman-environment": "2.3.4", "yeoman-generator": "3.2.0", - "yo": "2.0.6" + "yo": "3.1.0" }, "dependencies": { "fs-extra": { @@ -2471,26 +2570,21 @@ "universalify": "^0.1.0" } }, - "graceful-fs": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", - "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" - }, "jhipster-core": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/jhipster-core/-/jhipster-core-4.2.0.tgz", - "integrity": "sha512-IcppfMsIz8+5eBU8BztQ7MXNVSjflOxVCj60ugd+3CN22pcUX+tIZ9pm9DOQW4DeD3Uu2X2aY08FPj3MKD9O8A==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jhipster-core/-/jhipster-core-4.3.0.tgz", + "integrity": "sha512-6EY28JQ84FswajMon3n6D9SwbDFYEiU4Yw4Unj2C14XUkB33FMBBs5tXO0uDky8GCCGuFp/fMrDWhYeAMf6vAg==", "requires": { "chevrotain": "4.4.0", "fs-extra": "8.1.0", - "lodash": "4.17.11", + "lodash": "4.17.15", "winston": "3.2.1" }, "dependencies": { "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" } } } @@ -2508,11 +2602,15 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" + }, "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" }, "get-stream": { "version": "4.1.0", @@ -2589,6 +2687,27 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" }, + "global-agent": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.1.tgz", + "integrity": "sha512-MjLP2o331SpSxBMBFSWxs5PaWDhjXxysHepQ/hmBCjhjw74cbO9R/IBCbaSJ4GLPKm01dRcgXBtRr7p7XZEnfg==", + "requires": { + "boolean": "^1.0.0", + "core-js": "^3.2.1", + "es6-error": "^4.1.1", + "matcher": "^2.0.0", + "roarr": "^2.14.1", + "semver": "^6.3.0", + "serialize-error": "^4.1.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, "global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -2614,6 +2733,16 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globalthis": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.0.tgz", + "integrity": "sha512-vcCAZTJ3r5Qcu5l8/2oyVdoFwxKgfYnMTR2vwWeux/NAVZK3PwcMaWkdUIn4GJbmKuRK7xcvDsLuK+CKcXyodg==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "object-keys": "^1.0.12" + } + }, "globby": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", @@ -2657,9 +2786,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" }, "grouped-queue": { "version": "0.3.3", @@ -2793,9 +2922,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==" }, "htmlparser2": { "version": "3.10.1", @@ -2810,11 +2939,37 @@ "readable-stream": "^3.1.1" } }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, "http-cache-semantics": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.14.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.19.tgz", + "integrity": "sha512-j6Sqt38ssdMKutXBUuAcmWF8QtHW1Fwz/mz4Y+Wd9mzpBiVFirjpNQf363hG5itkG+yGaD+oiLyb50HxJ36l9Q==" + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -2847,9 +3002,9 @@ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" }, "import-fresh": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", - "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -2966,6 +3121,11 @@ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -2995,9 +3155,9 @@ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" }, "is-callable": { "version": "1.1.4", @@ -3188,9 +3348,9 @@ "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" }, "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" }, "is-root": { "version": "1.0.0", @@ -3312,11 +3472,6 @@ "universalify": "^0.1.0" } }, - "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==" - }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", @@ -3652,6 +3807,21 @@ "object-visit": "^1.0.0" } }, + "matcher": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-2.0.0.tgz", + "integrity": "sha512-nlmfSlgHBFx36j/Pl/KQPbIaqE8Zf0TqmSMjsuddHDg6PMSVgmyW9HpkLs0o0M1n2GIZ/S2BZBLIww/xjhiGng==", + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + } + } + }, "mem": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", @@ -3693,6 +3863,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -3759,6 +3934,11 @@ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -3808,9 +3988,9 @@ } }, "merge2": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", - "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==" }, "micromatch": { "version": "3.1.10", @@ -4040,9 +4220,9 @@ "dev": true }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -4223,12 +4403,12 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "nise": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.0.tgz", - "integrity": "sha512-Z3sfYEkLFzFmL8KY6xnSJLRxwQwYBjOXi/24lb62ZnZiGA0JUzGGTI6TBIgfCSMIDl9Jlu8SRmHNACLTemDHww==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.2.tgz", + "integrity": "sha512-/6RhOUlicRCbE9s+94qCUsyE+pKlVJ5AhIv+jEE7ESKwnbXqulKZ1FYU+XAtHHWE9TinYvAxDUJAb912PwPoWA==", "dev": true, "requires": { - "@sinonjs/formatio": "^3.1.0", + "@sinonjs/formatio": "^3.2.1", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "lolex": "^4.1.0", @@ -4246,9 +4426,9 @@ } }, "lolex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.1.0.tgz", - "integrity": "sha512-BYxIEXiVq5lGIXeVHnsFzqa1TxN5acnKnPCdlZSpzm8viNEOhiigupA4vTQ9HEFQ6nLTQ9wQOgBknJgzUYQ9Aw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", + "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", "dev": true } } @@ -4264,9 +4444,9 @@ }, "dependencies": { "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -4391,16 +4571,16 @@ } } }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/object-values/-/object-values-1.0.0.tgz", - "integrity": "sha1-cq+DljARnluYw7AruMJ+MjcVgQU=" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", @@ -4473,10 +4653,10 @@ "mimic-fn": "^1.0.0" } }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", "requires": { "is-wsl": "^1.1.0" } @@ -4676,6 +4856,11 @@ "callsites": "^3.0.0" } }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=" + }, "parse-gitignore": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-gitignore/-/parse-gitignore-1.0.1.tgz", @@ -4902,9 +5087,9 @@ } }, "pretty-bytes": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.2.0.tgz", - "integrity": "sha512-ujANBhiUsl9AhREUDUEY1GPOharMGm8x8juS7qOHybcLi7XsKfrYQ88hSly1l2i0klXHTDYrlL8ihMCG55Dc3w==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", + "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==" }, "process-nextick-args": { "version": "2.0.1", @@ -4917,6 +5102,14 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "promise": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.0.3.tgz", + "integrity": "sha512-HeRDUL1RJiLhyA0/grn+PTShlBAcLuh/1BJGtrvjwbvRDCTLLMEz9rOGCV+R3vHY4MixIuoMEd9Yq/XvsTPcjw==", + "requires": { + "asap": "~2.0.6" + } + }, "proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -4928,9 +5121,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.33.tgz", - "integrity": "sha512-LTDP2uSrsc7XCb5lO7A8BI1qYxRe/8EqlRvMeEl6rsnYAqDOl8xHR+8lSAIVfrNaSAlTPTNOCgNjWcoUL3AZsw==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" }, "pump": { "version": "3.0.0", @@ -5201,9 +5394,9 @@ "dev": true }, "resolve": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", - "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", "requires": { "path-parse": "^1.0.6" } @@ -5248,13 +5441,33 @@ "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { "glob": "^7.1.3" } }, + "roarr": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.14.1.tgz", + "integrity": "sha512-Fhm9shQ8JhpjFnOT7bgxKR7Xcg1Tq+0/Tdy+bloB4sUxxAib4MZDMJ6AjUBRE+798l2MnhhF2JTqbqx1+/kRyQ==", + "requires": { + "boolean": "^1.0.0", + "detect-node": "^2.0.4", + "globalthis": "^1.0.0", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + } + } + }, "root-check": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/root-check/-/root-check-1.0.0.tgz", @@ -5286,9 +5499,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, "safe-regex": { "version": "1.1.0", @@ -5326,6 +5539,11 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" + }, "semver-diff": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", @@ -5347,17 +5565,20 @@ "semver": "^5.3.0" } }, + "serialize-error": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-4.1.0.tgz", + "integrity": "sha512-5j9GgyGsP9vV9Uj1S0lDCvlsd+gc2LEPVK7HHHte7IyPwOD4lVQFeaX143gx3U5AnoCi+wbcb3mvaxVysjpxEw==", + "requires": { + "type-fest": "^0.3.0" + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" - }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -5633,9 +5854,9 @@ } }, "spdx-license-ids": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", - "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "split-string": { "version": "3.1.0", @@ -5731,6 +5952,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -5769,12 +5995,32 @@ "strip-ansi": "^4.0.0" } }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" } }, "strip-ansi": { @@ -5884,6 +6130,24 @@ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" }, + "sync-request": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.0.0.tgz", + "integrity": "sha512-jGNIAlCi9iU4X3Dm4oQnNQshDD3h0/1A7r79LyqjbjUnj69sX6mShAXlhRXgImsfVKtTcnra1jfzabdZvp+Lmw==", + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "requires": { + "get-port": "^3.1.0" + } + }, "syntax-error": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", @@ -5894,13 +6158,13 @@ } }, "table": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz", - "integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { - "ajv": "^6.9.1", - "lodash": "^4.17.11", + "ajv": "^6.10.2", + "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, @@ -5911,6 +6175,12 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -6105,11 +6375,6 @@ "minimist": "^1.1.0" }, "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" - }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", @@ -6167,9 +6432,34 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, "textextensions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.4.0.tgz", - "integrity": "sha512-qftQXnX1DzpSV8EddtHIT0eDDEiBF8ywhFYR2lI9xrGtxqKN+CvLXhACeCIGbCpQfxxERbrkZEFb8cZcDKbVZA==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.5.0.tgz", + "integrity": "sha512-1IkVr355eHcomgK7fgj1Xsokturx6L5S2JRT5WcRdA6v5shk9sxWuO/w/VbpQexwkXJMQIa/j1dBi3oo7+HhcA==" + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.54", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.54.tgz", + "integrity": "sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg==" + } + } }, "through": { "version": "2.3.8", @@ -6331,6 +6621,11 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==" + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -6583,6 +6878,14 @@ "semver": "^5.0.1" } }, + "windows-release": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", + "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", + "requires": { + "execa": "^1.0.0" + } + }, "winston": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz", @@ -6622,6 +6925,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -6662,7 +6970,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { "string-width": "^1.0.1", @@ -6732,9 +7040,9 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { "version": "3.2.1", @@ -6988,9 +7296,9 @@ } }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -7079,18 +7387,17 @@ } }, "yeoman-doctor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yeoman-doctor/-/yeoman-doctor-3.0.3.tgz", - "integrity": "sha512-L/1PUIReI8cOzAWgmBY64VBCLeH2IEpgtnF3X97BUU6SraQFczeXXIzh6n5idG4jfzMfWRF1lS4zf6wdg7hAbw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yeoman-doctor/-/yeoman-doctor-4.0.0.tgz", + "integrity": "sha512-CP0fwGk5Y+jel+A0AQbyqnIFZRRpkKOeYUibiTSmlgV9PcgNFFVwn86VcUIpDLOqVjF+9v+O9FWQMo+IUcV2mA==", "requires": { "ansi-styles": "^3.2.0", "bin-version-check": "^3.0.0", "chalk": "^2.3.0", - "each-async": "^1.1.1", + "global-agent": "^2.0.0", "global-tunnel-ng": "^2.5.3", "latest-version": "^3.1.0", "log-symbols": "^2.1.0", - "object-values": "^1.0.0", "semver": "^5.0.3", "twig": "^1.10.5", "user-home": "^2.0.0" @@ -7129,9 +7436,9 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -7139,9 +7446,9 @@ } }, "inquirer": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz", - "integrity": "sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "requires": { "ansi-escapes": "^3.2.0", "chalk": "^2.4.2", @@ -7149,7 +7456,7 @@ "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.17.11", + "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rxjs": "^6.4.0", @@ -7169,9 +7476,9 @@ } }, "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "requires": { "tslib": "^1.9.0" } @@ -7246,9 +7553,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "requires": { "p-try": "^2.0.0" } @@ -7387,6 +7694,12 @@ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", "dev": true }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -7456,9 +7769,9 @@ } }, "yo": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/yo/-/yo-2.0.6.tgz", - "integrity": "sha512-1OleNumZXtE/Lo/ZDPsMXqOX8oXr8tpBXYgUGEDAONYqLX3/n3PV3BWkXI7Iwq6vhuAAYPRLinncUe30izlcSg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/yo/-/yo-3.1.0.tgz", + "integrity": "sha512-boSESRRyvfyns3DfzxF2F0LVV97wSEFbKUi1oC7RwnZTA66KZ7Bo3JjOLe7mM6IjjeI0vEZcr4BbFjrSHh8d0Q==", "requires": { "async": "^2.6.1", "chalk": "^2.4.1", @@ -7467,15 +7780,16 @@ "cross-spawn": "^6.0.5", "figures": "^2.0.0", "fullname": "^3.2.0", - "global-tunnel-ng": "^2.5.3", + "global-agent": "^2.0.0", + "global-tunnel-ng": "^2.7.1", "got": "^8.3.2", "humanize-string": "^1.0.2", "inquirer": "^6.0.0", - "insight": "0.10.1", - "lodash": "^4.17.10", + "insight": "^0.10.3", + "lodash": "^4.17.11", "meow": "^3.0.0", "npm-keyword": "^5.0.0", - "opn": "^5.3.0", + "open": "^6.3.0", "package-json": "^5.0.0", "parse-help": "^1.0.0", "read-pkg-up": "^4.0.0", @@ -7487,8 +7801,8 @@ "update-notifier": "^2.5.0", "user-home": "^2.0.0", "yeoman-character": "^1.0.0", - "yeoman-doctor": "^3.0.1", - "yeoman-environment": "^2.3.0", + "yeoman-doctor": "^4.0.0", + "yeoman-environment": "^2.4.0", "yosay": "^2.0.2" }, "dependencies": { @@ -7521,6 +7835,18 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "conf": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-1.4.0.tgz", + "integrity": "sha512-bzlVWS2THbMetHqXKB8ypsXN4DQ/1qopGwNJi1eYbpwesJcd86FBjFciCQX/YwAhp9bM7NVnPFqZ5LpV7gP0Dg==", + "requires": { + "dot-prop": "^4.1.0", + "env-paths": "^1.0.0", + "make-dir": "^1.0.0", + "pkg-up": "^2.0.0", + "write-file-atomic": "^2.3.0" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -7548,11 +7874,6 @@ "pinkie-promise": "^2.0.0" } }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" - }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -7591,9 +7912,9 @@ } }, "inquirer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", - "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "requires": { "ansi-escapes": "^3.2.0", "chalk": "^2.4.2", @@ -7610,6 +7931,22 @@ "through": "^2.3.6" } }, + "insight": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/insight/-/insight-0.10.3.tgz", + "integrity": "sha512-YOncxSN6Omh+1Oqxt+OJAvJVMDKw7l6IEG0wT2cTMGxjsTcroOGW4IR926QDzxg/uZHcFZ2cZbckDWdZhc2pZw==", + "requires": { + "async": "^2.6.2", + "chalk": "^2.4.2", + "conf": "^1.4.0", + "inquirer": "^6.3.1", + "lodash.debounce": "^4.0.8", + "os-name": "^3.1.0", + "request": "^2.88.0", + "tough-cookie": "^3.0.1", + "uuid": "^3.3.2" + } + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -7653,6 +7990,11 @@ } } }, + "macos-release": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", + "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" + }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", @@ -7696,15 +8038,24 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" }, + "os-name": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", + "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", + "requires": { + "macos-release": "^2.2.0", + "windows-release": "^3.1.0" + } + }, "p-cancelable": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "requires": { "p-try": "^2.0.0" } @@ -7859,9 +8210,9 @@ } }, "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "requires": { "tslib": "^1.9.0" } @@ -8011,6 +8362,16 @@ } } }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -8023,6 +8384,56 @@ "requires": { "prepend-http": "^2.0.0" } + }, + "yeoman-environment": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.4.0.tgz", + "integrity": "sha512-SsvoL0RNAFIX69eFxkUhwKUN2hG1UwUjxrcP+T2ytwdhqC/kHdnFOH2SXdtSN1Ju4aO4xuimmzfRoheYY88RuA==", + "requires": { + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "debug": "^3.1.0", + "diff": "^3.5.0", + "escape-string-regexp": "^1.0.2", + "globby": "^8.0.1", + "grouped-queue": "^0.3.3", + "inquirer": "^6.0.0", + "is-scoped": "^1.0.0", + "lodash": "^4.17.10", + "log-symbols": "^2.2.0", + "mem-fs": "^1.1.0", + "strip-ansi": "^4.0.0", + "text-table": "^0.2.0", + "untildify": "^3.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } } } }, diff --git a/package.json b/package.json index 5ddfc1497..22da93a9f 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "commander": "2.19.0", "didyoumean": "1.2.1", "ejs": "2.6.1", - "generator-jhipster": "6.2.0", + "generator-jhipster": "6.3.1", "glob": "7.1.3", "insight": "0.10.1", "jhipster-core": "4.2.0", diff --git a/test-integration/samples-kotlin/kotlin-webflux-mongo/.yo-rc.json b/test-integration/samples-kotlin/kotlin-webflux-mongo/.yo-rc.json new file mode 100644 index 000000000..62fd1c847 --- /dev/null +++ b/test-integration/samples-kotlin/kotlin-webflux-mongo/.yo-rc.json @@ -0,0 +1,26 @@ +{ + "generator-jhipster": { + "applicationType": "monolith", + "reactive": true, + "baseName": "travisWebflux", + "packageName": "io.github.jhipster.travis", + "packageFolder": "io/github/jhipster/travis", + "authenticationType": "jwt", + "cacheProvider": "no", + "enableHibernateCache": false, + "websocket": false, + "databaseType": "mongodb", + "devDatabaseType": "mongodb", + "prodDatabaseType": "mongodb", + "searchEngine": false, + "buildTool": "maven", + "enableTranslation": true, + "nativeLanguage": "en", + "languages": ["en", "fr"], + "testFrameworks": ["gatling"], + "serverPort": "8080", + "jhiPrefix": "jhi", + "travis": true, + "clientFramework": "angularX" + } +} \ No newline at end of file diff --git a/test-integration/scripts/10-install-jhipster-kotlin.sh b/test-integration/scripts/10-install-jhipster-kotlin.sh index b9e1500b3..cc130ed56 100755 --- a/test-integration/scripts/10-install-jhipster-kotlin.sh +++ b/test-integration/scripts/10-install-jhipster-kotlin.sh @@ -13,7 +13,7 @@ if [[ "$JHI_REPO" == *"/jhipster" ]]; then cd "$JHI_HOME" git --no-pager log -n 10 --graph --pretty='%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit - ./mvnw clean install -Dgpg.skip=true + ./mvnw -ntp clean install -DskipTests -Dmaven.javadoc.skip=true -Dgpg.skip=true elif [[ "$JHI_LIB_BRANCH" == "release" ]]; then echo "*** jhipster: use release version" @@ -32,7 +32,7 @@ else test-integration/scripts/10-replace-version-jhipster.sh - ./mvnw clean install -Dgpg.skip=true + ./mvnw -ntp clean install -DskipTests -Dmaven.javadoc.skip=true -Dgpg.skip=true ls -al ~/.m2/repository/io/github/jhipster/jhipster-framework/ ls -al ~/.m2/repository/io/github/jhipster/jhipster-dependencies/ ls -al ~/.m2/repository/io/github/jhipster/jhipster-parent/ @@ -91,6 +91,6 @@ npm ci npm link npm link generator-jhipster -if [[ "$JHI_APP" == "" || "$JHI_APP" == "ngx-default" ]]; then +if [[ "$JHI_APP" == "" || "$JHI_APP" == "ms-micro-consul" ]]; then npm test fi diff --git a/test-integration/scripts/12-generate-project-kotlin.sh b/test-integration/scripts/12-generate-project-kotlin.sh index d78fd41ea..17d7bdcb6 100755 --- a/test-integration/scripts/12-generate-project-kotlin.sh +++ b/test-integration/scripts/12-generate-project-kotlin.sh @@ -40,7 +40,7 @@ else cp -f "$JHI_SAMPLES"/"$JHI_APP"/.yo-rc.json "$JHI_FOLDER_APP"/ cd "$JHI_FOLDER_APP" npm link generator-jhipster-kotlin - jhipster --force --no-insight --skip-checks --with-entities --from-cli --blueprint kotlin + khipster --force --no-insight --skip-checks --with-entities --from-cli fi diff --git a/test/server.spec.js b/test/server.spec.js index a48021db1..18449ce2b 100644 --- a/test/server.spec.js +++ b/test/server.spec.js @@ -6,7 +6,7 @@ const getFilesForOptions = require('./utils/utils').getFilesForOptions; const expectedFiles = require('./utils/expected-files'); describe('JHipster server generator', () => { - describe('generate server', () => { + describe('generate server with ehcache', () => { before(done => { helpers .run('generator-jhipster/generators/server') @@ -68,4 +68,67 @@ describe('JHipster server generator', () => { ); }); }); + + describe('generate server with caffeine', () => { + before(done => { + helpers + .run('generator-jhipster/generators/server') + .withOptions({ + 'from-cli': true, + skipInstall: true, + blueprint: 'kotlin', + skipChecks: true, + 'skip-ktlint-format': true + }) + .withGenerators([ + [ + require('../generators/server/index.js'), // eslint-disable-line global-require + 'jhipster-kotlin:server', + path.join(__dirname, '../generators/server/index.js') + ] + ]) + .withPrompts({ + baseName: 'jhipster', + packageName: 'com.mycompany.myapp', + packageFolder: 'com/mycompany/myapp', + serviceDiscoveryType: false, + authenticationType: 'jwt', + cacheProvider: 'caffeine', + enableHibernateCache: true, + databaseType: 'sql', + devDatabaseType: 'h2Memory', + prodDatabaseType: 'mysql', + enableTranslation: true, + nativeLanguage: 'en', + languages: ['fr'], + buildTool: 'maven', + rememberMeKey: '5c37379956bd1242f5636c8cb322c2966ad81277', + serverSideOptions: [] + }) + .on('end', done); + }); + + it('creates expected files for caffeine cache configuration for server generator', () => { + assert.noFile(expectedFiles.common); + assert.file(expectedFiles.server); + assert.file(expectedFiles.jwtServer); + assert.file(expectedFiles.userManagementServer); + assert.file(expectedFiles.maven); + assert.file(expectedFiles.mysql); + assert.file(expectedFiles.hibernateTimeZoneConfig); + assert.noFile( + getFilesForOptions( + angularfiles, + { + enableTranslation: true, + serviceDiscoveryType: false, + authenticationType: 'jwt', + testFrameworks: [] + }, + null, + ['package.json'] + ) + ); + }); + }); }); diff --git a/test/utils/expected-files.js b/test/utils/expected-files.js index 1eb1ecde2..7d6aec080 100644 --- a/test/utils/expected-files.js +++ b/test/utils/expected-files.js @@ -228,6 +228,7 @@ const expectedFiles = { `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/web/rest/UserResourceIT.kt`, `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/service/UserServiceIT.kt`, `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/service/MailServiceIT.kt`, + `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/service/AuditEventServiceIT.kt`, `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/service/mapper/UserMapperIT.kt`, `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/repository/CustomAuditEventRepositoryIT.kt` ], @@ -299,7 +300,6 @@ const expectedFiles = { `${CLIENT_MAIN_SRC_DIR}app/account/activate/activate.component.ts`, `${CLIENT_MAIN_SRC_DIR}app/account/activate/activate.route.ts`, `${CLIENT_MAIN_SRC_DIR}app/account/activate/activate.service.ts`, - `${CLIENT_MAIN_SRC_DIR}app/account/index.ts`, `${CLIENT_MAIN_SRC_DIR}app/account/password-reset/finish/password-reset-finish.component.html`, `${CLIENT_MAIN_SRC_DIR}app/account/password-reset/finish/password-reset-finish.component.ts`, `${CLIENT_MAIN_SRC_DIR}app/account/password-reset/finish/password-reset-finish.route.ts`, @@ -348,7 +348,10 @@ const expectedFiles = { client: [ 'angular.json', + '.eslintrc.json', + '.eslintignore', '.huskyrc', + '.lintstagedrc.js', 'package.json', 'postcss.config.js', 'proxy.conf.json', @@ -374,7 +377,6 @@ const expectedFiles = { `${CLIENT_MAIN_SRC_DIR}app/admin/health/health.component.ts`, `${CLIENT_MAIN_SRC_DIR}app/admin/health/health.route.ts`, `${CLIENT_MAIN_SRC_DIR}app/admin/health/health.service.ts`, - `${CLIENT_MAIN_SRC_DIR}app/admin/index.ts`, `${CLIENT_MAIN_SRC_DIR}app/admin/logs/log.model.ts`, `${CLIENT_MAIN_SRC_DIR}app/admin/logs/logs.component.html`, `${CLIENT_MAIN_SRC_DIR}app/admin/logs/logs.component.ts`, @@ -399,13 +401,11 @@ const expectedFiles = { `${CLIENT_MAIN_SRC_DIR}app/home/home.scss`, `${CLIENT_MAIN_SRC_DIR}app/home/home.module.ts`, `${CLIENT_MAIN_SRC_DIR}app/home/home.route.ts`, - `${CLIENT_MAIN_SRC_DIR}app/home/index.ts`, `${CLIENT_MAIN_SRC_DIR}app/layouts/error/error.component.html`, `${CLIENT_MAIN_SRC_DIR}app/layouts/error/error.component.ts`, `${CLIENT_MAIN_SRC_DIR}app/layouts/error/error.route.ts`, `${CLIENT_MAIN_SRC_DIR}app/layouts/footer/footer.component.html`, `${CLIENT_MAIN_SRC_DIR}app/layouts/footer/footer.component.ts`, - `${CLIENT_MAIN_SRC_DIR}app/layouts/index.ts`, `${CLIENT_MAIN_SRC_DIR}app/layouts/main/main.component.html`, `${CLIENT_MAIN_SRC_DIR}app/layouts/main/main.component.ts`, `${CLIENT_MAIN_SRC_DIR}app/layouts/navbar/active-menu.directive.ts`, @@ -422,13 +422,13 @@ const expectedFiles = { `${CLIENT_MAIN_SRC_DIR}app/shared/alert/alert.component.ts`, `${CLIENT_MAIN_SRC_DIR}app/core/auth/account.service.ts`, `${CLIENT_MAIN_SRC_DIR}app/core/auth/csrf.service.ts`, + `${CLIENT_MAIN_SRC_DIR}app/core/icons/font-awesome-icons.ts`, `${CLIENT_MAIN_SRC_DIR}app/shared/auth/has-any-authority.directive.ts`, `${CLIENT_MAIN_SRC_DIR}app/core/auth/state-storage.service.ts`, `${CLIENT_MAIN_SRC_DIR}app/core/auth/user-route-access-service.ts`, `${CLIENT_MAIN_SRC_DIR}app/shared/constants/error.constants.ts`, `${CLIENT_MAIN_SRC_DIR}app/shared/constants/input.constants.ts`, `${CLIENT_MAIN_SRC_DIR}app/shared/constants/pagination.constants.ts`, - `${CLIENT_MAIN_SRC_DIR}app/shared/index.ts`, `${CLIENT_MAIN_SRC_DIR}app/shared/language/find-language-from-key.pipe.ts`, `${CLIENT_MAIN_SRC_DIR}app/core/language/language.constants.ts`, `${CLIENT_MAIN_SRC_DIR}app/core/language/language.helper.ts`, @@ -438,12 +438,10 @@ const expectedFiles = { `${CLIENT_MAIN_SRC_DIR}app/core/login/login.service.ts`, `${CLIENT_MAIN_SRC_DIR}app/shared/util/request-util.ts`, `${CLIENT_MAIN_SRC_DIR}app/shared/util/datepicker-adapter.ts`, - `${CLIENT_MAIN_SRC_DIR}app/shared/shared-common.module.ts`, `${CLIENT_MAIN_SRC_DIR}app/shared/shared-libs.module.ts`, `${CLIENT_MAIN_SRC_DIR}app/shared/shared.module.ts`, `${CLIENT_MAIN_SRC_DIR}app/core/user/account.model.ts`, `${CLIENT_MAIN_SRC_DIR}app/core/core.module.ts`, - `${CLIENT_MAIN_SRC_DIR}app/core/index.ts`, `${CLIENT_MAIN_SRC_DIR}app/vendor.ts`, `${CLIENT_MAIN_SRC_DIR}content/scss/global.scss`, `${CLIENT_MAIN_SRC_DIR}content/css/loading.css`,