@sap/cds-dk 6.8.2 → 7.0.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 +15 -7
- package/bin/add.js +29 -15
- package/bin/bind.js +49 -116
- package/bin/build.js +114 -0
- package/bin/cds.js +67 -24
- package/bin/compile/index.js +2 -2
- package/bin/deploy/index.js +46 -39
- package/bin/deploy/to-hana.js +11 -8
- package/bin/deploy/to-postgres.js +8 -2
- package/bin/deploy/to-sqlite.js +0 -1
- package/bin/env.js +75 -41
- package/bin/eval.js +3 -3
- package/bin/extend.js +17 -10
- package/bin/help.js +22 -21
- package/bin/import.js +10 -7
- package/bin/init.js +38 -17
- package/bin/login.js +69 -55
- package/bin/logout.js +12 -9
- package/bin/migrate.js +10 -4
- package/bin/pull.js +12 -5
- package/bin/push.js +24 -13
- package/bin/repl.js +1 -0
- package/bin/run.js +25 -0
- package/bin/subscribe.js +13 -8
- package/bin/unsubscribe.js +15 -8
- package/bin/upgrade.js +15 -9
- package/bin/util/log.js +24 -0
- package/bin/version.js +124 -0
- package/bin/watch.js +1 -35
- package/bin/watched.js +39 -0
- package/lib/bind/KubernetesApiAccessor.js +2 -2
- package/lib/bind/bindingManager.js +1 -1
- package/lib/bind/bindingUtil.js +0 -9
- package/lib/bind/cfKeyProvider.js +10 -72
- package/lib/bind/index.js +114 -0
- package/lib/bind/kubernetesCredentialsProvider.js +2 -2
- package/lib/bind/userCdsrcJsonStorageProvider.js +7 -44
- package/lib/build/buildTaskEngine.js +355 -0
- package/lib/build/buildTaskFactory.js +284 -0
- package/lib/build/buildTaskHandler.js +240 -0
- package/lib/build/buildTaskProvider.js +22 -0
- package/lib/build/buildTaskProviderFactory.js +182 -0
- package/lib/build/constants.js +56 -0
- package/lib/build/index.js +21 -0
- package/lib/build/provider/buildTaskHandlerEdmx.js +83 -0
- package/lib/build/provider/buildTaskHandlerFeatureToggles.js +132 -0
- package/lib/build/provider/buildTaskHandlerInternal.js +228 -0
- package/lib/build/provider/buildTaskProviderInternal.js +370 -0
- package/lib/build/provider/fiori/index.js +167 -0
- package/lib/build/provider/hana/2migration.js +179 -0
- package/lib/build/provider/hana/index.js +522 -0
- package/lib/build/provider/hana/migrationtable.js +472 -0
- package/lib/build/provider/hana/template/.hdiconfig-all +163 -0
- package/lib/build/provider/hana/template/.hdiconfig-cloud +137 -0
- package/lib/build/provider/hana/template/.hdinamespace +4 -0
- package/lib/build/provider/hana/template/package.json +12 -0
- package/lib/build/provider/hana/template/undeploy.json +5 -0
- package/lib/build/provider/java/index.js +93 -0
- package/lib/build/provider/java-cf/index.js +1 -0
- package/lib/build/provider/mtx/index.js +37 -0
- package/lib/build/provider/mtx/resourcesTarBuilder.js +94 -0
- package/lib/build/provider/mtx-extension/index.js +131 -0
- package/lib/build/provider/mtx-sidecar/index.js +138 -0
- package/lib/build/provider/node-cf/index.js +1 -0
- package/lib/build/provider/nodejs/index.js +178 -0
- package/lib/build/util.js +263 -0
- package/lib/cds.js +9 -21
- package/lib/client/auth_manager.js +39 -16
- package/lib/client/helper/dependency_helper.js +7 -6
- package/lib/client/push.js +2 -1
- package/lib/client/settings_manager.js +10 -39
- package/lib/deploy/to-hana/hana.js +273 -0
- package/lib/deploy/to-hana/hdiDeployUtil.js +68 -0
- package/lib/deploy/to-hana/mtaUtil.js +171 -0
- package/lib/import/asyncapi/importAsyncAPI.js +3 -2
- package/lib/import/asyncapi/index.js +5 -2
- package/lib/import/asyncapi/parserContext.js +67 -26
- package/lib/import/asyncapi/utils.js +34 -3
- package/lib/import/common.js +40 -30
- package/lib/import/importapi.js +36 -35
- package/lib/index.js +12 -17
- package/lib/init/constants.js +36 -71
- package/lib/init/index.js +18 -52
- package/lib/init/template/_merging/registry-mta.js +21 -3
- package/lib/init/template/approuter/files/mta.yaml.hbs +29 -29
- package/lib/init/template/approuter/files/values.yaml.hbs +5 -5
- package/lib/init/template/approuter/files/xs-app.json.hbs +8 -2
- package/lib/init/template/approuter/index.js +7 -8
- package/lib/init/template/auditlog/files/mta.yaml.hbs +5 -5
- package/lib/init/template/auditlog/files/package.json.hbs +13 -13
- package/lib/init/template/auditlog/index.js +3 -3
- package/lib/init/template/cf-manifest/files/manifest.yml.hbs +22 -22
- package/lib/init/template/cf-manifest/files/services-manifest.yml.hbs +3 -3
- package/lib/init/template/connectivity/files/mta.yaml.hbs +14 -0
- package/lib/init/template/connectivity/files/package.json.hbs +17 -0
- package/lib/init/template/connectivity/index.js +21 -4
- package/lib/init/template/data/index.js +5 -1
- package/lib/init/template/destination/files/mta.yaml.hbs +14 -0
- package/lib/init/template/destination/files/package.json.hbs +17 -0
- package/lib/init/template/{destinations → destination}/index.js +19 -13
- package/lib/init/template/enterprise-messaging/files/event-mesh.json.hbs +3 -3
- package/lib/init/template/enterprise-messaging/files/mta.yaml.hbs +5 -5
- package/lib/init/template/enterprise-messaging/files/package.json.hbs +9 -9
- package/lib/init/template/enterprise-messaging/files/xs-security.json.hbs +19 -0
- package/lib/init/template/enterprise-messaging/index.js +27 -6
- package/lib/init/template/enterprise-messaging-shared/files/event-mesh.json.hbs +3 -3
- package/lib/init/template/enterprise-messaging-shared/files/mta.yaml.hbs +5 -5
- package/lib/init/template/enterprise-messaging-shared/files/package.json.hbs +9 -9
- package/lib/init/template/enterprise-messaging-shared/index.js +4 -5
- package/lib/init/template/extensibility/files/package.json.hbs +10 -10
- package/lib/init/template/extensibility/index.js +8 -9
- package/lib/init/template/file-based-messaging/files/package.json.hbs +9 -9
- package/lib/init/template/file-based-messaging/index.js +3 -4
- package/lib/init/template/hana/files/db/package.json +1 -1
- package/lib/init/template/hana/files/mta.yaml.hbs +21 -21
- package/lib/init/template/hana/files/package.json.hbs +16 -22
- package/lib/init/template/hana/files/values.yaml.hbs +1 -1
- package/lib/init/template/hana/index.js +5 -15
- package/lib/init/template/helm/files/Chart.yaml.hbs +4 -4
- package/lib/init/template/helm/files/values.yaml.hbs +6 -6
- package/lib/init/template/helm/index.js +5 -10
- package/lib/init/template/helm/subcharts/content-deployment/Chart.yaml +2 -0
- package/lib/init/template/helm/subcharts/content-deployment/templates/_helpers.tpl +37 -31
- package/lib/init/template/helm/subcharts/content-deployment/templates/job.yaml +13 -14
- package/lib/init/template/helm/subcharts/content-deployment/templates/secret.yaml +2 -2
- package/lib/init/template/helm/subcharts/content-deployment/templates/service-account.yaml +1 -1
- package/lib/init/template/helm/subcharts/content-deployment/templates/service-binding.yaml +3 -3
- package/lib/init/template/helm/subcharts/content-deployment/values.md +116 -116
- package/lib/init/template/helm/subcharts/service-instance/Chart.yaml +2 -0
- package/lib/init/template/helm/subcharts/service-instance/templates/_helpers.tpl +9 -9
- package/lib/init/template/helm/subcharts/service-instance/templates/serviceinstance.yaml +2 -2
- package/lib/init/template/helm/subcharts/service-instance/values.md +15 -15
- package/lib/init/template/helm/subcharts/web-application/Chart.yaml +2 -0
- package/lib/init/template/helm/subcharts/web-application/templates/NOTES.txt +15 -0
- package/lib/init/template/helm/subcharts/web-application/templates/_helpers.tpl +23 -23
- package/lib/init/template/helm/subcharts/web-application/templates/api-rule.yaml +4 -4
- package/lib/init/template/helm/subcharts/web-application/templates/deployment.yaml +17 -17
- package/lib/init/template/helm/subcharts/web-application/templates/network-policy.yaml +24 -3
- package/lib/init/template/helm/subcharts/web-application/templates/pod-disruption-budget.yaml +3 -3
- package/lib/init/template/helm/subcharts/web-application/templates/secret.yaml +2 -2
- package/lib/init/template/helm/subcharts/web-application/templates/service-account.yaml +1 -1
- package/lib/init/template/helm/subcharts/web-application/templates/service-binding.yaml +3 -3
- package/lib/init/template/helm/subcharts/web-application/templates/service.yaml +3 -3
- package/lib/init/template/helm/subcharts/web-application/values.md +141 -123
- package/lib/init/template/helm/subcharts/web-application/values.schema.json +7 -0
- package/lib/init/template/helm/subcharts/web-application/values.yaml +1 -0
- package/lib/init/template/html5-repo/index.js +4 -5
- package/lib/init/template/java/index.js +5 -5
- package/lib/init/template/kibana-logging/files/mta.yaml.hbs +5 -5
- package/lib/init/template/kibana-logging/files/package.json.hbs +9 -9
- package/lib/init/template/kibana-logging/index.js +3 -4
- package/lib/init/template/lint/index.js +3 -3
- package/lib/init/template/mta/files/mta.yaml.hbs +14 -14
- package/lib/init/template/mta/files/package.json +5 -0
- package/lib/init/template/mta/index.js +12 -13
- package/lib/init/template/mtx/index.js +2 -2
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +29 -27
- package/lib/init/template/multitenancy/files/package.json.hbs +17 -14
- package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +7 -7
- package/lib/init/template/multitenancy/files/values.yaml.hbs +19 -19
- package/lib/init/template/multitenancy/index.js +14 -16
- package/lib/init/template/nodejs/files/package.json.hbs +1 -1
- package/lib/init/template/nodejs/index.js +5 -8
- package/lib/init/template/redis-messaging/files/mta.yaml.hbs +5 -5
- package/lib/init/template/redis-messaging/files/package.json.hbs +9 -9
- package/lib/init/template/redis-messaging/index.js +4 -5
- package/lib/init/template/sample/files/app/_i18n/i18n.properties +43 -0
- package/lib/init/template/sample/files/app/_i18n/i18n_de.properties +14 -0
- package/lib/init/template/sample/files/app/admin-books/fiori-service.cds +114 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/Component.js +8 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n.properties +11 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +129 -0
- package/lib/init/template/sample/files/app/appconfig/fioriSandboxConfig.json +57 -0
- package/lib/init/template/sample/files/app/common.cds +263 -0
- package/lib/init/template/sample/files/app/index.html +30 -0
- package/lib/init/template/sample/files/app/services.cds +5 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +5 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books.csv +6 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books_texts.csv +5 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.csv +16 -0
- package/lib/init/template/sample/files/db/schema.cds +31 -0
- package/lib/init/template/sample/files/nodejs/admin-service.js +12 -0
- package/lib/init/template/sample/files/nodejs/cat-service.js +26 -0
- package/lib/init/template/sample/files/srv/admin-service.cds +5 -0
- package/lib/init/template/sample/files/srv/cat-service.cds +16 -0
- package/lib/init/template/sample/index.js +24 -0
- package/lib/init/template/sample-tiny/index.js +39 -0
- package/lib/init/template/samples/index.js +5 -56
- package/lib/init/template/sqlite/files/package.json.hbs +13 -13
- package/lib/init/template/sqlite/index.js +2 -2
- package/lib/init/template/templateBase.js +24 -1
- package/lib/init/template/toggles/files/package.json.hbs +10 -10
- package/lib/init/template/toggles/index.js +3 -3
- package/lib/init/template/typer/files/gitignore +1 -0
- package/lib/init/template/typer/files/package.json +8 -0
- package/lib/init/template/typer/files/xsconfig.json +9 -0
- package/lib/init/template/typer/index.js +36 -0
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +12 -12
- package/lib/init/template/xsuaa/files/package.json.hbs +13 -13
- package/lib/init/template/xsuaa/files/values.yaml.hbs +8 -8
- package/lib/init/template/xsuaa/index.js +8 -19
- package/lib/init/util/merge.js +73 -59
- package/lib/init/util/mvn.js +21 -17
- package/lib/init/util/projectReader.js +49 -87
- package/lib/init/util/xml.js +14 -23
- package/lib/util/cfUtil.js +366 -0
- package/lib/util/command.js +3 -3
- package/lib/util/gitUtil.js +55 -0
- package/lib/util/version.js +27 -0
- package/npm-shrinkwrap.json +339 -277
- package/package.json +6 -6
- package/CHANGELOG.md +0 -1453
- package/bin/build/all.js +0 -88
- package/bin/build/index.js +0 -82
- package/lib/compile/index.js +0 -14
- /package/lib/init/template/{samples → sample-tiny}/files/nodejs/db/data/my.bookshop-Books.csv +0 -0
- /package/lib/init/template/{samples → sample-tiny}/files/nodejs/db/data-model.cds +0 -0
- /package/lib/init/template/{samples → sample-tiny}/files/nodejs/srv/cat-service.cds.hbs +0 -0
package/bin/activate.js
CHANGED
|
@@ -12,18 +12,21 @@ module.exports = Object.assign(activate, {
|
|
|
12
12
|
Activate an extension project.
|
|
13
13
|
By default, the current working directory is used as project directory.
|
|
14
14
|
|
|
15
|
-
To facilitate running this multiple times against the same app, refer to the
|
|
15
|
+
To facilitate running this multiple times against the same app, refer to the
|
|
16
|
+
*cds login* command.
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
# OPTIONS
|
|
19
20
|
|
|
20
21
|
*--to* <url>
|
|
21
22
|
|
|
22
|
-
Specify the URL of the extensible SaaS app. By default, it's determined
|
|
23
|
+
Specify the URL of the extensible SaaS app. By default, it's determined
|
|
24
|
+
from project settings.
|
|
23
25
|
|
|
24
26
|
*-s* | *--subdomain* <tenant-subdomain>
|
|
25
27
|
|
|
26
|
-
Specify your tenant's subdomain. By default, it's determined from
|
|
28
|
+
Specify your tenant's subdomain. By default, it's determined from
|
|
29
|
+
project settings.
|
|
27
30
|
|
|
28
31
|
*-p* | *--passcode* <passcode>
|
|
29
32
|
|
|
@@ -36,11 +39,13 @@ module.exports = Object.assign(activate, {
|
|
|
36
39
|
|
|
37
40
|
*-c* | *--clientid* <clientid>
|
|
38
41
|
|
|
39
|
-
Client ID for authentication. This will override the default Client ID
|
|
42
|
+
Client ID for authentication. This will override the default Client ID
|
|
43
|
+
from environment.
|
|
40
44
|
|
|
41
45
|
*--undeploy*
|
|
42
46
|
|
|
43
|
-
Undeploy a previously deployed extension, e.g. to remove a renamed or
|
|
47
|
+
Undeploy a previously deployed extension, e.g. to remove a renamed or
|
|
48
|
+
otherwise obsolete extension.
|
|
44
49
|
|
|
45
50
|
*--sync*
|
|
46
51
|
|
|
@@ -48,8 +53,11 @@ module.exports = Object.assign(activate, {
|
|
|
48
53
|
|
|
49
54
|
# SEE ALSO
|
|
50
55
|
|
|
51
|
-
*cds push* to push an extension to a SaaS app based on current MTX Services
|
|
52
|
-
|
|
56
|
+
*cds push* to push an extension to a SaaS app based on current MTX Services
|
|
57
|
+
(@sap/cds-mtxs).
|
|
58
|
+
|
|
59
|
+
https://cap.cloud.sap/docs/guides/multitenancy/mtxs for information on
|
|
60
|
+
@sap/cds-mtxs.
|
|
53
61
|
|
|
54
62
|
`})
|
|
55
63
|
|
package/bin/add.js
CHANGED
|
@@ -25,41 +25,55 @@ module.exports = Object.assign(add, {
|
|
|
25
25
|
|
|
26
26
|
*extensibility* - adds configuration for extensibility
|
|
27
27
|
|
|
28
|
-
*mtx* - adds configuration for multitenancy, feature toggles and
|
|
28
|
+
*mtx* - adds configuration for multitenancy, feature toggles and
|
|
29
|
+
extensibility
|
|
29
30
|
|
|
30
31
|
*approuter* - adds configuration for the Cloud Foundry approuter
|
|
31
32
|
|
|
32
|
-
*mta* - adds an _mta.yaml_ file for MTA-based SAP Business
|
|
33
|
+
*mta* - adds an _mta.yaml_ file for MTA-based SAP Business
|
|
34
|
+
Technology Platform deployment
|
|
33
35
|
|
|
34
|
-
*cf-manifest* - adds _manifest.yml_ and _services-manifest.yml_ files for
|
|
36
|
+
*cf-manifest* - adds _manifest.yml_ and _services-manifest.yml_ files for
|
|
37
|
+
Cloud Foundry native deployment
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
This approach makes use of the 'Create-Service-Push
|
|
40
|
+
Plugin' that has to be installed separately using
|
|
41
|
+
_cf install-plugin Create-Service-Push_.
|
|
42
|
+
_cf create-service-push_ creates the service(s) and pushes
|
|
43
|
+
the application(s) to the SAP Business Technology
|
|
44
|
+
Platform.
|
|
40
45
|
|
|
41
46
|
*pipeline* - adds files for CI/CD pipeline integration
|
|
42
47
|
|
|
43
|
-
*
|
|
48
|
+
*sample* - adds sample files including Fiori UI
|
|
49
|
+
|
|
50
|
+
*sample-tiny* - adds minimal sample files
|
|
44
51
|
|
|
45
52
|
*data* - adds data content for CSN model entities (as csv files)
|
|
46
53
|
|
|
47
|
-
*helm* - adds helm chart folder that contains the files needed to
|
|
54
|
+
*helm* - adds helm chart folder that contains the files needed to
|
|
55
|
+
deploy the application using Kyma.
|
|
48
56
|
|
|
49
|
-
*html5-repo* - adds configuration for HTML5 Application Deployer to Helm
|
|
57
|
+
*html5-repo* - adds configuration for HTML5 Application Deployer to Helm
|
|
58
|
+
Chart (Kyma Only).
|
|
50
59
|
|
|
51
60
|
|
|
52
61
|
# OPTIONS
|
|
53
62
|
|
|
63
|
+
*--for* <profile>
|
|
64
|
+
|
|
65
|
+
Writes configuration data, if any, under the given profile, like
|
|
66
|
+
\`"[production]": { "db": "hana" }\`
|
|
67
|
+
|
|
54
68
|
*--data:for* <entity name or prefix>
|
|
55
69
|
|
|
56
|
-
Adds data content for entities matching the given pattern. If it contains
|
|
57
|
-
'^' or '*', it is treated like a regular expression,
|
|
70
|
+
Adds data content for entities matching the given pattern. If it contains
|
|
71
|
+
meta characters like '^' or '*', it is treated like a regular expression,
|
|
72
|
+
otherwise as a prefix.
|
|
58
73
|
|
|
59
74
|
*-o* | *--out* <target folder>
|
|
60
75
|
|
|
61
|
-
Specifies output target folder (applicable
|
|
62
|
-
|
|
76
|
+
Specifies output target folder (applicable to data feature only)
|
|
63
77
|
|
|
64
78
|
*--force*
|
|
65
79
|
|
|
@@ -71,7 +85,7 @@ module.exports = Object.assign(add, {
|
|
|
71
85
|
*cds add* multitenancy
|
|
72
86
|
*cds add* hana,xsuaa --for production
|
|
73
87
|
*cds add* cf-manifest
|
|
74
|
-
*cds add* data --for my.
|
|
88
|
+
*cds add* data --data:for my.namespace.MyEntity
|
|
75
89
|
*cds add* helm
|
|
76
90
|
|
|
77
91
|
|
package/bin/bind.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
module.exports = Object.assign(cds_bind, {
|
|
2
|
-
options: ['--to', '--
|
|
2
|
+
options: ['--to', '--for', '--on', '--kind', '--output-file'],
|
|
3
3
|
flags: ['--exec'],
|
|
4
|
-
shortcuts: ['-2', '-
|
|
4
|
+
shortcuts: ['-2', '-4', '-n', '-k', '-o'],
|
|
5
5
|
help: `
|
|
6
6
|
# SYNOPSIS
|
|
7
7
|
|
|
8
8
|
*cds bind* <service> [<options>]
|
|
9
9
|
*cds bind --exec* [--profile <profile>] [--] <command> <args ...>
|
|
10
10
|
|
|
11
|
-
Binds the given service to a service instance by storing connection
|
|
12
|
-
in
|
|
11
|
+
Binds the given service to a service instance by storing connection
|
|
12
|
+
information in *.cdsrc-private.json*
|
|
13
|
+
in your project directory. Credentials are not stored in the file but rather
|
|
14
|
+
retrieved dynamically during *cds watch*.
|
|
13
15
|
Use option *--output-file* to specify a different path or file.
|
|
14
16
|
|
|
15
|
-
With *--exec* you can execute arbitrary commands with your service bindings.
|
|
17
|
+
With *--exec* you can execute arbitrary commands with your service bindings.
|
|
18
|
+
The service bindings are provided
|
|
16
19
|
in the *VCAP_SERVICES* env variable to the command.
|
|
17
20
|
|
|
18
21
|
# OPTIONS
|
|
@@ -20,12 +23,13 @@ module.exports = Object.assign(cds_bind, {
|
|
|
20
23
|
*-2 | --to* <instance>[:<key>] | <service-binding> | <secret>
|
|
21
24
|
bind to a given Cloud Foundry instance, Kubernetes service binding or Kubernetes secret.
|
|
22
25
|
|
|
26
|
+
*-4 | --for* <profile>
|
|
27
|
+
store binding information under <profile> in *.cdsrc-private.json*. Default *hybrid* is used
|
|
28
|
+
if '--for' is not specified
|
|
29
|
+
|
|
23
30
|
*-n | --on* cf | k8s
|
|
24
31
|
bind to service on Cloud Foundry or Kubernetes, defaults to Cloud Foundry
|
|
25
32
|
|
|
26
|
-
*-p | --profile* <profile>
|
|
27
|
-
add the given profile, defaults to *hybrid*
|
|
28
|
-
|
|
29
33
|
*-k | --kind* <kind>
|
|
30
34
|
the kind of service
|
|
31
35
|
|
|
@@ -37,123 +41,62 @@ module.exports = Object.assign(cds_bind, {
|
|
|
37
41
|
|
|
38
42
|
cds bind --to my-hdi-container
|
|
39
43
|
cds bind --to my-hdi-container,my-xsuaa
|
|
40
|
-
cds bind uaa --to my-xsuaa:my-xsuaa-key --kind xsuaa --
|
|
44
|
+
cds bind uaa --to my-xsuaa:my-xsuaa-key --kind xsuaa --for myprofile
|
|
41
45
|
|
|
42
46
|
cds bind --to my-hdi-container --output-file .
|
|
43
47
|
cds bind --to my-hdi-container --output-file package.json
|
|
44
48
|
|
|
45
49
|
cds bind --to my-hdi-container --on k8s
|
|
50
|
+
cds bind --to my-hdi-container --for my-profile
|
|
46
51
|
`
|
|
47
52
|
});
|
|
48
53
|
|
|
54
|
+
const os = require('os');
|
|
55
|
+
const IS_WIN = os.platform() === 'win32';
|
|
49
56
|
|
|
50
|
-
const
|
|
57
|
+
const { CliError } = require('../lib/client/helper/errors');
|
|
58
|
+
const { bind, parseProfile } = require('../lib/bind');
|
|
51
59
|
|
|
52
|
-
const { highlight, bold, info } = require('../lib/util/term');
|
|
53
|
-
|
|
54
|
-
const { determineKinds, getRequiresNameFromKind, execAndExit, checkIsJavaProject, platformText, bindingText, logger } = require('../lib/bind/bindingUtil');
|
|
55
60
|
|
|
56
61
|
async function cds_bind(args, options) {
|
|
57
62
|
|
|
58
|
-
options.profile = parseProfile(options.profile);
|
|
59
|
-
setProfile(options.profile);
|
|
60
|
-
|
|
61
63
|
if (options.exec) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
throw new Error(`use option --to or -2 to specify the target instance, e.g. cds bind --to myInstance:myService`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (args.length > 1) {
|
|
71
|
-
throw new Error(`Too many arguments: Please specify only one or no service.`);
|
|
64
|
+
process.env.CDS_ENV = parseProfile(process.env.CDS_ENV);
|
|
65
|
+
if (options.for) {
|
|
66
|
+
console.warn('Parameter --for is not supported in combination with --exec. Its value will be ignored.');
|
|
67
|
+
}
|
|
68
|
+
return cds_bind_exec(args)
|
|
72
69
|
}
|
|
73
70
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const targets = options.to.split(/,/g);
|
|
78
|
-
|
|
79
|
-
if (targets.length >= 2 && serviceArg) {
|
|
80
|
-
throw new Error(`Service argument cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the service argument.`);
|
|
71
|
+
// Check if cds command was bind. Don't abort in case of deploy
|
|
72
|
+
if (process.env.CDS_ENV && process.argv[2] === 'bind') {
|
|
73
|
+
throw new CliError('Option --profile is no longer supported. Use --for instead to specify the profile to use when storing connection settings.');
|
|
81
74
|
}
|
|
75
|
+
options.for = options.for ?? 'hybrid';
|
|
82
76
|
|
|
83
|
-
if (
|
|
84
|
-
throw new
|
|
77
|
+
if (!options.to) {
|
|
78
|
+
throw new CliError(`Use option --to or -2 to specify the target instance, e.g. cds bind --to myInstance:myService`);
|
|
85
79
|
}
|
|
86
80
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
on = 'k8s';
|
|
90
|
-
} else if (!options.on || options.on === 'cf' || options.on === 'cloudfoundry') {
|
|
91
|
-
on = 'cf';
|
|
92
|
-
} else {
|
|
93
|
-
throw new Error(`Invalid value '${options.on}' for option --on.`);
|
|
81
|
+
if (args.length > 1) {
|
|
82
|
+
throw new CliError(`Too many arguments: Please specify only one or no service.`);
|
|
94
83
|
}
|
|
95
84
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
let resolvedServices
|
|
99
|
-
|
|
100
|
-
try {
|
|
101
|
-
resolvedServices = await Promise.all(targets.map(async target => {
|
|
102
|
-
let binding;
|
|
103
|
-
if (on === 'k8s') {
|
|
104
|
-
binding = { type: on, name: target };
|
|
105
|
-
} else if (on === 'cf') {
|
|
106
|
-
const [instance, key] = target.split(/:/);
|
|
107
|
-
binding = { type: on, instance, key };
|
|
108
|
-
} else {
|
|
109
|
-
throw new Error('Internal Error');
|
|
110
|
-
}
|
|
111
|
-
const resolvedService = await BindingResolver.resolveBinding(undefined, binding);
|
|
112
|
-
resolvedService._target = target;
|
|
113
|
-
delete resolvedService.credentials;
|
|
114
|
-
resolvedService.binding.resolved = false;
|
|
115
|
-
return resolvedService;
|
|
116
|
-
}));
|
|
117
|
-
} catch (error) {
|
|
118
|
-
if (error.name === 'AxiosError') {
|
|
119
|
-
const errors = error.response?.data?.errors ?? []
|
|
120
|
-
const responseInfo = errors.map(e => `${e.title}: ${e.detail} (${e.code})`).join(' \n')
|
|
121
|
-
const requestInfo = error.request?.path
|
|
122
|
-
throw new Error(`${error.toString()}\nResponse: ${responseInfo}\nRequest:${requestInfo}}`)
|
|
123
|
-
}
|
|
124
|
-
throw error
|
|
125
|
-
}
|
|
85
|
+
options.serviceArg = args[0]
|
|
86
|
+
options.targets = options.to.split(/,/g);
|
|
126
87
|
|
|
127
|
-
if (options.
|
|
128
|
-
|
|
129
|
-
} else {
|
|
130
|
-
determineKinds(resolvedServices);
|
|
88
|
+
if (options.targets.length >= 2 && options.serviceArg) {
|
|
89
|
+
throw new CliError(`Service argument cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the service argument.`);
|
|
131
90
|
}
|
|
132
91
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
resolvedService.name = serviceArg;
|
|
136
|
-
} else if (resolvedService.kind) {
|
|
137
|
-
resolvedService.name = getRequiresNameFromKind(resolvedService.binding.instance, resolvedService.kind);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
let { kind, name, binding } = resolvedService;
|
|
141
|
-
name = name ?? `custom-service:${binding.instance || binding.secret}`
|
|
142
|
-
resolvedService.name = resolvedService.name ?? name
|
|
143
|
-
const kindText = kind ? ` with kind ${highlight(kind)}` : ''
|
|
144
|
-
const nameText = highlight(name)
|
|
145
|
-
|
|
146
|
-
logger.log(`Binding ${nameText} to ${platformText(binding)} ${bindingText(binding, highlight)}${kindText}`);
|
|
92
|
+
if (options.targets.length >= 2 && options.kind) {
|
|
93
|
+
throw new CliError(`The option '--kind' cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the '--kind' option.`);
|
|
147
94
|
}
|
|
148
95
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
await userCdsrcJsonStorageProvider.storeServices(resolvedServices, {
|
|
153
|
-
...options
|
|
96
|
+
await bind({
|
|
97
|
+
...options,
|
|
98
|
+
outputFile: options['output-file']
|
|
154
99
|
});
|
|
155
|
-
|
|
156
|
-
logger.log(`${info('TIP:')} Run with cloud bindings: ${bold(runCmd(options, isJavaProject))}`);
|
|
157
100
|
}
|
|
158
101
|
|
|
159
102
|
async function cds_bind_exec(command) { // eslint-disable-lint
|
|
@@ -168,23 +111,13 @@ async function cds_bind_exec(command) { // eslint-disable-lint
|
|
|
168
111
|
execAndExit({ env: processEnv }, ...command);
|
|
169
112
|
}
|
|
170
113
|
|
|
171
|
-
function
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
function setProfile(profile) {
|
|
182
|
-
profile = parseProfile(profile);
|
|
183
|
-
if (profile) process.env.CDS_ENV = profile;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function parseProfile(profile) {
|
|
187
|
-
if (!profile) return 'hybrid';
|
|
188
|
-
else if (profile === '-') return 'development';
|
|
189
|
-
else return profile;
|
|
114
|
+
function execAndExit(options, command, ...args) {
|
|
115
|
+
const { spawnSync } = require('child_process');
|
|
116
|
+
// use shell with Windows only; without output is not visible and some commands cannot be run
|
|
117
|
+
const result = spawnSync(command, args, {
|
|
118
|
+
stdio: 'inherit',
|
|
119
|
+
shell: IS_WIN,
|
|
120
|
+
...options
|
|
121
|
+
});
|
|
122
|
+
process.exit(result.status);
|
|
190
123
|
}
|
package/bin/build.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module.exports = Object.assign(build, {
|
|
2
|
+
options: ['--project', '--src', '--dest', '--for', '--use', '--opts', '--log-level', '--options-model', '--clean'],
|
|
3
|
+
shortcuts: ['-in', '-s', '-o', '-4'],
|
|
4
|
+
help: `
|
|
5
|
+
# SYNOPSIS
|
|
6
|
+
|
|
7
|
+
*cds build* [<project>] [<options>]
|
|
8
|
+
|
|
9
|
+
Builds all modules in the current project by compiling contained CDS
|
|
10
|
+
sources.
|
|
11
|
+
The modules are folders in the project root directory. All well known
|
|
12
|
+
modules (db, srv, app) or those configured by build tasks defined in
|
|
13
|
+
*package.json* or *.cdsrc.json* are built.
|
|
14
|
+
|
|
15
|
+
# OPTIONS
|
|
16
|
+
|
|
17
|
+
*-4 | --for* hana | java | nodejs | mtx | mtx-sidecar | mtx-extension
|
|
18
|
+
|
|
19
|
+
Name of the build task that is applied to the source folder, either
|
|
20
|
+
explicitly configured in the build task list or generated out of the
|
|
21
|
+
project setup
|
|
22
|
+
For example, the 'hana' build task will create SAP HANA artefacts.
|
|
23
|
+
The module folder can be defined using option '--src', a default is used
|
|
24
|
+
otherwise.
|
|
25
|
+
|
|
26
|
+
*-s | --src* <folder>
|
|
27
|
+
|
|
28
|
+
The module folder to build using the build task defined by option
|
|
29
|
+
'--for'.
|
|
30
|
+
This option is only supported when building an individual module of the
|
|
31
|
+
project.
|
|
32
|
+
The folder is resolved based on '<project>/<cds.env.build.target>'.
|
|
33
|
+
A default is used based on the type of the build task, for example, the
|
|
34
|
+
folder 'db' is used for a
|
|
35
|
+
*hana* build task, 'srv' for *nodejs* or *java* build task.
|
|
36
|
+
|
|
37
|
+
*-o | --dest* <folder>
|
|
38
|
+
|
|
39
|
+
Output folder of the build task. The type of build task is defined by
|
|
40
|
+
option '--for'.
|
|
41
|
+
The folder is resolved based on '<project>/<cds.env.build.target>'.
|
|
42
|
+
Default - folder defined by option '--src'.
|
|
43
|
+
Note: <cds.env.build.target> can be configured in *.cdsrc.json* or
|
|
44
|
+
*package.json*.
|
|
45
|
+
For Node.js projects the folder 'gen' is used by default. The output is
|
|
46
|
+
written to '<project>/gen/*<dest>*/*'.
|
|
47
|
+
For Java projects '.' is used by default. The output is written to
|
|
48
|
+
'<project>/*<dest>*/*'.
|
|
49
|
+
|
|
50
|
+
*--opts* <build task specific options>
|
|
51
|
+
|
|
52
|
+
Add a comma-separated list of build task specific options in the format
|
|
53
|
+
<opt1>=[value1,value2],<opt2>=value.
|
|
54
|
+
For example, --opts model=[db,srv,schema.cds] loads and compiles the CDS
|
|
55
|
+
model based on the given sources.
|
|
56
|
+
|
|
57
|
+
*--profile* <profile,...>
|
|
58
|
+
|
|
59
|
+
Loads the configuration data for the specified profile(s) and executes
|
|
60
|
+
'cds build' based on this profile settings.
|
|
61
|
+
E.g. you may want to create the HANA deployment artefacts only if the
|
|
62
|
+
*production* profile is set.
|
|
63
|
+
The *development* profile is used by default.
|
|
64
|
+
|
|
65
|
+
*--production*
|
|
66
|
+
|
|
67
|
+
Shortcut for '--profile production'
|
|
68
|
+
|
|
69
|
+
*--log-level* <debug | info | warn | error>
|
|
70
|
+
|
|
71
|
+
Choose which level of cds build messages to log, default is *warn*.
|
|
72
|
+
|
|
73
|
+
*-in | --project* [<project>]
|
|
74
|
+
|
|
75
|
+
Runs 'cds build' for the specified project, default is current working
|
|
76
|
+
directory.
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# EXAMPLES
|
|
80
|
+
|
|
81
|
+
*cds* build
|
|
82
|
+
*cds* build --production --log-level info
|
|
83
|
+
*cds* build --for hana
|
|
84
|
+
*cds* build --for java --src service1
|
|
85
|
+
*cds* build --for java --dest ../srv/target --opts model=[db/model,srv,schema]
|
|
86
|
+
`})
|
|
87
|
+
|
|
88
|
+
async function build([project], options = {}) {
|
|
89
|
+
const path = require('path')
|
|
90
|
+
const cds = require('../lib/cds')
|
|
91
|
+
|
|
92
|
+
// IMPORTANT: call plugins before subsequent access to cds.env
|
|
93
|
+
await cds.plugins
|
|
94
|
+
|
|
95
|
+
cds.root = path.resolve(process.cwd(), project || options.project || '.')
|
|
96
|
+
cds.env = cds.env.for('cds', cds.root);
|
|
97
|
+
delete options.project // avoid that relative project paths are resolved twice
|
|
98
|
+
|
|
99
|
+
options.cli = true // avoid that errors are logged twice
|
|
100
|
+
|
|
101
|
+
const { CliError } = require('../lib/client/helper/errors')
|
|
102
|
+
const { build } = require('../lib/build')
|
|
103
|
+
|
|
104
|
+
if (options.clean === "false") {
|
|
105
|
+
throw new CliError("cds build option '--clean' is deprecated - build output folders are always cleaned before build")
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (typeof options["options-model"] === "string") {
|
|
109
|
+
options.opts = "model=[" + options["options-model"].split(",").map((entry) => entry.trim()) + "]"
|
|
110
|
+
delete options["options-model"]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
await build(options)
|
|
114
|
+
}
|
package/bin/cds.js
CHANGED
|
@@ -17,7 +17,6 @@ const cli = { //NOSONAR
|
|
|
17
17
|
d: 'deploy',
|
|
18
18
|
l: 'login',
|
|
19
19
|
o: 'logout',
|
|
20
|
-
x: 'extend', '-a': 'activate',
|
|
21
20
|
t: 'lint',
|
|
22
21
|
v: 'version', '-v':'version', '--version':'version',
|
|
23
22
|
h: 'help', '?':'help', '-?':'help', '--help':'help',
|
|
@@ -31,50 +30,90 @@ const cli = { //NOSONAR
|
|
|
31
30
|
if (cmd in this.Shortcuts) cmd = process.argv[2] = this.Shortcuts[cmd]
|
|
32
31
|
if (argv.some(a => this.Shortcuts[a]==='help')) return this.help (cmd)
|
|
33
32
|
|
|
34
|
-
const
|
|
35
|
-
DEBUG?.(`[cds] - @sap/cds ${
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const args =
|
|
33
|
+
const cds = require('../lib/cds')
|
|
34
|
+
DEBUG?.(`[cds] - @sap/cds ${cds.version} loaded: ${cds.home}`)
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const task = this.load(cmd, /*else*/(f) => argv.unshift(cmd) && (cmd = 'compile') && _defaultCompile(argv, f))
|
|
38
|
+
if (task) {
|
|
39
|
+
// REVISIT bind: '--' handling for cds bind --exec. Should be moved to cds_cli
|
|
40
|
+
const endOfOptions = argv.indexOf('--')
|
|
41
|
+
let appendArgs = []
|
|
42
|
+
if (endOfOptions >= 0) {
|
|
43
|
+
appendArgs = argv.slice(endOfOptions + 1)
|
|
44
|
+
argv = argv.slice(0, endOfOptions)
|
|
45
|
+
}
|
|
46
|
+
const args = this.args(task, argv)
|
|
48
47
|
args[0].push(...appendArgs)
|
|
49
|
-
if (args[1]?.['resolve-bindings']) await _resolveBindings()
|
|
48
|
+
if (args[1]?.['resolve-bindings']) await _resolveBindings({ silent: cmd === 'env' })
|
|
49
|
+
cds.cli = {
|
|
50
|
+
command: cmd,
|
|
51
|
+
argv: args[0],
|
|
52
|
+
options: args[1],
|
|
53
|
+
}
|
|
50
54
|
return await task.apply(this, args)
|
|
51
|
-
} catch (e) {
|
|
52
|
-
process.exitCode = 1
|
|
53
|
-
if (e.messages) require('../lib/cds')._log (e.messages)
|
|
54
|
-
else console.error(e)
|
|
55
55
|
}
|
|
56
|
+
} catch (e) {
|
|
57
|
+
process.exitCode = 1
|
|
58
|
+
if (process.argv[1].endsWith('watched')) throw e // bin/watched.js handles errors
|
|
59
|
+
cds._log(e.messages?.length ? e.messages : e.message ?? e, { 'log-level': cds.env.log.levels.cli })
|
|
56
60
|
}
|
|
57
61
|
},
|
|
58
62
|
|
|
59
63
|
load (cmd,_default) {
|
|
60
|
-
if (cmd === 'build/all')
|
|
64
|
+
if (cmd === 'build/all') {
|
|
65
|
+
console.error(`'cds build/all' is no longer supported, use 'cds build' instead`)
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
61
69
|
return /[\\/.-@]/.test(cmd) && _default && _default(true) // like `cds ./srv` or `cds @capire/bookshop`
|
|
62
70
|
|| /cds/i.test(cmd) && _dieForUnknownCommand (cmd) // cds cds
|
|
63
71
|
|| _require ('./'+cmd) // cds-dk commands
|
|
64
|
-
|| _require ('@sap/cds/bin/'+cmd, {paths:[process.cwd(), __dirname]}) // prefer local cds for the rest
|
|
65
72
|
|| _default && _default()
|
|
66
73
|
|| _dieForUnknownCommand (cmd)
|
|
67
74
|
},
|
|
68
75
|
|
|
76
|
+
// TODO replace w/ common arg parser from node
|
|
77
|
+
args (task, argv) {
|
|
78
|
+
|
|
79
|
+
const { options:o=[], flags:f=[], shortcuts:s=[] } = task
|
|
80
|
+
const _global = /^--(profile|production|sql|odata|build-.*|cdsc-.*|odata-.*|folders-.*)$/
|
|
81
|
+
const _flags = { '--production':true }
|
|
82
|
+
const options = {}, args = []
|
|
83
|
+
let k,a, env = null
|
|
84
|
+
|
|
85
|
+
if (argv.length) for (let i=0; i < argv.length; ++i) {
|
|
86
|
+
if ((a = argv[i])[0] !== '-') args.push(a)
|
|
87
|
+
else if ((k = s.indexOf(a)) >= 0) k < o.length ? add(o[k],argv[++i]) : add(f[k-o.length])
|
|
88
|
+
else if ((k = o.indexOf(a)) >= 0) add(o[k],argv[++i])
|
|
89
|
+
else if ((k = f.indexOf(a)) >= 0) add(f[k])
|
|
90
|
+
else if (_global.test(a)) add_global(a, _flags[a] || argv[++i])
|
|
91
|
+
else throw 'Invalid option: '+ a
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function add (k,v) { options[k.slice(2)] = v || true }
|
|
95
|
+
function add_global (k,v='') {
|
|
96
|
+
if (k === '--production') process.env.CDS_ENV = [...process.env.CDS_ENV?.split(',') ?? [], 'production']
|
|
97
|
+
if (k === '--profile') process.env.CDS_ENV = [...process.env.CDS_ENV?.split(',') ?? [], ...v.split(',')]
|
|
98
|
+
if (k === '--odata') v = { flavor:v }
|
|
99
|
+
let e=env || (env={}), path = k.slice(2).split('-')
|
|
100
|
+
while (path.length > 1) { let p = path.shift(); e = e[p]||(e[p]={}) }
|
|
101
|
+
add (k, e[path[0]] = v)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (env) require('../lib/cds').env.add (env)
|
|
105
|
+
return [ args, options ]
|
|
106
|
+
},
|
|
107
|
+
|
|
69
108
|
help (cmd) { return this.exec ('help', cmd) }
|
|
70
109
|
}
|
|
71
110
|
|
|
72
111
|
const DEBUG = /\b(y|all|cli)\b/.test(process.env.DEBUG) ? console.debug : undefined
|
|
73
112
|
|
|
74
|
-
async function _resolveBindings() {
|
|
113
|
+
async function _resolveBindings(options) {
|
|
75
114
|
const cds = require('../lib/cds')
|
|
76
115
|
const BindingManager = require('../lib/bind/bindingManager')
|
|
77
|
-
const bindingManager = new BindingManager()
|
|
116
|
+
const bindingManager = new BindingManager(options)
|
|
78
117
|
const bindingEnv = await bindingManager.bindingEnv()
|
|
79
118
|
Object.assign(process.env, bindingEnv)
|
|
80
119
|
cds.env = cds.env.for('cds') // reload env
|
|
@@ -149,6 +188,10 @@ function _require (id,o) {
|
|
|
149
188
|
return require (resolved)
|
|
150
189
|
}
|
|
151
190
|
|
|
191
|
+
if (process[Symbol.for('ts-node.register.instance')]) {
|
|
192
|
+
process.env.CDS_TYPESCRIPT = process.env.CDS_TYPESCRIPT || 'true'
|
|
193
|
+
}
|
|
194
|
+
|
|
152
195
|
module.exports = Object.assign ((..._) => cli.exec(..._), cli)
|
|
153
196
|
|
|
154
197
|
if (!module.parent) module.exports()
|
package/bin/compile/index.js
CHANGED
|
@@ -135,7 +135,7 @@ module.exports = Object.assign ( compile, {
|
|
|
135
135
|
function compile_all (root='.') {
|
|
136
136
|
|
|
137
137
|
const {exec} = require ('child_process')
|
|
138
|
-
const cds = require('../../lib
|
|
138
|
+
const cds = require('../../lib') // get the enhanced cds w/ additional compile processors
|
|
139
139
|
|
|
140
140
|
exec(`find ${root} -name *.cds ! -path '*/node_modules/*'`, (_,stdout)=>{
|
|
141
141
|
const all = stdout.split('\n').slice(0,-1)
|
|
@@ -157,7 +157,7 @@ function compile (models, options={}) {
|
|
|
157
157
|
if (options.all) return compile_all (models[0])
|
|
158
158
|
|
|
159
159
|
const { inspect } = require('util')
|
|
160
|
-
const cds = require('../../lib
|
|
160
|
+
const cds = require('../../lib') // get the enhanced cds w/ additional compile processors
|
|
161
161
|
|
|
162
162
|
let model, src, _suffix; //> be filled in below
|
|
163
163
|
if (!options.as && !/,/.test(options.to)) options.as = 'str'
|