@sap/cds-dk 8.7.3 → 8.8.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 (76) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/bin/bind.js +7 -8
  3. package/bin/cds.js +2 -4
  4. package/bin/compile/index.js +1 -0
  5. package/bin/deploy/index.js +10 -5
  6. package/bin/watch.js +48 -7
  7. package/lib/bind/{cfKeyProvider.js → cf.js} +43 -53
  8. package/lib/bind/k8s.js +138 -0
  9. package/lib/bind/plugin.js +48 -0
  10. package/lib/bind/shared.js +267 -0
  11. package/lib/build/buildTaskEngine.js +1 -1
  12. package/lib/build/plugins/helm/files/subcharts/content-deployment/Chart.yaml +0 -2
  13. package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -3
  14. package/lib/build/plugins/helm/files/subcharts/web-application/templates/service-binding.yaml +3 -0
  15. package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +3 -0
  16. package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +2 -1
  17. package/lib/build/util.js +1 -1
  18. package/lib/compile/to-mermaid.js +1 -2
  19. package/lib/deploy/to-hana/hana.js +1 -1
  20. package/lib/deploy/to-hana/mtaUtil.js +0 -13
  21. package/lib/env/schemas/cds-rc.js +17 -30
  22. package/lib/import/common.js +20 -10
  23. package/lib/init/constants.js +1 -1
  24. package/lib/init/merge.js +41 -32
  25. package/lib/init/projectReader.js +15 -7
  26. package/lib/init/registries/mta.js +7 -1
  27. package/lib/init/template/approuter/files/package.json +1 -1
  28. package/lib/init/template/approuter/files/xs-app.json.hbs +0 -11
  29. package/lib/init/template/cloud-logging/files/package.json.hbs +12 -1
  30. package/lib/init/template/cloud-logging/files/values.yaml.hbs +0 -2
  31. package/lib/init/template/cloud-logging/index.js +8 -15
  32. package/lib/init/template/destination/files/values.yaml +4 -4
  33. package/lib/init/template/destination/index.js +1 -1
  34. package/lib/init/template/html5-repo/files/app-package.json.hbs +0 -2
  35. package/lib/init/template/html5-repo/files/containerize.yaml.hbs +25 -0
  36. package/lib/init/template/html5-repo/files/mta.yaml.hbs +1 -2
  37. package/lib/init/template/html5-repo/files/package.json.hbs +1 -1
  38. package/lib/init/template/html5-repo/files/ui-resources/package.json.hbs +11 -0
  39. package/lib/init/template/html5-repo/files/ui5-deploy.yaml.hbs +4 -7
  40. package/lib/init/template/html5-repo/files/values.yaml.hbs +6 -4
  41. package/lib/init/template/html5-repo/index.js +22 -10
  42. package/lib/init/template/http/index.js +1 -1
  43. package/lib/init/template/lint/index.js +7 -1
  44. package/lib/init/template/multitenancy/files/mta.yaml.hbs +0 -2
  45. package/lib/init/template/multitenancy/index.js +1 -1
  46. package/lib/init/template/portal/files/mta.yaml.hbs +9 -0
  47. package/lib/init/template/portal/index.js +3 -1
  48. package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +119 -119
  49. package/lib/init/template/sample/files/app/browse/webapp/manifest.json +1 -1
  50. package/lib/init/template/telemetry/index.js +0 -13
  51. package/lib/init/template/typer/files/package.json +3 -0
  52. package/lib/init/template/workzone-standard/files/cdm.json.hbs +97 -0
  53. package/lib/init/template/workzone-standard/files/mta.yaml.hbs +23 -0
  54. package/lib/init/template/workzone-standard/index.js +70 -39
  55. package/lib/init/template/xsuaa/files/mta.yaml.hbs +2 -2
  56. package/lib/init/template/xsuaa/files/values.yaml.hbs +0 -2
  57. package/lib/init/template/xsuaa/index.js +22 -10
  58. package/lib/lint/io.js +8 -4
  59. package/lib/mtx/util/cf.js +1 -2
  60. package/lib/util/cf.js +104 -84
  61. package/lib/util/command.js +1 -2
  62. package/lib/util/git.js +1 -1
  63. package/npm-shrinkwrap.json +53 -45
  64. package/package.json +1 -1
  65. package/bin/deploy/to-cf.js +0 -0
  66. package/bin/deploy/via-mta.js +0 -0
  67. package/lib/bind/KubernetesApiAccessor.js +0 -81
  68. package/lib/bind/bindingManager.js +0 -89
  69. package/lib/bind/bindingResolver.js +0 -54
  70. package/lib/bind/bindingUtil.js +0 -129
  71. package/lib/bind/index.js +0 -127
  72. package/lib/bind/kubernetesCredentialsProvider.js +0 -84
  73. package/lib/bind/userCdsrcJsonStorageProvider.js +0 -92
  74. package/lib/init/template/destination/files/package.sidecar.json +0 -7
  75. package/lib/init/template/html5-repo/files/package.sidecar.json +0 -7
  76. package/lib/init/template/telemetry/files/package.json.hbs +0 -18
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@sap/cds-dk",
3
- "version": "8.7.3",
3
+ "version": "8.8.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@sap/cds-dk",
9
- "version": "8.7.3",
9
+ "version": "8.8.1",
10
10
  "license": "SEE LICENSE IN LICENSE",
