@sap/cds-dk 7.9.4 → 8.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2116 -0
- package/bin/add.js +18 -52
- package/bin/bind.js +2 -2
- package/bin/build.js +29 -4
- package/bin/cds.js +23 -11
- package/bin/compile/index.js +7 -6
- package/bin/completion/index.js +70 -46
- package/bin/completion/scripts/cds-bash.sh +4 -1
- package/bin/completion/scripts/cds-fish.fish +13 -0
- package/bin/completion/scripts/cds-ps.ps1 +2 -1
- package/bin/completion/scripts/cds-zsh.sh +2 -1
- package/bin/deploy/index.js +6 -5
- package/bin/deploy/to-sqlite.js +2 -2
- package/bin/extend.js +19 -50
- package/bin/help.js +2 -2
- package/bin/init.js +10 -77
- package/bin/login.js +13 -5
- package/bin/migrate.js +1 -1
- package/bin/pull.js +11 -0
- package/bin/repl.js +3 -0
- package/bin/test.js +5 -0
- package/bin/version.js +7 -7
- package/bin/watch.js +2 -11
- package/lib/bind/KubernetesApiAccessor.js +10 -9
- package/lib/build/buildTaskEngine.js +11 -7
- package/lib/build/buildTaskFactory.js +15 -43
- package/lib/build/buildTaskProviderFactory.js +16 -44
- package/lib/build/constants.js +3 -3
- package/lib/build/index.js +2 -2
- package/lib/build/{buildPlugin.js → plugin.js} +65 -46
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/Chart.yaml +1 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/values.yaml +1 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/Chart.yaml +1 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/templates/_helpers.tpl +7 -0
- package/lib/build/plugins/helm/files/subcharts/service-instance/templates/servicebinding.yaml +32 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/templates/serviceinstance.yaml +3 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/values.schema.json +63 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/service-instance/values.yaml +23 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/Chart.yaml +1 -1
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/deployment.yaml +2 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/hpa.yaml +22 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/pod-disruption-budget.yaml +1 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/values.schema.json +49 -0
- package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/values.yaml +8 -2
- package/lib/{init/template/helm/files/chart → build/plugins/helm/files}/templates/_deployment_helpers.tpl +5 -0
- package/lib/build/plugins/helm/files/templates/_helpers.tpl +13 -0
- package/lib/build/plugins/helm/index.js +81 -0
- package/lib/build/plugins.js +12 -15
- package/lib/build/provider/featureToggleBuildPlugin.js +7 -39
- package/lib/build/provider/hana/2migration.js +168 -124
- package/lib/build/provider/hana/index.js +20 -25
- package/lib/build/provider/hana/template/.hdiconfig-all +3 -0
- package/lib/build/provider/hana/template/.hdiconfig-cloud +3 -0
- package/lib/build/provider/hana/template/package.json +4 -3
- package/lib/build/provider/internalBuildPlugin.js +32 -97
- package/lib/build/provider/internalBuildTaskProvider.js +10 -46
- package/lib/build/provider/java/index.js +2 -3
- package/lib/build/provider/mtx/index.js +5 -4
- package/lib/build/provider/mtx-extension/index.js +5 -2
- package/lib/build/provider/mtx-sidecar/index.js +2 -2
- package/lib/build/util.js +83 -12
- package/lib/compile/to-mermaid.js +108 -0
- package/lib/compile/to_asyncapi.js +7 -0
- package/lib/compile/to_openapi.js +7 -0
- package/lib/deploy/to-hana/hana.js +37 -34
- package/lib/deploy/to-hana/hdiDeployUtil.js +8 -6
- package/lib/env/schemas/cds-rc.js +1 -1
- package/lib/import/common.js +2 -2
- package/lib/import/odata/metadataconverter/MetadataConverter.js +4 -4
- package/lib/import/odata/v2parser.js +83 -197
- package/lib/import/odata/v4parser.js +1 -38
- package/lib/import/openapi/importOpenAPI.js +164 -42
- package/lib/index.js +10 -12
- package/lib/init/bas.js +91 -0
- package/lib/init/constants.js +16 -10
- package/lib/init/index.js +74 -150
- package/lib/init/merge.js +12 -20
- package/lib/init/mvn.js +103 -150
- package/lib/init/plugin.js +11 -7
- package/lib/init/projectReader.js +53 -19
- package/lib/init/registries/mta.js +51 -6
- package/lib/init/template/application-logging/files/package.json.hbs +7 -0
- package/lib/init/template/application-logging/index.js +13 -1
- package/lib/init/template/approuter/files/containerize.yaml.hbs +10 -0
- package/lib/init/template/approuter/files/mta.yaml.hbs +1 -2
- package/lib/init/template/approuter/files/values.yaml.hbs +19 -4
- package/lib/init/template/approuter/files/xs-app.json.hbs +12 -3
- package/lib/init/template/approuter/index.js +29 -25
- package/lib/init/template/attachments/files/mta.yaml.hbs +14 -0
- package/lib/init/template/attachments/files/package.json.hbs +5 -0
- package/lib/init/template/attachments/files/values.yaml +7 -0
- package/lib/init/template/attachments/index.js +53 -0
- package/lib/init/template/audit-logging/files/mta.yaml.hbs +14 -0
- package/lib/init/template/audit-logging/files/package.json.hbs +7 -0
- package/lib/init/template/audit-logging/index.js +66 -0
- package/lib/init/template/cf-manifest/index.js +4 -0
- package/lib/init/template/completion/completionSetup.js +54 -33
- package/lib/init/template/completion/index.js +7 -1
- package/lib/init/template/connectivity/index.js +4 -4
- package/lib/init/template/containerize/files/containerize.yaml.hbs +26 -0
- package/lib/init/template/containerize/index.js +24 -0
- package/lib/init/template/data/index.js +4 -0
- package/lib/init/template/destination/files/mta.yaml.hbs +25 -1
- package/lib/init/template/destination/index.js +12 -2
- package/lib/init/template/enterprise-messaging/index.js +6 -3
- package/lib/init/template/enterprise-messaging-shared/index.js +5 -1
- package/lib/init/template/extensibility/files/package.json.hbs +1 -1
- package/lib/init/template/extensibility/files/xs-security.json.hbs +2 -8
- package/lib/init/template/extensibility/index.js +3 -1
- package/lib/init/template/file-based-messaging/index.js +4 -0
- package/lib/init/template/h2/index.js +4 -0
- package/lib/init/template/hana/files/containerize.yaml.hbs +10 -0
- package/lib/init/template/hana/files/db/package.json +3 -2
- package/lib/init/template/hana/files/package.json.hbs +4 -7
- package/lib/init/template/hana/files/src/.hdiconfig +3 -0
- package/lib/init/template/hana/files/values.yaml.hbs +1 -2
- package/lib/init/template/hana/index.js +15 -7
- package/lib/init/template/helm/files/Chart.yaml.hbs +2 -3
- package/lib/init/template/helm/files/values.schema.json +2173 -0
- package/lib/init/template/helm/files/values.yaml.hbs +11 -6
- package/lib/init/template/helm/index.js +77 -18
- package/lib/init/template/helm-unified-runtime/index.js +19 -56
- package/lib/init/template/html5-repo/files/app-package.json.hbs +11 -7
- package/lib/init/template/html5-repo/files/manifest.json +13 -0
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +41 -8
- package/lib/init/template/html5-repo/files/ui5-deploy.yaml.hbs +21 -0
- package/lib/init/template/html5-repo/files/ui5.yaml.hbs +2 -29
- package/lib/init/template/html5-repo/files/values.yaml.hbs +6 -2
- package/lib/init/template/html5-repo/files/xs-app.json.hbs +21 -8
- package/lib/init/template/html5-repo/index.js +33 -30
- package/lib/init/template/http/index.js +36 -12
- package/lib/init/template/java/index.js +18 -12
- package/lib/init/template/kafka/index.js +4 -0
- package/lib/init/template/lint/index.js +7 -2
- package/lib/init/template/liquibase/index.js +4 -0
- package/lib/init/template/local-messaging/index.js +4 -0
- package/lib/init/template/malware-scanner/files/mta.yaml.hbs +14 -0
- package/lib/init/template/malware-scanner/files/package.json.hbs +17 -0
- package/lib/init/template/malware-scanner/files/values.yaml +7 -0
- package/lib/init/template/malware-scanner/index.js +47 -0
- package/lib/init/template/mta/files/mta.yaml.hbs +3 -3
- package/lib/init/template/mta/files/package.json +1 -1
- package/lib/init/template/mta/index.js +4 -0
- package/lib/init/template/mtx/index.js +4 -0
- package/lib/init/template/multitenancy/files/containerize.yaml.hbs +10 -0
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +0 -1
- package/lib/init/template/multitenancy/files/package.json.hbs +1 -1
- package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +6 -5
- package/lib/init/template/multitenancy/files/values.yaml.hbs +14 -24
- package/lib/init/template/multitenancy/index.js +50 -28
- package/lib/init/template/nodejs/files/eslint.config.mjs +2 -0
- package/lib/init/template/nodejs/files/package.json.hbs +2 -3
- package/lib/init/template/nodejs/index.js +4 -0
- package/lib/init/template/notifications/files/mta.yaml.hbs +2 -2
- package/lib/init/template/notifications/index.js +4 -0
- package/lib/init/template/pipeline/files/.pipeline/config.yml +1 -1
- package/lib/init/template/pipeline/files/Jenkinsfile +1 -1
- package/lib/init/template/pipeline/index.js +4 -0
- package/lib/init/template/portal/files/mta.yaml.hbs +52 -0
- package/lib/init/template/portal/files/package.json.hbs +11 -0
- package/lib/init/template/portal/files/package.sidecar.json +7 -0
- package/lib/init/template/portal/files/portal-site/CommonDataModel.json.hbs +97 -0
- package/lib/init/template/portal/files/portal-site/i18n/catalog.properties +1 -0
- package/lib/init/template/portal/files/portal-site/i18n/catalog_de.properties +1 -0
- package/lib/init/template/portal/files/portal-site/i18n/group.properties +1 -0
- package/lib/init/template/portal/files/portal-site/i18n/group_de.properties +1 -0
- package/lib/init/template/portal/index.js +84 -0
- package/lib/init/template/postgres/index.js +5 -1
- package/lib/init/template/redis-messaging/index.js +4 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_de.properties +3 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n_en.properties +3 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +13 -1
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n.properties +2 -2
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_de.properties +3 -0
- package/lib/init/template/sample/files/app/browse/webapp/i18n/i18n_en.properties +4 -0
- package/lib/init/template/sample/files/app/browse/webapp/manifest.json +3 -3
- package/lib/init/template/sample/files/app/index.html +1 -1
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +5 -5
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books.csv +6 -6
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books_texts.csv +5 -5
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.csv +16 -16
- package/lib/init/template/sample/files/nodejs/cat-service.js +2 -2
- package/lib/init/template/sample/files/package.json.hbs +3 -0
- package/lib/init/template/sample/index.js +16 -9
- package/lib/init/template/sqlite/index.js +4 -0
- package/lib/init/template/tiny-sample/files/nodejs/db/data/my.bookshop-Books.csv +3 -3
- package/lib/init/template/tiny-sample/files/nodejs/srv/cat-service.cds.hbs +1 -1
- package/lib/init/template/tiny-sample/index.js +4 -0
- package/lib/init/template/toggles/files/package.json.hbs +1 -1
- package/lib/init/template/toggles/index.js +4 -0
- package/lib/init/template/typer/index.js +4 -0
- package/lib/init/template/typescript/files/package.json +12 -0
- package/lib/init/template/typescript/files/tsconfig.json +13 -0
- package/lib/init/template/typescript/index.js +39 -0
- package/lib/init/template/workzone/index.js +5 -0
- package/lib/init/template/workzone-standard/files/manifest.json.hbs +6 -0
- package/lib/init/template/workzone-standard/index.js +30 -0
- package/lib/init/template/xsuaa/files/package.json.hbs +1 -1
- package/lib/init/template/xsuaa/files/values.yaml.hbs +3 -2
- package/lib/init/template/xsuaa/index.js +11 -7
- package/lib/init/validate.js +27 -0
- package/lib/lint/generators.js +1 -1
- package/lib/lint/io.js +25 -7
- package/lib/mtx/auth_manager.js +64 -30
- package/lib/mtx/download_legacy.js +2 -2
- package/lib/mtx/index.js +0 -4
- package/lib/mtx/params.js +32 -38
- package/lib/mtx/pull.js +151 -43
- package/lib/mtx/push.js +3 -3
- package/lib/mtx/settings_manager.js +75 -35
- package/lib/mtx/tenant_action.js +1 -1
- package/lib/mtx/util/cf.js +1 -1
- package/lib/mtx/util/fs.js +26 -1
- package/lib/mtx/util/logging.js +7 -3
- package/lib/util/command.js +0 -2
- package/lib/util/fs.js +2 -3
- package/lib/util/question.js +28 -0
- package/lib/util/term.js +5 -3
- package/npm-shrinkwrap.json +231 -1089
- package/package.json +13 -8
- package/bin/activate.js +0 -77
- package/lib/compile/asyncapi/channels.js +0 -22
- package/lib/compile/asyncapi/components/messageTraits/index.js +0 -89
- package/lib/compile/asyncapi/components/messages/index.js +0 -173
- package/lib/compile/asyncapi/components/schemas/annotations.js +0 -33
- package/lib/compile/asyncapi/components/schemas/array.js +0 -8
- package/lib/compile/asyncapi/components/schemas/cache.js +0 -14
- package/lib/compile/asyncapi/components/schemas/definition.js +0 -187
- package/lib/compile/asyncapi/components/schemas/enum.js +0 -16
- package/lib/compile/asyncapi/components/schemas/examples.js +0 -10
- package/lib/compile/asyncapi/components/schemas/index.js +0 -14
- package/lib/compile/asyncapi/components/schemas/localized.js +0 -29
- package/lib/compile/asyncapi/components/schemas/primitiveElement.js +0 -41
- package/lib/compile/asyncapi/components/schemas/ref.js +0 -45
- package/lib/compile/asyncapi/components/schemas/utils.js +0 -108
- package/lib/compile/asyncapi/index.js +0 -247
- package/lib/compile/asyncapi/message.js +0 -13
- package/lib/compile/asyncapi/utils.js +0 -27
- package/lib/compile/openapi/csdl2openapi.js +0 -2448
- package/lib/compile/openapi/index.js +0 -68
- package/lib/init/template/helm/files/chart/templates/NOTES.txt +0 -14
- package/lib/init/template/helm/files/chart/templates/_helpers.tpl +0 -28
- package/lib/init/template/helm/files/chart/values.root.schema.json +0 -61
- package/lib/init/template/helm/files/chart/values.schema.json +0 -366
- package/lib/init/template/helm-unified-runtime/files/Chart.yaml.hbs +0 -10
- package/lib/init/template/helm-unified-runtime/files/templates/_deployment_helpers.tpl +0 -90
- package/lib/init/template/helm-unified-runtime/files/templates/_helpers.tpl +0 -28
- package/lib/init/template/helm-unified-runtime/files/values.root.schema.json +0 -61
- package/lib/init/template/helm-unified-runtime/files/values.schema.json +0 -366
- package/lib/init/template/helm-unified-runtime/files/values.yaml.hbs +0 -26
- package/lib/init/template/helm-unified-runtime/package.json +0 -4
- package/lib/init/template/multitenancy/files/mtxs-configmap-java-approuter.yaml +0 -20
- package/lib/init/template/multitenancy/files/mtxs-configmap-java.yaml +0 -18
- package/lib/init/template/multitenancy/files/mtxs-configmap-nodejs-approuter.yaml +0 -12
- package/lib/init/template/multitenancy/files/mtxs-configmap-nodejs.yaml +0 -12
- package/lib/init/template/multitenancy/files/saas-registry-secret.yaml +0 -9
- package/lib/init/template/nodejs/files/eslint.config.js +0 -13
- package/lib/init/template/notebook/index.js +0 -11
- package/lib/init/template/samples/index.js +0 -9
- package/lib/mtx/activate.js +0 -238
- package/lib/mtx/extend.js +0 -173
- package/lib/util/exec.d.ts +0 -54
- package/lib/util/exec.js +0 -211
- /package/lib/{init/template/approuter/files → build/plugins/helm/files/plugins/approuter}/approuter-configmap.yaml +0 -0
- /package/lib/{init/template/connectivity/files → build/plugins/helm/files/plugins/connectivity}/connectivity-proxy-info.yaml +0 -0
- /package/lib/{init/template/html5-repo/files → build/plugins/helm/files/plugins/html5-repo}/html5-apps-deployer-configmap.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/_helpers.tpl +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/job.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/secret.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/service-account.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/templates/service-binding.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/content-deployment/values.schema.json +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/NOTES.txt +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/_api.tpl +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/_helpers.tpl +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/api-rule.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/network-policy.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/rbac.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/secret.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service-account.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service-binding.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/service.yaml +0 -0
- /package/lib/{init/template/helm/files → build/plugins/helm/files/subcharts}/web-application/templates/virtual-service.yaml +0 -0
- /package/lib/{init/template/helm-unified-runtime → build/plugins/helm}/files/templates/NOTES.txt +0 -0
- /package/lib/init/template/{nodejs/files → java}/.cdsrc.json +0 -0
- /package/lib/init/template/tiny-sample/files/nodejs/db/{data-model.cds → schema.cds} +0 -0
package/lib/mtx/activate.js
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
const fs = require('fs').promises;
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const axios = require('axios');
|
|
4
|
-
|
|
5
|
-
const cds = require('../cds');
|
|
6
|
-
const AuthManager = require('./auth_manager');
|
|
7
|
-
|
|
8
|
-
require('../util/axios').pruneErrors();
|
|
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');
|
|
16
|
-
|
|
17
|
-
const COMMAND_URL_SUFFIX = 'asyncActivate';
|
|
18
|
-
const COMMAND_URL_SUFFIX_SYNC = 'activate';
|
|
19
|
-
const UPDATE_CUSTOM_FILE_URL_SUFFIX = 'updateCustomTenantContent';
|
|
20
|
-
|
|
21
|
-
const I18N_WHITELIST = ['.properties', '.csv'];
|
|
22
|
-
|
|
23
|
-
const JOB_STATUS = {
|
|
24
|
-
QUEUED: 'QUEUED',
|
|
25
|
-
RUNNING: 'RUNNING',
|
|
26
|
-
FINISHED: 'FINISHED',
|
|
27
|
-
FAILED: 'FAILED'
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
async function checkFinished(jobId, statusUrl, params, finisher) {
|
|
31
|
-
const { status, error } = (await axios.get(statusUrl, params.get('reqAuth'))).data;
|
|
32
|
-
|
|
33
|
-
if ((status === JOB_STATUS.FINISHED || status === JOB_STATUS.FAILED) && !finisher.finished) {
|
|
34
|
-
finisher.finished = true;
|
|
35
|
-
clearInterval(finisher.timer);
|
|
36
|
-
if (status === JOB_STATUS.FAILED) {
|
|
37
|
-
return finisher.reject(getMessage(`Job ${jobId} failed`, { error }));
|
|
38
|
-
}
|
|
39
|
-
console.log('Extension active');
|
|
40
|
-
finisher.resolve();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
module.exports = class Activate {
|
|
45
|
-
|
|
46
|
-
static get COMMAND_URL_SUFFIX() { return COMMAND_URL_SUFFIX; }
|
|
47
|
-
static get COMMAND_URL_SUFFIX_SYNC() { return COMMAND_URL_SUFFIX_SYNC; }
|
|
48
|
-
static get UPDATE_CUSTOM_FILE_URL_SUFFIX() { return UPDATE_CUSTOM_FILE_URL_SUFFIX; }
|
|
49
|
-
|
|
50
|
-
static async run(injection, paramValues) {
|
|
51
|
-
const params = await AuthManager.login(paramValues);
|
|
52
|
-
|
|
53
|
-
if (process.env.DEBUG) {
|
|
54
|
-
console.log('Activating extension with parameters', JSON.stringify({
|
|
55
|
-
appUrl: params.get('appUrl'),
|
|
56
|
-
projectFolder: params.get('projectFolder'),
|
|
57
|
-
undeploy: params.get('undeploy'),
|
|
58
|
-
sync: params.get('sync')
|
|
59
|
-
}));
|
|
60
|
-
} else {
|
|
61
|
-
console.log('Activating extension located at', params.get('projectFolder'), 'to URL', params.get('appUrl'));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!await checkProject(params.get('projectFolder'))) {
|
|
65
|
-
throw params.get('projectFolder') + ' is not a valid extension project';
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
await this.runActivate(injection.cds, params);
|
|
70
|
-
if (params.get('wsdl')) {
|
|
71
|
-
await this.runCustomFileUpload(params);
|
|
72
|
-
}
|
|
73
|
-
} catch (error) {
|
|
74
|
-
handleHttpError(error, params, { command: 'activate' });
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
static async collectExtensionFiles(cds, projectFolder) {
|
|
79
|
-
|
|
80
|
-
const absoluteFolder = projectFolder;
|
|
81
|
-
const dbFolder = path.join(absoluteFolder, 'db');
|
|
82
|
-
const srvFolder = path.join(absoluteFolder, 'srv');
|
|
83
|
-
|
|
84
|
-
const resolvedPathDb = cds.resolve(dbFolder, { root: dbFolder });
|
|
85
|
-
const resolvedPathSrv = cds.resolve(srvFolder, { root: srvFolder });
|
|
86
|
-
|
|
87
|
-
let resolvedPaths = [];
|
|
88
|
-
if (resolvedPathSrv) {
|
|
89
|
-
resolvedPaths = resolvedPaths.concat(resolvedPathSrv);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (resolvedPathDb) {
|
|
93
|
-
resolvedPaths = resolvedPaths.concat(resolvedPathDb);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
let allFiles = new Map();
|
|
97
|
-
|
|
98
|
-
if (resolvedPaths.length < 1) {
|
|
99
|
-
console.warn('No extension files found');
|
|
100
|
-
return allFiles;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const csn = await cds.load(resolvedPaths);
|
|
104
|
-
const sources = csn.$sources || csn._sources;
|
|
105
|
-
|
|
106
|
-
const filteredSources = sources && sources.filter((entry) => {
|
|
107
|
-
if (! entry.startsWith(projectFolder)) {
|
|
108
|
-
/* Current file might be below the base model's node_modules, in which case compilation on server should succeed.
|
|
109
|
-
Otherwise, compilation will probably fail, with this message giving a hint. */
|
|
110
|
-
DEBUG?.(`Source file outside project folder will not be uploaded: ${entry}`);
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
const unixFilename = toUnixPath(entry);
|
|
114
|
-
return !/.*node_modules\/_base\/.*/.test(unixFilename);
|
|
115
|
-
}) || [];
|
|
116
|
-
|
|
117
|
-
const sourceFiles = await collectFileContent(filteredSources, projectFolder);
|
|
118
|
-
allFiles = new Map([...allFiles, ...sourceFiles]);
|
|
119
|
-
|
|
120
|
-
const modelFiles4I18n = { $sources: filteredSources };
|
|
121
|
-
|
|
122
|
-
let i18nFolders = cds.localize.folders4(modelFiles4I18n);
|
|
123
|
-
i18nFolders = i18nFolders.filter(i18nFolder => {
|
|
124
|
-
const unixFilename = toUnixPath(i18nFolder);
|
|
125
|
-
return !(/.*node_modules\/_base\/.*/.test(unixFilename));
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
i18nFolders.forEach(folder => {
|
|
129
|
-
const i18nFiles = collectFiles(projectFolder, folder, entry => {
|
|
130
|
-
const ext = path.extname(entry);
|
|
131
|
-
return I18N_WHITELIST.includes(ext);
|
|
132
|
-
});
|
|
133
|
-
allFiles = new Map([...allFiles, ...i18nFiles]);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
let pkgJson;
|
|
137
|
-
try {
|
|
138
|
-
pkgJson = await fs.readFile(path.join(absoluteFolder, 'package.json'), 'utf-8');
|
|
139
|
-
} catch (error) {
|
|
140
|
-
throw getMessage('No package.json file found', { error });
|
|
141
|
-
}
|
|
142
|
-
allFiles.set('package.json', pkgJson);
|
|
143
|
-
|
|
144
|
-
return allFiles;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
static collectCustomFiles(projectFolder) {
|
|
148
|
-
const wsdlFolder = path.join(projectFolder, 'wsdl');
|
|
149
|
-
|
|
150
|
-
const wsdlFiles = collectFiles(projectFolder, wsdlFolder);
|
|
151
|
-
if (wsdlFiles.size === 0) {
|
|
152
|
-
console.log('No custom files found');
|
|
153
|
-
}
|
|
154
|
-
return wsdlFiles;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
static async runActivate(cds, params) {
|
|
158
|
-
let activationUrl;
|
|
159
|
-
const isSync = params.get('sync');
|
|
160
|
-
|
|
161
|
-
return this.collectExtensionFiles(cds, params.get('projectFolder'))
|
|
162
|
-
.then(allFiles => {
|
|
163
|
-
if (allFiles.size === 0) {
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
console.log('Activating extension...');
|
|
168
|
-
|
|
169
|
-
const urlSuffix = isSync ? this.COMMAND_URL_SUFFIX_SYNC : this.COMMAND_URL_SUFFIX;
|
|
170
|
-
activationUrl = getMtxApiUrl(params.get('appUrl'), urlSuffix);
|
|
171
|
-
const requestOptions = Object.assign({
|
|
172
|
-
headers: {}
|
|
173
|
-
}, params.get('reqAuth'));
|
|
174
|
-
requestOptions.headers['Content-Type'] = 'application/json';
|
|
175
|
-
|
|
176
|
-
return axios.post(activationUrl, {
|
|
177
|
-
extension: [...allFiles],
|
|
178
|
-
undeployExtension: params.get('undeploy')
|
|
179
|
-
}, requestOptions);
|
|
180
|
-
})
|
|
181
|
-
.then(response => {
|
|
182
|
-
if (isSync || response === null) {
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const { jobID: jobId, statusPath } = response.data;
|
|
187
|
-
|
|
188
|
-
if (jobId === undefined) {
|
|
189
|
-
throw 'Activation failed: did not receive job ID';
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (!statusPath) {
|
|
193
|
-
throw `Job ${jobId} failed: did not receive job-status path`;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
DEBUG?.(`Job ID: ${jobId}`);
|
|
197
|
-
|
|
198
|
-
return new Promise((resolve, reject) => {
|
|
199
|
-
const statusUrl = concatUrls(params.get('appUrl'), statusPath);
|
|
200
|
-
const finisher = {
|
|
201
|
-
resolve,
|
|
202
|
-
reject,
|
|
203
|
-
finished: false,
|
|
204
|
-
timer: null
|
|
205
|
-
};
|
|
206
|
-
finisher.timer = setInterval(checkFinished.bind(undefined, jobId, statusUrl, params, finisher), 250);
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
static async runCustomFileUpload(params) {
|
|
212
|
-
console.log('Uploading custom files to', params.get('appUrl'), '...');
|
|
213
|
-
|
|
214
|
-
const customFiles = this.collectCustomFiles(params.get('projectFolder'));
|
|
215
|
-
|
|
216
|
-
const customFilesSerialized = [];
|
|
217
|
-
customFiles.forEach((value, key) => {
|
|
218
|
-
customFilesSerialized.push({
|
|
219
|
-
category: "wsdl",
|
|
220
|
-
name: key,
|
|
221
|
-
content: value
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
const customFileUrl = getMtxApiUrl(params.get('appUrl'), this.UPDATE_CUSTOM_FILE_URL_SUFFIX);
|
|
226
|
-
const requestOptions = Object.assign({
|
|
227
|
-
headers: {},
|
|
228
|
-
}, params.get('reqAuth'));
|
|
229
|
-
requestOptions.headers['Content-Type'] = 'application/json';
|
|
230
|
-
|
|
231
|
-
await axios.post(customFileUrl, {
|
|
232
|
-
content: customFilesSerialized
|
|
233
|
-
}, requestOptions);
|
|
234
|
-
|
|
235
|
-
console.log('Custom file upload finished');
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
}
|
package/lib/mtx/extend.js
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const axios = require('axios');
|
|
4
|
-
|
|
5
|
-
const AuthManager = require('./auth_manager');
|
|
6
|
-
|
|
7
|
-
require('../util/axios').pruneErrors();
|
|
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');
|
|
13
|
-
|
|
14
|
-
const COMMAND_URL_SUFFIX = 'content';
|
|
15
|
-
const CUSTOM_FILE_URL_SUFFIX = 'customTenantContent';
|
|
16
|
-
const CUSTOM_FILE_FOLDERS = ['wsdl'];
|
|
17
|
-
const DB_FOLDER = 'db';
|
|
18
|
-
const SRV_FOLDER = 'srv';
|
|
19
|
-
const TEMPLATE_FOLDER = 'tpl';
|
|
20
|
-
|
|
21
|
-
function folderExists(folder) {
|
|
22
|
-
return `${folder} already contains an extension project, use another directory or use --force.` +
|
|
23
|
-
'\nWhen using --force, make sure you are using a version control system (like git) to avoid data loss';
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
module.exports = class Extend {
|
|
27
|
-
|
|
28
|
-
static get COMMAND_URL_SUFFIX() { return COMMAND_URL_SUFFIX; }
|
|
29
|
-
static get CUSTOM_FILE_URL_SUFFIX() { return CUSTOM_FILE_URL_SUFFIX; }
|
|
30
|
-
|
|
31
|
-
static async storeFiles(content, targetDirectory, filter) {
|
|
32
|
-
fs.mkdirSync(targetDirectory, { recursive: true });
|
|
33
|
-
targetDirectory = fs.realpathSync(targetDirectory)
|
|
34
|
-
const writtenFiles = new Set();
|
|
35
|
-
const filesToWrite = new Map();
|
|
36
|
-
for (const [filename, filecontent] of content) {
|
|
37
|
-
const filepath = path.join(targetDirectory, filename);
|
|
38
|
-
if (filepath.startsWith(targetDirectory) && (!filter || await filter(filepath))) {
|
|
39
|
-
filesToWrite.set(filepath, filecontent);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
for (const [filepath, content] of [...filesToWrite.entries()]) {
|
|
43
|
-
const normalizedFilepath = normalizePath(filepath);
|
|
44
|
-
fs.mkdirSync(path.dirname(normalizedFilepath), { recursive: true });
|
|
45
|
-
fs.writeFileSync(normalizedFilepath, content);
|
|
46
|
-
writtenFiles.add(path.relative(process.cwd(), normalizedFilepath));
|
|
47
|
-
Extend._logWrittenFile(normalizedFilepath);
|
|
48
|
-
}
|
|
49
|
-
return writtenFiles;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
static async storeCustomFiles(directory, customFiles) {
|
|
53
|
-
const customFileMap = new Map();
|
|
54
|
-
customFiles.forEach(entry => {
|
|
55
|
-
if (entry.category === 'wsdl') {
|
|
56
|
-
const normalizedFilename = normalizePath(entry.name);
|
|
57
|
-
const folder = normalizedFilename.split(path.sep)[0];
|
|
58
|
-
if (CUSTOM_FILE_FOLDERS.includes(folder)) {
|
|
59
|
-
customFileMap.set(entry.name, entry.content);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
await Extend.storeFiles([...customFileMap], directory);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
static async storeTemplateFiles(templates, directory) {
|
|
67
|
-
await Extend.storeFiles(templates, directory, async filepath => {
|
|
68
|
-
const normalizedPath = normalizePath(filepath);
|
|
69
|
-
if (!isParent(path.join(directory, DB_FOLDER), normalizedPath) && !isParent(path.join(directory, SRV_FOLDER), normalizedPath)) {
|
|
70
|
-
console.log('Ignoring template', normalizedPath, ': not in', DB_FOLDER, 'or', SRV_FOLDER);
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
return true;
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
static async run(paramValues) {
|
|
78
|
-
const params = await AuthManager.login(paramValues);
|
|
79
|
-
|
|
80
|
-
if (process.env.DEBUG) {
|
|
81
|
-
console.log('\n\nCreating extension project with parameters', JSON.stringify({
|
|
82
|
-
appUrl: params.get('appUrl'),
|
|
83
|
-
projectFolder: params.get('projectFolder'),
|
|
84
|
-
subdomain: params.get('subdomain'),
|
|
85
|
-
passcode: params.get('passcode'),
|
|
86
|
-
username: params.get('username'),
|
|
87
|
-
password: params.get('password') ? '***' : 'undefined'
|
|
88
|
-
}));
|
|
89
|
-
} else {
|
|
90
|
-
console.log('\n\nCreating extension project for', params.get('appUrl'), 'subdomain', params.get('subdomain'), 'in folder', params.get('projectFolder'));
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const runOnExistingProject = await checkProject(params.get('projectFolder'));
|
|
94
|
-
if (runOnExistingProject && !(params.get('force') || params.get('templates'))) {
|
|
95
|
-
throw getMessage(folderExists(params.get('projectFolder')), { command: 'extend' });
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
await Extend.runExtend(params);
|
|
100
|
-
} catch (error) {
|
|
101
|
-
await handleHttpError(error, params, { command: 'extend' });
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
static async runExtend(params) {
|
|
106
|
-
const contentUrl = getMtxApiUrl(params.get('appUrl'), COMMAND_URL_SUFFIX);
|
|
107
|
-
const requestOptions = Object.assign({ retry: 0 }, params.get('reqAuth'));
|
|
108
|
-
|
|
109
|
-
console.log('Retrieving files...');
|
|
110
|
-
|
|
111
|
-
const [ response ] = (await axios.get(contentUrl, requestOptions)).data;
|
|
112
|
-
|
|
113
|
-
console.log('\nWriting files to', params.get('projectFolder'));
|
|
114
|
-
|
|
115
|
-
if (params.get('templates')) {
|
|
116
|
-
await Extend.storeTemplateFilesToTpl(response.templates, params.get('projectFolder'));
|
|
117
|
-
return; // only write templates
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const content = response.base.concat(response.extension);
|
|
121
|
-
|
|
122
|
-
await Extend.storeFiles(content, params.get('projectFolder'));
|
|
123
|
-
|
|
124
|
-
await fs.promises.mkdir(path.join(params.get('projectFolder'), DB_FOLDER), { recursive: true });
|
|
125
|
-
await fs.promises.mkdir(path.join(params.get('projectFolder'), SRV_FOLDER), { recursive: true });
|
|
126
|
-
|
|
127
|
-
console.log('\nPut database extension models into', DB_FOLDER, 'folder.');
|
|
128
|
-
console.log('Put service extension models into', SRV_FOLDER, 'folder.');
|
|
129
|
-
|
|
130
|
-
if (response.templates && response.templates.length > 0) {
|
|
131
|
-
// only write templates if there are no extensions so far
|
|
132
|
-
if (response.extension && response.extension.length === 0) {
|
|
133
|
-
console.log('Writing template files to', DB_FOLDER, 'and', SRV_FOLDER, 'folder');
|
|
134
|
-
await Extend.storeTemplateFiles(response.templates, params.get('projectFolder'));
|
|
135
|
-
} else {
|
|
136
|
-
console.log('Ignoring templates because extension is already active.');
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (params.get('wsdl')) {
|
|
141
|
-
console.log('Writing custom files');
|
|
142
|
-
const customFileUrl = getMtxApiUrl(params.get('appUrl'), CUSTOM_FILE_URL_SUFFIX);
|
|
143
|
-
const customFiles = (await axios.get(customFileUrl, requestOptions)).data;
|
|
144
|
-
await Extend.storeCustomFiles(params.get('projectFolder'), customFiles);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
static async storeTemplateFilesToTpl(templates, projectFolder) {
|
|
149
|
-
if (templates && templates.length > 0) {
|
|
150
|
-
const targetDirectory = path.join(projectFolder, TEMPLATE_FOLDER);
|
|
151
|
-
const targetExists = fs.existsSync(targetDirectory);
|
|
152
|
-
if (!targetExists || await this.promptTemplateOverwrite()) {
|
|
153
|
-
if (targetExists) {
|
|
154
|
-
await fs.promises.rm(targetDirectory, { force: true, recursive: true });
|
|
155
|
-
}
|
|
156
|
-
console.log('Writing template files to', TEMPLATE_FOLDER, 'folder');
|
|
157
|
-
await Extend.storeTemplateFiles(templates, targetDirectory);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
} else {
|
|
161
|
-
console.log('No templates available');
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
static promptTemplateOverwrite() {
|
|
166
|
-
return Question.askBooleanQuestion(`This will overwrite existing templates in folder ${TEMPLATE_FOLDER}. Continue (yN)? `);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
static _logWrittenFile(file) {
|
|
170
|
-
console.log('CREATE:', file);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
}
|
package/lib/util/exec.d.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Typings only for common use cases
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
interface AdditionalExecOptions {
|
|
6
|
-
acceptStatuses? : Array<Number> | '*',
|
|
7
|
-
appendEnv?: {[key: string]: string},
|
|
8
|
-
log?: object
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
interface SpawnReturns {
|
|
12
|
-
status : number,
|
|
13
|
-
stdout? : string,
|
|
14
|
-
stderr? : string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
import { SpawnOptions, SpawnSyncOptions, SpawnSyncReturns } from "child_process";
|
|
18
|
-
|
|
19
|
-
type execTemplate<T> = (template: TemplateStringsArray, ...args : any[]) => T;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Execute commands with template strings asynchronously.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
*
|
|
26
|
-
* await exec `ls -l .`
|
|
27
|
-
* await exec `ls -l ${'spaces are safe in expressions'}` => spawn('ls', [ '-l', 'spaces are safe in expressions' ])
|
|
28
|
-
* await exec `ls -l "dir ${'with spaces'}"
|
|
29
|
-
* await exec `ls -l ${['db', 'srv']}`
|
|
30
|
-
* const out = (await exec({stdio: ['inherit', 'pipe', 'inherit']}) `ls -l`).stdout
|
|
31
|
-
* const out = await exec({result: 'stdout}) `ls -l`
|
|
32
|
-
*/
|
|
33
|
-
export function exec( template : TemplateStringsArray, ...args : any[] ) : Promise<SpawnReturns>
|
|
34
|
-
export function exec( options : { result: 'stdout' | 'stderr' } & SpawnOptions & AdditionalExecOptions) : execTemplate<Promise<string>>;
|
|
35
|
-
export function exec( options : SpawnOptions & AdditionalExecOptions) : execTemplate<Promise<SpawnReturns>>;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Execute commands with template strings synchronously.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
*
|
|
42
|
-
* execSync `ls -l .`
|
|
43
|
-
* execSync `ls -l ${'spaces are safe in expressions'}` => spawn('ls', [ '-l', 'spaces are safe in expressions' ])
|
|
44
|
-
* execSync `ls -l "dir ${'with spaces'}"
|
|
45
|
-
* execSync `ls -l ${['db', 'srv']}`
|
|
46
|
-
* const out = (execSync({stdio: ['inherit', 'pipe', 'inherit']}) `ls -l`).stdout
|
|
47
|
-
* const out = execSync({result: 'stdout}) `ls -l`
|
|
48
|
-
*/
|
|
49
|
-
export function execSync( template : TemplateStringsArray, ...args : any[] ) : SpawnSyncReturns<string>;
|
|
50
|
-
export function execSync( options : { result: 'stdout' | 'stderr' } & SpawnSyncOptions & AdditionalExecOptions) : execTemplate<string>;
|
|
51
|
-
export function execSync( options : { encoding : 'buffer' | null } & SpawnOptions & AdditionalExecOptions) : execTemplate<SpawnSyncReturns<Buffer>>;
|
|
52
|
-
export function execSync( options : SpawnOptions & AdditionalExecOptions) : execTemplate<SpawnSyncReturns<string>>;
|
|
53
|
-
|
|
54
|
-
export { execSync as $ };
|
package/lib/util/exec.js
DELETED
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
const { spawn, spawnSync } = require('child_process');
|
|
2
|
-
|
|
3
|
-
const cds = require('../cds');
|
|
4
|
-
const log = cds.log('exec');
|
|
5
|
-
const DEBUG = cds.debug('exec');
|
|
6
|
-
|
|
7
|
-
function* commandIterator(strs, args) {
|
|
8
|
-
for (let i=0; i<strs.length; i++) {
|
|
9
|
-
const str = strs[i];
|
|
10
|
-
const regex = /((\s+)|(["'])|$)/g;
|
|
11
|
-
let match;
|
|
12
|
-
let lastIndex = 0;
|
|
13
|
-
do {
|
|
14
|
-
match = regex.exec(str);
|
|
15
|
-
if (match.index > lastIndex) {
|
|
16
|
-
yield { type: 'WORD', value: str.substr(lastIndex, match.index - lastIndex) };
|
|
17
|
-
}
|
|
18
|
-
if (match[2]) {
|
|
19
|
-
yield { type: 'SPACE', value: match[2] };
|
|
20
|
-
}
|
|
21
|
-
if (match[3]) {
|
|
22
|
-
yield { type: 'QUOTE', value: match[3] }
|
|
23
|
-
}
|
|
24
|
-
lastIndex = match.index + match[0].length;
|
|
25
|
-
} while (lastIndex < str.length);
|
|
26
|
-
|
|
27
|
-
if (args[i]) {
|
|
28
|
-
if (Array.isArray(args[i])) {
|
|
29
|
-
let sep = false;
|
|
30
|
-
for (const value of args[i]) {
|
|
31
|
-
if (sep) yield { type: 'SPACE', value: ' '};
|
|
32
|
-
yield { type: 'WORD', value };
|
|
33
|
-
sep = true;
|
|
34
|
-
}
|
|
35
|
-
} else {
|
|
36
|
-
yield { type: 'WORD', value: args[i] };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function processTemplate(strs, ...args) {
|
|
43
|
-
let quote;
|
|
44
|
-
const result = [];
|
|
45
|
-
let index = 0;
|
|
46
|
-
|
|
47
|
-
const append = str => result[index] = (result[index] || '') + str;
|
|
48
|
-
const push = () => { if (index < result.length) index++; };
|
|
49
|
-
|
|
50
|
-
for (const token of commandIterator(strs, args)) {
|
|
51
|
-
switch (token.type) {
|
|
52
|
-
case 'WORD':
|
|
53
|
-
append(token.value);
|
|
54
|
-
break;
|
|
55
|
-
case 'SPACE':
|
|
56
|
-
if (quote) {
|
|
57
|
-
append(token.value);
|
|
58
|
-
} else {
|
|
59
|
-
push();
|
|
60
|
-
}
|
|
61
|
-
break;
|
|
62
|
-
case 'QUOTE':
|
|
63
|
-
if (quote === token.value) {
|
|
64
|
-
quote = undefined;
|
|
65
|
-
} else if (quote) {
|
|
66
|
-
append(token.value);
|
|
67
|
-
} else {
|
|
68
|
-
quote = token.value;
|
|
69
|
-
}
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function fetchOptions(cmd) {
|
|
78
|
-
const { options, args } = cmd;
|
|
79
|
-
if (typeof args[0] === 'object' && !Array.isArray(args[0])) {
|
|
80
|
-
const newOptions = args[0];
|
|
81
|
-
cmd.options = {...options, ...newOptions};
|
|
82
|
-
cmd.args = args.slice(1);
|
|
83
|
-
return true;
|
|
84
|
-
} else {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function exec_func(...args) {
|
|
90
|
-
const cmd = { options: {
|
|
91
|
-
log,
|
|
92
|
-
acceptStatuses: [ 0 ],
|
|
93
|
-
stdio: 'inherit',
|
|
94
|
-
shell: false,
|
|
95
|
-
encoding: 'utf-8'
|
|
96
|
-
}, args };
|
|
97
|
-
|
|
98
|
-
let hasOptions = false;
|
|
99
|
-
while (fetchOptions(cmd)) hasOptions = true;
|
|
100
|
-
if (hasOptions && cmd.args.length === 0) {
|
|
101
|
-
return (...args) => exec_func(cmd.options, ...args);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (Array.isArray(cmd.args[0])) cmd.args = processTemplate(...cmd.args);
|
|
105
|
-
return cmd.options.executer(cmd.options, ...cmd.args);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function getExecOptions(options) {
|
|
109
|
-
const execOptions = {...options};
|
|
110
|
-
[ 'acceptStatuses', 'appendEnv', 'exec', 'log', 'result' ].forEach( name => delete execOptions[name] );
|
|
111
|
-
|
|
112
|
-
const { appendEnv, result } = options;
|
|
113
|
-
if (appendEnv) {
|
|
114
|
-
execOptions.env = {...(options.env || process.env),...appendEnv};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
switch (result) {
|
|
118
|
-
case 'stdout':
|
|
119
|
-
execOptions.stdio = [ 'inherit', 'pipe', 'inherit' ];
|
|
120
|
-
break;
|
|
121
|
-
case 'stderr':
|
|
122
|
-
execOptions.stdio = [ 'inherit', 'inherit', 'pipe' ];
|
|
123
|
-
break;
|
|
124
|
-
case undefined:
|
|
125
|
-
break;
|
|
126
|
-
|
|
127
|
-
default:
|
|
128
|
-
throw new Error `Unexpected "result" option: "${result}"`;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return execOptions;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function toString(a) {
|
|
135
|
-
return typeof a === 'string' ? a : Buffer.from(a).toString('utf-8');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function processResult(result, options) {
|
|
139
|
-
switch (options.result) {
|
|
140
|
-
case 'stdout':
|
|
141
|
-
return toString(result.stdout);
|
|
142
|
-
case 'stderr':
|
|
143
|
-
return toString(result.stderr);
|
|
144
|
-
case undefined:
|
|
145
|
-
return result;
|
|
146
|
-
|
|
147
|
-
default:
|
|
148
|
-
throw new Error(`Unexpected "result" option: "${result}"`);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
function executeSync(options = {}, command, ...args) {
|
|
154
|
-
const { acceptStatuses } = options;
|
|
155
|
-
const execOptions = getExecOptions(options);
|
|
156
|
-
|
|
157
|
-
DEBUG?.(`exec: ${command} ${args.map( v => v.match(/\s/) ? `"${v}"` : v ).join(' ')}`);
|
|
158
|
-
const result = spawnSync(command, args, execOptions);
|
|
159
|
-
|
|
160
|
-
if (acceptStatuses !== '*' && acceptStatuses.indexOf(result.status) === -1) throw new Error(`Command '${command} ${args.join(' ')}' returned with status code ${result.status}`);
|
|
161
|
-
return processResult(result, options);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
async function executeAsync(options = {}, command, ...args) {
|
|
165
|
-
const { acceptStatuses } = options;
|
|
166
|
-
const execOptions = getExecOptions(options);
|
|
167
|
-
|
|
168
|
-
// ctx.log(`exec: ${command} ${args.map( v => v.match(/\s/) ? `"${v}"` : v ).join(' ')}`);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const result = await new Promise( (resolve, reject) => {
|
|
172
|
-
const child = spawn(command, args, execOptions);
|
|
173
|
-
const stdoutChunks = [];
|
|
174
|
-
const stderrChunks = [];
|
|
175
|
-
|
|
176
|
-
if (child.stdout) {
|
|
177
|
-
child.stdout.on('data', data => {
|
|
178
|
-
stdoutChunks.push(Buffer.from(data));
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (child.stderr) {
|
|
183
|
-
child.stderr.on('data', data => {
|
|
184
|
-
stderrChunks.push(Buffer.from(data));
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const exit = status => {
|
|
189
|
-
if (acceptStatuses !== '*' && acceptStatuses.indexOf(status) === -1) reject(new Error(`Command '${command} ${args.join(' ')}' returned with status code ${status}`))
|
|
190
|
-
else resolve({
|
|
191
|
-
status,
|
|
192
|
-
stdout: child.stdout ? Buffer.concat(stdoutChunks).toString("utf-8") : undefined,
|
|
193
|
-
stderr: child.stderr ? Buffer.concat(stderrChunks).toString("utf-8") : undefined
|
|
194
|
-
})
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
child.on('close', exit);
|
|
198
|
-
child.on('exit', exit);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
return processResult(result, options);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const exec = exec_func({ executer: executeAsync });
|
|
205
|
-
const execSync = exec_func({ executer: executeSync });
|
|
206
|
-
|
|
207
|
-
module.exports = {
|
|
208
|
-
exec,
|
|
209
|
-
execSync,
|
|
210
|
-
$ : execSync
|
|
211
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|