@sap/cds 5.4.6 → 5.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/CHANGELOG.md +208 -2
- package/apis/ql.d.ts +17 -15
- package/app/index.js +1 -1
- package/bin/build/buildTaskEngine.js +26 -42
- package/bin/build/buildTaskFactory.js +6 -10
- package/bin/build/buildTaskHandler.js +2 -4
- package/bin/build/buildTaskProvider.js +3 -1
- package/bin/build/buildTaskProviderFactory.js +9 -15
- package/bin/build/constants.js +15 -3
- package/bin/build/index.js +5 -4
- package/bin/build/mtaUtil.js +8 -11
- package/bin/build/provider/buildTaskHandlerEdmx.js +63 -6
- package/bin/build/provider/buildTaskHandlerInternal.js +2 -34
- package/bin/build/provider/buildTaskProviderInternal.js +16 -42
- package/bin/build/provider/fiori/index.js +13 -24
- package/bin/build/provider/hana/2migration.js +17 -15
- package/bin/build/provider/hana/2tabledata.js +52 -48
- package/bin/build/provider/hana/index.js +27 -25
- package/bin/build/provider/hana/migrationtable.js +91 -67
- package/bin/build/provider/java-cf/index.js +14 -24
- package/bin/build/provider/mtx/index.js +12 -14
- package/bin/build/provider/node-cf/index.js +18 -32
- package/bin/cds.js +5 -5
- package/bin/serve.js +29 -23
- package/bin/version.js +0 -1
- package/lib/compile/etc/_localized.js +4 -9
- package/lib/compile/for/sql.js +5 -2
- package/lib/compile/parse.js +25 -17
- package/lib/compile/to/srvinfo.js +2 -1
- package/lib/connect/bindings.js +2 -1
- package/lib/connect/index.js +48 -49
- package/lib/core/classes.js +1 -1
- package/lib/core/reflect.js +10 -2
- package/lib/deploy.js +26 -23
- package/lib/env/defaults.js +13 -6
- package/lib/env/index.js +73 -78
- package/lib/env/requires.js +38 -19
- package/lib/index.js +9 -10
- package/lib/lazy.js +2 -2
- package/lib/log/index.js +33 -45
- package/lib/log/service/index.js +2 -2
- package/lib/ql/CREATE.js +14 -9
- package/lib/ql/DELETE.js +6 -5
- package/lib/ql/DROP.js +12 -9
- package/lib/ql/INSERT.js +40 -16
- package/lib/ql/Query.js +67 -40
- package/lib/ql/SELECT.js +162 -127
- package/lib/ql/UPDATE.js +74 -42
- package/lib/ql/Whereable.js +77 -87
- package/lib/ql/index.js +36 -24
- package/lib/ql/parse.js +35 -0
- package/lib/req/context.js +44 -8
- package/lib/req/locale.js +7 -7
- package/lib/serve/Service-api.js +21 -14
- package/lib/serve/Service-dispatch.js +28 -12
- package/lib/serve/Transaction.js +22 -10
- package/lib/serve/index.js +16 -11
- package/lib/utils/axios.js +23 -16
- package/lib/utils/data.js +35 -0
- package/lib/utils/tests.js +27 -18
- package/libx/_runtime/audit/generic/personal/access.js +81 -0
- package/libx/_runtime/audit/generic/personal/constants.js +4 -0
- package/libx/_runtime/audit/generic/personal/index.js +50 -0
- package/libx/_runtime/audit/generic/personal/modification.js +138 -0
- package/libx/_runtime/audit/generic/personal/utils.js +186 -0
- package/libx/_runtime/audit/utils/v2.js +10 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +5 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +5 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +2 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +4 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +7 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +59 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +11 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +6 -10
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +3 -46
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +2 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/createToCQN.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/deleteToCQN.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +1 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +0 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectHelper.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/updateToCQN.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +16 -18
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityType.js +6 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/format/RepresentationKind.js +4 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/OdataRequest.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +15 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/validator/OperationValidator.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +8 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +6 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +12 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +1 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +7 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +14 -18
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +13 -13
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -1
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +2 -1
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +2 -2
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +2 -4
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +4 -2
- package/libx/_runtime/cds-services/services/Service.js +40 -5
- package/libx/_runtime/cds-services/services/utils/columns.js +13 -7
- package/libx/_runtime/cds-services/services/utils/compareJson.js +88 -4
- package/libx/_runtime/cds-services/services/utils/differ.js +24 -6
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +2 -2
- package/libx/_runtime/common/composition/data.js +44 -55
- package/libx/_runtime/common/composition/delete.js +97 -71
- package/libx/_runtime/common/composition/index.js +2 -1
- package/libx/_runtime/common/composition/insert.js +34 -11
- package/libx/_runtime/common/composition/tree.js +119 -92
- package/libx/_runtime/common/composition/update.js +4 -1
- package/libx/_runtime/common/composition/utils.js +1 -3
- package/libx/_runtime/common/constants/draft.js +12 -1
- package/libx/_runtime/common/generic/auth.js +6 -22
- package/libx/_runtime/common/generic/crud.js +14 -13
- package/libx/_runtime/common/generic/input.js +23 -26
- package/libx/_runtime/common/generic/put.js +1 -1
- package/libx/_runtime/common/generic/sorting.js +16 -16
- package/libx/_runtime/common/i18n/index.js +1 -1
- package/libx/_runtime/common/i18n/messages.properties +4 -0
- package/libx/_runtime/common/utils/backlinks.js +12 -5
- package/libx/_runtime/common/utils/cqn.js +6 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +102 -101
- package/libx/_runtime/common/utils/csn.js +47 -4
- package/libx/_runtime/common/utils/data.js +0 -37
- package/libx/_runtime/common/utils/enrichWithKeysFromWhere.js +1 -1
- package/libx/_runtime/common/utils/entityFromCqn.js +7 -24
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +39 -7
- package/libx/_runtime/common/utils/generateOnCond.js +11 -12
- package/libx/_runtime/common/utils/onlyKeysRemain.js +10 -0
- package/libx/_runtime/common/utils/path.js +35 -0
- package/libx/_runtime/common/utils/postProcessing.js +86 -0
- package/libx/_runtime/common/utils/quotingStyles.js +37 -26
- package/libx/_runtime/common/utils/resolveView.js +223 -171
- package/libx/_runtime/common/utils/rewriteAsterisk.js +46 -26
- package/libx/_runtime/common/utils/structured.js +6 -12
- package/libx/_runtime/common/utils/template.js +10 -5
- package/libx/_runtime/common/utils/templateDelimiter.js +1 -0
- package/libx/_runtime/common/utils/templateProcessor.js +22 -30
- package/libx/_runtime/common/utils/union.js +31 -0
- package/libx/_runtime/common/utils/unionCqnTemplate.js +184 -0
- package/libx/_runtime/db/Service.js +1 -1
- package/libx/_runtime/db/data-conversion/timestamp.js +2 -9
- package/libx/_runtime/db/expand/expandCQNToJoin.js +204 -297
- package/libx/_runtime/db/expand/index.js +3 -3
- package/libx/_runtime/db/expand/rawToExpanded.js +36 -7
- package/libx/_runtime/db/generic/index.js +1 -1
- package/libx/_runtime/db/generic/input.js +5 -7
- package/libx/_runtime/db/generic/integrity.js +1 -1
- package/libx/_runtime/db/generic/rewrite.js +2 -10
- package/libx/_runtime/db/generic/update.js +13 -5
- package/libx/_runtime/db/generic/virtual.js +22 -58
- package/libx/_runtime/db/query/delete.js +7 -4
- package/libx/_runtime/db/query/insert.js +6 -4
- package/libx/_runtime/db/query/read.js +13 -20
- package/libx/_runtime/db/query/run.js +4 -1
- package/libx/_runtime/db/query/update.js +5 -4
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +35 -2
- package/libx/_runtime/db/sql-builder/FunctionBuilder.js +17 -2
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +6 -5
- package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +10 -0
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +35 -24
- package/libx/_runtime/db/sql-builder/UpdateBuilder.js +14 -4
- package/libx/_runtime/db/sql-builder/arrayed.js +4 -0
- package/libx/_runtime/db/utils/deep.js +8 -0
- package/libx/_runtime/db/utils/generateAliases.js +2 -1
- package/libx/_runtime/fiori/generic/activate.js +19 -15
- package/libx/_runtime/fiori/generic/before.js +3 -11
- package/libx/_runtime/fiori/generic/cancel.js +1 -1
- package/libx/_runtime/fiori/generic/delete.js +3 -1
- package/libx/_runtime/fiori/generic/edit.js +12 -2
- package/libx/_runtime/fiori/generic/new.js +5 -5
- package/libx/_runtime/fiori/generic/patch.js +0 -18
- package/libx/_runtime/fiori/generic/read.js +241 -189
- package/libx/_runtime/fiori/utils/delete.js +36 -7
- package/libx/_runtime/fiori/utils/handler.js +43 -44
- package/libx/_runtime/fiori/utils/where.js +30 -15
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +4 -6
- package/libx/_runtime/hana/execute.js +2 -2
- package/libx/_runtime/hana/localized.js +4 -4
- package/libx/_runtime/hana/pool.js +29 -14
- package/libx/_runtime/hana/search2cqn4sql.js +2 -1
- package/libx/_runtime/hana/searchToContains.js +18 -14
- package/libx/_runtime/index.js +0 -5
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +13 -5
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +4 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +31 -19
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +1 -2
- package/libx/_runtime/messaging/enterprise-messaging.js +6 -4
- package/libx/_runtime/messaging/service.js +7 -6
- package/libx/_runtime/odata/cqn2odata.js +110 -43
- package/libx/_runtime/odata/index.js +26 -48
- package/libx/_runtime/odata/odata2cqn.js +1 -6154
- package/libx/_runtime/odata/odata2cqn.pegjs +559 -0
- package/libx/_runtime/odata/readToCqn.js +94 -64
- package/libx/_runtime/remote/Service.js +74 -21
- package/libx/_runtime/remote/cqn2odata/index.js +1 -5
- package/libx/_runtime/remote/utils/client.js +24 -101
- package/libx/_runtime/remote/utils/dataConversion.js +27 -12
- package/libx/_runtime/sqlite/Service.js +3 -5
- package/libx/_runtime/sqlite/execute.js +23 -24
- package/libx/_runtime/sqlite/localized.js +12 -7
- package/libx/_runtime/types/api.js +10 -0
- package/package.json +1 -1
- package/server.js +16 -2
- package/lib/ql/grammar.pegjs +0 -208
- package/lib/ql/parser.js +0 -1
- package/lib/ql/rt/DELETE.js +0 -29
- package/lib/ql/rt/INSERT.js +0 -23
- package/lib/ql/rt/Query.js +0 -84
- package/lib/ql/rt/SELECT.js +0 -174
- package/lib/ql/rt/UPDATE.js +0 -119
- package/lib/ql/rt/_helpers.js +0 -91
- package/lib/ql/rt/index.js +0 -32
- package/libx/_runtime/audit/generic/personal.js +0 -260
- package/libx/_runtime/cds-services/statements/BaseStatement.js +0 -72
- package/libx/_runtime/cds-services/statements/Create.js +0 -57
- package/libx/_runtime/cds-services/statements/Delete.js +0 -33
- package/libx/_runtime/cds-services/statements/Drop.js +0 -42
- package/libx/_runtime/cds-services/statements/Insert.js +0 -201
- package/libx/_runtime/cds-services/statements/Select.js +0 -826
- package/libx/_runtime/cds-services/statements/Update.js +0 -181
- package/libx/_runtime/cds-services/statements/Where.js +0 -726
- package/libx/_runtime/cds-services/statements/index.js +0 -25
- package/libx/_runtime/common/generic/resolve-mock.js +0 -9
|
@@ -4,10 +4,8 @@ const path = require('path')
|
|
|
4
4
|
const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
|
|
5
5
|
const { isOldJavaStack, BuildError } = require('../../util')
|
|
6
6
|
|
|
7
|
-
const { BUILD_OPTION_OUTPUT_MODE, ODATA_VERSION, ODATA_VERSION_V2,
|
|
8
|
-
OUTPUT_MODE_RESULT_ONLY, FILE_EXT_CDS, SKIP_ASSERT_COMPILER_V2 } = require('../../constants')
|
|
7
|
+
const { BUILD_OPTION_OUTPUT_MODE, ODATA_VERSION, ODATA_VERSION_V2, OUTPUT_MODE_RESULT_ONLY, FILE_EXT_CDS, SKIP_ASSERT_COMPILER_V2, CONTENT_LANGUAGE_BUNDLES, CONTENT_DEFAULT_CSN } = require('../../constants')
|
|
9
8
|
const { INFO } = require('../../buildTaskHandler')
|
|
10
|
-
const DEBUG = process.env.DEBUG
|
|
11
9
|
|
|
12
10
|
const DEFAULT_COMPILE_DEST_FOLDER = path.normalize('src/main/resources/edmx')
|
|
13
11
|
|
|
@@ -45,9 +43,13 @@ class JavaCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
45
43
|
return this._result
|
|
46
44
|
}
|
|
47
45
|
|
|
48
|
-
const odata = await this.
|
|
49
|
-
await this.
|
|
46
|
+
const odata = await this._compileForOdata(model, this.task.options.compileDest, odataOptions)
|
|
47
|
+
await this.compileToEdmx(odata, this.task.options.compileDest, odataOptions)
|
|
50
48
|
|
|
49
|
+
if (this.hasBuildOption(CONTENT_LANGUAGE_BUNDLES, true)) {
|
|
50
|
+
// collect and write language bundles into single i18n.json file
|
|
51
|
+
await this.collectLanguageBundles(model, this.task.dest)
|
|
52
|
+
}
|
|
51
53
|
if (!this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
|
|
52
54
|
await this._copyNativeContent(src, dest)
|
|
53
55
|
}
|
|
@@ -59,9 +61,7 @@ class JavaCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
59
61
|
await super.clean()
|
|
60
62
|
return
|
|
61
63
|
}
|
|
62
|
-
|
|
63
|
-
this.logger.log(`Deleting build target folder ${this.task.options.compileDest}`)
|
|
64
|
-
}
|
|
64
|
+
this.logger._debug && this.logger.debug(`Deleting build target folder ${this.task.options.compileDest}`)
|
|
65
65
|
await fs.remove(this.task.options.compileDest)
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -76,7 +76,7 @@ class JavaCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
76
76
|
})
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
async
|
|
79
|
+
async _compileForOdata(model, csnDest, compileOptions) {
|
|
80
80
|
// csn for service providers
|
|
81
81
|
const odataOptions = {
|
|
82
82
|
...this._options4odata(),
|
|
@@ -84,21 +84,11 @@ class JavaCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
84
84
|
}
|
|
85
85
|
const odataModel = this.cds.compile.for.odata(model, odataOptions)
|
|
86
86
|
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// This ensures that the paths are relative to the cwd when executing cds run.
|
|
93
|
-
const jsonOptions = {
|
|
94
|
-
cwd: this.buildOptions.root,
|
|
95
|
-
src: this.task.src === this.task.dest ? this.task.src : this.buildOptions.root
|
|
96
|
-
}
|
|
97
|
-
const extCsn = this.cds.compile.to.json(odataModel, jsonOptions)
|
|
98
|
-
this._result.csn = JSON.parse(extCsn)
|
|
99
|
-
|
|
100
|
-
if (!this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
|
|
101
|
-
await this.write(extCsn).to(path.join(csnDest, 'csn.json'))
|
|
87
|
+
// adding csn to build result containing @source and _where persisted properties
|
|
88
|
+
if (this.hasBuildOption(CONTENT_DEFAULT_CSN, true)) { //default true or undefined
|
|
89
|
+
await this.compileToJson(model, csnDest)
|
|
90
|
+
} else {
|
|
91
|
+
await this.compileToJson(odataModel, csnDest)
|
|
102
92
|
}
|
|
103
93
|
return odataModel
|
|
104
94
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/* eslint-disable no-empty */
|
|
2
2
|
const { fs } = require('@sap/cds-foss')
|
|
3
3
|
const path = require('path')
|
|
4
|
-
const BuildTaskHandlerInternal = require('../buildTaskHandlerInternal')
|
|
5
|
-
const BuildTaskProviderInternal = require('../buildTaskProviderInternal')
|
|
6
4
|
const { BUILD_TASK_HANA, FOLDER_GEN } = require('../../constants')
|
|
7
5
|
const { WARNING } = require('../../buildTaskHandler')
|
|
8
|
-
const
|
|
6
|
+
const BuildTaskProviderInternal = require("../buildTaskProviderInternal")
|
|
7
|
+
const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
|
|
9
8
|
|
|
10
9
|
const FOLDER_SDC = "sdc"
|
|
11
10
|
const FOLDER_NODE_MODULES = "node_modules"
|
|
12
11
|
const FOLDER_TEMPLATES = "tpl"
|
|
13
12
|
|
|
14
|
-
class MtxModuleBuilder extends
|
|
13
|
+
class MtxModuleBuilder extends BuildTaskHandlerEdmx {
|
|
15
14
|
get priority() {
|
|
16
15
|
// should be scheduled after all other build tasks are finished
|
|
17
|
-
return
|
|
16
|
+
return BuildTaskHandlerEdmx.PRIORITY_MIN_VALUE
|
|
18
17
|
}
|
|
19
18
|
init() {
|
|
19
|
+
super.init()
|
|
20
20
|
if (this.buildOptions.root === this.buildOptions.target) {
|
|
21
21
|
this.task.dest = path.join(this.task.dest, FOLDER_GEN, FOLDER_SDC)
|
|
22
22
|
} else {
|
|
@@ -38,19 +38,19 @@ class MtxModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
38
38
|
// copy base model sources
|
|
39
39
|
await Promise.all(model.$sources.map(src => {
|
|
40
40
|
if (src.includes(FOLDER_NODE_MODULES)) {
|
|
41
|
-
return this.copy(src).to(
|
|
41
|
+
return this.copy(src).to(src.substr(src.indexOf(FOLDER_NODE_MODULES)))
|
|
42
42
|
} else {
|
|
43
43
|
const relSrc = path.relative(this.buildOptions.root, src)
|
|
44
44
|
if (relSrc.startsWith("..")) {
|
|
45
|
-
this.logger.warn(`
|
|
45
|
+
this.logger.warn(`model file is out of project scope, skipping file ${src}`)
|
|
46
46
|
return Promise.resolve()
|
|
47
47
|
}
|
|
48
|
-
return this.copy(src).to(
|
|
48
|
+
return this.copy(src).to(relSrc)
|
|
49
49
|
}
|
|
50
50
|
}))
|
|
51
51
|
|
|
52
52
|
// collect and write language bundles into single i18n.json file
|
|
53
|
-
await this.
|
|
53
|
+
await this.collectLanguageBundles(model, this.task.dest)
|
|
54
54
|
|
|
55
55
|
// copy native hana content and templates
|
|
56
56
|
await this._copyNativeContent(this.task.src, this.task.dest, tenantDbPath)
|
|
@@ -62,9 +62,7 @@ class MtxModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
62
62
|
// delete entire folder 'gen'
|
|
63
63
|
const genDest = path.dirname(this.task.dest)
|
|
64
64
|
if (path.basename(genDest) === FOLDER_GEN) {
|
|
65
|
-
|
|
66
|
-
this.logger.log(`Deleting build target folder ${genDest}`)
|
|
67
|
-
}
|
|
65
|
+
this.logger._debug && this.logger.debug(`Deleting build target folder ${genDest}`)
|
|
68
66
|
await fs.remove(genDest)
|
|
69
67
|
}
|
|
70
68
|
}
|
|
@@ -207,9 +205,9 @@ class MtxModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
207
205
|
if (!tenantDbPath) {
|
|
208
206
|
tenantDbPath = path.join(this.buildOptions.root, this.env.folders.db)
|
|
209
207
|
if (hanaDbPaths.length === 0) {
|
|
210
|
-
this.pushMessage(`
|
|
208
|
+
this.pushMessage(`no 'hana' build task found, use default location '${tenantDbPath}'`, WARNING)
|
|
211
209
|
} else {
|
|
212
|
-
this.pushMessage(`
|
|
210
|
+
this.pushMessage(`no 'hana' build task found matching model scope '${this.task.options.model}', use default location '${tenantDbPath}'`, WARNING)
|
|
213
211
|
}
|
|
214
212
|
}
|
|
215
213
|
return tenantDbPath
|
|
@@ -4,15 +4,19 @@ const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
|
|
|
4
4
|
const { getHanaDbModuleDescriptor, getServiceModuleDescriptor } = require('../../mtaUtil')
|
|
5
5
|
const { BuildError } = require('../../util')
|
|
6
6
|
const { BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY, ODATA_VERSION, ODATA_VERSION_V2,
|
|
7
|
-
BUILD_NODEJS_EDMX_GENERAION,
|
|
7
|
+
BUILD_TASK_HANA, FOLDER_GEN, BUILD_NODEJS_EDMX_GENERAION, EDMX_GENERATION, SKIP_PACKAGE_JSON_GENERATION, SKIP_MANIFEST_GENERATION, CONTENT_EDMX, CONTENT_MANIFEST, CONTENT_PACKAGE_JSON } = require('../../constants')
|
|
8
8
|
const { WARNING } = require('../../buildTaskHandler')
|
|
9
9
|
|
|
10
|
-
const DEBUG = process.env.DEBUG
|
|
11
10
|
const FILE_NAME_MANIFEST_YML = "manifest.yml"
|
|
12
11
|
|
|
13
12
|
class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
14
13
|
init() {
|
|
15
14
|
super.init()
|
|
15
|
+
// set unified option values in order to easy access later on
|
|
16
|
+
this.task.options[CONTENT_EDMX] = this.hasBuildOption(CONTENT_EDMX, true) || this.hasCdsEnvOption(BUILD_NODEJS_EDMX_GENERAION, true) || this.hasBuildOption(EDMX_GENERATION, true) ? true : false
|
|
17
|
+
this.task.options[CONTENT_MANIFEST] = !this.hasBuildOption(CONTENT_MANIFEST, false) && !this.hasBuildOption(SKIP_MANIFEST_GENERATION, true) ? true : false
|
|
18
|
+
this.task.options[CONTENT_PACKAGE_JSON] = !this.hasBuildOption(CONTENT_PACKAGE_JSON, false) && !this.hasBuildOption(SKIP_PACKAGE_JSON_GENERATION, true) ? true : false
|
|
19
|
+
|
|
16
20
|
if (this.task.options.compileDest) {
|
|
17
21
|
throw new BuildError("Option not supported - compileDest")
|
|
18
22
|
}
|
|
@@ -31,36 +35,20 @@ class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
31
35
|
return this._result
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
// custom service handler implementations are relative to the origin .cds source files.
|
|
37
|
-
// For staging builds (task.src !== task.dest) the csn.json file that is served at runtime is copied into a corresponding srv subfolder.
|
|
38
|
-
// As a consequence the src folder name has to be included in the @source file name while for inplace builds (task.src === task.dest) this is not the case.
|
|
39
|
-
// This ensures that the paths are relative to the cwd when executing cds run.
|
|
40
|
-
const jsonOptions = {
|
|
41
|
-
cwd: this.buildOptions.root,
|
|
42
|
-
src: this.task.src === this.task.dest ? this.task.src : this.buildOptions.root
|
|
43
|
-
}
|
|
44
|
-
const extCsn = this.cds.compile.to.json(model, jsonOptions)
|
|
45
|
-
|
|
46
|
-
const extModel = JSON.parse(extCsn)
|
|
47
|
-
this._result.csn = extModel
|
|
48
|
-
|
|
49
|
-
if (!this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
|
|
50
|
-
await this.write(extCsn).to(path.join(this.destGen, "csn.json"))
|
|
51
|
-
}
|
|
38
|
+
// adding csn to build result containing @source and _where persisted properties
|
|
39
|
+
await this.compileToJson(model, this.destGen)
|
|
52
40
|
|
|
53
41
|
// collect and write language bundles into single i18n.json file
|
|
54
|
-
await this.
|
|
42
|
+
await this.collectLanguageBundles(model, this.destGen)
|
|
55
43
|
|
|
56
|
-
if (this.
|
|
57
|
-
await this.
|
|
44
|
+
if (this.hasBuildOption(CONTENT_EDMX, true)) {
|
|
45
|
+
await this.compileToEdmx(model, this.destGen)
|
|
58
46
|
}
|
|
59
47
|
|
|
60
48
|
if (!this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
|
|
61
49
|
await this._copyNativeContent(this.task.src, this.isStagingBuild() ? this.destGen : path.dirname(this.destGen))
|
|
62
50
|
|
|
63
|
-
if (
|
|
51
|
+
if (this.hasBuildOption(CONTENT_MANIFEST, true)) {
|
|
64
52
|
await Promise.all([this._writeManifestYml(), this._writeCfIgnore()])
|
|
65
53
|
}
|
|
66
54
|
}
|
|
@@ -72,9 +60,7 @@ class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
72
60
|
if (this.buildOptions.target === this.buildOptions.root) {
|
|
73
61
|
// delete the entire 'task.dest' folder otherwise, for details see #constructor
|
|
74
62
|
// - the value of the folder 'src' has been appended to the origin 'task.dest' dir
|
|
75
|
-
|
|
76
|
-
this.logger.log(`Deleting build target folder ${this.destGen}`)
|
|
77
|
-
}
|
|
63
|
+
this.logger._debug && this.logger.debug(`Deleting build target folder ${this.destGen}`)
|
|
78
64
|
await fs.remove(this.isStagingBuild() ? this.task.dest : this.destGen)
|
|
79
65
|
}
|
|
80
66
|
}
|
|
@@ -102,7 +88,7 @@ class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
102
88
|
if (/\.js$|\.properties$/.test(entry)) {
|
|
103
89
|
return true
|
|
104
90
|
}
|
|
105
|
-
if (/package\.json$/.test(entry) &&
|
|
91
|
+
if (/package\.json$/.test(entry) && this.hasBuildOption(CONTENT_PACKAGE_JSON, true)) {
|
|
106
92
|
packageJsonCopy = true
|
|
107
93
|
return true
|
|
108
94
|
}
|
|
@@ -126,7 +112,7 @@ class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
126
112
|
let changed = false
|
|
127
113
|
Object.keys(deps).forEach(key => {
|
|
128
114
|
if (typeof deps[key] === 'string' && deps[key].startsWith('.') || deps[key].startsWith('file:')) {
|
|
129
|
-
this.logger.log(
|
|
115
|
+
this.logger.log(`${this.task.for}: removing file dependency '${deps[key]}' from ${path.relative(this.buildOptions.root, file)}`)
|
|
130
116
|
delete deps[key]
|
|
131
117
|
changed = true
|
|
132
118
|
}
|
|
@@ -136,8 +122,8 @@ class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
136
122
|
function _addEnginesField(content) {
|
|
137
123
|
if (!content.engines || !content.engines.node) {
|
|
138
124
|
const { engines } = require('../../../../package.json')
|
|
139
|
-
this.logger.log(`[cds] - ${this.task.for}: adding node engines version to package.json ${engines}`)
|
|
140
125
|
if (engines && engines.node) {
|
|
126
|
+
this.logger.log(`${this.task.for}: adding node engines version to package.json ${engines.node}`)
|
|
141
127
|
content.engines = content.engines || {}
|
|
142
128
|
content.engines.node = engines.node
|
|
143
129
|
return true
|
|
@@ -193,8 +179,8 @@ class NodeCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
193
179
|
if (hanaBuildTask) {
|
|
194
180
|
const dbModuleDescriptor = await getHanaDbModuleDescriptor(this.buildOptions.root, path.basename(hanaBuildTask.src), this.logger)
|
|
195
181
|
hanaServiceBinding = ` - ${dbModuleDescriptor.hdiServiceName}`
|
|
196
|
-
} else
|
|
197
|
-
this.logger.
|
|
182
|
+
} else {
|
|
183
|
+
this.logger.debug("generating manifest.yml without HANA service binding, using sqlite database")
|
|
198
184
|
}
|
|
199
185
|
|
|
200
186
|
try {
|
package/bin/cds.js
CHANGED
|
@@ -40,9 +40,9 @@ const cli = { //NOSONAR
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function add (k,v) { options[k.slice(2)] = v || true }
|
|
43
|
-
function add_global (k,v) {
|
|
43
|
+
function add_global (k,v='') {
|
|
44
44
|
if (k === '--production') return process.env.NODE_ENV = 'production'
|
|
45
|
-
if (k === '--profile') return process.env.
|
|
45
|
+
if (k === '--profile') return process.env.CDS_ENV = v.split(',')
|
|
46
46
|
if (k === '--odata') v = { flavor:v }
|
|
47
47
|
let e=env || (env={}), path = k.slice(2).split('-')
|
|
48
48
|
while (path.length > 1) { let p = path.shift(); e = e[p]||(e[p]={}) }
|
|
@@ -54,10 +54,10 @@ const cli = { //NOSONAR
|
|
|
54
54
|
},
|
|
55
55
|
|
|
56
56
|
errorHandlers () {
|
|
57
|
-
const _error = (e) => { cli.log(e.errors || e, { 'log-level':
|
|
57
|
+
const _error = (e) => { cli.log(e.errors || e, { 'log-level': cds.env.log.levels.cli }); _exit(1) }
|
|
58
58
|
const _exit = (c) => { console.log(); process.exit(c) }
|
|
59
|
-
process.on ('unhandledRejection', _error)
|
|
60
|
-
process.on ('uncaughtException', _error)
|
|
59
|
+
cds.repl || process.on ('unhandledRejection', _error)
|
|
60
|
+
cds.repl || process.on ('uncaughtException', _error)
|
|
61
61
|
process.on ('SIGTERM',_exit)
|
|
62
62
|
process.on ('SIGHUP',_exit)
|
|
63
63
|
process.on ('SIGINT',_exit)
|
package/bin/serve.js
CHANGED
|
@@ -124,7 +124,7 @@ module.exports = Object.assign ( serve, {
|
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
const cds = require('../lib'), { exists, isfile, local, path } = cds.utils
|
|
127
|
-
|
|
127
|
+
let log = console.log // provisional logger, see _prepareLogging
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
130
|
* The main function which dispatches into the respective usage variants.
|
|
@@ -145,7 +145,7 @@ async function serve (all=[], o={}) { // NOSONAR
|
|
|
145
145
|
// handle --watch and --project
|
|
146
146
|
if (o.watch) return _watch (o.project,o) // cds serve --watch <project>
|
|
147
147
|
if (o.project) _chdir_to (o.project) // cds run --project <project>
|
|
148
|
-
if (!o.silent) _prepare_logging (
|
|
148
|
+
if (!o.silent) _prepare_logging ()
|
|
149
149
|
|
|
150
150
|
// The following things are meant for dev mode, which can be overruled by feature flagse...
|
|
151
151
|
const {features} = cds.env
|
|
@@ -192,43 +192,46 @@ function _local_server_js() {
|
|
|
192
192
|
const _local = file => isfile(file) || isfile (path.join(cds.env.folders.srv,file))
|
|
193
193
|
let server_js = process.env.CDS_TYPESCRIPT && _local('server.ts') || _local('server.js')
|
|
194
194
|
if (server_js) {
|
|
195
|
-
|
|
195
|
+
log && log ('Loading server from', { file: local(server_js) })
|
|
196
196
|
const fn = require (server_js)
|
|
197
197
|
return typeof fn === 'function' ? fn : cds.error `${local(server_js)} must export a function`
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
|
|
202
|
-
function _prepare_logging (
|
|
202
|
+
function _prepare_logging () { // NOSONAR
|
|
203
|
+
// change `log` function to cds.log
|
|
204
|
+
const LOG = cds.log('serve', { prefix:'cds' })
|
|
205
|
+
log = LOG._info && LOG.info
|
|
203
206
|
|
|
204
|
-
const _timer =
|
|
205
|
-
console.time (_timer)
|
|
206
|
-
console.log()
|
|
207
|
+
const _timer = log && `[cds] - launched at ${new Date().toLocaleString()}, in`
|
|
208
|
+
_timer && console.time (_timer)
|
|
207
209
|
|
|
208
210
|
// print information when model is loaded
|
|
209
211
|
cds.on ('loaded', (model)=>{
|
|
210
|
-
|
|
211
|
-
for (let each of model.$sources) console.log (' ', local(each))
|
|
212
|
-
console.log ('\x1b[0m')
|
|
212
|
+
log && log (`model loaded from ${model.$sources.length} file(s):\n\x1b[2m`)
|
|
213
|
+
for (let each of model.$sources) log && console.log (' ', local(each))
|
|
214
|
+
log && console.log ('\x1b[0m')
|
|
213
215
|
})
|
|
214
216
|
|
|
215
217
|
// print information about each connected service
|
|
216
218
|
cds.on ('connect', ({name,kind,options:{use,credentials}})=>{
|
|
217
|
-
|
|
219
|
+
log && log (`connect to ${name} > ${use||kind}`, _redacted(credentials))
|
|
218
220
|
})
|
|
219
221
|
|
|
220
222
|
// print information about each provided service
|
|
221
223
|
cds.on ('serving', (srv) => {
|
|
222
224
|
const details = { at: srv.path }
|
|
223
225
|
if (srv._source) details.impl = local(srv._source)
|
|
224
|
-
|
|
226
|
+
log && log (`${srv.mocked ? 'mocking' : 'serving'} ${srv.name}`, details)
|
|
225
227
|
})
|
|
226
228
|
|
|
227
229
|
// print info when we are finally on air
|
|
228
230
|
cds.once ('listening', ({url})=>{
|
|
229
|
-
console.log (
|
|
230
|
-
|
|
231
|
-
|
|
231
|
+
log && console.log ()
|
|
232
|
+
log && log ('server listening on',{url})
|
|
233
|
+
_timer && console.timeEnd (_timer)
|
|
234
|
+
if (process.stdin.isTTY) log && log (`[ terminate with ^C ]\n`)
|
|
232
235
|
})
|
|
233
236
|
|
|
234
237
|
return cds
|
|
@@ -264,7 +267,7 @@ function _in_memory (o) {
|
|
|
264
267
|
}}})
|
|
265
268
|
return true
|
|
266
269
|
}
|
|
267
|
-
if (db && db.credentials && db.credentials.database === ':memory:') {
|
|
270
|
+
if (db && db.credentials && (db.credentials.database || db.credentials.url) === ':memory:') {
|
|
268
271
|
return true
|
|
269
272
|
}
|
|
270
273
|
}
|
|
@@ -277,7 +280,7 @@ function _with_mocks (o) {
|
|
|
277
280
|
cds.on ('loaded', model => cds.deploy.include_external_entities_in(model))
|
|
278
281
|
const mocks = cds.env.features.test_mocks && isfile ('test/mocked.js')
|
|
279
282
|
if (mocks) cds.once ('served', ()=> {
|
|
280
|
-
|
|
283
|
+
log && log ('adding mock behaviours from', { file: local(mocks) })
|
|
281
284
|
require(mocks)
|
|
282
285
|
})
|
|
283
286
|
return true
|
|
@@ -285,14 +288,17 @@ function _with_mocks (o) {
|
|
|
285
288
|
}
|
|
286
289
|
|
|
287
290
|
|
|
291
|
+
const SECRETS = /(password)|(certificate)|(ca)|(clientsecret)/i // 'certificate' and 'ca' on HANA
|
|
288
292
|
/** mascades password-like strings, also reducing clutter in output */
|
|
289
293
|
function _redacted(cred) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
.forEach((k)
|
|
295
|
-
|
|
294
|
+
if (cred === null) return cred
|
|
295
|
+
if (Array.isArray(cred)) return cred.map(_redacted)
|
|
296
|
+
if (typeof cred === 'object') {
|
|
297
|
+
const newCred = Object.assign({}, cred)
|
|
298
|
+
Object.keys(newCred).forEach(k => (typeof newCred[k] === 'string' && SECRETS.test(k)) ? (newCred[k] = '...') : (newCred[k] = _redacted(newCred[k])))
|
|
299
|
+
return newCred
|
|
300
|
+
}
|
|
301
|
+
return cred
|
|
296
302
|
}
|
|
297
303
|
|
|
298
304
|
/* eslint no-console:off */
|
package/bin/version.js
CHANGED
|
@@ -54,7 +54,6 @@ function info(o) {
|
|
|
54
54
|
const main = _findPackage (require.main.filename)
|
|
55
55
|
return {
|
|
56
56
|
..._versions4(main, {}, true), // usually sap/cds-dk or sap/cds
|
|
57
|
-
..._versions4(o.all && '@sap/cds-sidecar-client', {}, null, o),
|
|
58
57
|
..._versions4('@sap/eslint-plugin-cds', {}, null, o),
|
|
59
58
|
..._versions4(process.cwd(), {}, null, o),
|
|
60
59
|
..._versions4('..', {}, null, o),
|
|
@@ -6,12 +6,7 @@ const _locales_4sql = {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
// FIXME: we reliably need to now if we'll be on sqlite even before the connect happened
|
|
9
|
-
const _on_sqlite = ()
|
|
10
|
-
const db = env.requires.db
|
|
11
|
-
if (db) return db.kind === 'sqlite' || (db.kind === 'sql' && db.use === 'sqlite')
|
|
12
|
-
return env.env === 'development'
|
|
13
|
-
}
|
|
14
|
-
|
|
9
|
+
const _on_sqlite = (env.requires.db || env.requires.sql).dialect === 'sqlite'
|
|
15
10
|
const { _texts_entries, _localized_entries } = env.cdsc.cv2 || {}
|
|
16
11
|
const _been_here = Symbol('is _localized')
|
|
17
12
|
|
|
@@ -50,17 +45,17 @@ function unfold_csn (m) { // NOSONAR
|
|
|
50
45
|
DEBUG && console.trace ('unfolding csn...')
|
|
51
46
|
const pass2 = []
|
|
52
47
|
|
|
53
|
-
const _locales = _on_sqlite
|
|
48
|
+
const _locales = _on_sqlite && _locales_4sql.sqlite
|
|
54
49
|
|
|
55
50
|
// Pass 1 - add localized.<locale> entities and views
|
|
56
51
|
for (let each in m.definitions) {
|
|
57
52
|
const d = m.definitions [each]
|
|
58
53
|
// Add <entry>_texts proxies for all <entry>.texts entities
|
|
59
|
-
if (_texts_entries && each.endsWith('.texts')) {
|
|
54
|
+
if (_texts_entries !== false && each.endsWith('.texts')) {
|
|
60
55
|
_add_proxy4 (d, each.slice(0,-6)+'_texts')
|
|
61
56
|
}
|
|
62
57
|
// Add localized.<entry> for all entities marked as .$localized
|
|
63
|
-
if (_localized_entries && d.own('$localized')) {
|
|
58
|
+
if (_localized_entries !== false && d.own('$localized')) {
|
|
64
59
|
let x = _add_proxy4 (d,`localized.${each}`)
|
|
65
60
|
if (x) pass2.push ([x])
|
|
66
61
|
// if running on sqlite add additional localized.<locale>. views
|
package/lib/compile/for/sql.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/** REVISIT: uses internal APIs to restore compile.for.sql in SNAPI */
|
|
2
2
|
const compile = require ('@sap/cds-compiler/lib/backends')
|
|
3
|
+
let _compile
|
|
3
4
|
|
|
4
5
|
module.exports = function cds_compile_for_sql (src,o) {
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
_compile = _compile || compile.toSqlWithCsn || compile.for_sql
|
|
7
|
+
// for_sql directly returns a CSN and not an object with a csn property
|
|
8
|
+
const res = _compile(src,{...o,csn:true})
|
|
9
|
+
return res.csn || res
|
|
7
10
|
}
|
package/lib/compile/parse.js
CHANGED
|
@@ -1,32 +1,39 @@
|
|
|
1
1
|
const cdsc = require ('@sap/cds-compiler')
|
|
2
2
|
const cds = require ('../index')
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
/** cds.parse is both, a namespace and a shortcut for cds.parse.cdl */
|
|
6
5
|
const cds_parse = (src,o) => cds.compile (src,o,'parsed')
|
|
7
6
|
const parse = module.exports = Object.assign (cds_parse, {
|
|
8
7
|
|
|
9
|
-
CDL: (...args) => tagged(
|
|
10
|
-
CQL: (...args) => tagged(
|
|
11
|
-
CXL: (...args) => tagged(
|
|
8
|
+
CDL: (...args) => tagged(parse.cdl, ...args),
|
|
9
|
+
CQL: (...args) => tagged(parse.cql, ...args),
|
|
10
|
+
CXL: (...args) => tagged(parse.expr, ...args),
|
|
12
11
|
|
|
13
12
|
cdl: cds_parse,
|
|
14
|
-
cql: x => { try { return cdsc.parse.cql(x,undefined,{messages:[]}) }
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
},
|
|
13
|
+
cql: x => { try { return cdsc.parse.cql(x,undefined,{messages:[]}) } catch(e) {
|
|
14
|
+
e.message = e.message.replace('<query>.cds:',`In '${e.cql = x}' at `)
|
|
15
|
+
throw e // with improved error message
|
|
16
|
+
}},
|
|
20
17
|
path: (x,...values) => {
|
|
21
|
-
if (x && x.raw) return tagged (
|
|
22
|
-
if (/^[A-Za-z_0-9.$]
|
|
23
|
-
let {SELECT} =
|
|
18
|
+
if (x && x.raw) return tagged (parse.path,x,...values)
|
|
19
|
+
if (/^[A-Za-z_$][A-Za-z_0-9.$]*$/.test(x)) return {ref:[x]}
|
|
20
|
+
let {SELECT} = parse.cql('SELECT from '+x)
|
|
24
21
|
return SELECT.from
|
|
25
22
|
},
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
column: x => {
|
|
24
|
+
let as = /\s+as\s+(\w+)$/i.exec(x)
|
|
25
|
+
if (as) {
|
|
26
|
+
let col = parse.expr(x.slice(0,as.index)); col.as = as[1]
|
|
27
|
+
return col
|
|
28
|
+
}
|
|
29
|
+
else return parse.expr(x)
|
|
30
|
+
},
|
|
31
|
+
expr: x => {
|
|
32
|
+
if (typeof x !== 'string') throw cds.error.expected `${{x}} to be an expression string`
|
|
33
|
+
if (x in keywords) return {ref:[x]}
|
|
34
|
+
try { return cdsc.parse.expr(x,undefined,{messages:[]}) } catch(e) {
|
|
28
35
|
e.message = e.message.replace('<expr>.cds:1:',`In '${e.expr = x}' at `)
|
|
29
|
-
throw e
|
|
36
|
+
throw e // with improved error message
|
|
30
37
|
}
|
|
31
38
|
},
|
|
32
39
|
xpr: x => { const y = parse.expr(x); return y.xpr || [y] },
|
|
@@ -68,4 +75,5 @@ const merge = (o,values) => {
|
|
|
68
75
|
return o
|
|
69
76
|
}
|
|
70
77
|
|
|
71
|
-
const cxn4 = x => x.SELECT || x.ref || x.xpr || x.val || x.list || x.func ? x : {val:x}
|
|
78
|
+
const cxn4 = x => x.SELECT || x.ref || x.xpr || x.val !== undefined|| x.list || x.func ? x : {val:x}
|
|
79
|
+
const keywords = { KEY:1, key:1, SELECT:1, select:1 }
|
|
@@ -74,7 +74,8 @@ module.exports = (model, options={}) => {
|
|
|
74
74
|
if (file) {
|
|
75
75
|
const yaml = cds.load.yaml(file)
|
|
76
76
|
for (let {cds} of Array.isArray(yaml) ? yaml : [yaml]) {
|
|
77
|
-
if (cds
|
|
77
|
+
if (cds && cds['odata-v4.endpoint.path']) return cds['odata-v4.endpoint.path']
|
|
78
|
+
if (cds && cds['odata-v2.endpoint.path']) return cds['odata-v2.endpoint.path']
|
|
78
79
|
}
|
|
79
80
|
return 'odata/v4/'
|
|
80
81
|
}
|
package/lib/connect/bindings.js
CHANGED
|
@@ -12,8 +12,9 @@ module.exports = class Bindings {
|
|
|
12
12
|
static get registry(){ return registry }
|
|
13
13
|
|
|
14
14
|
static then(r,e) {
|
|
15
|
+
const LOG = cds.log('serve', { prefix:'cds' })
|
|
15
16
|
const bindings = new Bindings
|
|
16
|
-
cds.prependOnceListener ('connect', ()=>
|
|
17
|
+
cds.prependOnceListener ('connect', ()=> LOG._info && LOG.info ('connect using bindings from:', { registry }))
|
|
17
18
|
cds.once('listening', ({url})=> bindings.export (cds.service.providers, url))
|
|
18
19
|
return bindings.import() .then (r,e)
|
|
19
20
|
}
|