@cap-js/db-service 1.17.2 → 1.19.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.
@@ -59,7 +59,7 @@ module.exports = async function fill_in_keys(req, next) {
59
59
  // REVISIT dummy handler until we have input processing
60
60
  if (!req.target || !this.model || req.target._unresolved) return next()
61
61
  // only for deep update
62
- if (req.event === 'UPDATE' && hasDeep(req.query, req.target)) {
62
+ if (req.event === 'UPDATE' && hasDeep(req.query)) {
63
63
  // REVISIT for deep update we need to inject the keys first
64
64
  enrichDataWithKeysFromWhere(req.data, req, this)
65
65
  }
@@ -4,7 +4,7 @@ const cds = require('@sap/cds')
4
4
 
5
5
  const JoinTree = require('./join-tree')
6
6
  const { pseudos } = require('./pseudos')
7
- const { isCalculatedOnRead } = require('../utils')
7
+ const { isCalculatedOnRead, getImplicitAlias } = require('../utils')
8
8
  const cdsTypes = cds.linked({
9
9
  definitions: {
10
10
  Timestamp: { type: 'cds.Timestamp' },
@@ -47,21 +47,16 @@ function infer(originalQuery, model) {
47
47
  const sources = inferTarget(_.from || _.into || _.entity, {})
48
48
  const joinTree = new JoinTree(sources)
49
49
  const aliases = Object.keys(sources)
50
+ const target = aliases.length === 1 ? getDefinitionFromSources(sources, aliases[0]) : originalQuery
50
51
  Object.defineProperties(inferred, {
51
52
  // REVISIT: public, or for local reuse, or in cqn4sql only?
52
53
  sources: { value: sources, writable: true },
53
- target: {
54
- value: aliases.length === 1 ? getDefinitionFromSources(sources, aliases[0]) : originalQuery,
55
- writable: true,
56
- }, // REVISIT: legacy?
54
+ _target: { value: target, writable: true, configurable: true }, // REVISIT: legacy?
57
55
  })
58
56
  // also enrich original query -> writable because it may be inferred again
59
57
  Object.defineProperties(originalQuery, {
60
58
  sources: { value: sources, writable: true },
61
- target: {
62
- value: aliases.length === 1 ? getDefinitionFromSources(sources, aliases[0]) : originalQuery,
63
- writable: true,
64
- },
59
+ _target: { value: target, writable: true, configurable: true },
65
60
  })
66
61
  if (originalQuery.SELECT || originalQuery.DELETE || originalQuery.UPDATE) {
67
62
  $combinedElements = inferCombinedElements()
@@ -97,7 +92,7 @@ function infer(originalQuery, model) {
97
92
  * Each key is a query source alias, and its value is the corresponding CSN Definition.
98
93
  * @returns {object} The updated `querySources` object with inferred sources from the `from` clause.
99
94
  */
100
- function inferTarget(from, querySources) {
95
+ function inferTarget(from, querySources, useTechnicalAlias = true) {
101
96
  const { ref } = from
102
97
  if (ref) {
103
98
  const { id, args } = ref[0]
@@ -119,14 +114,14 @@ function infer(originalQuery, model) {
119
114
  from.uniqueSubqueryAlias ||
120
115
  from.as ||
121
116
  (ref.length === 1
122
- ? first.substring(first.lastIndexOf('.') + 1)
123
- : (ref.at(-1).id || ref.at(-1)));
117
+ ? getImplicitAlias(first, useTechnicalAlias)
118
+ : getImplicitAlias(ref.at(-1).id || ref.at(-1), useTechnicalAlias));
124
119
  if (alias in querySources) throw new Error(`Duplicate alias "${alias}"`)
125
120
  querySources[alias] = { definition: target, args }
126
121
  const last = from.$refLinks.at(-1)
127
122
  last.alias = alias
128
123
  } else if (from.args) {
129
- from.args.forEach(a => inferTarget(a, querySources))
124
+ from.args.forEach(a => inferTarget(a, querySources, false))
130
125
  } else if (from.SELECT) {
131
126
  const subqueryInFrom = infer(from, model) // we need the .elements in the sources
132
127
  // if no explicit alias is provided, we make up one
@@ -136,7 +131,7 @@ function infer(originalQuery, model) {
136
131
  } else if (typeof from === 'string') {
137
132
  // TODO: Create unique alias, what about duplicates?
138
133
  const definition = getDefinition(from) || cds.error`"${from}" not found in the definitions of your model`
139
- querySources[from.substring(from.lastIndexOf('.') + 1)] = { definition }
134
+ querySources[getImplicitAlias(from, useTechnicalAlias)] = { definition }
140
135
  } else if (from.SET) {
141
136
  infer(from, model)
142
137
  }
package/lib/utils.js CHANGED
@@ -38,9 +38,34 @@ function isCalculatedElement(def) {
38
38
  return def?.value
39
39
  }
40
40
 
41
+ /**
42
+ * Calculates the implicit table alias for a given string.
43
+ *
44
+ * Based on the last part of the string, the implicit alias is calculated
45
+ * by taking the first character and prepending it with '$'.
46
+ * A leading '$' is removed if the last part already starts with '$'.
47
+ *
48
+ * @example
49
+ * getImplicitAlias('Books') => '$B'
50
+ * getImplicitAlias('bookshop.Books') => '$B'
51
+ * getImplicitAlias('bookshop.$B') => '$B'
52
+ *
53
+ * @param {string} str - The input string.
54
+ * @returns {string}
55
+ */
56
+ function getImplicitAlias(str, useTechnicalAlias = true) {
57
+ const index = str.lastIndexOf('.')
58
+ if(useTechnicalAlias) {
59
+ const postfix = (index != -1 ? str.substring(index + 1) : str).replace(/^\$/, '')[0] || /* str === '$' */ '$'
60
+ return '$' + postfix
61
+ }
62
+ return index != -1 ? str.substring(index + 1) : str
63
+ }
64
+
41
65
  // export the function to be used in other modules
42
66
  module.exports = {
43
67
  prettyPrintRef,
44
68
  isCalculatedOnRead,
45
- isCalculatedElement
69
+ isCalculatedElement,
70
+ getImplicitAlias,
46
71
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cap-js/db-service",
3
- "version": "1.17.2",
3
+ "version": "1.19.0",
4
4
  "description": "CDS base database service",
5
5
  "homepage": "https://github.com/cap-js/cds-dbs/tree/main/db-service#cds-base-database-service",
6
6
  "repository": {
@@ -16,7 +16,6 @@
16
16
  ],
17
17
  "author": "SAP SE (https://www.sap.com)",
18
18
  "main": "index.js",
19
- "types": "./dist/index.d.ts",
20
19
  "files": [
21
20
  "lib",
22
21
  "CHANGELOG.md"