@sap/cds 5.8.2 → 5.9.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 (252) hide show
  1. package/CHANGELOG.md +214 -78
  2. package/app/fiori/preview.js +16 -11
  3. package/app/fiori/routes.js +3 -0
  4. package/app/index.js +1 -1
  5. package/bin/build/buildTaskFactory.js +3 -3
  6. package/bin/build/buildTaskProviderFactory.js +1 -1
  7. package/bin/build/constants.js +1 -1
  8. package/bin/build/provider/buildTaskHandlerEdmx.js +12 -7
  9. package/bin/build/provider/buildTaskHandlerInternal.js +1 -1
  10. package/bin/build/provider/buildTaskProviderInternal.js +8 -2
  11. package/bin/build/provider/hana/2migration.js +27 -24
  12. package/bin/build/provider/hana/index.js +17 -18
  13. package/bin/build/provider/hana/migrationtable.js +9 -10
  14. package/bin/build/provider/java-cf/index.js +4 -5
  15. package/bin/build/provider/node-cf/index.js +99 -6
  16. package/bin/cds.js +20 -17
  17. package/bin/deploy/to-hana/cfUtil.js +16 -19
  18. package/bin/deploy/to-hana/hana.js +7 -24
  19. package/bin/deploy/to-hana/hdiDeployUtil.js +8 -4
  20. package/bin/mtx/in-cds.js +2 -2
  21. package/bin/serve.js +12 -5
  22. package/bin/utils/modules.js +7 -0
  23. package/bin/version.js +56 -3
  24. package/lib/compile/cdsc.js +26 -3
  25. package/lib/compile/etc/_localized.js +36 -25
  26. package/lib/compile/etc/csv.js +8 -8
  27. package/lib/compile/for/drafts.js +9 -0
  28. package/lib/compile/for/java.js +16 -0
  29. package/lib/compile/for/nodejs.js +12 -0
  30. package/lib/compile/for/odata.js +1 -1
  31. package/lib/compile/index.js +3 -0
  32. package/lib/compile/minify.js +16 -2
  33. package/lib/compile/parse.js +2 -2
  34. package/lib/compile/resolve.js +35 -18
  35. package/lib/compile/to/json.js +3 -1
  36. package/lib/compile/to/sql.js +2 -2
  37. package/lib/compile/to/srvinfo.js +4 -2
  38. package/lib/connect/index.js +1 -1
  39. package/lib/core/entities.js +15 -14
  40. package/lib/core/index.js +39 -36
  41. package/lib/core/reflect.js +4 -2
  42. package/lib/deploy.js +114 -127
  43. package/lib/env/defaults.js +1 -0
  44. package/lib/env/index.js +165 -165
  45. package/lib/env/presets.js +1 -0
  46. package/lib/env/requires.js +120 -49
  47. package/lib/index.js +1 -0
  48. package/lib/log/format/kibana.js +2 -2
  49. package/lib/ql/SELECT.js +10 -0
  50. package/lib/ql/parse.js +1 -0
  51. package/lib/req/cds-context.js +4 -1
  52. package/lib/req/context.js +50 -56
  53. package/lib/req/event.js +1 -6
  54. package/lib/req/locale.js +6 -5
  55. package/lib/req/request.js +2 -0
  56. package/lib/req/user.js +7 -5
  57. package/lib/serve/Service-api.js +10 -7
  58. package/lib/serve/Service-dispatch.js +9 -11
  59. package/lib/serve/Service-methods.js +30 -41
  60. package/lib/serve/Transaction.js +10 -7
  61. package/lib/serve/adapters.js +7 -5
  62. package/lib/serve/index.js +24 -12
  63. package/lib/utils/data.js +1 -1
  64. package/lib/utils/index.js +27 -30
  65. package/lib/utils/resources/index.js +101 -0
  66. package/lib/utils/resources/tar.js +71 -0
  67. package/lib/utils/resources/utils.js +11 -0
  68. package/libx/_runtime/audit/Service.js +36 -39
  69. package/libx/_runtime/audit/generic/personal/access.js +3 -4
  70. package/libx/_runtime/audit/generic/personal/modification.js +3 -4
  71. package/libx/_runtime/audit/utils/v2.js +1 -2
  72. package/libx/_runtime/auth/index.js +126 -84
  73. package/libx/_runtime/auth/strategies/JWT.js +12 -19
  74. package/libx/_runtime/auth/strategies/dummy.js +1 -5
  75. package/libx/_runtime/auth/strategies/dwc.js +11 -9
  76. package/libx/_runtime/auth/strategies/mock.js +0 -4
  77. package/libx/_runtime/auth/strategies/{utils/xssec.js → xssecUtils.js} +7 -4
  78. package/libx/_runtime/auth/strategies/xsuaa.js +12 -19
  79. package/libx/_runtime/auth/utils.js +22 -1
  80. package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +104 -98
  81. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +2 -2
  82. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +1 -1
  83. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +13 -0
  84. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/language.js +2 -8
  85. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -29
  86. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +2 -1
  87. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +3 -2
  88. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +2 -2
  89. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +4 -6
  90. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +24 -21
  91. package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +8 -2
  92. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +1 -1
  93. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/DeserializerFactory.js +2 -0
  94. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/ResourceJsonDeserializer.js +5 -6
  95. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DispatcherCommand.js +2 -6
  96. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/utils/UriHelper.js +4 -1
  97. package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -12
  98. package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +33 -9
  99. package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +50 -0
  100. package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +2 -2
  101. package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +10 -3
  102. package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +9 -11
  103. package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +6 -3
  104. package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +4 -2
  105. package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +1 -1
  106. package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +1 -1
  107. package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +2 -3
  108. package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +6 -4
  109. package/libx/_runtime/cds-services/adapter/rest/utils/result.js +1 -0
  110. package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +8 -5
  111. package/libx/_runtime/cds-services/services/Service.js +40 -0
  112. package/libx/_runtime/cds-services/services/utils/columns.js +4 -3
  113. package/libx/_runtime/cds-services/services/utils/compareJson.js +4 -4
  114. package/libx/_runtime/cds-services/services/utils/differ.js +3 -3
  115. package/libx/_runtime/cds-services/services/utils/handlerUtils.js +4 -4
  116. package/libx/_runtime/cds-services/services/utils/restrictions.js +78 -0
  117. package/libx/_runtime/cds-services/util/assert.js +20 -14
  118. package/libx/_runtime/cds.js +9 -1
  119. package/libx/_runtime/common/aspects/any.js +5 -0
  120. package/libx/_runtime/common/aspects/entity.js +25 -7
  121. package/libx/_runtime/common/aspects/utils.js +2 -2
  122. package/libx/_runtime/common/composition/data.js +6 -0
  123. package/libx/_runtime/common/composition/insert.js +3 -2
  124. package/libx/_runtime/common/composition/tree.js +4 -10
  125. package/libx/_runtime/common/composition/update.js +4 -4
  126. package/libx/_runtime/common/constants/draft.js +29 -26
  127. package/libx/_runtime/common/error/constants.js +2 -2
  128. package/libx/_runtime/common/error/frontend.js +7 -15
  129. package/libx/_runtime/common/generic/auth/capabilities.js +59 -0
  130. package/libx/_runtime/common/generic/auth/constants.js +20 -0
  131. package/libx/_runtime/common/generic/auth/expand.js +54 -0
  132. package/libx/_runtime/common/generic/auth/index.js +32 -0
  133. package/libx/_runtime/common/generic/auth/insertOnly.js +15 -0
  134. package/libx/_runtime/common/generic/auth/readOnly.js +26 -0
  135. package/libx/_runtime/common/generic/auth/requires.js +34 -0
  136. package/libx/_runtime/common/generic/auth/restrict.js +296 -0
  137. package/libx/_runtime/common/generic/auth/utils.js +213 -0
  138. package/libx/_runtime/common/generic/crud.js +14 -10
  139. package/libx/_runtime/common/generic/etag.js +1 -1
  140. package/libx/_runtime/common/generic/input.js +35 -35
  141. package/libx/_runtime/common/generic/sorting.js +2 -3
  142. package/libx/_runtime/common/generic/temporal.js +2 -2
  143. package/libx/_runtime/common/i18n/index.js +2 -31
  144. package/libx/_runtime/common/i18n/messages.properties +1 -1
  145. package/libx/_runtime/common/toggles/handler.js +21 -0
  146. package/libx/_runtime/common/utils/copy.js +10 -1
  147. package/libx/_runtime/common/utils/cqn2cqn4sql.js +100 -29
  148. package/libx/_runtime/common/utils/csn.js +63 -1
  149. package/libx/_runtime/common/utils/dollar.js +10 -1
  150. package/libx/_runtime/common/utils/draft.js +46 -7
  151. package/libx/_runtime/common/utils/entityFromCqn.js +13 -9
  152. package/libx/_runtime/common/utils/extensibilityUtils.js +18 -0
  153. package/libx/_runtime/common/utils/foreignKeyPropagations.js +88 -104
  154. package/libx/_runtime/common/utils/generateOnCond.js +9 -6
  155. package/libx/_runtime/common/utils/quotingStyles.js +2 -0
  156. package/libx/_runtime/common/utils/resolveStructured.js +25 -9
  157. package/libx/_runtime/common/utils/resolveView.js +4 -1
  158. package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -16
  159. package/libx/_runtime/common/utils/structured.js +33 -37
  160. package/libx/_runtime/common/utils/template.js +17 -8
  161. package/libx/_runtime/common/utils/templateProcessor.js +28 -28
  162. package/libx/_runtime/db/data-conversion/post-processing.js +118 -417
  163. package/libx/_runtime/db/expand/expandCQNToJoin.js +45 -41
  164. package/libx/_runtime/db/expand/rawToExpanded.js +29 -8
  165. package/libx/_runtime/db/generic/index.js +1 -3
  166. package/libx/_runtime/db/generic/input.js +5 -10
  167. package/libx/_runtime/db/generic/rewrite.js +5 -2
  168. package/libx/_runtime/db/generic/structured.js +2 -2
  169. package/libx/_runtime/db/query/delete.js +2 -2
  170. package/libx/_runtime/db/query/insert.js +1 -1
  171. package/libx/_runtime/db/query/update.js +9 -14
  172. package/libx/_runtime/db/sql-builder/CreateBuilder.js +4 -3
  173. package/libx/_runtime/db/sql-builder/InsertBuilder.js +14 -1
  174. package/libx/_runtime/db/sql-builder/SelectBuilder.js +3 -2
  175. package/libx/_runtime/db/sql-builder/dataTypes.js +3 -3
  176. package/libx/_runtime/db/utils/columns.js +3 -3
  177. package/libx/_runtime/db/utils/normalizeTimeData.js +2 -2
  178. package/libx/_runtime/db/utils/propagateForeignKeys.js +6 -2
  179. package/libx/_runtime/extensibility/mps/index.js +5 -0
  180. package/libx/_runtime/extensibility/mps/service.js +111 -0
  181. package/libx/_runtime/extensibility/mps/tar.js +42 -0
  182. package/libx/_runtime/extensibility/mps/utils.js +11 -0
  183. package/libx/_runtime/{fiori → extensibility}/uiflex/handler/transformREAD.js +0 -0
  184. package/libx/_runtime/{fiori → extensibility}/uiflex/handler/transformRESULT.js +17 -5
  185. package/libx/_runtime/{fiori → extensibility}/uiflex/handler/transformWRITE.js +1 -0
  186. package/libx/_runtime/extensibility/uiflex/index.js +54 -0
  187. package/libx/_runtime/extensibility/uiflex/service.js +276 -0
  188. package/libx/_runtime/{fiori → extensibility}/uiflex/utils.js +22 -7
  189. package/libx/_runtime/fiori/generic/activate.js +2 -2
  190. package/libx/_runtime/fiori/generic/before.js +4 -4
  191. package/libx/_runtime/fiori/generic/new.js +3 -3
  192. package/libx/_runtime/fiori/generic/patch.js +1 -1
  193. package/libx/_runtime/fiori/generic/read.js +58 -66
  194. package/libx/_runtime/fiori/generic/readOverDraft.js +71 -16
  195. package/libx/_runtime/fiori/utils/handler.js +6 -13
  196. package/libx/_runtime/fiori/utils/where.js +6 -5
  197. package/libx/_runtime/hana/Service.js +4 -10
  198. package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +2 -2
  199. package/libx/_runtime/hana/driver.js +2 -2
  200. package/libx/_runtime/hana/execute.js +29 -75
  201. package/libx/_runtime/hana/pool.js +1 -1
  202. package/libx/_runtime/hana/streaming.js +2 -1
  203. package/libx/_runtime/index.js +6 -6
  204. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +5 -21
  205. package/libx/_runtime/messaging/Outbox.js +2 -2
  206. package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -14
  207. package/libx/_runtime/messaging/common-utils/connections.js +5 -7
  208. package/libx/_runtime/messaging/common-utils/normalizeIncomingMessage.js +30 -0
  209. package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -1
  210. package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +36 -30
  211. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +19 -12
  212. package/libx/_runtime/messaging/enterprise-messaging.js +8 -8
  213. package/libx/_runtime/messaging/file-based.js +5 -5
  214. package/libx/_runtime/messaging/message-queuing.js +14 -12
  215. package/libx/_runtime/messaging/outbox/utils.js +18 -19
  216. package/libx/_runtime/messaging/redis-messaging.js +91 -0
  217. package/libx/_runtime/messaging/service.js +8 -6
  218. package/libx/_runtime/remote/Service.js +44 -8
  219. package/libx/_runtime/remote/utils/client.js +25 -13
  220. package/libx/_runtime/remote/utils/data.js +11 -11
  221. package/libx/_runtime/sqlite/Service.js +6 -9
  222. package/libx/_runtime/sqlite/customBuilder/CustomFunctionBuilder.js +5 -2
  223. package/libx/_runtime/types/api.js +10 -2
  224. package/libx/common/utils/ucsn.js +109 -0
  225. package/libx/gql/resolvers/crud/create.js +6 -1
  226. package/libx/gql/resolvers/crud/delete.js +6 -1
  227. package/libx/gql/resolvers/crud/read.js +6 -1
  228. package/libx/gql/resolvers/crud/update.js +9 -1
  229. package/libx/gql/resolvers/parse/ast2cqn/columns.js +3 -1
  230. package/libx/gql/schema/typeDefMap.js +2 -2
  231. package/libx/odata/afterburner.js +110 -16
  232. package/libx/odata/grammar.pegjs +9 -1
  233. package/libx/odata/parseToCqn.js +39 -0
  234. package/libx/odata/parser.js +1 -1
  235. package/libx/rest/RestAdapter.js +9 -1
  236. package/libx/rest/middleware/input.js +54 -0
  237. package/libx/rest/middleware/operation.js +14 -1
  238. package/libx/rest/middleware/parse.js +11 -7
  239. package/package.json +1 -1
  240. package/server.js +34 -19
  241. package/srv/audit-log.cds +2 -2
  242. package/srv/flex.cds +8 -2
  243. package/srv/flex.js +1 -1
  244. package/srv/mps.cds +23 -0
  245. package/srv/mps.js +1 -0
  246. package/libx/_runtime/auth/strategies/utils/uaa.js +0 -21
  247. package/libx/_runtime/common/generic/auth.js +0 -874
  248. package/libx/_runtime/common/toggles/alpha.js +0 -43
  249. package/libx/_runtime/db/generic/arrayed.js +0 -33
  250. package/libx/_runtime/fiori/uiflex/index.js +0 -35
  251. package/libx/_runtime/fiori/uiflex/service.js +0 -150
  252. package/libx/rest/utils/data.js +0 -60
