@sap/cds 6.8.3 → 7.0.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 (214) hide show
  1. package/CHANGELOG.md +61 -2
  2. package/README.md +0 -1
  3. package/bin/cds-serve.js +50 -3
  4. package/bin/deploy/to-hana.js +1 -0
  5. package/bin/serve.js +16 -20
  6. package/lib/auth/basic-auth.js +6 -4
  7. package/lib/auth/index.js +4 -3
  8. package/lib/auth/jwt-auth.js +2 -5
  9. package/lib/compile/cds-compile.js +34 -89
  10. package/lib/compile/cdsc.js +11 -0
  11. package/lib/compile/etc/properties.js +2 -2
  12. package/lib/compile/for/lean_drafts.js +36 -69
  13. package/lib/compile/for/nodejs.js +2 -1
  14. package/lib/compile/load.js +1 -1
  15. package/lib/compile/minify.js +2 -0
  16. package/lib/compile/to/csn.js +74 -0
  17. package/{bin/build/provider/hana/2tabledata.js → lib/compile/to/hdbtabledata.js} +4 -6
  18. package/lib/compile/to/json.js +1 -1
  19. package/lib/compile/to/sql.js +8 -6
  20. package/lib/dbs/cds-deploy.js +174 -114
  21. package/lib/env/cds-env.js +64 -79
  22. package/lib/env/cds-requires.js +11 -28
  23. package/lib/env/defaults.js +13 -3
  24. package/lib/env/plugins.js +1 -12
  25. package/lib/env/presets.js +25 -21
  26. package/lib/index.js +121 -147
  27. package/lib/{core/reflect.js → linked/models.js} +2 -2
  28. package/lib/{core/infer.js → linked/queries.js} +2 -0
  29. package/lib/{core/index.js → linked/types.js} +2 -1
  30. package/lib/log/cds-error.js +13 -7
  31. package/lib/log/format/cf.js +1 -1
  32. package/lib/plugins.js +49 -0
  33. package/lib/ql/Query.js +0 -9
  34. package/lib/ql/STREAM.js +0 -1
  35. package/lib/req/context.js +2 -7
  36. package/lib/req/request.js +6 -2
  37. package/lib/req/response.js +23 -10
  38. package/lib/srv/middlewares/ctx-model.js +1 -1
  39. package/lib/srv/middlewares/errors.js +1 -1
  40. package/lib/srv/protocols/_legacy.js +1 -0
  41. package/lib/srv/protocols/graphql.js +7 -16
  42. package/lib/srv/protocols/index.js +59 -45
  43. package/lib/srv/protocols/odata-v2-proxy.js +2 -70
  44. package/lib/srv/srv-api.js +9 -3
  45. package/lib/srv/srv-dispatch.js +12 -9
  46. package/lib/srv/srv-models.js +4 -21
  47. package/lib/srv/srv-tx.js +15 -12
  48. package/lib/utils/cds-test.js +14 -9
  49. package/lib/utils/cds-utils.js +2 -12
  50. package/lib/utils/check-version.js +17 -0
  51. package/{bin/build → lib/utils}/csv-reader.js +23 -24
  52. package/libx/_runtime/auth/index.js +27 -23
  53. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +15 -72
  54. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +1 -1
  55. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +0 -2
  56. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +33 -63
  57. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +14 -18
  58. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -5
  59. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +5 -4
  60. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +37 -40
  61. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/updateToCQN.js +7 -1
  62. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +101 -38
  63. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/errors/AbstractError.js +5 -1
  64. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +2 -1
  65. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/ResourceJsonDeserializer.js +9 -8
  66. package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
  67. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +15 -11
  68. package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +4 -0
  69. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +5 -2
  70. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +1 -123
  71. package/libx/_runtime/cds-services/services/Service.js +79 -107
  72. package/libx/_runtime/cds-services/services/utils/columns.js +23 -19
  73. package/libx/_runtime/cds-services/services/utils/compareJson.js +11 -1
  74. package/libx/_runtime/cds-services/services/utils/differ.js +7 -2
  75. package/libx/_runtime/cds-services/util/assert.js +65 -2
  76. package/libx/_runtime/common/composition/data.js +1 -0
  77. package/libx/_runtime/common/generic/auth/expand.js +1 -1
  78. package/libx/_runtime/common/generic/auth/restrict.js +5 -10
  79. package/libx/_runtime/common/generic/auth/restrictions.js +40 -0
  80. package/libx/_runtime/common/generic/auth/utils.js +1 -2
  81. package/libx/_runtime/common/generic/crud.js +32 -16
  82. package/libx/_runtime/common/generic/etag.js +133 -104
  83. package/libx/_runtime/common/generic/input.js +6 -21
  84. package/libx/_runtime/common/generic/put.js +1 -1
  85. package/libx/_runtime/common/generic/stream.js +52 -0
  86. package/libx/_runtime/common/generic/temporal.js +25 -8
  87. package/libx/_runtime/common/i18n/messages.properties +0 -2
  88. package/libx/_runtime/common/utils/cqn.js +1 -1
  89. package/libx/_runtime/common/utils/cqn2cqn4sql.js +5 -2
  90. package/libx/_runtime/common/utils/csn.js +0 -51
  91. package/libx/_runtime/common/utils/etag.js +30 -0
  92. package/libx/_runtime/common/utils/keys.js +1 -1
  93. package/libx/_runtime/common/utils/normalizeTimestamp.js +25 -0
  94. package/libx/_runtime/common/utils/path.js +1 -1
  95. package/libx/_runtime/common/utils/resolveView.js +2 -1
  96. package/libx/_runtime/common/utils/rewriteAsterisks.js +6 -4
  97. package/libx/_runtime/common/utils/search2cqn4sql.js +12 -16
  98. package/libx/_runtime/common/utils/stream.js +140 -0
  99. package/libx/_runtime/common/utils/streamProp.js +29 -12
  100. package/libx/_runtime/common/utils/templateProcessorPathSerializer.js +0 -2
  101. package/libx/_runtime/db/generic/index.js +0 -2
  102. package/libx/_runtime/db/query/delete.js +2 -2
  103. package/libx/_runtime/db/query/insert.js +2 -2
  104. package/libx/_runtime/db/query/read.js +2 -2
  105. package/libx/_runtime/db/query/run.js +2 -2
  106. package/libx/_runtime/db/query/update.js +2 -2
  107. package/libx/_runtime/db/sql-builder/BaseBuilder.js +0 -6
  108. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +23 -12
  109. package/libx/_runtime/db/sql-builder/FunctionBuilder.js +18 -6
  110. package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -0
  111. package/libx/_runtime/db/sql-builder/SelectBuilder.js +3 -7
  112. package/libx/_runtime/db/sql-builder/UpsertBuilder.js +1 -0
  113. package/libx/_runtime/db/utils/normalizeTimeData.js +7 -3
  114. package/libx/_runtime/fiori/draft.js +2 -0
  115. package/libx/_runtime/fiori/generic/activate.js +8 -9
  116. package/libx/_runtime/fiori/generic/before.js +30 -20
  117. package/libx/_runtime/fiori/generic/cancel.js +5 -3
  118. package/libx/_runtime/fiori/generic/delete.js +5 -3
  119. package/libx/_runtime/fiori/generic/edit.js +7 -7
  120. package/libx/_runtime/fiori/generic/index.js +10 -16
  121. package/libx/_runtime/fiori/generic/new.js +5 -3
  122. package/libx/_runtime/fiori/generic/patch.js +11 -8
  123. package/libx/_runtime/fiori/generic/prepare.js +13 -6
  124. package/libx/_runtime/fiori/generic/read.js +12 -6
  125. package/libx/_runtime/fiori/lean-draft.js +207 -152
  126. package/libx/_runtime/fiori/utils/delete.js +10 -5
  127. package/libx/_runtime/fiori/utils/req.js +17 -5
  128. package/libx/_runtime/fiori/utils/stream.js +36 -0
  129. package/libx/_runtime/hana/Service.js +12 -9
  130. package/libx/_runtime/hana/conversion.js +10 -15
  131. package/libx/_runtime/hana/driver.js +2 -0
  132. package/libx/_runtime/hana/execute.js +28 -6
  133. package/libx/_runtime/hana/pool.js +36 -122
  134. package/libx/_runtime/hana/search2cqn4sql.js +34 -36
  135. package/libx/_runtime/messaging/enterprise-messaging-utils/getTenantInfo.js +2 -6
  136. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +3 -1
  137. package/libx/_runtime/messaging/enterprise-messaging.js +10 -58
  138. package/libx/_runtime/messaging/outbox/utils.js +1 -1
  139. package/libx/_runtime/remote/Service.js +20 -1
  140. package/libx/_runtime/remote/utils/client.js +3 -5
  141. package/libx/_runtime/sqlite/Service.js +4 -6
  142. package/libx/_runtime/sqlite/conversion.js +3 -13
  143. package/libx/_runtime/sqlite/customBuilder/CustomFunctionBuilder.js +9 -6
  144. package/libx/_runtime/sqlite/customBuilder/CustomUpsertBuilder.js +6 -1
  145. package/libx/_runtime/sqlite/execute.js +5 -16
  146. package/libx/odata/afterburner.js +22 -6
  147. package/libx/odata/grammar.pegjs +6 -1
  148. package/libx/odata/parser.js +1 -1
  149. package/libx/rest/RestAdapter.js +16 -9
  150. package/libx/rest/RestRequest.js +1 -1
  151. package/libx/rest/middleware/input.js +2 -1
  152. package/libx/rest/middleware/operation.js +1 -0
  153. package/libx/rest/middleware/parse.js +3 -2
  154. package/libx/rest/middleware/payload.js +9 -8
  155. package/libx/rest/middleware/read.js +1 -0
  156. package/package.json +9 -16
  157. package/app/fiori/preview.js +0 -270
  158. package/app/fiori/routes.js +0 -59
  159. package/bin/build/buildTaskEngine.js +0 -360
  160. package/bin/build/buildTaskFactory.js +0 -283
  161. package/bin/build/buildTaskHandler.js +0 -241
  162. package/bin/build/buildTaskProvider.js +0 -22
  163. package/bin/build/buildTaskProviderFactory.js +0 -175
  164. package/bin/build/cds.js +0 -5
  165. package/bin/build/constants.js +0 -66
  166. package/bin/build/index.js +0 -58
  167. package/bin/build/provider/buildTaskHandlerEdmx.js +0 -82
  168. package/bin/build/provider/buildTaskHandlerFeatureToggles.js +0 -131
  169. package/bin/build/provider/buildTaskHandlerInternal.js +0 -254
  170. package/bin/build/provider/buildTaskProviderInternal.js +0 -383
  171. package/bin/build/provider/fiori/index.js +0 -171
  172. package/bin/build/provider/hana/2migration.js +0 -179
  173. package/bin/build/provider/hana/index.js +0 -505
  174. package/bin/build/provider/hana/migrationtable.js +0 -472
  175. package/bin/build/provider/hana/template/.hdiconfig-haas +0 -163
  176. package/bin/build/provider/hana/template/.hdiconfig-hanacloud +0 -137
  177. package/bin/build/provider/hana/template/.hdinamespace +0 -4
  178. package/bin/build/provider/hana/template/package.json +0 -12
  179. package/bin/build/provider/hana/template/undeploy.json +0 -5
  180. package/bin/build/provider/java/index.js +0 -111
  181. package/bin/build/provider/java-cf/index.js +0 -1
  182. package/bin/build/provider/mtx/index.js +0 -268
  183. package/bin/build/provider/mtx/resourcesTarBuilder.js +0 -95
  184. package/bin/build/provider/mtx-extension/index.js +0 -131
  185. package/bin/build/provider/mtx-sidecar/index.js +0 -137
  186. package/bin/build/provider/node-cf/index.js +0 -1
  187. package/bin/build/provider/nodejs/index.js +0 -192
  188. package/bin/build/util.js +0 -299
  189. package/bin/cds.js +0 -125
  190. package/bin/deploy/to-hana/cfUtil.js +0 -355
  191. package/bin/deploy/to-hana/gitUtil.js +0 -57
  192. package/bin/deploy/to-hana/hana.js +0 -306
  193. package/bin/deploy/to-hana/hdiDeployUtil.js +0 -153
  194. package/bin/deploy/to-hana/index.js +0 -16
  195. package/bin/deploy/to-hana/mtaUtil.js +0 -170
  196. package/bin/mtx/in-cds.js +0 -17
  197. package/bin/plugins.js +0 -32
  198. package/bin/run.js +0 -24
  199. package/bin/utils/log.js +0 -24
  200. package/bin/version.js +0 -178
  201. package/libx/_runtime/audit/Service.js +0 -222
  202. package/libx/_runtime/audit/generic/personal/access.js +0 -61
  203. package/libx/_runtime/audit/generic/personal/index.js +0 -56
  204. package/libx/_runtime/audit/generic/personal/modification.js +0 -132
  205. package/libx/_runtime/audit/generic/personal/utils.js +0 -186
  206. package/libx/_runtime/audit/utils/log.js +0 -23
  207. package/libx/_runtime/audit/utils/v2.js +0 -176
  208. package/libx/_runtime/db/data-conversion/timestamp.js +0 -9
  209. package/libx/_runtime/db/generic/integrity.js +0 -455
  210. package/srv/audit-log.cds +0 -87
  211. package/srv/mtx.cds +0 -2
  212. package/srv/mtx.js +0 -8
  213. /package/lib/{core → linked}/classes.js +0 -0
  214. /package/lib/{core → linked}/entities.js +0 -0
