@nstudio/angular
Version:
Angular Plugin for xplat
618 lines (617 loc) • 30.5 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.generate = generate;
exports.getFeatureName = getFeatureName;
exports.getNxFeaturePath = getNxFeaturePath;
exports.addToFeature = addToFeature;
exports.isFeatureInGeneralBarrel = isFeatureInGeneralBarrel;
exports.shouldTargetCoreBarrel = shouldTargetCoreBarrel;
exports.adjustBarrel = adjustBarrel;
exports.adjustBarrelIndex = adjustBarrelIndex;
exports.adjustBarrelIndexForType = adjustBarrelIndexForType;
exports.adjustModule = adjustModule;
exports.adjustFeatureModule = adjustFeatureModule;
exports.adjustFeatureModuleForState = adjustFeatureModuleForState;
exports.adjustRouting = adjustRouting;
exports.adjustSandbox = adjustSandbox;
const schematics_1 = require("@angular-devkit/schematics");
const xplat_1 = require("@nstudio/xplat");
const xplat_utils_1 = require("@nstudio/xplat-utils");
const ast_1 = require("./ast");
const ts = require("typescript");
function generate(type, options) {
if (!options.name) {
throw new Error((0, xplat_1.generateOptionError)(type));
}
let featureName = getFeatureName(options);
let platforms = [];
const externalChains = [];
if (options.projects) {
// building in projects
const projects = (0, xplat_utils_1.sanitizeCommaDelimitedArg)(options.projects);
for (const name of projects) {
const nameParts = name.split('-');
const platPrefix = nameParts[0];
const platSuffix = nameParts[nameParts.length - 1];
if (xplat_utils_1.supportedPlatforms.includes(platPrefix) &&
!platforms.includes(platPrefix)) {
// if project name is prefixed with supported platform and not already added
platforms.push(platPrefix);
}
else if (xplat_utils_1.supportedPlatforms.includes(platSuffix) &&
!platforms.includes(platSuffix)) {
// if project name is suffixed with supported platform and not already added
platforms.push(platSuffix);
}
}
}
else if (options.platforms) {
// building in shared code only
platforms = (0, xplat_utils_1.sanitizeCommaDelimitedArg)(options.platforms);
}
const projectChains = [];
if (options.projects) {
for (const fullProjectPath of options.projects.split(',')) {
const projectName = (0, xplat_utils_1.parseProjectNameFromPath)(fullProjectPath);
const projectParts = projectName.split('-');
const platform = xplat_utils_1.supportedPlatforms.includes(projectParts[0])
? projectParts[0]
: projectParts.length > 1
? projectParts[1]
: projectParts[0];
let appDir = platform === 'web' ? '/app' : '';
const prefixPath = `apps/${fullProjectPath}/src${appDir}`;
let featurePath;
if (shouldTargetCoreBarrel(type, featureName)) {
featureName = 'core';
featurePath = `${prefixPath}/${featureName}`;
}
else {
featurePath = `${prefixPath}/features/${featureName}`;
}
const featureModulePath = `${featurePath}/${featureName}.module.ts`;
let barrelIndex;
if (type === 'state') {
barrelIndex = `${featurePath}/index.ts`;
}
else {
barrelIndex = `${featurePath}/${type}s/index.ts`;
}
// console.log('will adjustProject:', projectName);
projectChains.push((tree, context) => {
// console.log('featureModulePath:', featureModulePath);
// console.log('projectName:', projectName);
if (!tree.exists(featureModulePath)) {
throw new Error((0, xplat_1.needFeatureModuleError)(featureModulePath, featureName, projectName, true));
}
return addToFeature(platform, type, options, prefixPath, tree)(tree, context);
});
if (type === 'state') {
// ngrx handling
projectChains.push((tree, context) => {
return adjustBarrelIndexForType(type, options, barrelIndex)(tree, context);
});
projectChains.push((tree, context) => {
return addToFeature(platform, type, options, prefixPath, tree, '_index')(tree, context);
});
projectChains.push((tree, context) => {
return adjustFeatureModuleForState(options, featureModulePath)(tree, context);
});
projectChains.push((tree, context) => {
return (0, xplat_1.updatePackageForNgrx)(tree, `apps/${fullProjectPath}/package.json`);
});
}
else {
projectChains.push((tree, context) => {
return adjustBarrelIndex(type, options, barrelIndex)(tree, context);
});
projectChains.push((tree, context) => {
return addToFeature(platform, type, options, prefixPath, tree, '_index')(tree, context);
});
projectChains.push((tree, context) => {
return adjustFeatureModule(type, options, featureModulePath)(tree, context);
});
}
}
}
else {
projectChains.push((0, schematics_1.noop)());
for (const platform of platforms) {
if (xplat_utils_1.supportedPlatforms.includes(platform)) {
// externalChains.push(externalSchematic(`@nstudio/${platform}-angular`, type, options, {
// interactive: false
// }));
externalChains.push((tree, context) => {
const xplatFolderName = xplat_1.XplatHelpers.getXplatFoldername(platform, 'angular');
return addToFeature(xplatFolderName, type, options, `libs/xplat/${xplatFolderName}`, tree);
});
// adjust barrel
externalChains.push((tree, context) => {
const xplatFolderName = xplat_1.XplatHelpers.getXplatFoldername(platform, 'angular');
return adjustBarrel(type, options, `libs/xplat/${xplatFolderName}`);
});
// add index barrel if needed
externalChains.push((tree, context) => {
const xplatFolderName = xplat_1.XplatHelpers.getXplatFoldername(platform, 'angular');
return options.needsIndex
? addToFeature(xplatFolderName, type, options, `libs/xplat/${xplatFolderName}`, tree, '_index')(tree, context)
: (0, schematics_1.noop)()(tree, context);
});
// adjust feature module metadata if needed
externalChains.push((tree, context) => {
const xplatFolderName = xplat_1.XplatHelpers.getXplatFoldername(platform, 'angular');
return adjustModule(tree, type, options, `libs/xplat/${xplatFolderName}`);
});
}
else {
throw new Error((0, xplat_1.unsupportedPlatformError)(platform));
}
}
}
return (0, schematics_1.chain)([
(0, xplat_utils_1.prerun)(),
(tree, context) =>
// for entire workspace usage
// no projects and no specific platforms specified
!options.projects && platforms.length === 0
? addToFeature('', type, options, 'libs/xplat', tree)(tree, context)
: (0, schematics_1.noop)()(tree, context),
// adjust libs barrel
(tree, context) => !options.projects && platforms.length === 0
? adjustBarrel(type, options, 'libs/xplat')(tree, context)
: (0, schematics_1.noop)()(tree, context),
// add index barrel if needed
(tree, context) => options.needsIndex
? addToFeature('', type, options, 'libs/xplat', tree, '_index')(tree, context)
: (0, schematics_1.noop)()(tree, context),
// adjust feature module metadata if needed
(tree, context) => !options.projects && platforms.length === 0
? adjustModule(tree, type, options, 'libs/xplat')(tree, context)
: (0, schematics_1.noop)()(tree, context),
// project handling
(tree, context) => (0, schematics_1.chain)(projectChains),
(tree, context) => (0, schematics_1.chain)(externalChains),
// dependency updates
(tree, context) => !options.projects && type === 'state'
? // ensure ngrx dependencies are added to root package
(0, xplat_1.updatePackageForNgrx)(tree)
: (0, schematics_1.noop)()(tree, context),
]);
}
function getFeatureName(options) {
let featureName;
const isNxLib = xplat_1.XplatHelpers.isFeatureNxLib(options.feature);
if (options.feature) {
if (isNxLib) {
// use lib name "as-is"
featureName = options.feature.toLowerCase();
}
else {
// otherwise, user is wanting to target a feature nested in a folder (within features)
const dirParts = options.feature.split('/');
if (dirParts.length) {
featureName = dirParts.pop().toLowerCase();
}
}
}
if (!featureName) {
if (options.projects) {
// default to shared barrel
featureName = 'shared';
}
else {
// default to ui barrel
featureName = 'ui';
}
}
return featureName;
}
function getNxFeaturePath(tree, featureName) {
const tsConfig = (0, xplat_utils_1.getJsonFromFile)(tree, 'tsconfig.base.json');
if (tsConfig) {
if (tsConfig.compilerOptions &&
tsConfig.compilerOptions.paths &&
tsConfig.compilerOptions.paths[featureName]) {
let libPath = tsConfig.compilerOptions.paths[featureName][0];
return libPath.replace('index.ts', 'lib');
}
else {
throw new Error(`No lib barrel path found in tsconfig.base.json matching "${featureName}"`);
}
}
else {
throw new Error('Workspace must have tsconfig.base.json.');
}
return null;
}
function addToFeature(xplatFolderName, type, options, prefixPath, tree, extra = '', forSubFolder) {
let featureName = getFeatureName(options);
const isNxLib = xplat_1.XplatHelpers.isFeatureNxLib(featureName);
let directory = '';
let relativeDirectory = '';
if (!isNxLib && options.feature) {
const dirParts = options.feature.split('/');
if (dirParts.length) {
dirParts.pop();
directory = dirParts.join('/');
const relative = [];
dirParts.forEach(() => relative.push('..'));
relativeDirectory = relative.join('/') + '/';
}
}
options.needsIndex = false; // reset
const srcSubFolderPath = options.projects ? '' : '/src/lib';
let featurePath;
// support targeting Nx libs with feature argument using the lib barrel (ie, @scope/mylib)
if (isNxLib) {
featurePath = getNxFeaturePath(tree, featureName);
}
else if (shouldTargetCoreBarrel(type, featureName)) {
// services and/or state should never be generated in shared or ui features
// therefore place in core (since they are service level)
featureName = 'core';
featurePath = `${prefixPath}/${featureName}${srcSubFolderPath}`;
}
else {
featurePath = `${prefixPath}/features${srcSubFolderPath}/${directory ? directory + '/' : ''}${featureName}`;
}
const featureModulePath = `${featurePath}/${featureName}.module.ts`;
let moveTo;
if (extra === '_base' || extra === '_base_index') {
// always in libs
moveTo = `libs/xplat/features/src/lib/${featureName}/base`;
}
else {
moveTo = `${featurePath}/${type}${type === 'state' ? '' : 's'}`;
if (!isNxLib && !tree.exists(featureModulePath)) {
let optionName;
if (prefixPath !== 'libs') {
// parse platform from prefix
const parts = prefixPath.split('/');
if (parts.length > 1) {
optionName = parts[2];
}
}
throw new Error((0, xplat_1.needFeatureModuleError)(featureModulePath, featureName, optionName));
}
}
if (forSubFolder && options.subFolder) {
moveTo += `/${options.subFolder}`;
}
// console.log('moveTo:', moveTo);
const indexPath = `${moveTo}/index.ts`;
if ((extra === '_index' || extra === '_base_index') &&
tree.exists(indexPath)) {
// already has an index barrel
return (0, schematics_1.noop)();
}
else {
return (0, schematics_1.branchAndMerge)((0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(`./${extra}_files`), [
(0, schematics_1.template)(Object.assign(Object.assign(Object.assign({}, options), (0, xplat_1.getDefaultTemplateOptions)()), { name: options.name.toLowerCase(), relativeDirectory,
xplatFolderName,
// feature: featureName,
forSubFolder })),
(0, schematics_1.move)(moveTo),
])));
}
}
function isFeatureInGeneralBarrel(featureName) {
// 'shared' barrel is for app specific shared components, pipes, directives (not service level features)
// 'ui' barrel is for entire workspace ui related sharing of components, pipes, directives (not service level features)
return featureName === 'shared' || featureName === 'ui';
}
function shouldTargetCoreBarrel(type, featureName) {
// when service or state is being generated with no options, it falls back to shared/ui
// services and state should never be generated in shared or ui features
// therefore target core barrel
return ((type === 'service' || type === 'state') &&
isFeatureInGeneralBarrel(featureName));
}
function adjustBarrel(type, options, prefix) {
let featureName = getFeatureName(options);
const srcSubFolderPath = options.projects ? '' : '/src/lib';
let barrelIndexPath;
if (shouldTargetCoreBarrel(type, featureName)) {
if (type === 'state') {
barrelIndexPath = `${prefix}/core${srcSubFolderPath}/index.ts`;
}
else {
barrelIndexPath = `${prefix}/core${srcSubFolderPath}/${type}s/index.ts`;
}
}
else {
if (type === 'state') {
barrelIndexPath = `${prefix}/features${srcSubFolderPath}/${featureName}/index.ts`;
}
else {
barrelIndexPath = `${prefix}/features${srcSubFolderPath}/${featureName}/${type}s/index.ts`;
}
}
if (type === 'state') {
return adjustBarrelIndexForType(type, options, barrelIndexPath);
}
else {
return adjustBarrelIndex(type, options, barrelIndexPath);
}
}
function adjustBarrelIndex(type, options, indexFilePath, inSubFolder, isBase, importIfSubFolder) {
return (host, context) => {
const devKitTree = (0, xplat_1.convertNgTreeToDevKit)(host, context);
// console.log('adjustBarrelIndex:', indexFilePath);
// console.log('host.exists(indexFilePath):', host.exists(indexFilePath));
if (host.exists(indexFilePath)) {
const indexSource = host.read(indexFilePath).toString('utf-8');
let indexSourceFile = ts.createSourceFile(indexFilePath, indexSource, ts.ScriptTarget.Latest, true);
const changes = [];
const name = options.name.toLowerCase();
if (!isBase && type !== 'service') {
// add to barrel collection
if (importIfSubFolder && options.subFolder) {
// import collection from subfolder
const symbolName = `${xplat_1.stringUtils
.sanitize(options.subFolder)
.toUpperCase()}_${type.toUpperCase()}S`;
indexSourceFile = (0, xplat_1.addGlobal)(devKitTree, indexSourceFile, indexFilePath, `import { ${symbolName} } from './${options.subFolder}';`, false);
indexSourceFile = (0, ast_1.addToCollection)(devKitTree, indexSourceFile, indexFilePath, `...${symbolName}`, ' ');
changes.push(indexSourceFile);
}
else {
const symbolName = `${xplat_1.stringUtils.classify(name)}${xplat_1.stringUtils.capitalize(type)}`;
indexSourceFile = (0, xplat_1.addGlobal)(devKitTree, indexSourceFile, indexFilePath, `import { ${symbolName} } from './${inSubFolder ? `${name}/` : ''}${name}.${type}';`);
indexSourceFile = (0, ast_1.addToCollection)(devKitTree, indexSourceFile, indexFilePath, symbolName, ' ');
changes.push(indexSourceFile);
}
}
if (type === 'component' || type === 'service' || type === 'pipe') {
// export symbol from barrel
if ((isBase || importIfSubFolder) && options.subFolder) {
indexSourceFile = (0, xplat_1.addGlobal)(devKitTree, indexSourceFile, indexFilePath, `export * from './${options.subFolder}';`, true);
changes.push(indexSourceFile);
}
else {
const subFolder = inSubFolder ? `${name}/` : '';
indexSourceFile = (0, xplat_1.addGlobal)(devKitTree, indexSourceFile, indexFilePath, `export * from './${subFolder}${name}.${isBase ? 'base-' : ''}${type}';`, true);
changes.push(indexSourceFile);
}
}
// insert(devKitTree.tree, indexFilePath, changes);
}
else {
options.needsIndex = true;
}
return devKitTree.tree;
};
}
function adjustBarrelIndexForType(type, options, indexFilePath) {
return (host, context) => {
const devKitTree = (0, xplat_1.convertNgTreeToDevKit)(host, context);
if (host.exists(indexFilePath)) {
const indexSource = host.read(indexFilePath).toString('utf-8');
const indexSourceFile = ts.createSourceFile(indexFilePath, indexSource, ts.ScriptTarget.Latest, true);
const changes = [];
changes.push((0, xplat_1.addGlobal)(devKitTree, indexSourceFile, indexFilePath, `export * from './${type}';`, true));
// insert(devKitTree.tree, indexFilePath, changes);
}
else {
options.needsIndex = true;
}
return devKitTree.tree;
};
}
function adjustModule(tree, type, options, prefixPath) {
let featureName = getFeatureName(options);
const isNxLib = xplat_1.XplatHelpers.isFeatureNxLib(featureName);
let featurePath;
if (isNxLib) {
featurePath = getNxFeaturePath(tree, featureName);
featureName = featureName.split('/').pop();
}
else if (shouldTargetCoreBarrel(type, featureName)) {
featureName = 'core';
featurePath = `${prefixPath}/${featureName}/src/lib`;
}
else {
featurePath = `${prefixPath}/features/src/lib/${featureName}`;
}
const featureModulePath = `${featurePath}/${featureName}.module.ts`;
if (type === 'state') {
return adjustFeatureModuleForState(options, featureModulePath);
}
else {
return adjustFeatureModule(type, options, featureModulePath);
}
}
function adjustFeatureModule(type, options, modulePath) {
return (host, context) => {
const devKitTree = (0, xplat_1.convertNgTreeToDevKit)(host, context);
// console.log('adjustFeatureModule:', modulePath);
if (host.exists(modulePath)) {
const moduleSource = host.read(modulePath).toString('utf-8');
const moduleSourceFile = (0, ast_1.getTsSourceFile)(devKitTree, modulePath);
const changes = [];
let featureName;
if (options.feature) {
featureName = xplat_1.stringUtils.sanitize(options.feature).toUpperCase();
}
else {
// default collections
if (type === 'service') {
featureName = 'CORE';
}
else {
if (modulePath.indexOf('apps') > -1) {
// app specific shared
featureName = 'SHARED';
}
else {
// workspace cross platform ui libraries
featureName = 'UI';
}
}
}
let collectionName;
switch (type) {
case 'component':
collectionName = `${featureName}_COMPONENTS`;
break;
case 'directive':
collectionName = `${featureName}_DIRECTIVES`;
break;
case 'pipe':
collectionName = `${featureName}_PIPES`;
break;
case 'service':
collectionName = `${featureName}_PROVIDERS`;
break;
}
// console.log('collectionName:', collectionName);
// console.log('moduleSource:', moduleSource);
if (moduleSource.indexOf(collectionName) > -1) {
// already handled
return host;
}
else {
if (type !== 'service') {
// add to module
changes.push((0, ast_1._addSymbolToNgModuleMetadata)(devKitTree, (0, ast_1.addDeclarationToModule)(devKitTree, (0, xplat_1.addGlobal)(devKitTree, moduleSourceFile, modulePath, `import { ${collectionName} } from './${type}s';`), modulePath, `...${collectionName}`), modulePath, 'exports', `...${collectionName}`));
}
// insert(devKitTree.tree, modulePath, changes);
}
}
return devKitTree.tree;
};
}
function adjustFeatureModuleForState(options, modulePath) {
return (host, context) => {
const devKitTree = (0, xplat_1.convertNgTreeToDevKit)(host, context);
// console.log('adjustFeatureModuleForState:', modulePath);
if (host.exists(modulePath)) {
const moduleSource = host.read(modulePath).toString('utf-8');
let moduleSourceFile = ts.createSourceFile(modulePath, moduleSource, ts.ScriptTarget.Latest, true);
// console.log('moduleSource:', moduleSource);
const isInLibs = modulePath.indexOf('libs/xplat/core') === 0;
const name = options.name.toLowerCase();
const changes = [];
if (moduleSource.indexOf('StoreModule') === -1) {
moduleSourceFile = (0, xplat_1.addGlobal)(devKitTree, moduleSourceFile, modulePath, `import { StoreModule } from '@ngrx/store';`);
changes.push(moduleSourceFile);
}
if (moduleSource.indexOf('EffectsModule') === -1) {
moduleSourceFile = (0, xplat_1.addGlobal)(devKitTree, moduleSourceFile, modulePath, `import { EffectsModule } from '@ngrx/effects';`);
changes.push(moduleSourceFile);
}
moduleSourceFile = (0, xplat_1.addGlobal)(devKitTree, moduleSourceFile, modulePath, `import { ${xplat_1.stringUtils.classify(name)}Effects } from './state/${name}.effects';`);
moduleSourceFile = (0, xplat_1.addGlobal)(devKitTree, moduleSourceFile, modulePath, `import { ${xplat_1.stringUtils.camelize(name)}Reducer } from './state/${name}.reducer';`);
moduleSourceFile = (0, xplat_1.addGlobal)(devKitTree, moduleSourceFile, modulePath, `import { ${xplat_1.stringUtils.classify(name)}State } from './state/${name}.state';`);
changes.push(moduleSourceFile);
if (options.root) {
if (moduleSource.indexOf('environments/environment') === -1) {
const envFrom = isInLibs
? './environments/environment'
: `@${(0, xplat_utils_1.getNpmScope)()}/xplat/core`;
moduleSourceFile = (0, xplat_1.addGlobal)(devKitTree, moduleSourceFile, modulePath, `import { environment } from '${envFrom}';`);
changes.push(moduleSourceFile);
}
moduleSourceFile = (0, ast_1.addImportToModule)(devKitTree, moduleSourceFile, modulePath, `StoreModule.forRoot(
{ ${xplat_1.stringUtils.camelize(name)}: ${xplat_1.stringUtils.camelize(name)}Reducer },
{
initialState: { ${xplat_1.stringUtils.camelize(name)}: ${xplat_1.stringUtils.classify(name)}State.initialState }
}
), EffectsModule.forRoot([${xplat_1.stringUtils.classify(name)}Effects])`);
moduleSourceFile = (0, ast_1.addProviderToModule)(devKitTree, moduleSourceFile, modulePath, `${xplat_1.stringUtils.classify(name)}Effects`);
changes.push(moduleSourceFile);
}
else {
moduleSourceFile = (0, ast_1.addImportToModule)(devKitTree, moduleSourceFile, modulePath, `StoreModule.forFeature('${xplat_1.stringUtils.camelize(name)}', ${xplat_1.stringUtils.camelize(name)}Reducer, { initialState: ${xplat_1.stringUtils.classify(name)}State.initialState }), EffectsModule.forFeature([${xplat_1.stringUtils.classify(name)}Effects])`);
moduleSourceFile = (0, ast_1.addProviderToModule)(devKitTree, moduleSourceFile, modulePath, `${xplat_1.stringUtils.classify(name)}Effects`);
// feature state
changes.push(moduleSourceFile);
}
// insert(devKitTree.tree, modulePath, changes);
}
return devKitTree.tree;
};
}
function adjustRouting(options, routingModulePaths, platform) {
return (host, context) => {
const devKitTree = (0, xplat_1.convertNgTreeToDevKit)(host, context);
const featureName = options.name.toLowerCase();
let routingModulePath;
// check which routing naming convention might be in use
// app.routing.ts or app-routing.module.ts
for (const modulePath of routingModulePaths) {
if (host.exists(modulePath)) {
routingModulePath = modulePath;
break;
}
}
// console.log('routingModulePath:',routingModulePath);
// console.log('host.exists(routingModulePath):',host.exists(routingModulePath));
if (routingModulePath) {
const routingSource = host.read(routingModulePath).toString('utf-8');
const routingSourceFile = ts.createSourceFile(routingModulePath, routingSource, ts.ScriptTarget.Latest, true);
const changes = [];
// add component to route config
changes.push((0, ast_1.addToCollection)(devKitTree, routingSourceFile, routingModulePath, `{
path: '${featureName}',
loadChildren: () => import('./features/${options.directory ? options.directory + '/' : ''}${featureName}/${featureName}.module').then(m => m.${xplat_1.stringUtils.classify(featureName)}Module)
}`));
// insert(devKitTree.tree, routingModulePath, changes);
}
return devKitTree.tree;
};
}
function adjustSandbox(options, platform, appDirectory) {
return (tree) => {
if (xplat_1.supportedSandboxPlatforms.includes(platform)) {
const homeCmpPath = `${appDirectory}/features/home/components/home.component.html`;
let homeTemplate = tree.get(homeCmpPath).content.toString();
switch (platform) {
case 'nativescript':
let buttonTag = 'Button';
let buttonEndIndex = homeTemplate.lastIndexOf(`</${buttonTag}>`);
if (buttonEndIndex === -1) {
// check for lowercase
buttonEndIndex = homeTemplate.lastIndexOf(`</${buttonTag.toLowerCase()}>`);
if (buttonEndIndex > -1) {
buttonTag = buttonTag.toLowerCase();
}
}
let customBtnClass = '';
if (buttonEndIndex === -1) {
// if no buttons were found this is a fresh sandbox app setup
// it should have a label as placeholder
buttonEndIndex = homeTemplate.lastIndexOf('</Label>');
if (buttonEndIndex === -1) {
buttonEndIndex = homeTemplate.lastIndexOf(`</label>`);
}
}
else {
const buttonClassStartIndex = homeTemplate.lastIndexOf('class="btn ');
if (buttonClassStartIndex > -1) {
// using custom button class
customBtnClass =
' ' +
homeTemplate.substring(buttonClassStartIndex + 11, homeTemplate.lastIndexOf(`"></${buttonTag}>`));
}
}
const featureName = options.name.toLowerCase();
const featureNameParts = featureName.split('-');
let routeName = featureName;
if (featureNameParts.length > 1) {
routeName = xplat_1.stringUtils.capitalize(featureNameParts[featureNameParts.length - 1]);
}
homeTemplate =
homeTemplate.slice(0, buttonEndIndex + 9) +
`<${buttonTag} text="${routeName}" (tap)="goTo('/${featureName}')" class="btn${customBtnClass}"></${buttonTag}>` +
homeTemplate.slice(buttonEndIndex + 9);
break;
}
(0, xplat_utils_1.updateFile)(tree, homeCmpPath, homeTemplate);
}
else {
throw new schematics_1.SchematicsException(`The --adjustSandbox option is only supported on the following at the moment: ${xplat_1.supportedSandboxPlatforms}`);
}
return tree;
};
}
;