@sassoftware/vi-solution-extension-angular-schematics
Version:
Schematics for SAS Visual Investigator solution extensions
181 lines • 8.78 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.webComponent = webComponent;
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const workspace_1 = require("@schematics/angular/utility/workspace");
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
const find_module_1 = require("@schematics/angular/utility/find-module");
const validation_1 = require("@schematics/angular/utility/validation");
const change_1 = require("@schematics/angular/utility/change");
const typescript_1 = require("typescript");
const parse_name_1 = require("@schematics/angular/utility/parse-name");
const inquirer_1 = require("inquirer");
let dataTypePromptChoices = [
{ name: "String", value: "STRING" },
{ name: "Boolean", value: "BOOLEAN" },
{ name: "Integer", value: "INTEGER" },
{ name: "Numeric", value: "NUMERIC" },
{ name: "Small Integer", value: "SMALLINT" },
{ name: "Long", value: "LONG" },
{ name: "Float", value: "FLOAT" },
{ name: "Double", value: "DOUBLE" },
{ name: "Date", value: "DATE" },
{ name: "Timestamp", value: "TIMESTAMP" },
{ name: "Timestamp with Time Zone", value: "TIMESTAMP_WITH_TIME_ZONE" },
{ name: "JSON Text", value: "JSON" },
{ name: "User Group", value: "USER_GROUP" },
{ name: "Reference Data", value: "REFERENCEDATA" }
];
// You don't have to export the function as default. You can also have more than one rule factory per file.
function webComponent(options) {
return (host) => __awaiter(this, void 0, void 0, function* () {
const workspace = yield (0, workspace_1.getWorkspace)(host);
const project = workspace.projects.get(options.project);
if (options.path === undefined && project) {
options.path = (0, workspace_1.buildDefaultPath)(project);
}
const controlTypesRequiringDataType = ["Page", "Home", "Toolbar", "MobileObjectControls"];
let initialPromptComplete = false;
const selectedDataTypes = [];
// This is prompt should be conditionally displayed on solution extension creation.
if (controlTypesRequiringDataType.includes(options.controlType)) {
while (true) {
// If user has selected every possible data type they should not
// be shown any further prompts.
if (!dataTypePromptChoices.length) {
break;
}
const shouldAddDataTypePrompt = yield inquirer_1.default.prompt([
{
type: "input",
name: "shouldAddDataType",
message: !initialPromptComplete
? "Do you want to define the data type of the control? (y/n) (default: y)"
: "Do you want to define an additional data type? (y/n) (default: n)",
default: !initialPromptComplete ? "y" : "n",
validate: function (input) {
const validInputs = ["y", "n", "Y", "N"];
if (validInputs.includes(input)) {
return true;
}
else {
return "Please enter 'y' or 'n'";
}
}
}
]);
initialPromptComplete = true;
if (shouldAddDataTypePrompt.shouldAddDataType.toLowerCase() === "y") {
const dataTypePrompt = yield inquirer_1.default.prompt([
{
type: "list",
name: "dataType",
message: "Choose the data type for the control",
choices: dataTypePromptChoices,
default: "STRING"
}
]);
selectedDataTypes.push(dataTypePrompt.dataType);
// Remove the selected data type from the choices so they cannot select
// again on next loop.
dataTypePromptChoices = dataTypePromptChoices.filter((choice) => choice.value !== dataTypePrompt.dataType);
}
else {
break;
}
}
options.dataTypes = selectedDataTypes.length
? selectedDataTypes.map((item) => `"${item}"`).join(" | ")
: undefined;
}
options.module = (0, find_module_1.findModuleFromOptions)(host, options);
const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
options.name = parsedPath.name;
options.path = parsedPath.path;
options.selector = options.selector || buildSelector(options, (project && project.prefix) || "");
options.type = "Component";
validateProvidedName(options.name);
options.sviParsedControlType = getSVIControlType(options);
(0, validation_1.validateHtmlSelector)(options.selector);
const templateSource = (0, schematics_1.apply)((0, schematics_1.url)("./files"), [
(0, schematics_1.applyTemplates)(Object.assign(Object.assign({}, core_1.strings), options)),
(0, schematics_1.move)(options.path)
]);
return (0, schematics_1.chain)([addImportToNgModule(options), (0, schematics_1.mergeWith)(templateSource)]);
});
}
function buildSelector(options, projectPrefix) {
let selector = core_1.strings.dasherize(options.name);
if (options.prefix) {
selector = `${options.prefix}-${selector}`;
}
else if (options.prefix === undefined && projectPrefix) {
selector = `${projectPrefix}-${selector}`;
}
return selector;
}
function validateProvidedName(name) {
if (name) {
(0, validation_1.validateClassName)(name);
}
else {
throw new schematics_1.SchematicsException(core_1.tags.oneLine `name can not be empty.`);
}
}
function getSVIControlType(options) {
switch (options.controlType) {
case "Home":
return "Home";
case "Toolbar":
return "ToolbarItems";
case "MobileHomepageControls":
return "MobileHomepageControls";
case "MobileObjectControls":
return "MobileObjectControls";
default:
if (options.controlType.includes("Property")) {
return "Property";
}
return "Fields";
}
}
function readIntoSourceFile(host, modulePath) {
const text = host.read(modulePath);
if (text === null) {
throw new schematics_1.SchematicsException(`File ${modulePath} does not exist.`);
}
const sourceText = text.toString("utf-8");
return (0, typescript_1.createSourceFile)(modulePath, sourceText, typescript_1.ScriptTarget.Latest, true);
}
function addImportToNgModule(options) {
return (host) => {
if (options.skipImport || !options.module) {
return host;
}
const appModulePath = options.module;
const source = readIntoSourceFile(host, appModulePath);
const componentModulePath = `/${options.path}/` + core_1.strings.dasherize(options.name) + "/" + core_1.strings.dasherize(options.name) + ".module";
const relativePath = (0, find_module_1.buildRelativePath)(appModulePath, componentModulePath);
const classifiedName = core_1.strings.classify(options.name) + "Module";
const importChanges = (0, ast_utils_1.addImportToModule)(source, appModulePath, classifiedName, relativePath);
const importRecorder = host.beginUpdate(appModulePath);
for (const change of importChanges) {
if (change instanceof change_1.InsertChange) {
importRecorder.insertLeft(change.pos, change.toAdd);
}
}
host.commitUpdate(importRecorder);
return host;
};
}
//# sourceMappingURL=index.js.map