@sap/cds-dk 6.3.1 → 6.4.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.
- package/CHANGELOG.md +37 -5
- package/bin/cds.js +2 -0
- package/bin/compile/index.js +2 -1
- package/bin/deploy/index.js +2 -2
- package/bin/deploy/to-sqlite.js +17 -15
- package/bin/help.js +7 -4
- package/bin/init.js +1 -1
- package/bin/login.js +3 -4
- package/bin/migrate.js +33 -0
- package/bin/pull.js +4 -4
- package/bin/push.js +1 -1
- package/bin/subscribe.js +58 -66
- package/bin/unsubscribe.js +67 -0
- package/bin/watch.js +4 -3
- package/lib/bind/bindingUtil.js +2 -0
- package/lib/bind/cfKeyProvider.js +5 -1
- package/lib/client/activate.js +3 -3
- package/lib/client/auth_manager.js +2 -2
- package/lib/client/base_command.js +7 -6
- package/lib/client/extend.js +2 -2
- package/lib/client/helper/errors.js +8 -2
- package/lib/client/helper/logging.js +13 -11
- package/lib/client/params.js +3 -0
- package/lib/client/pull.js +1 -1
- package/lib/client/push.js +4 -4
- package/lib/client/settings_manager.js +13 -6
- package/lib/client/subscription.js +81 -0
- package/lib/compile/to-xsuaa.js +25 -19
- package/lib/import/odata/metadataconverter/MetadataConverter.js +3 -3
- package/lib/import/odata/v2parser.js +37 -24
- package/lib/import/odata/v4parser.js +106 -37
- package/lib/init/constants.js +1 -1
- package/lib/init/index.js +2 -2
- package/lib/init/template/_merging/registry-mta.js +0 -3
- package/lib/init/template/approuter/files/approuter-configmap.yaml +10 -0
- package/lib/init/template/approuter/files/approuter-mtxs-configmap.yaml +15 -0
- package/lib/init/template/approuter/files/chart.yaml +4 -0
- package/lib/init/template/approuter/files/package.json +1 -1
- package/lib/init/template/approuter/files/values.yaml.hbs +31 -0
- package/lib/init/template/approuter/index.js +60 -12
- package/lib/init/template/auditlog/index.js +16 -8
- package/lib/init/template/cf-manifest/index.js +3 -3
- package/lib/init/template/connectivity/index.js +19 -10
- package/lib/init/template/destinations/index.js +23 -7
- package/lib/init/template/enterprise-messaging/files/cds.package.json +1 -2
- package/lib/init/template/enterprise-messaging/files/cds.profile.package.json.hbs +1 -2
- package/lib/init/template/enterprise-messaging/files/cdsrc.json +1 -2
- package/lib/init/template/enterprise-messaging/files/cdsrc.json.hbs +1 -2
- package/lib/init/template/enterprise-messaging/files/event-mesh.json.hbs +31 -0
- package/lib/init/template/enterprise-messaging/files/mta.yaml.hbs +1 -0
- package/lib/init/template/enterprise-messaging/index.js +26 -13
- package/lib/init/template/extensibility/index.js +19 -10
- package/lib/init/template/hana/files/mta.yaml.hbs +0 -4
- package/lib/init/template/hana/index.js +58 -22
- package/lib/init/template/helm/chart/templates/NOTES.txt +4 -3
- package/lib/init/template/helm/chart/templates/_deployment_helpers.tpl +25 -2
- package/lib/init/template/helm/chart/values.root.schema.json +5 -0
- package/lib/init/template/helm/chart/values.schema.json +27 -0
- package/lib/init/template/helm/files/values.yaml.hbs +1 -1
- package/lib/init/template/helm/index.js +25 -23
- package/lib/init/template/helm/subchart/templates/_helpers.tpl +29 -0
- package/lib/init/template/helm/subchart/templates/api-rule.yaml +5 -5
- package/lib/init/template/helm/subchart/templates/deployment.yaml +12 -9
- package/lib/init/template/helm/subchart/values.md +258 -88
- package/lib/init/template/helm/subchart/values.schema.json +96 -13
- package/lib/init/template/helm/subchart/values.yaml +6 -2
- package/lib/init/template/html5-repo/index.js +28 -11
- package/lib/init/template/java/index.js +5 -5
- package/lib/init/template/kibana-logging/index.js +5 -4
- package/lib/init/template/mta/index.js +2 -2
- package/lib/init/template/mtx/index.js +1 -1
- package/lib/init/template/multitenancy/files/chart.yaml +4 -0
- package/lib/init/template/multitenancy/files/java/mtxs-configmap.yaml +20 -0
- package/lib/init/template/multitenancy/files/java/package.json +6 -9
- package/lib/init/template/multitenancy/files/mtxs-configmap.yaml +15 -0
- package/lib/init/template/multitenancy/files/saas-registry.yaml +17 -19
- package/lib/init/template/multitenancy/files/values.yaml.hbs +47 -0
- package/lib/init/template/multitenancy/files/xs-security.json.hbs +0 -7
- package/lib/init/template/multitenancy/index.js +83 -37
- package/lib/init/template/nodejs/files/.eslintrc +26 -0
- package/lib/init/template/nodejs/files/package.json.hbs +0 -28
- package/lib/init/template/nodejs/index.js +7 -10
- package/lib/init/template/pipeline/index.js +4 -4
- package/lib/init/template/samples/index.js +5 -5
- package/lib/init/template/templateBase.js +1 -4
- package/lib/init/template/toggles/index.js +5 -5
- package/lib/init/template/xsuaa/files/values.yaml.hbs +21 -0
- package/lib/init/template/xsuaa/index.js +34 -24
- package/lib/init/util/md5Tracking.js +113 -0
- package/lib/init/util/merge.js +19 -2
- package/lib/init/util/projectReader.js +15 -12
- package/npm-shrinkwrap.json +70 -572
- package/package.json +3 -3
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
const { join } = require('path')
|
|
1
2
|
const cds = require('../../../cds')
|
|
2
|
-
const {
|
|
3
|
+
const { copy, exists } = cds.utils
|
|
3
4
|
const ProjectReader = require('../../util/projectReader')
|
|
4
5
|
const { mergeJSON, mergeYAML, sortDependencies } = require('../../util/merge')
|
|
6
|
+
const { copyAndTrack, parseMd5File, writeMd5File } = require('../../util/md5Tracking')
|
|
5
7
|
const {
|
|
6
8
|
srvNode, srvJava, // Server
|
|
7
9
|
mtxSidecar, // Additional Modules
|
|
@@ -19,27 +21,27 @@ module.exports = class MultitenancyTemplate extends require('../templateBase') {
|
|
|
19
21
|
// REVISIT: Check if this can be simplified
|
|
20
22
|
return options?.add?.has('mtx') || options?.add?.has('multitenancy') ||
|
|
21
23
|
!!env.requires?.multitenancy || !!env.requires?.db?.multiTenant ||
|
|
22
|
-
this.isJava && exists(
|
|
24
|
+
this.isJava && exists(join(projectPath, 'mtx', 'sidecar')) || false
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
async run() {
|
|
26
28
|
const projectDescriptor = await this.projectReader.read(this.options)
|
|
27
29
|
const { for: forProfile, isNodejs, isJava } = projectDescriptor.cap
|
|
28
30
|
if (isNodejs) {
|
|
29
|
-
const packageJSONPath =
|
|
31
|
+
const packageJSONPath = join(this.projectPath, 'package.json')
|
|
30
32
|
const cdsTemplateFile = forProfile ? 'cds.package.json.hbs' : 'cds.package.json'
|
|
31
|
-
await mergeJSON(packageJSONPath,
|
|
32
|
-
await mergeJSON(packageJSONPath,
|
|
33
|
+
await mergeJSON(packageJSONPath, join(__dirname, 'files', cdsTemplateFile), projectDescriptor)
|
|
34
|
+
await mergeJSON(packageJSONPath, join(__dirname, 'files', 'dependencies.package.json'))
|
|
33
35
|
await sortDependencies(packageJSONPath)
|
|
34
36
|
} else if (isJava) {
|
|
35
|
-
const cdsrcJSONPath =
|
|
36
|
-
await mergeJSON(cdsrcJSONPath,
|
|
37
|
-
await copy(
|
|
37
|
+
const cdsrcJSONPath = join(this.projectPath, '.cdsrc.json')
|
|
38
|
+
await mergeJSON(cdsrcJSONPath, join(__dirname, 'files', 'java', '.cdsrc.json'))
|
|
39
|
+
await copy(join(__dirname, 'files', 'java', 'package.json'), join(this.projectPath, 'mtx', 'sidecar', 'package.json'))
|
|
38
40
|
}
|
|
39
41
|
await this.runDependentMerging()
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
async runDependentMerging() {
|
|
44
|
+
async runDependentMerging(context = {}) {
|
|
43
45
|
const projectDescriptor = await this.projectReader.read()
|
|
44
46
|
const { isNodejs, isJava, hasMta, hasHelm, hasApprouter, hasXsuaa, hasHana } = projectDescriptor.cap
|
|
45
47
|
|
|
@@ -66,67 +68,109 @@ module.exports = class MultitenancyTemplate extends require('../templateBase') {
|
|
|
66
68
|
}
|
|
67
69
|
if (hasHana) {
|
|
68
70
|
relationships.push({
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
insert: [serviceManager, 'name'],
|
|
72
|
+
into: [mtxSidecar, 'requires', 'name'],
|
|
71
73
|
})
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
|
|
75
|
-
const templateMtaPath =
|
|
76
|
-
const mtaPath =
|
|
77
|
+
const templateMtaPath = join(__dirname, `files`, `mta.yaml.hbs`)
|
|
78
|
+
const mtaPath = join(this.projectPath, 'mta.yaml')
|
|
77
79
|
const mergingRules = { additions, overwrites, relationships }
|
|
78
80
|
await mergeYAML(mtaPath, templateMtaPath, projectDescriptor, mergingRules)
|
|
79
81
|
}
|
|
80
82
|
|
|
83
|
+
let isIndependentCommand = false
|
|
81
84
|
if (hasHelm) {
|
|
85
|
+
//in case facet is being added to the already exisiting charts folder
|
|
86
|
+
if (Object.keys(context).length == 0) {
|
|
87
|
+
isIndependentCommand = true
|
|
88
|
+
context.projectPath = this.projectPath
|
|
89
|
+
context.oldTrackingData = context.newTrackingData = await parseMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'))
|
|
90
|
+
}
|
|
91
|
+
|
|
82
92
|
await mergeYAML(
|
|
83
|
-
|
|
93
|
+
join(this.projectPath, 'chart', 'values.yaml'),
|
|
94
|
+
join(__dirname, 'files', 'values.yaml.hbs'),
|
|
95
|
+
projectDescriptor
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
await mergeYAML(
|
|
99
|
+
join(this.projectPath, 'chart', 'values.yaml'),
|
|
84
100
|
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
101
|
+
srv: {
|
|
102
|
+
envFrom: [
|
|
103
|
+
{
|
|
104
|
+
configMapRef: {
|
|
105
|
+
name: "{{ .Release.Name }}-mtxs-configmap",
|
|
106
|
+
tpl: true
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
]
|
|
88
110
|
}
|
|
89
111
|
},
|
|
90
|
-
|
|
112
|
+
projectDescriptor
|
|
91
113
|
)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
114
|
+
|
|
115
|
+
if (isJava) {
|
|
116
|
+
await mergeYAML(
|
|
117
|
+
join(this.projectPath, 'chart', 'Chart.yaml'),
|
|
118
|
+
join(__dirname, 'files', 'chart.yaml'),
|
|
119
|
+
projectDescriptor,
|
|
120
|
+
{
|
|
121
|
+
additions: [{
|
|
122
|
+
ref: `web-application-sidecar`,
|
|
123
|
+
in: `dependencies`,
|
|
124
|
+
where: [{
|
|
125
|
+
property: 'alias',
|
|
126
|
+
isEqualTo: 'sidecar'
|
|
127
|
+
}]
|
|
128
|
+
}]
|
|
129
|
+
}
|
|
96
130
|
)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const mtxsConfigmapPath = isNodejs
|
|
134
|
+
? join(__dirname, 'files', 'mtxs-configmap.yaml')
|
|
135
|
+
: join(__dirname, 'files', 'java', 'mtxs-configmap.yaml');
|
|
136
|
+
|
|
137
|
+
// add mtxs configmap
|
|
138
|
+
await copyAndTrack(
|
|
139
|
+
mtxsConfigmapPath,
|
|
140
|
+
join(this.projectPath, 'chart', 'templates', 'mtxs-configmap.yaml'),
|
|
141
|
+
context
|
|
101
142
|
)
|
|
143
|
+
|
|
144
|
+
await copyAndTrack(
|
|
145
|
+
join(__dirname, 'files', 'saas-registry.yaml'),
|
|
146
|
+
join(this.projectPath, 'chart', 'templates', 'saas-registry.yaml'),
|
|
147
|
+
context
|
|
148
|
+
)
|
|
149
|
+
if (isIndependentCommand) await writeMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'), context.newTrackingData)
|
|
102
150
|
}
|
|
103
151
|
|
|
104
152
|
if (hasApprouter) {
|
|
105
153
|
const ApprouterTemplate = require(`../approuter`)
|
|
106
154
|
const template = new ApprouterTemplate(this.projectPath, this.generator)
|
|
107
|
-
await template.runDependentMerging()
|
|
155
|
+
await template.runDependentMerging(context)
|
|
108
156
|
}
|
|
109
157
|
|
|
110
158
|
if (hasHana) {
|
|
111
159
|
const HanaTemplate = require(`../hana`)
|
|
112
160
|
const template = new HanaTemplate(this.projectPath, this.generator)
|
|
113
|
-
await template.runDependentMerging()
|
|
161
|
+
await template.runDependentMerging(context)
|
|
114
162
|
}
|
|
115
163
|
|
|
116
164
|
if (hasXsuaa) {
|
|
117
165
|
await mergeJSON(
|
|
118
|
-
|
|
119
|
-
|
|
166
|
+
join(this.projectPath, 'xs-security.json'),
|
|
167
|
+
join(__dirname, 'files', 'xs-security.json.hbs'),
|
|
120
168
|
projectDescriptor,
|
|
121
169
|
{
|
|
122
170
|
additions: [{
|
|
123
171
|
ref: 'scope-mtcallback',
|
|
124
172
|
in: 'scopes',
|
|
125
173
|
where: [{ property: 'name', isEqualTo: '$XSAPPNAME.mtcallback' }],
|
|
126
|
-
}, {
|
|
127
|
-
ref: 'scope-subscriber',
|
|
128
|
-
in: 'scopes',
|
|
129
|
-
where: [{ property: 'name', isEqualTo: '$XSAPPNAME.cds.Subscriber' }],
|
|
130
174
|
}]
|
|
131
175
|
}
|
|
132
176
|
)
|
|
@@ -134,10 +178,12 @@ module.exports = class MultitenancyTemplate extends require('../templateBase') {
|
|
|
134
178
|
|
|
135
179
|
if (hasXsuaa && hasHelm) {
|
|
136
180
|
// REVISIT: Shared xs-security.json location for Helm and MTA?
|
|
137
|
-
await
|
|
138
|
-
|
|
139
|
-
|
|
181
|
+
await copyAndTrack(
|
|
182
|
+
join(this.projectPath, 'xs-security.json'),
|
|
183
|
+
join(this.projectPath, 'chart', 'xs-security.json'),
|
|
184
|
+
context
|
|
140
185
|
)
|
|
186
|
+
if (isIndependentCommand) await writeMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'), context.newTrackingData)
|
|
141
187
|
}
|
|
142
188
|
}
|
|
143
189
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "eslint:recommended",
|
|
3
|
+
"env": {
|
|
4
|
+
"es2022": true,
|
|
5
|
+
"node": true,
|
|
6
|
+
"jest": true,
|
|
7
|
+
"mocha": true
|
|
8
|
+
},
|
|
9
|
+
"globals": {
|
|
10
|
+
"SELECT": true,
|
|
11
|
+
"INSERT": true,
|
|
12
|
+
"UPSERT": true,
|
|
13
|
+
"UPDATE": true,
|
|
14
|
+
"DELETE": true,
|
|
15
|
+
"CREATE": true,
|
|
16
|
+
"DROP": true,
|
|
17
|
+
"CDL": true,
|
|
18
|
+
"CQL": true,
|
|
19
|
+
"CXL": true,
|
|
20
|
+
"cds": true
|
|
21
|
+
},
|
|
22
|
+
"rules": {
|
|
23
|
+
"no-console": "off",
|
|
24
|
+
"require-atomic-updates": "off"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -14,33 +14,5 @@
|
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"start": "cds run"
|
|
17
|
-
},
|
|
18
|
-
"engines": {
|
|
19
|
-
"node": "^16.15"
|
|
20
|
-
},
|
|
21
|
-
"eslintConfig": {
|
|
22
|
-
"extends": "eslint:recommended",
|
|
23
|
-
"env": {
|
|
24
|
-
"es2020": true,
|
|
25
|
-
"node": true,
|
|
26
|
-
"jest": true,
|
|
27
|
-
"mocha": true
|
|
28
|
-
},
|
|
29
|
-
"globals": {
|
|
30
|
-
"SELECT": true,
|
|
31
|
-
"INSERT": true,
|
|
32
|
-
"UPDATE": true,
|
|
33
|
-
"DELETE": true,
|
|
34
|
-
"CREATE": true,
|
|
35
|
-
"DROP": true,
|
|
36
|
-
"CDL": true,
|
|
37
|
-
"CQL": true,
|
|
38
|
-
"CXL": true,
|
|
39
|
-
"cds": true
|
|
40
|
-
},
|
|
41
|
-
"rules": {
|
|
42
|
-
"no-console": "off",
|
|
43
|
-
"require-atomic-updates": "off"
|
|
44
|
-
}
|
|
45
17
|
}
|
|
46
18
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { join, relative } = require('path');
|
|
2
2
|
const { mkdirp } = require('../../../cds').utils
|
|
3
3
|
const { COMMAND_ADD, OPTION_JAVA, OPTION_NODEJS, URLS } = require('../../constants')
|
|
4
4
|
const { copyFiles } = require('../../util/templateUtil')
|
|
@@ -28,19 +28,16 @@ module.exports = class NodeJSTemplate extends require('../templateBase') {
|
|
|
28
28
|
|
|
29
29
|
async run() {
|
|
30
30
|
const env = await this.getEnv();
|
|
31
|
+
const { projectPath, projectName } = this
|
|
32
|
+
await copyFiles(join(__dirname, 'files'), projectPath, { projectName }, this.options.force)
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
await copyFiles(path.join(__dirname, 'files'), this.projectPath, values, this.options.force)
|
|
36
|
-
|
|
37
|
-
await mkdirp(this.projectPath, env.folders.db);
|
|
38
|
-
await mkdirp(this.projectPath, env.folders.srv);
|
|
39
|
-
await mkdirp(this.projectPath, env.folders.app);
|
|
34
|
+
await mkdirp(projectPath, env.folders.db);
|
|
35
|
+
await mkdirp(projectPath, env.folders.srv);
|
|
36
|
+
await mkdirp(projectPath, env.folders.app);
|
|
40
37
|
}
|
|
41
38
|
|
|
42
39
|
async finalize() {
|
|
43
|
-
const relativeProjectPath =
|
|
40
|
+
const relativeProjectPath = relative(this.cwd, this.projectPath);
|
|
44
41
|
if (relativeProjectPath && relativeProjectPath !== '.') {
|
|
45
42
|
LOG.info(`Continue with 'cd ${relativeProjectPath}'`);
|
|
46
43
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { join } = require('path');
|
|
2
2
|
const { exists } = require('../../../cds').utils
|
|
3
3
|
const { copyFiles } = require('../../util/templateUtil')
|
|
4
4
|
const { URLS } = require('../../constants')
|
|
@@ -14,8 +14,8 @@ module.exports = class PipelineTemplate extends require('../templateBase') {
|
|
|
14
14
|
return true;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
if (exists(
|
|
18
|
-
exists(
|
|
17
|
+
if (exists(join(this.projectPath, 'Jenkinsfile')) ||
|
|
18
|
+
exists(join(this.projectPath, '.pipeline/config.yml'))) {
|
|
19
19
|
throw new Error(`Pipeline support file exists. Use --force to overwrite.`);
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -23,7 +23,7 @@ module.exports = class PipelineTemplate extends require('../templateBase') {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
async run() {
|
|
26
|
-
await copyFiles(
|
|
26
|
+
await copyFiles(join(__dirname, 'files'), this.projectPath, {}, this.options.force);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
async finalize() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { join } = require('path');
|
|
2
2
|
const { copyFiles } = require('../../util/templateUtil')
|
|
3
3
|
const commandUtil = require('../../util/commandUtil');
|
|
4
4
|
const mvnArchetypes = require('../../util/mvnArchetypeUtil');
|
|
@@ -50,11 +50,11 @@ module.exports = class SamplesTemplate extends require('../templateBase') {
|
|
|
50
50
|
|
|
51
51
|
async _addNodejsSamples() {
|
|
52
52
|
const folders = (await this.getEnv()).folders;
|
|
53
|
-
const dbFolder =
|
|
54
|
-
await copyFiles(
|
|
53
|
+
const dbFolder = join(this.projectPath, folders.db);
|
|
54
|
+
await copyFiles(join(__dirname, 'files', 'nodejs', 'db'), dbFolder, {}, this.options.force);
|
|
55
55
|
|
|
56
|
-
const srvFolder =
|
|
57
|
-
await copyFiles(
|
|
56
|
+
const srvFolder = join(this.projectPath, folders.srv);
|
|
57
|
+
await copyFiles(join(__dirname, 'files', 'nodejs', 'srv'), srvFolder, {
|
|
58
58
|
dbFolder: folders.db.replace(/[\\/]+$/, '')
|
|
59
59
|
}, this.options.force);
|
|
60
60
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
const cds = require('../../cds');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
const TemplateUtil = require('../util/templateUtil');
|
|
5
|
-
|
|
6
4
|
const { PROJECT_TYPE } = require('../constants');
|
|
7
5
|
const { exists } = require('../../cds').utils;
|
|
8
6
|
|
|
@@ -27,10 +25,9 @@ module.exports = class TemplateBase {
|
|
|
27
25
|
|
|
28
26
|
/**
|
|
29
27
|
* Returns an array of required templates. These templates will also be added if not already included.
|
|
30
|
-
* Declared async to allow complex calculation of the dependencies.
|
|
31
28
|
* @returns an array with depending templates, might be empty or null
|
|
32
29
|
*/
|
|
33
|
-
|
|
30
|
+
getDependencies() {
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { join } = require('path')
|
|
2
2
|
const ProjectReader = require('../../util/projectReader')
|
|
3
3
|
const { mergeJSON, sortDependencies } = require('../../util/merge')
|
|
4
4
|
|
|
@@ -16,13 +16,13 @@ module.exports = class TogglesTemplate extends require('../templateBase') {
|
|
|
16
16
|
const projectDescriptor = await this.projectReader.read(this.options)
|
|
17
17
|
const { for: forProfile, isNodejs, isJava } = projectDescriptor.cap
|
|
18
18
|
if (isNodejs) {
|
|
19
|
-
const packageJSONPath =
|
|
19
|
+
const packageJSONPath = join(this.projectPath, 'package.json')
|
|
20
20
|
const cdsTemplateFile = forProfile ? 'cds.package.json.hbs' : 'cds.package.json'
|
|
21
|
-
await mergeJSON(packageJSONPath,
|
|
21
|
+
await mergeJSON(packageJSONPath, join(__dirname, 'files', cdsTemplateFile), projectDescriptor)
|
|
22
22
|
await sortDependencies(packageJSONPath)
|
|
23
23
|
} else if (isJava) {
|
|
24
|
-
const cdsrcPath =
|
|
25
|
-
const cdsTemplateFile =
|
|
24
|
+
const cdsrcPath = join(this.projectPath, '.cdsrc.json')
|
|
25
|
+
const cdsTemplateFile = join(__dirname, 'files', forProfile ? 'cdsrc.json.hbs' : 'cdsrc.json')
|
|
26
26
|
await mergeJSON(cdsrcPath, cdsTemplateFile, projectDescriptor)
|
|
27
27
|
}
|
|
28
28
|
await this.runDependentMerging()
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
{{#cap.isJava}}
|
|
3
|
+
{{#cap.isMultitenant}}
|
|
4
|
+
sidecar:
|
|
5
|
+
bindings:
|
|
6
|
+
auth:
|
|
7
|
+
serviceInstanceName: xsuaa
|
|
8
|
+
{{/cap.isMultitenant}}
|
|
9
|
+
{{/cap.isJava}}
|
|
10
|
+
{{#cap.hasApprouter}}
|
|
11
|
+
approuter:
|
|
12
|
+
bindings:
|
|
13
|
+
auth:
|
|
14
|
+
serviceInstanceName: xsuaa
|
|
15
|
+
{{/cap.hasApprouter}}
|
|
1
16
|
srv:
|
|
2
17
|
bindings:
|
|
3
18
|
auth:
|
|
@@ -7,4 +22,10 @@ xsuaa:
|
|
|
7
22
|
servicePlanName: application
|
|
8
23
|
parameters:
|
|
9
24
|
xsappname: {{cap.appName}}
|
|
25
|
+
tenant-mode: {{#cap.isMultitenant}}shared{{/cap.isMultitenant}}{{^cap.isMultitenant}}dedicated{{/cap.isMultitenant}}
|
|
26
|
+
{{#cap.hasApprouter}}
|
|
27
|
+
oauth2-configuration:
|
|
28
|
+
redirect-uris:
|
|
29
|
+
- https://*.<your-cluster-domain>/**
|
|
30
|
+
{{/cap.hasApprouter}}
|
|
10
31
|
config: xs-security.json
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
const
|
|
2
|
-
const cds = require('../../../cds')
|
|
3
|
-
const { copy } = cds.utils
|
|
1
|
+
const { join } = require('path')
|
|
4
2
|
const ProjectReader = require('../../util/projectReader')
|
|
5
3
|
const { mergeJSON, mergeYAML } = require('../../util/merge')
|
|
4
|
+
const { copyAndTrack, parseMd5File, writeMd5File } = require('../../util/md5Tracking')
|
|
6
5
|
const { srvNode, srvJava, xsuaa, mtxSidecar } = require('../_merging/registry-mta')
|
|
7
6
|
const { PROJECT_TYPE } = require('../../constants')
|
|
8
7
|
|
|
@@ -18,35 +17,35 @@ module.exports = class XsuaaTemplate extends require('../templateBase') {
|
|
|
18
17
|
|
|
19
18
|
async run() {
|
|
20
19
|
const { projectPath } = this
|
|
21
|
-
const templatePath =
|
|
20
|
+
const templatePath = join(__dirname, 'files')
|
|
22
21
|
const projectDescriptor = await this.projectReader.read(this.options)
|
|
23
22
|
const projectType = await this.getProjectType();
|
|
24
23
|
const { for: forProfile } = projectDescriptor.cap
|
|
25
24
|
|
|
26
25
|
if (projectType === PROJECT_TYPE.java) {
|
|
27
|
-
const cdsrcJSONPath =
|
|
26
|
+
const cdsrcJSONPath = join(projectPath, '.cdsrc.json')
|
|
28
27
|
const cdsTemplateFile = forProfile ? 'cds.cdsrc.json.hbs' : 'cds.cdsrc.json'
|
|
29
|
-
const cdsTemplatePath =
|
|
28
|
+
const cdsTemplatePath = join(templatePath, cdsTemplateFile)
|
|
30
29
|
await mergeJSON(cdsrcJSONPath, cdsTemplatePath, projectDescriptor)
|
|
31
30
|
} else if (projectType === PROJECT_TYPE.nodejs) {
|
|
32
|
-
const packageJSONPath =
|
|
31
|
+
const packageJSONPath = join(projectPath, 'package.json')
|
|
33
32
|
const cdsTemplateFile = forProfile ? 'cds.package.json.hbs' : 'cds.package.json'
|
|
34
|
-
const cdsTemplatePath =
|
|
33
|
+
const cdsTemplatePath = join(templatePath, cdsTemplateFile)
|
|
35
34
|
await mergeJSON(packageJSONPath, cdsTemplatePath, projectDescriptor)
|
|
36
|
-
const dependenciesTemplatePath =
|
|
35
|
+
const dependenciesTemplatePath = join(templatePath, 'dependencies.package.json')
|
|
37
36
|
await mergeJSON(packageJSONPath, dependenciesTemplatePath)
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
await this.runDependentMerging()
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
async runDependentMerging() {
|
|
42
|
+
async runDependentMerging( context = {}) {
|
|
44
43
|
const projectDescriptor = await this.projectReader.read(this.options)
|
|
45
44
|
const { isMultitenant, isExtensible, hasMta, hasHelm, isNodejs, isJava } = projectDescriptor.cap
|
|
46
45
|
|
|
47
46
|
const cds = require('../../../../lib/compile')
|
|
48
47
|
const xsSecurity = await (async () => { try {
|
|
49
|
-
const models = await cds.load(
|
|
48
|
+
const models = await cds.load(join(this.projectPath, cds.env.folders.srv))
|
|
50
49
|
return cds.compile.to.xsuaa(models)
|
|
51
50
|
} catch (error) { /* ignore */ }
|
|
52
51
|
})() || { scopes: [], attributes: [], 'role-templates': [], 'authorities-inheritance': false }
|
|
@@ -58,7 +57,7 @@ module.exports = class XsuaaTemplate extends require('../templateBase') {
|
|
|
58
57
|
isEqualTo: scope.name
|
|
59
58
|
}],
|
|
60
59
|
}))}
|
|
61
|
-
const xsSecurityPath =
|
|
60
|
+
const xsSecurityPath = join(this.projectPath, 'xs-security.json')
|
|
62
61
|
await mergeJSON(xsSecurityPath, xsSecurity, projectDescriptor, mergingSemantics)
|
|
63
62
|
|
|
64
63
|
if (hasMta) {
|
|
@@ -66,7 +65,7 @@ module.exports = class XsuaaTemplate extends require('../templateBase') {
|
|
|
66
65
|
const additions = [srv, xsuaa]
|
|
67
66
|
if (isMultitenant && isJava) additions.push(mtxSidecar)
|
|
68
67
|
|
|
69
|
-
const mtaYAMLPath =
|
|
68
|
+
const mtaYAMLPath = join(this.projectPath, 'mta.yaml')
|
|
70
69
|
const relationships = [{
|
|
71
70
|
insert: [xsuaa, 'name'],
|
|
72
71
|
into: [srv, 'requires', 'name']
|
|
@@ -88,20 +87,30 @@ module.exports = class XsuaaTemplate extends require('../templateBase') {
|
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
if (hasHelm) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
//in case facet is being added to the already exisiting charts folder
|
|
91
|
+
let isIndependentCommand = false;
|
|
92
|
+
if(Object.keys(context).length == 0){
|
|
93
|
+
isIndependentCommand = true;
|
|
94
|
+
context.projectPath = this.projectPath;
|
|
95
|
+
context.oldTrackingData = context.newTrackingData = await parseMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'));
|
|
96
|
+
}
|
|
97
|
+
await copyAndTrack(
|
|
98
|
+
join(__dirname, 'files', 'xsuaa.yaml'),
|
|
99
|
+
join(this.projectPath, 'chart', 'templates', 'xsuaa.yaml'),
|
|
100
|
+
context
|
|
94
101
|
)
|
|
95
102
|
await mergeYAML(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
projectDescriptor
|
|
103
|
+
join(this.projectPath, 'chart', 'values.yaml'),
|
|
104
|
+
join(__dirname, 'files', 'values.yaml.hbs'),
|
|
105
|
+
projectDescriptor
|
|
99
106
|
)
|
|
100
107
|
// REVISIT: Shared xs-security.json location for Helm and MTA?
|
|
101
|
-
await
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
await copyAndTrack(
|
|
109
|
+
join(this.projectPath, 'xs-security.json'),
|
|
110
|
+
join(this.projectPath, 'chart', 'xs-security.json'),
|
|
111
|
+
context
|
|
104
112
|
)
|
|
113
|
+
if(isIndependentCommand) await writeMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'), context.newTrackingData);
|
|
105
114
|
}
|
|
106
115
|
|
|
107
116
|
// Re-applying the merging part of `cds add mtx` because cds.compile.to.xsuaa
|
|
@@ -110,12 +119,13 @@ module.exports = class XsuaaTemplate extends require('../templateBase') {
|
|
|
110
119
|
if (isMultitenant) {
|
|
111
120
|
const MultitenancyTemplate = require(`../multitenancy`)
|
|
112
121
|
const multitenancyTemplate = new MultitenancyTemplate(this.projectPath, this.generator)
|
|
113
|
-
await multitenancyTemplate.runDependentMerging()
|
|
122
|
+
await multitenancyTemplate.runDependentMerging(context)
|
|
114
123
|
}
|
|
124
|
+
|
|
115
125
|
if (isExtensible) {
|
|
116
126
|
const ExtensibilityTemplate = require(`../extensibility`)
|
|
117
127
|
const extensibilityTemplate = new ExtensibilityTemplate(this.projectPath, this.generator)
|
|
118
|
-
await extensibilityTemplate.runDependentMerging()
|
|
128
|
+
await extensibilityTemplate.runDependentMerging(context)
|
|
119
129
|
}
|
|
120
130
|
}
|
|
121
131
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const path = require('path'), { dirname, resolve } = path;
|
|
2
|
+
const { mkdirp, isdir } = require('../../cds').utils;
|
|
3
|
+
const cds = require('../../cds');
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const crypto = require('crypto');
|
|
7
|
+
const LOG = cds.log('k8s');
|
|
8
|
+
const os = require('os');
|
|
9
|
+
|
|
10
|
+
async function copyAndTrack(source, dest, context = {}, force = false) {
|
|
11
|
+
const sourcePath = resolve(cds.root, source);
|
|
12
|
+
const destPath = resolve(cds.root, dest);
|
|
13
|
+
//if (fs.promises.cp) return fs.promises.cp(src, dst, { recursive: true });
|
|
14
|
+
await mkdirp(dirname(destPath));
|
|
15
|
+
if (isdir(sourcePath)) {
|
|
16
|
+
const entries = await fs.promises.readdir(sourcePath);
|
|
17
|
+
return Promise.all(entries.map(async each => {
|
|
18
|
+
const subSourcePath = path.join(sourcePath, each);
|
|
19
|
+
const subDestPath = path.join(destPath, each);
|
|
20
|
+
return copyAndTrack(subSourcePath, subDestPath, context);
|
|
21
|
+
}))
|
|
22
|
+
} else {
|
|
23
|
+
let data = await _readFileIfExists(sourcePath, 'utf-8');
|
|
24
|
+
if (!force && await _isChartFileModified(destPath, context)) {
|
|
25
|
+
LOG.warn("Chart file " + destPath + " has been modified and will not be updated.");
|
|
26
|
+
} else {
|
|
27
|
+
_track(destPath, data, context);
|
|
28
|
+
return fs.promises.copyFile(sourcePath, destPath);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Takes path of md5 file as an argument and returns a JSON object containing hashes of files stored in MD5 file.
|
|
36
|
+
* @param {String} path
|
|
37
|
+
* @returns {Promise<JSON>}
|
|
38
|
+
*/
|
|
39
|
+
async function parseMd5File(path) {
|
|
40
|
+
let md5Hashes = {};
|
|
41
|
+
const md5FileContent = await _readFileIfExists(path);
|
|
42
|
+
if (md5FileContent == undefined) return md5Hashes;
|
|
43
|
+
let md5Checksums = md5FileContent.toString().split(os.EOL)
|
|
44
|
+
md5Checksums.forEach((checksum) => {
|
|
45
|
+
checksum = checksum.split(" ")
|
|
46
|
+
md5Hashes[checksum[1]] = checksum[0];
|
|
47
|
+
})
|
|
48
|
+
return md5Hashes;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Takes json object containing key as filename and value as MD5 hash and generates a md5sum format file.
|
|
53
|
+
* @param {String} path
|
|
54
|
+
* @param {Promise<JSON>} data
|
|
55
|
+
*/
|
|
56
|
+
async function writeMd5File(path, data) {
|
|
57
|
+
let md5_output;
|
|
58
|
+
Object.keys(data).forEach(key => {
|
|
59
|
+
var currMd5 = `${data[key]} ${key}`;
|
|
60
|
+
if (md5_output === undefined)
|
|
61
|
+
md5_output = currMd5;
|
|
62
|
+
else
|
|
63
|
+
md5_output += os.EOL + currMd5;
|
|
64
|
+
})
|
|
65
|
+
await fs.promises.writeFile(path, md5_output);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function _readFileIfExists(path, encoding) {
|
|
69
|
+
try {
|
|
70
|
+
return await fs.promises.readFile(path, encoding);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
if (error.code === 'ENOENT' || error.code === 'EISDIR') return undefined;
|
|
73
|
+
else throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function _isChartFileModified(filePath, context = {}) {
|
|
78
|
+
const data = await _readFileIfExists(filePath, 'utf-8');
|
|
79
|
+
if (data == undefined) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const key = _pathKey(path.join(context.projectPath, 'chart'), filePath);
|
|
84
|
+
const currentHash = _hash(data);
|
|
85
|
+
return context.oldTrackingData != undefined && context.oldTrackingData[key] != undefined && context.oldTrackingData[key] != currentHash;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function _hash(data) {
|
|
89
|
+
return crypto.createHash('md5').update(data).digest('base64');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function _pathKey(basePath, cPath) {
|
|
93
|
+
return path.posix.normalize(_toPosix(path.relative(basePath, cPath)))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function _toPosix(path) {
|
|
97
|
+
return path.replace(/\\/g, '/');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function _track(filePath, data, context = {}) {
|
|
101
|
+
const key = _pathKey(path.join(context.projectPath, 'chart'), filePath);
|
|
102
|
+
const hashedContent = _hash(data);
|
|
103
|
+
if (context.oldTrackingData != undefined && context.oldTrackingData[key] != undefined) {
|
|
104
|
+
context.oldTrackingData[key] = hashedContent;
|
|
105
|
+
}
|
|
106
|
+
context.newTrackingData[key] = hashedContent;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = {
|
|
110
|
+
copyAndTrack,
|
|
111
|
+
parseMd5File,
|
|
112
|
+
writeMd5File
|
|
113
|
+
}
|