@sap/cds 7.2.0 → 7.3.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 (63) hide show
  1. package/CHANGELOG.md +174 -126
  2. package/README.md +1 -1
  3. package/apis/connect.d.ts +1 -1
  4. package/apis/core.d.ts +6 -4
  5. package/apis/serve.d.ts +1 -1
  6. package/apis/services.d.ts +51 -31
  7. package/apis/test.d.ts +24 -10
  8. package/bin/serve.js +4 -3
  9. package/common.cds +4 -4
  10. package/lib/auth/ias-auth.js +7 -8
  11. package/lib/compile/cdsc.js +5 -7
  12. package/lib/compile/etc/csv.js +22 -11
  13. package/lib/dbs/cds-deploy.js +1 -2
  14. package/lib/env/cds-env.js +26 -20
  15. package/lib/env/defaults.js +4 -3
  16. package/lib/env/schema.js +9 -0
  17. package/lib/i18n/localize.js +83 -77
  18. package/lib/index.js +6 -2
  19. package/lib/linked/classes.js +13 -13
  20. package/lib/plugins.js +41 -45
  21. package/lib/req/user.js +2 -2
  22. package/lib/srv/protocols/_legacy.js +0 -1
  23. package/lib/srv/protocols/odata-v4.js +4 -0
  24. package/lib/utils/axios.js +7 -1
  25. package/lib/utils/cds-test.js +140 -133
  26. package/lib/utils/cds-utils.js +1 -1
  27. package/lib/utils/check-version.js +6 -0
  28. package/lib/utils/data.js +19 -6
  29. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +20 -19
  30. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +10 -1
  31. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +1 -1
  32. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +2 -3
  33. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +0 -14
  34. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/OdataRequest.js +1 -0
  35. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/BatchRequestListBuilder.js +5 -2
  36. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/handler/MetadataHandler.js +1 -1
  37. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/handler/ServiceHandler.js +1 -1
  38. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DispatcherCommand.js +2 -2
  39. package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/utils/BufferedWriter.js +1 -3
  40. package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +1 -1
  41. package/libx/_runtime/common/composition/update.js +18 -2
  42. package/libx/_runtime/common/error/frontend.js +46 -34
  43. package/libx/_runtime/common/generic/auth/capabilities.js +33 -14
  44. package/libx/_runtime/common/generic/input.js +1 -1
  45. package/libx/_runtime/common/generic/paging.js +1 -0
  46. package/libx/_runtime/common/i18n/messages.properties +1 -0
  47. package/libx/_runtime/common/utils/cqn2cqn4sql.js +3 -3
  48. package/libx/_runtime/db/query/update.js +48 -30
  49. package/libx/_runtime/fiori/lean-draft.js +23 -24
  50. package/libx/_runtime/hana/conversion.js +3 -2
  51. package/libx/_runtime/messaging/enterprise-messaging-utils/getTenantInfo.js +1 -1
  52. package/libx/_runtime/messaging/outbox/utils.js +1 -1
  53. package/libx/_runtime/remote/Service.js +11 -26
  54. package/libx/_runtime/remote/utils/client.js +3 -2
  55. package/libx/_runtime/remote/utils/data.js +5 -7
  56. package/libx/odata/{grammar.pegjs → grammar.peggy} +1 -1
  57. package/libx/odata/metadata.js +121 -0
  58. package/libx/odata/parser.js +1 -1
  59. package/libx/odata/service-document.js +61 -0
  60. package/libx/odata/utils.js +102 -48
  61. package/libx/rest/RestAdapter.js +2 -2
  62. package/libx/rest/middleware/error.js +1 -1
  63. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The API package for the [SAP Cloud Application Programming Model (CAP)](https://cap.cloud.sap).
4
4
 
5
- See the [API documentation](https://cap.cloud.sap/docs/node.js/api) for more details.
5
+ See the [API documentation](https://cap.cloud.sap/docs/node.js) for more details.
6
6
 
7
7
  ## How to Obtain Support
8
8
 
package/apis/connect.d.ts CHANGED
@@ -18,7 +18,7 @@ declare class cds {
18
18
 
19
19
  /**
20
20
  * Connects the primary datasource.
21
- * @see [capire](https://cap.cloud.sap/docs/node.js/api#cds-connect)
21
+ * @see [capire](https://cap.cloud.sap/docs/node.js/cds-connect)
22
22
  */
23
23
  (options?: string | ConnectOptions) : Promise<typeof cds> //> cds.connect(<options>)
24
24
  }
package/apis/core.d.ts CHANGED
@@ -3,6 +3,9 @@ import { ReflectedModel, LinkedModel } from './reflect'
3
3
  import { CSN as csn, Definition } from './csn'
4
4
 
5
5
  type UserInput = string | { id: string; attr: Record<string, string>; roles: Record<string, string> } | User
6
+ type Intersect<T extends readonly unknown[]> = T extends [infer Head, ...infer Tail]
7
+ ? Head & Intersect<Tail>
8
+ : unknown
6
9
 
7
10
  export type Association = Definition
8
11
  export type Composition = Association
@@ -26,8 +29,9 @@ export class User {
26
29
  * @deprecated Use https://cap.cloud.sap/docs/node.js/events#tenant instead
27
30
  */
28
31
  tenant: string | undefined
32
+
29
33
  attr: Record<string, string>
30
- roles: Record<string, string>
34
+ roles: Array<string> | Record<string, string>
31
35
  static Privileged: typeof Privileged
32
36
  is(role: string): boolean
33
37
  }
@@ -112,9 +116,7 @@ declare class cds {
112
116
  * }.prototype)
113
117
  */
114
118
  extend<T>(target: T): {
115
- with<X, Y, Z>(x: X, y: Y, z: Z): T & X & Y & Z
116
- with<X, Y>(x: X, y: Y): T & X & Y
117
- with<X>(x: X): T & X
119
+ with<E extends readonly unknown[]>(...ext: E): T & Intersect<E>
118
120
  }
119
121
 
120
122
  /**
package/apis/serve.d.ts CHANGED
@@ -27,7 +27,7 @@ declare class cds_serve {
27
27
 
28
28
  /**
29
29
  * Constructs service providers from respective service definitions
30
- * @see [capire](https://cap.cloud.sap/docs/node.js/api#cds-serve)
30
+ * @see [capire](https://cap.cloud.sap/docs/node.js/cds-serve)
31
31
  */
32
32
  serve (service : string, options?: service_options) : _fluent & Promise<cds_services>
33
33
 
@@ -13,7 +13,7 @@ export class QueryAPI {
13
13
  entities : LinkedModel['entities']
14
14
 
15
15
  /**
16
- * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
16
+ * @see [docs](https://cap.cloud.sap/docs/node.js/core-services#crud-style-api)
17
17
  */
18
18
  read: {
19
19
  <T extends ArrayConstructable<any>>(entity: T, key?: any): Awaitable<SELECT<T>, InstanceType<T>>
@@ -21,7 +21,7 @@ export class QueryAPI {
21
21
  }
22
22
 
23
23
  /**
24
- * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
24
+ * @see [docs](https://cap.cloud.sap/docs/node.js/core-services#crud-style-api)
25
25
  */
26
26
  create: {
27
27
  <T extends ArrayConstructable<any>>(entity: T, key?: any): INSERT<T>
@@ -29,7 +29,7 @@ export class QueryAPI {
29
29
  }
30
30
 
31
31
  /**
32
- * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
32
+ * @see [docs](https://cap.cloud.sap/docs/node.js/core-services#crud-style-api)
33
33
  */
34
34
  insert: {
35
35
  <T extends ArrayConstructable<any>>(data: T): INSERT<T>
@@ -37,7 +37,7 @@ export class QueryAPI {
37
37
  }
38
38
 
39
39
  /**
40
- * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
40
+ * @see [docs](https://cap.cloud.sap/docs/node.js/core-services#crud-style-api)
41
41
  */
42
42
  upsert: {
43
43
  <T extends ArrayConstructable<any>>(data: T): UPSERT<T>
@@ -45,7 +45,7 @@ export class QueryAPI {
45
45
  }
46
46
 
47
47
  /**
48
- * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
48
+ * @see [docs](https://cap.cloud.sap/docs/node.js/core-services#crud-style-api)
49
49
  */
50
50
  update: {
51
51
  <T extends ArrayConstructable<any>>(entity: T, key?: any): UPDATE<T>
@@ -53,7 +53,7 @@ export class QueryAPI {
53
53
  }
54
54
 
55
55
  /**
56
- * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
56
+ * @see [docs](https://cap.cloud.sap/docs/node.js/core-services#crud-style-api)
57
57
  */
58
58
  run: {
59
59
  (query: ConstructedQuery | ConstructedQuery[]): Promise<ResultSet | any>
@@ -62,17 +62,17 @@ export class QueryAPI {
62
62
  }
63
63
 
64
64
  /**
65
- * @see [docs](https://cap.cloud.sap/docs/node.js/cds-facade?q=cds.delete)
65
+ * @see [docs](https://cap.cloud.sap/docs/node.js/core-services#crud-style-api)
66
66
  */
67
67
  delete<T>(entity: Definition | string, key?: any): DELETE<T>
68
68
 
69
69
  /**
70
- * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
70
+ * @see [docs](https://cap.cloud.sap/docs/node.js/core-services#srv-foreach-entity)
71
71
  */
72
72
  foreach(query: Query, callback: (row: object) => void): this
73
73
 
74
74
  /**
75
- * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-stream)
75
+ * @see [docs](https://cap.cloud.sap/docs/node.js/core-services#srv-stream-column)
76
76
  */
77
77
  stream: {
78
78
  (column: string): {
@@ -85,18 +85,28 @@ export class QueryAPI {
85
85
 
86
86
  /**
87
87
  * Starts or joins a transaction
88
- * @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-tx)
88
+ * @see [docs](https://cap.cloud.sap/docs/node.js/cds-tx)
89
89
  */
90
- tx(context?: object): Transaction
91
- transaction(context?: object): Transaction
90
+
91
+ tx: {
92
+ (fn: (tx: Transaction) => {}): Promise<unknown>
93
+ (context?: object): Transaction
94
+ (context: object, fn: (tx: Transaction) => {}): Promise<unknown>
95
+ }
96
+
97
+ transaction: {
98
+ (fn: (tx: Transaction) => {}): Promise<unknown>
99
+ (context?: object): Transaction
100
+ (context: object, fn: (tx: Transaction) => {}): Promise<unknown>
101
+ }
92
102
 
93
103
  /**
94
- * @see [docs](https://pages.github.tools.sap/cap/docs/node.js/cds-context-tx?q=spawn#cds-spawn)
104
+ * @see [docs](https://cap.cloud.sap/docs/node.js/cds-tx#cds-spawn)
95
105
  */
96
106
  spawn(options: Options, fn: (tx: Transaction) => {}): SpawnEventEmitter
97
107
 
98
108
  /**
99
- * @see [docs](https://pages.github.tools.sap/cap/docs/node.js/cds-context-tx?q=cds.context#cds-context
109
+ * @see [docs](https://cap.cloud.sap/docs/node.js/cds-tx#event-contexts
100
110
  */
101
111
  context: ContextProperties
102
112
  }
@@ -110,7 +120,7 @@ type ContextProperties = {
110
120
 
111
121
  /**
112
122
  * Class cds.Service
113
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services)
123
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services)
114
124
  */
115
125
  export class Service extends QueryAPI {
116
126
  constructor(
@@ -129,44 +139,44 @@ export class Service extends QueryAPI {
129
139
 
130
140
  /**
131
141
  * The model from which the service's definition was loaded
132
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-reflect)
142
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services)
133
143
  */
134
144
  model: LinkedModel
135
145
 
136
146
  /**
137
147
  * Provides access to the entities exposed by a service
138
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-reflect)
148
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services)
139
149
  */
140
150
  entities: Definitions & ((namespace: string) => Definitions)
141
151
 
142
152
  /**
143
153
  * Provides access to the events declared by a service
144
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-reflect)
154
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services)
145
155
  */
146
156
  events: Definitions & ((namespace: string) => Definitions)
147
157
 
148
158
  /**
149
159
  * Provides access to the types exposed by a service
150
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-reflect)
160
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services)
151
161
  */
152
162
  types: Definitions & ((namespace: string) => Definitions)
153
163
 
154
164
  /**
155
165
  * Provides access to the operations, i.e. actions and functions, exposed by a service
156
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-reflect)
166
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services)
157
167
  */
158
168
  operations: Definitions & ((namespace: string) => Definitions)
159
169
 
160
170
  /**
161
171
  * Acts like a parameter-less constructor. Ensure to call `await super.init()` to have the base class’s handlers added.
162
172
  * You may register own handlers before the base class’s ones, to intercept requests before the default handlers snap in.
163
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#cds-service-subclasses)
173
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#srv-init)
164
174
  */
165
175
  init(): Promise<void>
166
176
 
167
177
  /**
168
178
  * Constructs and emits an asynchronous event.
169
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-emit)
179
+ * @see [capire docs](https://cap.cloud.sap/docs/core-services#srv-emit-event)
170
180
  */
171
181
  emit: {
172
182
  <T = any>(details: { event: EventArg; data?: object; headers?: object }): Promise<T>
@@ -175,7 +185,7 @@ export class Service extends QueryAPI {
175
185
 
176
186
  /**
177
187
  * Constructs and sends a synchronous request.
178
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srvsend--method-path-data-headers--results-)
188
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#srv-send-request)
179
189
  */
180
190
  send: {
181
191
  <T = any>(event: EventArg, path: string, data?: object, headers?: object): Promise<T>
@@ -188,22 +198,22 @@ export class Service extends QueryAPI {
188
198
 
189
199
  /**
190
200
  * Constructs and sends a GET request.
191
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
201
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#rest-style-api)
192
202
  */
193
203
  get<T = any>(entityOrPath: Target, data?: object): Promise<T>
194
204
  /**
195
205
  * Constructs and sends a POST request.
196
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
206
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#rest-style-api)
197
207
  */
198
208
  post<T = any>(entityOrPath: Target, data?: object): Promise<T>
199
209
  /**
200
210
  * Constructs and sends a PUT request.
201
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
211
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#rest-style-api)
202
212
  */
203
213
  put<T = any>(entityOrPath: Target, data?: object): Promise<T>
204
214
  /**
205
215
  * Constructs and sends a PATCH request.
206
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
216
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services#rest-style-api)
207
217
  */
208
218
  patch<T = any>(entityOrPath: Target, data?: object): Promise<T>
209
219
  /**
@@ -221,8 +231,8 @@ export class Service extends QueryAPI {
221
231
  // Provider API
222
232
  prepend(fn: ServiceImpl): Promise<this>
223
233
  on<T extends Constructable>(eve: EventArg, entity: T, handler: CRUDEventHandler.On<InstanceType<T>, InstanceType<T> | void | Error>): this
224
- on<P,R>(boundAction: (args: P) => R, service: string, handler: ActionEventHandler<P, void | Error | R>): this
225
- on<P,R>(action: (args: P) => R, handler: ActionEventHandler<P, void | Error | R>): this
234
+ on<F extends CdsFunction>(boundAction: F, service: string, handler: ActionEventHandler<F['__parameters'], void | Error | F['__returns']>): this
235
+ on<F extends CdsFunction>(unboundAction: F, handler: ActionEventHandler<F['__parameters'], void | Error | F['__returns']>): this
226
236
  on(eve: EventArg, entity: Target, handler: OnEventHandler): this
227
237
  on(eve: EventArg, handler: OnEventHandler): this
228
238
 
@@ -259,7 +269,7 @@ export interface ResultSet extends Array<{}> {}
259
269
 
260
270
  declare class cds {
261
271
  /**
262
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/services)
272
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/core-services)
263
273
  */
264
274
  Service: typeof Service
265
275
  Request: typeof Request
@@ -312,9 +322,19 @@ type Partial<T> = { [Key in keyof T]: undefined | T[Key] }
312
322
  // So we always have to expect scalars as well as arrays in some callbacks.
313
323
  type OneOrMany<T> = T | T[];
314
324
 
325
+ // functions generated by cds-typer explicitly carry types for
326
+ // parameters and return type, as their names are not accessible from
327
+ // function signatures to the type system.
328
+ // This meta information is required in .on action handlers.
329
+ type CdsFunction = {
330
+ (...args: any[]): any,
331
+ __parameters: object,
332
+ __returns: unknown
333
+ }
334
+
315
335
  type TypedRequest<T> = Omit<Request, 'data'> & { data: T }
316
336
 
317
- // https://cap.cloud.sap/docs/node.js/services#event-handlers
337
+ // https://cap.cloud.sap/docs/node.js/core-services#srv-on-before-after
318
338
  export namespace CRUDEventHandler {
319
339
  type Before<P,R> = (req: TypedRequest<P>) => Promise<R> | R
320
340
  type On<P,R> = (req: TypedRequest<P>, next: (...args: any) => Promise<R> | R) => Promise<R> | R
package/apis/test.d.ts CHANGED
@@ -24,13 +24,17 @@ declare class Axios {
24
24
  declare class DataUtil {
25
25
  delete(db?: Service): Promise<void>;
26
26
  reset(db?: Service): Promise<void>;
27
- autoReset(enabled: boolean): this;
27
+ /** @deprecated */ autoReset(enabled: boolean): this;
28
28
  }
29
29
 
30
30
  declare class Test extends Axios {
31
+
32
+ test : Test
33
+
31
34
  run(cmd: string, ...args: string[]): this;
32
35
  in(...paths: string[]): this;
33
- verbose(v: boolean): this;
36
+ silent(): this;
37
+ /** @deprecated */ verbose(v: boolean): this;
34
38
 
35
39
  get chai(): typeof chai;
36
40
  get expect(): typeof chai.expect;
@@ -38,6 +42,12 @@ declare class Test extends Axios {
38
42
  get data(): DataUtil;
39
43
  get cds(): typeof import('./cds').default;
40
44
 
45
+ log() : {
46
+ output: string
47
+ clear(): void
48
+ release(): void
49
+ }
50
+
41
51
  then(r: (args: { server: http.Server, url: string }) => void): void;
42
52
 
43
53
  // get sleep(): (ms: number) => Promise<void>;
@@ -56,12 +66,16 @@ declare class Test extends Axios {
56
66
  export = cds
57
67
 
58
68
  declare class cds {
59
- /**
60
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/cds-test?q=cds.test#run)
61
- */
62
- test(projectDir: string): Test;
63
- /**
64
- * @see [capire docs](https://cap.cloud.sap/docs/node.js/cds-test?q=cds.test#run-2)
65
- */
66
- test(command: string, ...args: string[]): Test;
69
+ test: {
70
+ Test: typeof Test
71
+ /**
72
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/cds-test?q=cds.test#run)
73
+ */
74
+ (projectDir: string): Test;
75
+ /**
76
+ * @see [capire docs](https://cap.cloud.sap/docs/node.js/cds-test?q=cds.test#run-2)
77
+ */
78
+ (command: string, ...args: string[]): Test;
79
+ in (string) : Test
80
+ }
67
81
  }
package/bin/serve.js CHANGED
@@ -128,6 +128,7 @@ module.exports = Object.assign ( serve, {
128
128
 
129
129
 
130
130
  const cds = require('../lib'), { exists, isfile, local, path } = cds.utils
131
+ const COLORS = !!process.stdout.isTTY && !!process.stderr.isTTY && !process.env.NO_COLOR
131
132
 
132
133
  // provisional loggers, see _prepare_logging
133
134
  let log = console.log
@@ -201,7 +202,7 @@ async function serve (all=[], o={}) {
201
202
  _warn_if_cds_was_loaded_from_different_locations()
202
203
  const url = cds.server.url = `http://localhost:${server.address().port}`
203
204
  cds.emit ('listening', {server,url}) //> inform local listeners
204
- _resolve (server)
205
+ _resolve ({ server, url })
205
206
  }
206
207
 
207
208
  const LOG = cds.log('cli|server')
@@ -256,9 +257,9 @@ function _prepare_logging () { // NOSONAR
256
257
 
257
258
  // print information when model is loaded
258
259
  cds.on ('loaded', (model)=>{
259
- LOG.info (`loaded model from ${model.$sources.length} file(s):\n\x1b[2m`)
260
+ LOG.info (`loaded model from ${model.$sources.length} file(s):\n${COLORS ? '\x1b[2m' : ''}`)
260
261
  for (let each of model.$sources) console.log (' ', local(each))
261
- console.log ('\x1b[0m')
262
+ COLORS && console.log ('\x1b[0m')
262
263
  })
263
264
 
264
265
  // print information about each connected service
package/common.cds CHANGED
@@ -35,7 +35,7 @@ context sap.common {
35
35
  /**
36
36
  * Code list for languages
37
37
  *
38
- * See https://cap.cloud.sap/docs/cds/common#entity-sapcommonlanguages
38
+ * See https://cap.cloud.sap/docs/cds/common#entity-languages
39
39
  */
40
40
  entity Languages : CodeList {
41
41
  key code : Locale;
@@ -44,7 +44,7 @@ context sap.common {
44
44
  /**
45
45
  * Code list for countries
46
46
  *
47
- * See https://cap.cloud.sap/docs/cds/common#entity-sapcommoncountries
47
+ * See https://cap.cloud.sap/docs/cds/common#entity-countries
48
48
  */
49
49
  entity Countries : CodeList {
50
50
  key code : String(3) @(title : '{i18n>CountryCode}');
@@ -53,7 +53,7 @@ context sap.common {
53
53
  /**
54
54
  * Code list for currencies
55
55
  *
56
- * See https://cap.cloud.sap/docs/cds/common#entity-sapcommoncurrencies
56
+ * See https://cap.cloud.sap/docs/cds/common#entity-currencies
57
57
  */
58
58
  entity Currencies : CodeList {
59
59
  key code : String(3) @(title : '{i18n>CurrencyCode}');
@@ -64,7 +64,7 @@ context sap.common {
64
64
  /**
65
65
  * Aspect for a code list with name and description
66
66
  *
67
- * See https://cap.cloud.sap/docs/cds/common#aspect-sapcommoncodelist
67
+ * See https://cap.cloud.sap/docs/cds/common#aspect-codelist
68
68
  */
69
69
  aspect CodeList @(
70
70
  cds.autoexpose,
@@ -41,15 +41,14 @@ module.exports = function ias_auth(config) {
41
41
  .use((req, res, next) => {
42
42
  if (!('authInfo' in req)) return next()
43
43
 
44
- if (req.tokenInfo.getClientId() === req.tokenInfo.getSubject()) //> grant_type === client_credentials or x509
45
- req.user = new cds.User({
46
- id: 'system',
47
- roles: ['authenticated-user', 'system-user'],
48
- attr: {}
49
- })
50
- else {
44
+ const payload = req.tokenInfo.getPayload()
45
+ if (req.tokenInfo.getClientId() === req.tokenInfo.getSubject()) {
46
+ //> grant_type === client_credentials or x509
47
+ const roles = ['authenticated-user', 'system-user']
48
+ if (payload.azp === config.credentials.clientid) roles.push('internal-user')
49
+ req.user = new cds.User({ id: 'system', roles, attr: {} })
50
+ } else {
51
51
  // add all unknown attributes to req.user.attr in order to keep public API small
52
- const payload = req.tokenInfo.getPayload()
53
52
  const attributes = Object.keys(payload)
54
53
  .filter(k => !RESERVED_ATTRIBUTES.has(k))
55
54
  .reduce((attrs, k) => { attrs[k] = payload[k]; return attrs }, {})
@@ -1,8 +1,4 @@
1
1
  const cds = require ('../index')
2
- const {cdsc,odata,sql,features} = cds.env
3
- const constraints = {
4
- assertIntegrity: features.assert_integrity
5
- }
6
2
  const compile = require ('@sap/cds-compiler')
7
3
  const _4cdsc = Symbol('_4cdsc')
8
4
 
@@ -24,7 +20,7 @@ function _options4 (src, ...mappings) {
24
20
  // Optionally add .messages array to avoid compiler writing messages to stderr
25
21
  dst.messages = dst.messages || []
26
22
  // Finally override with options from cds.env.cdsc
27
- return Object.assign(dst,cdsc)
23
+ return Object.assign(dst,cds.env.cdsc)
28
24
  }
29
25
 
30
26
 
@@ -38,6 +34,7 @@ function _options4 (src, ...mappings) {
38
34
  const _options = {for: Object.assign (_options4, {
39
35
 
40
36
  odata(o,_more) {
37
+ const odata = cds.env.odata
41
38
  if (o && o[_4cdsc]) return o
42
39
  let f = o && o.flavor || odata.flavor || o, flavor = odata.flavors && odata.flavors[f] || {}
43
40
  let v = o && o.version || flavor.version || odata.version //> env.odata.flavors.version overrides env.odata.version!
@@ -66,8 +63,9 @@ const _options = {for: Object.assign (_options4, {
66
63
 
67
64
  sql(o,_env) {
68
65
  // REVISIT: compiler requires to only provide assertIntegrityType if defined
69
- if(constraints.assertIntegrity) constraints.assertIntegrityType = features.assert_integrity_type
70
- return _options4 ({ ...constraints, ..._env||sql, ...o }, {
66
+ let assertIntegrity = cds.env.features.assert_integrity
67
+ let constraints = assertIntegrity && { assertIntegrityType: cds.env.features.assert_integrity_type }
68
+ return _options4 ({ ...constraints, ..._env||cds.env.sql, ...o }, {
71
69
  sql_mapping : 'names', //> legacy
72
70
  sqlDialect : 'dialect', //> legacy
73
71
  sqlMapping : 'names',
@@ -12,12 +12,19 @@ function read (res) {
12
12
  function parse (csv) {
13
13
  if (csv[0] === BOM) csv = csv.slice(1)
14
14
  let sep
15
- const lines = csv.split(/\s*\n/)
15
+ const lines = csv.split('\n')
16
16
  const rows = [], headers = []
17
- for (let line of lines) {
17
+
18
+ let val, values=[]
19
+ let inString=false, quoted=false
20
+ for (let l = 0; l < lines.length; l++) {
21
+ const line = lines[l]
18
22
  if (!rows.length && _ignoreLine (line)) continue
19
23
  if (!sep) [sep] = SEPARATOR.exec(line)||[';']
20
- const values=[]; let val, currCol=0, c, inString=false, quoted=false
24
+ if (inString) val += '\n' // overflow from last line
25
+ else val = undefined
26
+
27
+ let currCol=0, c
21
28
  for (let i=0; i<line.length; ) {
22
29
  c = line[i++]
23
30
  if (c === sep && !inString) { // separator
@@ -39,19 +46,23 @@ function parse (csv) {
39
46
  val += c === '\\' ? '\\\\' : c
40
47
  }
41
48
  }
42
- // remaining value
43
- currCol++
44
- if (!rows.length && val !== undefined) headers.push(currCol) // skip column if header value is empty
45
- if ((val !== undefined || c === sep) && headers.includes(currCol)) values.push (_value4(val, quoted))
46
- if (values.length > 0) rows.push (values)
49
+
50
+ // finish line w/ remaining value
51
+ if (!inString || l === lines.length-1 ) { // unless unterminated string and more lines to come
52
+ currCol++
53
+ if (!rows.length && val !== undefined) headers.push(currCol) // skip column if header value is empty
54
+ if ((val !== undefined || c === sep) && headers.includes(currCol)) values.push (_value4(val, quoted))
55
+ if (values.length > 0) { rows.push (values); values = [] }
56
+ }
47
57
  }
48
58
  return rows
49
59
  }
50
60
 
51
- function _value4 (val, quoted = false) { //NOSONAR
61
+ function _value4 (val, quoted = false) {
62
+ if (quoted) return val
52
63
  if (val) val = val.trim()
53
- if (!quoted && val === 'true') return true
54
- if (!quoted && val === 'false') return false
64
+ if (val === 'true') return true
65
+ else if (val === 'false') return false
55
66
  else return val
56
67
  }
57
68
 
@@ -3,7 +3,7 @@ const cds = require('../index'), { local } = cds.utils
3
3
  const COLORS = !!process.stdout.isTTY && !!process.stderr.isTTY && !process.env.NO_COLOR
4
4
  const GREY = COLORS ? '\x1b[2m' : ''
5
5
  const RESET = COLORS ? '\x1b[0m' : ''
6
- let DEBUG // IMPORTANT: initialized later after await cds.plugins
6
+ const DEBUG = cds.debug('deploy')
7
7
 
8
8
  /**
9
9
  * Implementation of `cds.deploy` common to all databases.
@@ -12,7 +12,6 @@ let DEBUG // IMPORTANT: initialized later after await cds.plugins
12
12
  * in initial data, if present.
13
13
  */
14
14
  module.exports = exports = function cds_deploy (model,options,csvs) {
15
- DEBUG = cds.debug('deploy')
16
15
  return {
17
16
  /** @param {import('@sap/cds/lib/srv/srv-api')} db */
18
17
  async to(db, o = options || {}) {