@nstudio/schematics
Version:
Cross-platform (xplat) tools for Nx workspaces.
1,136 lines (1,131 loc) • 42.7 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const schematics_1 = require("@angular-devkit/schematics");
// import { configPath, CliConfig } from '@schematics/angular/utility/config';
const errors_1 = require("./errors");
// import * as os from 'os';
const fs = require("fs");
const name_utils_1 = require("./name-utils");
const util = require('util');
const xml2js = require('xml2js');
const stripJsonComments = require("strip-json-comments");
const tasks_1 = require("@angular-devkit/schematics/tasks");
exports.supportedPlatforms = [
"web",
"nativescript",
"ionic",
"electron",
"nest"
];
// list of all supported helpers
// TODO: add more convenient helpers (like firebase or Travis ci support files)
exports.supportedHelpers = ['imports', 'applitools'];
// list of platforms that support various sandbox flags
exports.supportedSandboxPlatforms = ['nativescript'];
let npmScope;
// selector prefix to use when generating various boilerplate for xplat support
let prefix;
// Group by app name (appname-platform) instead of the default (platform-appname)
let groupByName = false;
let isTest = false;
function getNpmScope() {
return npmScope;
}
exports.getNpmScope = getNpmScope;
function getPrefix() {
return prefix;
}
exports.getPrefix = getPrefix;
function getGroupByName() {
return groupByName;
}
exports.getGroupByName = getGroupByName;
function getAppName(options, platform) {
return groupByName ? options.name.replace(`-${platform}`, '') : options.name.replace(`${platform}-`, '');
}
exports.getAppName = getAppName;
function getFileContent(tree, path) {
const file = tree.read(path) || "";
if (!file) {
throw new schematics_1.SchematicsException(`${path} could not be read.`);
}
return file.toString("utf-8");
}
exports.getFileContent = getFileContent;
function setTest() {
isTest = true;
}
exports.setTest = setTest;
function isTesting() {
return isTest;
}
exports.isTesting = isTesting;
function jsonParse(content) {
if (content) {
// ensure comments are stripped when parsing (otherwise will fail)
return JSON.parse(stripJsonComments(content));
}
return {};
}
exports.jsonParse = jsonParse;
function serializeJson(json) {
return `${JSON.stringify(json, null, 2)}\n`;
}
exports.serializeJson = serializeJson;
function getJsonFromFile(tree, path) {
return jsonParse(getFileContent(tree, path));
}
exports.getJsonFromFile = getJsonFromFile;
function updateJsonFile(tree, path, jsonData) {
try {
// if (tree.exists(path)) {
tree.overwrite(path, JSON.stringify(jsonData, null, 2));
// }
return tree;
}
catch (err) {
// console.warn(err);
throw new schematics_1.SchematicsException(`${path}: ${err}`);
}
}
exports.updateJsonFile = updateJsonFile;
function updateFile(tree, path, content) {
try {
// if (tree.exists(path)) {
tree.overwrite(path, content);
// }
return tree;
}
catch (err) {
// console.warn(err);
throw new schematics_1.SchematicsException(`${path}: ${err}`);
}
}
exports.updateFile = updateFile;
function createOrUpdate(host, path, content) {
if (host.exists(path)) {
host.overwrite(path, content);
}
else {
host.create(path, content);
}
}
exports.createOrUpdate = createOrUpdate;
function getNxWorkspaceConfig(tree) {
const nxConfig = getJsonFromFile(tree, "nx.json"); //, 'Project must be an angular cli generated project, missing angular.json');
const hasWorkspaceDirs = tree.exists("apps") && tree.exists("libs");
// determine if Nx workspace
if (nxConfig) {
// if (ngConfig.$schema.indexOf('@nrwl/schematics') > -1 || ngConfig.$schema.indexOf('@nstudio/schematics') > -1 || hasWorkspaceDirs) {
// return ngConfig;
// }
if (nxConfig.npmScope || hasWorkspaceDirs) {
return nxConfig;
}
}
throw new schematics_1.SchematicsException("@nstudio/schematics must be used inside an Nx workspace. Create a workspace first. https://nrwl.io/nx/guide-nx-workspace");
}
exports.getNxWorkspaceConfig = getNxWorkspaceConfig;
/**
* Returns a name with the platform.
*
* @example (app, nest) => web-app or app-web
* @param name
* @param platform
*/
function getPlatformName(name, platform) {
const nameSanitized = name_utils_1.toFileName(name);
return groupByName ? `${nameSanitized}-${platform}` : `${platform}-${nameSanitized}`;
}
exports.getPlatformName = getPlatformName;
function applyAppNamingConvention(options, platform) {
return (tree, context) => {
options.name = getPlatformName(options.name, platform);
// if command line argument, make sure it's persisted to xplat settings
if (options.groupByName) {
return updatePackageForXplat(tree, null, {
groupByName: true
});
}
else {
// adjusted name, nothing else to do
return schematics_1.noop()(tree, context);
}
};
}
exports.applyAppNamingConvention = applyAppNamingConvention;
exports.copy = (tree, from, to) => {
const file = tree.get(from);
if (!file) {
throw new schematics_1.SchematicsException(`File ${from} does not exist!`);
}
tree.create(to, file.content);
};
exports.setDependency = (dependenciesMap, { name, version }) => Object.assign(dependenciesMap, { [name]: version });
function prerun(options, init) {
return (tree) => {
const nxJson = getNxWorkspaceConfig(tree);
if (nxJson) {
npmScope = nxJson.npmScope || "workspace";
}
// console.log('npmScope:', npmScope);
const packageJson = getJsonFromFile(tree, "package.json");
if (packageJson) {
prefix = "";
if (packageJson.xplat) {
// use persisted xplat settings
prefix = packageJson.xplat.prefix || npmScope; // (if not prefix, default to npmScope)
if (options) {
// ensure options are updated
options.prefix = prefix;
}
// grouping
groupByName = packageJson.xplat.groupByName || (options ? options.groupByName : false);
}
else if (options) {
groupByName = options.groupByName;
if (options.prefix) {
if (!prefix && init) {
// initializing for first time
prefix = options.prefix;
}
}
else {
// default to npmScope for prefix
options.prefix = npmScope;
}
}
// console.log('prefix:', prefix);
if (!prefix) {
if (init) {
// if no prefix was found and we're initializing, user need to specify a prefix
throw new schematics_1.SchematicsException(errors_1.errorMissingPrefix);
}
else {
// if no prefix was found and we're not initializing, user needs to generate xplat first
throw new schematics_1.SchematicsException(errors_1.errorXplat);
}
}
}
return tree;
};
}
exports.prerun = prerun;
function sanitizeCommaDelimitedArg(input) {
if (input) {
return input
.split(",")
.filter(i => !!i)
.map(i => i.trim().toLowerCase());
}
return [];
}
exports.sanitizeCommaDelimitedArg = sanitizeCommaDelimitedArg;
function addRootDeps(tree, targetPlatforms, packageJson) {
const packagePath = "package.json";
if (!packageJson) {
packageJson = getJsonFromFile(tree, packagePath);
}
if (packageJson) {
const angularVersion = packageJson.dependencies['@angular/core'];
const deps = [];
let dep = {
name: "@ngx-translate/core",
version: "~11.0.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@ngx-translate/http-loader",
version: "~4.0.0",
type: "dependency"
};
deps.push(dep);
if (!targetPlatforms.nest) {
// if just setting up workspace with nest, we don't need frontend scss
dep = {
name: `@${getNpmScope()}/scss`,
version: "file:libs/scss",
type: "dependency"
};
deps.push(dep);
}
dep = {
name: "reflect-metadata",
version: "^0.1.12",
type: "dependency"
};
deps.push(dep);
/** NATIVESCRIPT */
if (targetPlatforms.nativescript) {
dep = {
name: "nativescript-angular",
version: "~7.2.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "nativescript-ngx-fonticon",
version: "^4.2.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "nativescript-theme-core",
version: "^1.0.4",
type: "dependency"
};
deps.push(dep);
dep = {
name: "tns-core-modules",
version: "~5.2.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "terser-webpack-plugin",
version: "~1.2.0",
type: "devDependency"
};
dep = {
name: "tns-platform-declarations",
version: "~5.2.0",
type: "devDependency"
};
deps.push(dep);
}
/** IONIC */
if (targetPlatforms.ionic) {
dep = {
name: "@ionic-native/core",
version: "^5.0.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@ionic-native/splash-screen",
version: "^5.0.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@ionic-native/status-bar",
version: "^5.0.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@ionic/angular",
version: "^4.0.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@ionic/angular-toolkit",
version: "~1.2.0",
type: "devDependency"
};
deps.push(dep);
}
/** ELECTRON */
if (targetPlatforms.electron) {
// electron complains if this is missing
dep = {
name: "@angular/http",
version: angularVersion,
type: "dependency"
};
deps.push(dep);
dep = {
name: "electron",
version: "^4.0.5",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "electron-builder",
version: "^20.38.4",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "electron-rebuild",
version: "~1.8.4",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "electron-installer-dmg",
version: "~2.0.0",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "electron-packager",
version: "~13.1.0",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "electron-reload",
version: "~1.4.0",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "electron-store",
version: "~2.0.0",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "electron-updater",
version: "~4.0.6",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "npm-run-all",
version: "^4.1.5",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "npx",
version: "10.2.0",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "wait-on",
version: "~3.2.0",
type: "devDependency"
};
deps.push(dep);
}
/** NESTJS */
if (targetPlatforms.nest) {
dep = {
name: "@nestjs/common",
version: "^5.3.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@nestjs/core",
version: "^5.3.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@nestjs/testing",
version: "^5.3.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@nestjs/typeorm",
version: "^5.2.2",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@nestjs/websockets",
version: "^5.5.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@nestjs/microservices",
version: "^5.5.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "typeorm",
version: "^0.2.9",
type: "dependency"
};
deps.push(dep);
dep = {
name: "cache-manager",
version: "^2.9.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "helmet",
version: "^3.15.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "csurf",
version: "^1.9.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "express-rate-limit",
version: "^3.3.2",
type: "dependency"
};
deps.push(dep);
dep = {
name: "dotenv",
version: "^6.2.0",
type: "dependency"
};
deps.push(dep);
dep = {
name: "compression",
version: "^1.7.3",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@types/node",
version: "^9.3.0",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "ts-loader",
version: "^4.0.0",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "ts-node",
version: "^7.0.0",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "npm-run-all",
version: "^4.1.5",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "@types/jest",
version: "^20.0.8",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "jest",
version: "^20.0.4",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "ts-jest",
version: "^20.0.14",
type: "devDependency"
};
deps.push(dep);
dep = {
name: "supertest",
version: "^3.0.0",
type: "devDependency"
};
deps.push(dep);
}
if (targetPlatforms.ionic || targetPlatforms.electron) {
// ability to import web scss and share it
dep = {
name: `@${getNpmScope()}/web`,
version: "file:xplat/web",
type: "dependency"
};
deps.push(dep);
}
const dependenciesMap = Object.assign({}, packageJson.dependencies);
const devDependenciesMap = Object.assign({}, packageJson.devDependencies);
for (const dependency of deps) {
if (dependency.type === "dependency") {
packageJson.dependencies = exports.setDependency(dependenciesMap, dependency);
}
else {
packageJson.devDependencies = exports.setDependency(devDependenciesMap, dependency);
}
}
return updateJsonFile(tree, packagePath, packageJson);
}
return tree;
}
exports.addRootDeps = addRootDeps;
function updatePackageForXplat(tree,
// used when generating xplat support
targetPlatforms,
// used to update various xplat workspace settings
// can be used in combination with other generators to adjust settings
updatedSettings) {
const packagePath = "package.json";
const packageJson = getJsonFromFile(tree, packagePath);
if (packageJson) {
// TODO: potentially track this in angular.json (or xplat.json) in future
// doing so would involve customizing Nx schema.json which unsure about right now
// Ideally would store this as 'project': { 'prefix': prefix } (or add 'xplat' key there) for entire workspace/xplat setup, however that's unsupported in schema out of the box
// prefix is important because shared code is setup with a prefix to begin with which should be known and used for all subsequent apps which are generated
if (updatedSettings) {
packageJson.xplat = Object.assign({}, packageJson.xplat, updatedSettings);
// just update xplat workspace settings
return updateJsonFile(tree, packagePath, packageJson);
}
else {
packageJson.xplat = { prefix };
// update root dependencies for the generated xplat support
// console.log('updatePackageForXplat:', JSON.stringify(packageJson));
return addRootDeps(tree, targetPlatforms, packageJson);
}
}
return tree;
}
exports.updatePackageForXplat = updatePackageForXplat;
function updatePackageForNgrx(tree, packagePath = "package.json") {
if (tree.exists(packagePath)) {
const packageJson = getJsonFromFile(tree, packagePath);
if (packageJson) {
// sync version with what user has store set at
let rootNgrxVersion = packageJson.dependencies["@ngrx/store"];
const deps = [];
if (packagePath.indexOf("apps") === 0) {
// update project deps
let dep = {
name: "@ngrx/entity",
version: "file:../../node_modules/@ngrx/entity",
type: "dependency"
};
deps.push(dep);
dep = {
name: "ngrx-store-freeze",
version: "file:../../node_modules/ngrx-store-freeze",
type: "dependency"
};
deps.push(dep);
dep = {
name: "@nrwl/nx",
version: "file:../../node_modules/@nrwl/nx",
type: "dependency"
};
deps.push(dep);
}
else {
// update root deps
let dep = {
name: "@ngrx/entity",
version: rootNgrxVersion,
type: "dependency"
};
deps.push(dep);
if (!packageJson.dependencies["@nrwl/nx"]) {
dep = {
name: "@nrwl/nx",
version: "~7.0.0",
type: "dependency"
};
deps.push(dep);
}
}
const dependenciesMap = Object.assign({}, packageJson.dependencies);
const devDependenciesMap = Object.assign({}, packageJson.devDependencies);
for (const dependency of deps) {
if (dependency.type === "dependency") {
packageJson.dependencies = exports.setDependency(dependenciesMap, dependency);
}
else {
packageJson.devDependencies = exports.setDependency(devDependenciesMap, dependency);
}
}
return updateJsonFile(tree, packagePath, packageJson);
}
}
return tree;
}
exports.updatePackageForNgrx = updatePackageForNgrx;
function updateTsConfig(tree, callback, targetSuffix = '', prefixPath = '') {
const tsConfigPath = `${prefixPath}tsconfig${targetSuffix ? "." + targetSuffix : ""}.json`;
const tsConfig = getJsonFromFile(tree, tsConfigPath);
callback(tsConfig);
return updateJsonFile(tree, tsConfigPath, tsConfig);
}
exports.updateTsConfig = updateTsConfig;
function updatePackageScripts(tree, scripts) {
const path = "package.json";
const packageJson = getJsonFromFile(tree, path);
const scriptsMap = Object.assign({}, packageJson.scripts);
packageJson.scripts = Object.assign(scriptsMap, scripts);
return updateJsonFile(tree, path, packageJson);
}
exports.updatePackageScripts = updatePackageScripts;
function updateAngularProjects(tree, projects) {
const path = "angular.json";
const angularJson = getJsonFromFile(tree, path);
const projectsMap = Object.assign({}, angularJson.projects);
angularJson.projects = Object.assign(projectsMap, projects);
return updateJsonFile(tree, path, angularJson);
}
exports.updateAngularProjects = updateAngularProjects;
function updateNxProjects(tree, projects) {
const path = "nx.json";
const nxJson = getJsonFromFile(tree, path);
const projectsMap = Object.assign({}, nxJson.projects);
nxJson.projects = Object.assign(projectsMap, projects);
return updateJsonFile(tree, path, nxJson);
}
exports.updateNxProjects = updateNxProjects;
function updateGitIgnore() {
return (tree) => {
const gitIgnorePath = ".gitignore";
let gitIgnore = getFileContent(tree, gitIgnorePath);
if (gitIgnore) {
if (gitIgnore.indexOf("libs/**/*.js") === -1) {
gitIgnore += `
# nativescript
hooks\n
# libs
libs/**/*.js
libs/**/*.map
libs/**/*.d.ts
libs/**/*.metadata.json
libs/**/*.ngfactory.ts
libs/**/*.ngsummary.json
`;
}
if (gitIgnore.indexOf("xplat/**/*.js") === -1) {
gitIgnore += `
# xplat
xplat/**/*.js
xplat/**/*.map
xplat/**/*.d.ts
xplat/**/*.metadata.json
xplat/**/*.ngfactory.ts
xplat/**/*.ngsummary.json
`;
}
}
return updateFile(tree, gitIgnorePath, gitIgnore);
};
}
exports.updateGitIgnore = updateGitIgnore;
function addReferences() {
return (tree) => {
const filename = "references.d.ts";
if (!tree.exists(filename)) {
// add references.d.ts
tree.create(filename, `/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />
`);
}
return tree;
};
}
exports.addReferences = addReferences;
function addPostinstallers() {
return (tree) => {
const postinstallWeb = "/tools/web/postinstall.js";
if (!tree.exists(postinstallWeb)) {
// add references.d.ts
tree.create(postinstallWeb, `// Allow angular using electron module (native node modules)
const fs = require('fs');
const f_angular = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js';
fs.readFile(f_angular, 'utf8', function (err, data) {
if (err) {
return console.log(err);
}
var result = data.replace(/target: "electron-renderer",/g, '');
var result = result.replace(/target: "web",/g, '');
var result = result.replace(/return \{/g, 'return {target: "web",');
fs.writeFile(f_angular, result, 'utf8', function (err) {
if (err) return console.log(err);
});
});`);
}
const postinstallElectron = "/tools/electron/postinstall.js";
if (!tree.exists(postinstallElectron)) {
// add references.d.ts
tree.create(postinstallElectron, `// Allow angular using electron module (native node modules)
const fs = require('fs');
const f_angular = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js';
fs.readFile(f_angular, 'utf8', function (err, data) {
if (err) {
return console.log(err);
}
var result = data.replace(/target: "electron-renderer",/g, '');
var result = result.replace(/target: "web",/g, '');
var result = result.replace(/return \{/g, 'return {target: "electron-renderer",');
fs.writeFile(f_angular, result, 'utf8', function (err) {
if (err) return console.log(err);
});
});`);
}
return tree;
};
}
exports.addPostinstallers = addPostinstallers;
// export function persistPrefix(prefix: string) {
// return (tree: Tree) => {
// const nxConfig = getNxWorkspaceConfig(tree);
// ngConfig.defaults.prefix = prefix;
// return updateJsonFile(tree, 'angular.json', ngConfig);
// };
// }
function getPrefixWarning(prefix) {
return `A default prefix had already been set for your workspace: ${prefix}. Since xplat had already been configured we will be using '${prefix}' as the prefix.`;
}
exports.getPrefixWarning = getPrefixWarning;
exports.addTestingFiles = (tree, options, relativePath = "./") => {
if (tree.exists(`testing/karma.conf.js`)) {
return schematics_1.noop();
}
return schematics_1.branchAndMerge(schematics_1.mergeWith(schematics_1.apply(schematics_1.url(`${relativePath}_testing_files`), [
schematics_1.template(Object.assign({}, options, { npmScope: getNpmScope(), prefix: getPrefix(), dot: ".", utils: exports.stringUtils })),
schematics_1.move("testing")
])));
};
function updateIDESettings(tree, platformArg, devMode, allApps, focusOnApps) {
if (isTest) {
// ignore node file modifications when just testing
return tree;
}
try {
const cwd = process.cwd();
// console.log('workspace dir:', process.cwd());
// const dirName = cwd.split('/').slice(-1);
let isFullstack = false;
let isExcluding = false;
let appWildcards = [];
const userUpdates = {};
if (!devMode || devMode === "fullstack") {
// show all
isFullstack = true;
for (const p of exports.supportedPlatforms) {
const appFilter = groupByName ? `*-${p}` : `${p}-*`;
userUpdates[`**/apps/${appFilter}`] = false;
userUpdates[`**/xplat/${p}`] = false;
}
}
else if (platformArg) {
const platforms = sanitizeCommaDelimitedArg(platformArg);
// switch on/off platforms
for (const p of exports.supportedPlatforms) {
const excluded = platforms.includes(p) ? false : true;
const appFilter = groupByName ? `*-${p}` : `${p}-*`;
if (focusOnApps.length) {
// focusing on apps
// fill up wildcards to use below (we will clear all app wildcards when focusing on apps)
appWildcards.push(`**/apps/${appFilter}`);
}
else {
// use wildcards for apps only if no project names were specified
userUpdates[`**/apps/${appFilter}`] = excluded;
}
userUpdates[`**/xplat/${p}`] = excluded;
if (excluded) {
// if excluding any platform at all, set the flag
// this is used for WebStorm support below
isExcluding = true;
}
}
}
const isMac = process.platform == "darwin";
// VS Code support
// const homedir = os.homedir();
// console.log('os.homedir():',homedir);
let userSettingsVSCodePath = isMac
? process.env.HOME +
`/Library/Application Support/Code/User/settings.json`
: "/var/local/Code/User/settings.json";
const windowsHome = process.env.APPDATA;
if (windowsHome) {
userSettingsVSCodePath = path_1.join(windowsHome, "Code", "User", "settings.json");
}
// console.log('userSettingsVSCodePath:',userSettingsVSCodePath);
const isVsCode = fs.existsSync(userSettingsVSCodePath);
let vscodeCreateSettingsNote = `It's possible you don't have a user settings.json yet. If so, open VS Code User settings and save any kind of setting to have it created.`;
// console.log('isVsCode:',isVsCode);
if (isVsCode) {
const userSettings = fs.readFileSync(userSettingsVSCodePath, "UTF-8");
if (userSettings) {
const userSettingsJson = jsonParse(userSettings);
let exclude = userSettingsJson["files.exclude"];
if (!exclude) {
exclude = {};
}
let searchExclude = userSettingsJson["search.exclude"];
if (!searchExclude) {
searchExclude = {};
}
userSettingsJson["files.exclude"] = Object.assign(exclude, userUpdates);
userSettingsJson["search.exclude"] = Object.assign(searchExclude, userUpdates);
if (allApps.length) {
// always reset specific app filters
for (const app of allApps) {
delete userSettingsJson["files.exclude"][app];
delete userSettingsJson["search.exclude"][app];
}
}
if (!isFullstack && focusOnApps.length && allApps.length) {
// when focusing on projects, clear all specific app wildcards first if they exist
for (const wildcard of appWildcards) {
delete userSettingsJson["files.exclude"][wildcard];
delete userSettingsJson["search.exclude"][wildcard];
}
for (const focusApp of focusOnApps) {
userSettingsJson["files.exclude"][focusApp] = false;
userSettingsJson["search.exclude"][focusApp] = false;
}
// ensure all other apps are excluded (except for the one that's being focused on)
for (const app of allApps) {
if (!focusOnApps.includes(app)) {
userSettingsJson["files.exclude"][app] = true;
userSettingsJson["search.exclude"][app] = true;
}
}
}
fs.writeFileSync(userSettingsVSCodePath, JSON.stringify(userSettingsJson, null, 2));
}
else {
console.warn(`Warning: xplat could not read your VS Code settings.json file therefore development mode has not been set. ${vscodeCreateSettingsNote}`);
}
}
else {
console.log(`Note to VS Code users: no development mode set. xplat could not find any VS Code settings in the standard location: ${userSettingsVSCodePath} ${vscodeCreateSettingsNote}`);
}
// WebStorm support
let isWebStorm = false;
// list preferences to get correct webstorm prefs file
// let preferencesFolder = isMac
// ? process.env.HOME +
// `/Library/Preferences`
// : __dirname;
// if (windowsHome) {
// preferencesFolder = windowsHome;
// }
// const prefs = fs.readdirSync(preferencesFolder).filter(f => fs.statSync(join(preferencesFolder, f)).isDirectory());
// find first one
// TODO: user may have multiple version installed (or at least older versions) so may need to handle if multiples
// let webStormPrefFolderName = prefs.find(f => f.indexOf('WebStorm20') > -1);
// if (webStormPrefFolderName) {
// isWebStorm = true;
// webStormPrefFolderName = webStormPrefFolderName.split('/').slice(-1)[0];
// // console.log('webStormPrefFolderName:',webStormPrefFolderName);
// // ensure folders are excluded from project view
// let projectViewWebStormPath =
// isMac
// ? process.env.HOME +
// `/Library/Preferences/${webStormPrefFolderName}/options/projectView.xml`
// : join(__dirname, webStormPrefFolderName, 'config');
// if (windowsHome) {
// projectViewWebStormPath = join(windowsHome, webStormPrefFolderName, 'config');
// }
// let projectView = fs.readFileSync(projectViewWebStormPath, "UTF-8");
// if (projectView) {
// // console.log('projectView:', projectView);
// xml2js.parseString(projectView, (err, settings) => {
// // console.log(util.inspect(settings, false, null));
// if (settings && settings.application && settings.application.component && settings.application.component.length) {
// const builder = new xml2js.Builder({ headless: true });
// const sharedSettingsIndex = (<Array<any>>settings.application.component).findIndex(c => c.$.name === 'ProjectViewSharedSettings');
// if (sharedSettingsIndex > -1) {
// const sharedSettings = settings.application.component[sharedSettingsIndex];
// if (sharedSettings.option && sharedSettings.option.length) {
// const showExcludedFilesIndex = sharedSettings.option.findIndex(o => o.$.name === 'showExcludedFiles');
// if (showExcludedFilesIndex > -1) {
// settings.application.component[sharedSettingsIndex].option[showExcludedFilesIndex].$.value = `${!isExcluding}`;
// } else {
// settings.application.component[sharedSettingsIndex].option.push(webStormExcludedViewNode(isExcluding));
// }
// } else {
// settings.application.component[sharedSettingsIndex].option = [
// webStormExcludedViewNode(isExcluding)
// ];
// }
// settings = builder.buildObject(settings);
// } else {
// (<Array<any>>settings.application.component).push({
// $: 'ProjectViewSharedSettings',
// option: [
// webStormExcludedViewNode(isExcluding)
// ]
// });
// settings = builder.buildObject(settings);
// }
// } else {
// // create projectView.xml
// settings = createWebStormProjectView(isExcluding);
// }
// // modify projectView
// // console.log('settings:', settings);
// fs.writeFileSync(
// projectViewWebStormPath,
// settings
// );
// });
// } else {
// // create projectView.xml
// fs.writeFileSync(
// projectViewWebStormPath,
// createWebStormProjectView(isExcluding)
// );
// }
// }
if (!devMode) {
// only when not specifying a dev mode
const workspaceUpdates = {
"**/node_modules": true,
"**/hooks": true,
"**/apps/nativescript-*/app/package.json": false,
"**/apps/nativescript-*/hooks": true,
"**/apps/nativescript-*/platforms": true,
"**/apps/nativescript-*/report": true,
"**/apps/nativescript-*/app/**/*.js": {
when: "$(basename).ts"
},
"**/apps/nativescript-*/app/**/*.d.ts": {
when: "$(basename).ts"
},
"**/apps/nativescript-*/app/**/*.css": {
when: "$(basename).scss"
},
// also add groupByName support
"**/apps/*-nativescript/app/package.json": false,
"**/apps/*-nativescript/hooks": true,
"**/apps/*-nativescript/platforms": true,
"**/apps/*-nativescript/report": true,
"**/apps/*-nativescript/app/**/*.js": {
when: "$(basename).ts"
},
"**/apps/*-nativescript/app/**/*.d.ts": {
when: "$(basename).ts"
},
"**/apps/*-nativescript/app/**/*.css": {
when: "$(basename).scss"
},
// libs/xplat
"**/libs/**/*.js": {
when: "$(basename).ts"
},
"**/libs/**/*.d.ts": {
when: "$(basename).ts"
},
"**/xplat/**/*.js": {
when: "$(basename).ts"
},
"**/xplat/**/*.d.ts": {
when: "$(basename).ts"
}
};
if (isVsCode) {
const workspaceSettingsPath = path_1.join(cwd, ".vscode", "settings.json");
// console.log('workspaceSettingsPath:',workspaceSettingsPath);
let workspaceSettingsJson = {};
if (fs.existsSync(workspaceSettingsPath)) {
const workspaceSettings = fs.readFileSync(workspaceSettingsPath, "UTF-8");
workspaceSettingsJson = jsonParse(workspaceSettings);
const exclude = workspaceSettingsJson["files.exclude"];
workspaceSettingsJson["files.exclude"] = Object.assign(exclude, workspaceUpdates);
}
else {
// console.log('creating workspace settings...');
fs.mkdirSync(".vscode");
workspaceSettingsJson["files.exclude"] = workspaceUpdates;
}
fs.writeFileSync(workspaceSettingsPath, JSON.stringify(workspaceSettingsJson, null, 2));
}
if (isWebStorm) {
}
}
}
catch (err) {
// console.warn('IDE Settings could not be updated at this time:', err);
}
return tree;
}
exports.updateIDESettings = updateIDESettings;
function createWebStormProjectView(isExcluding) {
const projectViewObject = {
application: {
component: [
{
'$': {
name: 'ProjectViewSharedSettings'
},
option: [
webStormExcludedViewNode(isExcluding)
]
}
]
}
};
const builder = new xml2js.Builder({ headless: true });
return builder.buildObject(projectViewObject);
}
exports.createWebStormProjectView = createWebStormProjectView;
function webStormExcludedViewNode(isExcluding) {
return {
$: {
name: 'showExcludedFiles',
value: `${!isExcluding}`
}
};
}
exports.webStormExcludedViewNode = webStormExcludedViewNode;
/**
* Sanitizes a given string by removing all characters that
* are not letters or digits.
*
```javascript
sanitize('nativescript-app'); // 'nativescriptapp'
sanitize('action_name'); // 'actioname'
sanitize('css-class-name'); // 'cssclassname'
sanitize('my favorite items'); // 'myfavoriteitems'
```
@method sanitize
@param {String} str The string to sanitize.
@return {String} the sanitized string.
*/
exports.sanitize = (str) => str
.split("")
.filter(char => /[a-zA-Z0-9]/.test(char))
.join("");
/**
* Cannot read property 'classify' of undefined
TypeError: Cannot read property 'classify' of undefined
at Object.<anonymous> (/Users/nathan/Documents/github/nstudio/tmp/pnp-client/node_modules/@nstudio/schematics/src/utils.js:413:35)
*/
// for some reason angular-devkit/core is not resolving
// including code here manually
// const STRING_DASHERIZE_REGEXP = (/[ _]/g);
// const STRING_DECAMELIZE_REGEXP = (/([a-z\d])([A-Z])/g);
const STRING_CAMELIZE_REGEXP = /(-|_|\.|\s)+(.)?/g;
// const STRING_UNDERSCORE_REGEXP_1 = (/([a-z\d])([A-Z]+)/g);
// const STRING_UNDERSCORE_REGEXP_2 = (/-|\s+/g);
function camelize(str) {
return str
.replace(STRING_CAMELIZE_REGEXP, (_match, _separator, chr) => {
return chr ? chr.toUpperCase() : "";
})
.replace(/^([A-Z])/, match => match.toLowerCase());
}
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.substr(1);
}
function classify(str) {
return str
.split(".")
.map(part => capitalize(camelize(part)))
.join(".");
}
exports.stringUtils = { sanitize: exports.sanitize, classify, capitalize, camelize };
exports.toComponentClassName = (name) => `${classify(name)}Component`;
exports.toNgModuleClassName = (name) => `${classify(name)}Module`;
function addInstall(host, context) {
context.addTask(new tasks_1.NodePackageInstallTask());
return host;
}
exports.addInstall = addInstall;
//# sourceMappingURL=general.js.map
;