11
11
  "dependencies": {
12
12
  "@cap-js/asyncapi": "^1.0.0",
@@ -36,14 +36,14 @@
36
36
  }
37
37
  },
38
38
  "node_modules/@cap-js/asyncapi": {
39
- "version": "1.0.2",
39
+ "version": "1.0.3",
40
40
  "license": "SEE LICENSE IN LICENSE",
41
41
  "peerDependencies": {
42
42
  "@sap/cds": ">=7.6"
43
43
  }
44
44
  },
45
45
  "node_modules/@cap-js/db-service": {
46
- "version": "1.17.2",
46
+ "version": "1.18.0",
47
47
  "license": "SEE LICENSE",
48
48
  "optional": true,
49
49
  "dependencies": {
@@ -54,7 +54,7 @@
54
54
  }
55
55
  },
56
56
  "node_modules/@cap-js/openapi": {
57
- "version": "1.1.2",
57
+ "version": "1.2.1",
58
58
  "license": "SEE LICENSE IN LICENSE",
59
59
  "dependencies": {
60
60
  "pluralize": "^8.0.0"
@@ -64,11 +64,11 @@
64
64
  }
65
65
  },
66
66
  "node_modules/@cap-js/sqlite": {
67
- "version": "1.8.0",
67
+ "version": "1.9.0",
68
68
  "license": "SEE LICENSE",
69
69
  "optional": true,
70
70
  "dependencies": {
71
- "@cap-js/db-service": "^1.17.0",
71
+ "@cap-js/db-service": "^1.18.0",
72
72
  "better-sqlite3": "^11.0.0"
73
73
  },
74
74
  "peerDependencies": {
@@ -76,7 +76,7 @@
76
76
  }
77
77
  },
78
78
  "node_modules/@eslint-community/eslint-utils": {
79
- "version": "4.4.1",
79
+ "version": "4.5.1",
80
80
  "license": "MIT",
81
81
  "dependencies": {
82
82
  "eslint-visitor-keys": "^3.4.3"
@@ -120,8 +120,15 @@
120
120
  "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
121
121
  }
122
122
  },
123
+ "node_modules/@eslint/config-helpers": {
124
+ "version": "0.1.0",
125
+ "license": "Apache-2.0",
126
+ "engines": {
127
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
128
+ }
129
+ },
123
130
  "node_modules/@eslint/core": {
124
- "version": "0.11.0",
131
+ "version": "0.12.0",
125
132
  "license": "Apache-2.0",
126
133
  "dependencies": {
127
134
  "@types/json-schema": "^7.0.15"
@@ -131,7 +138,7 @@
131
138
  }
132
139
  },
