Option to generate index file (#174)

This commit is contained in:
Kononnable 2019-12-24 10:40:36 +01:00
parent 57c6c307b0
commit dc4208ad0f
5 changed files with 123 additions and 7 deletions

View File

@ -18,6 +18,7 @@ export default interface IGenerationOptions {
relationIds: boolean;
strictMode: "none" | "?" | "!";
skipSchema: boolean;
indexFile: boolean;
}
export function getDefaultGenerationOptions(): IGenerationOptions {
const generationOptions: IGenerationOptions = {
@ -34,7 +35,8 @@ export function getDefaultGenerationOptions(): IGenerationOptions {
customNamingStrategyPath: "",
relationIds: false,
strictMode: "none",
skipSchema: false
skipSchema: false,
indexFile: false
};
return generationOptions;
}

View File

@ -14,8 +14,7 @@ export default function modelGenerationPhase(
databaseModel: Entity[]
): void {
createHandlebarsHelpers(generationOptions);
const templatePath = path.resolve(__dirname, "templates", "entity.mst");
const template = fs.readFileSync(templatePath, "UTF-8");
const resultPath = generationOptions.resultsPath;
if (!fs.existsSync(resultPath)) {
fs.mkdirSync(resultPath);
@ -29,7 +28,24 @@ export default function modelGenerationPhase(
fs.mkdirSync(entitiesPath);
}
}
const compliedTemplate = Handlebars.compile(template, {
if (generationOptions.indexFile) {
createIndexFile(databaseModel, generationOptions, entitiesPath);
}
generateModels(databaseModel, generationOptions, entitiesPath);
}
function generateModels(
databaseModel: Entity[],
generationOptions: IGenerationOptions,
entitiesPath: string
) {
const entityTemplatePath = path.resolve(
__dirname,
"templates",
"entity.mst"
);
const entityTemplate = fs.readFileSync(entityTemplatePath, "UTF-8");
const entityCompliedTemplate = Handlebars.compile(entityTemplate, {
noEscape: true
});
databaseModel.forEach(element => {
@ -54,7 +70,7 @@ export default function modelGenerationPhase(
entitiesPath,
`${casedFileName}.ts`
);
const rendered = compliedTemplate(element);
const rendered = entityCompliedTemplate(element);
const withImportStatements = removeUnusedImports(rendered);
const formatted = Prettier.format(withImportStatements, {
parser: "typescript"
@ -65,6 +81,41 @@ export default function modelGenerationPhase(
});
});
}
function createIndexFile(
databaseModel: Entity[],
generationOptions: IGenerationOptions,
entitiesPath: string
) {
const templatePath = path.resolve(__dirname, "templates", "index.mst");
const template = fs.readFileSync(templatePath, "UTF-8");
const compliedTemplate = Handlebars.compile(template, {
noEscape: true
});
const rendered = compliedTemplate({ entities: databaseModel });
const formatted = Prettier.format(rendered, {
parser: "typescript"
});
let fileName = "index";
switch (generationOptions.convertCaseFile) {
case "camel":
fileName = changeCase.camelCase(fileName);
break;
case "param":
fileName = changeCase.paramCase(fileName);
break;
case "pascal":
fileName = changeCase.pascalCase(fileName);
break;
default:
}
const resultFilePath = path.resolve(entitiesPath, `${fileName}.ts`);
fs.writeFileSync(resultFilePath, formatted, {
encoding: "UTF-8",
flag: "w"
});
}
function removeUnusedImports(rendered: string) {
const openBracketIndex = rendered.indexOf("{") + 1;
const closeBracketIndex = rendered.indexOf("}");

View File

@ -255,6 +255,11 @@ function checkYargsParameters(options: options): options {
choices: ["none", "?", "!"],
default: options.generationOptions.strictMode,
describe: "Mark fields as optional(?) or non-null(!)"
},
index: {
boolean: true,
default: options.generationOptions.indexFile,
describe: "Generate index file"
}
});
@ -272,6 +277,7 @@ function checkYargsParameters(options: options): options {
: standardSchema;
options.connectionOptions.ssl = argv.ssl;
options.connectionOptions.user = argv.u || standardUser;
options.connectionOptions.skipTables = argv.skipTables.split(",");
options.generationOptions.activeRecord = argv.a;
options.generationOptions.generateConstructor = argv.generateConstructor;
options.generationOptions.convertCaseEntity = argv.ce as IGenerationOptions["convertCaseEntity"];
@ -286,7 +292,7 @@ function checkYargsParameters(options: options): options {
options.generationOptions.resultsPath = argv.o;
options.generationOptions.pluralizeNames = !argv.disablePluralization;
options.generationOptions.strictMode = argv.strictMode as IGenerationOptions["strictMode"];
options.connectionOptions.skipTables = argv.skipTables.split(",");
options.generationOptions.indexFile = argv.index;
return options;
}
@ -499,9 +505,14 @@ async function useInquirer(options: options): Promise<options> {
},
{
name:
"Pluralize OneToMany, ManyToMany relation names.",
"Pluralize OneToMany, ManyToMany relation names",
value: "pluralize",
checked: options.generationOptions.pluralizeNames
},
{
name: "Generate index file",
value: "index",
checked: options.generationOptions.indexFile
}
],
message: "Available customizations",
@ -555,6 +566,7 @@ async function useInquirer(options: options): Promise<options> {
options.generationOptions.generateConstructor = customizations.includes(
"constructor"
);
options.generationOptions.indexFile = customizations.includes("index");
if (customizations.includes("namingStrategy")) {
const namingStrategyPath = (

3
src/templates/index.mst Normal file
View File

@ -0,0 +1,3 @@
{{#entities~}}
export { {{toEntityName tscName}} } from './{{toFileName tscName}}'
{{/entities~}}

View File

@ -665,4 +665,52 @@ describe("Model customization phase", async () => {
compileGeneratedModel(generationOptions.resultsPath, [""]);
})
})
describe("index file generation", () => {
it("enabled", async () => {
const data = generateSampleData();
const generationOptions = generateGenerationOptions();
generationOptions.indexFile = true;
clearGenerationDir();
const customizedModel = modelCustomizationPhase(
data,
generationOptions,
{}
);
modelGenerationPhase(
getDefaultConnectionOptions(),
generationOptions,
customizedModel
);
const filesGenPath = path.resolve(resultsPath, "entities");
const indexFileContent = fs
.readFileSync(path.resolve(filesGenPath, "Index.ts"))
.toString();
expect(indexFileContent).to.contain('export { Post } from "./Post";');
expect(indexFileContent).to.contain('export { PostAuthor } from "./PostAuthor";');
compileGeneratedModel(generationOptions.resultsPath, [""]);
})
it("disabled", async () => {
const data = generateSampleData();
const generationOptions = generateGenerationOptions();
generationOptions.pluralizeNames = false;
clearGenerationDir();
const customizedModel = modelCustomizationPhase(
data,
generationOptions,
{}
);
modelGenerationPhase(
getDefaultConnectionOptions(),
generationOptions,
customizedModel
);
const filesGenPath = path.resolve(resultsPath, "entities");
expect(fs.existsSync(path.resolve(filesGenPath, "Index.ts"))).to.equal(false);
compileGeneratedModel(generationOptions.resultsPath, [""]);
})
})
});