@sap/cds 6.3.1 → 6.3.2

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.
package/CHANGELOG.md CHANGED
@@ -4,9 +4,20 @@
4
4
  - The format is based on [Keep a Changelog](http://keepachangelog.com/).
5
5
  - This project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## Version 6.3.2 - 2022-11-21
8
+
9
+ ### Fixed
10
+
11
+ - `cds deploy` reports errors correctly
12
+ - Reference resolution in QL API
13
+ - `cds.parse.path` to correctly handle special characters
14
+ - `cds build` issues on Windows: build with large number of files and build on Git Bash.
15
+ - `odata` as default protocol for enabled middlewares feature
16
+
7
17
  ## Version 6.3.1 - 2022-11-04
8
18
 
9
19
  ### Fixed
20
+
10
21
  - `cds build` no longer reports false positive validation errors for built-in MTX models like `@sap/cds/srv/mtx` or `@sap/cds-mtxs/srv/bootstrap`
11
22
  - `cds deploy` handles empty result from `cf` call correctly
12
23
  - `$search` fails on columns composed by a CQL expression that uses the SAP HANA `coalesce` predicate
@@ -88,9 +88,10 @@ class CfUtil {
88
88
  }
89
89
 
90
90
  if (response.errors) {
91
- const errorMessage = result.errors.map((entry) => `${entry.title}: ${entry.detail} (${entry.code})`).join('\n');
91
+ const errorMessage = response.errors.map((entry) => `${entry.title || ''}: ${entry.detail || ''} (${entry.code || ''})`).join('\n');
92
92
  throw new Error(errorMessage);
93
93
  }
94
+
94
95
  return response;
95
96
  }
96
97
 
@@ -16,7 +16,8 @@ const parse = module.exports = Object.assign (cds_parse, {
16
16
  }},
17
17
  path: (x,...values) => {
18
18
  if (x && x.raw) return tagged (parse.path,x,...values)
19
- if (/^[A-Za-z_$][A-Za-z_0-9.$]*$/.test(x)) return {ref:[x]}
19
+ if (/^[A-Za-z_0-9.$]*$/.test(x)) return {ref:[x]}
20
+ if ((cds.context?.model || cds.model)?.definitions[x]) return {ref:[x]}
20
21
  let {SELECT} = parse.cql('SELECT from '+x)
21
22
  return SELECT.from
22
23
  },
@@ -10,7 +10,9 @@ class ProtocolAdapter {
10
10
  for (let [k,o] of Object.entries(protocols)) if (typeof o === 'string') protocols[k] = {path:o}
11
11
  if (!protocols.odata) protocols.odata = { impl: join(__dirname,'odata-v4') }
12
12
  if (!protocols.rest) protocols.rest = { impl: join(__dirname,'rest') }
13
- return this.protocols = protocols
13
+
14
+ // odata must always be first for fallback
15
+ return this.protocols = { odata: protocols.odata, ...protocols }
14
16
  }
15
17
 
16
18
  /**
package/lib/utils/tar.js CHANGED
@@ -5,7 +5,7 @@ const spawn = /\btar\b/.test(process.env.DEBUG) ? (cmd, args, options) => {
5
5
  return child_process.spawn(cmd, args, options)
6
6
  } : child_process.spawn
7
7
 
8
- const cds = require('../index'), { fs, path, mkdirp } = cds.utils
8
+ const cds = require('../index'), { fs, path, mkdirp, exists, rimraf } = cds.utils
9
9
  const _resolve = (...x) => path.resolve (cds.root,...x)
10
10
 
11
11
  // tar does not work properly on Windows (by npm/jest tests) w/o this change
@@ -15,6 +15,21 @@ const win = path => {
15
15
  if (Array.isArray(path)) return path.map(el => win(el))
16
16
  }
17
17
 
18
+ // Copy files to temp dir on Windows and pack temp dir.
19
+ // cli tar has a size limit on Windows.
20
+ const createTemp = async (root, files) => {
21
+ const temp = await fs.promises.mkdtemp(`${fs.realpathSync(require('os').tmpdir())}${path.sep}tar-`)
22
+ for (const file of files) {
23
+ const fname = path.relative(root, file)
24
+ const destination = path.join(temp, fname)
25
+ const dirname = path.dirname(destination)
26
+ if (!await exists(dirname)) await fs.promises.mkdir(dirname, { recursive: true })
27
+ await fs.promises.copyFile(file, destination)
28
+ }
29
+
30
+ return temp
31
+ }
32
+
18
33
  /**
19
34
  * Creates a tar archive, to an in-memory Buffer, or piped to write stream or file.
20
35
  * @example ```js
@@ -39,15 +54,31 @@ const win = path => {
39
54
  * - `.then()` collects the tar output into an in-memory `Buffer`
40
55
  * - `.to()` is a convenient shortcut to pipe the output into a write stream
41
56
  */
