diff --git a/boilerplate/app/modules/entities/entities-screen.js b/boilerplate/app/modules/entities/entities-screen.js
index 339077ef7..f150a763b 100644
--- a/boilerplate/app/modules/entities/entities-screen.js
+++ b/boilerplate/app/modules/entities/entities-screen.js
@@ -2,9 +2,10 @@ import React from 'react'
import { ScrollView, Text } from 'react-native'
import { connect } from 'react-redux'
// Styles
-/*eslint-disable no-unused-vars*/
+/* eslint-disable no-unused-vars */
import RoundedButton from '../../shared/components/rounded-button/rounded-button'
import {
+ loginScreen,
// ignite-jhipster-entity-screen-import-needle
} from '../../navigation/layouts'
/* eslint-enable */
diff --git a/package-lock.json b/package-lock.json
index d7c604800..b2e2db59c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6468,6 +6468,11 @@
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
"dev": true
},
+ "prettier": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz",
+ "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw=="
+ },
"pretty-format": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz",
diff --git a/package.json b/package.json
index b6bd36948..ce434f2a0 100644
--- a/package.json
+++ b/package.json
@@ -60,6 +60,7 @@
"insight": "0.10.3",
"jhipster-core": "4.3.0",
"pluralize": "8.0.0",
+ "prettier": "1.18.2",
"ramda": "0.26.1",
"rimraf": "3.0.0",
"semver": "6.3.0"
diff --git a/src/boilerplate/files.js b/src/boilerplate/files.js
index 293246136..2ed816d74 100644
--- a/src/boilerplate/files.js
+++ b/src/boilerplate/files.js
@@ -5,8 +5,9 @@ const semver = require('semver')
* The files portion of the entity generator
*/
module.exports = async function (context, props, jhipsterConfig) {
- const { filesystem, ignite, print, strings } = context
+ const { filesystem, print, strings } = context
const { camelCase, upperFirst } = strings
+ const { copyBatch } = require('../lib/copy-batch')
const spinner = print.spin(`using the ${print.colors.blue('JHipster')} boilerplate`).succeed()
const { patchInFile } = require('../lib/patch-in-file')
@@ -169,7 +170,7 @@ module.exports = async function (context, props, jhipsterConfig) {
}
]
- await ignite.copyBatch(context, templates, props, {
+ await copyBatch(context, templates, props, {
quiet: true,
directory: `${__dirname}/../../boilerplate`
})
@@ -184,7 +185,7 @@ module.exports = async function (context, props, jhipsterConfig) {
if (!isMonolith) {
oauth2Files.push({ template: 'OAuth2SsoConfiguration.java.ejs', target: `${jhipsterPathPrefix}${props.jhipsterDirectory}/src/main/java/${props.packageFolder}/config/OAuth2SsoConfiguration.java` })
}
- await ignite.copyBatch(context, oauth2Files, props, {
+ await copyBatch(context, oauth2Files, props, {
quiet: true,
directory: `${__dirname}/../../templates/jhipster/oauth2`
})
@@ -213,7 +214,6 @@ module.exports = async function (context, props, jhipsterConfig) {
await patchInFile(context, 'android/app/build.gradle', {
before: 'applicationId',
insert: androidAuthRedirectContent,
- match: androidAuthRedirectContent
})
} else {
// remove OAuth2 files if not enabled
@@ -230,7 +230,6 @@ module.exports = async function (context, props, jhipsterConfig) {
await patchInFile(context, 'app/shared/reducers/index.js', {
before: 'ignite-jhipster-redux-store-import-needle',
insert: ` chat: require('../../modules/chat/chat.reducer').reducer,`,
- match: ` chat: require('../../modules/chat/chat.reducer').reducer,`
})
// TODO CHAT SCREEN
diff --git a/src/boilerplate/index.js b/src/boilerplate/index.js
index be1b46756..f3ca7124d 100644
--- a/src/boilerplate/index.js
+++ b/src/boilerplate/index.js
@@ -254,6 +254,12 @@ async function install (context) {
await importEntityJdl.run(context)
}
+ // run prettier to pass lint on generation
+ spinner.text = `▸ running prettier on generated code`
+ spinner.start()
+ // install any missing dependencies
+ await system.run(`${useNpm ? 'npm' : 'yarn'} run prettier`, { stdio: 'ignore' })
+
const perfDuration = parseInt(((new Date()).getTime() - perfStart) / 10) / 100
spinner.succeed(`ignited ${print.colors.yellow(name)} in ${perfDuration}s`)
diff --git a/src/entity/files.js b/src/entity/files.js
index a5ff7fab3..cf80aac77 100644
--- a/src/entity/files.js
+++ b/src/entity/files.js
@@ -1,13 +1,15 @@
/**
* The files portion of the entity generator
*/
+
module.exports = async function (generator, igniteContext) {
const semver = require('semver')
const pluralize = require('pluralize')
const fs = require('fs-extra')
const { patchInFile } = require('../lib/patch-in-file')
const { getEntityFormField, getRelationshipFormField } = require('../lib/entity-helpers')
- const { ignite, strings, parameters, print } = igniteContext
+ const { copyBatch } = require('../lib/copy-batch')
+ const { strings, parameters, print } = igniteContext
const { kebabCase, pascalCase, snakeCase, upperCase, camelCase, isBlank, upperFirst } = strings // eslint-disable-line
const name = generator.name
@@ -100,34 +102,33 @@ module.exports = async function (generator, igniteContext) {
// REDUX AND SAGA SECTION
let apiMethods = `
- const get${props.name} = (${camelCase(props.name)}Id) => api.get('${props.microservicePath}api/${kebabCase(props.pluralName)}/' + ${camelCase(props.name)}Id)
- const get${props.pluralName} = (options) => api.get('${props.microservicePath}api/${kebabCase(props.pluralName)}', options)
- const create${props.name} = (${camelCase(props.name)}) => api.post('${props.microservicePath}api/${kebabCase(props.pluralName)}', ${camelCase(props.name)})
- const update${props.name} = (${camelCase(props.name)}) => api.put('${props.microservicePath}api/${kebabCase(props.pluralName)}', ${camelCase(props.name)})
- const delete${props.name} = (${camelCase(props.name)}Id) => api.delete('${props.microservicePath}api/${kebabCase(props.pluralName)}/' + ${camelCase(props.name)}Id)`
+ const get${props.name} = ${camelCase(props.name)}Id => api.get('${props.microservicePath}api/${kebabCase(props.pluralName)}/' + ${camelCase(props.name)}Id)
+ const get${props.pluralName} = options => api.get('${props.microservicePath}api/${kebabCase(props.pluralName)}', options)
+ const create${props.name} = ${camelCase(props.name)} => api.post('${props.microservicePath}api/${kebabCase(props.pluralName)}', ${camelCase(props.name)})
+ const update${props.name} = ${camelCase(props.name)} => api.put('${props.microservicePath}api/${kebabCase(props.pluralName)}', ${camelCase(props.name)})
+ const delete${props.name} = ${camelCase(props.name)}Id => api.delete('${props.microservicePath}api/${kebabCase(props.pluralName)}/' + ${camelCase(props.name)}Id)`
- let fixtureApiMethods = `
- update${props.name}: (${camelCase(props.name)}) => {
+ let fixtureApiMethods = ` update${props.name}: ${camelCase(props.name)} => {
return {
ok: true,
- data: require('../../shared/fixtures/update-${props.name.toLowerCase()}.json')
+ data: require('../../shared/fixtures/update-${props.name.toLowerCase()}.json'),
}
},
get${props.pluralName}: () => {
return {
ok: true,
- data: require('../../shared/fixtures/get-${props.pluralName.toLowerCase()}.json')
+ data: require('../../shared/fixtures/get-${props.pluralName.toLowerCase()}.json'),
}
},
- get${props.name}: (${camelCase(props.name)}Id) => {
+ get${props.name}: ${camelCase(props.name)}Id => {
return {
ok: true,
- data: require('../../shared/fixtures/get-${props.name.toLowerCase()}.json')
+ data: require('../../shared/fixtures/get-${props.name.toLowerCase()}.json'),
}
},
- delete${props.name}: (${camelCase(props.name)}Id) => {
+ delete${props.name}: ${camelCase(props.name)}Id => {
return {
- ok: true
+ ok: true,
}
},`
@@ -167,42 +168,35 @@ module.exports = async function (generator, igniteContext) {
await patchInFile(igniteContext, apiFilePath, {
before: 'ignite-jhipster-api-method-needle',
insert: apiMethods,
- match: apiMethods
})
await patchInFile(igniteContext, apiFilePath, {
before: 'ignite-jhipster-api-export-needle',
insert: apiMethodsExport,
- match: apiMethodsExport
})
await patchInFile(igniteContext, fixtureApiFilePath, {
before: 'ignite-jhipster-api-fixture-needle',
insert: fixtureApiMethods,
- match: fixtureApiMethods
})
// import redux in redux/index.js
await patchInFile(igniteContext, reduxIndexFilePath, {
before: 'ignite-jhipster-redux-store-import-needle',
insert: ` ${camelCase(props.pluralName)}: require('../../modules/entities/${props.kebabName}/${props.kebabName}.reducer').reducer,`,
- match: ` ${camelCase(props.pluralName)}: require('../../modules/entities/${props.kebabName}/${props.kebabName}.reducer').reducer,`
})
// import saga/redux in sagas/index.js
await patchInFile(igniteContext, sagaIndexFilePath, {
before: 'ignite-jhipster-saga-redux-import-needle',
insert: `import { ${props.name}Types } from '../../modules/entities/${props.kebabName}/${props.kebabName}.reducer'`,
- match: `import { ${props.name}Types } from '../../modules/entities/${props.kebabName}/${props.kebabName}.reducer'`
})
await patchInFile(igniteContext, sagaIndexFilePath, {
before: 'ignite-jhipster-saga-method-import-needle',
insert: `import { get${props.name}, get${props.pluralName}, update${props.name}, delete${props.name}${props.searchEngine ? `, search${props.pluralName}` : ''} } from '../../modules/entities/${props.kebabName}/${props.kebabName}.sagas'`,
- match: `import { get${props.name}, get${props.pluralName}, update${props.name}, delete${props.name}${props.searchEngine ? `, search${props.pluralName}` : ''} } from '../../modules/entities/${props.kebabName}/${props.kebabName}.sagas'`
})
await patchInFile(igniteContext, sagaIndexFilePath, {
before: 'ignite-jhipster-saga-redux-connect-needle',
insert: sagaConnections,
- match: sagaConnections
})
const entityFiles = [
@@ -277,7 +271,7 @@ module.exports = async function (generator, igniteContext) {
})
}
- await ignite.copyBatch(igniteContext, entityFiles, props, {
+ await copyBatch(igniteContext, entityFiles, props, {
directory: `${__dirname}/../../templates/entity`
})
@@ -286,19 +280,16 @@ module.exports = async function (generator, igniteContext) {
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-import-needle',
insert: navigationImport,
- match: navigationImport
})
const navigationImportDetail = `import ${props.name}EntityDetailScreen from '../modules/entities/${props.kebabName}/${props.kebabName}-entity-detail-screen'`
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-import-needle',
insert: navigationImportDetail,
- match: navigationImportDetail
})
const navigationImportEdit = `import ${props.name}EntityEditScreen from '../modules/entities/${props.kebabName}/${props.kebabName}-entity-edit-screen'`
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-import-needle',
- insert: navigationImportEdit,
- match: navigationImportEdit
+ insert: navigationImportEdit
})
const upperSnakeCaseName = upperCase(snakeCase(props.name + 'EntityScreen')).replace(/ /g, '_')
const upperSnakeCaseNameEdit = upperCase(snakeCase(props.name + 'EntityEditScreen')).replace(/ /g, '_')
@@ -308,124 +299,116 @@ module.exports = async function (generator, igniteContext) {
const navigationDeclaration = `export const ${upperSnakeCaseName} = 'nav.${props.name}EntityScreen'`
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-declaration-needle',
- insert: navigationDeclaration,
- match: navigationDeclaration
+ insert: navigationDeclaration
})
const navigationDeclarationDetail = `export const ${upperSnakeCaseNameDetail} = 'nav.${props.name}EntityDetailScreen'`
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-declaration-needle',
- insert: navigationDeclarationDetail,
- match: navigationDeclarationDetail
+ insert: navigationDeclarationDetail
})
const navigationDeclarationEdit = `export const ${upperSnakeCaseNameEdit} = 'nav.${props.name}EntityEditScreen'`
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-declaration-needle',
- insert: navigationDeclarationEdit,
- match: navigationDeclarationEdit
+ insert: navigationDeclarationEdit
})
// add entity screens to navigation
const navigationScreen = ` Navigation.registerComponentWithRedux(${upperSnakeCaseName}, () => ${props.name}EntityScreen, Provider, store)`
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-registration-needle',
- insert: navigationScreen,
- match: navigationScreen
+ insert: navigationScreen
})
const navigationScreenDetail = ` Navigation.registerComponentWithRedux(${upperSnakeCaseNameDetail}, () => ${props.name}EntityDetailScreen, Provider, store)`
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-registration-needle',
- insert: navigationScreenDetail,
- match: navigationScreenDetail
+ insert: navigationScreenDetail
})
const navigationScreenEdit = ` Navigation.registerComponentWithRedux(${upperSnakeCaseNameEdit}, () => ${props.name}EntityEditScreen, Provider, store)`
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-registration-needle',
- insert: navigationScreenEdit,
- match: navigationScreenEdit
+ insert: navigationScreenEdit
})
const navigationMethodMain = `
-export const ${camelCase(props.name)}EntityScreen = () => Navigation.push('center', {
- component: {
- name: ${upperSnakeCaseName},
- options: {
- topBar: {
- title: {
- text: '${props.pluralName}',
- color: Colors.snow
+export const ${camelCase(props.name)}EntityScreen = () =>
+ Navigation.push('center', {
+ component: {
+ name: ${upperSnakeCaseName},
+ options: {
+ topBar: {
+ title: {
+ text: '${props.pluralName}',
+ color: Colors.snow,
+ },
+ rightButtons: [
+ {
+ id: 'createButton',
+ text: 'Create',
+ color: Colors.snow,
+ },
+ ],
},
- rightButtons: [
- {
- id: 'createButton',
- text: 'Create',
- color: Colors.snow
- }
- ]
- }
- }
- }
-})`
+ },
+ },
+ })`
const navigationMethodDetail = `
-export const ${camelCase(props.name)}EntityDetailScreen = (data) => Navigation.push('center', {
- component: {
- name: ${upperSnakeCaseNameDetail},
- passProps: {
- data
+export const ${camelCase(props.name)}EntityDetailScreen = data =>
+ Navigation.push('center', {
+ component: {
+ name: ${upperSnakeCaseNameDetail},
+ passProps: {
+ data,
+ },
+ options: {
+ topBar: {
+ title: {
+ text: '${props.pluralName}',
+ color: Colors.snow,
+ },
+ },
+ },
},
- options: {
- topBar: {
- title: {
- text: '${props.pluralName}',
- color: Colors.snow
- }
- }
- }
- }
-})`
+ })`
const navigationMethodEdit = `
-export const ${camelCase(props.name)}EntityEditScreen = (data) => Navigation.push('center', {
- component: {
- name: ${upperSnakeCaseNameEdit},
- passProps: {
- data
+export const ${camelCase(props.name)}EntityEditScreen = data =>
+ Navigation.push('center', {
+ component: {
+ name: ${upperSnakeCaseNameEdit},
+ passProps: {
+ data,
+ },
+ options: {
+ topBar: {
+ title: {
+ text: '${props.pluralName}',
+ color: Colors.snow,
+ },
+ },
+ },
},
- options: {
- topBar: {
- title: {
- text: '${props.pluralName}',
- color: Colors.snow
- }
- }
- }
- }
-})`
+ })`
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-method-needle',
- insert: navigationMethodMain,
- match: navigationMethodMain
+ insert: navigationMethodMain
})
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-method-needle',
- insert: navigationMethodEdit,
- match: navigationMethodEdit
+ insert: navigationMethodEdit
})
await patchInFile(igniteContext, navigationRouterFilePath, {
before: 'ignite-jhipster-navigation-method-needle',
- insert: navigationMethodDetail,
- match: navigationMethodDetail
+ insert: navigationMethodDetail
})
// add entity to entities screen
- const entityScreenButton = ` `
+ const entityScreenButton = ` `
await patchInFile(igniteContext, entityScreenFilePath, {
before: 'ignite-jhipster-entity-screen-needle',
- insert: entityScreenButton,
- match: entityScreenButton
+ insert: entityScreenButton
})
const entityScreenImport = ` ${camelCase(props.name)}EntityScreen,`
await patchInFile(igniteContext, entityScreenFilePath, {
before: 'ignite-jhipster-entity-screen-import-needle',
- insert: entityScreenImport,
- match: entityScreenImport
+ insert: entityScreenImport
})
}
diff --git a/src/lib/copy-batch.js b/src/lib/copy-batch.js
new file mode 100644
index 000000000..c392f60d7
--- /dev/null
+++ b/src/lib/copy-batch.js
@@ -0,0 +1,21 @@
+// wrapped version of ignite's copyBatch to run prettier on files before generation
+const { prettierTransformBatch } = require('./prettier-transform')
+const copyBatch = async (context, files, props, copyBatchOptions) => {
+ const { ignite, print } = context
+ try {
+ await ignite.copyBatch(context, files, props, copyBatchOptions)
+ } catch (e) {
+ print.warning('Could not copy files, error:')
+ print.error(e)
+ }
+ try {
+ await prettierTransformBatch(files)
+ } catch (e) {
+ print.warning('Could not run prettier on files, error:')
+ print.error(e)
+ }
+}
+
+module.exports = {
+ copyBatch,
+}
diff --git a/src/lib/prettier-transform.js b/src/lib/prettier-transform.js
new file mode 100644
index 000000000..8397940f1
--- /dev/null
+++ b/src/lib/prettier-transform.js
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+// transforms a file via prettier as it's generated
+// modified from https://github.com/jhipster/generator-jhipster/blob/6871b52b2336709fde83fb0dccf7165b1e227fd2/generators/generator-transforms.js
+const prettier = require('prettier')
+const fs = require('fs')
+const defaultOptions = {
+ printWidth: 140,
+ singleQuote: true,
+ useTabs: false,
+ tabWidth: 2,
+ // js and ts rules:
+ arrowParens: 'avoid',
+ // jsx and tsx rules:
+ jsxBracketSameLine: false
+}
+const prettierTransform = async (file) => {
+ /* resolve from the projects config */
+ let options = await prettier.resolveConfig(file.target)
+ if (!options || Object.keys(options).length === 0) {
+ options = defaultOptions
+ }
+ const str = fs.readFileSync(file.target, 'utf8')
+ // for better errors
+ options.filepath = file.target
+ const data = prettier.format(str, options)
+ fs.writeFileSync(file.target, Buffer.from(data))
+}
+
+const prettierTransformBatch = async (files) => {
+ await Promise.all(files.map(file => prettierTransform(file)))
+}
+
+module.exports = {
+ prettierTransform,
+ prettierTransformBatch
+}
diff --git a/src/lib/react-native-navigation.js b/src/lib/react-native-navigation.js
index 6d26fb6c9..811bed49b 100644
--- a/src/lib/react-native-navigation.js
+++ b/src/lib/react-native-navigation.js
@@ -1,4 +1,5 @@
const { patchInFile } = require('../lib/patch-in-file')
+const { copyBatch } = require('../lib/copy-batch')
const patchReactNativeNavigation = async (context = {}, props) => {
// REACT_NATIVE_NAVIGATION_VERSION
@@ -22,7 +23,7 @@ const patchReactNativeNavigation = async (context = {}, props) => {
if (props.authType === 'oauth2') {
navigationFiles.push({ template: 'AppDelegate.h.ejs', target: `ios/${props.name}/AppDelegate.h` })
}
- await ignite.copyBatch(context, navigationFiles, props, {
+ await copyBatch(context, navigationFiles, props, {
quiet: true,
directory: `${__dirname}/../../templates/react-native-navigation/`
})
@@ -31,7 +32,7 @@ const patchReactNativeNavigation = async (context = {}, props) => {
const rnnPatch = [
{ template: 'patches/tcomb-form-native+0.6.20.patch', target: `patches/tcomb-form-native+0.6.20.patch` }
]
- await ignite.copyBatch(context, rnnPatch, props, {
+ await copyBatch(context, rnnPatch, props, {
quiet: true,
directory: `${__dirname}/../../boilerplate`
})