@@ -1,137 +0,0 @@
1
-
2
- {
3
- "file_suffixes": {
4
- "csv": {
5
- "plugin_name": "com.sap.hana.di.tabledata.source"
6
- },
7
- "hdbafllangprocedure": {
8
- "plugin_name": "com.sap.hana.di.afllangprocedure"
9
- },
10
- "hdbanalyticprivilege": {
11
- "plugin_name": "com.sap.hana.di.analyticprivilege"
12
- },
13
- "hdbcalculationview": {
14
- "plugin_name": "com.sap.hana.di.calculationview"
15
- },
16
- "hdbcollection": {
17
- "plugin_name": "com.sap.hana.di.collection"
18
- },
19
- "hdbconstraint": {
20
- "plugin_name": "com.sap.hana.di.constraint"
21
- },
22
- "hdbdropcreatetable": {
23
- "plugin_name": "com.sap.hana.di.dropcreatetable"
24
- },
25
- "hdbflowgraph": {
26
- "plugin_name": "com.sap.hana.di.flowgraph"
27
- },
28
- "hdbfunction": {
29
- "plugin_name": "com.sap.hana.di.function"
30
- },
31
- "hdbgraphworkspace": {
32
- "plugin_name": "com.sap.hana.di.graphworkspace"
33
- },
34
- "hdbhadoopmrjob": {
35
- "plugin_name": "com.sap.hana.di.virtualfunctionpackage.hadoop"
36
- },
37
- "hdbindex": {
38
- "plugin_name": "com.sap.hana.di.index"
39
- },
40
- "hdblibrary": {
41
- "plugin_name": "com.sap.hana.di.library"
42
- },
43
- "hdbmigrationtable": {
44
- "plugin_name": "com.sap.hana.di.table.migration"
45
- },
46
- "hdbprocedure": {
47
- "plugin_name": "com.sap.hana.di.procedure"
48
- },
49
- "hdbprojectionview": {
50
- "plugin_name": "com.sap.hana.di.projectionview"
51
- },
52
- "hdbprojectionviewconfig": {
53
- "plugin_name": "com.sap.hana.di.projectionview.config"
54
- },
55
- "hdbreptask": {
56
- "plugin_name": "com.sap.hana.di.reptask"
57
- },
58
- "hdbresultcache": {
59
- "plugin_name": "com.sap.hana.di.resultcache"
60
- },
61
- "hdbrole": {
62
- "plugin_name": "com.sap.hana.di.role"
63
- },
64
- "hdbroleconfig": {
65
- "plugin_name": "com.sap.hana.di.role.config"
66
- },
67
- "hdbsearchruleset": {
68
- "plugin_name": "com.sap.hana.di.searchruleset"
69
- },
70
- "hdbsequence": {
71
- "plugin_name": "com.sap.hana.di.sequence"
72
- },
73
- "hdbstatistics": {
74
- "plugin_name": "com.sap.hana.di.statistics"
75
- },
76
- "hdbstructuredprivilege": {
77
- "plugin_name": "com.sap.hana.di.structuredprivilege"
78
- },
79
- "hdbsynonym": {
80
- "plugin_name": "com.sap.hana.di.synonym"
81
- },
82
- "hdbsynonymconfig": {
83
- "plugin_name": "com.sap.hana.di.synonym.config"
84
- },
85
- "hdbsystemversioning": {
86
- "plugin_name": "com.sap.hana.di.systemversioning"
87
- },
88
- "hdbtable": {
89
- "plugin_name": "com.sap.hana.di.table"
90
- },
91
- "hdbtabledata": {
92
- "plugin_name": "com.sap.hana.di.tabledata"
93
- },
94
- "hdbtabletype": {
95
- "plugin_name": "com.sap.hana.di.tabletype"
96
- },
97
- "hdbtrigger": {
98
- "plugin_name": "com.sap.hana.di.trigger"
99
- },
100
- "hdbview": {
101
- "plugin_name": "com.sap.hana.di.view"
102
- },
103
- "hdbvirtualfunction": {
104
- "plugin_name": "com.sap.hana.di.virtualfunction"
105
- },
106
- "hdbvirtualfunctionconfig": {
107
- "plugin_name": "com.sap.hana.di.virtualfunction.config"
108
- },
109
- "hdbvirtualpackagehadoop": {
110
- "plugin_name": "com.sap.hana.di.virtualpackage.hadoop"
111
- },
112
- "hdbvirtualpackagesparksql": {
113
- "plugin_name": "com.sap.hana.di.virtualpackage.sparksql"
114
- },
115
- "hdbvirtualprocedure": {
116
- "plugin_name": "com.sap.hana.di.virtualprocedure"
117
- },
118
- "hdbvirtualprocedureconfig": {
119
- "plugin_name": "com.sap.hana.di.virtualprocedure.config"
120
- },
121
- "hdbvirtualtable": {
122
- "plugin_name": "com.sap.hana.di.virtualtable"
123
- },
124
- "hdbvirtualtableconfig": {
125
- "plugin_name": "com.sap.hana.di.virtualtable.config"
126
- },
127
- "properties": {
128
- "plugin_name": "com.sap.hana.di.tabledata.properties"
129
- },
130
- "tags": {
131
- "plugin_name": "com.sap.hana.di.tabledata.properties"
132
- },
133
- "txt": {
134
- "plugin_name": "com.sap.hana.di.copyonly"
135
- }
136
- }
137
- }
@@ -1,4 +0,0 @@
1
- {
2
- "name": "",
3
- "subfolder": "ignore"
4
- }
@@ -1,12 +0,0 @@
1
- {
2
- "name": "deploy",
3
- "dependencies": {
4
- "@sap/hdi-deploy": "^4"
5
- },
6
- "engines": {
7
- "node": "^14 || ^16 || ^18"
8
- },
9
- "scripts": {
10
- "start": "node node_modules/@sap/hdi-deploy/deploy.js"
11
- }
12
- }
@@ -1,5 +0,0 @@
1
- [
2
- "src/gen/**/*.hdbview",
3
- "src/gen/**/*.hdbindex",
4
- "src/gen/**/*.hdbconstraint"
5
- ]
@@ -1,111 +0,0 @@
1
- const fs = require('fs')
2
- const path = require('path')
3
- const cds = require('../../cds')
4
- const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
5
- const { isOldJavaStack, BuildError } = require('../../util')
6
-
7
- const { BUILD_OPTION_OUTPUT_MODE, ODATA_VERSION_V2, OUTPUT_MODE_RESULT_ONLY, FILE_EXT_CDS, SKIP_ASSERT_COMPILER_V2, CONTENT_LANGUAGE_BUNDLES, CONTENT_DEFAULT_CSN, DEFAULT_CSN_FILE_NAME } = require('../../constants')
8
- const { INFO } = require('../../buildTaskHandler')
9
-
10
- const DEFAULT_COMPILE_DEST_FOLDER = path.normalize('src/main/resources/edmx')
11
-
12
- class JavaModuleBuilder extends BuildTaskHandlerEdmx {
13
- init() {
14
- super.init()
15
- this.task.options.compileDest = path.resolve(this.task.dest, this.task.options.compileDest || DEFAULT_COMPILE_DEST_FOLDER)
16
- }
17
-
18
- async build() {
19
- const { src, dest } = this.task
20
-
21
- const odataOptions = {
22
- version: cds.env.odata?.version
23
- }
24
-
25
- if (await isOldJavaStack([src, this.buildOptions.root])) {
26
- if (!this._isCompilerV1() && !cds.env.build?.[SKIP_ASSERT_COMPILER_V2]) {
27
- throw new BuildError('CDS compiler version 2 does no longer support the classic CAP Java runtime. It is recommended to migrate to the current CAP Java runtime SDK. See https://cap.cloud.sap/docs/java/migration for more.')
28
- }
29
- // default is now v4 and not v2 anymore, so warn and overwrite with v2 if using default
30
- if (!cds.env.for('cds', this.buildOptions.root, false).odata?.version) {
31
- odataOptions.version = ODATA_VERSION_V2
32
- this.pushMessage('Forcing OData v2 for building though the default is v4. Make sure to define OData v2 in cds configuration.', INFO)
33
- }
34
-
35
- // 'sql_mapping' and 'cds.persistence.name' annotations are required by old java stack
36
- if (cds.env.sql.names !== 'plain') {
37
- odataOptions.sql_mapping = cds.env.sql.names
38
- }
39
- }
40
-
41
- const model = await this.model()
42
- if (!model) {
43
- return this._result
44
- }
45
-
46
- const odata = await this._compileForOdata(model, this.task.options.compileDest, odataOptions)
47
- await this.compileToEdmx(odata, this.task.options.compileDest, odataOptions)
48
-
49
- if (this.hasBuildOption(CONTENT_LANGUAGE_BUNDLES, true)) {
50
- // collect and write language bundles into single i18n.json file
51
- const i18nFolder = cds.env.i18n.folders?.[0] || 'i18n'
52
- const i18n = await this.collectLanguageBundles(model, path.join(this.task.dest, i18nFolder))
53
- if (i18n) {
54
- this._result.languageBundles = i18n.bundles
55
- }
56
- }
57
- if (this.isStagingBuild() && !this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
58
- await this._copyNativeContent(src, dest)
59
- }
60
- return this._result
61
- }
62
-
63
- async clean() {
64
- if (this.isStagingBuild()) {
65
- return super.clean()
66
- }
67
- this.logger._debug && this.logger.debug(`Deleting build target folder ${this.task.options.compileDest}`)
68
- await fs.promises.rm(this.task.options.compileDest, { force: true, recursive: true })
69
- }
70
-
71
- async _copyNativeContent(src, dest) {
72
- return super.copyNativeContent(src, dest, (entry) => {
73
- if (fs.statSync(entry).isDirectory()) {
74
- return true // using common filter for folders
75
- } else {
76
- const extname = path.extname(entry)
77
- return extname !== FILE_EXT_CDS
78
- }
79
- })
80
- }
81
-
82
- async _compileForOdata(model, csnDest, compileOptions) {
83
- // csn for service providers
84
- const m = cds.compile.for.java(model, {
85
- ...this._options4odata(),
86
- ...compileOptions
87
- })
88
- const csnFile = path.join(csnDest, DEFAULT_CSN_FILE_NAME)
89
- let csnModel
90
- // adding csn to build result containing @source and _where persisted properties
91
- if (this.hasBuildOption(CONTENT_DEFAULT_CSN, true)) { //default true or undefined
92
- const csnStr = await this.compileToJson(model, csnFile)
93
- csnModel = JSON.parse(csnStr)
94
- csnModel.meta = model.meta
95
- } else {
96
- const csnStr = await this.compileToJson(m, csnFile)
97
- csnModel = JSON.parse(csnStr)
98
- csnModel.meta = m.meta
99
- }
100
- this._result.csn = csnModel
101
-
102
- return m
103
- }
104
-
105
- _isCompilerV1() {
106
- const version = cds.compiler.version()
107
- const match = version.match(/(\d+)\.?(\d*)\.?(\d*)/)
108
- return match && match[1] === 1
109
- }
110
- }
111
- module.exports = JavaModuleBuilder
@@ -1 +0,0 @@
1
- module.exports = require('../java')
@@ -1,268 +0,0 @@
1
- /* eslint-disable no-empty */
2
- const fs = require('fs')
3
- const path = require('path')
4
- const cds = require('../../cds')
5
- const BuildTaskProviderInternal = require("../buildTaskProviderInternal")
6
- const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
7
- const { isStreamlinedMtx, hasJavaNature } = require('../../util')
8
- const ResourcesTarProvider = require('./resourcesTarBuilder')
9
-
10
- const { BUILD_TASK_HANA, FOLDER_GEN } = require('../../constants')
11
- const { WARNING, ERROR } = BuildTaskHandlerEdmx
12
- const FOLDER_SDC = "sdc"
13
- const FOLDER_NODE_MODULES = "node_modules"
14
- const FOLDER_TEMPLATES = "tpl"
15
-
16
- class MtxModuleBuilder extends BuildTaskHandlerEdmx {
17
- get priority() {
18
- // should be scheduled after 'hana' build tasks are finished
19
- return BuildTaskHandlerEdmx.PRIORITY_MIN_VALUE
20
- }
21
- init() {
22
- super.init()
23
-
24
- if (hasJavaNature([this.buildOptions.root, this.task.src, cds.env.folders.srv])) {
25
- // Java projects having this build task configured are using Classic MTX
26
- // Streamlined MTX based Java projects have to configure the 'mtx-sidecar' build task instead.
27
- this._delegate = new ClassicMtxBuilder(this)
28
- } else {
29
- // Nodejs projects
30
- if (isStreamlinedMtx()) {
31
- this._delegate = new StreamlinedMtxBuilder(this)
32
- } else {
33
- this._delegate = new ClassicMtxBuilder(this)
34
- }
35
- }
36
- }
37
-
38
- async build() {
39
- return this._delegate.build()
40
- }
41
-
42
- async clean() {
43
- return this._delegate.clean()
44
- }
45
- }
46
-
47
- class StreamlinedMtxBuilder {
48
- constructor(handler) {
49
- this._handler = handler
50
- }
51
- async build() {
52
- // Non-sidecar scenario: model-provider is implemented by the Nodejs app itself (default for Nodejs).
53
- // Only create resources TAR, compiled CSN(s) are created by the Nodejs app build task.
54
- const dest = cds.env.build?.target !== "." ? this._handler.task.dest : path.join(this._handler.task.dest, FOLDER_GEN)
55
- const model = await this._handler.model()
56
- if (!model) {
57
- return
58
- }
59
- return new ResourcesTarProvider(this._handler).createTar(dest, model)
60
- }
61
- async clean() {
62
- // staging build content is deleted by BuildTaskEngine
63
- if (this._handler.buildOptions.root === this._handler.buildOptions.target) {
64
- // remove 'gen' folder
65
- return fs.promises.rm(path.join(this._handler.task.dest, FOLDER_GEN), { force: true, recursive: true })
66
- }
67
- }
68
- }
69
-
70
- class ClassicMtxBuilder {
71
- constructor(handler) {
72
- this._handler = handler
73
- }
74
-
75
- async build() {
76
- if (cds.env.requires.toggles === true) {
77
- throw new Error("Feature toggles are only supported by Streamlined MTX")
78
- }
79
-
80
- const buildOptions = this._handler.buildOptions
81
- const destSdc = buildOptions.root === buildOptions.target ? path.join(this._handler.task.dest, FOLDER_GEN, FOLDER_SDC) : path.join(this._handler.task.dest, FOLDER_SDC)
82
- const model = await this._handler.model()
83
- if (!model) {
84
- return
85
- }
86
-
87
- // custom build tasks for srv and db modules might be defined
88
- const tenantDbPath = await this._getHanaTenantDbPath()
89
-
90
- // validate extension whitelists defined for this SaaS application
91
- this._validateExtensionAllowLists(model, tenantDbPath)
92
-
93
- // copy base model sources
94
- await Promise.all(model.$sources.map(src => {
95
- if (src.includes(FOLDER_NODE_MODULES)) {
96
- return this._handler.copy(src).to(path.join(destSdc, src.substr(src.indexOf(FOLDER_NODE_MODULES))))
97
- } else {
98
- const relSrc = path.relative(buildOptions.root, src)
99
- if (relSrc.startsWith("..")) {
100
- this._handler.logger.warn(`model file is out of project scope, skipping file ${src}`)
101
- return Promise.resolve()
102
- }
103
- return this._handler.copy(src).to(path.join(destSdc, relSrc))
104
- }
105
- }))
106
-
107
- // collect and write language bundles into single i18n.json file
108
- const i18nFolder = cds.env.i18n.folders?.[0] || 'i18n'
109
- const i18n = await this._handler.collectLanguageBundles(model, path.join(destSdc, i18nFolder))
110
- if (i18n) {
111
- this._handler._result.languageBundles = i18n.bundles
112
- }
113
-
114
- // copy native hana content and templates
115
- await this._copyNativeContent(this._handler.task.src, destSdc, tenantDbPath)
116
- }
117
-
118
- async clean() {
119
- // staging build content is deleted by BuildTaskEngine
120
- if (this._handler.buildOptions.root === this._handler.buildOptions.target) {
121
- // remove 'gen' folder
122
- return fs.promises.rm(path.join(this._handler.task.dest, FOLDER_GEN), { force: true, recursive: true })
123
- }
124
- }
125
-
126
- async _copyNativeContent(src, dest, tenantDbPath) {
127
- // copying templates
128
- const tplSrc = path.join(src, FOLDER_TEMPLATES)
129
- if (fs.existsSync(tplSrc)) {
130
- const tplDest = path.join(path.dirname(dest), FOLDER_TEMPLATES)
131
- await this._copyTemplates(tplSrc, tplDest)
132
- }
133
-
134
- if (tenantDbPath) {
135
- // copy native HANA artifacts, e.g. .csv files
136
- const dbDest = path.resolve(dest, path.relative(this._handler.buildOptions.root, tenantDbPath))
137
- if (!src.startsWith(dbDest)) { // ensure valid paths
138
- await this._copyNativeHanaContent(tenantDbPath, dbDest)
139
- } else {
140
- this.pushMessage(`Invalid mtx build task configuration detected, destination folder ${dbDest} must not be nested within 'src' folder`, ERROR)
141
- }
142
- }
143
- }
144
-
145
- async _copyNativeHanaContent(src, dest) {
146
- return this._handler.copyNativeContent(src, dest, (entry) => {
147
- if (fs.statSync(entry).isDirectory()) {
148
- const folderName = path.basename(entry)
149
- return folderName !== FOLDER_NODE_MODULES
150
- }
151
- // also add table data properties files containing translated texts
152
- return /\.csv$|\.hdb.*$|^\.hdi.*|\.properties$|^undeploy\.json/.test(path.basename(entry))
153
- })
154
- }
155
-
156
- async _copyTemplates(src, dest) {
157
- return this._handler.copyNativeContent(src, dest, (entry) => {
158
- if (fs.statSync(entry).isFile()) {
159
- return /\.cds$/.test(path.basename(entry))
160
- }
161
- return true
162
- })
163
- }
164
-
165
- /**
166
- * Extensions shall be restricted to relevant entities, by default all entities and services can be extended.
167
- * Empty whitelists indicate that all services or entities can be extended.
168
- * <br>
169
- * A warning is logged in case neither a 'entity-whitelist' nor a o service-whitelist has been defined.
170
- * An error is thrown in case a invalid entry is found.
171
- *
172
- * @param {Object} model - the reflected csn for this SaaS application
173
- */
174
- _validateExtensionAllowLists(model, tenantDbPath) {
175
- let entityWhitelist = cds.env.mtx?.["entity-whitelist"]
176
- let serviceWhitelist = cds.env.mtx?.["service-whitelist"]
177
- let extensionAllowlist = cds.env.mtx?.["extension-allowlist"]
178
-
179
- // for java projects mtx configuration is part of sidecar config
180
- if (!entityWhitelist && !serviceWhitelist && !extensionAllowlist && tenantDbPath) {
181
- const dbEnv = cds.env.for("cds", tenantDbPath)
182
- entityWhitelist = dbEnv.mtx?.["entity-whitelist"]
183
- serviceWhitelist = dbEnv.mtx?.["service-whitelist"]
184
- extensionAllowlist = dbEnv.mtx?.["extension-allowlist"]
185
- }
186
-
187
- function isValid(e, pattern, nsPattern, kind) {
188
- return e && e.name && (e.name === pattern || (nsPattern && e.name.startsWith(nsPattern))) && (!kind || e.kind === kind)
189
- }
190
-
191
- if (extensionAllowlist || entityWhitelist || serviceWhitelist) {
192
- const invalidEntries = new Set()
193
- const reflected = cds.reflect(model)
194
-
195
- if (Array.isArray(extensionAllowlist)) {
196
- extensionAllowlist.forEach(allowListEntry => {
197
- if (Array.isArray(allowListEntry.for)) {
198
- allowListEntry.for.forEach(pattern => {
199
- if (pattern !== '*') {
200
- if (!reflected.find(e => isValid(e, pattern, pattern + '.', allowListEntry.kind))) {
201
- invalidEntries.add(pattern)
202
- }
203
- }
204
- })
205
- }
206
- })
207
- if (invalidEntries.size > 0) {
208
- this._handler.pushMessage(`Invalid entries found in 'extension-allowlist' - [${[...invalidEntries].join(', ')}]`, WARNING)
209
- }
210
- } else if (Array.isArray(entityWhitelist) || Array.isArray(serviceWhitelist)) {
211
- // validate whitelist entries
212
- if (Array.isArray(entityWhitelist)) {
213
- entityWhitelist.forEach(name => {
214
- if (!reflected.find(e => isValid(e, name, null, "entity"))) {
215
- invalidEntries.add(name)
216
- }
217
- })
218
- }
219
- if (Array.isArray(serviceWhitelist)) {
220
- serviceWhitelist.forEach(name => {
221
- if (!reflected.find(e => isValid(e, name, null, "service"))) {
222
- invalidEntries.add(name)
223
- }
224
- })
225
- }
226
- if (invalidEntries.size > 0) {
227
- this._handler.pushMessage(`Invalid entries found in 'entity-whitelist' or 'service-whitelist' - [${[...invalidEntries].join(', ')}]`, WARNING) //NOSONAR
228
- }
229
- }
230
- }
231
- }
232
-
233
- /**
234
- * Returns the build tasks of this project - either user defined or calculated by BuildTaskFactory.
235
- * A build task of type 'hana' is enforced in order to copy existing native hana artifacts later on.
236
- *
237
- * @returns {string} the src folder of the tenant db module
238
- */
239
- async _getHanaTenantDbPath() {
240
- let tasks = this._handler.buildOptions.tasks || []
241
- const modelPaths = this._handler.resolveModel()
242
-
243
- // ensure that the hana task is contained even if this mtx task has been executed solely using "cds build --for mtx"
244
- if (!tasks.find(task => task.for === BUILD_TASK_HANA)) {
245
- //mtx task might have been executed as separate task
246
- tasks = cds.env.build?.tasks || []
247
- if (tasks.length === 0) {
248
- const provider = new BuildTaskProviderInternal(this._handler.logger)
249
- await provider.lookupTasks(tasks, this._handler.buildOptions)
250
- }
251
- }
252
- // the SaaS app might use a tenant aware db as well as a shared db deployed using static hdi-deployer
253
- // pick the hana build task referring to the tenant aware db - the src path has to be contained in this build task's model options
254
- const hanaDbPaths = tasks.filter(task => task.for === BUILD_TASK_HANA).map(hanaTask => path.resolve(this._handler.buildOptions.root, hanaTask.src || cds.env.folders.db))
255
- let tenantDbPath = hanaDbPaths.find(hanaDbPath => hanaDbPaths.length === 1 || modelPaths.some(modelPath => path.dirname(modelPath) === hanaDbPath))
256
-
257
- if (!tenantDbPath) {
258
- tenantDbPath = path.join(this._handler.buildOptions.root, cds.env.folders.db)
259
- if (hanaDbPaths.length === 0) {
260
- this._handler.pushMessage(`no 'hana' build task found, use default location '${tenantDbPath}'`, WARNING)
261
- } else {
262
- this._handler.pushMessage(`no 'hana' build task found matching model scope '${this._handler.task.options.model}', use default location '${tenantDbPath}'`, WARNING)
263
- }
264
- }
265
- return tenantDbPath
266
- }
267
- }
268
- module.exports = MtxModuleBuilder
@@ -1,95 +0,0 @@
1
- const path = require('path')
2
- const cds = require('../../cds')
3
- const BuildTaskHandlerInternal = require('../buildTaskHandlerInternal')
4
-
5
- const { BUILD_TASK_HANA } = require('../../constants')
6
- const { fs } = require('../../../../lib/utils/cds-utils')
7
- const { WARNING } = BuildTaskHandlerInternal
8
- const DEFAULT_TAR_NAME = "resources.tgz"
9
-
10
- class ResourcesTarBuilder {
11
- constructor(handler) {
12
- this._handler = handler
13
- }
14
-
15
- get handler() { return this._handler }
16
-
17
- async createTar(dest, model) {
18
- const { root, resources } = await this._getResources(model)
19
- if (resources.length === 0) {
20
- // packTarArchive fails otherwise
21
- this.handler.pushMessage("No deployment resources found - skip resources.tgz", WARNING)
22
- return
23
- }
24
- await this.writeTarFile(path.join(dest, DEFAULT_TAR_NAME), root, resources)
25
- }
26
-
27
- /**
28
- * Creates a TAR file at the given absolute tarPath. An optional resources list holds the files and folders
29
- * that will be added to the TAR. Paths are relative to the passed root directory. If omitted, the entire
30
- * root directory contents will be added.
31
- * @param {*} tarFile Absolute TAR file name.
32
- * @param {*} root The root directory the passed resources are relative to.
33
- * @param {*} resources Optional list of absolute or relative resource paths - relative to the given root directory.
34
- * If omitted all resources contained in the root directory are added to the TAR file.
35
- */
36
- async writeTarFile(tarFile, root, resources) {
37
- const { tar } = require('../../../../lib').utils
38
- await tar.czfd(tarFile, root, resources)
39
- this.handler.pushFile(tarFile)
40
- }
41
-
42
- async _getResources(model) {
43
- // distinguish HANA and SQLITE deployment
44
- let root = await this._getHanaTenantDbDest()
45
- let resources
46
- if (root) {
47
- resources = this._getHanaResources(root)
48
- } else {
49
- root = this.handler.buildOptions.root
50
- resources = await this._getSqliteResources(model)
51
- }
52
- return { root, resources }
53
- }
54
-
55
- /**
56
- * Reads a list of files and folders required for HANA deployment.
57
- * This is a subset of all files contained in the directory.
58
- * - 'db/src', 'db/cfg', 'db/undeploy.json'...
59
- * See '../../../../lib.deploy'
60
- * Note: the hana build task has already been executed
61
- * @param {string} root
62
- * @returns an array containing all resources
63
- */
64
- _getHanaResources(root) {
65
- return ['src', 'cfg', 'undeploy.json', '.hdiignore'].reduce((acc, res) => {
66
- const resPath = path.join(root, res)
67
- if (fs.existsSync(resPath)) {
68
- acc.push(resPath)
69
- }
70
- return acc
71
- }, [])
72
- }
73
-
74
- /**
75
- * Reads all resources for Sqlite deployment - see '../../../../lib.deploy'
76
- *
77
- * @param {object} model
78
- * @returns
79
- */
80
- async _getSqliteResources(model) {
81
- const { resources } = cds.deploy
82
- return Object.keys(await resources(model))
83
- }
84
-
85
- async _getHanaTenantDbDest() {
86
- const buildOptions = this.handler.buildOptions
87
- let hanaTask = buildOptions.tasks ? buildOptions.tasks.find(task => task.for === BUILD_TASK_HANA) : undefined
88
- if (!hanaTask) {
89
- this.handler.pushMessage(`Found SQLite database configuration. Ensure that productive cloud deployments requiring SAP HANA database are built with 'production' profile.`, WARNING)
90
- return null
91
- }
92
- return hanaTask.dest
93
- }
94
- }
95
- module.exports = ResourcesTarBuilder