@sap/cds 5.4.6 → 5.5.0

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 (228) hide show
  1. package/CHANGELOG.md +208 -2
  2. package/apis/ql.d.ts +17 -15
  3. package/app/index.js +1 -1
  4. package/bin/build/buildTaskEngine.js +26 -42
  5. package/bin/build/buildTaskFactory.js +6 -10
  6. package/bin/build/buildTaskHandler.js +2 -4
  7. package/bin/build/buildTaskProvider.js +3 -1
  8. package/bin/build/buildTaskProviderFactory.js +9 -15
  9. package/bin/build/constants.js +15 -3
  10. package/bin/build/index.js +5 -4
  11. package/bin/build/mtaUtil.js +8 -11
  12. package/bin/build/provider/buildTaskHandlerEdmx.js +63 -6
  13. package/bin/build/provider/buildTaskHandlerInternal.js +2 -34
  14. package/bin/build/provider/buildTaskProviderInternal.js +16 -42
  15. package/bin/build/provider/fiori/index.js +13 -24
  16. package/bin/build/provider/hana/2migration.js +17 -15
  17. package/bin/build/provider/hana/2tabledata.js +52 -48
  18. package/bin/build/provider/hana/index.js +27 -25
  19. package/bin/build/provider/hana/migrationtable.js +91 -67
  20. package/bin/build/provider/java-cf/index.js +14 -24
  21. package/bin/build/provider/mtx/index.js +12 -14
  22. package/bin/build/provider/node-cf/index.js +18 -32
  23. package/bin/cds.js +5 -5
  24. package/bin/serve.js +29 -23
  25. package/bin/version.js +0 -1
  26. package/lib/compile/etc/_localized.js +4 -9
  27. package/lib/compile/for/sql.js +5 -2
  28. package/lib/compile/parse.js +25 -17
  29. package/lib/compile/to/srvinfo.js +2 -1
  30. package/lib/connect/bindings.js +2 -1
  31. package/lib/connect/index.js +48 -49
  32. package/lib/core/classes.js +1 -1
  33. package/lib/core/reflect.js +10 -2
  34. package/lib/deploy.js +26 -23
  35. package/lib/env/defaults.js +13 -6
  36. package/lib/env/index.js +73 -78
  37. package/lib/env/requires.js +38 -19
  38. package/lib/index.js +9 -10
  39. package/lib/lazy.js +2 -2
  40. package/lib/log/index.js +33 -45
  41. package/lib/log/service/index.js +2 -2
  42. package/lib/ql/CREATE.js +14 -9
  43. package/lib/ql/DELETE.js +6 -5
  44. package/lib/ql/DROP.js +12 -9
  45. package/lib/ql/INSERT.js +40 -16
  46. package/lib/ql/Query.js +67 -40
  47. package/lib/ql/SELECT.js +162 -127
  48. package/lib/ql/UPDATE.js +74 -42
  49. package/lib/ql/Whereable.js +77 -87
  50. package/lib/ql/index.js +36 -24
  51. package/lib/ql/parse.js +35 -0
  52. package/lib/req/context.js +44 -8
  53. package/lib/req/locale.js +7 -7
  54. package/lib/serve/Service-api.js +21 -14
  55. package/lib/serve/Service-dispatch.js +28 -12
  56. package/lib/serve/Transaction.js +22 -10
  57. package/lib/serve/index.js +16 -11
  58. package/lib/utils/axios.js +23 -16
  59. package/lib/utils/data.js +35 -0
  60. package/lib/utils/tests.js +27 -18
  61. package/libx/_runtime/audit/generic/personal/access.js +81 -0
  62. package/libx/_runtime/audit/generic/personal/constants.js +4 -0
  63. package/libx/_runtime/audit/generic/personal/index.js +50 -0
  64. package/libx/_runtime/audit/generic/personal/modification.js +138 -0
  65. package/libx/_runtime/audit/generic/personal/utils.js +186 -0
  66. package/libx/_runtime/audit/utils/v2.js +10 -4
  67. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +5 -5
  68. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -7
  69. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +5 -7
  70. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -7
  71. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +2 -3
  72. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +4 -0
  73. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +7 -4
  74. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +59 -8
  75. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +11 -1
  76. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +6 -10
  77. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +3 -46
  78. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +2 -5
  79. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/createToCQN.js +2 -2
  80. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/deleteToCQN.js +4 -3
  81. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +1 -2
  82. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +0 -1
  83. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectHelper.js +1 -1
  84. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/updateToCQN.js +2 -2
  85. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +16 -18
  86. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityType.js +6 -3
  87. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/format/RepresentationKind.js +4 -1
  88. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/OdataRequest.js +1 -0
  89. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +15 -2
  90. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/validator/OperationValidator.js +1 -0
  91. package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
  92. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +8 -1
  93. package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +6 -1
  94. package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +12 -5
  95. package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +1 -7
  96. package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +7 -7
  97. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +14 -18
  98. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +13 -13
  99. package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -1
  100. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +2 -1
  101. package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +2 -2
  102. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +2 -4
  103. package/libx/_runtime/cds-services/adapter/rest/utils/result.js +4 -2
  104. package/libx/_runtime/cds-services/services/Service.js +40 -5
  105. package/libx/_runtime/cds-services/services/utils/columns.js +13 -7
  106. package/libx/_runtime/cds-services/services/utils/compareJson.js +88 -4
  107. package/libx/_runtime/cds-services/services/utils/differ.js +24 -6
  108. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +2 -2
  109. package/libx/_runtime/common/composition/data.js +44 -55
  110. package/libx/_runtime/common/composition/delete.js +97 -71
  111. package/libx/_runtime/common/composition/index.js +2 -1
  112. package/libx/_runtime/common/composition/insert.js +34 -11
  113. package/libx/_runtime/common/composition/tree.js +119 -92
  114. package/libx/_runtime/common/composition/update.js +4 -1
  115. package/libx/_runtime/common/composition/utils.js +1 -3
  116. package/libx/_runtime/common/constants/draft.js +12 -1
  117. package/libx/_runtime/common/generic/auth.js +6 -22
  118. package/libx/_runtime/common/generic/crud.js +14 -13
  119. package/libx/_runtime/common/generic/input.js +23 -26
  120. package/libx/_runtime/common/generic/put.js +1 -1
  121. package/libx/_runtime/common/generic/sorting.js +16 -16
  122. package/libx/_runtime/common/i18n/index.js +1 -1
  123. package/libx/_runtime/common/i18n/messages.properties +4 -0
  124. package/libx/_runtime/common/utils/backlinks.js +12 -5
  125. package/libx/_runtime/common/utils/cqn.js +6 -1
  126. package/libx/_runtime/common/utils/cqn2cqn4sql.js +102 -101
  127. package/libx/_runtime/common/utils/csn.js +47 -4
  128. package/libx/_runtime/common/utils/data.js +0 -37
  129. package/libx/_runtime/common/utils/enrichWithKeysFromWhere.js +1 -1
  130. package/libx/_runtime/common/utils/entityFromCqn.js +7 -24
  131. package/libx/_runtime/common/utils/foreignKeyPropagations.js +39 -7
  132. package/libx/_runtime/common/utils/generateOnCond.js +11 -12
  133. package/libx/_runtime/common/utils/onlyKeysRemain.js +10 -0
  134. package/libx/_runtime/common/utils/path.js +35 -0
  135. package/libx/_runtime/common/utils/postProcessing.js +86 -0
  136. package/libx/_runtime/common/utils/quotingStyles.js +37 -26
  137. package/libx/_runtime/common/utils/resolveView.js +223 -171
  138. package/libx/_runtime/common/utils/rewriteAsterisk.js +46 -26
  139. package/libx/_runtime/common/utils/structured.js +6 -12
  140. package/libx/_runtime/common/utils/template.js +10 -5
  141. package/libx/_runtime/common/utils/templateDelimiter.js +1 -0
  142. package/libx/_runtime/common/utils/templateProcessor.js +22 -30
  143. package/libx/_runtime/common/utils/union.js +31 -0
  144. package/libx/_runtime/common/utils/unionCqnTemplate.js +184 -0
  145. package/libx/_runtime/db/Service.js +1 -1
  146. package/libx/_runtime/db/data-conversion/timestamp.js +2 -9
  147. package/libx/_runtime/db/expand/expandCQNToJoin.js +204 -297
  148. package/libx/_runtime/db/expand/index.js +3 -3
  149. package/libx/_runtime/db/expand/rawToExpanded.js +36 -7
  150. package/libx/_runtime/db/generic/index.js +1 -1
  151. package/libx/_runtime/db/generic/input.js +5 -7
  152. package/libx/_runtime/db/generic/integrity.js +1 -1
  153. package/libx/_runtime/db/generic/rewrite.js +2 -10
  154. package/libx/_runtime/db/generic/update.js +13 -5
  155. package/libx/_runtime/db/generic/virtual.js +22 -58
  156. package/libx/_runtime/db/query/delete.js +7 -4
  157. package/libx/_runtime/db/query/insert.js +6 -4
  158. package/libx/_runtime/db/query/read.js +13 -20
  159. package/libx/_runtime/db/query/run.js +4 -1
  160. package/libx/_runtime/db/query/update.js +5 -4
  161. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +35 -2
  162. package/libx/_runtime/db/sql-builder/FunctionBuilder.js +17 -2
  163. package/libx/_runtime/db/sql-builder/InsertBuilder.js +6 -5
  164. package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +10 -0
  165. package/libx/_runtime/db/sql-builder/SelectBuilder.js +35 -24
  166. package/libx/_runtime/db/sql-builder/UpdateBuilder.js +14 -4
  167. package/libx/_runtime/db/sql-builder/arrayed.js +4 -0
  168. package/libx/_runtime/db/utils/deep.js +8 -0
  169. package/libx/_runtime/db/utils/generateAliases.js +2 -1
  170. package/libx/_runtime/fiori/generic/activate.js +19 -15
  171. package/libx/_runtime/fiori/generic/before.js +3 -11
  172. package/libx/_runtime/fiori/generic/cancel.js +1 -1
  173. package/libx/_runtime/fiori/generic/delete.js +3 -1
  174. package/libx/_runtime/fiori/generic/edit.js +12 -2
  175. package/libx/_runtime/fiori/generic/new.js +5 -5
  176. package/libx/_runtime/fiori/generic/patch.js +0 -18
  177. package/libx/_runtime/fiori/generic/read.js +241 -189
  178. package/libx/_runtime/fiori/utils/delete.js +36 -7
  179. package/libx/_runtime/fiori/utils/handler.js +43 -44
  180. package/libx/_runtime/fiori/utils/where.js +30 -15
  181. package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +4 -6
  182. package/libx/_runtime/hana/execute.js +2 -2
  183. package/libx/_runtime/hana/localized.js +4 -4
  184. package/libx/_runtime/hana/pool.js +29 -14
  185. package/libx/_runtime/hana/search2cqn4sql.js +2 -1
  186. package/libx/_runtime/hana/searchToContains.js +18 -14
  187. package/libx/_runtime/index.js +0 -5
  188. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +13 -5
  189. package/libx/_runtime/messaging/common-utils/naming-conventions.js +4 -1
  190. package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +31 -19
  191. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +1 -2
  192. package/libx/_runtime/messaging/enterprise-messaging.js +6 -4
  193. package/libx/_runtime/messaging/service.js +7 -6
  194. package/libx/_runtime/odata/cqn2odata.js +110 -43
  195. package/libx/_runtime/odata/index.js +26 -48
  196. package/libx/_runtime/odata/odata2cqn.js +1 -6154
  197. package/libx/_runtime/odata/odata2cqn.pegjs +559 -0
  198. package/libx/_runtime/odata/readToCqn.js +94 -64
  199. package/libx/_runtime/remote/Service.js +74 -21
  200. package/libx/_runtime/remote/cqn2odata/index.js +1 -5
  201. package/libx/_runtime/remote/utils/client.js +24 -101
  202. package/libx/_runtime/remote/utils/dataConversion.js +27 -12
  203. package/libx/_runtime/sqlite/Service.js +3 -5
  204. package/libx/_runtime/sqlite/execute.js +23 -24
  205. package/libx/_runtime/sqlite/localized.js +12 -7
  206. package/libx/_runtime/types/api.js +10 -0
  207. package/package.json +1 -1
  208. package/server.js +16 -2
  209. package/lib/ql/grammar.pegjs +0 -208
  210. package/lib/ql/parser.js +0 -1
  211. package/lib/ql/rt/DELETE.js +0 -29
  212. package/lib/ql/rt/INSERT.js +0 -23
  213. package/lib/ql/rt/Query.js +0 -84
  214. package/lib/ql/rt/SELECT.js +0 -174
  215. package/lib/ql/rt/UPDATE.js +0 -119
  216. package/lib/ql/rt/_helpers.js +0 -91
  217. package/lib/ql/rt/index.js +0 -32
  218. package/libx/_runtime/audit/generic/personal.js +0 -260
  219. package/libx/_runtime/cds-services/statements/BaseStatement.js +0 -72
  220. package/libx/_runtime/cds-services/statements/Create.js +0 -57
  221. package/libx/_runtime/cds-services/statements/Delete.js +0 -33
  222. package/libx/_runtime/cds-services/statements/Drop.js +0 -42
  223. package/libx/_runtime/cds-services/statements/Insert.js +0 -201
  224. package/libx/_runtime/cds-services/statements/Select.js +0 -826
  225. package/libx/_runtime/cds-services/statements/Update.js +0 -181
  226. package/libx/_runtime/cds-services/statements/Where.js +0 -726
  227. package/libx/_runtime/cds-services/statements/index.js +0 -25
  228. package/libx/_runtime/common/generic/resolve-mock.js +0 -9
