@sassoftware/vi-solution-extension-angular-schematics
Version:
Schematics for SAS Visual Investigator solution extensions
217 lines (216 loc) • 10.8 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.ngAdd = ngAdd;
exports.addMobile = addMobile;
const dependencies_1 = require("@schematics/angular/utility/dependencies");
const tasks_1 = require("@angular-devkit/schematics/tasks");
const shell = require("shelljs");
const prompt = require("prompt");
const fs = require("fs");
const path = require("path");
const mobileElementsModulePath = `${process.cwd()}/projects/mobile-elements/src/app/app.module.ts`;
const mobileModulePath = `${process.cwd()}/projects/components/src/mobile-app.module.ts`;
function log(message) {
console.log(`----- ${message} -----`);
}
function executeNgCommand(command) {
return executeAndLogCommand(`npx ng ${command}`);
}
function executeAndLogCommand(command) {
log(`Executing command: ${command}`);
return shell.exec(command);
}
function ngAdd() {
return (tree, context) => {
const commandString = process.argv.join(" ");
const hasMobileFlag = commandString.includes("--mobile");
const viApiDependency = {
type: dependencies_1.NodeDependencyType.Default,
name: "@sassoftware/vi-api",
version: "latest"
};
const mobileInvestigatorDependency = {
type: dependencies_1.NodeDependencyType.Default,
name: "@sassoftware/mobile-investigator",
version: "latest"
};
(0, dependencies_1.addPackageJsonDependency)(tree, viApiDependency);
if (hasMobileFlag) {
(0, dependencies_1.addPackageJsonDependency)(tree, mobileInvestigatorDependency);
}
context.addTask(new tasks_1.NodePackageInstallTask());
return tree;
};
}
/*
A user may not have initially set up their project with mobile in mind, this command allows them to do
this retroactively. It first checks if there are some of the files existing from a previous mobile set up and prompts
to make sure they want to set up mobile. If they choose yes then there is some clean up and then the set up is done.
If a previous set up is not detected then the mobile set up continues without a prompt.
*/
function addMobile() {
return (tree) => __awaiter(this, void 0, void 0, function* () {
if (fs.existsSync(mobileElementsModulePath) || fs.existsSync(mobileModulePath)) {
yield promptForConfirmation();
executeAddMobile();
}
else {
executeAddMobile();
}
return tree;
});
}
function promptForConfirmation() {
return new Promise((resolve, reject) => {
prompt.start();
const promptSchema = {
properties: {
continueAddMobile: {
description: "It looks like this project has previously been set up for mobile development, are you sure you want to continue? (y/n)",
type: "string",
pattern: /^[YyNn]$/, // Accepts only Y or N
default: "n", // Default value is N
required: false
}
}
};
prompt.get(promptSchema, (err, result) => {
if (err) {
console.error("Error occurred while prompting for confirmation:", err);
reject(err);
}
const continueAddMobile = result.continueAddMobile.toLowerCase() === "y";
if (continueAddMobile) {
resolve();
}
else {
console.log("Operation cancelled.");
process.exit(0); // Exit the process if the user cancels
}
});
});
}
/*
This causes an error if the user wants to continue but the project is still defined in angular.json therefore
we clean it up before setting up angular. This is required when partial set ups are still existing in the project.
*/
function mobileElementsAngularJsonCleanUp() {
const angularJson = fs.readFileSync(`${process.cwd()}/angular.json`, "utf8");
const config = JSON.parse(angularJson);
if (config.projects && config.projects["mobile-elements"]) {
// Remove the "mobile-elements" object
delete config.projects["mobile-elements"];
const modifiedConfig = JSON.stringify(config, null, 2);
fs.writeFileSync(`${process.cwd()}/angular.json`, modifiedConfig, "utf8");
}
}
/*
As part of the build step a "main" property is required instead of "browser"since upgrading the
ngx-build-plus:browser builder version which is not added in the project setup and must be done
as part of the scaffold.
*/
function addPathToAngularJSONMobile() {
const alterAngularJsonLogger = createLogger("Altering angular.json file");
alterAngularJsonLogger.start();
const angularJson = fs.readFileSync(`${process.cwd()}/angular.json`, "utf8");
const config = JSON.parse(angularJson);
if (config.projects && config.projects["mobile-elements"]) {
// Add the 'main' property in architect.build.options
if (!config.projects["mobile-elements"].architect.build.options.main) {
const browserValue = config.projects["mobile-elements"].architect.build.options.browser;
config.projects["mobile-elements"].architect.build.options.main =
browserValue || "projects/elements/src/main.ts";
}
// Delete browser property if existing.
if (config.projects["mobile-elements"].architect.build.options.browser) {
delete config.projects["mobile-elements"].architect.build.options.browser;
}
const modifiedConfig = JSON.stringify(config, null, 2);
fs.writeFileSync(`${process.cwd()}/angular.json`, modifiedConfig, "utf8");
alterAngularJsonLogger.end();
}
}
/*
The main.ts file is not in the correct state for the purposes of this project after upgrading Angular
version, this function resets it to the required state.
*/
function modifyMainTypeScriptFile() {
const alterMainFileLogger = createLogger("Altering main.ts file");
alterMainFileLogger.start();
const mainFile = fs.readFileSync(path.resolve(__dirname, "../files/main.ts"), "utf-8");
fs.writeFileSync(`${process.cwd()}/projects/mobile-elements/src/main.ts`, mainFile);
alterMainFileLogger.end();
}
function executeAddMobile() {
const packageJsonPath = `${process.cwd()}/package.json`;
const pkg = require(packageJsonPath);
// If this file exists but the user has still chosen to reset mobile then we want to clear this and reset the repo
// to prevent following steps failing.
if (fs.existsSync(mobileElementsModulePath)) {
fs.rmdirSync(`${process.cwd()}/projects/mobile-elements`, { recursive: true });
}
// Clean up angular.json
mobileElementsAngularJsonCleanUp();
// Set up mobile project
executeNgCommand("g application mobile-elements --routing false --style scss");
executeNgCommand("add @angular/elements --project mobile-elements --skip-confirmation true");
executeNgCommand("add ngx-build-plus@^18.0.0 --project mobile-elements --skip-confirmation true");
// Copy across required files
const mobileComponentsAppModule = fs.readFileSync(path.resolve(__dirname, "../files/app-modules/mobile-components.app.module.ts"), "utf-8");
const mobileElementsAppModule = fs.readFileSync(path.resolve(__dirname, "../files/app-modules/mobile-elements.app.module.ts"), "utf-8");
fs.writeFileSync(`${process.cwd()}/projects/components/src/mobile-app.module.ts`, mobileComponentsAppModule);
fs.writeFileSync(`${process.cwd()}/projects/mobile-elements/src/app/app.module.ts`, mobileElementsAppModule);
// Add required mobile specific scripts to project
pkg.scripts["add-mobile"] = "ng g @sassoftware/vi-solution-extension-angular-schematics:add-mobile";
pkg.scripts["build:mobile"] =
"env-cmd ng build --configuration production --project mobile-elements --output-hashing none --single-bundle";
pkg.scripts["watch:mobile"] =
"env-cmd ng build --configuration production --project mobile-elements --output-hashing none --single-bundle --watch --plugin @sassoftware/vi-solution-extension-upload/src/upload-bundle.ngx-plugin";
pkg.scripts["watch:mobile-debug"] =
"env-cmd ng build --configuration development --project mobile-elements --output-hashing none --single-bundle --watch --plugin @sassoftware/vi-solution-extension-upload/src/upload-bundle.ngx-plugin";
pkg.scripts["create:solution-control-mobile"] =
"env-cmd ng g @sassoftware/vi-solution-extension-angular-schematics:mwc --project components";
fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2));
const filePath = path.resolve(__dirname, `${process.cwd()}/.env`);
const lineToAppend = `\nSMI_BUNDLE_PATH=./dist/mobile-elements/main.js\n`;
const fileContent = fs.readFileSync(filePath, "utf-8");
// Check if the line already exists
if (!fileContent.includes("SMI_BUNDLE_PATH=./dist/mobile-elements/main.js")) {
// Append the line to the file
fs.appendFileSync(filePath, lineToAppend, "utf-8");
console.log("Line appended successfully.");
}
// Remove unused files in app directory
shell.rm("./projects/mobile-elements/src/app/app.component.*");
shell.rm("./projects/mobile-elements/src/app/app.config.*");
// Install mobile types package
executeAndLogCommand("npm i --save @sassoftware/mobile-investigator");
addPathToAngularJSONMobile();
modifyMainTypeScriptFile();
return (tree, context) => {
const mobileInvestigatorDependency = {
type: dependencies_1.NodeDependencyType.Default,
name: "@sassoftware/mobile-investigator",
version: "latest"
};
(0, dependencies_1.addPackageJsonDependency)(tree, mobileInvestigatorDependency);
context.addTask(new tasks_1.NodePackageInstallTask());
return tree;
};
}
function createLogger(message) {
return {
start: () => log(`Start: ${message}.`),
end: () => log(`End: ${message}.`)
};
}
//# sourceMappingURL=index.js.map