@@ -9,6 +9,9 @@ const {lazified} = require ('../lazy'); require = lazified (module) // eslint-d
9
9
  const compile = module.exports = Object.assign (cds_compile, {
10
10
 
11
11
  for: lazified ({
12
+ java: require('./for/java'),
13
+ nodejs: require('./for/nodejs'),
14
+ drafts: require('./for/drafts'),
12
15
  odata: require('./for/odata'),
13
16
  sql: require('./for/sql'),
14
17
  }),
@@ -32,11 +32,11 @@ module.exports = function cds_minify (csn, _roots = global.cds.env.features.skip
32
32
  }
33
33
  function _visit (d) {
34
34
  if (typeof d === 'string') {
35
- if (d.startsWith('cds.')) return
35
+ if (isInReservedNamespace(d)) return
36
36
  else d = all[d]
37
37
  } else if (d.ref) return d.ref.reduce((p,n) => {
38
38
  let d = (p.elements || csn.definitions[p.target].elements)[n.id || n] // > n.id -> view with parameters
39
- _visit(d)
39
+ if (d) _visit(d)
40
40
  return d
41
41
  },{elements:all})
42
42
  if (reached.has(d)) return; else reached.add(d)
@@ -58,4 +58,18 @@ module.exports = function cds_minify (csn, _roots = global.cds.env.features.skip
58
58
  return minified
59
59
  }
60
60
 
61
+ /**
62
+ * TODO - keep in sync with @sap/cds-compiler. Use their public API once it is available!
63
+ * Checks whether the given absolute path is inside a reserved namespace.
64
+ *
65
+ * @param {string} absolute
66
+ * @returns {boolean}
67
+ */
68
+ function isInReservedNamespace(absolute) {
69
+ return absolute.startsWith( 'cds.') &&
70
+ !absolute.match(/^cds\.foundation(\.|$)/) &&
71
+ !absolute.match(/^cds\.outbox(\.|$)/) && // Requested by Node runtime
72
+ !absolute.match(/^cds\.xt(\.|$)/); // Requested by Mtx
73
+ }
74
+
61
75
  const _minified = Symbol('minified')
@@ -10,7 +10,7 @@ const parse = module.exports = Object.assign (cds_parse, {
10
10
  CXL: (...args) => tagged(parse.expr, ...args),
11
11
 
12
12
  cdl: cds_parse,
13
- cql: x => { try { return cdsc.parse.cql(x,undefined,{messages:[]}) } catch(e) {
13
+ cql: (x,o) => { try { return cdsc.parse.cql(x,undefined,{ messages:[], ...o }) } catch(e) {
14
14
  e.message = e.message.replace('<query>.cds:',`In '${e.cql = x}' at `)
15
15
  throw e // with improved error message
16
16
  }},
@@ -76,4 +76,4 @@ const merge = (o,values) => {
76
76
  }
77
77
 
78
78
  const cxn4 = x => x.SELECT || x.ref || x.xpr || x.val !== undefined|| x.list || x.func ? x : {val:x}
79
- const keywords = { KEY:1, key:1, SELECT:1, select:1 }
79
+ const keywords = { KEY:1, key:1, SELECT:1, select:1 }
@@ -2,6 +2,7 @@ const { resolve, join, sep } = require('path')
2
2
  const { readdirSync } = require('fs')
3
3
  const suffixes = [ '.csn', '.cds', sep+'index.csn', sep+'index.cds', sep+'csn.json' ]
4
4
 
5
+
5
6
  /**
6
7
  * Resolves given model references to an array of absolute filenames.
7
8
  * For the model references, all these are accepted:
@@ -16,18 +17,20 @@ module.exports = exports = function cds_resolve (model, o={}) { // NOSONAR
16
17
 
17
18
  if (!model || model === '--') return
18
19
  if (model._resolved) return model
19
- if (model === '*') return exports.cache['*'] || _resolve_all(this,o)
20
- if (Array.isArray(model)) return _resolved (
21
- [... new Set(model)] .reduce ((prev,next) => prev.concat (this.resolve(next,o)||[]), [])
22
- )
20
+ if (model === '*') return _resolve_all(o,this)
21
+ if (Array.isArray(model)) {
22
+ const resolved = [... new Set(model)] .reduce ((prev,next) => prev.concat (this.resolve(next,o)||[]), [])
23
+ return o.dry || o === false ? resolved : _resolved (resolved)
24
+ }
25
+ if (model.endsWith('/*')) return _resolve_subdirs_in(model,o,this)
23
26
 
24
- const cwd = o.root || global.cds && global.cds.root, local = resolve (cwd,model)
27
+ const cwd = o.root || this.root, local = resolve (cwd,model)
25
28
  const context = _paths(cwd), {cached} = context
26
29
  let id = model.startsWith('.') ? local : model
27
- if (id in cached && !o.skipModelCache) return cached[id]
30
+ if (id in cached) return cached[id]
28
31
 
29
32
  // expand @sap/cds by cds.home
30
- if (id.startsWith('@sap/cds/')) id = global.cds.home + id.slice(8)
33
+ if (id.startsWith('@sap/cds/')) id = this.home + id.slice(8)
31
34
 
32
35
  // fetch file with .cds/.csn suffix as is
33
36
  if (/\.(csn|cds)$/.test(id)) try {
@@ -58,27 +61,41 @@ module.exports = exports = function cds_resolve (model, o={}) { // NOSONAR
58
61
 
59
62
  }
60
63
 
64
+
61
65
  exports.cache = {}
62
66
 
63
67
 
68
+ const _required = cds => Object.values(cds.env.requires) .map (r => r.model) .filter(x=>x)
64
69
  const _resolve = require('module')._resolveFilename
65
70
 
66
- function _resolve_all (cds,o) {
67
- const {roots,requires} = cds.env, {cache} = exports
68
- const required = Object.values(requires) .map (r => r.model) .filter(x=>x)
69
- if (o.dry || o === false) return [ ...roots, ...required ]
70
- cache['*'] = [] // important to avoid endless recursion on '*'
71
- const resolved = cds.resolve (roots,o) || []
72
- if (!(resolved.length === 1 && resolved[0].endsWith('csn.json')))
73
- resolved.push (...cds.resolve (required,o)||[])
74
- return cache['*'] = _resolved ([ ...new Set (resolved) ])
71
+ function _resolve_all (o,cds) {
72
+ const {roots} = cds.env; if (o.dry || o === false) return [ ...roots, ..._required(cds) ]
73
+ const cached = exports.cache['*']; if (cached) return cached
74
+ exports.cache['*'] = [] // important to avoid endless recursion on '*'
75
+ const sources = cds.resolve (roots,o) || []
76
+ if (!(sources.length === 1 && sources[0].endsWith('csn.json'))) // REVISIT: why is that? -> pre-compiled gen/csn.json?
77
+ sources.push (...cds.resolve (_required(cds),o)||[])
78
+ return exports.cache['*'] = _resolved (sources)
79
+ }
80
+
81
+ function _resolve_subdirs_in (pattern='fts/*',o,cds) {
82
+ const cached = exports.cache[pattern]; if (cached && !o.dry && o !== false) return cached
83
+ const folder = pattern.slice(0,-2), dir = resolve (cds.root, folder)
84
+ try {
85
+ const dirs = readdirSync(dir) .map (e => folder+'/'+e+'/') .filter (cds.utils.isdir)
86
+ if (o.dry || o === false) return dirs
87
+ return exports.cache[pattern] = cds.resolve (dirs,o) || undefined
88
+ } catch(e) {
89
+ if (e.code === 'ENOENT')
90
+ return exports.cache[pattern] = undefined
91
+ }
75
92
  }
76
93
 
77
94
  function _paths (dir) {
78
- const {cache} = exports; if (dir in cache) return cache[dir]
95
+ const cached = exports.cache[dir]; if (cached) return cached
79
96
  const a = dir.split(sep), n = a.length, nm = sep+'node_modules'
80
97
  const paths = [ dir, ...a.map ((_,i,a)=> a.slice(0,n-i).join(sep)+nm) ]
81
- return cache[dir] = { paths, cached:{} }
98
+ return exports.cache[dir] = { paths, cached:{} }
82
99
  }
83
100
 
84
101
  function _resolved (array) {
@@ -8,12 +8,14 @@ module.exports = (csn,o={}) => JSON.stringify (csn, (_,v) => {
8
8
 
9
9
  else if (v.grant && v.where) try {
10
10
  // Add a parsed _where clause for @restrict.{grant,where} annotations
11
+ // Note: This has moved to cds.compile.for.java meanwhile, but is kept
12
+ // here for compatibility, at least temporarily.
11
13
  return {...v, _where: JSON.stringify (cds.parse.xpr(v.where)) }
12
14
  } catch(e){/* ignored */}
13
15
 
14
16
  else if (v.kind === "service" && !v['@source'] && v.$location && v.$location.file) {
15
17
  // Preserve original sources for services so we can use them for finding
16
- // sibling implementation filed when reloaded from csn.json.
18
+ // sibling implementation files when reloaded from csn.json.
17
19
  const file = (o.cwd !== o.src) ? path.relative(o.src, path.join(o.cwd, v.$location.file)) : v.$location.file
18
20
  return { '@source': file.replace(/\\/g,'/'), ...v }
19
21
  }
@@ -1,4 +1,4 @@
1
- const cds = require ('../..'), { unfold_ddl: cds_localized } = cds.compile._localized
1
+ const cds = require ('../..')
2
2
  const cdsc = require ('../cdsc')
3
3
 
4
4
 
@@ -6,7 +6,7 @@ function cds_compile_to_sql (csn,_o) {
6
6
  csn = _extended(cds.minify(csn))
7
7
  const o = cdsc._options.for.sql(_o) //> used twice below...
8
8
  const all = cdsc.to.sql(csn,o) .map (each => each.replace(/^-- .+\n/,'')) //> strip comments
9
- const sql = cds_localized(all, csn, o)
9
+ const sql = cds.compile._localized.unfold_ddl(all, csn, o)
10
10
  if (o.as === 'str') return `\n${sql.join('\n\n')}\n`
11
11
  return sql
12
12
  }
@@ -74,8 +74,10 @@ module.exports = (model, options={}) => {
74
74
  if (file) {
75
75
  const yaml = cds.load.yaml(file)
76
76
  for (let {cds} of Array.isArray(yaml) ? yaml : [yaml]) {
77
- if (cds && cds['odata-v4.endpoint.path']) return cds['odata-v4.endpoint.path']
78
- if (cds && cds['odata-v2.endpoint.path']) return cds['odata-v2.endpoint.path']
77
+ if (!cds) continue
78
+ return cds['odataV4.endpoint.path'] || cds['odataV2.endpoint.path'] // https://cap.cloud.sap/docs/java/application-services#configure-base-path
79
+ || cds['odata-v4.endpoint.path'] || cds['odata-v2.endpoint.path'] // older/intermediate config, keep for backward compatibility
80
+
79
81
  }
80
82
  return 'odata/v4/'
81
83
  }
@@ -38,7 +38,7 @@ connect.to = async (datasource, options) => {
38
38
  // check if required service definition exists
39
39
  const required = cds.requires[datasource]
40
40
  if (required && required.model && datasource !== 'db' && !m.definitions[required.service||datasource]) {
41
- LOG._error && LOG.error(`No service definition found for '${required.service || datasource}', as required by 'cds.requires.${datasource}':`, required)
41
+ LOG.error(`No service definition found for '${required.service || datasource}', as required by 'cds.requires.${datasource}':`, required)
42
42
  throw new Error (`No service definition found for '${required.service || datasource}'`)
43
43
  }
44
44
  // construct new service instance
@@ -34,23 +34,24 @@ class Association extends type {
34
34
  return !c || c.max === 1 || (!c.max && !c.targetMax) || c.targetMax === 1
35
35
  }
36
36
 
37
- set _elements(k) { this.set('_elements', k) }
38
- get _elements() {
39
- const { keys } = this
40
- if (!keys) return (this._elements = undefined)
41
- const fks = {},{ elements } = this._target
42
- for (let k of keys) fks[k.as || k.ref[0]] = elements[k.ref[0]]
43
- return (this._elements = fks)
37
+ set foreignKeys(k) { this.set('foreignKeys', k) }
38
+ get foreignKeys() {
39
+ const keys = this.keys; if (!keys) return this.foreignKeys = undefined
40
+ const foreignKeys = {}
41
+ for (const k of keys) {
42
+ const el = k.ref.reduce((target,n)=> target.elements[n], this._target)
43
+ const as = k.as || k.ref[k.ref.length-1]
44
+ foreignKeys [as] = el
45
+ }
46
+ return this.foreignKeys = foreignKeys
44
47
  }
45
48
 
46
- set _keys(k) { this.set('keys', k) }
47
- get _keys() {
48
- if (this.keys) return (this._keys = this.keys)
49
- if (this.on || this.is2many || !this._target) return (this._keys = undefined)
50
- const keys = [],
51
- tks = this._target.keys
49
+ set keys(k) { super.keys = k }
50
+ get keys() {
51
+ if (this.on || this.is2many || !this._target) return this._keys = undefined
52
+ const keys=[], tks = this._target.keys
52
53
  for (let k in tks) keys.push({ ref: [tks[k].name] })
53
- return (this._keys = keys)
54
+ return this.keys = keys
54
55
  }
55
56
  }
56
57
 
package/lib/core/index.js CHANGED
@@ -8,8 +8,9 @@ const classes = Object.assign (
8
8
  require('./entities'),
9
9
  )
10
10
 
11
- // Type system roots -> can be used with instanceof
12
- const roots = _bootstrap ({
11
+
12
+ /** Type system roots -> can be used with instanceof */
13
+ const roots = _roots ({
13
14
  context: {},
14
15
  type: {},
15
16
  scalar: {type:'type'},
@@ -27,9 +28,28 @@ const roots = _bootstrap ({
27
28
  service: {type:'context'},
28
29
  })
29
30
 
30
- // Adding common recommended types
31
- const common = { __proto__:roots,
32
- UUID: {type:'string',length:36},
31
+ /**
32
+ * Turns the given CSN definitions into linked definitions with classes.
33
+ * @type <T>(csn:T) => T
34
+ */
35
+ function _roots (defs) {
36
+ const linked = { any: classes.any.prototype }
37
+ for (const t in defs) {
38
+ if (t in classes) {
39
+ linked[t] = classes[t].prototype
40
+ continue
41
+ }
42
+ const c = class extends classes[defs[t].type || 'any'] {}
43
+ linked[t] = Object.defineProperty (c.prototype, 'name', {value:t})
44
+ classes[t] = Object.defineProperty (c, 'name', {value:t})
45
+ }
46
+ return linked
47
+ }
48
+
49
+
50
+ /** Construct builtin.types as dictionary of all roots and common types */
51
+ const types = _common ({ __proto__: roots,
52
+ UUID: {type:'string',length:36,isUUID:true},
33
53
  Boolean: {type:'boolean'},
34
54
  Integer: {type:'number'},
35
55
  Integer16: {type:'Integer'},
@@ -47,41 +67,24 @@ const common = { __proto__:roots,
47
67
  Binary: {type:'string'},
48
68
  LargeString: {type:'string'},
49
69
  LargeBinary: {type:'string'},
50
- }
70
+ })
51
71
 
52
72
  /**
53
- * Construct builtin.types as dictionary of all roots and common types
54
- * @type { typeof roots & typeof common }
73
+ * Link all definitions, essentially by: d.__proto__ = resolved (d.type),
74
+ * and prefixes all common types with a namespace 'cds'.
75
+ * @type <T>(csn:T) => T & roots
55
76
  */
56
- const types = { __proto__:common }
57
-
58
- // Link all definitions, essentially by: d.__proto__ = resolved (d.type)
59
- for (let [name,d] of Object.entries(common)) {
60
- common[name] = Object.defineProperty({ ...d, __proto__: types[d.type] }, 'name', {value:name})
77
+ function _common (defs) {
78
+ const prefixed = {__proto__:defs}
79
+ for (let [name,d] of Object.entries(defs)) {
80
+ defs[name] = Object.defineProperty({ ...d, __proto__: defs[d.type] }, 'name', {value:name})
81
+ Object.defineProperty (prefixed['cds.'+name] = defs[name], '_type', {value:'cds.'+name})
82
+ }
83
+ for (let name of ['Association','Composition']) {
84
+ Object.defineProperty (prefixed['cds.'+name] = defs[name], '_type', {value:'cds.'+name})
85
+ }
86
+ return prefixed
61
87
  }
62
88
 
63
- // Prefix all common types with a namespace 'cds'
64
- for (let t of Object.keys(common)) types['cds.'+t] = types[t]
65
- types['cds.Association'] = types.Association
66
- types['cds.Composition'] = types.Composition
67
89
 
68
90
  module.exports = { types, classes }
69
-
70
-
71
- /**
72
- * Turns the given CSN definitions into linked definitions.
73
- * @type <T>(csn:T) => T
74
- */
75
- function _bootstrap (csn) {
76
- const defs = { any: classes.any.prototype }
77
- for (const t in csn) {
78
- if (t in classes) {
79
- defs[t] = classes[t].prototype
80
- continue
81
- }
82
- const c = class extends classes[csn[t].type || 'any'] {}
83
- defs[t] = Object.defineProperty(c.prototype, 'name', { value: t })
84
- classes[t] = Object.defineProperty(c, 'name', { value: t })
85
- }
86
- return defs
87
- }
@@ -95,7 +95,7 @@ class LinkedCSN extends any {
95
95
  }
96
96
 
97
97
 
98
- const _unresolved = (x,unknown=any) => ({name:x, __proto__:unknown.prototype, _unresolved:true})
98
+ const _unresolved = (x,unknown=any) => ({ name:x, __proto__:unknown.prototype, _unresolved:true })
99
99
  const _builtin = x => types[x] || typeof x === 'string' && x.startsWith('cds.hana.') && any.prototype
100
100
  const _infer = require('./infer'), _not_inferred = _unresolved('<query>',entity)
101
101
  const _set = (o,p,v) => Object.defineProperty (o,p,{value:v,enumerable:false,configurable:1,writable:1})
@@ -107,4 +107,6 @@ const _is = x => {
107
107
  }
108
108
 
109
109
  /** @returns {LinkedCSN} */
110
- module.exports = x => x instanceof any ? x : new LinkedCSN(x)
110
+ module.exports = x => x instanceof any ? x : new LinkedCSN (
111
+ typeof x === 'string' ? global.cds.parse(x) : x
112
+ )