42
- exports.create = (dir='.', ...args) => {
57
+ exports.create = async (dir='.', ...args) => {
43
58
 
44
59
  if (typeof dir === 'string') dir = _resolve(dir)
45
60
  if (Array.isArray(dir)) [ dir, ...args ] = [ cds.root, dir, ...args ]
46
- if (Array.isArray(args[0])) args.push (...args.shift().map (f => path.isAbsolute(f) ? path.relative(dir,f) : f))
47
- else args.push('.')
48
- const c = process.platform === 'linux'
49
- ? spawn (`tar c -C ${dir}`, args, { shell:true })
50
- : spawn (`tar cf - -C ${win(dir)}`, args, { shell:true })
61
+
62
+ let c, temp
63
+ if (process.platform === 'win32') {
64
+ const spawnDir = (dir, args) => {
65
+ if (args.some(arg => arg === '-f')) return spawn ('tar', ['c', '-C', win(dir), ...win(args)])
66
+ else return spawn ('tar', ['cf', '-', '-C', win(dir), ...win(args)])
67
+ }
68
+ args.push('.')
69
+ if (Array.isArray(args[0])) {
70
+ temp = await createTemp(dir, args[0])
71
+ args.shift()
72
+ c = spawnDir(temp, args)
73
+ } else {
74
+ c = spawnDir(dir, args)
75
+ }
76
+ } else {
77
+ if (Array.isArray(args[0])) args.push (...args.shift().map (f => path.isAbsolute(f) ? path.relative(dir,f) : f))
78
+ else args.push('.')
79
+
80
+ c = spawn ('tar', ['c', '-C', dir, ...args])
81
+ }
51
82
 
52
83
  return {__proto__:c, // returning a thenable + fluent ChildProcess...
53
84
 
@@ -60,6 +91,10 @@ exports.create = (dir='.', ...args) => {
60
91
  const bb=[]; c.stdout.on('data', b => bb.push(b))
61
92
  c.on('close', ()=>r(Buffer.concat(bb)))
62
93
  c.on('error', e)
94
+ if (process.platform === 'win32') {
95
+ c.on('close', async () => temp && exists(temp) && await rimraf(temp))
96
+ c.on('error', async () => temp && exists(temp) && await rimraf(temp))
97
+ }
63
98
  },
64
99
 
65
100
  /**
@@ -107,7 +142,7 @@ exports.extract = (archive, ...args) => ({
107
142
  to (...dest) {
108
143
  if (typeof dest === 'string') dest = _resolve(...dest)
109
144
  const input = typeof archive !== 'string' || archive == '-' ? '-' : _resolve(archive)
110
- const x = spawn(`tar xf ${win(input)} -C ${win(dest)}`, args, { shell:true })
145
+ const x = spawn('tar', ['xf', win(input), '-C', win(dest), ...args])
111
146
  if (archive === '-') return x.stdin
112
147
  if (Buffer.isBuffer(archive)) archive = require('stream').Readable.from (archive)
113
148
  if (typeof archive !== 'string') archive.pipe (x.stdin)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds",
3
- "version": "6.3.1",
3
+ "version": "6.3.2",
4
4
  "description": "SAP Cloud Application Programming Model - CDS for Node.js",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "keywords": [