@sap/cds-dk 7.4.0 → 7.5.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/bin/activate.js +1 -1
- package/bin/add.js +6 -4
- package/bin/build.js +10 -12
- package/bin/cds.js +4 -1
- package/bin/deploy/index.js +5 -2
- package/bin/eval.js +1 -1
- package/bin/extend.js +3 -3
- package/bin/login.js +2 -2
- package/bin/logout.js +1 -1
- package/bin/pull.js +1 -1
- package/bin/push.js +5 -5
- package/bin/subscribe.js +2 -2
- package/bin/unsubscribe.js +2 -2
- package/bin/upgrade.js +2 -2
- package/bin/version.js +2 -2
- package/bin/watch.js +1 -1
- package/lib/bind/bindingUtil.js +6 -3
- package/lib/bind/cfKeyProvider.js +1 -1
- package/lib/bind/userCdsrcJsonStorageProvider.js +1 -1
- package/lib/build/buildPlugin.js +6 -12
- package/lib/build/buildTaskEngine.js +24 -19
- package/lib/build/buildTaskFactory.js +27 -33
- package/lib/build/buildTaskProvider.js +1 -1
- package/lib/build/buildTaskProviderFactory.js +26 -41
- package/lib/build/constants.js +0 -1
- package/lib/build/index.js +3 -3
- package/lib/build/plugins.js +15 -15
- package/lib/build/provider/edmxBuildPlugin.js +6 -7
- package/lib/build/provider/fiori/index.js +8 -8
- package/lib/build/provider/hana/2migration.js +12 -16
- package/lib/build/provider/hana/index.js +5 -7
- package/lib/build/provider/hana/template/package.json +1 -1
- package/lib/build/provider/internalBuildPlugin.js +0 -8
- package/lib/build/provider/internalBuildTaskProvider.js +17 -21
- package/lib/build/provider/java/index.js +2 -1
- package/lib/build/provider/mtx-extension/index.js +8 -5
- package/lib/build/provider/mtx-sidecar/index.js +2 -1
- package/lib/build/provider/nodejs/index.js +64 -58
- package/lib/compile/openapi/csdl2openapi.js +29 -15
- package/lib/compile/openapi/index.js +6 -6
- package/lib/deploy/to-hana/hana.js +5 -3
- package/lib/env/schema.js +2 -3
- package/lib/index.js +68 -28
- package/lib/init/add.js +17 -0
- package/lib/init/constants.js +5 -3
- package/lib/init/index.js +39 -25
- package/lib/init/{util/merge.js → merge.js} +32 -20
- package/lib/init/{util/mvn.js → mvn.js} +5 -5
- package/lib/init/plugin.js +85 -0
- package/lib/init/projectReader.js +145 -0
- package/lib/init/registries/mta.js +151 -0
- package/lib/init/template/{kibana → application-logging}/files/mta.yaml.hbs +3 -3
- package/lib/init/template/application-logging/index.js +49 -0
- package/lib/init/template/approuter/files/mta.yaml.hbs +11 -11
- package/lib/init/template/approuter/files/xs-app.json.hbs +2 -2
- package/lib/init/template/approuter/index.js +36 -81
- package/lib/init/template/cf-manifest/files/manifest.yml.hbs +3 -3
- package/lib/init/template/cf-manifest/files/services-manifest.yml.hbs +4 -4
- package/lib/init/template/cf-manifest/index.js +4 -4
- package/lib/init/template/connectivity/index.js +22 -35
- package/lib/init/template/data/index.js +3 -2
- package/lib/init/template/destination/files/values.yaml +9 -0
- package/lib/init/template/destination/index.js +15 -47
- package/lib/init/template/enterprise-messaging/index.js +26 -58
- package/lib/init/template/enterprise-messaging-shared/index.js +23 -39
- package/lib/init/template/extensibility/index.js +16 -30
- package/lib/init/template/file-based-messaging/index.js +7 -8
- package/lib/init/template/h2/index.js +4 -4
- package/lib/init/template/hana/files/mta.yaml.hbs +8 -8
- package/lib/init/template/hana/index.js +29 -115
- package/lib/init/template/helm/files/chart/templates/NOTES.txt +12 -0
- package/lib/init/template/helm/files/chart/templates/_deployment_helpers.tpl +82 -0
- package/lib/init/template/helm/files/chart/templates/_helpers.tpl +28 -0
- package/lib/init/template/helm/files/chart/values.root.schema.json +61 -0
- package/lib/init/template/helm/files/chart/values.schema.json +366 -0
- package/lib/init/template/helm/{subcharts → files}/web-application/Chart.yaml +1 -1
- package/lib/init/template/helm/{subcharts → files}/web-application/templates/_api.tpl +1 -1
- package/lib/init/template/helm/{subcharts → files}/web-application/values.yaml +1 -1
- package/lib/init/template/helm/index.js +84 -85
- package/lib/init/template/helm-unified-runtime/files/Chart.yaml.hbs +10 -0
- package/lib/init/template/helm-unified-runtime/files/values.yaml.hbs +26 -0
- package/lib/init/template/helm-unified-runtime/index.js +91 -0
- package/lib/init/template/helm-unified-runtime/lib/build.js +0 -0
- package/lib/init/template/helm-unified-runtime/package.json +4 -0
- package/lib/init/template/html5-repo/files/values.yaml.hbs +28 -0
- package/lib/init/template/html5-repo/index.js +23 -97
- package/lib/init/template/java/index.js +3 -3
- package/lib/init/template/lint/index.js +2 -2
- package/lib/init/template/liquibase/index.js +16 -0
- package/lib/init/template/local-messaging/index.js +7 -8
- package/lib/init/template/mta/index.js +7 -19
- package/lib/init/template/mtx/index.js +2 -2
- package/lib/init/template/multitenancy/index.js +38 -89
- package/lib/init/template/nodejs/index.js +5 -4
- package/lib/init/template/notebook/index.js +1 -1
- package/lib/init/template/notifications/index.js +16 -19
- package/lib/init/template/pipeline/index.js +1 -1
- package/lib/init/template/postgres/index.js +25 -31
- package/lib/init/template/redis-messaging/index.js +23 -27
- package/lib/init/template/sample/index.js +4 -4
- package/lib/init/template/samples/index.js +2 -2
- package/lib/init/template/sqlite/files/{package.json.hbs → package.json} +0 -2
- package/lib/init/template/sqlite/index.js +6 -10
- package/lib/init/template/tiny-sample/index.js +6 -6
- package/lib/init/template/toggles/index.js +7 -8
- package/lib/init/template/typer/index.js +6 -6
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +3 -3
- package/lib/init/template/xsuaa/files/values.yaml.hbs +3 -3
- package/lib/init/template/xsuaa/index.js +27 -52
- package/lib/init/{util/template.js → template.js} +1 -1
- package/lib/{client → mtx}/activate.js +15 -11
- package/lib/{client → mtx}/auth_manager.js +5 -4
- package/lib/{client → mtx}/download_legacy.js +6 -4
- package/lib/{client → mtx}/extend.js +14 -9
- package/lib/{client → mtx}/index.js +1 -1
- package/lib/{client → mtx}/params.js +4 -1
- package/lib/{client → mtx}/pull.js +6 -4
- package/lib/{client → mtx}/push.js +11 -10
- package/lib/{client → mtx}/settings_manager.js +8 -6
- package/lib/{client → mtx}/tenant_action.js +9 -8
- package/lib/{client/helper/cf_helper.js → mtx/util/cf.js} +4 -3
- package/lib/{client/helper/dependency_helper.js → mtx/util/dependencies.js} +1 -0
- package/lib/mtx/util/errors.js +27 -0
- package/lib/mtx/util/legacy_ext.js +16 -0
- package/lib/{client/helper/url_helper.js → mtx/util/urls.js} +12 -1
- package/lib/util/fs.js +5 -1
- package/lib/util/pruneAxiosErrors.js +35 -18
- package/lib/util/write.js +1 -1
- package/npm-shrinkwrap.json +27 -27
- package/package.json +10 -1
- package/lib/client/base_command.js +0 -54
- package/lib/init/template/_merging/registry-mta.js +0 -304
- package/lib/init/template/helm/Model.d.ts +0 -53
- package/lib/init/template/kibana/files/package.json.hbs +0 -17
- package/lib/init/template/kibana/index.js +0 -54
- package/lib/init/template/templateBase.js +0 -100
- package/lib/init/util/md5.js +0 -86
- package/lib/init/util/projectReader.js +0 -94
- /package/lib/init/{util/indent.js → indent.js} +0 -0
- /package/lib/init/template/helm/{subcharts → files}/content-deployment/Chart.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/_helpers.tpl +0 -0
- /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/job.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/secret.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/service-account.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/content-deployment/templates/service-binding.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/content-deployment/values.schema.json +0 -0
- /package/lib/init/template/helm/{subcharts → files}/content-deployment/values.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/service-instance/Chart.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/service-instance/templates/_helpers.tpl +0 -0
- /package/lib/init/template/helm/{subcharts → files}/service-instance/templates/serviceinstance.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/service-instance/values.schema.json +0 -0
- /package/lib/init/template/helm/{subcharts → files}/service-instance/values.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/NOTES.txt +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/_helpers.tpl +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/api-rule.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/deployment.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/network-policy.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/pod-disruption-budget.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/rbac.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/secret.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/service-account.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/service-binding.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/service.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/templates/virtual-service.yaml +0 -0
- /package/lib/init/template/helm/{subcharts → files}/web-application/values.schema.json +0 -0
- /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/templates/NOTES.txt +0 -0
- /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/templates/_deployment_helpers.tpl +0 -0
- /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/templates/_helpers.tpl +0 -0
- /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/values.root.schema.json +0 -0
- /package/lib/init/template/{helm/chart → helm-unified-runtime/files}/values.schema.json +0 -0
- /package/lib/init/template/postgres/files/{mta.yaml.hbs → mta.yml.hbs} +0 -0
- /package/lib/init/{util/xml.js → xml.js} +0 -0
- /package/lib/{client/helper/env_helper.js → mtx/util/env.js} +0 -0
- /package/lib/{client/helper/fs_helper.js → mtx/util/fs.js} +0 -0
- /package/lib/{client/helper → mtx/util}/logging.js +0 -0
- /package/lib/{client/helper → mtx/util}/question.js +0 -0
- /package/lib/{client/helper/string_helper.js → mtx/util/strings.js} +0 -0
- /package/lib/util/{cfUtil.js → cf.js} +0 -0
- /package/lib/util/{gitUtil.js → git.js} +0 -0
|
@@ -1,87 +1,62 @@
|
|
|
1
|
-
const { join } = require('path')
|
|
2
1
|
const cds = require('../../../cds')
|
|
3
2
|
const { read } = cds.utils
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
7
|
-
const {
|
|
3
|
+
const term = require('../../../util/term')
|
|
4
|
+
const { readProject } = require('../../projectReader')
|
|
5
|
+
const { merge } = require('../../merge')
|
|
6
|
+
const { srv4, xsuaa, mtxSidecar4 } = require('../../registries/mta')
|
|
8
7
|
|
|
9
|
-
module.exports = class XsuaaTemplate extends require('
|
|
8
|
+
module.exports = class XsuaaTemplate extends require('../../plugin') {
|
|
10
9
|
|
|
11
|
-
static
|
|
10
|
+
static hasInProduction(env) {
|
|
12
11
|
return env.requires?.auth?.kind === 'xsuaa'
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
getRelatedFacets() {
|
|
16
|
-
return ['multitenancy', 'extensibility', 'enterprise-messaging']
|
|
17
|
-
}
|
|
18
|
-
|
|
19
14
|
async run() {
|
|
20
|
-
const project =
|
|
15
|
+
const project = readProject()
|
|
21
16
|
const { configFile } = project
|
|
22
17
|
project.shortcut = !(await read(configFile)).cds?.requires?.auth?.kind
|
|
23
|
-
await
|
|
18
|
+
await merge(__dirname, 'files/package.json.hbs').into(configFile, { project, forceOverwrite: true })
|
|
24
19
|
}
|
|
25
20
|
|
|
26
|
-
async
|
|
27
|
-
const project =
|
|
28
|
-
const {
|
|
21
|
+
async combine() {
|
|
22
|
+
const project = readProject()
|
|
23
|
+
const { hasMultitenancy, hasMta, hasHelm, hasHelmUnifiedRuntime, isJava, srvPath } = project
|
|
29
24
|
|
|
30
25
|
const cds = require('../../../../lib')
|
|
31
26
|
const xsSecurity = await (async () => { try {
|
|
32
27
|
const models = await cds.load(cds.env.folders.srv)
|
|
33
28
|
return cds.compile.to.xsuaa(models)
|
|
34
|
-
} catch (error) { /* ignore */ }
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
where: [{
|
|
39
|
-
property: 'name',
|
|
40
|
-
isEqualTo: scope.name
|
|
41
|
-
}],
|
|
42
|
-
}))}
|
|
43
|
-
await mergeJSON('xs-security.json', xsSecurity, project, mergingSemantics)
|
|
29
|
+
} catch (error) { /* ignore */ }})() ?? { scopes: [], attributes: [], 'role-templates': [], 'authorities-inheritance': false }
|
|
30
|
+
|
|
31
|
+
const additions = xsSecurity.scopes.map(scope => ({ in: 'scopes', where: { name: scope.name } }))
|
|
32
|
+
await merge(xsSecurity).into('xs-security.json', { project, additions })
|
|
44
33
|
|
|
45
34
|
if (hasMta) {
|
|
46
|
-
const srv = (
|
|
35
|
+
const srv = srv4(srvPath)
|
|
47
36
|
const additions = [srv, xsuaa]
|
|
48
37
|
const mtxSidecar = mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar')
|
|
49
|
-
if (
|
|
38
|
+
if (hasMultitenancy && isJava) additions.push(mtxSidecar)
|
|
50
39
|
|
|
51
40
|
const relationships = [{
|
|
52
41
|
insert: [xsuaa, 'name'],
|
|
53
42
|
into: [srv, 'requires', 'name']
|
|
54
43
|
}]
|
|
55
|
-
if (
|
|
44
|
+
if (hasMultitenancy) relationships.push({
|
|
56
45
|
insert: [xsuaa, 'name'],
|
|
57
46
|
into: [mtxSidecar, 'requires', 'name']
|
|
58
47
|
})
|
|
59
|
-
|
|
60
|
-
await mergeYAML('mta.yaml', join(__dirname, 'files', 'mta.yaml.hbs'), project, { additions, relationships })
|
|
48
|
+
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { project, additions, relationships })
|
|
61
49
|
}
|
|
62
50
|
|
|
63
|
-
if (hasHelm) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
isIndependentCommand = true;
|
|
68
|
-
context.oldTrackingData = context.newTrackingData = await parseMd5File(join('chart', '.cds-add-helm-files.md5'));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// copy service-instance chart
|
|
72
|
-
const HelmTemplate = require(`../helm`);
|
|
73
|
-
const helmTemplate = new HelmTemplate(context.oldTrackingData, context.newTrackingData);
|
|
74
|
-
isIndependentCommand = isIndependentCommand | await helmTemplate.addSubChart('service-instance');
|
|
75
|
-
|
|
76
|
-
// add dependency entry in chart.yaml
|
|
77
|
-
await helmTemplate.addDependency('service-instance', 'xsuaa');
|
|
51
|
+
if (hasHelm || hasHelmUnifiedRuntime) {
|
|
52
|
+
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
|
|
53
|
+
}
|
|
54
|
+
}
|
|
78
55
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
)
|
|
84
|
-
if(isIndependentCommand) await writeMd5File(join('chart', '.cds-add-helm-files.md5'), context.newTrackingData);
|
|
56
|
+
finalize() {
|
|
57
|
+
const { hasUI, hasApprouter } = readProject()
|
|
58
|
+
if (hasUI && !hasApprouter) {
|
|
59
|
+
console.log(`\nAlso run ${term.bold('cds add approuter --for production')} to route and authenticate the paths accessed via the UI.`)
|
|
85
60
|
}
|
|
86
61
|
}
|
|
87
62
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const Mustache = require('mustache')
|
|
2
|
-
const cds = require('
|
|
2
|
+
const cds = require('../cds')
|
|
3
3
|
const { copy, read, write, exists, readdir, path, isdir } = cds.utils
|
|
4
4
|
|
|
5
5
|
async function renderAndCopy(from, into, replacements, overwrite = cds.cli.options.force) {
|
|
@@ -3,12 +3,16 @@ const path = require('path');
|
|
|
3
3
|
const axios = require('axios');
|
|
4
4
|
|
|
5
5
|
const cds = require('../cds');
|
|
6
|
-
const DEBUG = cds.debug('cli');
|
|
7
|
-
const { collectFileContent, collectFiles, toUnixPath } = require('./helper/fs_helper');
|
|
8
|
-
const { getMessage } = require('./helper/logging');
|
|
9
|
-
|
|
10
6
|
const AuthManager = require('./auth_manager');
|
|
11
|
-
|
|
7
|
+
|
|
8
|
+
require('../util/pruneAxiosErrors');
|
|
9
|
+
const { collectFileContent, collectFiles, toUnixPath } = require('./util/fs');
|
|
10
|
+
const { getMessage } = require('./util/logging');
|
|
11
|
+
const { handleHttpError } = require('./util/errors');
|
|
12
|
+
const { concatUrls } = require('./util/urls');
|
|
13
|
+
const { checkProject, getMtxApiUrl } = require('./util/legacy_ext');
|
|
14
|
+
|
|
15
|
+
const DEBUG = cds.debug('cli');
|
|
12
16
|
|
|
13
17
|
const COMMAND_URL_SUFFIX = 'asyncActivate';
|
|
14
18
|
const COMMAND_URL_SUFFIX_SYNC = 'activate';
|
|
@@ -37,7 +41,7 @@ async function checkFinished(jobId, statusUrl, params, finisher) {
|
|
|
37
41
|
}
|
|
38
42
|
}
|
|
39
43
|
|
|
40
|
-
module.exports = class Activate
|
|
44
|
+
module.exports = class Activate {
|
|
41
45
|
|
|
42
46
|
static get COMMAND_URL_SUFFIX() { return COMMAND_URL_SUFFIX; }
|
|
43
47
|
static get COMMAND_URL_SUFFIX_SYNC() { return COMMAND_URL_SUFFIX_SYNC; }
|
|
@@ -57,7 +61,7 @@ module.exports = class Activate extends BaseCommand {
|
|
|
57
61
|
console.log('Activating extension located at', params.get('projectFolder'), 'to URL', params.get('appUrl'));
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
if (!await
|
|
64
|
+
if (!await checkProject(params.get('projectFolder'))) {
|
|
61
65
|
throw params.get('projectFolder') + ' is not a valid extension project';
|
|
62
66
|
}
|
|
63
67
|
|
|
@@ -67,7 +71,7 @@ module.exports = class Activate extends BaseCommand {
|
|
|
67
71
|
await this.runCustomFileUpload(params);
|
|
68
72
|
}
|
|
69
73
|
} catch (error) {
|
|
70
|
-
|
|
74
|
+
handleHttpError(error, params, { command: 'activate' });
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
|
|
@@ -163,7 +167,7 @@ module.exports = class Activate extends BaseCommand {
|
|
|
163
167
|
console.log('Activating extension...');
|
|
164
168
|
|
|
165
169
|
const urlSuffix = isSync ? this.COMMAND_URL_SUFFIX_SYNC : this.COMMAND_URL_SUFFIX;
|
|
166
|
-
activationUrl =
|
|
170
|
+
activationUrl = getMtxApiUrl(params.get('appUrl'), urlSuffix);
|
|
167
171
|
const requestOptions = Object.assign({
|
|
168
172
|
headers: {}
|
|
169
173
|
}, params.get('reqAuth'));
|
|
@@ -192,7 +196,7 @@ module.exports = class Activate extends BaseCommand {
|
|
|
192
196
|
DEBUG?.(`Job ID: ${jobId}`);
|
|
193
197
|
|
|
194
198
|
return new Promise((resolve, reject) => {
|
|
195
|
-
const statusUrl =
|
|
199
|
+
const statusUrl = concatUrls(params.get('appUrl'), statusPath);
|
|
196
200
|
const finisher = {
|
|
197
201
|
resolve,
|
|
198
202
|
reject,
|
|
@@ -218,7 +222,7 @@ module.exports = class Activate extends BaseCommand {
|
|
|
218
222
|
});
|
|
219
223
|
});
|
|
220
224
|
|
|
221
|
-
const customFileUrl =
|
|
225
|
+
const customFileUrl = getMtxApiUrl(params.get('appUrl'), this.UPDATE_CUSTOM_FILE_URL_SUFFIX);
|
|
222
226
|
const requestOptions = Object.assign({
|
|
223
227
|
headers: {},
|
|
224
228
|
}, params.get('reqAuth'));
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
|
|
3
|
-
require('../util/pruneAxiosErrors');
|
|
4
|
-
|
|
5
3
|
const cds = require('../cds');
|
|
6
|
-
const DEBUG = cds.debug('cli');
|
|
7
4
|
const { SettingsManager } = require('./settings_manager');
|
|
8
5
|
const { ParamCollection } = require('./params');
|
|
9
|
-
|
|
6
|
+
|
|
7
|
+
require('../util/pruneAxiosErrors');
|
|
8
|
+
const { getMessage } = require('./util/logging');
|
|
9
|
+
|
|
10
|
+
const DEBUG = cds.debug('cli');
|
|
10
11
|
|
|
11
12
|
function addTokenInfo(params, authData) {
|
|
12
13
|
params.set('token', authData.access_token);
|
|
@@ -3,11 +3,13 @@ const { join } = require('path');
|
|
|
3
3
|
const axios = require('axios');
|
|
4
4
|
|
|
5
5
|
const { login } = require('./auth_manager');
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
require('../util/pruneAxiosErrors');
|
|
8
|
+
const { handleHttpError } = require('./util/errors');
|
|
7
9
|
|
|
8
10
|
const DOWNLOAD_FILE_NAME = 'migrated_projects.tgz'; // TODO try to add tenant later, if possible
|
|
9
11
|
|
|
10
|
-
module.exports = class Download
|
|
12
|
+
module.exports = class Download {
|
|
11
13
|
|
|
12
14
|
static async run(paramValues) {
|
|
13
15
|
const params = await login(paramValues);
|
|
@@ -15,7 +17,7 @@ module.exports = class Download extends BaseCommand {
|
|
|
15
17
|
const projectFolder = params.get('projectFolder');
|
|
16
18
|
const downloadPath = join(projectFolder, DOWNLOAD_FILE_NAME);
|
|
17
19
|
|
|
18
|
-
if (fs.existsSync(downloadPath) && !(await require('./
|
|
20
|
+
if (fs.existsSync(downloadPath) && !(await require('./util/question').askBooleanQuestion(`File ${DOWNLOAD_FILE_NAME} already exists. Continue (yN)? `, false, false))) {
|
|
19
21
|
console.log('Download cancelled');
|
|
20
22
|
return;
|
|
21
23
|
}
|
|
@@ -35,6 +37,6 @@ module.exports = class Download extends BaseCommand {
|
|
|
35
37
|
|
|
36
38
|
return axios.post(downloadUrl, { tagRule, defaultTag }, options)
|
|
37
39
|
.then(response => Buffer.from(response.data))
|
|
38
|
-
.catch(error =>
|
|
40
|
+
.catch(error => handleHttpError(error, params, { url: downloadUrl }));
|
|
39
41
|
}
|
|
40
42
|
}
|
|
@@ -3,12 +3,16 @@ const path = require('path');
|
|
|
3
3
|
const axios = require('axios');
|
|
4
4
|
|
|
5
5
|
const AuthManager = require('./auth_manager');
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
6
|
+
|
|
7
|
+
require('../util/pruneAxiosErrors');
|
|
8
|
+
const { normalizePath, isParent } = require('./util/fs');
|
|
9
|
+
const Question = require('./util/question');
|
|
10
|
+
const { getMessage } = require('./util/logging');
|
|
11
|
+
const { handleHttpError } = require('./util/errors');
|
|
12
|
+
const { checkProject, getMtxApiUrl } = require('./util/legacy_ext');
|
|
10
13
|
|
|
11
14
|
const COMMAND_URL_SUFFIX = 'content';
|
|
15
|
+
const CUSTOM_FILE_URL_SUFFIX = 'customTenantContent';
|
|
12
16
|
const CUSTOM_FILE_FOLDERS = ['wsdl'];
|
|
13
17
|
const DB_FOLDER = 'db';
|
|
14
18
|
const SRV_FOLDER = 'srv';
|
|
@@ -19,9 +23,10 @@ function folderExists(folder) {
|
|
|
19
23
|
'\nWhen using --force, make sure you are using a version control system (like git) to avoid data loss';
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
module.exports = class Extend
|
|
26
|
+
module.exports = class Extend {
|
|
23
27
|
|
|
24
28
|
static get COMMAND_URL_SUFFIX() { return COMMAND_URL_SUFFIX; }
|
|
29
|
+
static get CUSTOM_FILE_URL_SUFFIX() { return CUSTOM_FILE_URL_SUFFIX; }
|
|
25
30
|
|
|
26
31
|
static async storeFiles(content, targetDirectory, filter) {
|
|
27
32
|
fs.mkdirSync(targetDirectory, { recursive: true });
|
|
@@ -85,7 +90,7 @@ module.exports = class Extend extends BaseCommand {
|
|
|
85
90
|
console.log('\n\nCreating extension project for', params.get('appUrl'), 'subdomain', params.get('subdomain'), 'in folder', params.get('projectFolder'));
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
const runOnExistingProject = await
|
|
93
|
+
const runOnExistingProject = await checkProject(params.get('projectFolder'));
|
|
89
94
|
if (runOnExistingProject && !(params.get('force') || params.get('templates'))) {
|
|
90
95
|
throw getMessage(folderExists(params.get('projectFolder')), { command: 'extend' });
|
|
91
96
|
}
|
|
@@ -93,12 +98,12 @@ module.exports = class Extend extends BaseCommand {
|
|
|
93
98
|
try {
|
|
94
99
|
await Extend.runExtend(params);
|
|
95
100
|
} catch (error) {
|
|
96
|
-
await
|
|
101
|
+
await handleHttpError(error, params, { command: 'extend' });
|
|
97
102
|
}
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
static async runExtend(params) {
|
|
101
|
-
const contentUrl =
|
|
106
|
+
const contentUrl = getMtxApiUrl(params.get('appUrl'), COMMAND_URL_SUFFIX);
|
|
102
107
|
const requestOptions = Object.assign({ retry: 0 }, params.get('reqAuth'));
|
|
103
108
|
|
|
104
109
|
console.log('Retrieving files...');
|
|
@@ -134,7 +139,7 @@ module.exports = class Extend extends BaseCommand {
|
|
|
134
139
|
|
|
135
140
|
if (params.get('wsdl')) {
|
|
136
141
|
console.log('Writing custom files');
|
|
137
|
-
const customFileUrl =
|
|
142
|
+
const customFileUrl = getMtxApiUrl(params.get('appUrl'), CUSTOM_FILE_URL_SUFFIX);
|
|
138
143
|
const customFiles = (await axios.get(customFileUrl, requestOptions)).data;
|
|
139
144
|
await Extend.storeCustomFiles(params.get('projectFolder'), customFiles);
|
|
140
145
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const Activate = require('./activate');
|
|
2
2
|
const AuthManager = require('./auth_manager');
|
|
3
3
|
const Extend = require('./extend');
|
|
4
|
-
const Question = require('./helper/question');
|
|
5
4
|
const { SettingsManager } = require('./settings_manager');
|
|
5
|
+
const Question = require('./util/question');
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
extend: Extend.run,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const cds = require('../cds');
|
|
2
|
+
|
|
3
|
+
const { escapeRegex } = require('./util/strings');
|
|
4
|
+
|
|
2
5
|
const DEBUG = cds.debug('cli');
|
|
3
|
-
const { escapeRegex } = require('./helper/string_helper');
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
// PARAM BASE TYPES
|
|
@@ -216,6 +218,7 @@ class AllParams extends BasicParams {
|
|
|
216
218
|
this.undeploy = new Param('undeploy', false);
|
|
217
219
|
this.wsdl = new Param('wsdl', false);
|
|
218
220
|
this.sync = new Param('sync', false);
|
|
221
|
+
this.async = new Param('async', false);
|
|
219
222
|
|
|
220
223
|
// `login` PARAMS
|
|
221
224
|
this.skipToken = new Param('skipToken', false, { internal: true });
|
|
@@ -6,10 +6,12 @@ const { join } = require('path');
|
|
|
6
6
|
const axios = require('axios');
|
|
7
7
|
|
|
8
8
|
const { login } = require('./auth_manager');
|
|
9
|
-
const BaseCommand = require('./base_command');
|
|
10
|
-
const { getMessage } = require('./helper/logging');
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
require('../util/pruneAxiosErrors');
|
|
11
|
+
const { getMessage } = require('./util/logging');
|
|
12
|
+
const { handleHttpError } = require('./util/errors');
|
|
13
|
+
|
|
14
|
+
module.exports = class Pull {
|
|
13
15
|
|
|
14
16
|
static async run(paramValues) {
|
|
15
17
|
if (!tar) {
|
|
@@ -46,7 +48,7 @@ module.exports = class Pull extends BaseCommand {
|
|
|
46
48
|
|
|
47
49
|
return axios.post(pullUrl, {}, options)
|
|
48
50
|
.then(response => Buffer.from(response.data))
|
|
49
|
-
.catch(error =>
|
|
51
|
+
.catch(error => handleHttpError(error, params, { url: pullUrl }));
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
static getPackageJsonIndentation(packageContents) {
|
|
@@ -4,11 +4,13 @@ const { readFileSync, existsSync } = require('fs');
|
|
|
4
4
|
const axios = require('axios');
|
|
5
5
|
|
|
6
6
|
const { login } = require('./auth_manager');
|
|
7
|
-
const BaseCommand = require('./base_command');
|
|
8
|
-
const { getMessage } = require('./helper/logging');
|
|
9
|
-
const { schemaRegex } = require('./helper/url_helper');
|
|
10
7
|
const buildSystem = require('../build')
|
|
11
8
|
|
|
9
|
+
require('../util/pruneAxiosErrors');
|
|
10
|
+
const { getMessage } = require('./util/logging');
|
|
11
|
+
const { schemaRegex } = require('./util/urls');
|
|
12
|
+
const { handleHttpError } = require('./util/errors');
|
|
13
|
+
|
|
12
14
|
const JOB_STATUS = {
|
|
13
15
|
QUEUED: 'QUEUED',
|
|
14
16
|
RUNNING: 'RUNNING',
|
|
@@ -16,7 +18,7 @@ const JOB_STATUS = {
|
|
|
16
18
|
FAILED: 'FAILED'
|
|
17
19
|
};
|
|
18
20
|
|
|
19
|
-
module.exports = class Push
|
|
21
|
+
module.exports = class Push {
|
|
20
22
|
|
|
21
23
|
static async run(paramValues, pushOptions = {}) {
|
|
22
24
|
const params = await login(paramValues);
|
|
@@ -35,8 +37,7 @@ module.exports = class Push extends BaseCommand {
|
|
|
35
37
|
|
|
36
38
|
console.log(`\nPushing extension '${extensionName}' from`, { src }, 'to', target);
|
|
37
39
|
const push = await this.pushTgz(params, content, extensionName);
|
|
38
|
-
|
|
39
|
-
if (async) {
|
|
40
|
+
if (params.get('async')) {
|
|
40
41
|
await this.pollUntilFinished(push.headers.location, params)
|
|
41
42
|
}
|
|
42
43
|
console.log ('Activation succeeded.\n')
|
|
@@ -55,7 +56,7 @@ module.exports = class Push extends BaseCommand {
|
|
|
55
56
|
try {
|
|
56
57
|
content = (await axios.get(src, { responseEncoding: 'base64' })).data;
|
|
57
58
|
} catch (error) {
|
|
58
|
-
|
|
59
|
+
handleHttpError(error, params, { url: src });
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
return { src, content };
|
|
@@ -72,7 +73,7 @@ module.exports = class Push extends BaseCommand {
|
|
|
72
73
|
static async pushTgz(params, tgz, extensionName) {
|
|
73
74
|
const pushUrl = `${params.get('appUrl')}/-/cds/extensibility/push`;
|
|
74
75
|
const options = { ...params.get('reqAuth') };
|
|
75
|
-
const async =
|
|
76
|
+
const async = params.get('async');
|
|
76
77
|
if (async) {
|
|
77
78
|
options.headers = { prefer: 'respond-async', ...options.headers }
|
|
78
79
|
}
|
|
@@ -81,7 +82,7 @@ module.exports = class Push extends BaseCommand {
|
|
|
81
82
|
extension: tgz,
|
|
82
83
|
tag: extensionName
|
|
83
84
|
}, options)
|
|
84
|
-
.catch(error =>
|
|
85
|
+
.catch(error => handleHttpError(error, params, { url: pushUrl }));
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
static async pollUntilFinished(jobUrl, params) {
|
|
@@ -94,7 +95,7 @@ module.exports = class Push extends BaseCommand {
|
|
|
94
95
|
}, 5 * 60 * 1000);
|
|
95
96
|
|
|
96
97
|
const interval = setInterval(async () => {
|
|
97
|
-
const { status, error } = (await axios.get(jobUrl, options)).data;
|
|
98
|
+
const { status, error = 'cds push failed' } = (await axios.get(jobUrl, options)).data;
|
|
98
99
|
if (status === JOB_STATUS.FINISHED || status === JOB_STATUS.FAILED) {
|
|
99
100
|
clearInterval(interval);
|
|
100
101
|
clearTimeout(timeout);
|
|
@@ -4,13 +4,15 @@ const path = require('path');
|
|
|
4
4
|
const axios = require('axios');
|
|
5
5
|
|
|
6
6
|
const cds = require('../cds');
|
|
7
|
+
|
|
8
|
+
const { requireGlobal } = require('./util/dependencies');
|
|
9
|
+
const { getAppFromSuggestions, getSubdomain } = require('./util/cf');
|
|
10
|
+
const isBas = require('./util/env');
|
|
11
|
+
const Question = require('./util/question');
|
|
12
|
+
const { httpSchema, httpsSchema, schemaRegex, localhostRegex } = require('./util/urls');
|
|
13
|
+
const { capitalize } = require('./util/strings');
|
|
14
|
+
|
|
7
15
|
const DEBUG = cds.debug('cli');
|
|
8
|
-
const { requireGlobal } = require('./helper/dependency_helper');
|
|
9
|
-
const { getAppFromSuggestions, getSubdomain } = require('./helper/cf_helper');
|
|
10
|
-
const isBas = require('./helper/env_helper');
|
|
11
|
-
const Question = require('./helper/question');
|
|
12
|
-
const { httpSchema, httpsSchema, schemaRegex, localhostRegex } = require('./helper/url_helper');
|
|
13
|
-
const { capitalize } = require('./helper/string_helper');
|
|
14
16
|
|
|
15
17
|
const { ParamCollection, Persistence } = require('./params');
|
|
16
18
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const cds = require('../cds');
|
|
2
|
-
const DEBUG = cds.debug('cli');
|
|
3
|
-
|
|
4
|
-
const BaseCommand = require('./base_command');
|
|
5
|
-
const { getMessage } = require('./helper/logging');
|
|
6
2
|
const { ParamCollection } = require('./params');
|
|
7
3
|
const AuthManager = require('./auth_manager');
|
|
8
|
-
|
|
4
|
+
|
|
5
|
+
require('../util/pruneAxiosErrors');
|
|
6
|
+
const { getMessage } = require('./util/logging');
|
|
7
|
+
const { capitalize } = require('./util/strings');
|
|
8
|
+
const { handleHttpError } = require('./util/errors');
|
|
9
|
+
|
|
10
|
+
const DEBUG = cds.debug('cli');
|
|
9
11
|
|
|
10
12
|
const COMMANDS = {
|
|
11
13
|
subscribe: 'to',
|
|
@@ -13,7 +15,7 @@ const COMMANDS = {
|
|
|
13
15
|
unsubscribe: 'from'
|
|
14
16
|
};
|
|
15
17
|
|
|
16
|
-
module.exports = class TenantAction
|
|
18
|
+
module.exports = class TenantAction {
|
|
17
19
|
|
|
18
20
|
// TODO JSDoc
|
|
19
21
|
/**
|
|
@@ -23,7 +25,6 @@ module.exports = class TenantAction extends BaseCommand {
|
|
|
23
25
|
if (!(command in COMMANDS)) {
|
|
24
26
|
throw new Error(`invalid command: ${command}`);
|
|
25
27
|
}
|
|
26
|
-
super();
|
|
27
28
|
this.command = command;
|
|
28
29
|
this.gerund = command.replace(/e$/, 'ing');
|
|
29
30
|
this.preposition = COMMANDS[command];
|
|
@@ -50,7 +51,7 @@ module.exports = class TenantAction extends BaseCommand {
|
|
|
50
51
|
try {
|
|
51
52
|
await require('axios').post(url, { tenant }, params.get('reqAuth'));
|
|
52
53
|
} catch (error) {
|
|
53
|
-
|
|
54
|
+
handleHttpError(error, params, { url });
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -2,10 +2,11 @@ const os = require('os');
|
|
|
2
2
|
const { execFile } = require('child_process');
|
|
3
3
|
|
|
4
4
|
const cds = require('../../cds');
|
|
5
|
-
const DEBUG = cds.debug('cli');
|
|
6
5
|
const Question = require('./question');
|
|
7
|
-
const { formatObjectsFixedWidth } = require('./
|
|
8
|
-
const { schemaRegex } = require('./
|
|
6
|
+
const { formatObjectsFixedWidth } = require('./strings');
|
|
7
|
+
const { schemaRegex } = require('./urls');
|
|
8
|
+
|
|
9
|
+
const DEBUG = cds.debug('cli');
|
|
9
10
|
|
|
10
11
|
function runCf(args, callback) {
|
|
11
12
|
const env = Object.assign({}, process.env, { LC_ALL: 'en_US.UTF-8' }); // enforce English headings
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { getMessage } = require('./logging');
|
|
2
|
+
|
|
3
|
+
function handleHttpError(error, params, { url, command } = {}) {
|
|
4
|
+
url = url ?? params.get('appUrl');
|
|
5
|
+
const prefix = `Request to ${url} failed`;
|
|
6
|
+
switch (error.status) {
|
|
7
|
+
case 401:
|
|
8
|
+
throw getMessage(`${prefix}: invalid authentication.\nRetry with valid passcode${
|
|
9
|
+
params.has('passcodeUrl') ? ` from ${params.get('passcodeUrl')}` : ''
|
|
10
|
+
} or username/password (required if SaaS app is configured with mocked-auth).`, { error, command });
|
|
11
|
+
case 403:
|
|
12
|
+
throw getMessage(prefix + ': insufficient authorization. Ensure client has all necessary roles.', { error, command });
|
|
13
|
+
case 404:
|
|
14
|
+
throw getMessage(prefix + ': resource not found.', { error, command });
|
|
15
|
+
case 422:
|
|
16
|
+
// Compilation or native-extension error.
|
|
17
|
+
throw getMessage(prefix + '.', { error, command });
|
|
18
|
+
default:
|
|
19
|
+
// Unexpected error should be transparent to user.
|
|
20
|
+
delete error.status; // Purge extra property already included in message.
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
handleHttpError
|
|
27
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs').promises;
|
|
3
|
+
|
|
4
|
+
const { concatUrls } = require('./urls');
|
|
5
|
+
require('../../util/pruneAxiosErrors');
|
|
6
|
+
|
|
7
|
+
const MTX_URL_PATH_PREFIX = 'mtx/v1/model/';
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
async checkProject(folder) {
|
|
11
|
+
return await fs.access(path.join(folder, 'package.json')).then(() => true).catch(() => false);
|
|
12
|
+
},
|
|
13
|
+
getMtxApiUrl(url, action) {
|
|
14
|
+
return concatUrls(url, MTX_URL_PATH_PREFIX, action);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -12,10 +12,21 @@ function extractSubdomain(url) {
|
|
|
12
12
|
return hostname.split('.')[0];
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
function concatUrls(...parts) {
|
|
16
|
+
return parts
|
|
17
|
+
.map((p, i) => i === 0
|
|
18
|
+
? p.replace(/\/$/ /*end slash*/, '')
|
|
19
|
+
: i === parts.length - 1
|
|
20
|
+
? p.replace(/^\// /*begin slash*/, '')
|
|
21
|
+
: p.replace(/^\/|\/$/g /*both*/, ''))
|
|
22
|
+
.join('/');
|
|
23
|
+
}
|
|
24
|
+
|
|
15
25
|
module.exports = {
|
|
16
26
|
schemaRegex,
|
|
17
27
|
localhostRegex,
|
|
18
28
|
httpSchema,
|
|
19
29
|
httpsSchema,
|
|
20
|
-
extractSubdomain
|
|
30
|
+
extractSubdomain,
|
|
31
|
+
concatUrls
|
|
21
32
|
};
|
package/lib/util/fs.js
CHANGED
|
@@ -44,7 +44,11 @@ module.exports = new class FsUtil {
|
|
|
44
44
|
const renderedFile = Mustache.render(file, project)
|
|
45
45
|
return JSON.parse(renderedFile)
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(file)
|
|
49
|
+
} catch (error) {
|
|
50
|
+
throw new Error(error.message + '\n' + file)
|
|
51
|
+
}
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
async readJSONC(src) {
|