@@ -1,14 +1,14 @@
1
1
  const path = require('path')
2
- const {fs} = require('@sap/cds-foss')
2
+ const { fs } = require('@sap/cds-foss')
3
3
  const BuildTaskEngine = require('./buildTaskEngine')
4
4
  const BuildTaskFactory = require('./buildTaskFactory')
5
5
  const BuildTaskHandler = require('./buildTaskHandler')
6
- const constants = require('./constants')
6
+ const { LOG_MODULE_NAMES } = require('./constants')
7
7
  const { BuildError } = require('./util')
8
8
  const { BUILD_MODE_INPLACE } = require('./constants')
9
9
 
10
10
  module.exports = Object.assign(build,
11
- { build, BuildTaskFactory, BuildTaskEngine, BuildTaskHandler, BuildError, constants }
11
+ { build, BuildTaskFactory, BuildTaskEngine, BuildTaskHandler, BuildError }
12
12
  )
13
13
 
14
14
  /**
@@ -18,7 +18,6 @@ module.exports = Object.assign(build,
18
18
  * @param {object} _env - for testing purposes only, will be removed.
19
19
  */
20
20
  async function build(options = {}, _env = null /* for unit tests only: */) {
21
- const logger = options.logger || global.console
22
21
  const projectPath = path.resolve(options.project || '.')
23
22
 
24
23
  if (!fs.lstatSync(projectPath).isDirectory()) {
@@ -26,6 +25,8 @@ async function build(options = {}, _env = null /* for unit tests only: */) {
26
25
  }
27
26
 
28
27
  const cds = require('./cds').in(projectPath)
28
+ const logger = options.logger || cds.log(LOG_MODULE_NAMES)
29
+
29
30
  if (_env) {
30
31
  // REVISIT: please avoid using internal APIs
31
32
  cds.env = cds.env._merge_with(_env)
@@ -1,9 +1,8 @@
1
- const cds = require ('./cds')
2
- const {fs} = require('@sap/cds-foss')
1
+ const cds = require('./cds')
2
+ const { fs } = require('@sap/cds-foss')
3
3
  const path = require('path')
4
4
  const { getProperty } = require('./util')
5
5
 
6
- const DEBUG = process.env.DEBUG
7
6
  const HDI_CONTAINER_TYPES = ['com.sap.xs.hdi-container']
8
7
  const UTF_8 = 'utf-8'
9
8
  const MTA_YAML = 'mta.yaml'
@@ -11,7 +10,7 @@ const MTA_YAML = 'mta.yaml'
11
10
  async function getHanaDbModuleDescriptor(projectPath, moduleName, logger) {
12
11
  // mta might be null if mta.yaml does not exist
13
12
  const mta = await _getMta(projectPath, logger)
14
- const projectInfo = await _getProjectInfo(projectPath, mta)
13
+ const projectInfo = await _getProjectInfo(projectPath, mta, logger)
15
14
  const hdiService = _findHdiResource(mta, moduleName, logger)
16
15
  const appName = _getApplicationName(mta, moduleName, 'hdb')
17
16
 
@@ -26,7 +25,7 @@ async function getHanaDbModuleDescriptor(projectPath, moduleName, logger) {
26
25
  async function getServiceModuleDescriptor(projectPath, moduleName, moduleType, logger) {
27
26
  // mta might be null if mta.yaml does not exist
28
27
  const mta = await _getMta(projectPath, logger)
29
- const projectInfo = await _getProjectInfo(projectPath, mta)
28
+ const projectInfo = await _getProjectInfo(projectPath, mta, logger)
30
29
  const appName = _getApplicationName(mta, moduleName, moduleType)
31
30
 
32
31
  return {
@@ -35,7 +34,7 @@ async function getServiceModuleDescriptor(projectPath, moduleName, moduleType, l
35
34
  }
36
35
  }
37
36
 
38
- async function _getProjectInfo(projectPath, mta) {
37
+ async function _getProjectInfo(projectPath, mta, logger) {
39
38
  const details = {
40
39
  }
41
40
  // 1. use mta data
@@ -76,8 +75,8 @@ async function _getProjectInfo(projectPath, mta) {
76
75
  }
77
76
  }
78
77
  } catch (e) {
79
- this.logger.error(`Failed to load ${packageJsonPath} - skip application data`)
80
- this.logger.error(e)
78
+ logger.error(`Failed to load ${packageJsonPath} - skip application data`)
79
+ logger.error(e)
81
80
  }
82
81
  }
83
82
  // 3. use project name and static default values
@@ -103,9 +102,7 @@ async function _getMta(projectPath, logger) {
103
102
 
104
103
  const existsMtaYaml = await fs.pathExists(mtaFilePath)
105
104
  if (!existsMtaYaml) {
106
- if (DEBUG) {
107
- logger.log('[cds] - mta.yaml not existing')
108
- }
105
+ logger.debug('mta.yaml not existing')
109
106
  return null
110
107
  }
111
108
 
@@ -1,7 +1,6 @@
1
1
  const path = require('path')
2
2
  const BuildTaskHandlerInternal = require('./buildTaskHandlerInternal')
3
3
  const { BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY } = require('../constants')
4
- const DEBUG = process.env.DEBUG
5
4
 
6
5
  class BuildTaskHandlerEdmx extends BuildTaskHandlerInternal {
7
6
  init() {
@@ -10,10 +9,11 @@ class BuildTaskHandlerEdmx extends BuildTaskHandlerInternal {
10
9
  csn: {},
11
10
  edmx: new Map(),
12
11
  languages: new Set(),
13
- services: new Set()
12
+ services: new Set(),
13
+ languageBundles: {}
14
14
  }
15
15
  }
16
- async compileEdmx(model, edmxDest, compileOptions = {}) { // NOSONAR
16
+ async compileToEdmx(model, edmxDest, compileOptions = {}) { // NOSONAR
17
17
  const promises = []
18
18
  const services = this.cds.reflect(model).services
19
19
 
@@ -26,10 +26,8 @@ class BuildTaskHandlerEdmx extends BuildTaskHandlerInternal {
26
26
  ...this._options4edmx(),
27
27
  ...compileOptions
28
28
  }
29
+ this.logger._debug && this.logger.debug(`compiling edmx files using OData version ${options.version}`)
29
30
 
30
- if (DEBUG) {
31
- this.logger.log(`[cds] - compiling edmx files using OData version ${options.version}`)
32
- }
33
31
  const result = this.cds.compile.to.edmx(model, options)
34
32
 
35
33
  if (result) {
@@ -57,6 +55,65 @@ class BuildTaskHandlerEdmx extends BuildTaskHandlerInternal {
57
55
  return Promise.all(promises)
58
56
  }
59
57
 
58
+ async compileToJson(model, csnDest) {
59
+ // This will als add a @source prop containing the relative path to the origin .cds source file
60
+ // and a parsed _where clause for @restrict.{grant,where} annotations.
61
+ // The @source annotation is required for correct custom handler resolution if no @impl annotation has been defined as
62
+ // custom service handler implementations are relative to the origin .cds source files.
63
+ // For staging builds (task.src !== task.dest) the csn.json file that is served at runtime is copied into a corresponding srv subfolder.
64
+ // As a consequence the src folder name has to be included in the @source file name while for inplace builds (task.src === task.dest) this is not the case.
65
+ // This ensures that the paths are relative to the cwd when executing cds run.
66
+ const jsonOptions = {
67
+ cwd: this.buildOptions.root,
68
+ src: this.task.src === this.task.dest ? this.task.src : this.buildOptions.root
69
+ }
70
+ const csnStr = this.cds.compile.to.json(model, jsonOptions)
71
+ this._result.csn = JSON.parse(csnStr)
72
+ this._result.csn.meta = model.meta
73
+
74
+ // csnDest might be null
75
+ if (csnDest && !this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
76
+ await this.write(csnStr).to(path.join(csnDest, 'csn.json'))
77
+ }
78
+ return this._result.csn
79
+ }
80
+
81
+ /**
82
+ * Collect and write language bundles into a single i18n.json file.
83
+ * @param {Object} model
84
+ * @param {string} bundleDest
85
+ */
86
+ async collectLanguageBundles(model, bundleDest) {
87
+ // collect effective i18n properties...
88
+ let bundles = {}
89
+ const bundleGenerator = this.cds.localize.bundles4(model)
90
+ if (bundleGenerator && bundleGenerator[Symbol.iterator]) {
91
+ for (let [locale, bundle] of bundleGenerator) {
92
+ // fallback bundle has the name ""
93
+ if (typeof locale === 'string') {
94
+ bundles[locale] = bundle
95
+ }
96
+ }
97
+ }
98
+
99
+ // omit bundles in case the fallback bundle is the only existing entry
100
+ const keys = Object.keys(bundles)
101
+ if (keys.length === 1 && keys[0] === "" && Object.keys(bundles[keys[0]]).length === 0) {
102
+ bundles = {}
103
+ }
104
+ // copied from ../compile/i18n.js
105
+ const { folders = ['i18n'], file = 'i18n' } = this.env.i18n
106
+
107
+ // bundleDest might be null
108
+ if (bundleDest && Object.keys(bundles).length > 0) {
109
+ if (!this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
110
+ await this.write(bundles).to(path.join(bundleDest, folders[0], file + '.json'))
111
+ }
112
+ }
113
+ this._result.languageBundles = bundles
114
+ return bundles
115
+ }
116
+
60
117
  _options4odata() {
61
118
  const o = this.options()
62
119
  o.version = this.env.odata.version
@@ -2,7 +2,7 @@ const { fs } = require('@sap/cds-foss')
2
2
  const path = require('path')
3
3
  const BuildTaskHandler = require('../buildTaskHandler')
4
4
  const { hasOptionValue } = require('../util')
5
- const { BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY, FOLDER_GEN } = require('../constants')
5
+ const { FOLDER_GEN } = require('../constants')
6
6
 
7
7
  class BuildTaskHandlerInternal extends BuildTaskHandler {
8
8
  /**
@@ -165,40 +165,8 @@ class BuildTaskHandlerInternal extends BuildTaskHandler {
165
165
  )
166
166
  }
167
167
 
168
- /**
169
- * Collect and write language bundles into a single i18n.json file.
170
- * @param {Object} model
171
- * @param {string} dest
172
- */
173
- async copyLanguageBundles(model, dest) {
174
- // collect effective i18n properties...
175
- let bundles = {}
176
- const bundleGenerator = this.cds.localize.bundles4(model)
177
- if (bundleGenerator && bundleGenerator[Symbol.iterator]) {
178
- for (let [locale, bundle] of bundleGenerator) {
179
- // fallback bundle has the name ""
180
- if (typeof locale === 'string') {
181
- bundles[locale] = bundle
182
- }
183
- }
184
- }
185
-
186
- // omit bundles in case the fallback bundle is the only existing entry
187
- const keys = Object.keys(bundles)
188
- if (keys.length === 1 && keys[0] === "" && Object.keys(bundles[keys[0]]).length === 0) {
189
- bundles = {}
190
- }
191
- // copied from ../compile/i18n.js
192
- const { folders = ['i18n'], file = 'i18n' } = this.env.i18n
193
- if (Object.keys(bundles).length > 0) {
194
- if (!this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
195
- await this.write(bundles).to(path.join(dest, folders[0], file + '.json'))
196
- }
197
- }
198
- }
199
-
200
168
  options() {
201
- return { messages: this._messages }
169
+ return { messages: this._messages, logger: this.logger }
202
170
  }
203
171
 
204
172
  _isSubDirectory(parent, child) {
@@ -5,8 +5,6 @@ const { FILE_EXT_CDS, BUILD_TASK_HANA, BUILD_TASK_FIORI, BUILD_TASK_JAVA, BUILD_
5
5
  CDS_CONFIG_PATH_SEP, BUILD_MODE_INPLACE, BUILD_TASK_PREFIX, BUILD_TASKS } = require("../constants")
6
6
  const BuildTaskProvider = require('../buildTaskProvider')
7
7
 
8
- const DEBUG = process.env.DEBUG
9
-
10
8
  class BuildTaskProviderInternal extends BuildTaskProvider {
11
9
  constructor(cds, logger) {
12
10
  super()
@@ -64,9 +62,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
64
62
  }
65
63
 
66
64
  async _createTasks(buildOptions) { // NOSONAR
67
- if (DEBUG) {
68
- this.logger.log("[cds] - Determining CDS build tasks from CDS configuration - applying defaults")
69
- }
65
+ this.logger.debug("[cds] - Determining CDS build tasks from CDS configuration - applying defaults")
70
66
  const { root: projectPath } = buildOptions
71
67
  let tasks = []
72
68
  let db = typeof this.env.folders.db === "string" ? [BuildTaskProviderInternal._normalizePath(this.env.folders.db)] : this.env.folders.db
@@ -139,15 +135,11 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
139
135
  }
140
136
 
141
137
  _createDbTask(projectPath, src, taskOptions, buildOptions) {
142
- if (DEBUG) {
143
- this.logger.log("[cds] - Determining database kind.")
144
- }
138
+ this.logger.debug("[cds] - Determining database kind.")
145
139
  let task = null
146
140
 
147
141
  if (this._useHana(projectPath, buildOptions)) {
148
- if (DEBUG) {
149
- this.logger.log("[cds] - Found HANA database.")
150
- }
142
+ this.logger.debug("[cds] - Found HANA database.")
151
143
  // legacy build supports dest property
152
144
  const compileDest = this.env.get("data.dest")
153
145
  if (compileDest) {
@@ -162,19 +154,17 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
162
154
  options: taskOptions
163
155
  }
164
156
  } else {
165
- if (DEBUG) {
166
- this.logger.log("[cds] - Found sqlite database - skipping HANA build task")
167
- }
157
+ this.logger.debug("[cds] - Found sqlite database - skipping HANA build task")
168
158
  }
169
159
  return task
170
160
  }
171
161
 
172
162
  _useHana(projectPath, buildOptions) {
173
163
  if (this.env.get("build.mode") === BUILD_MODE_INPLACE
174
- // || !this.env.get("requires.db.kind")
175
- || getProperty(buildOptions, "for.hana.skipManifestGeneration") // fallback for webide fullstack and mtx
164
+ || getProperty(buildOptions, "for.hana.skipManifestGeneration") // deprecated fallback for webide fullstack and mtx
165
+ || getProperty(buildOptions, "for.hana.contentManifest") === false // fallback for webide fullstack and mtx
176
166
  || this.env.get("requires.db.kind") === "hana"
177
- || this.env.get("requires.db.use") === "hana") {
167
+ || this.env.get("requires.db.dialect") === "hana") {
178
168
 
179
169
  return true
180
170
  }
@@ -189,38 +179,28 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
189
179
  }
190
180
 
191
181
  _createMtxTask(srv) {
192
- if (DEBUG) {
193
- this.logger.log("[cds] - Determining single or multi-tenant strategy.")
194
- }
182
+ this.logger.debug("[cds] - Determining single or multi-tenant strategy.")
195
183
  let task = null
196
184
 
197
- if (this.env.get("requires.multitenancy") && (this.env.get("requires.db.kind") === "hana" || this.env.get("requires.db.use") === "hana")) {
198
- if (DEBUG) {
199
- this.logger.log("[cds] - Found multi-tenant app.")
200
- }
185
+ if (this.env.get("requires.multitenancy") && (this.env.get("requires.db.kind") === "hana" || this.env.get("requires.db.dialect") === "hana")) {
186
+ this.logger.debug("[cds] - Found multi-tenant app.")
201
187
  task = {
202
188
  src: ".",
203
189
  for: BUILD_TASK_MTX,
204
190
  dest: srv
205
191
  }
206
192
  } else {
207
- if (DEBUG) {
208
- this.logger.log("[cds] - Found single-tenant app - skipping mtx build task")
209
- }
193
+ this.logger.debug("[cds] - Found single-tenant app - skipping mtx build task")
210
194
  }
211
195
  return task
212
196
  }
213
197
 
214
198
  _createSrvTask(projectPath, src, taskOptions) {
215
- if (DEBUG) {
216
- this.logger.log("[cds] - Determining implementation technology")
217
- }
199
+ this.logger.debug("[cds] - Determining implementation technology")
218
200
  let task = this._createJavaTask(projectPath, src, taskOptions)
219
201
 
220
202
  if (!task) {
221
- if (DEBUG) {
222
- this.logger.log("[cds] - Found implementation technology node")
223
- }
203
+ this.logger.debug("[cds] - Found implementation technology node")
224
204
  task = {
225
205
  src: src,
226
206
  for: BUILD_TASK_NODE,
@@ -232,9 +212,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
232
212
 
233
213
  _createJavaTask(projectPath, src, taskOptions) {
234
214
  if (this._hasJavaNature(projectPath, src)) {
235
- if (DEBUG) {
236
- this.logger.log("[cds] - Found implementation technology java")
237
- }
215
+ this.logger.debug("[cds] - Found implementation technology java")
238
216
  // legacy build supports dest property
239
217
  const compileDest = this.env.get("service.dest")
240
218
  if (compileDest) {
@@ -259,9 +237,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
259
237
  */
260
238
  _createFioriTasks(projectPath, fioriSrvOptions) {
261
239
  let tasks = []
262
- if (DEBUG) {
263
- this.logger.log("[cds] - Determining fiori modules - matching modules */webapp/manifest.json")
264
- }
240
+ this.logger.debug("[cds] - Determining fiori modules - matching modules */webapp/manifest.json")
265
241
  // fiori-app build-tasks
266
242
  let appDirs = this.env.ui && this.env.ui.apps ? this.env.ui.apps : undefined
267
243
  if (!appDirs) {
@@ -287,9 +263,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
287
263
  return appDir
288
264
  })
289
265
  }
290
- if (DEBUG) {
291
- this.logger.log(`[cds] - Found fiori app paths [${appDirs}]`)
292
- }
266
+ this.logger._debug && this.logger.debug(`[cds] - Found fiori app paths [${appDirs}]`)
293
267
  appDirs.forEach(appDir => {
294
268
  appDir = BuildTaskProviderInternal._normalizePath(appDir)
295
269
  let modelPaths = this._resolveModel(path.resolve(projectPath, appDir))
@@ -2,7 +2,6 @@ const path = require('path')
2
2
  const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
3
3
  const URL = require('url')
4
4
  const { getProperty, isOldJavaStack, relativePaths } = require('../../util')
5
- const DEBUG = process.env.DEBUG
6
5
 
7
6
  const { ODATA_VERSION, ODATA_VERSION_V2, BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY, BUILD_TASK_FIORI, BUILD_TASK_JAVA, CDS_CONFIG_PATH_SEP } = require('../../constants')
8
7
 
@@ -56,30 +55,26 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
56
55
 
57
56
  // old java stack
58
57
  // default is now v4 and not v2 anymore, so overwrite with v2 if using default
59
- if (DEBUG) {
60
- this.logger.log("Fiori task is forcing OData v2 for building though the default is v4.")
61
- }
58
+ this.logger.debug("Fiori task is forcing OData v2 for building though the default is v4.")
62
59
  edmxOptions.version = ODATA_VERSION_V2
63
60
  }
64
61
  }
65
62
 
66
63
  for (let [appFolder, appModelGroup] of appModelGroups.entries()) {
67
- this.logger.log(`[cds] - building module [${appFolder}] using [${this.constructor.name}]`)
64
+ this.logger.log(`building module [${appFolder}] using [${this.constructor.name}]`)
68
65
  const modelPaths = this.cds.resolve(Array.from(appModelGroup.values()), this.buildOptions)
69
66
  if (!modelPaths || modelPaths.length === 0) {
70
- this.logger.log(`[cds] - no model found`)
67
+ this.logger.log(`no model found`)
71
68
  continue
72
69
  }
73
- if (DEBUG) {
74
- this.logger.log(`[cds] - model: ${relativePaths(this.buildOptions.root, modelPaths).join(", ")}`)
75
- }
70
+ this.logger._debug && this.logger.debug(`model: ${relativePaths(this.buildOptions.root, modelPaths).join(", ")}`)
76
71
 
77
72
  //cache model per fiori app root folder
78
73
  const options = this.options()
79
74
  const model = await this.cds.load(modelPaths, options)
80
75
  fioriBuildOptions.appModel.set(appFolder, model)
81
76
 
82
- await this.compileEdmx(model, null, edmxOptions)
77
+ await this.compileToEdmx(model, null, edmxOptions)
83
78
 
84
79
  // cache edmx per fiori app root folder
85
80
  fioriBuildOptions.appEdmx.set(appFolder, this._result.edmx)
@@ -100,12 +95,10 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
100
95
  const { src, dest } = this.task
101
96
  const modelPaths = this.resolveModel()
102
97
  if (!modelPaths || modelPaths.length === 0) {
103
- this.logger.log(`[cds] - no model found`)
98
+ this.logger.log(`no model found`)
104
99
  return
105
100
  }
106
- if (DEBUG) {
107
- this.logger.log(`[cds] - model: ${relativePaths(this.buildOptions.root, modelPaths).join(", ")}`)
108
- }
101
+ this.logger._debug && this.logger.debug(`model: ${relativePaths(this.buildOptions.root, modelPaths).join(", ")}`)
109
102
 
110
103
  await this._writeEdmxToWebapp(src, dest)
111
104
  }
@@ -117,16 +110,14 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
117
110
  try {
118
111
  manifest = require(manifestPath)
119
112
  } catch (error) {
120
- this.logger.log(`[cds] - UI module does not contain a manifest.json [${relativePaths(this.buildOptions.root, manifestPath)}], skipping build`)
113
+ this.logger.log(`UI module does not contain a manifest.json [${relativePaths(this.buildOptions.root, manifestPath)}], skipping build`)
121
114
  return
122
115
  }
123
116
 
124
117
  const mainService = getProperty(manifest, ['sap.app', 'dataSources', 'mainService'])
125
118
  if (!mainService) {
126
- if (DEBUG) {
127
- // no mainService defined - not supported
128
- this.logger.log(`[cds] - UI module does not have a datasource [mainService], [${relativePaths(this.buildOptions.root, manifestPath)}], skipping build`)
129
- }
119
+ // no mainService defined - not supported
120
+ this.logger._debug && this.logger.debug(`UI module does not have a datasource [mainService], [${relativePaths(this.buildOptions.root, manifestPath)}], skipping build`)
130
121
  return
131
122
  }
132
123
 
@@ -134,22 +125,20 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
134
125
  const uri = mainService.uri
135
126
 
136
127
  if (!localUri || !uri) {
137
- if (DEBUG) {
138
- this.logger.warn(`[cds] - local uri setting missing for data source [mainService], [${relativePaths(this.buildOptions.root, manifestPath)}]`)
139
- }
128
+ this.logger._debug && this.logger.warn(`local uri setting missing for data source [mainService], [${relativePaths(this.buildOptions.root, manifestPath)}]`)
140
129
  return
141
130
  }
142
131
 
143
132
  const appFolder = path.relative(this.buildOptions.root, src).split(CDS_CONFIG_PATH_SEP)[0]
144
133
  const model = this.getBuildOption("appModel").get(appFolder)
145
134
  if (!model) {
146
- this.logger.error(`[cds] - failed to load model for service uri ${uri}, data source [mainService]`)
135
+ this.logger.error(`failed to load model for service uri ${uri}, data source [mainService]`)
147
136
  return
148
137
  }
149
138
 
150
139
  const edmx = this._getEdmxForUri(model, appFolder, uri)
151
140
  if (!edmx) {
152
- this.logger.error(`[cds] - failed to resolve service definition for service uri ${uri}, data source [mainService]`)
141
+ this.logger.error(`failed to resolve service definition for service uri ${uri}, data source [mainService]`)
153
142
  return
154
143
  }
155
144
 
@@ -1,13 +1,17 @@
1
- const DEBUG = /\b(true|y|all)\b/.test(process.env.DEBUG) && function (message) { console.warn(message ? '[DEBUG] - ' + message : '') }// eslint-disable-line
2
- const _warn = (message) => { DEBUG && console.error('[WARNING] [hdbmigrationtable] - ', message) } // eslint-disable-line
3
1
  const path = require('path')
4
- const { MigrationTableParser } = require('./migrationtable')
2
+ const parser = require('./migrationtable')
5
3
  const { getProperty, BuildError } = require('../../util')
4
+ const { LOG_MODULE_NAMES } = require('../../constants')
6
5
  const cdscVersion = `-- generated by cds-compiler version ${require('@sap/cds-compiler/package.json').version}`
7
- const cds = require ('../../cds'), minified = csn => cds.linked(csn).minified()
8
- const { compiler:cdsc } = cds
6
+ const cds = require('../../cds'), minified = csn => cds.linked(csn).minified()
7
+ const { compiler: cdsc } = cds
8
+ let logger = cds.log(LOG_MODULE_NAMES)
9
9
 
10
10
  module.exports = async (model, lastDevVersion, srcPath, options = {}) => {
11
+ if (options.logger) {
12
+ logger = options.logger
13
+ }
14
+
11
15
  const journalEntityNames = _getJournalEntityNames(model)
12
16
  const { definitions, deletions, migrations, afterImage } = _toHdiMigration(model, lastDevVersion, journalEntityNames, options)
13
17
  const definitionResult = []
@@ -31,13 +35,13 @@ module.exports = async (model, lastDevVersion, srcPath, options = {}) => {
31
35
  function _toHdiMigration(model, lastDevVersion, journalEntityNames, options) {
32
36
  options.sqlChangeMode = getProperty(options, 'hana.journal.change-mode')
33
37
  const result = cdsc.to.hdi.migration(minified(model), options, lastDevVersion);
34
- if (DEBUG) {
35
- DEBUG('cdsc.to.hdi.migration returned')
38
+ if (logger._debug) {
39
+ logger.debug('cdsc.to.hdi.migration returned')
36
40
  for (const { name, suffix, sql } of result.definitions) {
37
41
  if (suffix === '.hdbtable' || suffix === '.hdbmigrationtable') {
38
42
  if (journalEntityNames.has(name)) {
39
43
  const migration = result.migrations.find(migration => migration.name === name)
40
- DEBUG(`
44
+ logger.debug(`
41
45
  File ${name + '.hdbmigrationtable'} - ${migration ? migration.changeset.length : 0} new changes
42
46
  ${sql}
43
47
  ${migration ? migration.changeset.map(change => change.sql).join('\n') : 'Empty changeset'}
@@ -62,7 +66,7 @@ async function _2migrationtable(srcPath, migration, tableSql, options) {
62
66
  let migrationTableModel = null
63
67
  const file = path.join(srcPath, migration.name + migration.suffix)
64
68
  try {
65
- migrationTableModel = await MigrationTableParser.read(file)
69
+ migrationTableModel = await parser.read(file)
66
70
  } catch (e) {
67
71
  // abort build in order to ensure consistent afterImage model state / hdbmigrationtable file state
68
72
  throw new BuildError(`${path.relative(process.cwd(), file)}: ${e.message}`)
@@ -132,17 +136,15 @@ function _getJournalEntityNames(model) {
132
136
  const journalNames = new Set(cds.reflect(model).all(item => {
133
137
  if (item.kind === 'entity' && item['@cds.persistence.journal'] === true) {
134
138
  if (item['@cds.persistence.skip'] === true || item['@cds.persistence.exists'] === true) {
135
- _warn(`Annotation @cds.persistence.journal skipped for entity '${item.name}' as persistence exists`)
139
+ logger.warn(`[hdbmigrationtable] annotation @cds.persistence.journal skipped for entity '${item.name}' as persistence exists`)
136
140
  }
137
141
  return true
138
142
  }
139
143
  return false
140
144
  }).map(entity => entity.name))
141
145
 
142
- if (DEBUG) {
143
- DEBUG()
144
- DEBUG(`Found ${journalNames.size} model entities annotated with '@cds.persistence.journal`)
145
- DEBUG(`${[...journalNames].join(', ')}`)
146
- }
146
+ logger._debug && logger.debug(`\n[hdbmigrationtable] found ${journalNames.size} model entities annotated with '@cds.persistence.journal`)
147
+ logger._debug && logger.debug(`[hdbmigrationtable] ${[...journalNames].join(', ')}\n`)
148
+
147
149
  return journalNames
148
150
  }