133
140
  "node_modules/@eslint/eslintrc": {
134
- "version": "3.2.0",
141
+ "version": "3.3.0",
135
142
  "license": "MIT",
136
143
  "dependencies": {
137
144
  "ajv": "^6.12.4",
@@ -152,7 +159,7 @@
152
159
  }
153
160
  },
154
161
  "node_modules/@eslint/js": {
155
- "version": "9.20.0",
162
+ "version": "9.22.0",
156
163
  "license": "MIT",
157
164
  "engines": {
158
165
  "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -166,10 +173,10 @@
166
173
  }
167
174
  },
168
175
  "node_modules/@eslint/plugin-kit": {
169
- "version": "0.2.6",
176
+ "version": "0.2.7",
170
177
  "license": "Apache-2.0",
171
178
  "dependencies": {
172
- "@eslint/core": "^0.11.0",
179
+ "@eslint/core": "^0.12.0",
173
180
  "levn": "^0.4.1"
174
181
  },
175
182
  "engines": {
@@ -217,7 +224,7 @@
217
224
  }
218
225
  },
219
226
  "node_modules/@humanwhocodes/retry": {
220
- "version": "0.4.1",
227
+ "version": "0.4.2",
221
228
  "license": "Apache-2.0",
222
229
  "engines": {
223
230
  "node": ">=18.18"
@@ -228,7 +235,7 @@
228
235
  }
229
236
  },
230
237
  "node_modules/@sap/cds": {
231
- "version": "8.7.2",
238
+ "version": "8.8.2",
232
239
  "license": "SEE LICENSE IN LICENSE",
233
240
  "dependencies": {
234
241
  "@sap/cds-compiler": ">=5.1",
@@ -258,7 +265,7 @@
258
265
  }
259
266
  },
260
267
  "node_modules/@sap/cds-compiler": {
261
- "version": "5.7.4",
268
+ "version": "5.8.2",
262
269
  "license": "SEE LICENSE IN LICENSE",
263
270
  "dependencies": {
264
271
  "antlr4": "4.9.3"
@@ -273,7 +280,7 @@
273
280
  }
274
281
  },
275
282
  "node_modules/@sap/cds-fiori": {
276
- "version": "1.3.0",
283
+ "version": "1.4.0",
277
284
  "license": "SEE LICENSE IN LICENSE",
278
285
  "peerDependencies": {
279
286
  "@sap/cds": ">=7.6",
@@ -294,7 +301,7 @@
294
301
  }
295
302
  },
296
303
  "node_modules/@sap/cds-mtxs": {
297
- "version": "2.5.1",
304
+ "version": "2.6.1",
298
305
  "license": "SEE LICENSE IN LICENSE",
299
306
  "dependencies": {
300
307
  "@sap/hdi-deploy": ">=4",
@@ -306,11 +313,11 @@
306
313
  }
307
314
  },
308
315
  "node_modules/@sap/eslint-plugin-cds": {
309
- "version": "3.1.2",
316
+ "version": "3.2.0",
310
317
  "license": "See LICENSE file",
311
318
  "dependencies": {
312
319
  "@sap/cds": ">=7",
313
- "semver": "^7.3.4"
320
+ "semver": "^7.7.1"
314
321
  },
315
322
  "engines": {
316
323
  "node": ">=18"
@@ -342,10 +349,10 @@
342
349
  }
343
350
  },
344
351
  "node_modules/@sap/hdi-deploy": {
345
- "version": "5.3.2",
352
+ "version": "5.4.1",
346
353
  "license": "See LICENSE file",
347
354
  "dependencies": {
348
- "@sap/hdi": "^4.6.0",
355
+ "@sap/hdi": "^4.7.0",
349
356
  "@sap/xsenv": "^5.2.0",
350
357
  "async": "^3.2.6",
351
358
  "dotenv": "^16.4.5",
@@ -353,7 +360,7 @@
353
360
  "micromatch": "^4.0.8"
354
361
  },
355
362
  "engines": {
356
- "node": "^18.0.0 || ^20.0.0"
363
+ "node": ">=18.x"
357
364
  },
358
365
  "peerDependencies": {
359
366
  "@sap/hana-client": "^2 >= 2.6",
@@ -369,10 +376,10 @@
369
376
  }
370
377
  },
