UNPKG

@nstudio/schematics

Version:

Cross-platform (xplat) tools for Nx workspaces.

287 lines 13.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const schematics_1 = require("@angular-devkit/schematics"); const utils_1 = require("../utils"); const ts = require("typescript"); const test_1 = require("@schematics/angular/utility/test"); const strings_1 = require("@angular-devkit/core/src/utils/strings"); let featureName; let projectNames; function default_1(options) { if (!options.name) { throw new schematics_1.SchematicsException(`You did not specify the name of the feature you'd like to generate. For example: ng g feature my-feature`); } featureName = options.name.toLowerCase(); let projects = options.projects; let platforms = []; if (options.adjustSandbox) { // when adjusting sandbox for the feature, turn dependent options on // for convenience also setup some default fallbacks to avoid requiring so many options // sandbox flags are meant to be quick and convenient options.onlyProject = true; options.routing = true; if (!projects) { if (!options.platforms) { // default to {N} sandbox projects = 'nativescript-sandbox'; } else { platforms = options.platforms.split(","); const projectSandboxNames = []; // default to project with sandbox name for (const p of platforms) { if (utils_1.supportedSandboxPlatforms.includes(p)) { projectSandboxNames.push(`${p}-sandbox`); } else { throw new schematics_1.SchematicsException(`The --adjustSandbox flag supports the following at the moment: ${utils_1.supportedSandboxPlatforms}`); } } projects = projectSandboxNames.join(','); } } } if (options.routing && !options.onlyProject) { throw new schematics_1.SchematicsException(`When generating a feature with the --routing option, please also specify --onlyProject. Support for shared code routing is under development and will be available in the future.`); } if (projects) { // building feature in shared code and in projects projectNames = projects.split(","); for (const name of projectNames) { const platPrefix = name.split("-")[0]; if (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 (options.platforms) { // building feature in shared code only platforms = options.platforms.split(","); } if (platforms.length === 0) { let error = projects ? utils_1.platformAppPrefixError() : utils_1.generatorError("feature"); throw new schematics_1.SchematicsException(utils_1.optionsMissingError(error)); } const targetPlatforms = {}; for (const t of platforms) { if (utils_1.supportedPlatforms.includes(t)) { targetPlatforms[t] = true; } else { throw new schematics_1.SchematicsException(utils_1.unsupportedPlatformError(t)); } } const projectChains = []; if (options.onlyProject) { for (const projectName of projectNames) { const platPrefix = projectName.split("-")[0]; let srcDir = platPrefix !== "nativescript" ? "src/" : ""; // check for 2 different naming conventions on routing modules const routingModulePathOptions = []; const appDirectory = `apps/${projectName}/${srcDir}app/`; routingModulePathOptions.push(`${appDirectory}app.routing.ts`); routingModulePathOptions.push(`${appDirectory}app-routing.module.ts`); projectChains.push((tree, context) => { return addFiles(options, platPrefix, projectName)(tree, context); }); if (options.routing) { projectChains.push((tree, context) => { return adjustRouting(routingModulePathOptions, platPrefix)(tree, context); }); if (options.adjustSandbox) { projectChains.push((tree, context) => { return adjustSandbox(platPrefix, appDirectory)(tree, context); }); } } if (!options.onlyModule) { projectChains.push((tree, context) => { return addFiles(options, platPrefix, projectName, "_component")(tree, context); }); } } } else { projectChains.push(schematics_1.noop()); } return schematics_1.chain([ utils_1.prerun(), // libs (tree, context) => options.onlyProject ? schematics_1.noop()(tree, context) : addFiles(options)(tree, context), // libs (tree, context) => options.onlyProject || !options.createBase || options.onlyModule ? schematics_1.noop()(tree, context) : addFiles(options, null, null, "_component")(tree, context), // update libs index (tree, context) => options.onlyProject ? schematics_1.noop()(tree, context) : adjustBarrelIndex("libs/features/index.ts")(tree, context), // web (tree, context) => !options.onlyProject && targetPlatforms.web ? addFiles(options, "web")(tree, context) : schematics_1.noop()(tree, context), // update web index (tree, context) => !options.onlyProject && targetPlatforms.web ? adjustBarrelIndex("xplat/web/features/index.ts")(tree, context) : schematics_1.noop()(tree, context), // add starting component unless onlyModule (tree, context) => !options.onlyProject && !options.onlyModule && targetPlatforms.web ? addFiles(options, "web", null, "_component")(tree, context) : schematics_1.noop()(tree, context), // nativescript (tree, context) => !options.onlyProject && targetPlatforms.nativescript ? addFiles(options, "nativescript")(tree, context) : schematics_1.noop()(tree, context), // update nativescript index (tree, context) => !options.onlyProject && targetPlatforms.nativescript ? adjustBarrelIndex("xplat/nativescript/features/index.ts")(tree, context) : schematics_1.noop()(tree, context), // add starting component unless onlyModule (tree, context) => !options.onlyProject && !options.onlyModule && targetPlatforms.nativescript ? addFiles(options, "nativescript", null, "_component")(tree, context) : schematics_1.noop()(tree, context), // ionic (tree, context) => !options.onlyProject && targetPlatforms.ionic ? addFiles(options, "ionic")(tree, context) : schematics_1.noop()(tree, context), // update ionic index (tree, context) => !options.onlyProject && targetPlatforms.ionic ? adjustBarrelIndex("xplat/ionic/features/index.ts")(tree, context) : schematics_1.noop()(tree, context), // add starting component unless onlyModule (tree, context) => !options.onlyProject && !options.onlyModule && targetPlatforms.ionic ? addFiles(options, "ionic", null, "_component")(tree, context) : schematics_1.noop()(tree, context), // project handling ...projectChains, options.skipFormat ? schematics_1.noop() : utils_1.formatFiles(options) ]); } exports.default = default_1; const addFiles = (options, target = "", projectName = "", extra = "") => { let moveTo; if (target) { moveTo = getMoveTo(target, projectName); } else { target = "lib"; moveTo = `libs/features/${featureName}`; } return schematics_1.branchAndMerge(schematics_1.mergeWith(schematics_1.apply(schematics_1.url(`./_${target}${extra}_files`), [ schematics_1.template(getTemplateOptions(options)), schematics_1.move(moveTo) ]))); }; function adjustBarrelIndex(indexFilePath) { return (host) => { const indexSource = host.read(indexFilePath).toString("utf-8"); const indexSourceFile = ts.createSourceFile(indexFilePath, indexSource, ts.ScriptTarget.Latest, true); utils_1.insert(host, indexFilePath, [ ...utils_1.addGlobal(indexSourceFile, indexFilePath, `export * from './${featureName}';`, true) ]); return host; }; } function getTemplateOptions(options) { const nameParts = options.name.split('-'); let endingDashName = nameParts[0]; if (nameParts.length > 1) { endingDashName = strings_1.capitalize(nameParts[nameParts.length - 1]); } return Object.assign({}, options, { name: featureName, endingDashName, npmScope: utils_1.getNpmScope(), prefix: utils_1.getPrefix(), dot: ".", utils: utils_1.stringUtils }); } function getMoveTo(platform, projectName) { let moveTo = `xplat/${platform}/features/${featureName}`; if (projectName) { let srcDir = platform !== "nativescript" ? "src/" : ""; moveTo = `apps/${projectName}/${srcDir}app/features/${featureName}`; // console.log('moveTo:', moveTo); } return moveTo; } function adjustRouting(routingModulePaths, platform) { return (host) => { 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 = []; const loadPrefix = platform === "nativescript" ? "~" : "."; // add component to route config changes.push(...utils_1.addToCollection(routingSourceFile, routingModulePath, `{ path: '${featureName}', loadChildren: '${loadPrefix}/features/${featureName}/${featureName}.module#${utils_1.stringUtils.classify(featureName)}Module' }`)); utils_1.insert(host, routingModulePath, changes); } return host; }; } function adjustSandbox(platform, appDirectory) { return (tree) => { if (utils_1.supportedSandboxPlatforms.includes(platform)) { const homeCmpPath = `${appDirectory}/features/home/components/home.component.html`; let homeTemplate = test_1.getFileContent(tree, homeCmpPath); 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 featureNameParts = featureName.split("-"); let routeName = featureName; if (featureNameParts.length > 1) { routeName = strings_1.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; } utils_1.createOrUpdate(tree, homeCmpPath, homeTemplate); } else { throw new schematics_1.SchematicsException(`The --adjustSandbox option is only supported on the following at the moment: ${utils_1.supportedSandboxPlatforms}`); } return tree; }; } //# sourceMappingURL=index.js.map