@sap/cds-dk 7.9.5 → 8.0.2

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 (283) hide show
  1. package/CHANGELOG.md +2116 -0
  2. package/bin/add.js +18 -52
  3. package/bin/bind.js +2 -2
  4. package/bin/build.js +29 -4
  5. package/bin/cds.js +23 -11
  6. package/bin/compile/index.js +7 -6
  7. package/bin/completion/index.js +70 -46
  8. package/bin/completion/scripts/cds-bash.sh +4 -1
  9. package/bin/completion/scripts/cds-fish.fish +13 -0
  10. package/bin/completion/scripts/cds-ps.ps1 +2 -1
  11. package/bin/completion/scripts/cds-zsh.sh +2 -1
  12. package/bin/deploy/index.js +6 -5
  13. package/bin/deploy/to-sqlite.js +2 -2
  14. package/bin/extend.js +19 -50
  15. package/bin/help.js +2 -2
  16. package/bin/init.js +10 -77
  17. package/bin/login.js +13 -5
  18. package/bin/migrate.js +1 -1
  19. package/bin/pull.js +11 -0
  20. package/bin/repl.js +3 -0
  21. package/bin/test.js +5 -0
  22. package/bin/version.js +7 -7
  23. package/bin/watch.js +1 -10
  24. package/lib/bind/KubernetesApiAccessor.js +10 -9
  25. package/lib/build/buildTaskEngine.js +11 -7
  26. package/lib/build/buildTaskFactory.js +15 -43
  27. package/lib/build/buildTaskProviderFactory.js +16 -44
  28. package/lib/build/constants.js +3 -3
  29. package/lib/build/index.js +2 -2
  30. package/lib/build/{buildPlugin.js → plugin.js} +65 -46
  31. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/Chart.yaml +1 -1
  32. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/values.yaml +1 -1
  33. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/Chart.yaml +1 -1
  34. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/templates/_helpers.tpl +7 -0
  35. package/lib/build/plugins/helm/files/subcharts/service-instance/templates/servicebinding.yaml +32 -0
  36. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/templates/serviceinstance.yaml +3 -0
  37. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/values.schema.json +63 -0
  38. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/values.yaml +23 -1
  39. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/Chart.yaml +1 -1
  40. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/deployment.yaml +2 -0
  41. package/lib/build/plugins/helm/files/subcharts/web-application/templates/hpa.yaml +22 -0
  42. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/pod-disruption-budget.yaml +1 -0
  43. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/values.schema.json +49 -0
  44. package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/values.yaml +8 -2
  45. package/lib/{init/template/helm/files/chart → build/plugins/helm/files}/templates/_deployment_helpers.tpl +5 -0
  46. package/lib/build/plugins/helm/files/templates/_helpers.tpl +13 -0
  47. package/lib/build/plugins/helm/index.js +81 -0
  48. package/lib/build/plugins.js +12 -15
  49. package/lib/build/provider/featureToggleBuildPlugin.js +7 -39
  50. package/lib/build/provider/hana/2migration.js +168 -124
  51. package/lib/build/provider/hana/index.js +20 -25
  52. package/lib/build/provider/hana/template/package.json +4 -3
  53. package/lib/build/provider/internalBuildPlugin.js +32 -97
  54. package/lib/build/provider/internalBuildTaskProvider.js +10 -46
  55. package/lib/build/provider/java/index.js +2 -3
  56. package/lib/build/provider/mtx/index.js +5 -4
  57. package/lib/build/provider/mtx-extension/index.js +5 -2
  58. package/lib/build/provider/mtx-sidecar/index.js +2 -2
  59. package/lib/build/util.js +83 -12
  60. package/lib/compile/to-mermaid.js +108 -0
  61. package/lib/compile/to_asyncapi.js +7 -0
  62. package/lib/compile/to_openapi.js +7 -0
  63. package/lib/deploy/to-hana/hana.js +37 -34
  64. package/lib/deploy/to-hana/hdiDeployUtil.js +8 -6
  65. package/lib/env/schemas/cds-rc.js +1 -1
  66. package/lib/import/common.js +2 -2
  67. package/lib/import/odata/metadataconverter/MetadataConverter.js +4 -4
  68. package/lib/import/odata/v2parser.js +83 -197
  69. package/lib/import/odata/v4parser.js +1 -38
  70. package/lib/import/openapi/importOpenAPI.js +164 -42
  71. package/lib/index.js +10 -12
  72. package/lib/init/bas.js +91 -0
  73. package/lib/init/constants.js +16 -10
  74. package/lib/init/index.js +72 -150
  75. package/lib/init/merge.js +12 -20
  76. package/lib/init/mvn.js +103 -150
  77. package/lib/init/plugin.js +11 -7
  78. package/lib/init/projectReader.js +53 -19
  79. package/lib/init/registries/mta.js +51 -6
  80. package/lib/init/template/application-logging/files/package.json.hbs +7 -0
  81. package/lib/init/template/application-logging/index.js +13 -1
  82. package/lib/init/template/approuter/files/containerize.yaml.hbs +10 -0
  83. package/lib/init/template/approuter/files/mta.yaml.hbs +1 -2
  84. package/lib/init/template/approuter/files/values.yaml.hbs +19 -4
  85. package/lib/init/template/approuter/files/xs-app.json.hbs +12 -3
  86. package/lib/init/template/approuter/index.js +29 -25
  87. package/lib/init/template/attachments/files/mta.yaml.hbs +14 -0
  88. package/lib/init/template/attachments/files/package.json.hbs +5 -0
  89. package/lib/init/template/attachments/files/values.yaml +7 -0
  90. package/lib/init/template/attachments/index.js +53 -0
  91. package/lib/init/template/audit-logging/files/mta.yaml.hbs +14 -0
  92. package/lib/init/template/audit-logging/files/package.json.hbs +7 -0
  93. package/lib/init/template/audit-logging/index.js +66 -0
  94. package/lib/init/template/cf-manifest/index.js +4 -0
  95. package/lib/init/template/completion/completionSetup.js +54 -33
  96. package/lib/init/template/completion/index.js +7 -1
  97. package/lib/init/template/connectivity/index.js +4 -4
  98. package/lib/init/template/containerize/files/containerize.yaml.hbs +26 -0
  99. package/lib/init/template/containerize/index.js +24 -0
  100. package/lib/init/template/data/index.js +4 -0
  101. package/lib/init/template/destination/files/mta.yaml.hbs +25 -1
  102. package/lib/init/template/destination/index.js +12 -2
  103. package/lib/init/template/enterprise-messaging/index.js +6 -3
  104. package/lib/init/template/enterprise-messaging-shared/index.js +5 -1
  105. package/lib/init/template/extensibility/files/package.json.hbs +1 -1
  106. package/lib/init/template/extensibility/files/xs-security.json.hbs +2 -8
  107. package/lib/init/template/extensibility/index.js +3 -1
  108. package/lib/init/template/file-based-messaging/index.js +4 -0
  109. package/lib/init/template/h2/index.js +4 -0
  110. package/lib/init/template/hana/files/containerize.yaml.hbs +10 -0
  111. package/lib/init/template/hana/files/db/package.json +3 -2
  112. package/lib/init/template/hana/files/package.json.hbs +4 -7
  113. package/lib/init/template/hana/files/values.yaml.hbs +1 -2
  114. package/lib/init/template/hana/index.js +15 -7
  115. package/lib/init/template/helm/files/Chart.yaml.hbs +2 -3
  116. package/lib/init/template/helm/files/values.schema.json +2173 -0
  117. package/lib/init/template/helm/files/values.yaml.hbs +11 -6
  118. package/lib/init/template/helm/index.js +77 -18
  119. package/lib/init/template/helm-unified-runtime/index.js +19 -56
  120. package/lib/init/template/html5-repo/files/app-package.json.hbs +11 -7
  121. package/lib/init/template/html5-repo/files/manifest.json +13 -0
  122. package/lib/init/template/html5-repo/files/mta.yaml.hbs +41 -8
  123. package/lib/init/template/html5-repo/files/ui5-deploy.yaml.hbs +21 -0
  124. package/lib/init/template/html5-repo/files/ui5.yaml.hbs +2 -29
  125. package/lib/init/template/html5-repo/files/values.yaml.hbs +6 -2
  126. package/lib/init/template/html5-repo/files/xs-app.json.hbs +21 -8
  127. package/lib/init/template/html5-repo/index.js +33 -30
  128. package/lib/init/template/http/index.js +36 -12
  129. package/lib/init/template/java/index.js +18 -12
  130. package/lib/init/template/kafka/index.js +4 -0
  131. package/lib/init/template/lint/index.js +7 -2
  132. package/lib/init/template/liquibase/index.js +4 -0
  133. package/lib/init/template/local-messaging/index.js +4 -0
  134. package/lib/init/template/malware-scanner/files/mta.yaml.hbs +14 -0
  135. package/lib/init/template/malware-scanner/files/package.json.hbs +17 -0
  136. package/lib/init/template/malware-scanner/files/values.yaml +7 -0
  137. package/lib/init/template/malware-scanner/index.js +47 -0
  138. package/lib/init/template/mta/files/mta.yaml.hbs +3 -3
  139. package/lib/init/template/mta/files/package.json +1 -1
  140. package/lib/init/template/mta/index.js +4 -0
  141. package/lib/init/template/mtx/index.js +4 -0
  142. package/lib/init/template/multitenancy/files/containerize.yaml.hbs +10 -0
  143. package/lib/init/template/multitenancy/files/mta.yaml.hbs +0 -1
  144. package/lib/init/template/multitenancy/files/package.json.hbs +1 -1
  145. package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +6 -5
  146. package/lib/init/template/multitenancy/files/values.yaml.hbs +14 -24
  147. package/lib/init/template/multitenancy/index.js +50 -28
  148. package/lib/init/template/nodejs/files/eslint.config.mjs +2 -0
  149. package/lib/init/template/nodejs/files/package.json.hbs +2 -3
  150. package/lib/init/template/nodejs/index.js +4 -0
  151. package/lib/init/template/notifications/files/mta.yaml.hbs +2 -2
  152. package/lib/init/template/notifications/index.js +4 -0
  153. package/lib/init/template/pipeline/files/.pipeline/config.yml +1 -1
  154. package/lib/init/template/pipeline/files/Jenkinsfile +1 -1
  155. package/lib/init/template/pipeline/index.js +4 -0
  156. package/lib/init/template/portal/files/mta.yaml.hbs +52 -0
  157. package/lib/init/template/portal/files/package.json.hbs +11 -0
  158. package/lib/init/template/portal/files/package.sidecar.json +7 -0
  159. package/lib/init/template/portal/files/portal-site/CommonDataModel.json.hbs +97 -0
  160. package/lib/init/template/portal/files/portal-site/i18n/catalog.properties +1 -0
  161. package/lib/init/template/portal/files/portal-site/i18n/catalog_de.properties +1 -0
  162. package/lib/init/template/portal/files/portal-site/i18n/group.properties +1 -0
  163. package/lib/init/template/portal/files/portal-site/i18n/group_de.properties +1 -0
  164. package/lib/init/template/portal/index.js +84 -0
  165. package/lib/init/template/postgres/index.js +5 -1
  166. package/lib/init/template/redis-messaging/index.js +4 -0
  167. package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_de.properties +3 -0
  168. package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_en.properties +3 -0
  169. package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +13 -1
  170. package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n.properties +2 -2
  171. package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_de.properties +3 -0
  172. package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_en.properties +4 -0
  173. package/lib/init/template/sample/files/app/browse/webapp/manifest.json +3 -3
  174. package/lib/init/template/sample/files/app/index.html +1 -1
  175. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +5 -5
  176. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books.csv +6 -6
  177. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books_texts.csv +5 -5
  178. package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.csv +16 -16
  179. package/lib/init/template/sample/files/nodejs/cat-service.js +2 -2
  180. package/lib/init/template/sample/files/package.json.hbs +3 -0
  181. package/lib/init/template/sample/index.js +16 -9
  182. package/lib/init/template/sqlite/index.js +4 -0
  183. package/lib/init/template/tiny-sample/files/nodejs/db/data/my.bookshop-Books.csv +3 -3
  184. package/lib/init/template/tiny-sample/files/nodejs/srv/cat-service.cds.hbs +1 -1
  185. package/lib/init/template/tiny-sample/index.js +4 -0
  186. package/lib/init/template/toggles/files/package.json.hbs +1 -1
  187. package/lib/init/template/toggles/index.js +4 -0
  188. package/lib/init/template/typer/index.js +4 -0
  189. package/lib/init/template/typescript/files/package.json +12 -0
  190. package/lib/init/template/typescript/files/tsconfig.json +13 -0
  191. package/lib/init/template/typescript/index.js +39 -0
  192. package/lib/init/template/workzone/index.js +5 -0
  193. package/lib/init/template/workzone-standard/files/manifest.json.hbs +6 -0
  194. package/lib/init/template/workzone-standard/index.js +30 -0
  195. package/lib/init/template/xsuaa/files/package.json.hbs +1 -1
  196. package/lib/init/template/xsuaa/files/values.yaml.hbs +3 -2
  197. package/lib/init/template/xsuaa/index.js +11 -7
  198. package/lib/init/validate.js +27 -0
  199. package/lib/lint/generators.js +1 -1
  200. package/lib/lint/io.js +25 -7
  201. package/lib/mtx/auth_manager.js +64 -30
  202. package/lib/mtx/download_legacy.js +2 -2
  203. package/lib/mtx/index.js +0 -4
  204. package/lib/mtx/params.js +32 -38
  205. package/lib/mtx/pull.js +151 -43
  206. package/lib/mtx/push.js +3 -3
  207. package/lib/mtx/settings_manager.js +75 -35
  208. package/lib/mtx/tenant_action.js +1 -1
  209. package/lib/mtx/util/cf.js +1 -1
  210. package/lib/mtx/util/fs.js +26 -1
  211. package/lib/mtx/util/logging.js +7 -3
  212. package/lib/util/command.js +0 -2
  213. package/lib/util/fs.js +2 -3
  214. package/lib/util/question.js +28 -0
  215. package/lib/util/term.js +5 -3
  216. package/npm-shrinkwrap.json +226 -1087
  217. package/package.json +13 -8
  218. package/bin/activate.js +0 -77
  219. package/lib/compile/asyncapi/channels.js +0 -22
  220. package/lib/compile/asyncapi/components/messageTraits/index.js +0 -89
  221. package/lib/compile/asyncapi/components/messages/index.js +0 -173
  222. package/lib/compile/asyncapi/components/schemas/annotations.js +0 -33
  223. package/lib/compile/asyncapi/components/schemas/array.js +0 -8
  224. package/lib/compile/asyncapi/components/schemas/cache.js +0 -14
  225. package/lib/compile/asyncapi/components/schemas/definition.js +0 -187
  226. package/lib/compile/asyncapi/components/schemas/enum.js +0 -16
  227. package/lib/compile/asyncapi/components/schemas/examples.js +0 -10
  228. package/lib/compile/asyncapi/components/schemas/index.js +0 -14
  229. package/lib/compile/asyncapi/components/schemas/localized.js +0 -29
  230. package/lib/compile/asyncapi/components/schemas/primitiveElement.js +0 -41
  231. package/lib/compile/asyncapi/components/schemas/ref.js +0 -45
  232. package/lib/compile/asyncapi/components/schemas/utils.js +0 -108
  233. package/lib/compile/asyncapi/index.js +0 -247
  234. package/lib/compile/asyncapi/message.js +0 -13
  235. package/lib/compile/asyncapi/utils.js +0 -27
  236. package/lib/compile/openapi/csdl2openapi.js +0 -2448
  237. package/lib/compile/openapi/index.js +0 -68
  238. package/lib/init/template/helm/files/chart/templates/NOTES.txt +0 -14
  239. package/lib/init/template/helm/files/chart/templates/_helpers.tpl +0 -28
  240. package/lib/init/template/helm/files/chart/values.root.schema.json +0 -61
  241. package/lib/init/template/helm/files/chart/values.schema.json +0 -366
  242. package/lib/init/template/helm-unified-runtime/files/Chart.yaml.hbs +0 -10
  243. package/lib/init/template/helm-unified-runtime/files/templates/_deployment_helpers.tpl +0 -90
  244. package/lib/init/template/helm-unified-runtime/files/templates/_helpers.tpl +0 -28
  245. package/lib/init/template/helm-unified-runtime/files/values.root.schema.json +0 -61
  246. package/lib/init/template/helm-unified-runtime/files/values.schema.json +0 -366
  247. package/lib/init/template/helm-unified-runtime/files/values.yaml.hbs +0 -26
  248. package/lib/init/template/helm-unified-runtime/package.json +0 -4
  249. package/lib/init/template/multitenancy/files/mtxs-configmap-java-approuter.yaml +0 -20
  250. package/lib/init/template/multitenancy/files/mtxs-configmap-java.yaml +0 -18
  251. package/lib/init/template/multitenancy/files/mtxs-configmap-nodejs-approuter.yaml +0 -12
  252. package/lib/init/template/multitenancy/files/mtxs-configmap-nodejs.yaml +0 -12
  253. package/lib/init/template/multitenancy/files/saas-registry-secret.yaml +0 -9
  254. package/lib/init/template/nodejs/files/eslint.config.js +0 -13
  255. package/lib/init/template/notebook/index.js +0 -11
  256. package/lib/init/template/samples/index.js +0 -9
  257. package/lib/mtx/activate.js +0 -238
  258. package/lib/mtx/extend.js +0 -173
  259. package/lib/util/exec.d.ts +0 -54
  260. package/lib/util/exec.js +0 -211
  261. /package/lib/{init/template/approuter/files → build/plugins/helm/files/plugins/approuter}/approuter-configmap.yaml +0 -0
  262. /package/lib/{init/template/connectivity/files → build/plugins/helm/files/plugins/connectivity}/connectivity-proxy-info.yaml +0 -0
  263. /package/lib/{init/template/html5-repo/files → build/plugins/helm/files/plugins/html5-repo}/html5-apps-deployer-configmap.yaml +0 -0
  264. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/_helpers.tpl +0 -0
  265. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/job.yaml +0 -0
  266. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/secret.yaml +0 -0
  267. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/service-account.yaml +0 -0
  268. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/service-binding.yaml +0 -0
  269. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/values.schema.json +0 -0
  270. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/NOTES.txt +0 -0
  271. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/_api.tpl +0 -0
  272. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/_helpers.tpl +0 -0
  273. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/api-rule.yaml +0 -0
  274. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/network-policy.yaml +0 -0
  275. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/rbac.yaml +0 -0
  276. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/secret.yaml +0 -0
  277. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service-account.yaml +0 -0
  278. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service-binding.yaml +0 -0
  279. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service.yaml +0 -0
  280. /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/virtual-service.yaml +0 -0
  281. /package/lib/{init/template/helm-unified-runtime → build/plugins/helm}/files/templates/NOTES.txt +0 -0
  282. /package/lib/init/template/{nodejs/files → java}/.cdsrc.json +0 -0
  283. /package/lib/init/template/tiny-sample/files/nodejs/db/{data-model.cds → schema.cds} +0 -0
