@verizonconnect/ngx-form-generator
Version:
Generates an Angular ReactiveForm from a Swagger or OpenAPI definition
104 lines (102 loc) • 3.73 kB
JavaScript
;
/**
* @license
* Licensed under the MIT License, (“the License”); you may not use this
* file except in compliance with the License.
*
* Copyright (c) 2020 Verizon
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadSpec = exports.saveFile = exports.makeForm = exports.makeFileName = exports.resetRules = exports.addRule = void 0;
const ts_morph_1 = require("ts-morph");
const prettier_1 = __importDefault(require("prettier"));
const camelcase_1 = __importDefault(require("camelcase"));
const rules_1 = require("./rules");
const swagger_parser_1 = __importDefault(require("@apidevtools/swagger-parser"));
const DEFAULT_RULES = [rules_1.requiredRule, rules_1.patternRule, rules_1.minLengthRule, rules_1.maxLengthRule, rules_1.emailRule, rules_1.minimumRule, rules_1.maximumRule];
let rules = [...DEFAULT_RULES];
function addRule(rule) {
rules.push(rule);
}
exports.addRule = addRule;
function resetRules() {
rules = [...DEFAULT_RULES];
}
exports.resetRules = resetRules;
function makeFileName(swagger) {
if (swagger.info && swagger.info.title) {
return `${camelcase_1.default(swagger.info.title)}.ts`;
}
}
exports.makeFileName = makeFileName;
function makeFieldRules(fieldName, definition) {
return rules
.map(rule => rule(fieldName, definition))
.filter(item => item != '')
.join();
}
function makeField(fieldName, definition) {
return `${fieldName}: new FormControl(null, [${makeFieldRules(fieldName, definition)}])`;
}
function makeFieldsBody(definition) {
if ('allOf' in definition) {
const definitionKeys = Object.keys(definition.allOf);
const allOfFieldsBody = definitionKeys
.map(key => makeFieldsBody(definition.allOf[key]))
.reduce((acc, val) => acc.concat(val), []);
return allOfFieldsBody;
}
const fields = Object.keys(definition.properties);
const fieldsBody = fields.map(fieldName => makeField(fieldName, definition)).filter(item => item !== '');
return fieldsBody;
}
function makeDefinition(definitionName, definition) {
const fieldsBody = makeFieldsBody(definition);
return `
export const ${camelcase_1.default(definitionName)}Form = new FormGroup({
${fieldsBody}
});
`;
}
function makeHeader(body) {
return `import { FormGroup, FormControl, Validators } from '@angular/forms';
${body}`;
}
function makeForm(spec) {
var _a;
let definitions;
if ('definitions' in spec) {
definitions = spec.definitions;
}
else if ('components' in spec) {
definitions = (_a = spec.components) === null || _a === void 0 ? void 0 : _a.schemas;
}
else {
throw new Error('Cannot find schemas/definitions');
}
if (!definitions) {
throw new Error('Cannot find schemas/definitions');
}
const definitionKeys = Object.keys(definitions);
const forms = definitionKeys
.map(key => makeDefinition(key, definitions[key]))
.filter(item => item != '')
.join('');
const file = makeHeader(forms);
return prettier_1.default.format(file, { parser: 'typescript', singleQuote: true });
}
exports.makeForm = makeForm;
async function saveFile(file, fileName) {
const project = new ts_morph_1.Project();
project.createSourceFile(fileName, file, { overwrite: true });
return project.save();
}
exports.saveFile = saveFile;
async function loadSpec(fileOrUrlPath) {
const parser = new swagger_parser_1.default();
return parser.dereference(fileOrUrlPath);
}
exports.loadSpec = loadSpec;