@sap/cds 6.8.4 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/CHANGELOG.md +66 -4
  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 +3 -3
  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 +2 -2
  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/protocols/odata-v4.js +9 -4
  45. package/lib/srv/srv-api.js +9 -3
  46. package/lib/srv/srv-dispatch.js +12 -9
  47. package/lib/srv/srv-models.js +4 -21
  48. package/lib/srv/srv-tx.js +15 -12
  49. package/lib/utils/cds-test.js +14 -9
  50. package/lib/utils/cds-utils.js +2 -12
  51. package/lib/utils/check-version.js +17 -0
  52. package/{bin/build → lib/utils}/csv-reader.js +23 -24
  53. package/libx/_runtime/auth/index.js +27 -23
  54. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +15 -72
  55. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +1 -1
  56. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +0 -2
  57. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +33 -63
  58. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +14 -18
  59. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -5
  60. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +5 -4
  61. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +37 -40
  62. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/updateToCQN.js +7 -1
  63. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +101 -38
  64. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/errors/AbstractError.js +5 -1
  65. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriTokenizer.js +5 -8
  66. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +2 -1
  67. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/ResourceJsonDeserializer.js +9 -8
  68. package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
  69. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +15 -11
  70. package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +4 -0
  71. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +5 -2
  72. package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +1 -123
  73. package/libx/_runtime/cds-services/services/Service.js +79 -107
  74. package/libx/_runtime/cds-services/services/utils/columns.js +23 -19
  75. package/libx/_runtime/cds-services/services/utils/compareJson.js +11 -1
  76. package/libx/_runtime/cds-services/services/utils/differ.js +7 -2
  77. package/libx/_runtime/cds-services/util/assert.js +65 -2
  78. package/libx/_runtime/common/composition/data.js +1 -0
  79. package/libx/_runtime/common/generic/auth/expand.js +1 -1
  80. package/libx/_runtime/common/generic/auth/restrict.js +5 -10
  81. package/libx/_runtime/common/generic/auth/restrictions.js +40 -0
  82. package/libx/_runtime/common/generic/auth/utils.js +1 -2
  83. package/libx/_runtime/common/generic/crud.js +32 -16
  84. package/libx/_runtime/common/generic/etag.js +133 -104
  85. package/libx/_runtime/common/generic/input.js +6 -21
  86. package/libx/_runtime/common/generic/put.js +1 -1
  87. package/libx/_runtime/common/generic/stream.js +52 -0
  88. package/libx/_runtime/common/generic/temporal.js +25 -8
  89. package/libx/_runtime/common/i18n/messages.properties +0 -2
  90. package/libx/_runtime/common/utils/cqn.js +1 -1
  91. package/libx/_runtime/common/utils/cqn2cqn4sql.js +5 -2
  92. package/libx/_runtime/common/utils/csn.js +0 -51
  93. package/libx/_runtime/common/utils/etag.js +30 -0
  94. package/libx/_runtime/common/utils/keys.js +1 -1
  95. package/libx/_runtime/common/utils/normalizeTimestamp.js +25 -0
  96. package/libx/_runtime/common/utils/path.js +1 -1
  97. package/libx/_runtime/common/utils/resolveView.js +2 -1
  98. package/libx/_runtime/common/utils/rewriteAsterisks.js +6 -4
  99. package/libx/_runtime/common/utils/search2cqn4sql.js +12 -16
  100. package/libx/_runtime/common/utils/stream.js +140 -0
  101. package/libx/_runtime/common/utils/streamProp.js +29 -12
  102. package/libx/_runtime/common/utils/templateProcessorPathSerializer.js +0 -2
  103. package/libx/_runtime/db/generic/index.js +0 -2
  104. package/libx/_runtime/db/query/delete.js +2 -2
  105. package/libx/_runtime/db/query/insert.js +2 -2
  106. package/libx/_runtime/db/query/read.js +2 -2
  107. package/libx/_runtime/db/query/run.js +2 -2
  108. package/libx/_runtime/db/query/update.js +2 -2
  109. package/libx/_runtime/db/sql-builder/BaseBuilder.js +0 -6
  110. package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +23 -12
  111. package/libx/_runtime/db/sql-builder/FunctionBuilder.js +18 -6
  112. package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -0
  113. package/libx/_runtime/db/sql-builder/SelectBuilder.js +3 -7
  114. package/libx/_runtime/db/sql-builder/UpsertBuilder.js +1 -0
  115. package/libx/_runtime/db/utils/normalizeTimeData.js +7 -3
  116. package/libx/_runtime/fiori/draft.js +2 -0
  117. package/libx/_runtime/fiori/generic/activate.js +8 -9
  118. package/libx/_runtime/fiori/generic/before.js +30 -20
  119. package/libx/_runtime/fiori/generic/cancel.js +5 -3
  120. package/libx/_runtime/fiori/generic/delete.js +5 -3
  121. package/libx/_runtime/fiori/generic/edit.js +7 -7
  122. package/libx/_runtime/fiori/generic/index.js +10 -16
  123. package/libx/_runtime/fiori/generic/new.js +5 -3
  124. package/libx/_runtime/fiori/generic/patch.js +11 -8
  125. package/libx/_runtime/fiori/generic/prepare.js +13 -6
  126. package/libx/_runtime/fiori/generic/read.js +12 -6
  127. package/libx/_runtime/fiori/lean-draft.js +207 -152
  128. package/libx/_runtime/fiori/utils/delete.js +10 -5
  129. package/libx/_runtime/fiori/utils/req.js +17 -5
  130. package/libx/_runtime/fiori/utils/stream.js +36 -0
  131. package/libx/_runtime/hana/Service.js +12 -9
  132. package/libx/_runtime/hana/conversion.js +10 -15
  133. package/libx/_runtime/hana/driver.js +2 -0
  134. package/libx/_runtime/hana/execute.js +28 -6
  135. package/libx/_runtime/hana/pool.js +36 -122
  136. package/libx/_runtime/hana/search2cqn4sql.js +34 -36
  137. package/libx/_runtime/messaging/enterprise-messaging-utils/getTenantInfo.js +2 -6
  138. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +3 -1
  139. package/libx/_runtime/messaging/enterprise-messaging.js +10 -58
  140. package/libx/_runtime/messaging/outbox/utils.js +1 -1
  141. package/libx/_runtime/remote/Service.js +20 -1
  142. package/libx/_runtime/remote/utils/client.js +3 -5
  143. package/libx/_runtime/sqlite/Service.js +4 -6
  144. package/libx/_runtime/sqlite/conversion.js +3 -13
  145. package/libx/_runtime/sqlite/customBuilder/CustomFunctionBuilder.js +9 -6
  146. package/libx/_runtime/sqlite/customBuilder/CustomUpsertBuilder.js +6 -1
  147. package/libx/_runtime/sqlite/execute.js +5 -16
  148. package/libx/odata/afterburner.js +22 -6
  149. package/libx/odata/grammar.pegjs +6 -1
  150. package/libx/odata/parser.js +1 -1
  151. package/libx/rest/RestAdapter.js +16 -9
  152. package/libx/rest/RestRequest.js +1 -1
  153. package/libx/rest/middleware/input.js +2 -1
  154. package/libx/rest/middleware/operation.js +1 -0
  155. package/libx/rest/middleware/parse.js +3 -2
  156. package/libx/rest/middleware/payload.js +9 -8
  157. package/libx/rest/middleware/read.js +1 -0
  158. package/package.json +9 -16
  159. package/server.js +1 -1
  160. package/app/fiori/preview.js +0 -270
  161. package/app/fiori/routes.js +0 -59
  162. package/bin/build/buildTaskEngine.js +0 -360
  163. package/bin/build/buildTaskFactory.js +0 -283
  164. package/bin/build/buildTaskHandler.js +0 -241
  165. package/bin/build/buildTaskProvider.js +0 -22
  166. package/bin/build/buildTaskProviderFactory.js +0 -175
  167. package/bin/build/cds.js +0 -5
  168. package/bin/build/constants.js +0 -66
  169. package/bin/build/index.js +0 -58
  170. package/bin/build/provider/buildTaskHandlerEdmx.js +0 -82
  171. package/bin/build/provider/buildTaskHandlerFeatureToggles.js +0 -131
  172. package/bin/build/provider/buildTaskHandlerInternal.js +0 -254
  173. package/bin/build/provider/buildTaskProviderInternal.js +0 -383
  174. package/bin/build/provider/fiori/index.js +0 -171
  175. package/bin/build/provider/hana/2migration.js +0 -179
  176. package/bin/build/provider/hana/index.js +0 -505
  177. package/bin/build/provider/hana/migrationtable.js +0 -472
  178. package/bin/build/provider/hana/template/.hdiconfig-haas +0 -163
  179. package/bin/build/provider/hana/template/.hdiconfig-hanacloud +0 -137
  180. package/bin/build/provider/hana/template/.hdinamespace +0 -4
  181. package/bin/build/provider/hana/template/package.json +0 -12
  182. package/bin/build/provider/hana/template/undeploy.json +0 -5
  183. package/bin/build/provider/java/index.js +0 -111
  184. package/bin/build/provider/java-cf/index.js +0 -1
  185. package/bin/build/provider/mtx/index.js +0 -268
  186. package/bin/build/provider/mtx/resourcesTarBuilder.js +0 -95
  187. package/bin/build/provider/mtx-extension/index.js +0 -131
  188. package/bin/build/provider/mtx-sidecar/index.js +0 -137
  189. package/bin/build/provider/node-cf/index.js +0 -1
  190. package/bin/build/provider/nodejs/index.js +0 -192
  191. package/bin/build/util.js +0 -299
  192. package/bin/cds.js +0 -125
  193. package/bin/deploy/to-hana/cfUtil.js +0 -355
  194. package/bin/deploy/to-hana/gitUtil.js +0 -57
  195. package/bin/deploy/to-hana/hana.js +0 -306
  196. package/bin/deploy/to-hana/hdiDeployUtil.js +0 -153
  197. package/bin/deploy/to-hana/index.js +0 -16
  198. package/bin/deploy/to-hana/mtaUtil.js +0 -170
  199. package/bin/mtx/in-cds.js +0 -17
  200. package/bin/plugins.js +0 -32
  201. package/bin/run.js +0 -24
  202. package/bin/utils/log.js +0 -24
  203. package/bin/version.js +0 -178
  204. package/libx/_runtime/audit/Service.js +0 -222
  205. package/libx/_runtime/audit/generic/personal/access.js +0 -61
  206. package/libx/_runtime/audit/generic/personal/index.js +0 -56
  207. package/libx/_runtime/audit/generic/personal/modification.js +0 -132
  208. package/libx/_runtime/audit/generic/personal/utils.js +0 -186
  209. package/libx/_runtime/audit/utils/log.js +0 -23
  210. package/libx/_runtime/audit/utils/v2.js +0 -176
  211. package/libx/_runtime/db/data-conversion/timestamp.js +0 -9
  212. package/libx/_runtime/db/generic/integrity.js +0 -455
  213. package/srv/audit-log.cds +0 -87
  214. package/srv/mtx.cds +0 -2
  215. package/srv/mtx.js +0 -8
  216. /package/lib/{core → linked}/classes.js +0 -0
  217. /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