@sap/cds-dk 9.6.1 → 9.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/bin/add.js +5 -2
  3. package/bin/cds.js +10 -25
  4. package/bin/data-products/import.js +3 -0
  5. package/bin/debug.js +76 -16
  6. package/bin/env.js +2 -1
  7. package/bin/export.js +18 -13
  8. package/bin/help/export.md +2 -1
  9. package/bin/import.js +21 -18
  10. package/bin/init.js +8 -1
  11. package/bin/minify.js +11 -12
  12. package/bin/mock.js +17 -9
  13. package/bin/repl.js +2 -2
  14. package/bin/up.js +34 -4
  15. package/bin/version.js +203 -131
  16. package/lib/build/buildTaskEngine.js +4 -0
  17. package/lib/build/buildTaskFactory.js +6 -36
  18. package/lib/build/index.js +10 -10
  19. package/lib/build/plugin.js +8 -5
  20. package/lib/build/plugins/helm/files/subcharts/content-deployment/Chart.yaml +3 -1
  21. package/lib/build/plugins/helm/files/subcharts/content-deployment/templates/_helpers.tpl +1 -1
  22. package/lib/build/plugins/helm/files/subcharts/content-deployment/templates/job.yaml +8 -0
  23. package/lib/build/plugins/helm/files/subcharts/content-deployment/values.schema.json +18 -0
  24. package/lib/build/plugins/helm/files/subcharts/content-deployment/values.yaml +11 -1
  25. package/lib/build/plugins.js +8 -16
  26. package/lib/build/provider/fiori/index.js +3 -3
  27. package/lib/build/provider/hana/index.js +16 -19
  28. package/lib/build/provider/internalBuildPlugin.js +5 -4
  29. package/lib/build/provider/internalBuildTaskProvider.js +26 -88
  30. package/lib/build/provider/mtx/index.js +0 -8
  31. package/lib/build/provider/mtx-sidecar/index.js +88 -80
  32. package/lib/build/provider/nodejs/index.js +3 -8
  33. package/lib/build/util.js +52 -115
  34. package/lib/deploy/to-hana/hana.js +117 -109
  35. package/lib/env/schemas/cds-rc.js +0 -4
  36. package/lib/import/odata/v4parser.js +80 -56
  37. package/lib/init/constants.js +5 -2
  38. package/lib/init/index.js +48 -41
  39. package/lib/init/merge.js +7 -2
  40. package/lib/init/projectReader.js +3 -8
  41. package/lib/init/template/ams/index.js +1 -4
  42. package/lib/init/template/attachments/files/package.json.hbs +1 -1
  43. package/lib/init/template/completion/completionSetup.js +1 -1
  44. package/lib/init/template/data/as-csv.js +4 -1
  45. package/lib/init/template/data/index.js +1 -1
  46. package/lib/init/template/extension/index.js +4 -4
  47. package/lib/init/template/hana/files/package.json.hbs +3 -3
  48. package/lib/init/template/handler/index.js +1 -1
  49. package/lib/init/template/helm/index.js +3 -3
  50. package/lib/init/template/helm-unified-runtime/index.js +5 -1
  51. package/lib/init/template/html5-repo/files/mta.yaml.hbs +1 -1
  52. package/lib/init/template/html5-repo/index.js +6 -5
  53. package/lib/init/template/ias/files/mta.yaml.hbs +3 -3
  54. package/lib/init/template/initial/files/.vscode/tasks.json +10 -0
  55. package/lib/init/template/{nodejs/files/README.md → initial/files/readme.md} +2 -3
  56. package/lib/init/template/initial/index.js +15 -0
  57. package/lib/init/template/java/index.js +4 -11
  58. package/lib/init/template/kyma/index.js +21 -20
  59. package/lib/init/template/lint/index.js +3 -1
  60. package/lib/init/template/mta/index.js +0 -5
  61. package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +1 -2
  62. package/lib/init/template/multitenancy/files/values.yaml.hbs +30 -0
  63. package/lib/init/template/nodejs/files/.vscode/tasks.json +1 -14
  64. package/lib/init/template/nodejs/files/package.json.hbs +2 -4
  65. package/lib/init/template/nodejs/index.js +8 -12
  66. package/lib/init/template/sample/index.js +5 -6
  67. package/lib/init/template/sqlite/files/package.json.hbs +7 -1
  68. package/lib/init/template/test/index.js +1 -1
  69. package/lib/init/template/tiny-sample/files/nodejs/db/data/CatalogService.Books.csv +6 -0
  70. package/lib/init/template/tiny-sample/files/nodejs/srv/cat-service.cds +5 -0
  71. package/lib/init/template/tiny-sample/index.js +2 -2
  72. package/lib/init/template/workzone-standard/files/mta.yaml.hbs +6 -0
  73. package/lib/init/template/workzone-standard/index.js +13 -3
  74. package/lib/init/template/xsuaa/index.js +1 -1
  75. package/lib/init/validate.js +11 -6
  76. package/lib/util/checksum.js +2 -2
  77. package/lib/util/fs.js +109 -53
  78. package/lib/util/glob.js +2 -1
  79. package/lib/util/term.js +1 -7
  80. package/lib/util/write.js +2 -4
  81. package/lib/watch/watched.js +1 -1
  82. package/npm-shrinkwrap.json +233 -266
  83. package/package.json +2 -2
  84. package/lib/init/template/nodejs/files/.vscode/settings.json +0 -11
  85. package/lib/init/template/tiny-sample/files/nodejs/db/data/my.bookshop-Books.csv +0 -3
  86. package/lib/init/template/tiny-sample/files/nodejs/db/schema.cds +0 -7
  87. package/lib/init/template/tiny-sample/files/nodejs/srv/cat-service.cds.hbs +0 -5
