@sap/cds 6.8.4 → 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/CHANGELOG.md +58 -5
- 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 +1 -1
- 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 +1 -1
- 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/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/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/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
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const cds = require('../cds')
|
|
4
|
-
const BuildTaskHandler = require('../buildTaskHandler')
|
|
5
|
-
const { hasOptionValue } = require('../util')
|
|
6
|
-
const { FOLDER_GEN, BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY } = require('../constants')
|
|
7
|
-
|
|
8
|
-
class BuildTaskHandlerInternal extends BuildTaskHandler {
|
|
9
|
-
/**
|
|
10
|
-
* Returns the logger that has been passed the build task engine.
|
|
11
|
-
* @returns {object}
|
|
12
|
-
*/
|
|
13
|
-
get logger() {
|
|
14
|
-
//injected by framework
|
|
15
|
-
return this._logger;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Returns the build options used for this CDS build execution
|
|
19
|
-
* @returns {object}
|
|
20
|
-
*/
|
|
21
|
-
get buildOptions() {
|
|
22
|
-
return this._buildOptions
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Custom build handlers are executed before internal handlers in order
|
|
26
|
-
* ensure and content cannot be overwritten by mistake.
|
|
27
|
-
*/
|
|
28
|
-
get priority() {
|
|
29
|
-
return BuildTaskHandlerInternal.PRIORITY_MAX_VALUE
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async clean() {
|
|
33
|
-
// the build results have already been deleted by the BuildTaskEngine if the build.target !== '.'
|
|
34
|
-
// make sure that src is not a subfolder of dest
|
|
35
|
-
if (this._buildOptions.root === this._buildOptions.target && this.task.src !== this.task.dest && !this._isSubDirectory(this.task.dest, this.task.src)) {
|
|
36
|
-
await fs.promises.rm(this.task.dest, { force: true, recursive: true })
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Used by the framework to initialize the logger implementation.
|
|
42
|
-
* @param {object} logger
|
|
43
|
-
*/
|
|
44
|
-
set logger(logger) {
|
|
45
|
-
super.logger = logger;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Sets the build options used for this CDS build execution
|
|
49
|
-
* @param {object} options
|
|
50
|
-
*/
|
|
51
|
-
set buildOptions(options) {
|
|
52
|
-
super.buildOptions = options
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Maximum allowed priority for internal build tasks.
|
|
56
|
-
*/
|
|
57
|
-
static get PRIORITY_MAX_VALUE() {
|
|
58
|
-
return 0;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Minimum allowed priority for custom build tasks.
|
|
62
|
-
*/
|
|
63
|
-
static get PRIORITY_MIN_VALUE() {
|
|
64
|
-
return Number.MIN_SAFE_INTEGER;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Called by the framework after {@link #init()}. Handlers may want to perform more elaborate preparation.
|
|
69
|
-
* E.g. caching some pre-calculated data that can be used across multiple build tasks. This kind of data
|
|
70
|
-
* has to be stored in the handler type specific buildOptions section.
|
|
71
|
-
* @returns {Promise<boolean>} A value 'false' indicates that {@link #prepare()} will not be called for other instances
|
|
72
|
-
* of this handler type.
|
|
73
|
-
* True indicates that {@link #prepare()} will be called for other instances of this of this handler type.
|
|
74
|
-
* @deprecated
|
|
75
|
-
*/
|
|
76
|
-
async prepare() {
|
|
77
|
-
// cancel subsequent prepare calls for other handlers of the same type by default
|
|
78
|
-
return false
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Returns whether cds env has a property with the specified value.
|
|
83
|
-
* If the value is omitted the existence of the given property name is checked.
|
|
84
|
-
* @param {string} qualifiedName
|
|
85
|
-
* @param {any=} value
|
|
86
|
-
*/
|
|
87
|
-
hasCdsEnvOption(qualifiedName, value) {
|
|
88
|
-
return hasOptionValue(cds.env.get(qualifiedName), value)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Determines whether the given build option value has been set for this build task.
|
|
93
|
-
* If the value is omitted, the existence of the given property name is checked.
|
|
94
|
-
* @param {string} qualifiedName
|
|
95
|
-
* @param {any=} value
|
|
96
|
-
*/
|
|
97
|
-
hasBuildOption(qualifiedName, value) {
|
|
98
|
-
return hasOptionValue(this._getBuildOption(qualifiedName), value)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Returns the value of the given build option defined for this build task.
|
|
103
|
-
* @param {string} qualifiedName
|
|
104
|
-
*/
|
|
105
|
-
getBuildOption(qualifiedName) {
|
|
106
|
-
return super._getBuildOption(qualifiedName)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Returns a list of CDS model files defining the transitive closure of the CDS model based on the model options
|
|
111
|
-
* defined for this build task.
|
|
112
|
-
*/
|
|
113
|
-
resolveModel() {
|
|
114
|
-
return this._resolveModel()
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Returns whether the build results of this build plugin are created inplace
|
|
119
|
-
* or in a separate staging folder which is not part of the build tasks src folder.
|
|
120
|
-
*/
|
|
121
|
-
isStagingBuild() {
|
|
122
|
-
return !this.task.src.startsWith(this.task.dest)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
async copyNativeContent(srcDir, destDir, customFilter) {
|
|
126
|
-
const files = BuildTaskHandlerInternal._find(srcDir, (src) => {
|
|
127
|
-
// do not copy files that:
|
|
128
|
-
// - are contained in the 'buildOptions.target' folder
|
|
129
|
-
// - are contained in this modules 'dest' folder
|
|
130
|
-
// - are contained in some generation folder
|
|
131
|
-
// - do NOT fulfill additional specific filter criteria
|
|
132
|
-
return this._commonStagingBuildFilter(src, destDir) && (!customFilter || customFilter.call(this, src))
|
|
133
|
-
})
|
|
134
|
-
return Promise.all(
|
|
135
|
-
files.map((srcFile) => {
|
|
136
|
-
let relFile = path.relative(srcDir, srcFile)
|
|
137
|
-
let destFile = path.join(destDir, relFile)
|
|
138
|
-
return this.copy(srcFile).to(destFile)
|
|
139
|
-
})
|
|
140
|
-
)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async compileToJson(model, csnFile) {
|
|
144
|
-
// This will als add a @source prop containing the relative path to the origin .cds source file
|
|
145
|
-
// and a parsed _where clause for @restrict.{grant,where} annotations.
|
|
146
|
-
// The @source annotation is required for correct custom handler resolution if no @impl annotation has been defined as
|
|
147
|
-
// custom service handler implementations are relative to the origin .cds source files.
|
|
148
|
-
// For staging builds (task.src !== task.dest) the csn.json file that is served at runtime is copied into a corresponding srv subfolder.
|
|
149
|
-
// 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.
|
|
150
|
-
// This ensures that the paths are relative to the cwd when executing cds run.
|
|
151
|
-
const jsonOptions = {
|
|
152
|
-
cwd: this.buildOptions.root,
|
|
153
|
-
src: this.task.src === this.task.dest ? this.task.src : this.buildOptions.root
|
|
154
|
-
}
|
|
155
|
-
const csnStr = cds.compile.to.json(model, jsonOptions)
|
|
156
|
-
if (!this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
|
|
157
|
-
await this.write(csnStr).to(csnFile)
|
|
158
|
-
}
|
|
159
|
-
return csnStr
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Collect and write language bundles into a single i18n.json file.
|
|
164
|
-
* @param {Object} model
|
|
165
|
-
* @param {string} bundleDest
|
|
166
|
-
*/
|
|
167
|
-
async collectLanguageBundles(model, bundleDest) {
|
|
168
|
-
// collect effective i18n properties...
|
|
169
|
-
let bundles = {}
|
|
170
|
-
const bundleGenerator = cds.localize.bundles4(model)
|
|
171
|
-
if (bundleGenerator && bundleGenerator[Symbol.iterator]) {
|
|
172
|
-
for (let [locale, bundle] of bundleGenerator) {
|
|
173
|
-
// fallback bundle has the name ""
|
|
174
|
-
if (typeof locale === 'string') {
|
|
175
|
-
bundles[locale] = bundle
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// omit bundles in case the fallback bundle is the only existing entry
|
|
181
|
-
const keys = Object.keys(bundles)
|
|
182
|
-
if (keys.length === 1 && keys[0] === "" && Object.keys(bundles[keys[0]]).length === 0) {
|
|
183
|
-
bundles = {}
|
|
184
|
-
}
|
|
185
|
-
// copied from ../compile/i18n.js
|
|
186
|
-
const { file: base = 'i18n' } = cds.env.i18n
|
|
187
|
-
const file = path.join(bundleDest, base + '.json')
|
|
188
|
-
|
|
189
|
-
// bundleDest might be null
|
|
190
|
-
if (bundleDest && Object.keys(bundles).length > 0) {
|
|
191
|
-
if (!this.hasBuildOption(BUILD_OPTION_OUTPUT_MODE, OUTPUT_MODE_RESULT_ONLY)) {
|
|
192
|
-
await this.write(bundles).to(file)
|
|
193
|
-
}
|
|
194
|
-
return { file, bundles }
|
|
195
|
-
}
|
|
196
|
-
return null
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
_isSubDirectory(parent, child) {
|
|
200
|
-
return !path.relative(parent, child).startsWith('..')
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
_commonStagingBuildFilter(src, destDir) {
|
|
204
|
-
if (typeof src !== "string" || typeof destDir !== "string") {
|
|
205
|
-
return false
|
|
206
|
-
}
|
|
207
|
-
if (!fs.statSync(src).isDirectory()) {
|
|
208
|
-
return true //file
|
|
209
|
-
}
|
|
210
|
-
if (src === destDir) {
|
|
211
|
-
return false
|
|
212
|
-
}
|
|
213
|
-
const regex = new RegExp(FOLDER_GEN + "\\b")
|
|
214
|
-
if (src === this.buildOptions.target) {
|
|
215
|
-
return false
|
|
216
|
-
}
|
|
217
|
-
return !regex.exec(path.basename(src))
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
static _find(srcDir, filter) {
|
|
221
|
-
const files = []
|
|
222
|
-
this._traverseFileSystem(srcDir, files, filter)
|
|
223
|
-
return files;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
static _traverseFileSystem(srcDir, files, filter) {
|
|
227
|
-
let entries = []
|
|
228
|
-
try {
|
|
229
|
-
entries = fs.readdirSync(srcDir)
|
|
230
|
-
} catch (e) {
|
|
231
|
-
// ignore if not existing
|
|
232
|
-
}
|
|
233
|
-
entries.map(subDirEntry => path.join(srcDir, subDirEntry)).forEach((entry) => {
|
|
234
|
-
this._handleResource(entry, files, filter)
|
|
235
|
-
})
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
static _handleResource(entry, files, filter) {
|
|
239
|
-
if (!filter || filter.call(this, entry)) {
|
|
240
|
-
var stats = this._getResourceStatus(entry)
|
|
241
|
-
if (stats.isDirectory()) {
|
|
242
|
-
this._traverseFileSystem(entry, files, filter)
|
|
243
|
-
} else if (stats.isFile() || stats.isSymbolicLink()) {
|
|
244
|
-
files.push(entry)
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// for testing purposes
|
|
250
|
-
static _getResourceStatus(entry) {
|
|
251
|
-
return fs.lstatSync(entry)
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
module.exports = BuildTaskHandlerInternal
|
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const cds = require('../cds')
|
|
4
|
-
const { hasJavaNature, getProperty, isStreamlinedMtx, getDefaultModelOptions, BuildError, hasOptionValue } = require('../util')
|
|
5
|
-
const BuildTaskProvider = require('../buildTaskProvider')
|
|
6
|
-
|
|
7
|
-
const { FILE_EXT_CDS, BUILD_TASK_HANA, BUILD_TASK_FIORI, BUILD_TASK_JAVA, BUILD_TASK_JAVA_CF, BUILD_TASK_NODEJS, BUILD_TASK_NODE_CF, BUILD_TASK_MTX,
|
|
8
|
-
BUILD_TASK_PREFIX, BUILD_TASKS, BUILD_TASK_MTX_SIDECAR, MTX_SIDECAR_FOLDER, BUILD_TASK_MTX_EXTENSION, NODEJS_MODEL_EXCLUDE_LIST,
|
|
9
|
-
DEFAULT_BUILT_IN_MODELS } = require("../constants")
|
|
10
|
-
|
|
11
|
-
class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
12
|
-
constructor(logger) {
|
|
13
|
-
super()
|
|
14
|
-
this._logger = logger
|
|
15
|
-
}
|
|
16
|
-
get logger() {
|
|
17
|
-
return this._logger
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
canHandleTask(task) {
|
|
21
|
-
return BUILD_TASKS.includes(task.for)
|
|
22
|
-
|| task.use && task.use.startsWith(BUILD_TASK_PREFIX)
|
|
23
|
-
// support different build task implementations of the same build task ID defined by 'for'
|
|
24
|
-
//return (BUILD_TASKS.includes(task.for) && !task.use) || (task.use && task.use.startsWith(BUILD_TASK_PREFIX))
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
loadHandler(task) {
|
|
28
|
-
return require(`./${BuildTaskProviderInternal._getForValueFromTask(task)}`)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async lookupTasks(tasks, buildOptions) {
|
|
32
|
-
return this._createTasks(tasks, buildOptions, tasks.length > 0)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async applyTaskDefaults(task, buildOptions) {
|
|
36
|
-
const taskFor = BuildTaskProviderInternal._getForValueFromTask(task)
|
|
37
|
-
const { root: projectPath } = buildOptions
|
|
38
|
-
task.for = task.for || taskFor
|
|
39
|
-
task.use = task.use || `${BUILD_TASK_PREFIX}/${taskFor}`
|
|
40
|
-
|
|
41
|
-
BuildTaskProviderInternal._setDefaultSrcFolder(task)
|
|
42
|
-
|
|
43
|
-
// src folder needs to be initialized first
|
|
44
|
-
BuildTaskProviderInternal._setDefaultModel(task, projectPath)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async _createTasks(tasks, buildOptions, addRequiredTasks) {
|
|
48
|
-
const { root: projectPath } = buildOptions
|
|
49
|
-
let db = typeof cds.env.folders.db === "string" ? [BuildTaskProviderInternal._normalizePath(cds.env.folders.db)] : cds.env.folders.db
|
|
50
|
-
let srv = typeof cds.env.folders.srv === "string" ? [BuildTaskProviderInternal._normalizePath(cds.env.folders.srv)] : cds.env.folders.srv
|
|
51
|
-
|
|
52
|
-
const dbOptions = {
|
|
53
|
-
model: []
|
|
54
|
-
}
|
|
55
|
-
const srvOptions = {
|
|
56
|
-
model: []
|
|
57
|
-
}
|
|
58
|
-
if (Array.isArray(db) && db.length > 0) {
|
|
59
|
-
db = BuildTaskProviderInternal._getModuleFolder(projectPath, db) || null
|
|
60
|
-
if (!db && !addRequiredTasks) { // log once
|
|
61
|
-
this.logger.debug("No database module found")
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (Array.isArray(srv) && srv.length > 0) {
|
|
65
|
-
srv = BuildTaskProviderInternal._getModuleFolder(projectPath, srv) || null
|
|
66
|
-
if (!srv && !addRequiredTasks) { // log once
|
|
67
|
-
this.logger.debug("No service module found")
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
// create required build tasks
|
|
71
|
-
if (addRequiredTasks) {
|
|
72
|
-
const mtxTask = tasks.find(task => task.for === BUILD_TASK_MTX || task.for === BUILD_TASK_MTX_SIDECAR)
|
|
73
|
-
if (mtxTask) {
|
|
74
|
-
//restore used tasks as they might have been filtered by 'cds build --for mtx'
|
|
75
|
-
if (mtxTask._uses) {
|
|
76
|
-
mtxTask._uses.map(use => use.task).forEach(task => {
|
|
77
|
-
if (!tasks.includes(task)) {
|
|
78
|
-
tasks.push(task)
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
}
|
|
82
|
-
let dbTask = tasks.find(task => task.for === BUILD_TASK_HANA)
|
|
83
|
-
if (!dbTask) {
|
|
84
|
-
// db task might be missing if mtx task is enforced by 'cds build --for mtx'
|
|
85
|
-
dbTask = this._createDbTask(projectPath, db, dbOptions)
|
|
86
|
-
if (dbTask) {
|
|
87
|
-
tasks.push(dbTask)
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
if (dbTask && (!mtxTask._uses || !mtxTask._uses.map(use => use.task).includes(dbTask))) {
|
|
91
|
-
const use = { task: dbTask }
|
|
92
|
-
mtxTask._uses ? mtxTask._uses.push(use) : mtxTask._uses = [use]
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
} else {
|
|
96
|
-
!db && this.logger._debug && this.logger.debug(`project doesn't have a database module '${cds.env.folders.db}'`)
|
|
97
|
-
!srv && this.logger._debug && this.logger.debug(`project doesn't have a service module '${cds.env.folders.srv}'`)
|
|
98
|
-
|
|
99
|
-
// create hana build task
|
|
100
|
-
const dbTask = this._createDbTask(projectPath, db, dbOptions, buildOptions)
|
|
101
|
-
if (dbTask) {
|
|
102
|
-
tasks.push(dbTask)
|
|
103
|
-
}
|
|
104
|
-
// create java or node build task
|
|
105
|
-
const srvTask = this._createSrvTask(projectPath, srv, srvOptions)
|
|
106
|
-
if (srvTask) {
|
|
107
|
-
tasks.push(srvTask)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// REVISIT: disable for cds-dk projectReader - causing error due to inconsistent state during project creation
|
|
111
|
-
if (buildOptions.resolve !== false) {
|
|
112
|
-
// create mtx build task
|
|
113
|
-
const mtxTask = this._createMtxTask(projectPath, srv, srv, tasks)
|
|
114
|
-
if (mtxTask) {
|
|
115
|
-
tasks.push(mtxTask)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
_createDbTask(projectPath, src, taskOptions, buildOptions) {
|
|
122
|
-
this.logger.debug("determining database kind.")
|
|
123
|
-
if (!src || BuildTaskProviderInternal._isMtxExtension()) {
|
|
124
|
-
return null
|
|
125
|
-
}
|
|
126
|
-
let task = null
|
|
127
|
-
if (this._useHana(projectPath, buildOptions)) {
|
|
128
|
-
this.logger.debug("found HANA database.")
|
|
129
|
-
// legacy build supports dest property
|
|
130
|
-
const compileDest = cds.env.data?.dest
|
|
131
|
-
if (compileDest) {
|
|
132
|
-
//../db/src/gen
|
|
133
|
-
// compileDest is relative to src folder in modular build - resolve correctly
|
|
134
|
-
taskOptions.compileDest = path.relative(path.resolve(projectPath, src), path.resolve(projectPath, compileDest))
|
|
135
|
-
}
|
|
136
|
-
task = {
|
|
137
|
-
src: src,
|
|
138
|
-
for: BUILD_TASK_HANA,
|
|
139
|
-
options: taskOptions
|
|
140
|
-
}
|
|
141
|
-
} else {
|
|
142
|
-
this.logger.debug("found sqlite database - skipping HANA build task")
|
|
143
|
-
}
|
|
144
|
-
return task
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
_useHana(projectPath, buildOptions) {
|
|
148
|
-
if (getProperty(buildOptions, "for.hana.skipManifestGeneration") // deprecated fallback for webide fullstack and mtx
|
|
149
|
-
|| getProperty(buildOptions, "for.hana.contentManifest") === false // fallback for webide fullstack and mtx
|
|
150
|
-
|| cds.env.requires.db?.kind === "hana"
|
|
151
|
-
|| cds.env.requires.db?.dialect === "hana") {
|
|
152
|
-
|
|
153
|
-
return true
|
|
154
|
-
}
|
|
155
|
-
// false if other db has been defined
|
|
156
|
-
if (cds.env.requires.db?.kind) {
|
|
157
|
-
return false
|
|
158
|
-
}
|
|
159
|
-
// check whether cds config represents a legacy build system config for which requires.db was not configured
|
|
160
|
-
// Note: compat layer sets requires.db: {}
|
|
161
|
-
const userEnv = cds.env.for("cds", projectPath, false)
|
|
162
|
-
return userEnv && (userEnv.data?.model || userEnv.service?.model)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
_createMtxTask(projectPath, src, dest, tasks) {
|
|
166
|
-
this.logger.debug("determining mtx version of nodejs project")
|
|
167
|
-
|
|
168
|
-
// preserve order of creation
|
|
169
|
-
if (BuildTaskProviderInternal._isMtxExtension()) {
|
|
170
|
-
this.logger.debug("MTX extension app")
|
|
171
|
-
return { for: BUILD_TASK_MTX_EXTENSION }
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (isStreamlinedMtx()) {
|
|
175
|
-
const sidecarPath = path.join(projectPath, MTX_SIDECAR_FOLDER)
|
|
176
|
-
let sidecarEnv
|
|
177
|
-
if (fs.existsSync(sidecarPath)) {
|
|
178
|
-
sidecarEnv = cds.env.for("cds", sidecarPath)
|
|
179
|
-
}
|
|
180
|
-
if (
|
|
181
|
-
cds.env.profiles?.includes('with-mtx-sidecar') || // new presets
|
|
182
|
-
cds.env.requires["cds.xt.ModelProviderService"]?.external // for compatibility with former mtxs presets
|
|
183
|
-
) {
|
|
184
|
-
this.logger.debug("MTX app with sidecar")
|
|
185
|
-
if (!sidecarEnv) {
|
|
186
|
-
throw new BuildError(`MTX sidecar directory '${sidecarPath}' not existing. Custom build task configuration required if the folder is named differently.`)
|
|
187
|
-
}
|
|
188
|
-
if (!sidecarEnv.requires["cds.xt.ModelProviderService"]?._in_sidecar) {
|
|
189
|
-
// correct profile might have been set, but couldn't be resolved
|
|
190
|
-
if (sidecarEnv.profiles?.includes('mtx-sidecar')) {
|
|
191
|
-
throw new BuildError('MTX configuration cannot be resolved. Make sure an up-to-date version of @sap/cds-mtxs is installed.')
|
|
192
|
-
}
|
|
193
|
-
throw new BuildError(`Invalid MTX sidecar configuration - profile 'mtx-sidecar' not set.`)
|
|
194
|
-
}
|
|
195
|
-
return { for: BUILD_TASK_MTX_SIDECAR }
|
|
196
|
-
}
|
|
197
|
-
if (sidecarEnv?.requires["cds.xt.ModelProviderService"]?._in_sidecar || sidecarEnv?.profiles?.includes('mtx-sidecar')) {
|
|
198
|
-
throw new BuildError(`MTX sidecar requires profile 'with-mtx-sidecar' in project root configuration.`)
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (cds.env.requires["cds.xt.ModelProviderService"]?._in_sidecar || cds.env.profiles?.includes('mtx-sidecar')) {
|
|
202
|
-
// cds build is executed in sidecar folder
|
|
203
|
-
throw new BuildError(`Seems that you are executing 'cds build' in the 'mtx/sidecar' folder. Execute 'cds build' in the project root folder instead.`)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// without sidecar
|
|
207
|
-
if (!tasks.some(task => task.for === BUILD_TASK_JAVA || task.for === BUILD_TASK_JAVA_CF)) {
|
|
208
|
-
this.logger.debug("Nodejs MTX app without sidecar")
|
|
209
|
-
return {
|
|
210
|
-
for: BUILD_TASK_MTX,
|
|
211
|
-
src
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
if (!tasks.some(task => task.for === BUILD_TASK_JAVA || task.for === BUILD_TASK_JAVA_CF)) {
|
|
216
|
-
if (cds.env.requires.multitenancy) {
|
|
217
|
-
this.logger.debug("Nodejs Classic MTX app without sidecar")
|
|
218
|
-
return {
|
|
219
|
-
src: ".",
|
|
220
|
-
for: BUILD_TASK_MTX,
|
|
221
|
-
dest
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
_createSrvTask(projectPath, src, taskOptions) {
|
|
228
|
-
this.logger.debug("determining implementation technology")
|
|
229
|
-
if (!src || BuildTaskProviderInternal._isMtxExtension()) {
|
|
230
|
-
return null
|
|
231
|
-
}
|
|
232
|
-
let task = null
|
|
233
|
-
if (BuildTaskProviderInternal._hasJavaNature(projectPath, src)) {
|
|
234
|
-
task = this._createJavaTask(projectPath, src, taskOptions)
|
|
235
|
-
} else {
|
|
236
|
-
task = this._createNodeTask(src, taskOptions)
|
|
237
|
-
}
|
|
238
|
-
return task
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
_createJavaTask(projectPath, src, taskOptions) {
|
|
242
|
-
this.logger.debug("found implementation technology java")
|
|
243
|
-
// legacy build supports dest property
|
|
244
|
-
const compileDest = cds.env.service?.dest
|
|
245
|
-
if (compileDest) {
|
|
246
|
-
// compileDest is relative to src folder in modular build - resolve correctly
|
|
247
|
-
taskOptions.compileDest = path.relative(path.resolve(projectPath, src), path.resolve(projectPath, compileDest))
|
|
248
|
-
}
|
|
249
|
-
return {
|
|
250
|
-
src: src,
|
|
251
|
-
for: BUILD_TASK_JAVA,
|
|
252
|
-
options: taskOptions
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
_createNodeTask(src, taskOptions) {
|
|
257
|
-
this.logger.debug("found implementation technology node")
|
|
258
|
-
return {
|
|
259
|
-
src: src,
|
|
260
|
-
for: BUILD_TASK_NODEJS,
|
|
261
|
-
options: taskOptions
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
static _isMtxExtension() {
|
|
266
|
-
return !!cds.env.extends
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
static _setDefaultSrcFolder(task) {
|
|
270
|
-
switch (task.for) {
|
|
271
|
-
case BUILD_TASK_HANA:
|
|
272
|
-
task.src = task.src || this._normalizePath(cds.env.folders.db)
|
|
273
|
-
break
|
|
274
|
-
case BUILD_TASK_JAVA:
|
|
275
|
-
case BUILD_TASK_JAVA_CF:
|
|
276
|
-
case BUILD_TASK_NODEJS:
|
|
277
|
-
case BUILD_TASK_NODE_CF:
|
|
278
|
-
task.src = task.src || this._normalizePath(cds.env.folders.srv)
|
|
279
|
-
break
|
|
280
|
-
case BUILD_TASK_FIORI:
|
|
281
|
-
task.src = task.src || this._normalizePath(cds.env.folders.app)
|
|
282
|
-
break
|
|
283
|
-
case BUILD_TASK_MTX_SIDECAR:
|
|
284
|
-
task.src = task.src || MTX_SIDECAR_FOLDER
|
|
285
|
-
break
|
|
286
|
-
case BUILD_TASK_MTX_EXTENSION:
|
|
287
|
-
task.src = task.src || "."
|
|
288
|
-
break
|
|
289
|
-
case BUILD_TASK_MTX:
|
|
290
|
-
if (isStreamlinedMtx()) {
|
|
291
|
-
task.src = task.src || this._normalizePath(cds.env.folders.srv)
|
|
292
|
-
} else {
|
|
293
|
-
task.src = task.src || "."
|
|
294
|
-
}
|
|
295
|
-
break
|
|
296
|
-
default:
|
|
297
|
-
throw new Error(`Unknown build task '${task.use || task.for}'`)
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
static _setDefaultModel(task, projectPath) {
|
|
302
|
-
let taskModelPaths = task.options?.model
|
|
303
|
-
if (taskModelPaths && !Array.isArray(taskModelPaths)) {
|
|
304
|
-
taskModelPaths = [taskModelPaths]
|
|
305
|
-
}
|
|
306
|
-
task.options = task.options || {}
|
|
307
|
-
let defaultModelPaths = []
|
|
308
|
-
// add default models to custom build tasks if this hasn't been disabled
|
|
309
|
-
if (taskModelPaths?.length) {
|
|
310
|
-
if (!hasOptionValue(task.options?.[DEFAULT_BUILT_IN_MODELS], false)) {
|
|
311
|
-
// get the built-in models
|
|
312
|
-
defaultModelPaths = getDefaultModelOptions(projectPath).filter(p => p.match('@sap/cds'))
|
|
313
|
-
}
|
|
314
|
-
} else {
|
|
315
|
-
defaultModelPaths = getDefaultModelOptions(projectPath)
|
|
316
|
-
defaultModelPaths.push(task.src)
|
|
317
|
-
if (hasOptionValue(task.options?.[DEFAULT_BUILT_IN_MODELS], false)) {
|
|
318
|
-
// all default models except the built-in models
|
|
319
|
-
defaultModelPaths = defaultModelPaths.filter(p => !p.match('@sap/cds'))
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// REVISIT: filter nodejs bootstrap service models for Java - issues/12770#issuecomment-1805719
|
|
324
|
-
if (this._hasJavaNature(projectPath, cds.env.folders.srv)) {
|
|
325
|
-
defaultModelPaths = defaultModelPaths.filter(p => !NODEJS_MODEL_EXCLUDE_LIST.includes(p))
|
|
326
|
-
}
|
|
327
|
-
// also add built-in models to custom build tasks already containing model options
|
|
328
|
-
if (!taskModelPaths || defaultModelPaths.length) {
|
|
329
|
-
task.options.model = [...new Set(taskModelPaths?.length ? taskModelPaths.concat(defaultModelPaths) : defaultModelPaths)]
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Returns whether this project is a java project or not.
|
|
335
|
-
* @param {string} projectPath - the absolute project path
|
|
336
|
-
* @param {string} srv - the folder name of the service module
|
|
337
|
-
*/
|
|
338
|
-
static _hasJavaNature(projectPath, srv) {
|
|
339
|
-
srv = this._getModuleFolder(projectPath, Array.isArray(srv) ? srv : [srv])
|
|
340
|
-
return hasJavaNature([projectPath, srv && path.join(projectPath, srv)])
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
static _getForValueFromTask(task) {
|
|
344
|
-
return task.for ? task.for : task.use && task.use.substring(BUILD_TASK_PREFIX.length + 1)
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* For valid paths remove trailing '/'. Otherwise return as is - important!!
|
|
349
|
-
* @param {*} dir
|
|
350
|
-
*/
|
|
351
|
-
static _normalizePath(dir) {
|
|
352
|
-
return typeof dir === "string" ? dir.replace(/\/$/, '') : dir
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Determines the module folder from the past list that may represent files or folders w or w/o .cds file extension.
|
|
357
|
-
* @param {string} projectPath
|
|
358
|
-
* @param {Array} filesOrFolders
|
|
359
|
-
*/
|
|
360
|
-
static _getModuleFolder(projectPath, filesOrFolders) {
|
|
361
|
-
const resources = [...filesOrFolders]
|
|
362
|
-
filesOrFolders.forEach(fileOrFolder => {
|
|
363
|
-
if (path.extname(fileOrFolder) !== FILE_EXT_CDS) {
|
|
364
|
-
resources.push(fileOrFolder + FILE_EXT_CDS)
|
|
365
|
-
}
|
|
366
|
-
})
|
|
367
|
-
return resources.reduce((acc, resource) => {
|
|
368
|
-
if (!acc) {
|
|
369
|
-
let resourcePath = path.resolve(projectPath, resource)
|
|
370
|
-
if (fs.existsSync(resourcePath)) {
|
|
371
|
-
if (fs.lstatSync(resourcePath).isDirectory()) {
|
|
372
|
-
acc = resource
|
|
373
|
-
} else {
|
|
374
|
-
// represents file
|
|
375
|
-
acc = path.dirname(resource)
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
return acc
|
|
380
|
-
}, null)
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
module.exports = BuildTaskProviderInternal
|