@@ -3,6 +3,10 @@ const { merge, sort } = require('../../merge')
3
3
 
4
4
  module.exports = class TogglesTemplate extends require('../../plugin') {
5
5
 
6
+ static help() {
7
+ return 'allow dynamically toggled features'
8
+ }
9
+
6
10
  static hasInProduction(env) {
7
11
  return !!env.requires?.toggles
8
12
  }
@@ -6,6 +6,10 @@ const { TYPER } = require('../../constants').OPTIONS
6
6
  const { exists, read } = require('../../../cds').utils
7
7
 
8
8
  module.exports = class TyperTemplate extends require('../../plugin') {
9
+ static help() {
10
+ return 'type generation for CDS models'
11
+ }
12
+
9
13
  async canRun() {
10
14
  const { isJava } = readProject()
11
15
  if (isJava) {
@@ -0,0 +1,12 @@
1
+ {
2
+ "devDependencies": {
3
+ "typescript": "^5",
4
+ "@cap-js/cds-types": "<1",
5
+ "@types/node": "^20"
6
+ },
7
+ "scripts": {
8
+ "watch": "cds-ts w",
9
+ "build:ts": "tsc",
10
+ "build": "cds build && npm run build:ts"
11
+ }
12
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "esModuleInterop": true,
7
+ "forceConsistentCasingInFileNames": true,
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "sourceMap": true,
11
+ "allowJs": true
12
+ }
13
+ }
@@ -0,0 +1,39 @@
1
+ const { join } = require('path')
2
+ const { readProject } = require('../../projectReader')
3
+ const { merge } = require('../../merge')
4
+ const { warn } = require('../../../util/term')
5
+ const { TYPESCRIPT } = require('../../constants').OPTIONS
6
+ const { exists } = require('../../../cds').utils
7
+ const TyperTemplate = require('../typer')
8
+
9
+ module.exports = class TypescriptTemplate extends require('../../plugin') {
10
+ static help() {
11
+ return 'add minimum configuration for a bare TypeScript project'
12
+ }
13
+
14
+ async canRun() {
15
+ const { isJava } = readProject()
16
+ if (isJava) {
17
+ console.warn(warn(`This appears to be a Java project. 'cds add ${TYPESCRIPT}' is intended to be used in Node.js projects. Proceeding anyway.\n`))
18
+ }
19
+ return true
20
+ }
21
+
22
+ static hasInProduction() {
23
+ return exists('tsconfig.ts')
24
+ }
25
+
26
+ async run() {
27
+ const tsconfig = join(__dirname, 'files', 'tsconfig.json')
28
+
29
+ try {
30
+ await merge(tsconfig).into('tsconfig.json')
31
+ } catch (e) {
32
+ throw e instanceof SyntaxError
33
+ ? `SyntaxError in existing tsconfig.json. This could indicate a JSON file with comments, which is not supported at this time. Remove all comments from your tsconfig.json and rerun`
34
+ : e
35
+ }
36
+ await merge(join(__dirname, 'files', 'package.json')).into('package.json')
37
+ await new TyperTemplate().run() // REVISIT: we should avoid referencing other plugins
38
+ }
39
+ }
@@ -0,0 +1,5 @@
1
+ module.exports = class extends require('../../plugin') {
2
+ requires() {
3
+ return ['workzone-standard']
4
+ }
5
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "sap.cloud": {
3
+ "public": true,
4
+ "service": "{{appName}}.service"
5
+ }
6
+ }
@@ -0,0 +1,30 @@
1
+ const cds = require('../../../cds')
2
+ const { readProject } = require('../../projectReader')
3
+ const { merge } = require('../../merge')
4
+ const { join } = require('path')
5
+
6
+ module.exports = class extends require('../../plugin') {
7
+
8
+ canRun() {
9
+ if (cds.requires.multitenancy) {
10
+ throw `SAP BTP Work Zone, Standard Edition does not support multitenancy yet.`
11
+ }
12
+ return true
13
+ }
14
+
15
+ requires() {
16
+ return ['html5-repo']
17
+ }
18
+
19
+ static help() {
20
+ return 'SAP BTP Work Zone, Standard Edition'
21
+ }
22
+
23
+ async run() {
24
+ const project = readProject()
25
+ const { appUIPaths, appPath } = project
26
+ await Promise.all(appUIPaths.map(p =>
27
+ merge(__dirname, 'files/manifest.json.hbs').into(join(appPath, p, 'webapp/manifest.json'), { project })
28
+ ))
29
+ }
30
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  {{#isNodejs}}
3
3
  "dependencies": {
4
- "@sap/xssec": "^3"
4
+ "@sap/xssec": "^4"
5
5
  },
6
6
  "cds": {
7
7
  {{/isNodejs}}
@@ -19,10 +19,11 @@ xsuaa:
19
19
  serviceOfferingName: xsuaa
20
20
  servicePlanName: application
21
21
  parameters:
22
- xsappname: {{appName}}
23
22
  tenant-mode: {{#hasMultitenancy}}shared{{/hasMultitenancy}}{{^hasMultitenancy}}dedicated{{/hasMultitenancy}}
24
23
  {{#hasApprouter}}
25
24
  oauth2-configuration:
26
25
  redirect-uris:
27
- - https://*.<your-cluster-domain>/**
26
+ {{=<% %>=}}
27
+ - https://*.{{ tpl .Values.global.domain . }}/**
28
+ <%={{ }}=%>
28
29
  {{/hasApprouter}}
@@ -1,12 +1,15 @@
1
1
  const cds = require('../../../cds')
2
2
  const { read } = cds.utils
3
- const term = require('../../../util/term')
4
3
  const { readProject } = require('../../projectReader')
5
4
  const { merge } = require('../../merge')
6
5
  const { srv4, xsuaa, mtxSidecar4 } = require('../../registries/mta')
7
6
 
8
7
  module.exports = class XsuaaTemplate extends require('../../plugin') {
9
8
 
9
+ static help() {
10
+ return 'authentication via XSUAA'
11
+ }
12
+
10
13
  static hasInProduction(env) {
11
14
  return env.requires?.auth?.kind === 'xsuaa'
12
15
  }
@@ -50,13 +53,14 @@ module.exports = class XsuaaTemplate extends require('../../plugin') {
50
53
 
51
54
  if (hasHelm || hasHelmUnifiedRuntime) {
52
55
  await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
53
- }
54
- }
55
56
 
56
- finalize() {
57
- const { hasUI, hasApprouter } = readProject()
58
- if (hasUI && !hasApprouter) {
59
- console.log(`\nAlso run ${term.bold('cds add approuter --for production')} to route and authenticate the paths accessed via the UI.`)
57
+ await merge({
58
+ xsuaa: {
59
+ parameters: {
60
+ xsappname: `${project.appName}-{{ .Release.Namespace }}`
61
+ }
62
+ }
63
+ }).into('chart/values.yaml')
60
64
  }
61
65
  }
62
66
  }
@@ -0,0 +1,27 @@
1
+ const { PROJECT_FILES } = require('./constants')
2
+ const REGEX_PROJECT_NAME = /[^0-9a-zA-Z_-]+/g
3
+ const cds = require('../../lib/cds')
4
+ const { exists } = cds.utils
5
+ const { bold } = require('../../lib/util/term')
6
+
7
+ module.exports.projectName = projectName => {
8
+ if (!projectName) throw 'Specify a project name.'
9
+ const invalidChars = new Set(projectName.match(REGEX_PROJECT_NAME)) // remove duplicates
10
+ if (invalidChars.size > 0) {
11
+ throw `Project name '${projectName}' contains at least one character ('${[...invalidChars]}') which is not supported in npm package names.
12
+ Specify a different project name by replacing characters with '_' or '-', for example '${projectName.replace(REGEX_PROJECT_NAME, '_')}' or '${projectName.replace(REGEX_PROJECT_NAME, '-')}'.`
13
+ }
14
+ }
15
+
16
+ module.exports.projectFolder = cwd => {
17
+ const existingProjectFile = PROJECT_FILES.find(exists)
18
+ if (existingProjectFile) {
19
+ let message
20
+ if (cwd === cds.root) {
21
+ message = `You seem to be working in a project which is already initialized. Use ${bold('cds add')} to add more features.`
22
+ } else {
23
+ message = `You seem to be trying to initialize an existing project. Use a different project name instead.`
24
+ }
25
+ throw `${message}\nDetails: File '${existingProjectFile}' exists in the project folder which indicates an existing project. Use ${bold('cds add')} to add more features.`
26
+ }
27
+ }
@@ -34,7 +34,7 @@ module.exports = {
34
34
  eslintOpts[0] = `
35
35
  # SYNOPSIS
36
36
 
37
- ${cdslintCmd} [beta]
37
+ ${cdslintCmd}
38
38
 
39
39
  Runs environment checks and/or checks the specified models
40
40
  based on the ESLint framework
package/lib/lint/io.js CHANGED
@@ -1,8 +1,7 @@
1
+ const { read, write, exists, yaml } = require('../cds').utils;
2
+ const { readJSONC } = require("../util/fs");
1
3
  const path = require("path");
2
- const yaml = require("@sap/cds-foss")("yaml");
3
4
  const term = require("../util/term");
4
- const { read, write, exists } = require('../cds').utils;
5
- const { readJSONC } = require("../util/fs");
6
5
  const JSONC = require('../util/jsonc');
7
6
 
8
7
  module.exports = {
@@ -226,7 +225,6 @@ module.exports = {
226
225
  switch (configFile) {
227
226
  case "eslint.config.js":
228
227
  case "eslint.config.cjs":
229
- case "eslint.config.mjs":
230
228
  if (exists(configPath)) {
231
229
  logger.log(
232
230
  `${term.warn(
@@ -245,16 +243,36 @@ module.exports = [
245
243
  cds.configs.recommended,
246
244
  {
247
245
  plugins: {
248
- "@sap/cds": cds
246
+ '@sap/cds': cds
249
247
  },
250
- "files": [
248
+ files: [
251
249
  ...cds.configs.recommended.files
252
250
  ],
253
- "rules": {
251
+ rules: {
254
252
  ...cds.configs.recommended.rules
255
253
  }
256
254
  }
257
255
  ]
256
+ `)
257
+ }
258
+ break;
259
+ case "eslint.config.mjs":
260
+ if (exists(configPath)) {
261
+ logger.log(
262
+ `${term.warn(
263
+ `\n\nPlease add the following to your "${configFile}":` +
264
+ '\n\n 1. At the top of your file, import the following:')}` +
265
+ `\n\n ${term.bold('import cdsPlugin from \'@sap/eslint-plugin-cds\'')}` +
266
+ `${term.warn(
267
+ '\n\n 2. In your export, add the following to the front of the array:')}` +
268
+ `\n\n ${term.bold('cdsPlugin.configs.recommended')}`
269
+ );
270
+ } else {
271
+ await write(configPath, `
272
+ import cds from '@sap/cds/eslint.config.mjs'
273
+ import cdsPlugin from '@sap/eslint-plugin-cds'
274
+
275
+ export default [...cds.recommended, cdsPlugin.configs.recommended]
258
276
  `)
259
277
  }
260
278
  break;
@@ -12,9 +12,13 @@ const REASONS = { invalid_scope: /\binvalid_scope\b/ };
12
12
 
13
13
  function assign(params, authData) {
14
14
  if (authData?.access_token) {
15
+ let message = 'Retrieved access token';
15
16
  params.set('token', authData.access_token);
16
17
  if (authData.expires_in) {
17
18
  params.set('tokenExpirationDate', Date.now() + authData.expires_in * 1000);
19
+ if (params.get('saveData')) {
20
+ message += ` (expires on ${(new Date(params.get('tokenExpirationDate'))).toLocaleString()})`;
21
+ }
18
22
  } else {
19
23
  params.delete('tokenExpirationDate');
20
24
  }
@@ -23,6 +27,7 @@ function assign(params, authData) {
23
27
  } else {
24
28
  params.delete('refreshToken');
25
29
  }
30
+ console.log(message + '.');
26
31
  }
27
32
  if (authData?.passcode_url) {
28
33
  params.set('passcodeUrl', authData.passcode_url);
@@ -31,15 +36,19 @@ function assign(params, authData) {
31
36
  function reqParams(method, params) {
32
37
  const url = params.get('tokenUrl');
33
38
  const d = {};
39
+ const ignored = {};
34
40
  if (params.has('subdomain')) {
35
41
  d.subdomain = params.get('subdomain');
36
42
  }
37
43
  if (params.has('refreshToken')) {
38
44
  d.refresh_token = params.get('refreshToken');
45
+ const param = ['passcode', 'clientid'].find(param => params.has(param));
46
+ if (param) {
47
+ ignored[param] = 'refresh token is present';
48
+ }
39
49
  } else if (params.has('passcode')) {
40
50
  d.passcode = params.get('passcode');
41
- }
42
- if (params.has('clientsecret')) {
51
+ } else if (params.has('clientsecret')) {
43
52
  d.clientid = params.get('clientid');
44
53
  d.clientsecret = params.get('clientsecret');
45
54
  } else if (params.has('key')) {
@@ -48,43 +57,60 @@ function reqParams(method, params) {
48
57
  }
49
58
  const data = new URLSearchParams(d).toString();
50
59
  return method === 'post'
51
- ? { url, data }
52
- : { url: `${url}?${data}`, data: undefined };
60
+ ? { url, data, ignored }
61
+ : { url: `${url}?${data}`, data: undefined, ignored };
53
62
  }
54
63
 
55
- async function retrieveTokenOrPasscodeUrl(params) {
56
- if (params.has('token') || !params.has('refreshToken') && !params.has('passcode') && params.has('passcodeUrl')) {
64
+ async function fetchToken(params) {
65
+ if (params.has('token') || !(params.has('refreshToken') || params.has('passcode') || !params.has('passcodeUrl'))) {
57
66
  return;
58
67
  }
59
68
 
60
69
  let response, error;
61
- reqParams: for (const method of ['post', 'get']) {
62
- do {
63
- const { url, data } = reqParams(method, params);
64
- try {
65
- DEBUG?.(`Getting authentication token or passcode URL from ${method.toUpperCase()} ${params.obfuscateQueryParams(url)}`);
66
- response = await axios[method](url, data);
67
- } catch (e) {
68
- if (e.status === 404) { // may represent 405 in case of wrong method
69
- continue reqParams;
70
- } else if (params.has('refreshToken')) {
71
- DEBUG?.('Discarding invalid refresh token');
72
- params.delete('refreshToken');
73
- } else {
74
- error = e;
75
- break reqParams;
76
- }
70
+ const method = 'post';
71
+ do {
72
+ const { url, data, ignored } = reqParams(method, params);
73
+ if (Object.keys(ignored).length) {
74
+ console.log(`Ignoring parameters for fetching token: ${Object.entries(ignored).map(([param, reason]) => `${param} (${reason})`).join(', ')}.`);
75
+ }
76
+ DEBUG?.(`Getting authentication token from ${method.toUpperCase()} ${params.obfuscateQueryParams(url)}`);
77
+ error = undefined;
78
+ try {
79
+ response = await axios[method](url, data);
80
+ break;
81
+ } catch (e) {
82
+ error = e;
83
+ DEBUG?.(`HTTP status ${e.status}`);
84
+ if (params.has('refreshToken')) {
85
+ DEBUG?.('Discarding invalid refresh token');
86
+ params.delete('refreshToken');
87
+ } else {
88
+ break;
77
89
  }
78
- } while (!response);
79
- }
90
+ }
91
+ } while (!response);
80
92
  const data = response?.data ?? error?.auth;
81
93
  assign(params, data);
82
94
  if (error) {
83
- throw new Error(REASONS.invalid_scope.test(error.message)
84
- ? 'Token has invalid scope. Check if your user has the required roles'
85
- : `No valid passcode or token provided. Get a passcode${
86
- params.get('passcodeUrl') ? ' from ' + params.get('passcodeUrl') : ''
87
- } and re-run the command with '-p <passcode>'`, { cause: error });
95
+ let message;
96
+ if (REASONS.invalid_scope.test(error.message)) {
97
+ message = 'token has invalid scope. Check if your user has the required roles';
98
+ } else if (error.status === 404) {
99
+ message = 'token endpoint not found. Check if MTX is running with extensibility enabled';
100
+ } else if (error.message.includes('<html')) { // should already be caught when fetching passcode URL
101
+ message = 'HTML response received. Check if route to MTX is configured correctly in App Router';
102
+ } else if (error.status === 401) {
103
+ message = `invalid credentials`;
104
+ if (params.has('passcode')) {
105
+ message += `. Check if passcode is correct`;
106
+ if (params.has('passcodeUrl')) {
107
+ message += `. Passcode URL: ${params.get('passcodeUrl')}`;
108
+ }
109
+ }
110
+ } else {
111
+ message = 'error on token request';
112
+ }
113
+ throw new Error(message + '.', { cause: error });
88
114
  }
89
115
  }
90
116
 
@@ -98,7 +124,7 @@ module.exports = class AuthManager {
98
124
  params.set('reqAuth', { auth: { username: params.get('username'), password: params.get('password') } });
99
125
  } else if (!params.get('skipToken')) {
100
126
  try {
101
- await retrieveTokenOrPasscodeUrl(params);
127
+ await fetchToken(params);
102
128
  } catch (error) {
103
129
  if (params.get('saveData')) {
104
130
  await SettingsManager.saveSettings(params);
@@ -106,6 +132,14 @@ module.exports = class AuthManager {
106
132
  throw getMessage('Failed to login', { error });
107
133
  }
108
134
  params.set('reqAuth', { headers: { Authorization: 'Bearer ' + params.get('token') } });
135
+ if (params.has('refreshToken') && params.get('saveData')) {
136
+ if (params.get('saveRefreshToken')) {
137
+ console.log('Refresh Token saved. Token will be refreshed automatically.');
138
+ } else {
139
+ console.log(`Note: Refresh Token is not saved by default for security reasons. Use '--save-refresh-token' to override.`);
140
+ params.delete('refreshToken');
141
+ }
142
+ }
109
143
  }
110
144
 
111
145
  if (params.get('saveData')) {
@@ -23,13 +23,13 @@ module.exports = class Download {
23
23
  }
24
24
 
25
25
  console.log(`Downloading migrated @sap/mtx extension project(s)`);
26
- const downloadedTgz = await this.getTgz(params);
26
+ const downloadedTgz = await this.pullTgz(params);
27
27
  await fs.promises.writeFile(downloadPath, downloadedTgz);
28
28
 
29
29
  console.log(`Finished.`);
30
30
  }
31
31
 
32
- static async getTgz(params) {
32
+ static async pullTgz(params) {
33
33
  const tagRule = params.get('tagRule');
34
34
  const defaultTag = params.get('defaultTag');
35
35
  const downloadUrl = `${(params.get('appUrl'))}/-/cds/extensibility/getMigratedProjects`;
package/lib/mtx/index.js CHANGED
@@ -1,12 +1,8 @@
1
- const Activate = require('./activate');
2
1
  const AuthManager = require('./auth_manager');
3
- const Extend = require('./extend');
4
2
  const { SettingsManager } = require('./settings_manager');
5
3
  const Question = require('./util/question');
6
4
 
7
5
  module.exports = {
8
- extend: Extend.run,
9
- activate: Activate.run,
10
6
  login: AuthManager.login,
11
7
  logout: AuthManager.logout,
12
8
  question: Question,
package/lib/mtx/params.js CHANGED
@@ -36,7 +36,7 @@ class Param {
36
36
  * @param options constructor options
37
37
  */
38
38
  constructor(name,
39
- val,
39
+ val = undefined,
40
40
  options = {}) {
41
41
 
42
42
  this.persist = Persistence.none;
@@ -44,6 +44,11 @@ class Param {
44
44
  this.abbreviate = false;
45
45
  this.internal = false;
46
46
  this.allowedValues = null;
47
+ this.type = val === undefined
48
+ ? this.allowedValues
49
+ ? typeof this.allowedValues[0]
50
+ : 'string' // default
51
+ : typeof val;
47
52
 
48
53
  this.name = name;
49
54
  this._val = val;
@@ -102,12 +107,8 @@ class Param {
102
107
  if (val === undefined) {
103
108
  return; // Allow `undefined` always.
104
109
  }
105
- let expectedType = typeof this.val;
106
- if (expectedType === 'undefined' && this.allowedValues) {
107
- expectedType = typeof this.allowedValues[0];
108
- }
109
- if (typeof val !== expectedType) {
110
- throw `Failed to set '${(this.name)}' = ${JSON.stringify(val)}: expected value of type ${expectedType}`;
110
+ if (typeof val !== this.type) {
111
+ throw `Failed to set '${(this.name)}' = ${JSON.stringify(val)}: expected value of type ${this.type}`;
111
112
  }
112
113
  if (this.allowedValues && !(this.allowedValues).includes(val)) {
113
114
  throw `Failed to set '${(this.name)}' = ${JSON.stringify(val)}: expected one of ${JSON.stringify(this.allowedValues)}`;
@@ -125,7 +126,7 @@ class Param {
125
126
  ? undefined
126
127
  : this.obfuscate === ObfuscationLevel.none && (!this.abbreviate || process.env.DEBUG)
127
128
  ? this.val
128
- : this.obfuscate === ObfuscationLevel.partial && process.env.DEBUG && typeof this.val === 'string'
129
+ : this.obfuscate === ObfuscationLevel.partial && process.env.DEBUG && this.type === 'string'
129
130
  ? this.val.slice(0, DISCLOSURE_LENGTH) + '...' + this.val.slice(-DISCLOSURE_LENGTH)
130
131
  : '...';
131
132
  }
@@ -161,48 +162,44 @@ class BasicParams {
161
162
  constructor() {
162
163
  // GENERAL PARAMS
163
164
  // - non-persisted
164
- this.projectFolder = new Param('projectFolder', '');
165
+ this.projectFolder = new Param('projectFolder');
165
166
  this.directory = this.projectFolder.newAlias('directory');
166
167
 
167
- this.tagRule = new Param('tagRule', '');
168
- this.defaultTag = new Param('defaultTag', '');
169
-
170
- // - non-persisted, internal
171
- this.reqAuth = new Param('reqAuth', null, { obfuscate: ObfuscationLevel.full, internal: true });
172
- this.clearOtherTokenStorage = new Param('clearOtherTokenStorage', false, { internal: true });
173
-
174
168
  // - persisted
175
- this.appUrl = new Param('appUrl', '', { persist: Persistence.setting }); // any trailing slash (/) is removed
169
+ this.appUrl = new Param('appUrl', undefined, { persist: Persistence.setting }); // any trailing slash (/) is removed
176
170
  this.url = this.appUrl.newAlias('url');
177
171
  this.from = this.appUrl.newAlias('from');
178
172
  this.to = this.appUrl.newAlias('to');
179
173
  this.at = this.appUrl.newAlias('at');
180
- this.subdomain = new Param('subdomain', '', { persist: Persistence.setting }); // only needed to fetch token
181
- this.passcodeUrl = new Param('passcodeUrl', '', { persist: Persistence.setting, abbreviate: true });
174
+ this.subdomain = new Param('subdomain', undefined, { persist: Persistence.setting }); // only needed to fetch token
175
+ this.passcodeUrl = new Param('passcodeUrl', undefined, { persist: Persistence.setting, abbreviate: true });
182
176
  this.passcode_url = this.passcodeUrl.newAlias('passcode_url');
183
- this.tokenUrl = new Param('tokenUrl', '', { persist: Persistence.setting, abbreviate: true })
177
+ this.tokenUrl = new Param('tokenUrl', undefined, { persist: Persistence.setting, abbreviate: true })
184
178
 
185
179
  // AUTH PARAMS
186
180
  // - non-persisted
187
- this.passcode = new Param('passcode', '', { obfuscate: ObfuscationLevel.partial });
181
+ this.passcode = new Param('passcode', undefined, { obfuscate: ObfuscationLevel.partial });
182
+ this.password = new Param('password', undefined, { obfuscate: ObfuscationLevel.full });
183
+ this.clientid = new Param('clientid', undefined);
184
+ this.clientsecret = new Param('clientsecret', undefined, { obfuscate: ObfuscationLevel.partial });
185
+ this.key = new Param('key', undefined, { obfuscate: ObfuscationLevel.partial }); // private key of client certificate
188
186
  this.tokenStorage = new Param('tokenStorage', undefined, { allowedValues: ['plain', 'keyring'] });
187
+ this.clearOtherTokenStorage = new Param('clearOtherTokenStorage', false, { internal: true });
189
188
  this.plain = new Param('plain', false, { internal: true }); // for backward compatibility - superseded by tokenStorage
190
189
  this.saveData = new Param('saveData', false, { internal: true });
191
- this.renewLogin = new Param('renewLogin', false);
192
- this.password = new Param('password', '', { obfuscate: ObfuscationLevel.full });
193
- this.clientid = new Param('clientid', '');
194
- this.clientsecret = new Param('clientsecret', '', { obfuscate: ObfuscationLevel.partial });
195
- this.key = new Param('key', '', { obfuscate: ObfuscationLevel.partial }); // private key of client certificate
190
+ this.renewLogin = new Param('renewLogin', false, { internal: true });
191
+ this.reqAuth = new Param('reqAuth', undefined, { internal: true, type: 'object', obfuscate: ObfuscationLevel.full });
196
192
 
197
193
  // - persisted
198
- this.username = new Param('username', '', { persist: Persistence.setting }); // only saved against localhost (non-productive); as setting due to ambiguous app URL
194
+ this.username = new Param('username', undefined, { persist: Persistence.setting }); // only saved against localhost (non-productive); as setting due to ambiguous app URL
199
195
  this.isEmptyPassword = new Param('isEmptyPassword', false, { internal: true, persist: Persistence.setting }); // extra param so we can ensure we never save a password
200
- this.token = new Param('token', '', { persist: Persistence.auth, obfuscate: ObfuscationLevel.partial });
196
+ this.token = new Param('token', undefined, { persist: Persistence.auth, obfuscate: ObfuscationLevel.partial });
201
197
  this.tokenExpirationDate = new Param('tokenExpirationDate', Number.MAX_SAFE_INTEGER, { persist: Persistence.auth });
202
- this.refreshToken = new Param('refreshToken', '', { persist: Persistence.auth, obfuscate: ObfuscationLevel.partial });
198
+ this.refreshToken = new Param('refreshToken', undefined, { persist: Persistence.auth, obfuscate: ObfuscationLevel.partial });
203
199
  }
204
200
  }
205
201
 
202
+ // TODO pass these as extra arguments to lib functions
206
203
  /**
207
204
  * All known params including those needed for specific commands.
208
205
  */
@@ -211,28 +208,25 @@ class AllParams extends BasicParams {
211
208
  super();
212
209
 
213
210
  // `extend` PARAMS
214
- this.force = new Param('force', false);
215
- this.templates = new Param('templates', false);
216
- this["download-migrated-projects"] = new Param('download-migrated-projects', false)
211
+ this.defaultTag = new Param('defaultTag', undefined);
212
+ this.tagRule = new Param('tagRule', undefined);
217
213
 
218
- // `activate` PARAMS
219
- this.undeploy = new Param('undeploy', false);
220
- this.wsdl = new Param('wsdl', false);
214
+ // `push` PARAMS
221
215
  this.sync = new Param('sync', false);
222
216
  this.async = new Param('async', false);
223
217
 
224
218
  // `subscribe` PARAMS
225
- this.body = new Param('body', '', { persist: Persistence.none });
219
+ this.body = new Param('body', undefined, { internal: true, persist: Persistence.none });
226
220
 
227
221
  // `login` PARAMS
228
222
  this.skipToken = new Param('skipToken', false, { internal: true });
223
+ this.saveRefreshToken = new Param('saveRefreshToken', false, { internal: true });
229
224
 
230
225
  // `logout` PARAMS
231
226
  this.deleteSettings = new Param('deleteSettings', false);
232
227
  this["delete-settings"] = this.deleteSettings.newAlias('delete-settings');
233
228
  this.clearInvalid = new Param('clearInvalid', false);
234
229
  this["clear-invalid"] = this.clearInvalid.newAlias('clear-invalid');
235
-
236
230
  }
237
231
  }
238
232
 
@@ -411,7 +405,7 @@ class ParamCollection {
411
405
  }
412
406
 
413
407
  /**
414
- * Return an object mapping each of the contained params' names to its corresponding value.
408
+ * Return an object mapping the names of each of the contained params to their corresponding values.
415
409
  * @param persistence the type of persistence to filter for (omit to disable filtering)
416
410
  */
417
411
  toEntries(persistence) {