package/lib/init/index.js CHANGED
@@ -1,15 +1,13 @@
1
- const path = require('path')
2
- const term = require('../util/term')
3
- const validate = require('./validate')
4
1
 
5
- const { OPTIONS, COMMAND_INIT, PROJECT_FILES } = require('./constants')
6
- const { readdirSync } = require('fs')
7
- const { join } = require('path')
2
+ const { readdirSync } = require('node:fs')
3
+ const { basename, join, relative, resolve } = require('node:path')
4
+ const { OPTIONS, COMMAND_INIT } = require('./constants'), { JAVA, COMPLETION } = OPTIONS
5
+ const validate = require('./validate')
8
6
  const cmd = require('../util/command')
9
- const { NODEJS, JAVA } = OPTIONS
10
7
 
11
8
  const cds = require('..'), { exists } = cds.utils
12
- const DEBUG = /\b(y|all|cli)\b/.test(process.env.DEBUG) ? console.debug : undefined
9
+ const { BOLD, DIMMED, RESET } = cds.utils.colors
10
+ const DEBUG = /\b(y|all|cli|init|add)\b/.test(process.env.DEBUG) ? console.debug : undefined
13
11
 
14
12
  module.exports = class CDSGenerator {
15
13
 
@@ -71,14 +69,6 @@ module.exports = class CDSGenerator {
71
69
  this._initialize(null);
72
70
  this._greetings();
73
71
 
74
- // `add completion` configures global shell completion and not project settings
75
- // `add data` can live without project metadata
76
- const nonProjectFacets = { completion:1, data:1 }
77
- const needsProject = facets.some(facet => !nonProjectFacets[facet])
78
- if (needsProject && !PROJECT_FILES.some(exists)) {
79
- throw `The current folder doesn't seem to contain a project. None of the following files found: ${PROJECT_FILES.join(', ')}.`
80
- }
81
-
82
72
  await this._process(facets);
83
73
  await this.stepEnd();
84
74
  }
@@ -92,6 +82,7 @@ module.exports = class CDSGenerator {
92
82
  }
93
83
 
94
84
  async stepInit(projectName, options) { // Also used by CAP Generator
85
+ projectName = projectName?.trim();
95
86
  if (options) {
96
87
  // called from CAP generator with options
97
88
  // cds.cli is not set correctly when called from CAP generator
@@ -100,7 +91,7 @@ module.exports = class CDSGenerator {
100
91
  command: COMMAND_INIT,
101
92
  // keep caller independent from internal names
102
93
  options: {
103
- cwd: options.cwd,
94
+ ...options,
104
95
  add: new Set(options.add)
105
96
  },
106
97
  argv:[]
@@ -123,18 +114,13 @@ module.exports = class CDSGenerator {
123
114
  }
124
115
  const { options } = cds.cli
125
116
  this.cwd = options.cwd || process.cwd();
126
- cds.root = path.resolve(this.cwd, projectName || '.');
127
- this.projectName = path.basename(cds.root);
117
+ cds.root = resolve(this.cwd, projectName || '.');
118
+ this.projectName = basename(cds.root);
128
119
 
129
120
  this._cleanupOptions();
130
121
  }
131
122
 
132
123
  _greetings() {
133
- if (cds.cli.command === COMMAND_INIT) {
134
- const relativeProjectPath = path.relative(this.cwd, cds.root)
135
- const folderName = relativeProjectPath ? `.${path.sep}${relativeProjectPath}` : 'the current folder'
136
- console.log(`creating new CAP project in ${term.bold(folderName)}\n`)
137
- }
138
124
  if (cds.cli.options.for && typeof cds.cli.options.for !== 'string') {
139
125
  throw 'the --for argument must not be empty'
140
126
  }
@@ -157,12 +143,14 @@ module.exports = class CDSGenerator {
157
143
  const cmds = Object.values(OPTIONS)
158
144
  const byPriority = (a, b) => cmds.indexOf(a) - cmds.indexOf(b)
159
145
  const sorted = Array.from(plugins).sort(byPriority)
146
+ const skipLogFacets = ['initial', COMPLETION]
160
147
  for (const [i, facet] of Object.entries(sorted)) {
161
- if (!cds.cli.options.dry) console.log(`adding ${term.bold(facet)}`)
148
+ if (!cds.cli.options.dry && !skipLogFacets.includes(facet))
149
+ console.log(`Adding facet: ${BOLD + facet + RESET}`)
162
150
  const template = this.templateList[i]
163
151
  await template.run()
164
152
  }
165
- DEBUG && console.log()
153
+ if ((cds.cli.command !== 'init' || cds.cli.options.add.size !== 1 || !cds.cli.options.add.has('initial')) && !cds.cli.options.dry) console.log()
166
154
  DEBUG && console.log('plugins active for production:')
167
155
  const fromDk = readdirSync(join(__dirname, './template'))
168
156
  const { registered } = require('./add')
@@ -191,19 +179,17 @@ module.exports = class CDSGenerator {
191
179
  await cmd.spawnCommand('npm' , ['i', '--package-lock-only'], { cwd:cds.root })
192
180
  if (exists('mtx/sidecar/package.json') && !exists('mtx/sidecar/package-lock.json')) {
193
181
  console.log('updating frozen dependencies in mtx/sidecar/package-lock.json…')
194
- await cmd.spawnCommand('npm', ['i', '--package-lock-only'], { cwd: path.join(cds.root, 'mtx/sidecar') })
182
+ await cmd.spawnCommand('npm', ['i', '--package-lock-only', '--prefix', 'mtx/sidecar'], { cwd:cds.root })
195
183
  }
196
184
  }
197
185
 
198
186
  if (cds.cli.command === COMMAND_INIT) {
199
- const relativeProjectPath = path.relative(this.cwd, cds.root)
200
- let message = 'successfully created project'
201
- if (relativeProjectPath) {
202
- message += ` – continue with ${term.bold('cd ' + relativeProjectPath)}`
203
- }
204
- console.log('\n' + message)
187
+ console.log ('Successfully initialized CAP project')
188
+ let relativeProjectPath = relative(this.cwd, cds.root)
189
+ if (relativeProjectPath)
190
+ console.log ('Continue with:', BOLD +'code', relativeProjectPath, RESET)
205
191
  } else if (!cds.cli.options.dry) {
206
- console.log(`\nsuccessfully added features to your project`)
192
+ console.log(`Successfully added features to your project`)
207
193
  }
208
194
  }
209
195
 
@@ -219,10 +205,10 @@ module.exports = class CDSGenerator {
219
205
  const max = entries.reduce((max, {name}) => Math.max(max, name.length), 0)
220
206
  const allFacetsText = entries.filter(({module})=> module.help()).map(({name, module}) => {
221
207
  const help = module.help?.() ?? ''
222
- return `${term.bold(name) + ' '.repeat(max - name.length)} ${term.dim(help)}`
208
+ return `${BOLD+ name +RESET + ' '.repeat(max - name.length)} ${DIMMED+ help +RESET}`
223
209
  }).join('\n')
224
210
  DEBUG?.(err)
225
- throw `unknown facet ${term.bold(plugin)} – did you mean ${term.bold(`cds add ${bestMatch}`)}?\n\nall supported facets:\n\n${allFacetsText}\n`
211
+ throw `unknown facet ${BOLD+ plugin +RESET} – did you mean ${BOLD + `cds add ` + bestMatch + RESET}?\n\nall supported facets:\n\n${allFacetsText}\n`
226
212
  }
227
213
  throw err
228
214
  }
@@ -231,14 +217,14 @@ module.exports = class CDSGenerator {
231
217
  async _fillTemplateList(plugins) {
232
218
  const templates = new Map
233
219
  for (let plugin of plugins) {
234
- // cds 10 remove
235
- if(plugin === "helm" || plugin === "helm-unified-runtime") {
220
+ // cds10: remove
221
+ if (plugin === "helm" || plugin === "helm-unified-runtime") {
236
222
  cds.cli.options.add?.add("kyma")
237
223
  cds.cli.argv[0] += ",kyma"
238
224
  }
239
225
  // Compat
240
226
  if (plugin === 'helm' && cds.cli.options['internal-unified-runtime-charts']) {
241
- console.warn(term.warn('"--internal-unified-runtime-charts" is deprecated, please use "cds add kyma --unified-runtime" instead'))
227
+ console.warn('"--internal-unified-runtime-charts" is deprecated, please use "cds add kyma --unified-runtime" instead')
242
228
  plugin = 'helm-unified-runtime'
243
229
  cds.cli.options.add?.delete('helm')
244
230
  cds.cli.options.add?.add('helm-unified-runtime')
@@ -258,6 +244,21 @@ module.exports = class CDSGenerator {
258
244
  _alias('kibana', 'application-logging')
259
245
  _alias('kibana-logging', 'application-logging')
260
246
 
247
+ const runtimeAgnostic = { initial:1, 'tiny-sample':1, data:1, completion: 1 }
248
+ if (!(plugin in runtimeAgnostic)) {
249
+ const creating = ['java', 'nodejs', 'typescript', 'esm', 'extension']
250
+ const { command, options, argv } = cds.cli
251
+ const inOptions = option => command === 'init' && options.add.has(option) ||
252
+ command === 'add' && argv[0]?.split(',').includes(option)
253
+ if (!exists('pom.xml') && !exists('package.json') && !creating.some(inOptions)) {
254
+ if (command === 'init') {
255
+ const project = argv[0] ? argv[0]+' ' : ''
256
+ throw `First decide if this is a Node.js or Java project. Either run\n ${BOLD+`cds init ${project}--java`+RESET} ...\nor\n ${BOLD+`cds init ${project}--nodejs`+RESET} ...\n`
257
+ }
258
+ throw `First decide if this is a Node.js or Java project. Either run\n ${BOLD+'cds add nodejs'+RESET}\nor\n ${BOLD+'cds add java'+RESET}\n`
259
+ }
260
+ }
261
+
261
262
  if (!templates.has(plugin)) {
262
263
  const template = await this._createTemplate(plugin)
263
264
  if (await template.canRun()) {
@@ -313,15 +314,21 @@ module.exports = class CDSGenerator {
313
314
  return facet;
314
315
  }).filter(Boolean);
315
316
 
316
- // set is ordered ... always
317
317
  options.add = new Set(trimmedTokens);
318
318
 
319
+ if (options?.nodejs) { // --nodejs -> --add nodejs
320
+ options.add.add('nodejs')
321
+ }
319
322
  if (options?.java) { // --java -> --add java
320
323
  options.add.add('java')
321
324
  }
322
325
 
323
326
  if (cds.cli.command === COMMAND_INIT && !options.add.has(JAVA)) {
324
- options.add.add(NODEJS);
327
+ options.add.add('initial')
328
+
329
+ // cds10: remove
330
+ const { isBas } = require('./projectReader').readProject()
331
+ if (isBas) options.add.add('nodejs')
325
332
  }
326
333
  }
327
334
  }
package/lib/init/merge.js CHANGED
@@ -326,8 +326,13 @@ async function _mergeYAML(into, from, project, semantics = {}) {
326
326
  let [,parent] = collectionStack
327
327
  additions?.filter(addition => {
328
328
  if (typeof addition.in === 'string' || Array.isArray(addition.in) && typeof addition.in[0] === 'string') return true
329
- const inEntry = Array.isArray(addition.in) ? entryMap.get(addition.in[0]) : entryMap.get(addition.in)
330
- return inEntry?.node === parent
329
+ const base = Array.isArray(addition.in) ? addition.in[0] : addition.in
330
+ const keyPath = Array.isArray(addition.in) ? addition.in[1] : ''
331
+ const inEntry = entryMap.get(base)
332
+ if (!inEntry) return false
333
+ const depth = String(keyPath).split('.').filter(Boolean).length
334
+ const expectedParent = depth > 1 ? collectionStack[depth] : parent
335
+ return inEntry.node === expectedParent
331
336
  })
332
337
  .filter(addition => {
333
338
  const keyPath = typeof addition.in === 'string' ? addition.in : Array.isArray(addition.in) && typeof addition.in[0] === 'string' ? addition.in[0] : addition.in[1]
@@ -90,6 +90,7 @@ module.exports = new class ProjectReader {
90
90
  has: x => _inProd(x),
91
91
  profile: () => cds.cli.options?.for,
92
92
  profileSpecified: () => !!cds.cli.options.for,
93
+ profileProduction: () => cds.cli.options?.for === 'production',
93
94
  language: () => _isJava() ? 'java' : 'nodejs',
94
95
  isJava: () => _isJava(),
95
96
  isNodejs: () => !_isJava(),
@@ -193,14 +194,7 @@ module.exports = new class ProjectReader {
193
194
  values: values ?? {},
194
195
  containerize: containerize ?? {}
195
196
  }
196
- },
197
- hasHelmUnifiedRuntime: () =>
198
- exists(join(cds.root, 'chart', 'Chart.yaml')) &&
199
- (() => {
200
- const chartYaml = cds.load.yaml(join(cds.root, 'chart', 'Chart.yaml'))
201
- return chartYaml.annotations?.['app.kubernetes.io/managed-by'] === 'cds-dk/helm'
202
- && chartYaml.dependencies?.find(dep => dep.name === 'web-application')?.repository !== undefined
203
- })()
197
+ }
204
198
  }
205
199
 
206
200
  // Automatically creates availability checks for `cds add` commands.
@@ -337,4 +331,5 @@ function _normalizeSpringBootCfg(obj) {
337
331
  * @property {String} githubSlug GitHub org/repo.
338
332
  * @property {boolean} isMonorepoMicroservice Indicates if the project is a monorepo microservice.
339
333
  * @property {String} npmWorkspaceRoot The root path of the monorepo workspace.
334
+ * @property {String} isBas Indicates if the project is running in Business Application Studio (BAS).
340
335
  */
@@ -28,7 +28,7 @@ module.exports = class AmsTemplate extends require('../../plugin') {
28
28
 
29
29
  async combine() {
30
30
  const project = readProject()
31
- const { addMta, addCfManifest, addContainerize, addKyma } = project
31
+ const { addMta, addCfManifest, addKyma } = project
32
32
 
33
33
  if (addMta) {
34
34
  await this.#combineWithMta(project)
@@ -40,9 +40,6 @@ module.exports = class AmsTemplate extends require('../../plugin') {
40
40
 
41
41
  if (addKyma) {
42
42
  await this.#combineWithHelm(project)
43
- }
44
-
45
- if (addContainerize) {
46
43
  await this.#combineWithContainerize(project)
47
44
  }
48
45
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "dependencies": {
3
- "@cap-js/attachments": "^2"
3
+ "@cap-js/attachments": "^3"
4
4
  }
5
5
  }
@@ -90,7 +90,7 @@ module.exports = new class CompletionSetup {
90
90
  profileFile = '.config/fish/config.fish';
91
91
  break;
92
92
  default:
93
- throw `Completion is only supported for ${SUPPORTED_LINUX_SHELLS.join(', ')}.`;
93
+ throw `Current shell is '${shell}'. Completion is only supported for ${SUPPORTED_LINUX_SHELLS.join(', ')}.`;
94
94
  }
95
95
 
96
96
  profileFile = path.join(os.homedir(), profileFile);
@@ -28,7 +28,10 @@ module.exports = async (data={}, csn, { headerOnly=false, separator=',' }={}) =>
28
28
  if (value === undefined)
29
29
  continue
30
30
  if (element._type === 'cds.Composition') {
31
- data[element.target] = value // Add object for a new entity. Next pass will process it.
31
+ const t = element.target
32
+ if (data[t] === undefined) {
33
+ data[t] = value // Add object for a new entity. Next pass will process it.
34
+ }
32
35
  }
33
36
  else if (element._type === 'cds.Association') {
34
37
  if (element.on) {
@@ -68,7 +68,7 @@ module.exports = class DataTemplate extends require('../../plugin') {
68
68
  : getDefaultTargetFolder(env)
69
69
  dest = resolve(cds.root, dest)
70
70
 
71
- let csn = await cds.load([cds.env.roots, join(`${cds.env.folders.srv}`, `external`) ]) // normal CSN. Default paths and models imported with `cds import`
71
+ let csn = await cds.load([...cds.env.roots, join(`${cds.env.folders.srv}`, `external`) ]) // normal CSN. Default paths and models imported with `cds import`
72
72
  // Skip of unused reuse entities like Language, Country, Currency
73
73
  csn = cds.minify(csn)
74
74
  csn = cds.reflect(csn) // reflected model (adds additional helper functions)
@@ -7,6 +7,10 @@ const npmPackageRegex = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/
7
7
 
8
8
  module.exports = class ExtensionProjectTemplate extends require('../../plugin') {
9
9
 
10
+ requires() {
11
+ return ['nodejs']
12
+ }
13
+
10
14
  static help() {
11
15
  return 'extension project'
12
16
  }
@@ -72,10 +76,6 @@ module.exports = class ExtensionProjectTemplate extends require('../../plugin')
72
76
  }
73
77
 
74
78
  }
75
-
76
- // async finalize() {
77
- // console.log(`For information on project "Piper" and its pipelines see ${URLS.PIPELINE_HELP}`);
78
- // }
79
79
  }
80
80
 
81
81
  function namespacify(s) {
@@ -2,9 +2,8 @@
2
2
  {{#isNodejs}}
3
3
  "dependencies": {
4
4
  "@cap-js/hana": "^2"
5
- },
5
+ }{{#profile}},
6
6
  "cds": {
7
- {{#profile}}
8
7
  "requires": {
9
8
  "[{{profile}}]": {
10
9
  {{#shortcut}}
@@ -16,8 +15,9 @@
16
15
  }
17
16
  {{/shortcut}}
18
17
  }
19
- }{{/profile}}
18
+ }
20
19
  }
20
+ {{/profile}}
21
21
  {{/isNodejs}}
22
22
  {{#isJava}}
23
23
  "requires": {
@@ -155,7 +155,7 @@ async function createExtCodeHandler(service, proj, out, force) {
155
155
  */
156
156
  async function loadModel() {
157
157
  try {
158
- return cds.linked(cds.minify(await cds.load([cds.env.roots])))
158
+ return cds.linked(cds.minify(await cds.load(cds.env.roots)))
159
159
  } catch (err) {
160
160
  if (err.code === 'MODEL_NOT_FOUND') return null
161
161
  throw new Error(`Error compiling CDS files. Run 'npm install' and try again.`, {cause:err})
@@ -22,9 +22,9 @@ module.exports = class HelmTemplate extends require('../../plugin') {
22
22
  async canRun() {
23
23
  const hasInProduction = HelmTemplate.hasInProduction()
24
24
  if (cds.cli.options.force) {
25
- await rimraf(join('chart'))
25
+ await rimraf('chart')
26
26
  return true
27
- } else if (exists(join(cds.root, 'chart')) && !hasInProduction) {
27
+ } else if (exists('chart') && !hasInProduction) {
28
28
  throw `Chart already exists. Use --force to overwrite.`
29
29
  }
30
30
  return true
@@ -60,7 +60,7 @@ module.exports = class HelmTemplate extends require('../../plugin') {
60
60
  domain ??= await ask4([`cluster domain: `])
61
61
  }
62
62
  }
63
- project.registry = registry ?? '<registry-server>'
63
+ project.registry = registry ?? '<your-container-registry-server>'
64
64
  project.domain = domain ?? '<cluster-domain>'
65
65
  project.imagePullSecret = imagePullSecret ?? 'docker-registry'
66
66
  project.tag = tag ?? 'latest'
@@ -29,7 +29,11 @@ module.exports = class HelmUnifiedRuntimeTemplate extends require('../helm') {
29
29
  }
30
30
 
31
31
  static hasInProduction() {
32
- if (cds.cli.options?.add?.has('helm-unified-runtime')) return true
32
+ if (cds.cli.options?.add?.has('helm-unified-runtime') ||
33
+ cds.cli.options['unified-runtime']) {
34
+
35
+ return true
36
+ }
33
37
 
34
38
  if (exists(join(cds.root, 'chart', 'Chart.yaml'))) {
35
39
  const chartFile = readFileSync(join(cds.root, 'chart', 'Chart.yaml'), 'utf8')
@@ -34,7 +34,7 @@ modules:
34
34
  content-target: true
35
35
  config:
36
36
  HTML5Runtime_enabled: true{{#hasIas}}
37
- IASDependencyName: {{appName}}-api{{/hasIas}}
37
+ IASDependencyName: {{appName}}-ias-api{{/hasIas}}
38
38
  build-parameters:
39
39
  build-result: {{#isNodejs}}{{& appPath }}{{/isNodejs}}{{#isJava}}resources{{/isJava}}
40
40
  requires:
@@ -37,8 +37,8 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
37
37
  const project = readProject()
38
38
  const {
39
39
  isJava, srvPath, appPath, apps,
40
- hasApprouter, addApprouter, addContainerize, addKyma, addHelm, addHelmUnifiedRuntime, addMultitenancy, addWorkzoneStandard, addXsuaa,
41
- addSample, hasMta, addMta, hasXsuaa, hasMultitenancy, hasUI5
40
+ hasApprouter, hasMta, addMta, hasKyma, hasXsuaa, hasMultitenancy, hasUI5,
41
+ addSample, addApprouter, addContainerize, addKyma, addHelm, addHelmUnifiedRuntime, addMultitenancy, addWorkzoneStandard, addXsuaa, addIas
42
42
  } = project
43
43
 
44
44
  await Promise.all(apps.map(async ({ app }) => {
@@ -65,7 +65,8 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
65
65
  await merge({ cds: { requires: { 'html5-repo': true } } }).into('mtx/sidecar/package.json')
66
66
  }
67
67
 
68
- if (addMta || (addXsuaa || addApprouter || addWorkzoneStandard || addMultitenancy || addSample) && hasMta) {
68
+ const affected = addXsuaa || addApprouter || addWorkzoneStandard || addMultitenancy || addSample || addIas
69
+ if (addMta || affected && hasMta) {
69
70
  const srv = srv4(srvPath)
70
71
  project.apps = apps
71
72
  const relationships = [{
@@ -109,7 +110,7 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
109
110
  })
110
111
  }
111
112
 
112
- // cds10
113
+ // cds10: change to if (addKyma)
113
114
  // needed because of adding kyma to cli options in case of helm
114
115
  if (addContainerize || (addKyma && !addHelm && !addHelmUnifiedRuntime)) {
115
116
  const additions = [{
@@ -119,7 +120,7 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
119
120
  await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project, additions })
120
121
  }
121
122
 
122
- if (addKyma) {
123
+ if (addKyma || affected && hasKyma) {
123
124
  await renderAndCopy(join(__dirname, 'files/html5-deployer.package.json.hbs'), 'app/html5-deployer/package.json', project)
124
125
  await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
125
126
  }
@@ -66,10 +66,10 @@ resources:
66
66
  access-token-format: "jwt"
67
67
  {{#hasApprouter}}
68
68
  redirect-uris:
69
- - ~{app-api/app-protocol}://*.~{app-api/app-uri}/login/callback
70
- - ~{app-api/app-protocol}://~{app-api/app-uri}/login/callback
69
+ - http://localhost:5000/login/callback?authType=ias
70
+ - ~{app-api/app-protocol}://*~{app-api/app-uri}/login/callback
71
71
  post-logout-redirect-uris:
72
- - ~{app-api/app-protocol}://*.~{app-api/app-uri}/*/logout.html
72
+ - ~{app-api/app-protocol}://*~{app-api/app-uri}/*/logout.html
73
73
  {{/hasApprouter}}
74
74
  {{#hasAms}}
75
75
  authorization:
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": "2.0.0",
3
+ "tasks": [
4
+ {
5
+ "type": "shell",
6
+ "label": "cds watch",
7
+ "command": "cds watch",
8
+ }
9
+ ]
10
+ }
@@ -1,6 +1,6 @@
1
1
  # Getting Started
2
2
 
3
- Welcome to your new project.
3
+ Welcome to your new CAP project.
4
4
 
5
5
  It contains these folders and files, following our recommended project layout:
6
6
 
@@ -9,7 +9,6 @@ File or Folder | Purpose
9
9
  `app/` | content for UI frontends goes here
10
10
  `db/` | your domain models and data go here
11
11
  `srv/` | your service models and code go here
12
- `package.json` | project metadata and configuration
13
12
  `readme.md` | this getting started guide
14
13
 
15
14
 
@@ -22,4 +21,4 @@ File or Folder | Purpose
22
21
 
23
22
  ## Learn More
24
23
 
25
- Learn more at https://cap.cloud.sap/docs/get-started/.
24
+ Learn more at https://cap.cloud.sap.
@@ -0,0 +1,15 @@
1
+ const { join } = require('path')
2
+ const cds = require('../../../cds')
3
+ const { mkdirp, path } = cds.utils
4
+ const { env4 } = require('../../projectReader')
5
+ const { renderAndCopy } = require('../../template')
6
+
7
+ module.exports = class extends require('../../plugin') {
8
+
9
+ async run() {
10
+ const { db, srv, app } = env4('production').folders
11
+ await renderAndCopy(join(__dirname, 'files'), cds.root, { projectName: path.basename(cds.root) })
12
+ await Promise.all([db, srv, app].map(p => mkdirp(p)))
13
+ }
14
+
15
+ }
@@ -4,9 +4,9 @@ const { exists, copy, rimraf, fs:{promises:{ mkdtemp }}, path } = cds.utils, { j
4
4
  const cmd = require('../../../util/command')
5
5
  const mvn = require('../../mvn')
6
6
  const { merge } = require('../../merge')
7
- const { bold, info, link } = require('../../../util/term')
8
- const { URLS, OPTIONS: { NODEJS, JAVA }, COMMAND_ADD } = require('../../constants')
9
- const { command, options } = cds.cli
7
+ const { bold, info } = require('../../../util/term')
8
+ const { URLS, OPTIONS: { NODEJS, JAVA } } = require('../../constants')
9
+ const { options } = cds.cli
10
10
 
11
11
  module.exports = class JavaTemplate extends require('../../plugin') {
12
12
 
@@ -15,13 +15,10 @@ module.exports = class JavaTemplate extends require('../../plugin') {
15
15
  }
16
16
 
17
17
  static hasInProduction() {
18
- return exists('pom.xml') || options?.add?.has(JAVA)
18
+ return exists('pom.xml')
19
19
  }
20
20
 
21
21
  async canRun() {
22
- if (command === COMMAND_ADD) {
23
- throw `You can't change the runtime of an existing project.`
24
- }
25
22
  if (options.add?.has(NODEJS)) {
26
23
  throw `only one runtime per project is supported – specify either ${bold(JAVA)} or ${bold(NODEJS)}`
27
24
  }
@@ -59,8 +56,4 @@ module.exports = class JavaTemplate extends require('../../plugin') {
59
56
  await rimraf(temp)
60
57
  }
61
58
  }
62
-
63
- async finalize() {
64
- console.log(`learn about next steps at ${link(URLS.CAPIRE)}`)
65
- }
66
59
  }
@@ -9,17 +9,28 @@ const { mvn } = require('../../add')
9
9
 
10
10
  module.exports = class KymaTemplate extends require('../../plugin') {
11
11
 
12
- static hasInProduction() {
13
- return exists('chart/Chart.yaml')
12
+ options() {
13
+ return {
14
+ 'unified-runtime': {
15
+ type: 'boolean'
16
+ },
17
+ 'y': {
18
+ type: 'boolean',
19
+ }
14
20
  }
21
+ }
22
+
23
+ static hasInProduction() {
24
+ return exists('chart/Chart.yaml')
25
+ }
15
26
 
16
27
  async canRun() {
17
28
  const hasInProduction = KymaTemplate.hasInProduction()
18
29
  if (cds.cli.options.force) {
19
- await rimraf(join('chart'))
30
+ await rimraf('chart')
20
31
  await rimraf('containerize.yaml')
21
32
  return true
22
- } else if (hasInProduction) {
33
+ } else if (exists('chart') && !hasInProduction) {
23
34
  throw `Chart already exists. Use --force to overwrite.`
24
35
  }
25
36
  return true
@@ -31,7 +42,6 @@ module.exports = class KymaTemplate extends require('../../plugin') {
31
42
 
32
43
  async run() {
33
44
  const project = readProject()
34
-
35
45
  let imagePullSecret, registry, domain, tag
36
46
  if (!KymaTemplate.hasInProduction() && !project.isBas /* don't run this for the BAS Yeoman generator */) {
37
47
  try {
@@ -40,7 +50,7 @@ module.exports = class KymaTemplate extends require('../../plugin') {
40
50
  if (domainStartIndex !== -1) domain = domainGuess.substring(domainStartIndex + 4)
41
51
  } catch (error) { /* ignore */ }
42
52
 
43
- //REVISIT: remove cds10
53
+ // cds10: remove
44
54
  if (exists('containerize.yaml')) {
45
55
  const { repository: r, tag: t } = yaml.parse(join(cds.root, 'containerize.yaml'))
46
56
  if (r) registry = r
@@ -51,30 +61,19 @@ module.exports = class KymaTemplate extends require('../../plugin') {
51
61
  domain ??= await ask4([`cluster domain: `])
52
62
  }
53
63
  }
54
- project.registry = registry ?? '<registry-server>'
64
+ project.registry = registry ?? '<your-container-registry-server>'
55
65
  project.domain = domain ?? '<cluster-domain>'
56
66
  project.imagePullSecret = imagePullSecret ?? 'docker-registry'
57
67
  project.tag = tag ?? 'latest'
58
68
  await copy(join(__dirname, 'files', 'values.schema.json')).to('chart/values.schema.json')
59
69
  await merge(__dirname, 'files/Chart.yaml.hbs').into('chart/Chart.yaml', { with: project })
60
70
  await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
61
- await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project })
71
+ await merge(__dirname, 'files/containerize.yaml.hbs').into('containerize.yaml', { with: project })
62
72
  await KymaTemplate.mergeDependency('web-application', 'srv')
63
73
  if (project.isJava) await mvn.add('k8s')
64
74
 
65
75
  }
66
76
 
67
- options() {
68
- return {
69
- 'unified-runtime': {
70
- type: 'boolean'
71
- },
72
- 'y': {
73
- type: 'boolean',
74
- }
75
- }
76
- }
77
-
78
77
  async combine() {
79
78
  // REVISIT: This must be moved to the respective plugins
80
79
  const {
@@ -105,6 +104,7 @@ module.exports = class KymaTemplate extends require('../../plugin') {
105
104
  if (addHana || addMultitenancy) {
106
105
  if (hasMultitenancy) {
107
106
  await KymaTemplate.mergeDependency('service-instance', 'service-manager')
107
+ await KymaTemplate.mergeDependency('content-deployment', 'mtx-upgrade')
108
108
  } else {
109
109
  await KymaTemplate.mergeDependency('service-instance', 'hana')
110
110
  await KymaTemplate.mergeDependency('content-deployment', 'hana-deployer')
@@ -127,7 +127,8 @@ module.exports = class KymaTemplate extends require('../../plugin') {
127
127
  additions: [{
128
128
  in: 'dependencies',
129
129
  where: { alias }
130
- }]}
130
+ }]
131
+ }
131
132
  )
132
133
 
133
134
  }