|
| 1 | +import chalk from "chalk" |
| 2 | +import fs from "fs" |
| 3 | +import Generator from "yeoman-generator" |
| 4 | +import prompts from "./prompts.js" |
| 5 | +import { |
| 6 | + lookForParentUI5ProjectAndPrompt, |
| 7 | + addModuleToNPMWorkspaces |
| 8 | +} from "../helpers.js" |
| 9 | +import dependencies from "../dependencies.js" |
| 10 | +import yaml from "yaml" |
| 11 | + |
| 12 | +import ModelGenerator from "../model/index.js" |
| 13 | +import { createRequire } from "node:module" |
| 14 | +const require = createRequire(import.meta.url) |
| 15 | + |
| 16 | +export default class extends Generator { |
| 17 | + static displayName = "Create a new SAP CAP module within an existing OpenUI5/SAPUI5 project" |
| 18 | + |
| 19 | + async prompting() { |
| 20 | + if (this.config.get("platform") === "SAP NetWeaver") { |
| 21 | + this.log(chalk.red("This subgenerator cannot be run if your target deployment platform is SAP NetWeaver.")) |
| 22 | + this.cancelCancellableTasks() |
| 23 | + return |
| 24 | + } |
| 25 | + await lookForParentUI5ProjectAndPrompt.call(this, prompts, true, "Which existing uimodule would you like to connect with your new SAP CAP module?") |
| 26 | + } |
| 27 | + |
| 28 | + async writing() { |
| 29 | + this.log(chalk.green(`✨ creating new SAP CAP module for ${this.options.config.projectName}`)) |
| 30 | + |
| 31 | + // TO-DO: check for typescript and configure cap project accordingly |
| 32 | + this.spawnCommandSync("npx", ["-p", "@sap/cds-dk", "cds", "init", `${this.options.config.capName}`, "--add", "tiny-sample, data, xsuaa, mta, postgres"], |
| 33 | + this.destinationPath() |
| 34 | + ) |
| 35 | + |
| 36 | + addModuleToNPMWorkspaces.call(this, this.options.config.capName) |
| 37 | + } |
| 38 | + |
| 39 | + async install() { |
| 40 | + fs.rmdirSync(this.destinationPath(`${this.options.config.capName}/app`)) |
| 41 | + |
| 42 | + const packageJson = JSON.parse(fs.readFileSync(this.destinationPath(`${this.options.config.capName}/package.json`))) |
| 43 | + delete packageJson["cds"] // go with the cds defaults (no auth required at dev time) |
| 44 | + if (!packageJson["devDependencies"]) packageJson["devDependencies"] = {} |
| 45 | + packageJson["devDependencies"]["@sap/cds-dk"] = dependencies["@sap/cds-dk"] |
| 46 | + packageJson["devDependencies"]["cds-plugin-ui5"] = dependencies["cds-plugin-ui5"] |
| 47 | + packageJson["devDependencies"][this.options.config.uimoduleName] = `../${this.options.config.uimoduleName}` |
| 48 | + packageJson["scripts"]["dev"] = "cds watch" |
| 49 | + packageJson["scripts"]["build"] = "cds build --production" |
| 50 | + fs.writeFileSync(this.destinationPath(`${this.options.config.capName}/package.json`), JSON.stringify(packageJson, null, 4)) |
| 51 | + |
| 52 | + // use parts of generated mta.yaml from "cds init" to enrich root mta.yaml |
| 53 | + const capMtaYaml = yaml.parse(fs.readFileSync(this.destinationPath(`${this.options.config.capName}/mta.yaml`)).toString()) |
| 54 | + const rootMtaYaml = yaml.parse(fs.readFileSync(this.destinationPath("mta.yaml")).toString()) |
| 55 | + if (!rootMtaYaml.resources) rootMtaYaml.resources = [] |
| 56 | + |
| 57 | + const authName = `${this.options.config.projectId}-auth` |
| 58 | + // use auth and xs-security.json from cap module |
| 59 | + if (["Static webserver", "Application Router"].includes(this.options.config.platform)) { |
| 60 | + const capAuth = capMtaYaml.resources.find(resource => resource.name === `${this.options.config.capName}-auth`) |
| 61 | + capAuth.name = authName |
| 62 | + capAuth.parameters.path = `${this.options.config.capName}/xs-security.json` |
| 63 | + if (this.options.config.platform === "Application Router") { |
| 64 | + capAuth.parameters.config["oauth2-configuration"] = { |
| 65 | + "redirect-uris": ["~{approuter/callback-url}"] |
| 66 | + } |
| 67 | + if (!capAuth.requires) capAuth.requires = [] |
| 68 | + capAuth.requires.push({ name: "approuter" }) |
| 69 | + const approuter = rootMtaYaml.modules.find(module => module.name === `${this.options.config.projectId}-approuter`) |
| 70 | + if (!approuter.requires) approuter.requires = [] |
| 71 | + approuter.requires.push({ name: capAuth.name }) |
| 72 | + } |
| 73 | + rootMtaYaml.resources.push(capAuth) |
| 74 | + } |
| 75 | + // use auth and xs-security.json from root |
| 76 | + else if (["SAP HTML5 Application Repository Service", "SAP Build Work Zone, standard edition"].includes(this.options.config.platform)) { |
| 77 | + fs.rename(this.destinationPath("xs-security.json"), `${this.options.config.capName}/xs-security.json`, err => { }) |
| 78 | + const rootAuth = rootMtaYaml.resources.find(resource => resource.name === authName) |
| 79 | + rootAuth.parameters.path = `${this.options.config.capName}/xs-security.json` |
| 80 | + } |
| 81 | + |
| 82 | + const capPostgres = capMtaYaml.resources.find(resource => resource.name === `${this.options.config.capName}-postgres`) |
| 83 | + capPostgres.name = `${this.options.config.projectId}-${capPostgres.name}` |
| 84 | + rootMtaYaml.resources.push(capPostgres) |
| 85 | + |
| 86 | + const capDeployer = capMtaYaml.modules.find(module => module.name === `${this.options.config.capName}-postgres-deployer`) |
| 87 | + capDeployer.path = this.options.config.capName + "/" + capDeployer.path |
| 88 | + capDeployer.name = `${this.options.config.projectId}-${capDeployer.name}` |
| 89 | + capDeployer.requires = [ |
| 90 | + { name: capPostgres.name } |
| 91 | + ] |
| 92 | + rootMtaYaml.modules.push(capDeployer) |
| 93 | + |
| 94 | + const capSrv = capMtaYaml.modules.find(module => module.name === `${this.options.config.capName}-srv`) |
| 95 | + capSrv.path = this.options.config.capName + "/" + capSrv.path |
| 96 | + capSrv.name = `${this.options.config.projectId}-${capSrv.name}` |
| 97 | + capSrv.requires = [ |
| 98 | + { name: capPostgres.name }, |
| 99 | + { name: authName } |
| 100 | + ] |
| 101 | + rootMtaYaml.modules.push(capSrv) |
| 102 | + |
| 103 | + fs.unlinkSync(this.destinationPath(`${this.options.config.capName}/mta.yaml`)) |
| 104 | + this.writeDestination(this.destinationPath("mta.yaml"), yaml.stringify(rootMtaYaml)) |
| 105 | + |
| 106 | + if (this.options.config.runModelSubgenerator) { |
| 107 | + this.composeWith( |
| 108 | + { |
| 109 | + Generator: ModelGenerator, |
| 110 | + path: require.resolve("../model") |
| 111 | + }, |
| 112 | + { |
| 113 | + config: { |
| 114 | + projectId: this.options.config.projectId, |
| 115 | + uimoduleName: this.options.config.uimoduleName, |
| 116 | + platform: this.options.config.platform, |
| 117 | + modelName: "", |
| 118 | + modelType: "OData v4", |
| 119 | + modelUrl: "http://localhost:4004/odata/v4/catalog", |
| 120 | + setupProxy: true, |
| 121 | + setupRouteAndDest: ["Application Router", "SAP HTML5 Application Repository Service", "SAP Build Work Zone, standard edition"].includes(this.options.config.platform), |
| 122 | + destName: this.options.config.capName |
| 123 | + } |
| 124 | + |
| 125 | + } |
| 126 | + ) |
| 127 | + } |
| 128 | + } |
| 129 | +} |
0 commit comments