371
378
  "node_modules/@sap/xsenv": {
372
- "version": "5.4.0",
379
+ "version": "5.5.0",
373
380
  "license": "SEE LICENSE IN LICENSE file",
374
381
  "dependencies": {
375
- "debug": "4.3.7",
382
+ "debug": "4.4.0",
376
383
  "node-cache": "^5.1.2",
377
384
  "verror": "1.10.1"
378
385
  },
@@ -400,7 +407,7 @@
400
407
  }
401
408
  },
402
409
  "node_modules/acorn": {
403
- "version": "8.14.0",
410
+ "version": "8.14.1",
404
411
  "license": "MIT",
405
412
  "bin": {
406
413
  "acorn": "bin/acorn"
@@ -474,7 +481,7 @@
474
481
  "license": "MIT"
475
482
  },
476
483
  "node_modules/axios": {
477
- "version": "1.7.9",
484
+ "version": "1.8.3",
478
485
  "license": "MIT",
479
486
  "dependencies": {
480
487
  "follow-redirects": "^1.15.6",
@@ -637,11 +644,11 @@
637
644
  }
638
645
  },
639
646
  "node_modules/call-bound": {
640
- "version": "1.0.3",
647
+ "version": "1.0.4",
641
648
  "license": "MIT",
642
649
  "dependencies": {
643
- "call-bind-apply-helpers": "^1.0.1",
644
- "get-intrinsic": "^1.2.6"
650
+ "call-bind-apply-helpers": "^1.0.2",
651
+ "get-intrinsic": "^1.3.0"
645
652
  },
646
653
  "engines": {
647
654
  "node": ">= 0.4"
@@ -756,7 +763,7 @@
756
763
  }
757
764
  },
758
765
  "node_modules/debug": {
759
- "version": "4.3.7",
766
+ "version": "4.4.0",
760
767
  "license": "MIT",
761
768
  "dependencies": {
762
769
  "ms": "^2.1.3"
@@ -919,19 +926,20 @@
919
926
  }
920
927
  },
921
928
  "node_modules/eslint": {
922
- "version": "9.20.1",
929
+ "version": "9.22.0",
923
930
  "license": "MIT",
924
931
  "dependencies": {
925
932
  "@eslint-community/eslint-utils": "^4.2.0",
926
933
  "@eslint-community/regexpp": "^4.12.1",
927
- "@eslint/config-array": "^0.19.0",
928
- "@eslint/core": "^0.11.0",
929
- "@eslint/eslintrc": "^3.2.0",
930
- "@eslint/js": "9.20.0",
931
- "@eslint/plugin-kit": "^0.2.5",
934
+ "@eslint/config-array": "^0.19.2",
935
+ "@eslint/config-helpers": "^0.1.0",
936
+ "@eslint/core": "^0.12.0",
937
+ "@eslint/eslintrc": "^3.3.0",
938
+ "@eslint/js": "9.22.0",
939
+ "@eslint/plugin-kit": "^0.2.7",
932
940
  "@humanfs/node": "^0.16.6",
933
941
  "@humanwhocodes/module-importer": "^1.0.1",
934
- "@humanwhocodes/retry": "^0.4.1",
942
+ "@humanwhocodes/retry": "^0.4.2",
935
943
  "@types/estree": "^1.0.6",
936
944
  "@types/json-schema": "^7.0.15",
937
945
  "ajv": "^6.12.4",
@@ -939,7 +947,7 @@
939
947
  "cross-spawn": "^7.0.6",
940
948
  "debug": "^4.3.2",
941
949
  "escape-string-regexp": "^4.0.0",
942
- "eslint-scope": "^8.2.0",
950
+ "eslint-scope": "^8.3.0",
943
951
  "eslint-visitor-keys": "^4.2.0",
944
952
  "espree": "^10.3.0",
945
953
  "esquery": "^1.5.0",
@@ -976,7 +984,7 @@
976
984
  }
977
985
  },
978
986
  "node_modules/eslint-scope": {
979
- "version": "8.2.0",
987
+ "version": "8.3.0",
980
988
  "license": "BSD-2-Clause",
981
989
  "dependencies": {
982
990
  "esrecurse": "^4.3.0",
@@ -1283,15 +1291,15 @@
1283
1291
  }
1284
1292
  },
1285
1293
  "node_modules/get-intrinsic": {
1286
- "version": "1.2.7",
1294
+ "version": "1.3.0",
1287
1295
  "license": "MIT",
1288
1296
  "dependencies": {
1289
- "call-bind-apply-helpers": "^1.0.1",
1297
+ "call-bind-apply-helpers": "^1.0.2",
1290
1298
  "es-define-property": "^1.0.1",
1291
1299
  "es-errors": "^1.3.0",
1292
- "es-object-atoms": "^1.0.0",
1300
+ "es-object-atoms": "^1.1.1",
1293
1301
  "function-bind": "^1.1.2",
1294
- "get-proto": "^1.0.0",
1302
+ "get-proto": "^1.0.1",
1295
1303
  "gopd": "^1.2.0",
1296
1304
  "has-symbols": "^1.1.0",
1297
1305
  "hasown": "^2.0.2",
@@ -2432,7 +2440,7 @@
2432
2440
  "optional": true
2433
2441
  },
2434
2442
  "node_modules/ws": {
2435
- "version": "8.18.0",
2443
+ "version": "8.18.1",
2436
2444
  "license": "MIT",
2437
2445
  "engines": {
2438
2446
  "node": ">=10.0.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-dk",
3
- "version": "8.7.3",
3
+ "version": "8.8.1",
4
4
  "description": "Command line client and development toolkit for the SAP Cloud Application Programming Model",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "keywords": [
File without changes
File without changes
@@ -1,81 +0,0 @@
1
- const { yaml } = require('../cds').utils
2
- const { execSync } = require('child_process');
3
- const { bold } = require('../util/term');
4
-
5
- class KubernetesApiAccessor {
6
-
7
- constructor() {
8
-
9
- this.config = once( async() => {
10
- const configString = execSync('kubectl config view --raw').toString();
11
- const config = yaml.parse(configString);
12
-
13
- const currentContextName = config['current-context'];
14
- if (!currentContextName) throw new Error(`No current context in kubectl config.`);
15
- const currentContextEntry = config.contexts && config.contexts.find( entry => entry.name === currentContextName && entry.context && entry.context.cluster && entry.context.user );
16
- if (!currentContextEntry) throw new Error(`Current context not found in kubectl config.`);
17
- const currentContext = currentContextEntry.context;
18
- const clusterEntry = config.clusters && config.clusters.find( entry => entry.name === currentContext.cluster && entry.cluster && entry.cluster.server );
19
- if (!currentContextEntry) throw new Error(`Cluster ${bold(currentContext.cluster)} not found in kubectl config.`);
20
- const { cluster } = clusterEntry;
21
-
22
- const serverToContext = {};
23
- for (const clusterEntry of config.clusters) {
24
- const contextEntries = config.contexts.filter( contextEntry => contextEntry.context.cluster === clusterEntry.name );
25
- // Collect only cluster servers that are used in exactly one context, to clearly identify the context to be used
26
- if (contextEntries.length === 1) {
27
- serverToContext[clusterEntry.cluster.server] = contextEntries[0];
28
- }
29
- }
30
-
31
- return {
32
- namespace: currentContext.namespace || 'default',
33
- context: currentContextEntry,
34
- cluster,
35
- serverToContext
36
- }
37
- });
38
- }
39
-
40
- async context({cluster, namespace}) {
41
- const config = await this.config();
42
- let contextEntry;
43
-
44
- if (cluster && cluster !== config.cluster.server) {
45
- contextEntry = config.serverToContext[cluster] || throwError(`Cluster ${bold(cluster)} not found in kubectl configuration`);
46
- } else {
47
- contextEntry = config.context;
48
- }
49
-
50
- return {
51
- context: contextEntry.name,
52
- cluster: cluster || config.cluster.server,
53
- namespace: namespace || contextEntry.context.namespace || 'default'
54
- };
55
- }
56
-
57
- async get(options) {
58
- const {context, namespace, kind, name} = options;
59
- try {
60
- return JSON.parse(execSync(`kubectl --output json --context ${context} --namespace ${namespace} get ${kind} ${name}`).toString());
61
- }
62
- catch (error) {
63
- if (error.status === 1) return null
64
- else throw error
65
- }
66
- }
67
- }
68
-
69
- function once(func) {
70
- let result;
71
- return function(...args) {
72
- if (!result) result = func(...args);
73
- return result;
74
- }
75
- }
76
-
77
- function throwError(msg = 'Internal Error') {
78
- throw new Error(msg);
79
- }
80
-
81
- module.exports = KubernetesApiAccessor;
@@ -1,89 +0,0 @@
1
- const bindingResolver = require('./bindingResolver')
2
- const { logger } = require('./bindingUtil')
3
- const cds = require('../cds')
4
- const DEBUG = cds.log('cli')._debug // REVISIT: This loads cds.env too early!
5
-
6
- class BindingManager {
7
- constructor(options = {}) {
8
- this.cache = {}
9
- this.bindingsStr = ''
10
- this.options = options
11
- logger.log = DEBUG || !options.silent ? console.log : () => { }
12
- }
13
-
14
- getBindings() {
15
- const bindings = bindingResolver.getUnresolvedBindings(this.options)
16
- return bindings
17
- }
18
-
19
- async resolve(bindings) {
20
- if (!bindings) {
21
- bindings = this.getBindings()
22
- this.bindingsStr = JSON.stringify(bindings)
23
- }
24
-
25
- return await bindingResolver.resolveBindings({ ...this.options, bindings, cache: this.cache })
26
- }
27
-
28
- async bindingEnv(bindings) {
29
- if (!bindings) bindings = await this.resolve()
30
- if (bindings) {
31
- const VCAP_SERVICES = JSON.stringify(BindingManager.toVcapServices(bindings))
32
- return { VCAP_SERVICES }
33
- } else {
34
- return undefined
35
- }
36
- }
37
-
38
- async update({ onBeforeUpdate, onAfterUpdate } = {}) {
39
- const oldBindingsStr = this.bindingsStr
40
- const bindings = this.getBindings()
41
- const bindingsStr = JSON.stringify(bindings)
42
- this.bindingsStr = bindingsStr
43
-
44
- if (this.bindingsStr === oldBindingsStr) return // No change
45
- if (onBeforeUpdate) await onBeforeUpdate()
46
-
47
- try {
48
- if (this.pendingUpdate) await this.pendingUpdate
49
- } catch (error) {
50
- // ignore
51
- }
52
- this.pendingUpdate = undefined
53
-
54
- if (this.bindingsStr !== bindingsStr) return // Next update in progress
55
-
56
- let resolvedBindings
57
- try {
58
- this.pendingUpdate = this.resolve(bindings)
59
- resolvedBindings = await this.pendingUpdate
60
- } catch (error) {
61
- console.error(error.message)
62
- return
63
- }
64
-
65
- if (this.bindingsStr !== bindingsStr) return // Next update in progress
66
-
67
- const env = Object.assign({ VCAP_SERVICES: '{}' }, await this.bindingEnv(resolvedBindings));
68
- if (onAfterUpdate) onAfterUpdate({ bindings: resolvedBindings, env })
69
- }
70
-
71
- static toVcapServices(bindings) {
72
- const services = {}
73
-
74
- for (const name in bindings) {
75
- const binding = bindings[name]
76
- const vcap = binding.binding.vcap || {}
77
- const type = vcap.type || vcap.label
78
- const serviceEntries = services[type] = services[type] || []
79
-
80
- // setting the 'name' property is important to make CAP match the CDS service to the VCAP service
81
- // it is also added to the 'vcap' property by 'cds bind'
82
- serviceEntries.push({ ...vcap, name, credentials: binding.credentials })
83
- }
84
-
85
- return services
86
- }
87
- }
88
-
89
- module.exports = BindingManager
@@ -1,54 +0,0 @@
1
- const cds = require('../cds');
2
- const path = require('path');
3
- const { platformText, bindingText, logger } = require('./bindingUtil');
4
- const { bold } = require('../util/term');
5
-
6
- class BindingResolver {
7
- getUnresolvedBindings({ cwd = process.cwd(), env } = {}) {
8
- if (!env) {
9
- env = cds.env.for('cds', path.resolve(cwd)) // REVISIT: This might load cds.env too early!
10
- }
11
- const bindings = {}
12
- const requires = env.requires || {}
13
- for (const name in requires) {
14
- const service = requires[name]
15
- if (service && service.binding && !service.binding.resolved) {
16
- bindings[name] = { ...service.binding, kind: service.kind }
17
- }
18
- }
19
- return bindings
20
- }
21
-
22
- async resolveBindings({ bindings, cwd = process.cwd(), env, cache = {} }) {
23
- bindings = bindings || this.getUnresolvedBindings({ cwd, env })
24
- if (Object.keys(bindings).length === 0) return undefined
25
- logger.log(`resolving cloud service bindings...`)
26
-
27
- const resolvedBindings = {}
28
-
29
- // run in parallel
30
- await Promise.all(Object.keys(bindings).map(async name => {
31
- const binding = bindings[name]
32
- const cacheKey = JSON.stringify(binding)
33
- let resolvedBinding
34
- if (!cache[cacheKey]) {
35
- resolvedBinding = cache[cacheKey] = await this.resolveBinding(name, binding)
36
- logger.log(`bound ${bold(name)} to ${platformText(binding)} ${bindingText(binding)}`)
37
- } else {
38
- resolvedBinding = cache[cacheKey]
39
- }
40
- resolvedBindings[name] = resolvedBinding
41
- }));
42
- return Object.keys(resolvedBindings).length > 0 ? resolvedBindings : undefined
43
- }
44
-
45
- resolveBinding(name, binding) {
46
- switch (binding.type) {
47
- case 'cf': return require('./cfKeyProvider').resolve(name, binding)
48
- case 'k8s': return require('./kubernetesCredentialsProvider').resolve(name, binding)
49
- default: throw new Error(`Unsupported binding type ${bold(binding.type)} for service ${bold(name)}.`)
50
- }
51
- }
52
- }
53
-
54
- module.exports = new BindingResolver()
@@ -1,129 +0,0 @@
1
- const { bold } = require('../util/term');
2
-
3
- const KindToRequiresNameMap = {
4
- xsuaa: 'auth', // REVISIT: remove with ^8
5
- 'xsuaa-auth': 'auth',
6
- 'ias-auth': 'auth',
7
- 'hana-cloud': 'db',
8
- hana: 'db',
9
- 'hana-mt': 'db', // For compatibility only
10
- 'sql-mt': 'db', // For compatibility only
11
- destinations: 'destinations',
12
- connectivity: 'connectivity',
13
- 'audit-log': 'auditlog',
14
- 'audit-log-to-restv2': 'auditlog',
15
- 'enterprise-messaging': 'messaging',
16
- 'enterprise-messaging-amqp': 'messaging',
17
- 'enterprise-messaging-http': 'messaging',
18
- 'enterprise-messaging-shared': 'messaging',
19
- 'redis-messaging': 'messaging',
20
- 'multitenancy': 'multitenancy'
21
- }
22
-
23
- const PreferredKinds = {
24
- multitenancy: 1, 'hana-cloud': 1, xsuaa: 1, 'xsuaa-auth': 1, 'ias-auth': 1, 'saas-registry': 1
25
- };
26
-
27
- const PLATFORM_TYPES = {
28
- 'cf': 'Cloud Foundry',
29
- 'k8s': 'Kubernetes'
30
- }
31
-
32
- class BindingUtil {
33
- static getRequiresNameFromKind(service, kind) {
34
- const requiresName = KindToRequiresNameMap[kind];
35
- if (!requiresName) throw new Error(`Unknown CDS service name for service ${bold(service)}. Please specify as argument for ${bold('cds bind')}.`)
36
- return requiresName;
37
- }
38
-
39
- /**
40
- * Determine kind value for services based on VCAP binding
41
- * information in the configuration.
42
- */
43
- static determineKinds(services) {
44
- const vcapServices = {}
45
-
46
- // Build VCAP_SERVICES
47
- for (const service of services) {
48
- service.kindCandidates = []
49
-
50
- const { vcap = {} } = service.binding || {};
51
- let { label, type } = vcap;
52
- type = type || label;
53
- if (!type) continue;
54
-
55
- if (!vcapServices[type]) vcapServices[type] = [];
56
- vcapServices[type].push({ credentials: { dummy: 'dummy' }, ...vcap, service });
57
- }
58
-
59
- // Auto configure services based on VCAP_SERVICES
60
-
61
- const cds = require('../cds');
62
- const env = cds.env.for('cds', process.cwd()); // REVISIT: This might load cds.env too early!
63
-
64
- if (!env._find_credentials_for_required_service) {
65
- throw new Error(`Please provide a service kind or update @sap/cds version to use the kind detection.`);
66
- }
67
-
68
- const requires = env.requires.kinds || {};
69
- for (const [kind, service] of Object.entries(requires)) {
70
- const vcapService = env._find_credentials_for_required_service(kind, service, vcapServices);
71
- if (!vcapService) continue;
72
- const isUniqueKind = !Object.values(requires).some(otherService =>
73
- otherService !== service && otherService.kind === kind
74
- )
75
- if (isUniqueKind) vcapService.service.kindCandidates.push(kind);
76
- }
77
-
78
- // Check if one "kind" per service was found
79
- for (const service of services) {
80
- const preferredKind = service.kindCandidates.find(kind => kind in PreferredKinds);
81
- if (preferredKind) {
82
- service.kind = preferredKind;
83
- } else if (service.kindCandidates.length === 1) {
84
- service.kind = service.kindCandidates[0];
85
- }
86
- delete service.kindCandidates;
87
- }
88
- }
89
-
90
- static async checkIsJavaProject(projectPath) {
91
- const { constants, promises: fsp } = require('fs');
92
- const path = require('path');
93
- const pomXmlPath = path.join(projectPath, 'pom.xml');
94
- try {
95
- await fsp.access(pomXmlPath, constants.F_OK);
96
- return true;
97
- } catch (err) {
98
- return false;
99
- }
100
- }
101
-
102
- static platformText(binding) {
103
- if (!PLATFORM_TYPES[binding.type]) throw new Error(`Unexpected binding type ${bold(binding.type)}.`);
104
- return PLATFORM_TYPES[binding.type]
105
- }
106
-
107
- static bindingText(binding) {
108
- switch (binding.type) {
109
- case 'cf':
110
- if (binding.key) {
111
- return `managed service ${bold(binding.instance + ':' + binding.key)}`
112
- } else {
113
- return `user provided service ${bold(binding.instance)}`
114
- }
115
- case 'k8s':
116
- if (binding.name) {
117
- return `service binding ${bold(binding.name)}`
118
- } else {
119
- return `secret ${bold(binding.secret)}`
120
- }
121
- default:
122
- throw new Error('Internal Error');
123
- }
124
- }
125
-
126
- static logger = { log: console.log }
127
- }
128
-
129
- module.exports = BindingUtil