@sap/cds 6.8.4 → 7.0.1
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 +66 -4
- package/README.md +0 -1
- package/bin/cds-serve.js +50 -3
- package/bin/deploy/to-hana.js +1 -0
- package/bin/serve.js +16 -20
- package/lib/auth/basic-auth.js +6 -4
- package/lib/auth/index.js +4 -3
- package/lib/auth/jwt-auth.js +2 -5
- package/lib/compile/cds-compile.js +34 -89
- package/lib/compile/cdsc.js +11 -0
- package/lib/compile/etc/properties.js +2 -2
- package/lib/compile/for/lean_drafts.js +36 -69
- package/lib/compile/for/nodejs.js +2 -1
- package/lib/compile/load.js +3 -3
- package/lib/compile/minify.js +2 -0
- package/lib/compile/to/csn.js +74 -0
- package/{bin/build/provider/hana/2tabledata.js → lib/compile/to/hdbtabledata.js} +4 -6
- package/lib/compile/to/json.js +1 -1
- package/lib/compile/to/sql.js +8 -6
- package/lib/dbs/cds-deploy.js +174 -114
- package/lib/env/cds-env.js +64 -79
- package/lib/env/cds-requires.js +11 -28
- package/lib/env/defaults.js +13 -3
- package/lib/env/plugins.js +1 -12
- package/lib/env/presets.js +25 -21
- package/lib/index.js +121 -147
- package/lib/{core/reflect.js → linked/models.js} +2 -2
- package/lib/{core/infer.js → linked/queries.js} +2 -0
- package/lib/{core/index.js → linked/types.js} +2 -1
- package/lib/log/cds-error.js +13 -7
- package/lib/log/format/cf.js +1 -1
- package/lib/plugins.js +49 -0
- package/lib/ql/Query.js +0 -9
- package/lib/ql/STREAM.js +0 -1
- package/lib/req/context.js +2 -7
- package/lib/req/request.js +6 -2
- package/lib/req/response.js +23 -10
- package/lib/srv/middlewares/ctx-model.js +2 -2
- package/lib/srv/middlewares/errors.js +1 -1
- package/lib/srv/protocols/_legacy.js +1 -0
- package/lib/srv/protocols/graphql.js +7 -16
- package/lib/srv/protocols/index.js +59 -45
- package/lib/srv/protocols/odata-v2-proxy.js +2 -70
- package/lib/srv/protocols/odata-v4.js +9 -4
- package/lib/srv/srv-api.js +9 -3
- package/lib/srv/srv-dispatch.js +12 -9
- package/lib/srv/srv-models.js +4 -21
- package/lib/srv/srv-tx.js +15 -12
- package/lib/utils/cds-test.js +14 -9
- package/lib/utils/cds-utils.js +2 -12
- package/lib/utils/check-version.js +17 -0
- package/{bin/build → lib/utils}/csv-reader.js +23 -24
- package/libx/_runtime/auth/index.js +27 -23
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +15 -72
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +0 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +33 -63
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +14 -18
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +5 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +37 -40
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/updateToCQN.js +7 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +101 -38
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/errors/AbstractError.js +5 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriTokenizer.js +5 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +2 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/ResourceJsonDeserializer.js +9 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +15 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +4 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +5 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +1 -123
- package/libx/_runtime/cds-services/services/Service.js +79 -107
- package/libx/_runtime/cds-services/services/utils/columns.js +23 -19
- package/libx/_runtime/cds-services/services/utils/compareJson.js +11 -1
- package/libx/_runtime/cds-services/services/utils/differ.js +7 -2
- package/libx/_runtime/cds-services/util/assert.js +65 -2
- package/libx/_runtime/common/composition/data.js +1 -0
- package/libx/_runtime/common/generic/auth/expand.js +1 -1
- package/libx/_runtime/common/generic/auth/restrict.js +5 -10
- package/libx/_runtime/common/generic/auth/restrictions.js +40 -0
- package/libx/_runtime/common/generic/auth/utils.js +1 -2
- package/libx/_runtime/common/generic/crud.js +32 -16
- package/libx/_runtime/common/generic/etag.js +133 -104
- package/libx/_runtime/common/generic/input.js +6 -21
- package/libx/_runtime/common/generic/put.js +1 -1
- package/libx/_runtime/common/generic/stream.js +52 -0
- package/libx/_runtime/common/generic/temporal.js +25 -8
- package/libx/_runtime/common/i18n/messages.properties +0 -2
- package/libx/_runtime/common/utils/cqn.js +1 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +5 -2
- package/libx/_runtime/common/utils/csn.js +0 -51
- package/libx/_runtime/common/utils/etag.js +30 -0
- package/libx/_runtime/common/utils/keys.js +1 -1
- package/libx/_runtime/common/utils/normalizeTimestamp.js +25 -0
- package/libx/_runtime/common/utils/path.js +1 -1
- package/libx/_runtime/common/utils/resolveView.js +2 -1
- package/libx/_runtime/common/utils/rewriteAsterisks.js +6 -4
- package/libx/_runtime/common/utils/search2cqn4sql.js +12 -16
- package/libx/_runtime/common/utils/stream.js +140 -0
- package/libx/_runtime/common/utils/streamProp.js +29 -12
- package/libx/_runtime/common/utils/templateProcessorPathSerializer.js +0 -2
- package/libx/_runtime/db/generic/index.js +0 -2
- package/libx/_runtime/db/query/delete.js +2 -2
- package/libx/_runtime/db/query/insert.js +2 -2
- package/libx/_runtime/db/query/read.js +2 -2
- package/libx/_runtime/db/query/run.js +2 -2
- package/libx/_runtime/db/query/update.js +2 -2
- package/libx/_runtime/db/sql-builder/BaseBuilder.js +0 -6
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +23 -12
- package/libx/_runtime/db/sql-builder/FunctionBuilder.js +18 -6
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -0
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +3 -7
- package/libx/_runtime/db/sql-builder/UpsertBuilder.js +1 -0
- package/libx/_runtime/db/utils/normalizeTimeData.js +7 -3
- package/libx/_runtime/fiori/draft.js +2 -0
- package/libx/_runtime/fiori/generic/activate.js +8 -9
- package/libx/_runtime/fiori/generic/before.js +30 -20
- package/libx/_runtime/fiori/generic/cancel.js +5 -3
- package/libx/_runtime/fiori/generic/delete.js +5 -3
- package/libx/_runtime/fiori/generic/edit.js +7 -7
- package/libx/_runtime/fiori/generic/index.js +10 -16
- package/libx/_runtime/fiori/generic/new.js +5 -3
- package/libx/_runtime/fiori/generic/patch.js +11 -8
- package/libx/_runtime/fiori/generic/prepare.js +13 -6
- package/libx/_runtime/fiori/generic/read.js +12 -6
- package/libx/_runtime/fiori/lean-draft.js +207 -152
- package/libx/_runtime/fiori/utils/delete.js +10 -5
- package/libx/_runtime/fiori/utils/req.js +17 -5
- package/libx/_runtime/fiori/utils/stream.js +36 -0
- package/libx/_runtime/hana/Service.js +12 -9
- package/libx/_runtime/hana/conversion.js +10 -15
- package/libx/_runtime/hana/driver.js +2 -0
- package/libx/_runtime/hana/execute.js +28 -6
- package/libx/_runtime/hana/pool.js +36 -122
- package/libx/_runtime/hana/search2cqn4sql.js +34 -36
- package/libx/_runtime/messaging/enterprise-messaging-utils/getTenantInfo.js +2 -6
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +3 -1
- package/libx/_runtime/messaging/enterprise-messaging.js +10 -58
- package/libx/_runtime/messaging/outbox/utils.js +1 -1
- package/libx/_runtime/remote/Service.js +20 -1
- package/libx/_runtime/remote/utils/client.js +3 -5
- package/libx/_runtime/sqlite/Service.js +4 -6
- package/libx/_runtime/sqlite/conversion.js +3 -13
- package/libx/_runtime/sqlite/customBuilder/CustomFunctionBuilder.js +9 -6
- package/libx/_runtime/sqlite/customBuilder/CustomUpsertBuilder.js +6 -1
- package/libx/_runtime/sqlite/execute.js +5 -16
- package/libx/odata/afterburner.js +22 -6
- package/libx/odata/grammar.pegjs +6 -1
- package/libx/odata/parser.js +1 -1
- package/libx/rest/RestAdapter.js +16 -9
- package/libx/rest/RestRequest.js +1 -1
- package/libx/rest/middleware/input.js +2 -1
- package/libx/rest/middleware/operation.js +1 -0
- package/libx/rest/middleware/parse.js +3 -2
- package/libx/rest/middleware/payload.js +9 -8
- package/libx/rest/middleware/read.js +1 -0
- package/package.json +9 -16
- package/server.js +1 -1
- package/app/fiori/preview.js +0 -270
- package/app/fiori/routes.js +0 -59
- package/bin/build/buildTaskEngine.js +0 -360
- package/bin/build/buildTaskFactory.js +0 -283
- package/bin/build/buildTaskHandler.js +0 -241
- package/bin/build/buildTaskProvider.js +0 -22
- package/bin/build/buildTaskProviderFactory.js +0 -175
- package/bin/build/cds.js +0 -5
- package/bin/build/constants.js +0 -66
- package/bin/build/index.js +0 -58
- package/bin/build/provider/buildTaskHandlerEdmx.js +0 -82
- package/bin/build/provider/buildTaskHandlerFeatureToggles.js +0 -131
- package/bin/build/provider/buildTaskHandlerInternal.js +0 -254
- package/bin/build/provider/buildTaskProviderInternal.js +0 -383
- package/bin/build/provider/fiori/index.js +0 -171
- package/bin/build/provider/hana/2migration.js +0 -179
- package/bin/build/provider/hana/index.js +0 -505
- package/bin/build/provider/hana/migrationtable.js +0 -472
- package/bin/build/provider/hana/template/.hdiconfig-haas +0 -163
- package/bin/build/provider/hana/template/.hdiconfig-hanacloud +0 -137
- package/bin/build/provider/hana/template/.hdinamespace +0 -4
- package/bin/build/provider/hana/template/package.json +0 -12
- package/bin/build/provider/hana/template/undeploy.json +0 -5
- package/bin/build/provider/java/index.js +0 -111
- package/bin/build/provider/java-cf/index.js +0 -1
- package/bin/build/provider/mtx/index.js +0 -268
- package/bin/build/provider/mtx/resourcesTarBuilder.js +0 -95
- package/bin/build/provider/mtx-extension/index.js +0 -131
- package/bin/build/provider/mtx-sidecar/index.js +0 -137
- package/bin/build/provider/node-cf/index.js +0 -1
- package/bin/build/provider/nodejs/index.js +0 -192
- package/bin/build/util.js +0 -299
- package/bin/cds.js +0 -125
- package/bin/deploy/to-hana/cfUtil.js +0 -355
- package/bin/deploy/to-hana/gitUtil.js +0 -57
- package/bin/deploy/to-hana/hana.js +0 -306
- package/bin/deploy/to-hana/hdiDeployUtil.js +0 -153
- package/bin/deploy/to-hana/index.js +0 -16
- package/bin/deploy/to-hana/mtaUtil.js +0 -170
- package/bin/mtx/in-cds.js +0 -17
- package/bin/plugins.js +0 -32
- package/bin/run.js +0 -24
- package/bin/utils/log.js +0 -24
- package/bin/version.js +0 -178
- package/libx/_runtime/audit/Service.js +0 -222
- package/libx/_runtime/audit/generic/personal/access.js +0 -61
- package/libx/_runtime/audit/generic/personal/index.js +0 -56
- package/libx/_runtime/audit/generic/personal/modification.js +0 -132
- package/libx/_runtime/audit/generic/personal/utils.js +0 -186
- package/libx/_runtime/audit/utils/log.js +0 -23
- package/libx/_runtime/audit/utils/v2.js +0 -176
- package/libx/_runtime/db/data-conversion/timestamp.js +0 -9
- package/libx/_runtime/db/generic/integrity.js +0 -455
- package/srv/audit-log.cds +0 -87
- package/srv/mtx.cds +0 -2
- package/srv/mtx.js +0 -8
- /package/lib/{core → linked}/classes.js +0 -0
- /package/lib/{core → linked}/entities.js +0 -0
package/app/fiori/preview.js
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
const cds = require('../../lib')
|
|
2
|
-
cds.on('served', ()=>{
|
|
3
|
-
|
|
4
|
-
const { app, env, service:{providers} } = cds
|
|
5
|
-
|
|
6
|
-
const mountPoint = '/$fiori-preview'
|
|
7
|
-
const appID = 'preview-app'
|
|
8
|
-
const _appURL = (srv, entity) => `${mountPoint}/${srv}/${entity}#${appID}`
|
|
9
|
-
const _componentURL = (srv, entity) => `${mountPoint}/${srv}/${entity}/app`
|
|
10
|
-
|
|
11
|
-
function _manifest(serviceName, entityName) {
|
|
12
|
-
const [serviceProv, serviceInfo] = _validate(serviceName, entityName)
|
|
13
|
-
const listPageInitialLoad = (env.preview && env.preview.fiori && env.preview.fiori.initialload !== undefined)
|
|
14
|
-
? env.preview.fiori.initialload
|
|
15
|
-
: true
|
|
16
|
-
const manifest = {
|
|
17
|
-
_version: '1.8.0',
|
|
18
|
-
'sap.app': {
|
|
19
|
-
id: 'preview',
|
|
20
|
-
type: 'application',
|
|
21
|
-
title: `Preview ‒ List of ${serviceProv.name}.${entityName}`,
|
|
22
|
-
description: 'Preview Application',
|
|
23
|
-
dataSources: {
|
|
24
|
-
mainService: {
|
|
25
|
-
uri: `${serviceProv.path}/`,
|
|
26
|
-
type: 'OData',
|
|
27
|
-
settings: {
|
|
28
|
-
odataVersion: '4.0'
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
'sap.ui5': {
|
|
34
|
-
flexEnabled: true,
|
|
35
|
-
dependencies: {
|
|
36
|
-
minUI5Version: '1.96.0',
|
|
37
|
-
libs: {
|
|
38
|
-
'sap.ui.core': {},
|
|
39
|
-
'sap.fe.templates': {}
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
models: {
|
|
43
|
-
'': {
|
|
44
|
-
dataSource: 'mainService',
|
|
45
|
-
settings: {
|
|
46
|
-
synchronizationMode: 'None',
|
|
47
|
-
operationMode: 'Server',
|
|
48
|
-
autoExpandSelect: true,
|
|
49
|
-
earlyRequests: true,
|
|
50
|
-
groupProperties: {
|
|
51
|
-
default: {
|
|
52
|
-
submit: 'Auto'
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
routing: {
|
|
59
|
-
routes: [
|
|
60
|
-
{
|
|
61
|
-
name: `${entityName}ListRoute`,
|
|
62
|
-
target: `${entityName}ListTarget`,
|
|
63
|
-
pattern: ':?query:',
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
name: `${entityName}DetailsRoute`,
|
|
67
|
-
target: `${entityName}DetailsTarget`,
|
|
68
|
-
pattern: `${entityName}({key}):?query:`,
|
|
69
|
-
}
|
|
70
|
-
],
|
|
71
|
-
targets: {
|
|
72
|
-
[`${entityName}ListTarget`]: {
|
|
73
|
-
type: 'Component',
|
|
74
|
-
id: `${entityName}ListTarget`,
|
|
75
|
-
name: 'sap.fe.templates.ListReport',
|
|
76
|
-
options: {
|
|
77
|
-
settings: {
|
|
78
|
-
entitySet: `${entityName}`,
|
|
79
|
-
initialLoad: listPageInitialLoad,
|
|
80
|
-
navigation: {
|
|
81
|
-
[`${entityName}`]: {
|
|
82
|
-
detail: {
|
|
83
|
-
route: `${entityName}DetailsRoute`
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
[`${entityName}DetailsTarget`]: {
|
|
91
|
-
type: 'Component',
|
|
92
|
-
id: `${entityName}DetailsTarget`,
|
|
93
|
-
name: 'sap.fe.templates.ObjectPage',
|
|
94
|
-
options: {
|
|
95
|
-
settings: {
|
|
96
|
-
entitySet: `${entityName}`,
|
|
97
|
-
navigation: {}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
contentDensities: {
|
|
105
|
-
compact: true,
|
|
106
|
-
cozy: true
|
|
107
|
-
},
|
|
108
|
-
'sap.ui': {
|
|
109
|
-
technology: 'UI5',
|
|
110
|
-
fullWidth: true,
|
|
111
|
-
deviceTypes: {
|
|
112
|
-
desktop: true,
|
|
113
|
-
tablet: true,
|
|
114
|
-
phone: true
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
'sap.fiori': {
|
|
118
|
-
registrationIds: [],
|
|
119
|
-
archeType: 'transactional'
|
|
120
|
-
},
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const { routing } = manifest['sap.ui5']
|
|
124
|
-
for (const {navProperty, targetEntity} of serviceInfo) {
|
|
125
|
-
// add a route for the navigation property
|
|
126
|
-
routing.routes.push(
|
|
127
|
-
{
|
|
128
|
-
name: `${navProperty}Route`,
|
|
129
|
-
target: `${navProperty}Target`,
|
|
130
|
-
pattern: `${entityName}({key})/${navProperty}({key2}):?query:`,
|
|
131
|
-
}
|
|
132
|
-
)
|
|
133
|
-
// add a route target leading to the target entity
|
|
134
|
-
routing.targets[`${navProperty}Target`] = {
|
|
135
|
-
type: 'Component',
|
|
136
|
-
id: `${navProperty}Target`,
|
|
137
|
-
name: 'sap.fe.templates.ObjectPage',
|
|
138
|
-
options: {
|
|
139
|
-
settings: {
|
|
140
|
-
entitySet: targetEntity
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// wire the new route from the source entity's navigation (see above)
|
|
145
|
-
routing.targets[`${entityName}DetailsTarget`].options.settings.navigation[navProperty] = {
|
|
146
|
-
detail: {
|
|
147
|
-
route: `${navProperty}Route`
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return manifest
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function _html(serviceName, entityName) {
|
|
156
|
-
_validate(serviceName, entityName)
|
|
157
|
-
let ui5Version = (env.preview && env.preview.ui5 && env.preview.ui5.version) || ''
|
|
158
|
-
let ui5Host = (env.preview && env.preview.ui5 && env.preview.ui5.host) || `https://sapui5.hana.ondemand.com/${ui5Version}`
|
|
159
|
-
if (!ui5Host.endsWith('/')) ui5Host += '/'
|
|
160
|
-
|
|
161
|
-
// copied from UI5's test-resources/sap/ushell/shells/sandbox/fioriSandbox.html
|
|
162
|
-
return `
|
|
163
|
-
<!DOCTYPE html>
|
|
164
|
-
<html>
|
|
165
|
-
<head>
|
|
166
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
167
|
-
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
|
|
168
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
169
|
-
<title>Preview for ${serviceName}.${entityName}</title>
|
|
170
|
-
<script>
|
|
171
|
-
window["sap-ushell-config"] = {
|
|
172
|
-
defaultRenderer: "fiori2",
|
|
173
|
-
applications: {
|
|
174
|
-
"${appID}": {
|
|
175
|
-
title: "Browse ${entityName}",
|
|
176
|
-
description: "from ${serviceName}",
|
|
177
|
-
additionalInformation: "SAPUI5.Component=app",
|
|
178
|
-
applicationType : "URL",
|
|
179
|
-
url: "${_componentURL(serviceName, entityName)}",
|
|
180
|
-
navigationMode: "embedded"
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
</script>
|
|
185
|
-
<script id="sap-ushell-bootstrap" src="${ui5Host}test-resources/sap/ushell/bootstrap/sandbox.js"></script>
|
|
186
|
-
<script id="sap-ui-bootstrap" src="${ui5Host}resources/sap-ui-core.js"
|
|
187
|
-
data-sap-ui-theme="sap_horizon"
|
|
188
|
-
data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
|
|
189
|
-
data-sap-ui-compatVersion="edge"
|
|
190
|
-
data-sap-ui-async="true"
|
|
191
|
-
data-sap-ui-preload="async"></script>
|
|
192
|
-
<script>
|
|
193
|
-
sap.ui.getCore().attachInit(function() { sap.ushell.Container.createRenderer().placeAt("content") })
|
|
194
|
-
</script>
|
|
195
|
-
</head>
|
|
196
|
-
<body class="sapUiBody sapUiSizeCompact" id="content"></body>
|
|
197
|
-
</html>
|
|
198
|
-
`
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function _componentJs(serviceName, entityName) {
|
|
202
|
-
const manifest = _manifest(serviceName, entityName)
|
|
203
|
-
return `sap.ui.define(["sap/fe/core/AppComponent"], function(AppComponent) {
|
|
204
|
-
"use strict";
|
|
205
|
-
return AppComponent.extend("preview.Component", {
|
|
206
|
-
metadata: { manifest: ${JSON.stringify(manifest, null, 2)} }
|
|
207
|
-
});
|
|
208
|
-
});`
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function _validate(serviceName, entityName) {
|
|
212
|
-
const serviceProv = providers.find (s => s.name === serviceName)
|
|
213
|
-
if (!serviceProv) throw _badRequest (`No such service '${serviceName}'. Available: [${providers.map(p => p.name)}]`)
|
|
214
|
-
return _serviceInfo (serviceProv, entityName)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
function _serviceInfo (serviceProv, entityName) {
|
|
218
|
-
const entities = serviceProv.model.entities(serviceProv.name)
|
|
219
|
-
const entity = entities[entityName]
|
|
220
|
-
if (!entity) throw _badRequest (`No such entity '${entityName}' in service '${serviceProv.name}'`)
|
|
221
|
-
return [serviceProv, serviceProv.model.all ('Association', entity.elements)
|
|
222
|
-
.filter (a =>
|
|
223
|
-
!a.target.endsWith('.texts') &&
|
|
224
|
-
!a.target.endsWith('_texts') &&
|
|
225
|
-
!a.target.endsWith('DraftAdministrativeData') &&
|
|
226
|
-
a.name !== 'SiblingEntity')
|
|
227
|
-
.map (a => { return { navProperty: a.name, targetEntity: a.target.split('.')[1] } })
|
|
228
|
-
]
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const _badRequest = (message) => { const err = new Error (message); err.statusCode = 400; return err}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
// fetch and instrument all OData providers
|
|
235
|
-
const any = providers.filter (srv =>
|
|
236
|
-
srv._adapters && srv._adapters [Object.keys(srv._adapters) .find (a => a.startsWith ('odata'))]
|
|
237
|
-
)
|
|
238
|
-
.map(srv => {
|
|
239
|
-
// called from ../index.js to provide the data for the HTML link
|
|
240
|
-
const link = linkProvider(srv)
|
|
241
|
-
srv.$linkProviders ? srv.$linkProviders.push (link) : srv.$linkProviders = [link]
|
|
242
|
-
return link
|
|
243
|
-
})
|
|
244
|
-
.length
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
// install middlewares once
|
|
248
|
-
if (any) {
|
|
249
|
-
// eslint-disable-next-line cds/no-missing-dependencies
|
|
250
|
-
const router = require('express').Router()
|
|
251
|
-
// UI5 component
|
|
252
|
-
router.get ('/:service/:entity/app/Component.js', ({ params }, resp) => resp.send(_componentJs(params.service, params.entity)))
|
|
253
|
-
// html
|
|
254
|
-
router.get ('/:service/:entity', ({ params }, resp) => resp.send(_html(params.service, params.entity)))
|
|
255
|
-
|
|
256
|
-
app.use(mountPoint.replace('$','\\$'), router)
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
function linkProvider(service) {
|
|
260
|
-
return (entity) => {
|
|
261
|
-
if (!entity) return
|
|
262
|
-
return {
|
|
263
|
-
href: _appURL(service.name, entity),
|
|
264
|
-
title: 'Preview in Fiori elements',
|
|
265
|
-
name: 'Fiori preview'
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
})
|
package/app/fiori/routes.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
const cds = require('../../lib')
|
|
2
|
-
const DEBUG = cds.debug('fiori/routes')
|
|
3
|
-
const {dirname, relative, join} = require('path')
|
|
4
|
-
|
|
5
|
-
// Only for local cds runs w/o approuter:
|
|
6
|
-
// If there is a relative URL in UI5's manifest.json for the datasource,
|
|
7
|
-
// like 'browse/' or 'prefix/browse/', we get called with a prefix to the
|
|
8
|
-
// service path, like '/browse/webapp/browse/'.
|
|
9
|
-
// Serve these requests by redirecting to the actual service URL.
|
|
10
|
-
cds.on ('bootstrap', app => {
|
|
11
|
-
|
|
12
|
-
const { env, utils:{find,fs}} = cds
|
|
13
|
-
const v2Prefix = (env.odata.v2proxy && env.odata.v2proxy.urlpath) || '/v2'
|
|
14
|
-
const serviceForUri = {}
|
|
15
|
-
|
|
16
|
-
dataSourceURIs (env.folders.app).forEach(({appPath, dataSourceUri}) => {
|
|
17
|
-
const uiRoutes = [
|
|
18
|
-
join('/', appPath, dataSourceUri, '*'), // /uiApp/webapp/browse/*
|
|
19
|
-
join('/', appPath, '*', dataSourceUri, '*') // /uiApp/webapp/*/browse/*
|
|
20
|
-
].map(r => r.replace(/\\/g, '/')) // handle Windows \
|
|
21
|
-
DEBUG && DEBUG ('Register routes', uiRoutes)
|
|
22
|
-
|
|
23
|
-
app.use(uiRoutes, ({originalUrl}, res, next)=> {
|
|
24
|
-
// any of our special URLs ($fiori-, $api-docs) ? -> next
|
|
25
|
-
if (originalUrl.startsWith('/$')) return next()
|
|
26
|
-
|
|
27
|
-
// is there a service for '[prefix]/browse' ?
|
|
28
|
-
const srv = serviceForUri[dataSourceUri] || (serviceForUri[dataSourceUri] =
|
|
29
|
-
cds.service.providers.find (srv => ('/'+dataSourceUri).lastIndexOf(srv.path) >=0))
|
|
30
|
-
if (srv) {
|
|
31
|
-
let redirectUrl
|
|
32
|
-
// odata-proxy may be in the line with its /v2 prefix. Make sure we retain it.
|
|
33
|
-
const v2Index = originalUrl.lastIndexOf(v2Prefix+srv.path)
|
|
34
|
-
if (v2Index >= 0) // --> /browse/webapp[/prefix]/v2/browse/ -> /v2/browse
|
|
35
|
-
redirectUrl = originalUrl.substring(v2Index)
|
|
36
|
-
else // --> /browse/webapp[/prefix]/browse/ -> /browse
|
|
37
|
-
redirectUrl = originalUrl.substring(originalUrl.lastIndexOf(srv.path+'/'))
|
|
38
|
-
if (originalUrl !== redirectUrl) {// safeguard to prevent running in loops
|
|
39
|
-
DEBUG && DEBUG ('Redirecting', {src: originalUrl}, '~>', {target: redirectUrl})
|
|
40
|
-
return res.redirect (308, redirectUrl)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
next()
|
|
44
|
-
})
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
function dataSourceURIs (dir) {
|
|
48
|
-
const uris = new Set()
|
|
49
|
-
find (dir, ['*/manifest.json', '*/*/manifest.json']).forEach(file => {
|
|
50
|
-
const appPath = relative(join(cds.root, dir), dirname(file))
|
|
51
|
-
const {dataSources: ds} = JSON.parse(fs.readFileSync(file))['sap.app'] || {}
|
|
52
|
-
Object.keys (ds||[])
|
|
53
|
-
.filter (k => ds[k].uri && !ds[k].uri.startsWith('/')) // only consider relative URLs)
|
|
54
|
-
.forEach(k => uris.add({ appPath, dataSourceUri: ds[k].uri }))
|
|
55
|
-
})
|
|
56
|
-
return uris
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
})
|
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const cds = require('./cds'), { log } = cds.exec
|
|
4
|
-
const { sortMessagesSeverityAware, deduplicateMessages, CompilationError } = require('@sap/cds-compiler')
|
|
5
|
-
const { relativePaths, BuildError, BuildMessage, resolveRequiredSapModels } = require('./util')
|
|
6
|
-
const { OUTPUT_MODE_DEFAULT, SEVERITIES, LOG_LEVELS, LOG_MODULE_NAMES } = require('./constants')
|
|
7
|
-
const BuildTaskProviderFactory = require('./buildTaskProviderFactory')
|
|
8
|
-
const BuildTaskHandlerInternal = require('./provider/buildTaskHandlerInternal')
|
|
9
|
-
|
|
10
|
-
const COMPILATION_ERROR = 'CompilationError'
|
|
11
|
-
const COMPILE_MESSAGE = 'CompileMessage'
|
|
12
|
-
|
|
13
|
-
class BuildTaskEngine {
|
|
14
|
-
constructor(logger) {
|
|
15
|
-
this._logger = logger || cds.log(LOG_MODULE_NAMES)
|
|
16
|
-
}
|
|
17
|
-
get logger() {
|
|
18
|
-
return this._logger
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async processTasks(tasks, buildOptions, clean = true) {
|
|
22
|
-
const startTime = Date.now()
|
|
23
|
-
const messages = []
|
|
24
|
-
|
|
25
|
-
if (buildOptions) {
|
|
26
|
-
// clone as data may be stored as part of the buildOptions object
|
|
27
|
-
buildOptions = JSON.parse(JSON.stringify(buildOptions))
|
|
28
|
-
} else {
|
|
29
|
-
buildOptions = {
|
|
30
|
-
root: process.env._TEST_CWD || process.cwd()
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (!buildOptions.outputMode) {
|
|
34
|
-
buildOptions.outputMode = OUTPUT_MODE_DEFAULT
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
this.logger.log(`building project [${buildOptions.root}], clean [${clean}]`)
|
|
38
|
-
this.logger.log(`cds [${cds.version}], compiler [${cds.compiler.version()}], home [${cds.home}]\n`)
|
|
39
|
-
|
|
40
|
-
if (!buildOptions.target) {
|
|
41
|
-
buildOptions.target = path.resolve(buildOptions.root, cds.env.build.target)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// validate required @sap namespace models - log only
|
|
45
|
-
const unresolved = BuildTaskEngine._resolveRequiredSapServices(tasks)
|
|
46
|
-
if (unresolved.length > 0) {
|
|
47
|
-
messages.push(new BuildMessage(`Required CDS models [${unresolved.join(', ')}] cannot be resolved. Make sure up-to-date versions of the missing modules are installed.`))
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// create build task handlers
|
|
51
|
-
const handlers = []
|
|
52
|
-
tasks.forEach((task) => {
|
|
53
|
-
if (task) {
|
|
54
|
-
const handler = this._createHandler(task, buildOptions)
|
|
55
|
-
handlers.push(handler)
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
// use resolved tasks
|
|
60
|
-
buildOptions.tasks = handlers.map(handler => handler.task)
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
await this._executePrepare(handlers, buildOptions)
|
|
64
|
-
await this._executeCleanBuildTasks(handlers, buildOptions, clean)
|
|
65
|
-
|
|
66
|
-
// throwing Exception in case of compilation errors
|
|
67
|
-
const buildResult = await this._executeBuildTasks(handlers, buildOptions)
|
|
68
|
-
|
|
69
|
-
await this._writeGenerationLog(handlers, buildOptions)
|
|
70
|
-
this._logBuildOutput(handlers, buildOptions)
|
|
71
|
-
this._logMessages(buildOptions, [...BuildTaskEngine._getHandlerMessages(handlers), ...messages])
|
|
72
|
-
this._logTimer(startTime, Date.now())
|
|
73
|
-
|
|
74
|
-
return buildResult
|
|
75
|
-
} catch (error) {
|
|
76
|
-
this._logBuildOutput(handlers, buildOptions)
|
|
77
|
-
|
|
78
|
-
// cds CLI layer logs in case of an exception if invoked from CLI
|
|
79
|
-
if (!buildOptions.cli) {
|
|
80
|
-
this._logMessages(buildOptions, [...BuildTaskEngine._getErrorMessages([error]), ...messages])
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (error.name === BuildError.name && error.errors.length > 0 && error.errors[0].constructor.name === COMPILATION_ERROR) {
|
|
84
|
-
// TODO: for compatibility reasons with cds-mtx we're throwing the actual cause of type CompiliationError
|
|
85
|
-
// Note: As a consequence we are loosing any info or warning messages issued by build task handlers
|
|
86
|
-
throw error.errors[0]
|
|
87
|
-
}
|
|
88
|
-
throw error
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* BuildTaskHandler#prepare has been deprecated and was never part of the public API.
|
|
94
|
-
* Currently only used by internal FioriBuildTaskHandller.
|
|
95
|
-
* @deprecated
|
|
96
|
-
* @param {*} handlers
|
|
97
|
-
* @returns
|
|
98
|
-
*/
|
|
99
|
-
async _executePrepare(handlers, buildOptions) {
|
|
100
|
-
const handlerGroups = new Map()
|
|
101
|
-
|
|
102
|
-
// group handlers by type
|
|
103
|
-
handlers.forEach(handler => {
|
|
104
|
-
handlerGroups.has(handler.task.for) ? handlerGroups.get(handler.task.for).push(handler) : handlerGroups.set(handler.task.for, [handler])
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
const promises = []
|
|
108
|
-
for (let handlerGroup of handlerGroups.values()) {
|
|
109
|
-
promises.push(this._doPrepare(handlerGroup, buildOptions))
|
|
110
|
-
}
|
|
111
|
-
return Promise.all(promises)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* @deprecated
|
|
116
|
-
* @param {*} handlerGroup
|
|
117
|
-
*/
|
|
118
|
-
async _doPrepare(handlerGroup, buildOptions) {
|
|
119
|
-
for (let handler of handlerGroup) {
|
|
120
|
-
// prepare has been deprecated
|
|
121
|
-
if (handler instanceof BuildTaskHandlerInternal) {
|
|
122
|
-
this.logger._debug && this.logger.debug(`preparing, handler [${handler.constructor.name}], src [${relativePaths(buildOptions.root, handler.task.src)}]`)
|
|
123
|
-
const result = await handler.prepare()
|
|
124
|
-
if (result === false) {
|
|
125
|
-
break
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async _executeCleanBuildTasks(handlers, buildOptions, clean) {
|
|
132
|
-
if (clean) {
|
|
133
|
-
// clean entire build staging folder once
|
|
134
|
-
if (buildOptions.target !== buildOptions.root) {
|
|
135
|
-
this.logger._debug && this.logger.debug(`cleaning staging folder ${buildOptions.target}`)
|
|
136
|
-
await fs.promises.rm(buildOptions.target, { force: true, recursive: true })
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const results = await Promise.allSettled(handlers.map((handler) => {
|
|
140
|
-
this.logger._debug && this.logger.debug(`cleaning, handler [${handler.constructor.name}], src [${relativePaths(buildOptions.root, handler.task.src)}]`)
|
|
141
|
-
return handler.clean()
|
|
142
|
-
}))
|
|
143
|
-
// check for errors and throw exception
|
|
144
|
-
BuildTaskEngine._resolveHandlerResponse(results, buildOptions)
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async _executeBuildTasks(handlers, buildOptions) {
|
|
149
|
-
// sort handlers based on priority in
|
|
150
|
-
handlers = handlers.sort((a, b) => {
|
|
151
|
-
return a.priority === b.priority ? 0 : a.priority > b.priority ? -1 : 1
|
|
152
|
-
})
|
|
153
|
-
// group handlers with same priority in order to execute in parallel
|
|
154
|
-
const buildPipeline = handlers.reduce((acc, handler) => {
|
|
155
|
-
if (acc.length === 0) {
|
|
156
|
-
acc.push([handler])
|
|
157
|
-
} else {
|
|
158
|
-
const currGroup = acc[acc.length - 1]
|
|
159
|
-
if (currGroup[0].priority === handler.priority) {
|
|
160
|
-
currGroup.push(handler)
|
|
161
|
-
} else {
|
|
162
|
-
acc.push([handler])
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return acc
|
|
166
|
-
}, [])
|
|
167
|
-
|
|
168
|
-
const results = await this._executePipeline(buildOptions, buildPipeline)
|
|
169
|
-
|
|
170
|
-
// check for errors and throw exception - return results otherwise including any compiler and build status messages
|
|
171
|
-
return BuildTaskEngine._resolveHandlerResponse(results, buildOptions, BuildTaskEngine._getHandlerMessages(handlers))
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async _executePipeline(buildOptions, pipeline) {
|
|
175
|
-
let allResults = []
|
|
176
|
-
for (const group of pipeline) {
|
|
177
|
-
const results = await Promise.allSettled(group.map((handler) => {
|
|
178
|
-
this.logger._debug && this.logger.debug(`building, handler [${handler.constructor.name}], src [${relativePaths(buildOptions.root, handler.task.src)}]`)
|
|
179
|
-
return handler.build()
|
|
180
|
-
.then(handlerResult => {
|
|
181
|
-
return Promise.resolve({
|
|
182
|
-
task: handler.task,
|
|
183
|
-
result: handlerResult,
|
|
184
|
-
messages: BuildTaskEngine._sortMessagesUnique(buildOptions, handler.messages)
|
|
185
|
-
})
|
|
186
|
-
})
|
|
187
|
-
}))
|
|
188
|
-
allResults = allResults.concat(results)
|
|
189
|
-
}
|
|
190
|
-
return allResults
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
static _resolveHandlerResponse(results, buildOptions, handlerMessages = []) {
|
|
194
|
-
const errors = []
|
|
195
|
-
const resolvedResults = results.reduce((acc, r) => {
|
|
196
|
-
if (r.status === 'fulfilled') {
|
|
197
|
-
acc.push(r.value)
|
|
198
|
-
}
|
|
199
|
-
if (r.status === 'rejected' && r.reason) {
|
|
200
|
-
errors.push(r.reason)
|
|
201
|
-
}
|
|
202
|
-
return acc
|
|
203
|
-
}, [])
|
|
204
|
-
|
|
205
|
-
if (errors.length > 0) {
|
|
206
|
-
const error = errors.find(e => e.constructor.name !== COMPILATION_ERROR)
|
|
207
|
-
if (error) {
|
|
208
|
-
// throw original error, including BuildErrors
|
|
209
|
-
// for BuildErrors we do not merge other build messages that might exist in order to keep the original error intact
|
|
210
|
-
throw error
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// propagate existing CompilationErrors
|
|
214
|
-
// merge all existing compilation messages into a single CompilationError
|
|
215
|
-
// compiler warning and info messages are returned as handler messages
|
|
216
|
-
const compileErrors = errors.filter(e => e.constructor.name === COMPILATION_ERROR)
|
|
217
|
-
const compileMessages = handlerMessages.filter(message => message.constructor.name === COMPILE_MESSAGE)
|
|
218
|
-
if (compileErrors.length) {
|
|
219
|
-
throw new CompilationError(BuildTaskEngine._sortMessagesUnique(buildOptions, BuildTaskEngine._getErrorMessages(compileErrors), compileMessages))
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return resolvedResults
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
_createHandler(task, buildOptions) {
|
|
226
|
-
try {
|
|
227
|
-
const providerFactory = new BuildTaskProviderFactory(this._logger, buildOptions)
|
|
228
|
-
const handler = providerFactory.createHandler(task)
|
|
229
|
-
handler.init()
|
|
230
|
-
|
|
231
|
-
if (!(handler instanceof BuildTaskHandlerInternal) && handler.priority !== 1) {
|
|
232
|
-
// Custom build handlers are executed before internal handlers to ensure
|
|
233
|
-
// that generated content cannot be overwriten by mistake
|
|
234
|
-
throw new Error(`Illegal priority for ${handler.consructor.name} encountered for custom handler - in this version only priority value '1' is allowed`)
|
|
235
|
-
}
|
|
236
|
-
this._logTaskHandler(handler, buildOptions)
|
|
237
|
-
|
|
238
|
-
return handler
|
|
239
|
-
} catch (error) {
|
|
240
|
-
log(error, { log: this.logger.log })
|
|
241
|
-
throw error
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
_logBuildOutput(handlers, buildOptions) {
|
|
246
|
-
// log all generated files
|
|
247
|
-
const files = BuildTaskEngine._getBuildOutput(handlers, buildOptions)
|
|
248
|
-
if (files.length > 0) {
|
|
249
|
-
this.logger.log(`done > wrote output to:\n ${files.join("\n ")}\n`)
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
async _writeGenerationLog(handlers, buildOptions) {
|
|
254
|
-
const outputFile = cds.env.build.outputfile || process.env.GENERATION_LOG
|
|
255
|
-
if (outputFile) {
|
|
256
|
-
const files = BuildTaskEngine._getBuildOutput(handlers, buildOptions)
|
|
257
|
-
this.logger.log(`writing generation log to [${outputFile}]\n`)
|
|
258
|
-
try {
|
|
259
|
-
await fs.promises.mkdir(path.dirname(outputFile), { recursive: true }).then(() => fs.promises.writeFile(outputFile, files.join('\n')))
|
|
260
|
-
} catch (error) {
|
|
261
|
-
this.logger.error(`failed to write generation log`)
|
|
262
|
-
this.logger.error(error.stack || error)
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
static _getBuildOutput(handlers, buildOptions) {
|
|
268
|
-
const files = handlers.reduce((acc, handler) => acc.concat(handler.files), []).sort()
|
|
269
|
-
return files.map(file => path.relative(buildOptions.root, file))
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
_logTimer(start, end) {
|
|
273
|
-
this.logger.log(`build completed in ${end - start} ms\n`)
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
_logTaskHandler(handler, buildOptions) {
|
|
277
|
-
this.logger._debug && this.logger.debug(`handler ${handler.constructor.name}`)
|
|
278
|
-
this.logger._debug && this.logger.debug(`details src [${relativePaths(buildOptions.root, handler.task.src)}], dest [${relativePaths(buildOptions.root, handler.task.dest)}], use [${handler.task.use}], options [${JSON.stringify(handler.task.options)}]`) //NOSONAR
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
_logMessages(buildOptions, messages) {
|
|
282
|
-
if (messages.length > 0) {
|
|
283
|
-
const options = {
|
|
284
|
-
log: this.logger.log,
|
|
285
|
-
"log-level": BuildTaskEngine._getLogLevel(buildOptions) // ensures that for tests the correct cds.env is used
|
|
286
|
-
}
|
|
287
|
-
deduplicateMessages(messages)
|
|
288
|
-
log(messages, options)
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
static _resolveRequiredSapServices(tasks) {
|
|
293
|
-
const taskModelPaths = tasks.reduce((acc, task) => {
|
|
294
|
-
const model = task.options?.model
|
|
295
|
-
if (model) {
|
|
296
|
-
if (Array.isArray(model)) {
|
|
297
|
-
model.forEach(m => acc.add(m))
|
|
298
|
-
} else {
|
|
299
|
-
acc.add(model)
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
return acc
|
|
303
|
-
}, new Set())
|
|
304
|
-
|
|
305
|
-
return resolveRequiredSapModels([...taskModelPaths])
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Returns a sorted and flattened list of all messages extracted from the given errors.
|
|
310
|
-
* @param {Array<Error>} errors
|
|
311
|
-
*/
|
|
312
|
-
static _getErrorMessages(errors) {
|
|
313
|
-
let messages = []
|
|
314
|
-
// flatten all compile messages in order to filter duplicates and sort later on
|
|
315
|
-
errors.forEach(error => {
|
|
316
|
-
if (Array.isArray(error.errors) && error.errors.length > 0) {
|
|
317
|
-
messages = messages.concat(BuildTaskEngine._getErrorMessages(error.errors))
|
|
318
|
-
} else {
|
|
319
|
-
messages.push(error)
|
|
320
|
-
}
|
|
321
|
-
})
|
|
322
|
-
return messages
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Returns compiler messages and validation messages issued by handlers.
|
|
327
|
-
* @param {Array<BuildTaskHandler>} handlers
|
|
328
|
-
*/
|
|
329
|
-
static _getHandlerMessages(handlers) {
|
|
330
|
-
return handlers.reduce((acc, handler) => acc.concat(handler.messages), [])
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Sort and filter the given errors of type CompileMessage or BuildMessage according to their severity and location,
|
|
335
|
-
* but leave any other errors untouched as part of the result array.<br>
|
|
336
|
-
* The log level passed as 'buildOptions.log-level' or defined in 'cds.env' is used to filter the given messages.
|
|
337
|
-
* @param {object} buildOptions
|
|
338
|
-
* @param {...Error} messages
|
|
339
|
-
*/
|
|
340
|
-
static _sortMessagesUnique(buildOptions, ...messages) {
|
|
341
|
-
const logLevelIdx = LOG_LEVELS.indexOf(this._getLogLevel(buildOptions))
|
|
342
|
-
// flatten
|
|
343
|
-
messages = messages.reduce((acc, m) => acc.concat(m), [])
|
|
344
|
-
// filter according to log-level
|
|
345
|
-
const filteredMessages = messages.filter(message => !message.severity || logLevelIdx >= SEVERITIES.indexOf(message.severity))
|
|
346
|
-
// remove duplicates
|
|
347
|
-
deduplicateMessages(filteredMessages)
|
|
348
|
-
// sort
|
|
349
|
-
return sortMessagesSeverityAware(filteredMessages)
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Return user defined log level or default value 'warn'
|
|
354
|
-
* @param {string} buildOptions
|
|
355
|
-
*/
|
|
356
|
-
static _getLogLevel(buildOptions) {
|
|
357
|
-
return buildOptions["log-level"] || cds.env["log-level"]
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
module.exports = BuildTaskEngine
|